Iniúchadh ar inneall VoIP Mediastreamer2. Cuid 11

Tógtar ábhar an ailt ó mo cainéal zen.

Iniúchadh ar inneall VoIP Mediastreamer2. Cuid 11

Meicníocht gluaiseachta sonraí

  • Bloc sonraí dblk_t
  • Teachtaireacht mblk_t
  • Feidhmeanna chun oibriú le teachtaireachtaí mblk_t
  • scuaine_t
  • Feidhmeanna chun oibriú le scuainí queue_t
  • Scagairí a nascadh
  • Pointe comhartha de ghraf próiseála sonraí
  • Gníomhaíochtaí an ticker taobh thiar de na radhairc
  • Maolán (MSBufferizer)
  • Feidhmeanna chun oibriú le MSBufferizer

Sa cheann deireanach Airteagal tá ár scagaire féin forbartha againn. Díreoidh an t-alt seo ar an meicníocht inmheánach chun sonraí a bhogadh idir scagairí sruthaithe meán. Tabharfaidh sé seo deis duit scagairí sofaisticiúla a scríobh le níos lú iarracht sa todhchaí.

Meicníocht gluaiseachta sonraí

Baintear úsáid as scuainí a chuireann an struchtúr síos orthu ag gluaiseacht sonraí sa sruthlóir meán scuaine_t. Teaghráin teachtaireachtaí cosúil le mblk_t, nach bhfuil sonraí comhartha iontu féin, ach naisc amháin chuig an teachtaireacht roimhe sin, an chéad teachtaireacht eile agus leis an mbloc sonraí. Ina theannta sin, ba mhaith liom a aibhsiú go háirithe go bhfuil réimse ann freisin le haghaidh nasc chuig teachtaireacht den chineál céanna, a ligeann duit liosta teachtaireachtaí atá nasctha go haonarach a eagrú. Cuirfimid tuple ar ghrúpa teachtaireachtaí aontaithe ag liosta den sórt sin. Mar sin, is féidir le haon eilimint den scuaine a bheith ina teachtaireacht amháin mblk_t, agus b'fhéidir an ceann tuple teachtaireacht mblk_t. Is féidir a bhloc sonraí barda féin a bheith ag gach teachtaireacht tuple. Déanfaimid plé ar cén fáth go bhfuil gá le tuples beagán níos déanaí.

Mar a luadh thuas, níl bloc sonraí sa teachtaireacht féin; ina ionad sin, níl ann ach pointeoir chuig an limistéar cuimhne ina bhfuil an bloc stóráilte. Sa chuid seo, tá an pictiúr iomlán d’obair an tsruthaora meán chun cuimhne an stórais dorais sa chartún “Monsters, Inc.,” áit a ngluaiseann doirse (naisc le sonraí - seomraí) ar luas dÚsachtach ar feadh iompróirí lastuas, agus na seomraí féin fanacht gan gluaiseacht.

Anois, ag bogadh feadh an ordlathais ó bhun go barr, déanaimis machnamh mionsonraithe ar na heintitis liostaithe den mheicníocht tarchurtha sonraí sa sruthóir meán.

Bloc sonraí dblk_t

Tá ceanntásc agus maolán sonraí sa bhloc sonraí. Déantar cur síos ar an gceanntásc leis an struchtúr seo a leanas,

typedef struct datab
{
unsigned char *db_base; // Указатель на начало буфер данных.
unsigned char *db_lim;  // Указатель на конец буфер данных.
void (*db_freefn)(void*); // Функция освобождения памяти при удалении блока.
int db_ref; // Счетчик ссылок.
} dblk_t;

Tá leideanna i réimsí an struchtúir maidir le tús an mhaoláin, deireadh an mhaoláin, agus an fheidhm chun an maolán sonraí a scriosadh. An eilimint dheireanach sa cheanntásc db_ref — cuntar tagartha, má shroicheann sé nialas, feidhmíonn sé seo mar chomhartha chun an bloc seo a scriosadh ón gcuimhne. Má chruthaigh an fheidhm bloc sonraí datab_alloc() , ansin cuirfear an maolán sonraí sa chuimhne díreach tar éis an ceanntásc. I ngach cás eile, is féidir an maolán a bheith suite áit éigin ar leithligh. Beidh samplaí comhartha nó sonraí eile sa maolán sonraí a theastaíonn uainn a phróiseáil le scagairí.

Cruthaítear sampla nua de bhloc sonraí ag baint úsáide as an bhfeidhm:

dblk_t *datab_alloc(int size);

Mar pharaiméadar ionchuir, tugtar méid na sonraí a stórálfaidh an bloc. Leithdháiltear níos mó cuimhne chun ceanntásc - struchtúr - a chur ag tús an chuimhne leithdháilte sonraíb. Ach nuair a bhíonn feidhmeanna eile á n-úsáid, ní tharlaíonn sé seo i gcónaí; i gcásanna áirithe, d’fhéadfadh an maolán sonraí a bheith suite ar leithligh ó cheanntásc an bhloic sonraí. Nuair a bhíonn struchtúr á chruthú, déantar na réimsí a chumrú ionas go mbeidh a réimse db_bun dírithe ar thús an limistéir sonraí, agus db_lim go dtí a deireadh. Comhaireamh naisc db_ref socraithe go ceann. Socraítear pointeoir feidhm shoiléir na sonraí go nialas.

Teachtaireacht mblk_t

Mar a dúradh, tá gnéithe scuaine de chineál mblk_t, sainmhínítear é mar seo a leanas:

typedef struct msgb
{
  struct msgb *b_prev;   // Указатель на предыдущий элемент списка.
  struct msgb *b_next;   // Указатель на следующий элемент списка.
  struct msgb *b_cont;   // Указатель для подклейки к сообщению других сообщений, для создания кортежа сообщений.
  struct datab *b_datap; // Указатель на структуру блока данных.
  unsigned char *b_rptr; // Указатель на начало области данных для чтения данных буфера b_datap.
  unsigned char *b_wptr; // Указатель на начало области данных для записи данных буфера b_datap.
  uint32_t reserved1;    // Зарезервированное поле1, медиастример помещает туда служебную информацию. 
  uint32_t reserved2;    // Зарезервированное поле2, медиастример помещает туда служебную информацию.
  #if defined(ORTP_TIMESTAMP)
  struct timeval timestamp;
  #endif
  ortp_recv_addr_t recv_addr;
} mblk_t;

Struchtúr mblk_t tá leideanna ag an tús b_roimhe, b_ seo chugainn, atá riachtanach chun liosta nasctha faoi dhó a eagrú (is scuaine é scuaine_t).

Ansin tagann an pointeoir b_cont, a úsáidtear ach amháin nuair a bhíonn an teachtaireacht mar chuid de tuple. Maidir leis an teachtaireacht dheireanach sa tuple, fanann an pointeoir seo ar neamhní.

Ansin feicimid pointeoir chuig bloc sonraí b_sonraí, a bhfuil an teachtaireacht ann ina leith. Ina dhiaidh sin tá leideanna chuig an limistéar laistigh den maolán sonraí bloc. Gort b_rptr sonraítear an áit óna léifear sonraí ón maolán. Gort b_wptr léiríonn sé an suíomh óna ndéanfar scríobh chuig an maolán.

Is de chineál seirbhíse na réimsí atá fágtha agus ní bhaineann siad le hoibriú na meicníochta aistrithe sonraí.

Anseo thíos tá teachtaireacht amháin leis an ainm m1 agus bloc sonraí d1.
Iniúchadh ar inneall VoIP Mediastreamer2. Cuid 11
Taispeánann an figiúr seo a leanas tuple de thrí theachtaireacht m1, m1_1, m1_2.
Iniúchadh ar inneall VoIP Mediastreamer2. Cuid 11

Feidhmeanna teachtaireachtaí mblk_t

Teachtaireacht nua mblk_t cruthaithe ag an bhfeidhm:

mblk_t *allocb(int size, int pri); 

cuireann sí teachtaireacht nua i gcuimhne mblk_t le bloc sonraí den mhéid sonraithe méid, an dara argóint - pri nach n-úsáidtear sa leagan seo den leabharlann. Ba cheart go bhfanfadh sé nialas. Le linn oibriú na feidhme, leithdháilfear cuimhne ar struchtúr na teachtaireachta nua agus tabharfar an fheidhm mblk_init(), a athshocróidh gach réimse de chás cruthaithe an struchtúir agus ansin, ag baint úsáide as an méid thuasluaite datab_alloc(), cruthóidh sé maolán sonraí. Ina dhiaidh sin déanfar na réimsí sa struchtúr a chumrú:

mp->b_datap=datab;
mp->b_rptr=mp->b_wptr=datab->db_base;
mp->b_next=mp->b_prev=mp->b_cont=NULL;

Ag an aschur faighimid teachtaireacht nua le réimsí tosaigh agus maolán sonraí folamh. Chun sonraí a chur le teachtaireacht, ní mór duit é a chóipeáil chuig an maolán bloc sonraí:

memcpy(msg->b_rptr, data, size);

i gcás dáta is pointeoir chuig an bhfoinse sonraí, agus méid - a méid.
ansin caithfidh tú an pointeoir a nuashonrú go dtí an pointe scríofa ionas go díríonn sé arís ar thús an limistéir shaora sa mhaolán:

msg->b_wptr = msg->b_wptr + size

Más gá duit teachtaireacht a chruthú ó mhaolán atá ann cheana féin, gan cóipeáil, bain úsáid as an bhfeidhm:

mblk_t *esballoc(uint8_t *buf, int size, int pri, void (*freefn)(void*)); 

Déanfaidh an fheidhm, tar éis an teachtaireacht agus struchtúr an bhloc sonraí a chruthú, a leideanna a chumrú do na sonraí ag an seoladh buff. Iad siúd. sa chás seo, níl an maolán sonraí suite tar éis réimsí ceanntásca an bhloc sonraí, mar a tharla nuair a cruthaíodh bloc sonraí leis an bhfeidhm datab_alloc(). Fanfaidh an maolán le sonraí a cuireadh ar aghaidh chuig an bhfeidhm san áit a raibh sé, ach le cabhair ó threo beidh sé ceangailte le ceanntásc nuachruthaithe an bhloic sonraí, agus sin, dá réir sin, leis an teachtaireacht.

A teachtaireacht amháin mblk_t Is féidir roinnt bloic sonraí a chomhchaiúnú go seicheamhach. Déantar é seo ag an bhfeidhm:

mblk_t * appendb(mblk_t *mp, const char *data, int size, bool_t pad); 

mp — teachtaireacht a gcuirfear bloc sonraí eile léi;
dáta — pointeoir don bhloc, a gcuirfear cóip de leis an teachtaireacht;
méid — méid na sonraí;
ceap — bratach nach mór méid na cuimhne leithdháilte a ailíniú feadh teorainn 4 bheart (déanfar an stuáil le nialais).

Má tá go leor spáis sa maolán sonraí teachtaireachta atá ann cheana féin, ansin déanfar na sonraí nua a ghreamú taobh thiar de na sonraí atá ann cheana féin. Má tá níos lú spáis saor i maolán sonraí na teachtaireachta ná méid, ansin cruthaítear teachtaireacht nua le méid maolánach leordhóthanach agus déantar na sonraí a chóipeáil chuig a maolán. Is teachtaireacht nua í seo, atá nasctha leis an gceann bunaidh le pointeoir b_cont. Sa chás seo, casann an teachtaireacht isteach i tuple.

Más gá duit bloc eile sonraí a chur leis an tuple, caithfidh tú an fheidhm a úsáid:

void msgappend(mblk_t *mp, const char *data, int size, bool_t pad);

gheobhaidh sí an teachtaireacht dheireanach sa tuple (tá aige b_cont beidh sé null) agus glaofaidh sé an fheidhm don teachtaireacht seo aguisín().

Is féidir leat méid na sonraí i dteachtaireacht nó tuple a fháil amach ag baint úsáide as an bhfeidhm:

int msgdsize(const mblk_t *mp);

lúbfaidh sé tríd na teachtaireachtaí go léir sa tuple agus seolfaidh sé an méid iomlán sonraí i maoláin sonraí na dteachtaireachtaí sin. I gcás gach teachtaireachta, ríomhtar méid na sonraí mar seo a leanas:

 mp->b_wptr - mp->b_rptr

Chun dhá thuple a chur le chéile, úsáid an fheidhm:

mblk_t *concatb(mblk_t *mp, mblk_t *newm);

cuireann sí an tuple i gceangal leis nuam a eireaball an tuple mp agus cuireann sé pointeoir ar ais chuig an teachtaireacht dheireanach ón tuple dá bharr.

Más gá, is féidir tuple a iompú isteach i dteachtaireacht amháin le bloc amháin sonraí; déantar é seo ag an bhfeidhm:

void msgpullup(mblk_t *mp,int len);

más argóint LEN is -1, ansin déantar méid an mhaoláin leithdháilte a chinneadh go huathoibríoch. Dá LEN is uimhir dheimhneach é, cruthófar maolán den mhéid seo agus déanfar sonraí na teachtaireachta tuple a chóipeáil isteach ann. Má ritheann an maolán amach, stopfaidh an chóipeáil ansin. Gheobhaidh an chéad teachtaireacht ón tuple maolán méid nua leis na sonraí cóipeáilte. Scriosfar na teachtaireachtaí atá fágtha agus cuirfear an chuimhne ar ais chuig an gcarn.

Agus struchtúr á scriosadh mblk_t cuirtear comhaireamh tagartha an bhloic sonraí san áireamh más rud é, agus tú ag glaoch saor() casadh sé amach a bheith nialas, ansin tá an maolán sonraí a scriosadh chomh maith leis an ásc mblk_t, a thugann suntas dó.

Réimsí na teachtaireachta nua á dtosú:

void mblk_init(mblk_t *mp);

Ag cur píosa eile sonraí leis an teachtaireacht:

mblk_t * appendb(mblk_t *mp, const char *data, size_t size, bool_t pad);

Mura n-oireann na sonraí nua isteach i spás saor in aisce an mhaoláin sonraí teachtaireachta, ansin tá teachtaireacht arna cruthú go leithleach le maolán den mhéid riachtanach ceangailte leis an teachtaireacht (tá pointeoir don teachtaireacht bhreise socraithe sa chéad teachtaireacht) agus an teachtaireacht iompú isteach i tuple.

Ag cur píosa sonraí le tuple:

void msgappend(mblk_t *mp, const char *data, size_t size, bool_t pad); 

Glaonn an fheidhm appendb() i lúb.

Dhá thuple a chomhcheangal i gceann amháin:

mblk_t *concatb(mblk_t *mp, mblk_t *newm);

Teachtaireacht nuam ag gabháil leis mp.

Ag déanamh cóip de theachtaireacht amháin:

mblk_t *copyb(const mblk_t *mp);

Cóipeáil iomlán tuple leis na bloic sonraí go léir:

mblk_t *copymsg(const mblk_t *mp);

Déantar gnéithe an tuple a chóipeáil ag an bhfeidhm cóip().

Cruthaigh cóip éasca de theachtaireacht mblk_t. Sa chás seo, ní chóipeáiltear an bloc sonraí, ach méadaítear a gcuntar tagartha db_ref:

mblk_t *dupb(mblk_t *mp);

Ag déanamh cóip éadrom de tuple. Ní dhéantar bloic sonraí a chóipeáil, ní dhéantar ach a n-áiritheoirí tagartha a mhéadú db_ref:

mblk_t *dupmsg(mblk_t* m);

Gach teachtaireacht de thuple a ghreamú in aon teachtaireacht amháin:

void msgpullup(mblk_t *mp,size_t len);

Má tá an argóint LEN is -1, ansin déantar méid an mhaoláin leithdháilte a chinneadh go huathoibríoch.

Teachtaireacht á scriosadh, tuple:

void freemsg(mblk_t *mp);

Laghdaítear comhaireamh tagartha an bhloc sonraí faoi cheann amháin. Má shroicheann sé nialas, scriostar an bloc sonraí freisin.

Méid iomlán na sonraí i dteachtaireacht nó tuple a ríomh.

size_t msgdsize(const mblk_t *mp);

Ag fáil teachtaireachta ó eireaball na scuaine:

mblk_t *ms_queue_peek_last (q);

Ábhar na réimsí forchoimeádta de theachtaireacht amháin a chóipeáil isteach i dteachtaireacht eile (go deimhin, tá bratacha sna réimsí seo a úsáideann an sruthóir meán):

mblk_meta_copy(const mblk_t *source, mblk *dest);

Cas scuaine_t

Cuirtear an scuaine teachtaireachta sa sruthóir meán i bhfeidhm mar liosta ciorclach nasctha faoi dhó. Tá pointeoir chuig bloc sonraí le samplaí comhartha i ngach eilimint liosta. Tharlaíonn sé go raibh ach leideanna chun an t-aistriú bloc sonraí ar a seal, cé go bhfanann na sonraí féin motionless. Iad siúd. ní bhogtar ach naisc chucu.
Struchtúr ag cur síos ar an scuaine scuaine_t, léirithe thíos:

typedef struct _queue
{
   mblk_t _q_stopper; /* "Холостой" элемент очереди, не указывает на данные, используется только для управления очередью. При инициализации очереди (qinit()) его указатели настраиваются так, чтобы они указывали на него самого. */
   int q_mcount;        // Количество элементов в очереди.
} queue_t;

Tá réimse sa struchtúr - pointeoir _q_ stopallán cineál *mblk_t, díríonn sé ar an gcéad eilimint (teachtaireacht) sa scuaine. Is é an dara réimse den struchtúr an gcuntar teachtaireachtaí sa scuaine.
Taispeánann an figiúr thíos scuaine darb ainm q1 ina bhfuil 4 theachtaireacht m1, m2, m3, m4.
Iniúchadh ar inneall VoIP Mediastreamer2. Cuid 11
Taispeánann an figiúr seo a leanas scuaine darb ainm q1 ina bhfuil 4 theachtaireacht m1,m2,m3,m4. Is é teachtaireacht m2 ceann tuple ina bhfuil dhá theachtaireacht eile m2_1 agus m2_2.

Iniúchadh ar inneall VoIP Mediastreamer2. Cuid 11

Feidhmeanna chun oibriú le scuainí queue_t

Túsú scuaine:

void qinit(queue_t *q);

Réimse _q_ stopallán (dá ngairfear “stopair” anseo feasta) is é an fheidhm atá leis an tús mblk_init(), déantar a eilimint roimhe seo agus an pointeoir eilimint eile a choigeartú chun a chur in iúl dó féin. Athshocraítear cuntar na heiliminte scuaine go nialas.

Ag cur eilimint nua (teachtaireachtaí):

void putq(queue_t *q, mblk_t *m);

Eilimint nua m a chur le deireadh an liosta, na leideanna eilimint a choigeartú ionas go mbeidh an stopallán an chéad eilimint eile dó, agus beidh sé mar an eilimint roimhe seo don stopallán. Tá an cuntar eilimint scuaine méadaithe.

Ag fáil eiliminte ón scuaine:

mblk_t * getq(queue_t *q); 

Aisghabhtar an teachtaireacht a thagann tar éis an stopalláin, agus déantar an cuntar eilimint a laghdú. Mura bhfuil aon eilimintí sa scuaine ach amháin an stopallán, ansin cuirtear 0 ar ais.

Teachtaireacht á cur isteach i scuaine:

void insq(queue_t *q, mblk_t *emp, mblk_t *mp); 

Eilimint mp a cuireadh isteach roimh an eilimint EMP. Dá EMP=0, ansin cuirtear an teachtaireacht le heireaball na scuaine.

Ag fáil teachtaireachta ó cheann na scuaine:

void remq(queue_t *q, mblk_t *mp); 

Tá an cuntar eilimint laghdaithe.

Ag léamh pointeoir don chéad eilimint sa scuaine:

mblk_t * peekq(queue_t *q); 

Gach eilimint a bhaint den scuaine agus na heilimintí á scriosadh iad féin:

void flushq(queue_t *q, int how);

Argóint conas a nach n-úsáidtear. Tá cuntar na heiliminte scuaine socraithe go nialas.

Macra chun pointeoir a léamh don eilimint dheireanach den scuaine:

mblk_t * qlast(queue_t *q);

Agus tú ag obair le scuainí teachtaireachta, bí ar an eolas nuair a ghlaonn tú ms_queue_put(q, m) le pointeoir nialasach don teachtaireacht, lúbann an fheidhm. Beidh do chlár reoite. iompar mar an gcéanna ms_ scuaine_ar aghaidh(q, m).

Scagairí a nascadh

Úsáidtear an scuaine a bhfuil cur síos déanta uirthi thuas chun teachtaireachtaí a chur ar aghaidh ó scagaire go chéile nó ó scagairí go roinnt. Cruthaíonn na scagairí agus a gcuid nasc graf dírithe. Tabharfar an focal ginearálta “bioráin” ar ionchur nó aschur an scagaire. Chun cur síos a dhéanamh ar an ord ina bhfuil na scagairí nasctha lena chéile, úsáideann an sruthlóir meán an coincheap "pointe comhartha". Is struchtúr é pointe comhartha _MSCPpoint, ina bhfuil pointeoir don scagaire agus uimhir a haon dá bhioráin; dá réir sin, cuireann sé síos ar nasc ceann d’ionchuir nó d’aschur an scagaire.

Pointe comhartha de ghraf próiseála sonraí

typedef struct _MSCPoint{
struct _MSFilter *filter; // Указатель на фильтр медиастримера.
int pin;                        // Номер одного из входов или выходов фильтра, т.е. пин.
} MSCPoint;

Tá na bioráin scagaire uimhrithe ag tosú ó nialas.

Déanann an struchtúr cur síos ar nascadh dhá bhioráin trí scuaine teachtaireachta _MSQueue, ina bhfuil scuaine teachtaireachta agus leideanna chuig an dá phointe comhartha a nascann sé:

typedef struct _MSQueue
{
queue_t q;
MSCPoint prev;
MSCPoint next;
}MSQueue;

Tabharfaimid nasc comhartha ar an struchtúr seo. Tá tábla de naisc ionchuir agus tábla de naisc aschuir (MSQueue). Socraítear méid na dtáblaí agus scagaire á chruthú; rinneamar é seo cheana féin ag baint úsáide as athróg de chineál easpórtáilte MSFilterDesc, nuair a d'fhorbair muid ár scagaire féin. Seo thíos struchtúr a chuireann síos ar aon scagaire i sruthóir meán, Scagaire MSF:


struct _MSFilter{
    MSFilterDesc *desc;    /* Указатель на дескриптор фильтра. */
    /* Защищенные атрибуты, их нельзя сдвигать или убирать иначе будет нарушена работа с плагинами. */
    ms_mutex_t lock;      /* Семафор. */
    MSQueue **inputs;     /* Таблица входных линков. */
    MSQueue **outputs;    /* Таблица выходных линков. */
    struct _MSFactory *factory; /* Указатель на фабрику, которая создала данный экземпляр фильтра. */
    void *padding;              /* Не используется, будет задействован если добавятся защищенные поля. */
    void *data;                 /* Указатель на произвольную структуру для хранения данных внутреннего состояния фильтра и промежуточных вычислений. */
    struct _MSTicker *ticker;   /* Указатель на объект тикера, который не должен быть нулевым когда вызывается функция process(). */
    /*private attributes, they can be moved and changed at any time*/
    MSList *notify_callbacks; /* Список обратных вызовов, используемых для обработки событий фильтра. */
    uint32_t last_tick;       /* Номер последнего такта, когда выполнялся вызов process(). */ 
    MSFilterStats *stats;     /* Статистика работы фильтра.*/
    int postponed_task; /*Количество отложенных задач. Некоторые фильтры могут откладывать обработку данных (вызов process()) на несколько тактов.*/
    bool_t seen;  /* Флаг, который использует тикер, чтобы помечать что этот экземпляр фильтра он уже обслужил на данном такте.*/
};
typedef struct _MSFilter MSFilter;

Tar éis dúinn na scagairí sa chlár C a nascadh de réir ár bplean (ach níor nasc muid an ticeoir), chruthaigh muid graf dírithe ar an mbealach sin, ar cásanna den struchtúr iad na nóid. Scagaire MSFIs samplaí de naisc iad , agus imill MSQueue.

Gníomhaíochtaí an ticker taobh thiar de na radhairc

Nuair a dúirt mé leat gur scagaire é an ticker le haghaidh fhoinse na sceartán, ní raibh sé an fhírinne iomlán faoi. Is rud é ticker a ritheann feidhmeanna ar an gclog próiseas() gach scagairí den chiorcad (graf) lena bhfuil sé nasctha. Nuair a nascaimid ticeoir le grafscagaire i ríomhchlár C, taispeánaimid don ticeoir an graf a rialóidh sé as seo amach go dtí go gcasfaimid as é. Tar éis nascadh, tosaíonn an ticker ag scrúdú an ghraf a chuirtear faoina chúram, ag tiomsú liosta de na scagairí a chuimsíonn sé. Chun gan an scagaire céanna a “chomhaireamh” faoi dhó, marcálann sé na scagairí braite trí ticbhosca a chur iontu le feiceáil. Déantar an cuardach ag baint úsáide as na táblaí naisc atá ag gach scagaire.

Le linn a thurais tosaigh ar an ngraf, seiceálann an ticker cibé an bhfuil ceann amháin ar a laghad i measc na scagairí a fheidhmíonn mar fhoinse bloic sonraí. Mura bhfuil aon cheann ann, meastar go bhfuil an graf mícheart agus tuairteanna an ticker.

Má tharlaíonn sé go bhfuil an graf “ceart”, do gach scagaire a aimsítear, glaoitear an fheidhm chun tosaigh réamhphróiseas(). Chomh luath agus a thagann an nóiméad don chéad timthriall próiseála eile (gach 10 milleasoicind de réir réamhshocraithe), glaonn an ticker an fheidhm próiseas() do gach scagairí foinse a fuarthas roimhe seo, agus ansin do na scagairí atá fágtha sa liosta. Má tá naisc ionchuir ag an scagaire, ansin rith an fheidhm próiseas() athuair go dtí go bhfuil na scuainí naisc ionchuir folamh. Ina dhiaidh sin, bogann sé ar aghaidh go dtí an chéad scagaire eile ar an liosta agus “scrollaigh” é go dtí go mbeidh na naisc ionchuir saor ó theachtaireachtaí. Bogann an ticeoir ó scagaire go scagaire go dtí go gcríochnaíonn an liosta. Críochnaíonn sé seo próiseáil an timthrialla.

Anois cuirfimid ar ais chuig tuples agus labhairt faoi cén fáth ar cuireadh eintiteas den sórt sin leis an sruthóir meáin. Go ginearálta, ní hionann an méid sonraí a theastaíonn ón algartam atá ag feidhmiú taobh istigh den scagaire agus ní iolraí é de mhéid na maoláin sonraí a fuarthas ag an ionchur. Mar shampla, tá scagaire á scríobh againn a dhéanann claochlú tapa Fourier, nach féidir de réir sainmhínithe ach bloic sonraí a bhfuil cumhacht dhá mhéid acu a phróiseáil. Bíodh sé 512 chomhaireamh. Má ghintear na sonraí trí chainéal teileafóin, ansin tabharfaidh maolán sonraí gach teachtaireachta ag an ionchur 160 sampla comhartha dúinn. Tá sé mealltach gan sonraí a bhailiú ón ionchur go dtí go mbíonn an méid sonraí riachtanach ann. Ach sa chás seo, tarlóidh imbhualadh leis an ticker, rud a dhéanfaidh iarracht gan rath an scagaire a scrollú go dtí go mbeidh an nasc ionchuir folamh. Roimhe seo, d'ainmnigh muid an riail seo mar an tríú prionsabal an scagaire. De réir an phrionsabail seo, ní mór d'fheidhm próisis() an scagaire na sonraí go léir a thógáil ó na scuainí ionchuir.

Ina theannta sin, ní bheidh sé indéanta ach 512 sampla a thógáil ón ionchur, mar ní féidir leat ach bloic iomlána a ghlacadh, i.e. beidh ar an scagaire 640 sampla a thógáil agus 512 díobh a úsáid, an chuid eile sula mbaileofar cuid nua sonraí. Mar sin, ní mór dár scagaire, chomh maith lena phríomhobair, gníomhartha cúnta a sholáthar chun sonraí ionchuir a stóráil go hidirmheánach. D'fhorbair forbróirí an streamer meáin agus réiteach ar an bhfadhb ghinearálta seo réad speisialta - MBufferizer (maolán), a réitíonn an fhadhb seo ag baint úsáide as tuples.

Maolán (MSBufferizer)

Is rud é seo a charnóidh sonraí ionchuir taobh istigh den scagaire agus a thosóidh á gcur isteach le próiseáil a luaithe is leor an méid faisnéise chun an algartam scagaire a rith. Cé go bhfuil an maolán ag bailiú sonraí, oibreoidh an scagaire i mód díomhaoin, gan úsáid a bhaint as cumhacht próiseála an phróiseálaí. Ach a luaithe a thugann feidhm léitheoireachta an mhaoláin luach seachas nialas ar ais, tosaíonn an fheidhm próiseas() den scagaire sonraí ón maolán a thógáil agus a phróiseáil i gcodanna den mhéid riachtanach, go dtí go bhfuil sé ídithe.
Tá sonraí nach bhfuil ag teastáil fós sa mhaolán mar an chéad eilimint den tuple, a bhfuil bloic sonraí ionchuir ina dhiaidh sin ceangailte leis.

An struchtúr a chuireann síos ar an maolán:

struct _MSBufferizer{
queue_t q; /* Очередь сообщений. */
int size; /* Суммарный размер данных находящихся в буферизаторе в данный момент. */
};
typedef struct _MSBufferizer MSBufferizer;

Feidhmeanna chun oibriú le MSBufferizer

Mar shampla maolánach nua á chruthú:

MSBufferizer * ms_bufferizer_new(void);

Leithdháiltear cuimhne, cuirtear tús leis ms_bufferizer_init() agus cuirtear pointeoir ar ais.

Feidhm tosaigh:

void ms_bufferizer_init(MSBufferizer *obj); 

Tá an scuaine ag tosú q, Gort méid socraithe go nialas.

Ag cur teachtaireachta:

void ms_bufferizer_put(MSBufferizer *obj, mblk_t *m); 

Cuirtear teachtaireacht m leis an scuaine. Cuirtear leis an méid ríofa de bhloic sonraí méid.

Gach teachtaireacht a aistriú ón scuaine sonraí naisc chuig an maolán q:

void ms_bufferizer_put_from_queue(MSBufferizer *obj, MSQueue *q);   

Teachtaireachtaí a aistriú ó nasc q sa maolán a dhéantar ag baint úsáide as an fheidhm ms_bufferizer_put().

Ag léamh ón maolán:

int ms_bufferizer_read(MSBufferizer *obj, uint8_t *data, int datalen); 

Más lú méid na sonraí atá carntha sa mhaolán ná an ceann iarrtha (datalen), ansin filleann an fheidhm nialas, ní dhéantar sonraí a chóipeáil go sonraí. Seachas sin, déantar sonraí a chóipeáil go seicheamhach ó thuples atá suite sa mhaolán. Tar éis é a chóipeáil, scriostar an tuple agus saortar an chuimhne. Críochnaíonn an chóipeáil faoi láthair nuair a chóipeáiltear bearta datalen. Má ritheann an spás amach i lár an bhloic sonraí, ansin sa teachtaireacht seo, laghdófar an bloc sonraí go dtí an chuid neamhchóipeáilte atá fágtha. An chéad uair eile a ghlaonn tú, leanfar den chóipeáil ón bpointe seo.

Léamh an méid sonraí atá ar fáil faoi láthair sa maolán:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

Filleann an réimse méid maolán.

Ag fáil réidh le cuid de na sonraí sa mhaolán:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

Déantar líon sonraithe beart na sonraí a aisghabháil agus a chaitheamh i leataobh. Cuirtear na sonraí is sine i leataobh.

Gach teachtaireacht sa mhaolán a scriosadh:

void ms_bufferizer_flush(MSBufferizer *obj); 

Athshocraítear an cuntar sonraí go nialas.

Gach teachtaireacht sa mhaolán a scriosadh:

void ms_bufferizer_uninit(MSBufferizer *obj); 

Ní athshocraítear an cuntar.

An maolán a bhaint agus cuimhne a shaoradh:

void ms_bufferizer_destroy(MSBufferizer *obj);  

Tá samplaí d’úsáid an mhaoláin le fáil i gcód foinse roinnt scagairí sruthaithe meán. Mar shampla, sa scagaire MS_L16_ENC, a athshocraíonn na bearta sna samplaí ón ordú líonra go dtí an t-ordú óstaigh: l16.c

Sa chéad alt eile, féachfaimid ar an tsaincheist maidir le meastachán a dhéanamh ar an ualach ar ticker agus bealaí chun dul i ngleic le ró-ualach ríomhaireachta i sruthóir meáin.

Foinse: will.com

Add a comment