Pagsuhid sa Mediastreamer2 VoIP engine. Bahin 11

Ang materyal sa artikulo gikuha gikan sa akong zen channel.

Pagsuhid sa Mediastreamer2 VoIP engine. Bahin 11

Mekanismo sa paglihok sa datos

  • Data block dblk_t
  • Mensahe mblk_t
  • Mga gimbuhaton alang sa pagtrabaho sa mga mensahe mblk_t
  • Pila nga pila_t
  • Mga gimbuhaton alang sa pagtrabaho sa mga pila queue_t
  • Pagkonektar sa mga filter
  • Signal point sa data processing graph
  • Sa luyo sa mga talan-awon nga mga kalihokan sa ticker
  • Bufferizer (MSBufferizer)
  • Mga gimbuhaton alang sa pagtrabaho kauban ang MSBufferizer

Sa ulahi artikulo nakahimo kami sa among kaugalingon nga filter. Kini nga artikulo magpunting sa internal nga mekanismo alang sa pagbalhin sa datos tali sa mga filter sa streamer sa media. Kini magtugot kanimo sa pagsulat sa mga sopistikado nga mga pagsala nga adunay gamay nga paningkamot sa umaabot.

Mekanismo sa paglihok sa datos

Ang paglihok sa datos sa media streamer gihimo gamit ang mga pila nga gihulagway sa istruktura pila_t. Strings sa mga mensahe sama sa mblk_t, nga sa ilang kaugalingon wala maglangkob sa signal data, apan nagsumpay lamang sa nauna, sunod nga mensahe ug sa data block. Dugang pa, gusto nako ilabi na nga hatagan og gibug-aton nga adunay usa usab ka natad alang sa usa ka link sa usa ka mensahe nga parehas nga tipo, nga nagtugot kanimo sa pag-organisar sa usa ka lista sa mga mensahe nga na-link. Tawgon nato ang usa ka grupo sa mga mensahe nga gihiusa sa ingon nga listahan nga usa ka tuple. Busa, ang bisan unsang elemento sa pila mahimong usa ka mensahe mblk_t, ug tingali ang ulo sa usa ka mensahe nga tuple mblk_t. Ang matag tuple nga mensahe mahimong adunay kaugalingong ward data block. Atong hisgutan kung nganong gikinahanglan ang mga tuple sa ulahi.

Sama sa nahisgutan sa ibabaw, ang mensahe mismo wala maglangkob sa usa ka bloke sa datos; sa baylo, kini adunay usa lamang ka pointer sa lugar sa panumduman diin gitipigan ang bloke. Niini nga bahin, ang kinatibuk-ang hulagway sa trabaho sa media streamer nagpahinumdum sa bodega sa pultahan sa cartoon nga "Monsters, Inc.," diin ang mga pultahan (mga link sa data - mga lawak) molihok sa usa ka buang nga tulin sa mga overhead conveyor, samtang ang mga lawak mismo. magpabiling walay lihok.

Karon, ang paglihok subay sa hierarchy gikan sa ubos hangtod sa taas, atong tagdon sa detalye ang nalista nga mga entidad sa mekanismo sa pagpadala sa datos sa media streamer.

Block sa datos dblk_t

Ang data block naglangkob sa usa ka header ug usa ka data buffer. Ang ulohan gihulagway sa mosunod nga istruktura,

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

Ang mga natad sa istruktura adunay mga punto sa sinugdanan sa buffer, ang katapusan sa buffer, ug ang function alang sa pagtangtang sa data buffer. Katapusan nga elemento sa header db_ref — reference counter, kon kini moabot sa zero, kini nagsilbi nga usa ka signal sa pagtangtang niini nga block gikan sa memorya. Kung ang data block gihimo sa function datab_alloc() , unya ang data buffer ibutang sa memorya dayon human sa header. Sa tanan nga uban nga mga kaso, ang buffer mahimong mahimutang sa usa ka lugar nga gilain. Ang data buffer maglangkob sa mga sample sa signal o uban pang datos nga gusto namong iproseso gamit ang mga filter.

Usa ka bag-ong pananglitan sa usa ka data block gihimo gamit ang function:

dblk_t *datab_alloc(int size);

Ingon usa ka parameter sa input, gihatag ang gidak-on sa datos nga itago sa block. Dugang panumduman ang gigahin aron ibutang ang usa ka header - istruktura - sa sinugdanan sa gigahin nga memorya datosb. Apan kung mogamit sa ubang mga gimbuhaton, dili kini kanunay nga mahitabo; sa pipila ka mga kaso, ang data buffer mahimong nahimutang nga gilain gikan sa header sa block sa datos. Sa paghimo sa usa ka istruktura, ang mga natad gi-configure aron ang natad niini db_base nagtudlo sa sinugdanan sa lugar sa datos, ug db_lim hangtod sa kataposan niini. Ihap sa link db_ref gibutang sa usa. Ang data clear function pointer gibutang sa zero.

mensahe mblk_t

Sama sa giingon, ang mga elemento sa pila lahi mblk_t, kini gihubit ingon sa mosunod:

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;

gambalay mblk_t adunay mga punto sa sinugdanan b_prev, b_sunod, nga gikinahanglan aron ma-organisar ang usa ka doble nga na-link nga lista (nga usa ka pila pila_t).

Unya moabut ang pointer b_padayon, nga gigamit lamang kung ang mensahe kabahin sa usa ka tuple. Alang sa katapusang mensahe sa tuple, kini nga pointer nagpabilin nga null.

Sunod atong makita ang usa ka pointer sa usa ka data block b_datap, diin anaa ang mensahe. Gisundan kini sa mga pointer sa lugar sulod sa block data buffer. Natad b_rptr nagtino sa lokasyon diin ang datos gikan sa buffer mabasa. Natad b_wptr nagpaila sa lokasyon diin ang pagsulat sa buffer himuon.

Ang nahabilin nga mga natad usa ka kinaiya sa serbisyo ug wala’y kalabotan sa operasyon sa mekanismo sa pagbalhin sa datos.

Sa ubos usa ka mensahe nga adunay ngalan m1 ug data block d1.
Pagsuhid sa Mediastreamer2 VoIP engine. Bahin 11
Ang mosunod nga numero nagpakita sa usa ka tuple sa tulo ka mga mensahe m1, m1_1, m1_2.
Pagsuhid sa Mediastreamer2 VoIP engine. Bahin 11

Mga gimbuhaton sa pagmemensahe mblk_t

Usa ka bag-ong mensahe mblk_t gihimo sa function:

mblk_t *allocb(int size, int pri); 

gibutang niya ang usa ka bag-ong mensahe sa panumduman mblk_t nga adunay usa ka bloke sa datos sa gitakda nga gidak-on gidak-on, ikaduha nga argumento - pri wala gigamit niini nga bersyon sa librarya. Kinahanglan nga magpabilin kini nga zero. Atol sa operasyon sa function, ang memorya igahin alang sa istruktura sa bag-ong mensahe ug ang function tawgon mblk_init(), nga mag-reset sa tanan nga mga natad sa gibuhat nga pananglitan sa istruktura ug dayon, gamit ang gihisgutan sa ibabaw datab_alloc(), maghimo ug data buffer. Pagkahuman ang mga natad sa istruktura ma-configure:

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

Sa output nakadawat kami usa ka bag-ong mensahe nga adunay mga na-umpisahan nga mga natad ug usa ka walay sulod nga buffer sa datos. Aron makadugang og data sa usa ka mensahe, kinahanglan nimo kining kopyahon sa data block buffer:

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

diin nga data usa ka pointer sa tinubdan sa datos, ug gidak-on - ilang gidak-on.
unya kinahanglan nimo nga i-update ang pointer sa punto sa pagsulat aron kini magpunting pag-usab sa sinugdanan sa libre nga lugar sa buffer:

msg->b_wptr = msg->b_wptr + size

Kung kinahanglan nimo nga maghimo usa ka mensahe gikan sa usa ka naglungtad nga buffer, nga wala pagkopya, unya gamita ang function:

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

Ang function, human sa paghimo sa mensahe ug ang istruktura sa data block, i-configure ang mga pointer niini sa data sa adres buff. Mga. sa kini nga kaso, ang data buffer wala mahimutang human sa header fields sa data block, sama sa nahitabo sa paghimo sa usa ka data block nga adunay function. datab_alloc(). Ang buffer nga adunay data nga gipasa sa function magpabilin kung asa kini, apan sa tabang sa mga pointer kini ilakip sa bag-ong nahimo nga header sa data block, ug kana, sumala niana, sa mensahe.

Sa usa ka mensahe mblk_t Daghang mga bloke sa datos mahimong madugtong nga sunud-sunod. Gihimo kini pinaagi sa function:

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

mp — usa ka mensahe diin idugang ang lain nga bloke sa datos;
nga data — pointer sa block, usa ka kopya nga idugang sa mensahe;
gidak-on - gidak-on sa datos;
pad — usa ka bandila nga ang gidak-on sa gigahin nga panumduman kinahanglan ipahiangay sa usa ka 4-byte nga utlanan (padding pagabuhaton sa mga sero).

Kung adunay igo nga wanang sa naglungtad nga buffer data sa mensahe, nan ang bag-ong datos idikit sa luyo sa datos nga naa na. Kung adunay gamay nga libre nga wanang sa buffer data sa mensahe kaysa gidak-on, unya usa ka bag-ong mensahe ang gihimo nga adunay igo nga gidak-on sa buffer ug ang datos gikopya sa buffer niini. Kini usa ka bag-ong mensahe, nalambigit sa orihinal gamit ang usa ka pointer b_padayon. Sa kini nga kaso, ang mensahe mahimong usa ka tuple.

Kung kinahanglan nimo nga idugang ang lain nga bloke sa datos sa tuple, nan kinahanglan nimo nga gamiton ang function:

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

makit-an niya ang katapusang mensahe sa tuple (naa siya b_padayon mahimong null) ug tawagan ang function alang niini nga mensahe appendb().

Mahimo nimong mahibal-an ang gidak-on sa datos sa usa ka mensahe o tuple gamit ang function:

int msgdsize(const mblk_t *mp);

kini mag-loop sa tanang mga mensahe sa tuple ug ibalik ang kinatibuk-ang gidaghanon sa datos sa data buffers niadtong mga mensahe. Alang sa matag mensahe, ang gidaghanon sa datos gikalkulo sama sa mosunod:

 mp->b_wptr - mp->b_rptr

Aron makombinar ang duha ka tuple, gamita ang function:

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

iyang gidugang ang tuple newm ngadto sa ikog sa tuple mp ug ibalik ang usa ka pointer sa katapusang mensahe sa resulta nga tuple.

Kung gikinahanglan, ang usa ka tuple mahimo nga usa ka mensahe nga adunay usa ka bloke sa datos; kini gihimo pinaagi sa function:

void msgpullup(mblk_t *mp,int len);

kon argumento len mao ang -1, dayon ang gidak-on sa gigahin nga buffer awtomatik nga matino. Kung len usa ka positibo nga numero, usa ka buffer sa kini nga gidak-on pagabuhaton ug ang data sa tuple nga mensahe makopya niini. Kung mahurot ang buffer, ang pagkopya mohunong didto. Ang unang mensahe sa tuple makadawat og bag-ong gidak-on nga buffer nga adunay gikopya nga datos. Ang nahabilin nga mga mensahe mapapas ug ang memorya ibalik sa pundok.

Sa pagtangtang sa usa ka istruktura mblk_t ang ihap sa pakisayran sa data block gikonsiderar kung, kung nagtawag libreb() kini nahimo nga zero, unya ang data buffer matangtang kauban ang pananglitan mblk_t, nga nagpunting niini.

Pagsugod sa mga natad sa bag-ong mensahe:

void mblk_init(mblk_t *mp);

Pagdugang og laing piraso sa datos sa mensahe:

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

Kung ang bag-ong datos dili mohaum sa libre nga wanang sa buffer data sa mensahe, nan ang usa ka gilain nga gibuhat nga mensahe nga adunay buffer sa gikinahanglan nga gidak-on gilakip sa mensahe (usa ka pointer sa gidugang nga mensahe ang gibutang sa una nga mensahe) ug ang ang mensahe nahimong tuple.

Pagdugang usa ka piraso sa datos sa usa ka tuple:

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

Ang function nagtawag sa appendb() sa usa ka loop.

Paghiusa sa duha ka tuple sa usa:

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

mensahe newm idugtong sa mp.

Paghimo og kopya sa usa ka mensahe:

mblk_t *copyb(const mblk_t *mp);

Kompleto nga pagkopya sa usa ka tuple nga adunay tanan nga mga bloke sa datos:

mblk_t *copymsg(const mblk_t *mp);

Ang mga elemento sa tuple gikopya sa function copyb().

Paghimo og sayon ​​nga kopya sa usa ka mensahe mblk_t. Sa kini nga kaso, ang data block dili gikopya, apan ang reference counter niini gidugangan db_ref:

mblk_t *dupb(mblk_t *mp);

Paghimo og gaan nga kopya sa usa ka tuple. Ang mga bloke sa datos dili gikopya, ang ilang mga reference counter lamang ang gidugangan db_ref:

mblk_t *dupmsg(mblk_t* m);

Pagdugtong sa tanang mensahe sa usa ka tuple ngadto sa usa ka mensahe:

void msgpullup(mblk_t *mp,size_t len);

Kung ang argumento len mao ang -1, dayon ang gidak-on sa gigahin nga buffer awtomatik nga matino.

Pagtangtang sa usa ka mensahe, tuple:

void freemsg(mblk_t *mp);

Ang ihap sa pakisayran sa data block gikunhoran sa usa. Kung kini moabot sa zero, ang data block mapapas usab.

Pagkalkula sa kinatibuk-ang gidaghanon sa datos sa usa ka mensahe o tuple.

size_t msgdsize(const mblk_t *mp);

Pagkuha og mensahe gikan sa ikog sa pila:

mblk_t *ms_queue_peek_last (q);

Pagkopya sa mga sulod sa gireserba nga mga natad sa usa ka mensahe ngadto sa laing mensahe (sa pagkatinuod, kini nga mga field adunay mga bandila nga gigamit sa media streamer):

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

Pag-pila pila_t

Ang pila nga mensahe sa streamer sa media gipatuman ingon usa ka lingin nga doble nga na-link nga lista. Ang matag elemento sa lista adunay usa ka pointer sa usa ka bloke sa datos nga adunay mga sample sa signal. Kini nahimo nga ang mga pointer lamang sa data block molihok sa baylo, samtang ang data mismo nagpabilin nga wala’y paglihok. Mga. ang mga link lang sa ila ang ginabalhin.
Istruktura nga naghulagway sa pila pila_t, gipakita sa ubos:

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

Ang istruktura naglangkob sa usa ka uma - usa ka pointer _q_stopper type *mblk_t, kini nagpunting sa unang elemento (mensahe) sa pila. Ang ikaduhang natad sa istruktura mao ang counter sa mga mensahe sa pila.
Ang numero sa ubos nagpakita sa pila nga ginganlag q1 nga adunay 4 nga mga mensahe m1, m2, m3, m4.
Pagsuhid sa Mediastreamer2 VoIP engine. Bahin 11
Ang mosunod nga numero nagpakita sa usa ka pila nga ginganlag q1 nga adunay 4 nga mga mensahe m1,m2,m3,m4. Ang mensahe nga m2 mao ang ulo sa usa ka tuple nga adunay duha pa ka mensahe nga m2_1 ug m2_2.

Pagsuhid sa Mediastreamer2 VoIP engine. Bahin 11

Mga gimbuhaton alang sa pagtrabaho sa mga pila queue_t

Pagsugod sa pila:

void qinit(queue_t *q);

uma _q_stopper (human niini tawgon nato kini nga "stopper") gisugdan pinaagi sa function mblk_init(), ang nauna nga elemento niini ug ang sunod nga pointer sa elemento gi-adjust aron ipunting ang kaugalingon. Ang counter sa elemento sa pila gi-reset sa zero.

Pagdugang og bag-ong elemento (mensahe):

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

Bag-ong elemento m idugang sa katapusan sa lista, ang mga pointer sa elemento gi-adjust aron ang stopper mahimong sunod nga elemento alang niini, ug kini mahimong nauna nga elemento para sa stopper. Ang queue element counter gidugangan.

Pagkuha sa usa ka elemento gikan sa pila:

mblk_t * getq(queue_t *q); 

Ang mensahe nga moabut human ang stopper makuha, ug ang elemento counter gikunhoran. Kung walay mga elemento sa pila gawas sa stopper, unya ang 0 ibalik.

Pagsulud sa usa ka mensahe sa usa ka pila:

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

Elemento mp gisulod sa atubangan sa elemento EMP. Kon EMP=0, unya ang mensahe idugang sa ikog sa pila.

Pagkuha og mensahe gikan sa ulohan sa pila:

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

Ang elemento nga counter gipaubos.

Pagbasa sa usa ka pointer sa unang elemento sa pila:

mblk_t * peekq(queue_t *q); 

Pagtangtang sa tanan nga mga elemento gikan sa pila samtang gitangtang ang mga elemento mismo:

void flushq(queue_t *q, int how);

argumento sa unsa nga paagi wala gigamit. Ang queue element counter gitakda sa zero.

Macro alang sa pagbasa sa usa ka pointer sa katapusang elemento sa pila:

mblk_t * qlast(queue_t *q);

Kung nagtrabaho kauban ang mga pila sa mensahe, hinumdomi nga kung nagtawag ka ms_queue_put(q, m) nga adunay null pointer sa mensahe, ang function loops. Ang imong programa mag-freeze. parehas ang paggawi ms_queue_next(q, m).

Pagkonektar sa mga filter

Ang pila nga gihulagway sa ibabaw gigamit sa pagpasa sa mga mensahe gikan sa usa ka filter ngadto sa lain o gikan sa usa ngadto sa daghang mga filter. Ang mga filter ug ang ilang mga koneksyon nagporma og usa ka direkta nga graph. Ang input o output sa filter tawgon nga kinatibuk-ang pulong nga "pin". Aron ihulagway ang han-ay diin ang mga filter konektado sa usag usa, ang media streamer naggamit sa konsepto sa usa ka "signal point". Ang punto sa signal mao ang istruktura _MSCPpoint, nga adunay usa ka pointer sa filter ug ang numero sa usa sa mga pin niini; sumala niana, kini naghulagway sa koneksyon sa usa sa mga input o output sa filter.

Signal point sa data processing graph

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

Ang mga filter pin ginumero gikan sa zero.

Ang koneksyon sa duha ka mga lagdok pinaagi sa usa ka pila nga mensahe gihulagway sa istruktura _MSQueue, nga adunay sulud nga pila sa mensahe ug mga punto sa duha nga mga punto sa signal nga gikonektar niini:

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

Tawgon nato kini nga istruktura nga usa ka signal link. Ang matag media streamer filter adunay usa ka lamesa sa mga link sa input ug usa ka lamesa sa mga link sa output (MSQueue). Ang gidak-on sa mga lamesa gitakda sa paghimo sa usa ka filter; nahimo na namo kini gamit ang usa ka gi-eksport nga variable sa tipo MSFilterDesc, sa dihang naghimo kami sa among kaugalingong filter. Sa ubos usa ka istruktura nga naghulagway sa bisan unsang filter sa usa ka streamer sa media, 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;

Human namo makonektar ang mga filter sa programa sa C subay sa among plano (apan wala magkonektar sa ticker), sa ingon naghimo kami og usa ka direkta nga graph, ang mga node niini mga pananglitan sa istruktura. MSFilter, ug ang mga ngilit maoy mga pananglitan sa mga sumpay MSQueue.

Sa luyo sa mga talan-awon nga mga kalihokan sa ticker

Sa dihang gisultihan ko ikaw nga ang ticker usa ka filter alang sa tinubdan sa mga ticks, dili kini ang tibuok nga kamatuoran mahitungod niini. Ang ticker usa ka butang nga nagpadagan sa mga function sa orasan proseso() tanan nga mga filter sa sirkito (graph) diin kini konektado. Kung atong ikonektar ang usa ka ticker sa usa ka graph filter sa usa ka C nga programa, atong ipakita sa ticker ang graph nga kini kontrolahon gikan karon hangtud nga atong i-off kini. Human sa pagkonektar, ang ticker magsugod sa pagsusi sa graph nga gisalig sa pag-atiman niini, pag-compile sa usa ka lista sa mga filter nga naglakip niini. Aron dili "ihap" ang parehas nga pagsala sa makaduha, kini nagtimaan sa mga nakit-an nga mga pagsala pinaagi sa pagbutang sa usa ka checkbox niini. nakita. Ang pagpangita gihimo gamit ang link nga mga lamesa nga adunay matag filter.

Atol sa pasiuna nga paglibot niini sa graph, gisusi sa ticker kung taliwala sa mga filter adunay labing menos usa nga naglihok ingon usa ka gigikanan sa mga bloke sa datos. Kung wala, ang graph giisip nga dili husto ug ang ticker nahagsa.

Kung ang graph nahimo nga "husto", alang sa matag nakit-an nga filter, ang function gitawag alang sa pagsugod preprocess(). Sa diha nga ang takna moabut alang sa sunod nga pagproseso cycle (matag 10 milliseconds sa default), ang ticker nagtawag sa function proseso() alang sa tanan nga nakit-an kaniadto nga gigikanan nga mga pagsala, ug dayon alang sa nahabilin nga mga pagsala sa lista. Kung ang filter adunay mga link sa input, dayon ipadagan ang function proseso() gisubli hangtud nga ang mga linya sa input link walay sulod. Pagkahuman niini, mobalhin kini sa sunod nga filter sa lista ug "i-scroll" kini hangtod ang mga link sa pag-input wala’y mga mensahe. Ang ticker mobalhin gikan sa filter ngadto sa filter hangtod matapos ang listahan. Nakompleto niini ang pagproseso sa siklo.

Karon mobalik kami sa mga tuple ug maghisgot kung ngano nga ang ingon nga entidad gidugang sa streamer sa media. Sa kinatibuk-an, ang gidaghanon sa datos nga gikinahanglan sa algorithm nga nag-operate sulod sa filter dili motakdo ug dili usa ka multiple sa gidak-on sa data buffers nga nadawat sa input. Pananglitan, nagsulat kami og usa ka filter nga naghimo sa usa ka paspas nga pagbag-o sa Fourier, nga pinaagi sa kahulugan mahimo lamang nga magproseso sa mga bloke sa datos kansang gidak-on usa ka gahum sa duha. Himoa kini nga 512 nga ihap. Kung ang datos gihimo sa usa ka channel sa telepono, nan ang data buffer sa matag mensahe sa input magdala kanato og 160 nga mga sample sa signal. Makatintal nga dili kolektahon ang datos gikan sa input hangtod ang gikinahanglan nga kantidad sa datos naa didto. Apan sa kini nga kaso, usa ka bangga ang mahitabo sa ticker, nga dili molampos nga mosulay sa pag-scroll sa filter hangtod nga wala’y sulod ang input link. Kaniadto, among gitudlo kini nga lagda isip ikatulo nga prinsipyo sa filter. Sumala niini nga prinsipyo, ang proseso sa filter() function kinahanglan nga mokuha sa tanang data gikan sa input queues.

Dugang pa, dili mahimo ang pagkuha lamang sa 512 nga mga sample gikan sa input, tungod kay mahimo ra nimo makuha ang tibuuk nga mga bloke, i.e. ang filter kinahanglang mokuha ug 640 ka sample ug gamiton ang 512 niini, ang nahibilin sa dili pa magtigom ug bag-ong bahin sa datos. Busa, ang atong filter, dugang pa sa iyang nag-unang trabaho, kinahanglan nga maghatag ug auxiliary nga mga aksyon alang sa intermediate nga pagtipig sa input data. Ang mga nag-develop sa media streamer ug solusyon niining kinatibuk-ang problema nakamugna og usa ka espesyal nga butang - MSBufferizer (bufferer), nga nagsulbad niini nga problema gamit ang mga tuple.

Bufferizer (MSBufferizer)

Kini usa ka butang nga magtigum sa input data sa sulod sa filter ug magsugod sa pagsumite niini alang sa pagproseso sa diha nga ang gidaghanon sa impormasyon igo na sa pagpadagan sa filter algorithm. Samtang ang buffer nagtigum og mga datos, ang filter molihok sa idle mode, nga dili mogamit sa gahum sa pagproseso sa processor. Apan sa diha nga ang pagbasa function gikan sa bufferer mibalik sa usa ka bili gawas sa zero, ang proseso () function sa filter magsugod sa pagkuha ug pagproseso sa data gikan sa bufferer sa mga bahin sa gikinahanglan nga gidak-on, hangtud nga kini mahurot.
Ang datos nga wala pa gikinahanglan nagpabilin sa buffer isip unang elemento sa tuple, diin ang sunod nga mga bloke sa input data gilakip.

Ang istruktura nga naghulagway sa buffer:

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

Mga gimbuhaton alang sa pagtrabaho kauban ang MSBufferizer

Paghimo og bag-ong buffer nga pananglitan:

MSBufferizer * ms_bufferizer_new(void);

Gigahin ang memorya, gisugdan sa ms_bufferizer_init() ug ang usa ka pointer gibalik.

Pagsugod sa function:

void ms_bufferizer_init(MSBufferizer *obj); 

Nagsugod na ang pila q, uma gidak-on gibutang sa zero.

Pagdugang og mensahe:

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

Ang mensahe m gidugang sa pila. Gidugang ang kalkulado nga gidak-on sa mga bloke sa datos gidak-on.

Pagbalhin sa tanang mensahe gikan sa link data queue ngadto sa buffer q:

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

Pagbalhin sa mga mensahe gikan sa usa ka link q sa buffer gihimo gamit ang function ms_bufferizer_put().

Pagbasa gikan sa buffer:

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

Kung ang gidak-on sa datos nga natipon sa buffer mas gamay kaysa sa gihangyo (datalen), unya ang function mobalik sa zero, ang datos dili makopya sa datos. Kung dili, ang sunud-sunod nga pagkopya sa datos gikan sa mga tuple nga nahimutang sa buffer gihimo. Human sa pagkopya, ang tuple mapapas ug ang panumduman mapagawas. Ang pagkopya matapos sa higayon nga ang datalen bytes makopya. Kung mahurot ang wanang sa tunga sa usa ka bloke sa datos, nan sa kini nga mensahe, ang bloke sa datos maminusan sa nahabilin nga wala makopya nga bahin. Sa sunod higayon nga motawag ka, ang pagkopya magpadayon gikan niining puntoha.

Pagbasa sa gidaghanon sa datos nga anaa karon sa buffer:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

Ibalik ang uma gidak-on bufferer.

Paglabay sa bahin sa datos sa buffer:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

Ang espesipikong gidaghanon sa mga byte sa datos gikuha ug gilabay. Ang labing karaan nga datos gilabay.

Pagtangtang sa tanang mensahe sa buffer:

void ms_bufferizer_flush(MSBufferizer *obj); 

Ang data counter gi-reset sa zero.

Pagtangtang sa tanang mensahe sa buffer:

void ms_bufferizer_uninit(MSBufferizer *obj); 

Ang counter wala ma-reset.

Pagtangtang sa buffer ug pagpahigawas sa memorya:

void ms_bufferizer_destroy(MSBufferizer *obj);  

Ang mga pananglitan sa paggamit sa bufferer makita sa source code sa daghang media streamer filters. Pananglitan, sa MS_L16_ENC filter, nga nag-usab sa mga byte sa mga sample gikan sa network order ngadto sa host order: l16.c

Sa sunod nga artikulo, atong tan-awon ang isyu sa ticker load estimation ug unsaon pag-atubang sa sobra nga computing load sa media streamer.

Source: www.habr.com

Idugang sa usa ka comment