Nesploraw il-magna VoIP Mediastreamer2. Parti 11

Il-materjal tal-artiklu huwa meħud minn tiegħi kanal zen.

Nesploraw il-magna VoIP Mediastreamer2. Parti 11

Mekkaniżmu tal-moviment tad-data

  • Blokk tad-dejta dblk_t
  • Messaġġ mblk_t
  • Funzjonijiet biex taħdem ma' messaġġi mblk_t
  • Kju queue_t
  • Funzjonijiet biex taħdem bil-kjuwijiet queue_t
  • Filtri li jgħaqqdu
  • Punt tas-sinjal tal-grafika tal-ipproċessar tad-dejta
  • Wara l-kwinti attivitajiet tal-ticker
  • Bufferizer (MSBufferizer)
  • Funzjonijiet biex taħdem ma 'MSBufferizer

Fl-aħħar artikolu żviluppajna l-filtru tagħna stess. Dan l-artikolu se jiffoka fuq il-mekkaniżmu intern għaċ-ċaqliq tad-dejta bejn il-filtri tal-media streamer. Dan jippermettilek tikteb filtri sofistikati b'inqas sforz fil-futur.

Mekkaniżmu tal-moviment tad-data

Il-moviment tad-dejta fil-media streamer jitwettaq bl-użu ta' kjuwijiet deskritti mill-istruttura kju_t. Strings ta 'messaġġi simili mblk_t, li huma stess ma fihomx data tas-sinjali, iżda biss links għall-messaġġ preċedenti, li jmiss u għall-blokk tad-data. Barra minn hekk, irrid nenfasizza b’mod speċjali li hemm ukoll qasam għal link għal messaġġ tal-istess tip, li jippermettilek torganizza lista ta’ messaġġi marbuta waħedhom. Aħna se nsejħu grupp ta 'messaġġi magħquda b'tali lista tuple. Għalhekk, kwalunkwe element tal-kju jista 'jkun messaġġ wieħed mblk_t, u forsi l-kap ta 'messaġġ tuple mblk_t. Kull messaġġ tuple jista' jkollu l-blokk tad-dejta tal-ward tiegħu stess. Aħna ser niddiskutu għaliex it-tuples huma meħtieġa ftit aktar tard.

Kif imsemmi hawn fuq, il-messaġġ innifsu ma fihx blokk ta 'dejta; minflok, fih biss pointer lejn iż-żona tal-memorja fejn il-blokk huwa maħżun. F'din il-parti, l-istampa ġenerali tax-xogħol tal-media streamer hija reminixxenti tal-maħżen tal-bieb fil-kartun "Monsters, Inc.," fejn il-bibien (links għal data - kmamar) jimxu b'veloċità tal-ġenn tul conveyors overhead, filwaqt li l-kmamar infushom jibqgħu bla moviment.

Issa, nimxu tul il-ġerarkija minn isfel għal fuq, ejja nikkunsidraw fid-dettall l-entitajiet elenkati tal-mekkaniżmu tat-trażmissjoni tad-dejta fil-media streamer.

Blokk tad-data dblk_t

Il-blokk tad-dejta jikkonsisti minn header u buffer tad-dejta. L-intestatura hija deskritta mill-istruttura li ġejja,

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

L-oqsma tal-istruttura fihom indikaturi għall-bidu tal-buffer, it-tmiem tal-buffer, u l-funzjoni għat-tħassir tal-buffer tad-dejta. L-aħħar element fl-header db_ref — il-counter ta' referenza, jekk jilħaq iż-żero, dan iservi bħala sinjal biex titħassar din il-blokka mill-memorja. Jekk il-blokk tad-dejta nħoloq mill-funzjoni datab_alloc() , allura l-buffer tad-dejta jitqiegħed fil-memorja immedjatament wara l-header. Fil-każijiet l-oħra kollha, il-buffer jista' jinstab x'imkien separatament. Il-buffer tad-dejta se jkun fih kampjuni tas-sinjali jew dejta oħra li rridu nipproċessaw bil-filtri.

Istanza ġdida ta' blokk tad-dejta tinħoloq bl-użu tal-funzjoni:

dblk_t *datab_alloc(int size);

Bħala parametru ta 'input, jingħata d-daqs tad-dejta li l-blokka se taħżen. Aktar memorja hija allokata sabiex titqiegħed header - struttura - fil-bidu tal-memorja allokata datab. Iżda meta tuża funzjonijiet oħra, dan mhux dejjem iseħħ; f'xi każijiet, il-buffer tad-dejta jista 'jkun lokalizzat separatament mill-header tal-blokka tad-dejta. Meta tinħoloq struttura, l-oqsma huma kkonfigurati sabiex il-qasam tagħha db_base indika l-bidu taż-żona tad-dejta, u db_lim sa tmiemha. Għadd ta' links db_ref huwa ssettjat għal wieħed. Il-pointer tal-funzjoni ċara tad-dejta huwa ssettjat għal żero.

Messaġġ mblk_t

Kif intqal, l-elementi tal-kju huma tat-tip mblk_t, hija definita kif ġej:

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;

Struttura mblk_t fih indikaturi fil-bidu b_prev, b_li jmiss, li huma meħtieġa biex tiġi organizzata lista konnessa doppjament (li hija kju kju_t).

Imbagħad jiġi l-pointer b_kont, li jintuża biss meta l-messaġġ ikun parti minn tuple. Għall-aħħar messaġġ fit-tuple, dan il-pointer jibqa' null.

Sussegwentement naraw pointer għal blokka tad-data b_datap, li għaliha jeżisti l-messaġġ. Huwa segwit minn indikaturi lejn iż-żona ġewwa l-buffer tad-dejta tal-blokk. Qasam b_rptr jispeċifika l-post minn fejn id-dejta mill-buffer se tinqara. Qasam b_wptr jindika l-post minn fejn se titwettaq il-kitba fil-buffer.

L-oqsma li jifdal huma ta' natura ta' servizz u ma jirrelatawx mat-tħaddim tal-mekkaniżmu tat-trasferiment tad-dejta.

Hawn taħt hemm messaġġ wieħed bl-isem m1 u blokk tad-data d1.
Nesploraw il-magna VoIP Mediastreamer2. Parti 11
Il-figura li ġejja turi tuple ta’ tliet messaġġi m1, m1_1, m1_2.
Nesploraw il-magna VoIP Mediastreamer2. Parti 11

Funzjonijiet ta' messaġġi mblk_t

Messaġġ ġdid mblk_t maħluqa mill-funzjoni:

mblk_t *allocb(int size, int pri); 

hi tpoġġi messaġġ ġdid fil-memorja mblk_t bi blokk tad-data tad-daqs speċifikat daqs, it-tieni argument - pri mhux użat f'din il-verżjoni tal-librerija. Għandu jibqa' żero. Matul it-tħaddim tal-funzjoni, il-memorja se tiġi allokata għall-istruttura tal-messaġġ il-ġdid u l-funzjoni se tissejjaħ mblk_init(), li se reset l-oqsma kollha tal-istanza maħluqa tal-istruttura u mbagħad, billi tuża l-imsemmija hawn fuq datab_alloc(), se toħloq buffer tad-dejta. Wara dan l-oqsma fl-istruttura se jiġu kkonfigurati:

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

Fl-output nirċievu messaġġ ġdid b'oqsma inizjalizzati u buffer tad-dejta vojt. Biex iżżid id-dejta ma' messaġġ, trid tikkopjaha fil-buffer tal-blokka tad-dejta:

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

fejn data huwa pointer għas-sors tad-dejta, u daqs - id-daqs tagħhom.
imbagħad għandek bżonn taġġorna l-pointer għall-punt tal-kitba sabiex jerġa 'jippunta lejn il-bidu taż-żona ħielsa fil-buffer:

msg->b_wptr = msg->b_wptr + size

Jekk għandek bżonn toħloq messaġġ minn buffer eżistenti, mingħajr ma tikkopja, imbagħad uża l-funzjoni:

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

Il-funzjoni, wara li toħloq il-messaġġ u l-istruttura tal-blokka tad-dejta, se tikkonfigura l-indikaturi tagħha għad-dejta fl-indirizz buff. Dawk. f'dan il-każ, il-buffer tad-dejta ma jinsabx wara l-oqsma tal-header tal-blokka tad-dejta, kif kien il-każ meta ħolqot blokk tad-dejta bil-funzjoni datab_alloc(). Il-buffer bid-dejta mgħoddija lill-funzjoni se tibqa 'fejn kienet, iżda bl-għajnuna ta' indikaturi se tkun mehmuża mal-header maħluq ġdid tal-blokka tad-dejta, u li, għaldaqstant, mal-messaġġ.

Għal messaġġ wieħed mblk_t Diversi blokki tad-dejta jistgħu jiġu konkatenati b'mod sekwenzjali. Dan isir bil-funzjoni:

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

mp — messaġġ li miegħu se jiġi miżjud blokk tad-data ieħor;
data — pointer għall-blokk, li kopja tiegħu se tiżdied mal-messaġġ;
daqs — id-daqs tad-dejta;
kuxxinett — bandiera li d-daqs tal-memorja allokata għandu jkun allinjat tul konfini ta’ 4 byte (il-ikkuttunar se jsir b’żeri).

Jekk ikun hemm biżżejjed spazju fil-buffer tad-dejta tal-messaġġ eżistenti, allura d-dejta l-ġdida titwaħħal wara d-dejta li diġà hemm. Jekk ikun hemm inqas spazju ħieles fil-buffer tad-data tal-messaġġ milli daqs, imbagħad jinħoloq messaġġ ġdid b'daqs tal-buffer suffiċjenti u d-dejta tiġi kkupjata fil-buffer tagħha. Dan huwa messaġġ ġdid, marbut ma' dak oriġinali permezz ta' pointer b_kont. F'dan il-każ, il-messaġġ jinbidel f'tuple.

Jekk għandek bżonn iżżid blokk ieħor ta 'dejta mat-tuple, allura trid tuża l-funzjoni:

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

hi se ssib l-aħħar messaġġ fit-tuple (he has b_kont se jkun null) u se jsejjaħ il-funzjoni għal dan il-messaġġ appendb().

Tista' ssib id-daqs tad-dejta f'messaġġ jew tuple billi tuża l-funzjoni:

int msgdsize(const mblk_t *mp);

se loop permezz tal-messaġġi kollha fit-tuple u jirritorna l-ammont totali ta 'data fil-buffers tad-data ta' dawk il-messaġġi. Għal kull messaġġ, l-ammont ta’ dejta huwa kkalkulat kif ġej:

 mp->b_wptr - mp->b_rptr

Biex tgħaqqad żewġ tupli, uża l-funzjoni:

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

hi tehmeż it-tuple newm għad-denb tat-tuple mp u jirritorna pointer għall-aħħar messaġġ tat-tuple li jirriżulta.

Jekk meħtieġ, tuple jista' jinbidel f'messaġġ wieħed bi blokka waħda ta' dejta; dan isir bil-funzjoni:

void msgpullup(mblk_t *mp,int len);

jekk argument len huwa -1, allura d-daqs tal-buffer allokat jiġi determinat awtomatikament. Jekk len huwa numru pożittiv, se jinħoloq buffer ta' dan id-daqs u d-dejta tal-messaġġ tuple tiġi kkupjata fiha. Jekk il-buffer jispiċċa, l-ikkupjar jieqaf hemm. L-ewwel messaġġ tat-tuple se jirċievi buffer tad-daqs ġdid bid-dejta kkupjata. Il-messaġġi li jifdal se jitħassru u l-memorja terġa 'lura fil-borġ.

Meta tħassar struttura mblk_t l-għadd ta' referenza tal-blokk tad-dejta jitqies jekk, meta ssejjaħ freeb() jirriżulta li jkun żero, allura l-buffer tad-dejta jitħassar flimkien mal-istanza mblk_t, li jindikaha.

Inizjalizzazzjoni tal-oqsma ta' messaġġ ġdid:

void mblk_init(mblk_t *mp);

Iżżid biċċa dejta oħra mal-messaġġ:

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

Jekk id-dejta l-ġdida ma tidħolx fl-ispazju ħieles tal-buffer tad-dejta tal-messaġġ, allura messaġġ maħluq separatament b'buffer tad-daqs meħtieġ huwa mehmuż mal-messaġġ (pointer għall-messaġġ miżjud huwa stabbilit fl-ewwel messaġġ) u l- messaġġ jinbidel fi tuple.

Żieda ta’ biċċa dejta ma’ tuple:

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

Il-funzjoni ssejjaħ appendb() f'linja.

Tgħaqqad żewġ tuples f'wieħed:

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

Messaġġ newm se tkun mehmuża ma mp.

Nagħmlu kopja ta' messaġġ wieħed:

mblk_t *copyb(const mblk_t *mp);

Ikkopjar komplut ta' tuple bil-blokki tad-dejta kollha:

mblk_t *copymsg(const mblk_t *mp);

L-elementi tat-tuple huma kkupjati mill-funzjoni kopjab().

Oħloq kopja faċli ta' messaġġ mblk_t. F'dan il-każ, il-blokk tad-dejta ma jiġix ikkupjat, iżda l-counter ta 'referenza tiegħu jiżdied db_ref:

mblk_t *dupb(mblk_t *mp);

Nagħmlu kopja ħafifa ta 'tuple. Il-blokki tad-dejta mhumiex ikkupjati, il-counters ta' referenza tagħhom biss huma inkrementati db_ref:

mblk_t *dupmsg(mblk_t* m);

L-inkullar tal-messaġġi kollha ta' tuple f'messaġġ wieħed:

void msgpullup(mblk_t *mp,size_t len);

Jekk l-argument len huwa -1, allura d-daqs tal-buffer allokat jiġi determinat awtomatikament.

Tħassar messaġġ, tuple:

void freemsg(mblk_t *mp);

L-għadd ta' referenza tal-blokk tad-dejta jitnaqqas b'wieħed. Jekk jilħaq iż-żero, il-blokka tad-dejta titħassar ukoll.

Kalkolu ta 'l-ammont totali ta' dejta f'messaġġ jew tuple.

size_t msgdsize(const mblk_t *mp);

Irkuprar messaġġ minn denb tal-kju:

mblk_t *ms_queue_peek_last (q);

Il-kopja tal-kontenut tal-oqsma riżervati ta' messaġġ wieħed f'messaġġ ieħor (fil-fatt, dawn l-oqsma fihom bnadar li jintużaw mill-media streamer):

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

Kju kju_t

Il-kju tal-messaġġi fil-media streamer huwa implimentat bħala lista ċirkolari marbuta doppjament. Kull element tal-lista fih pointer għal blokka tad-dejta b'kampjuni tas-sinjali. Jirriżulta li indikaturi biss lejn il-blokka tad-dejta jimxu min-naħa tagħhom, filwaqt li d-dejta nnifisha tibqa' bla moviment. Dawk. links għalihom biss huma mċaqalqa.
Struttura li tiddeskrivi l-kju kju_t, muri hawn taħt:

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

L-istruttura fiha qasam - pointer _q_stopper tip *mblk_t, jindika l-ewwel element (messaġġ) fil-kju. It-tieni qasam tal-istruttura huwa l-counter tal-messaġġi fil-kju.
Il-figura hawn taħt turi kju jismu q1 li fih 4 messaġġi m1, m2, m3, m4.
Nesploraw il-magna VoIP Mediastreamer2. Parti 11
Il-figura li ġejja turi kju jismu q1 li fih 4 messaġġi m1,m2,m3,m4. Il-messaġġ m2 huwa r-ras ta' tuple li fih żewġ messaġġi oħra m2_1 u m2_2.

Nesploraw il-magna VoIP Mediastreamer2. Parti 11

Funzjonijiet biex taħdem bil-kjuwijiet queue_t

Inizjalizzazzjoni tal-kju:

void qinit(queue_t *q);

Qasam _q_stopper (minn hawn 'il quddiem se nsejħulha "tapp") hija initialized mill-funzjoni mblk_init(), l-element preċedenti tiegħu u l-pointer tal-element li jmiss huma aġġustati biex jindikaw lilu nnifsu. Il-counter tal-element tal-kju huwa reset għal żero.

Żieda ta' element ġdid (messaġġi):

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

Element ġdid m huwa miżjud fl-aħħar tal-lista, il-pointers tal-element huma aġġustati sabiex it-tapp isir l-element li jmiss għalih, u jsir l-element preċedenti għat-tapp. Il-counter tal-element tal-kju huwa inkrementat.

Irkupru ta' element mill-kju:

mblk_t * getq(queue_t *q); 

Il-messaġġ li jidher wara li t-tapp jiġi rkuprat, u l-counter tal-element jitnaqqas. Jekk ma jkunx hemm elementi fil-kju ħlief it-tapp, allura 0 jiġi rritornat.

Daħħal messaġġ fi kju:

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

Element mp imdaħħal qabel l-element emp. Jekk emp=0, allura l-messaġġ jiġi miżjud mad-denb tal-kju.

Irkuprar messaġġ mill-kap tal-kju:

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

Il-counter tal-element jitnaqqas.

Qari ta 'pointer għall-ewwel element fil-kju:

mblk_t * peekq(queue_t *q); 

Tneħħi l-elementi kollha mill-kju filwaqt li tħassar l-elementi nfushom:

void flushq(queue_t *q, int how);

argument kif mhux użat. Il-counter tal-element tal-kju huwa ssettjat għal żero.

Makro biex taqra pointer għall-aħħar element tal-kju:

mblk_t * qlast(queue_t *q);

Meta taħdem bil-kjuwijiet tal-messaġġi, kun konxju li meta ċċempel ms_queue_put(q, m) bil-pointer null għall-messaġġ, il-loops funzjoni. Il-programm tiegħek se jiffriża. iġib ruħu bl-istess mod ms_queue_next(q, m).

Filtri li jgħaqqdu

Il-kju deskritt hawn fuq jintuża biex jgħaddi messaġġi minn filtru għal ieħor jew minn filtru għal diversi. Il-filtri u l-konnessjonijiet tagħhom jiffurmaw graff dirett. L-input jew l-output tal-filtru se jissejjaħ il-kelma ġenerali "pin". Biex tiddeskrivi l-ordni li fiha l-filtri huma konnessi ma 'xulxin, l-istreamer tal-midja juża l-kunċett ta' "punt tas-sinjal". Il-punt tas-sinjal huwa l-istruttura _MSCPoint, li fih pointer għall-filtru u n-numru ta 'wieħed mill-brilli tiegħu; għalhekk, jiddeskrivi l-konnessjoni ta' wieħed mill-inputs jew outputs tal-filtru.

Punt tas-sinjal tal-grafika tal-ipproċessar tad-dejta

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

Il-brilli tal-filtri huma nnumerati li jibdew minn żero.

Il-konnessjoni ta 'żewġ pinnijiet minn kju ta' messaġġi hija deskritta mill-istruttura _MSQueue, li fih kju ta' messaġġi u indikaturi għaż-żewġ punti tas-sinjali li jgħaqqad:

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

Aħna se nsejħu din l-istruttura rabta sinjal. Kull filtru tal-media streamer fih tabella ta' links ta' input u tabella ta' links ta' output (MSQueue). Id-daqs tat-tabelli huwa stabbilit meta jinħoloq filtru; diġà għamilna dan bl-użu ta 'varjabbli esportat tat-tip MSFilterDesc, meta żviluppajna l-filtru tagħna stess. Hawn taħt hawn struttura li tiddeskrivi kwalunkwe filtru fi streamer tal-midja, MSFilter:


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;

Wara li kkonnettja l-filtri fil-programm C skont il-pjan tagħna (iżda ma qabbadx it-ticker), b'hekk ħloqna graff dirett, li n-nodi tiegħu huma każijiet tal-istruttura MSFilter, u t-truf huma każijiet ta' links MSQueue.

Wara l-kwinti attivitajiet tal-ticker

Meta għedtlek li t-ticker huwa filtru għas-sors tal-qurdien, ma kinitx il-verità kollha dwarha. Ticker huwa oġġett li jħaddem funzjonijiet fuq l-arloġġ proċess() il-filtri kollha taċ-ċirkwit (graff) li miegħu huwa konness. Meta ngħaqqdu ticker ma' filtru tal-graff fi programm C, nuru lill-ticker il-grafika li se tikkontrolla minn issa 'l quddiem sakemm nitfih. Wara li tikkonnettja, it-ticker jibda jeżamina l-graff fdat f'idejh, u jikkompila lista ta 'filtri li jinkluduha. Sabiex ma "jgħoddx" l-istess filtru darbtejn, timmarka l-filtri misjuba billi tpoġġi kaxxa ta' kontroll fihom tidher. It-tfittxija ssir bl-użu tat-tabelli tal-link li għandu kull filtru.

Matul il-mawra introduttorja tiegħu tal-graff, il-ticker jiċċekkja jekk fost il-filtri hemmx mill-inqas wieħed li jaġixxi bħala sors ta 'blokki tad-dejta. Jekk ma jkunx hemm, allura l-grafika titqies mhux korretta u l-ticker jiġġarraf.

Jekk il-grafika tirriżulta li hija "korretta", għal kull filtru misjub, il-funzjoni tissejjaħ għall-inizjalizzazzjoni proċess minn qabel (). Hekk kif jasal il-mument għaċ-ċiklu tal-ipproċessar li jmiss (kull 10 millisekondi awtomatikament), il-ticker isejjaħ il-funzjoni proċess() għall-filtri tas-sors kollha misjuba qabel, u mbagħad għall-filtri li jifdal fil-lista. Jekk il-filtru għandu links ta 'input, imbagħad iħaddem il-funzjoni proċess() tirrepeti sakemm il-kjuwijiet tal-link tal-input ikunu vojta. Wara dan, jimxi fuq il-filtru li jmiss fil-lista u "scrolls" sakemm il-links tad-dħul huma ħielsa mill-messaġġi. Il-ticker jimxi minn filtru għal filtru sakemm tispiċċa l-lista. Dan itemm l-ipproċessar taċ-ċiklu.

Issa se nerġgħu lura għal tuples u nitkellmu dwar għaliex entità bħal din ġiet miżjuda mal-media streamer. B'mod ġenerali, l-ammont ta 'dejta meħtieġa mill-algoritmu li jopera ġewwa l-filtru ma jikkoinċidix u mhuwiex multiplu tad-daqs tal-buffers tad-dejta riċevuti fl-input. Pereżempju, qed niktbu filtru li jwettaq trasformazzjoni ta 'Fourier veloċi, li b'definizzjoni tista' tipproċessa biss blokki tad-dejta li d-daqs tagħhom huwa qawwa ta 'tnejn. Ħalli jkun 512 għadd. Jekk id-dejta tiġi ġġenerata minn kanal tat-telefon, allura l-buffer tad-dejta ta 'kull messaġġ fl-input ser iġibna 160 kampjun tas-sinjal. Huwa jitħajjar li ma tiġborx data mill-input sakemm l-ammont meħtieġ ta 'data jkun hemm. Iżda f'dan il-każ, se sseħħ ħabta mal-ticker, li mingħajr suċċess tipprova tiskrollja l-filtru sakemm il-link tal-input ikun vojt. Preċedentement, innominajna din ir-regola bħala t-tielet prinċipju tal-filtru. Skont dan il-prinċipju, il-funzjoni tal-proċess() tal-filtru trid tieħu d-dejta kollha mill-kjuwijiet tal-input.

Barra minn hekk, mhux se jkun possibbli li tieħu biss 512-il kampjun mill-input, peress li tista 'tieħu biss blokki sħaħ, i.e. il-filtru se jkollu jieħu 640 kampjun u juża 512 minnhom, il-bqija qabel jakkumula porzjon ġdid ta 'data. Għalhekk, il-filtru tagħna, minbarra x-xogħol ewlieni tiegħu, għandu jipprovdi azzjonijiet awżiljarji għall-ħażna intermedja tad-dejta tal-input. L-iżviluppaturi tal-media streamer u s-soluzzjoni għal din il-problema ġenerali żviluppaw oġġett speċjali - MSBufferizer (bufferer), li jsolvi din il-problema bl-użu ta 'tuples.

Bufferizer (MSBufferizer)

Dan huwa oġġett li jakkumula dejta tal-input ġewwa l-filtru u jibda jissottomettiha għall-ipproċessar hekk kif l-ammont ta 'informazzjoni jkun biżżejjed biex iħaddem l-algoritmu tal-filtru. Waqt li l-buffer ikun qed jakkumula d-dejta, il-filtru se jopera fil-mod idle, mingħajr ma juża s-saħħa tal-ipproċessar tal-proċessur. Iżda hekk kif il-funzjoni tal-qari mill-bufferer tagħti valur ieħor għajr żero, il-funzjoni tal-proċess() tal-filtru tibda tieħu u tipproċessa d-dejta mill-bufferer f'porzjonijiet tad-daqs meħtieġ, sakemm tiġi eżawrita.
Dejta li għadha mhix meħtieġa tibqa' fil-buffer bħala l-ewwel element tat-tuple, li miegħu huma mehmuża blokki sussegwenti ta' data input.

L-istruttura li tiddeskrivi l-buffer:

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

Funzjonijiet biex taħdem ma 'MSBufferizer

Il-ħolqien ta' eżempju ta' buffer ġdid:

MSBufferizer * ms_bufferizer_new(void);

Il-memorja hija allokata, inizjalizzata fi ms_bufferizer_init() u jiġi rritornat pointer.

Funzjoni ta' inizjalizzazzjoni:

void ms_bufferizer_init(MSBufferizer *obj); 

Il-kju qed jinizjalizza q, qasam daqs huwa ssettjat għal żero.

Żid messaġġ:

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

Il-messaġġ m huwa miżjud mal-kju. Id-daqs ikkalkulat tal-blokki tad-dejta huwa miżjud daqs.

It-trasferiment tal-messaġġi kollha mill-kju tad-data tal-link għall-buffer q:

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

It-trasferiment ta' messaġġi minn link q fil-buffer titwettaq bl-użu tal-funzjoni ms_bufferizer_put().

Qari mill-buffer:

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

Jekk id-daqs tad-dejta akkumulat fil-buffer huwa inqas minn dak mitlub (datalen), allura l-funzjoni tirritorna żero, id-data ma tiġix ikkupjata għad-data. Inkella, isir ikkupjar sekwenzjali tad-dejta minn tuples li jinsabu fil-buffer. Wara l-ikkupjar, it-tuple jitħassar u l-memorja tiġi meħlusa. L-ikkupjar jintemm fil-mument meta jiġu kkupjati datalen bytes. Jekk l-ispazju jispiċċa fin-nofs ta 'blokk tad-dejta, allura f'dan il-messaġġ, il-blokka tad-dejta titnaqqas għall-parti mhux ikkupjata li fadal. Il-ħin li jmiss li ċċempel, l-ikkupjar se jkompli minn dan il-punt.

Qari tal-ammont ta' dejta li bħalissa hija disponibbli fil-buffer:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

Jirritorna l-qasam daqs bufferer.

Jarmi parti mid-dejta fil-buffer:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

In-numru speċifikat ta' bytes ta' data jiġu rkuprati u mormija. L-eqdem data tintrema.

Tħassir tal-messaġġi kollha fil-buffer:

void ms_bufferizer_flush(MSBufferizer *obj); 

Il-counter tad-data huwa reset għal żero.

Tħassir tal-messaġġi kollha fil-buffer:

void ms_bufferizer_uninit(MSBufferizer *obj); 

Il-counter mhux reset.

It-tneħħija tal-buffer u l-ħelsien tal-memorja:

void ms_bufferizer_destroy(MSBufferizer *obj);  

Eżempji ta 'użu tal-bufferer jistgħu jinstabu fil-kodiċi tas-sors ta' diversi filtri streamer tal-midja. Pereżempju, fil-filtru MS_L16_ENC, li jirranġa l-bytes fil-kampjuni mill-ordni tan-netwerk għall-ordni tal-ospitanti: l16.c

Fl-artiklu li jmiss, se nħarsu lejn il-kwistjoni tal-istima tat-tagħbija fuq ticker u modi kif niġġieldu t-tagħbija tal-kompjuters eċċessiva fi streamer tal-midja.

Sors: www.habr.com

Żid kumment