Ihlola injini ye-Mediastreamer2 VoIP. Ingxenye 11

Indaba ye-athikili ithathwe kweyami ishaneli zen.

Ihlola injini ye-Mediastreamer2 VoIP. Ingxenye 11

Indlela yokuhambisa idatha

  • Ibhulokhi yedatha dblk_t
  • Umlayezo mblk_t
  • Imisebenzi yokusebenza ngemilayezo mblk_t
  • Ulayini_t
  • Imisebenzi yokusebenza ngolayini ulayini_t
  • Ixhuma izihlungi
  • Iphoyinti lesiginali legrafu yokucubungula idatha
  • Ngemuva kwezigcawu imisebenzi yethikha
  • I-Bufferizer (MSBufferizer)
  • Imisebenzi yokusebenza nge-MSBufferizer

Ekugcineni isihloko sizenzele esethu isihlungi. Lesi sihloko sizogxila endleleni yangaphakathi yokuhambisa idatha phakathi kwezihlungi ze-media streamer. Lokhu kuzokuvumela ukuthi ubhale izihlungi eziyinkimbinkimbi ngomzamo omncane ngokuzayo.

Indlela yokuhambisa idatha

Ukuhambisa idatha ku-media streamer kwenziwa kusetshenziswa imigqa echazwe isakhiwo ulayini_t. Inqwaba yemiyalezo efana mblk_t, zona ngokwazo aziqukethe idatha yesignali, kodwa izixhumanisi zangaphambilini, umlayezo olandelayo kanye nebhulokhi yedatha. Ngaphezu kwalokho, ngifuna ukugcizelela ngokukhethekile ukuthi kukhona nenkambu yesixhumanisi somlayezo wohlobo olufanayo, okuvumela ukuthi uhlele uhlu oluxhumeke olulodwa lwemilayezo. Sizobiza iqembu lemiyalezo elihlanganiswe uhlu olunjalo ngokuthi i-tuple. Ngakho, noma iyiphi ingxenye yomugqa ingaba umlayezo owodwa mblk_t, futhi mhlawumbe nenhloko yomlayezo we-tuple mblk_t. Umlayezo we-tuple ngamunye ungaba nebhulokhi yawo yedatha yesigceme. Sizoxoxa ngokuthi kungani ama-tuples edingeka kamuva.

Njengoba kushiwo ngenhla, umlayezo ngokwawo awunalo ibhulokhi yedatha; esikhundleni salokho, uqukethe kuphela i-pointer endaweni yememori lapho kugcinwa khona ibhulokhi. Kule ngxenye, isithombe sisonke somsebenzi womsakazo wemidiya usikhumbuza indawo yokugcina impahla ekhathuni ethi “Monsters, Inc.,” lapho iminyango (izixhumanisi zamakamelo - amagumbi) ihamba ngesivinini esiphambene eduze kwamaconveyor, kuyilapho amagumbi ngokwawo. hlala unganyakazi.

Manje, sihamba ngohlelo ukusuka phansi kuye phezulu, ake sicabangele ngokuningiliziwe izinhlangano ezisohlwini zendlela yokudlulisa idatha kusisakaza semidiya.

Ibhulokhi yedatha dblk_t

Ibhulokhi yedatha iqukethe unhlokweni kanye nesigcinalwazi sedatha. Unhlokweni uchazwa yisakhiwo esilandelayo,

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

Izinkambu zesakhiwo ziqukethe izikhombi eziya ekuqaleni kwebhafa, ekugcineni kwebhafa, nomsebenzi wokususa isigcinalwazi sedatha. Isici sokugcina kunhlokweni db_ref — ikhawunta yereferensi, uma ifinyelela ku-zero, lokhu kusebenza njengesignali yokususa le block kumemori. Uma i-data block idalwe umsebenzi idathab_alloc() , bese isigcinalwazi sedatha sizofakwa kumemori ngokushesha ngemva kwesihloko. Kuzo zonke ezinye izimo, i-buffer ingatholakala ndawana thize ngokuhlukana. Isigcinalwazi sedatha sizoqukatha amasampula esignali noma enye idatha esifuna ukuyicubungula ngezihlungi.

Isenzakalo esisha sokuvimba idatha senziwa kusetshenziswa umsebenzi:

dblk_t *datab_alloc(int size);

Njengepharamitha yokufaka, inikezwa usayizi wedatha ibhulokhi ezoyigcina. Imemori eyengeziwe yabelwe ukuze kubekwe unhlokweni - isakhiwo - ekuqaleni kwememori eyabiwe idathab. Kodwa uma usebenzisa eminye imisebenzi, lokhu akwenzeki ngaso sonke isikhathi, kwezinye izimo, isigcinalwazi sedatha singase sibekwe ngokuhlukene nesihloko sebhulokhi yedatha. Lapho udala isakhiwo, amasimu amisiwe ukuze insimu yawo db_base ikhombe ekuqaleni kwendawo yedatha, futhi db_lim kuze kube sekupheleni kwayo. Isibalo sesixhumanisi db_ref isethwe kokukodwa. Isikhombi sokusebenza esicacile sedatha sisethwe ukuze sithi ziro.

Umlayezo mblk_t

Njengoba kushiwo, izici zomugqa ziwuhlobo mblk_t, kuchazwa kanje:

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;

isakhiwo mblk_t iqukethe izinkomba ekuqaleni b_prev, b_okulandelayo, okudingekayo ukuze uhlele uhlu oluxhunywe kabili (okungumugqa ulayini_t).

Bese kufika i-pointer b_qhubeka, esetshenziswa kuphela uma umlayezo uyingxenye ye-tuple. Ngomlayezo wokugcina ku-tuple, lesi sikhombi sihlala singenalutho.

Okulandelayo sibona isikhombisi sebhulokhi yedatha b_idathap, umlayezo okhona. Ilandelwa yizinkomba zendawo engaphakathi kwe-block data buffer. Inkambu b_rptr icacisa indawo lapho kuzofundwa khona idatha evela kusigcinalwazi. Inkambu b_wptr ikhombisa indawo okuzobhalelwa kuyo kusigcinalwazi.

Izinkambu ezisele ziwuhlobo lwesevisi futhi azihlobene nokusebenza kwendlela yokudlulisa idatha.

Ngezansi kunomlayezo owodwa onegama m1 kanye ne-data block d1.
Ihlola injini ye-Mediastreamer2 VoIP. Ingxenye 11
Umfanekiso olandelayo ubonisa ikhophi yemiyalezo emithathu m1, m1_1, m1_2.
Ihlola injini ye-Mediastreamer2 VoIP. Ingxenye 11

Imisebenzi yemiyalezo mblk_t

Umlayezo omusha mblk_t idalwe ngomsebenzi:

mblk_t *allocb(int size, int pri); 

ubeka umlayezo omusha enkumbulweni mblk_t ngebhulokhi yedatha yosayizi oshiwo usayizi, impikiswano yesibili - pri ayisetshenziswanga kule nguqulo yelabhulali. Kufanele ihlale inguziro. Ngesikhathi sokusebenza komsebenzi, inkumbulo izokwabelwa isakhiwo somlayezo omusha futhi umsebenzi uzobizwa mblk_init(), ezosetha kabusha zonke izinkambu zesibonelo esidaliwe sesakhiwo bese, kusetshenziswa lokhu okukhulunywe ngenhla idathab_alloc(), izodala isilondolozi sedatha. Ngemva kwalokho izinkambu esakhiweni zizolungiselelwa:

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

Kokukhiphayo sithola umlayezo omusha onezinkambu eziqalisiwe kanye nesigcinalwazi esingenalutho. Ukwengeza idatha kumlayezo, udinga ukuyikopishela kusigcinalwazi sebhulokhi yedatha:

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

kuphi idatha iyisikhombi somthombo wedatha, futhi usayizi - usayizi wabo.
khona-ke udinga ukubuyekeza i-pointer endaweni yokubhala ukuze iphinde ikhombe ekuqaleni kwendawo yamahhala ku-buffer:

msg->b_wptr = msg->b_wptr + size

Uma udinga ukudala umlayezo ovela kusigcinalwazi esikhona, ngaphandle kokukopisha, bese usebenzisa umsebenzi:

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

Umsebenzi, ngemuva kokudala umlayezo kanye nesakhiwo sebhulokhi yedatha, uzomisa izinkomba zayo kudatha ekhelini. buff. Labo. kulesi simo, isilondolozi sedatha asitholakali ngemva kwezinkambu zesihloko sebhulokhi yedatha, njengoba kwakunjalo lapho udala ibhulokhi yedatha ngomsebenzi. idathab_alloc(). I-buffer enedatha edluliselwe emsebenzini izohlala lapho yayikhona, kodwa ngosizo lwezikhombisi izonamathiselwa kunhlokweni esanda kwakhiwa yebhulokhi yedatha, nokuthi, ngokufanele, kumlayezo.

Emlayezweni owodwa mblk_t Amabhulokhi wedatha amaningana angahlanganiswa ngokulandelana. Lokhu kwenziwa ngumsebenzi:

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

mp — umyalezo okuzongezwa kuwo enye i-data block;
idatha — i-pointer block, ikhophi yayo ezongezwa emyalezweni;
usayizi - usayizi wedatha;
i-pad — ifulegi ukuthi usayizi wememori eyabiwe kufanele uqondaniswe nomngcele wamabhayithi angu-4 (ukupheda kuzokwenziwa ngoziro).

Uma kunesikhala esanele kubhafa yedatha yomlayezo ekhona, idatha entsha izonamathiselwa ngemuva kwedatha esivele ikhona. Uma kunesikhala esincane esikhululekile kubhafa yedatha yomlayezo kune usayizi, bese kwakhiwa umlayezo omusha ngosayizi owanele webhafa futhi idatha ikopishelwe kubhafa yayo. Lona umlayezo omusha, oxhunywe kowangempela kusetshenziswa isikhombi b_qhubeka. Kulokhu, umlayezo uphenduka i-tuple.

Uma udinga ukwengeza enye ibhulokhi yedatha ku-tuple, kuzomele usebenzise umsebenzi:

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

uzothola umlayezo wokugcina ku-tuple (unayo b_qhubeka izoba yize) futhi izobiza umsebenzi walo mlayezo appendb().

Ungathola usayizi wedatha kumlayezo noma ku-tuple usebenzisa umsebenzi:

int msgdsize(const mblk_t *mp);

izongena kuyo yonke imilayezo eku-tuple futhi ibuyisele inani eliphelele ledatha kumabhafa wedatha yaleyo milayezo. Kumlayezo ngamunye, inani ledatha libalwa ngale ndlela elandelayo:

 mp->b_wptr - mp->b_rptr

Ukuhlanganisa ama-tuples amabili, sebenzisa umsebenzi:

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

ehlanganisa i-tuple entsham emsileni we-tuple mp futhi ibuyisela isikhombisi kumlayezo wokugcina we-tuple ewumphumela.

Uma kunesidingo, i-tuple ingaguqulwa ibe umlayezo owodwa onebhulokhi eyodwa yedatha; lokhu kwenziwa umsebenzi:

void msgpullup(mblk_t *mp,int len);

uma ingxabano ilensi ngu-1, bese usayizi wesigcinalwazi esinikeziwe unqunywa ngokuzenzakalelayo. Uma ilensi iyinombolo ephozithivu, isilondolozi salo sayizi sizokwenziwa futhi idatha yomlayezo we-tuple izokopishelwa kuyo. Uma isilondolozi siphela, ukukopisha kuzoma lapho. Umlayezo wokuqala we-tuple uzothola ibhafa kasayizi omusha nedatha ekopishiwe. Imilayezo esele izosuswa futhi inkumbulo ibuyiselwe enqwabeni.

Uma ususa isakhiwo mblk_t ukubalwa kwereferensi yebhulokhi yedatha kucatshangelwa uma, lapho ushaya ucingo khulula() kuvele kunguziro, bese isigcinalwazi sedatha siyasuswa kanye nesibonelo mblk_t, okukhomba khona.

Ukuqala izinkambu zomlayezo omusha:

void mblk_init(mblk_t *mp);

Ukwengeza olunye ucezu lwedatha kumlayezo:

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

Uma idatha entsha ingangeni endaweni ekhululekile yesigcinalwazi sedatha yomlayezo, kusho ukuthi umlayezo odalwe ngokwehlukana onesigcina sesilondolozi sosayizi odingekayo unamathiselwe kumlayezo (isikhombi somlayezo owengeziwe sisethwe kumlayezo wokuqala) futhi umyalezo uphenduka i-tuple.

Ukwengeza ucezu lwedatha ku-tuple:

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

Umsebenzi ubiza i-appendb() ku-loop.

Ukuhlanganisa ama-tuples amabili abe munye:

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

Umlayezo entsham izonamathiselwa ku mp.

Ukwenza ikhophi yomlayezo owodwa:

mblk_t *copyb(const mblk_t *mp);

Qedela ukukopishwa kwe-tuple ngawo wonke amabhulokhi wedatha:

mblk_t *copymsg(const mblk_t *mp);

Izakhi ze-tuple zikopishwa umsebenzi ikhophib().

Dala ikhophi elula yomlayezo mblk_t. Kulesi simo, ibhulokhi yedatha ayikopishwa, kodwa isibali sayo sereferensi siyanda db_ref:

mblk_t *dupb(mblk_t *mp);

Ukwenza ikhophi engasindi ye-tuple. Amabhulokhi wedatha awakopishwa, izibali zawo eziyinkomba kuphela ziyandiswa db_ref:

mblk_t *dupmsg(mblk_t* m);

Ukunamathisela yonke imilayezo ye-tuple kumlayezo owodwa:

void msgpullup(mblk_t *mp,size_t len);

Uma ingxabano ilensi ngu -1, bese usayizi wesigcinalwazi esinikeziwe unqunywa ngokuzenzakalelayo.

Isusa umlayezo, bhala:

void freemsg(mblk_t *mp);

Isibalo sesithenjwa sebhulokhi yedatha sincishiswa ngesisodwa. Uma ifinyelela ku-zero, i-data block nayo iyasuswa.

Ukubalwa kwesamba senani ledatha kumlayezo noma umbhalo.

size_t msgdsize(const mblk_t *mp);

Ibuyisa umlayezo ovela emsileni wolayini:

mblk_t *ms_queue_peek_last (q);

Ukukopisha okuqukethwe kwezinkambu ezigodliwe zomyalezo owodwa komunye umlayezo (eqinisweni, lezi zindawo ziqukethe amafulegi asetshenziswa umsakazi wemidiya):

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

Jika ulayini_t

Ulayini wemilayezo ku-media streamer usetshenziswa njengohlu oluxhunywe kabili oluyindilinga. Isici sohlu ngasinye siqukethe isikhombi sebhulokhi yedatha enamasampuli esignali. Kuvela ukuthi izinkomba kuphela zebhulokhi yedatha zihamba ngokushintshana, kuyilapho idatha ngokwayo ihlala inganyakazi. Labo. izixhumanisi kuzo kuphela ezisusiwe.
Isakhiwo esichaza ulayini ulayini_t, kuboniswe ngezansi:

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

Isakhiwo siqukethe inkambu - i-pointer _q_isivimbeli thayipha *mblk_t, ikhomba into yokuqala (umlayezo) kulayini. Umkhakha wesibili wesakhiwo uyisibali semiyalezo emgqeni.
Isibalo esingezansi sibonisa umugqa oqanjwe ngokuthi q1 oqukethe imilayezo engu-4 m1, m2, m3, m4.
Ihlola injini ye-Mediastreamer2 VoIP. Ingxenye 11
Umfanekiso olandelayo ubonisa umugqa obizwa ngokuthi q1 oqukethe imilayezo engu-4 m1,m2,m3,m4. Umlayezo m2 uyinhloko ye-tuple equkethe imilayezo emibili ethi m2_1 kanye ne-m2_2.

Ihlola injini ye-Mediastreamer2 VoIP. Ingxenye 11

Imisebenzi yokusebenza ngolayini ulayini_t

Ukuqaliswa komugqa:

void qinit(queue_t *q);

Insimu _q_isivimbeli (ngemuva kwalokhu sizoyibiza ngokuthi “i-stopper”) iqalwa umsebenzi mblk_init(), i-elementi yayo yangaphambili kanye nesikhombi se-elementi elandelayo zilungiswa ukuze zikhombe yona. Isibali se-elementi yomugqa sisethwe kabusha ukuze sibe uziro.

Ukwengeza i-elementi entsha (imilayezo):

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

Isici esisha m yengezwa ekugcineni kohlu, izinkomba zesici ziyalungiswa ukuze isitobha sibe yisici esilandelayo saso, futhi sibe yisici sangaphambilini sesitobhi. Ikhawunta yesici somugqa siyandiswa.

Ibuyisa i-elementi emgqeni:

mblk_t * getq(queue_t *q); 

Umlayezo oza ngemva kokuba isivimbo sesibuyisiwe, futhi isibali sesici sincishisiwe. Uma zingekho izici kulayini ngaphandle kwesitobhi, kuzobe sekubuyiswa u-0.

Ukufaka umlayezo kulayini:

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

Isici mp ifakwe ngaphambi kwe-elementi EMP. Uma EMP=0, bese umlayezo wengezwa emsileni womugqa.

Ibuyisa umlayezo ovela enhlokweni yolayini:

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

Ikhawunta ye-elementi incishisiwe.

Ukufunda isikhombi sento yokuqala kulayini:

mblk_t * peekq(queue_t *q); 

Isusa zonke izici emugqeni kuyilapho isusa ama-elementi ngokwawo:

void flushq(queue_t *q, int how);

Ukuphikisana Kanjani engasetshenzisiwe. Icounter element yomugqa isethwe ukuze ithi ziro.

Imakhro yokufunda i-pointer engxenyeni yokugcina yomugqa:

mblk_t * qlast(queue_t *q);

Uma usebenza ngolayini bemiyalezo, qaphela ukuthi uma ufona ms_queue_put(q, m) nge-null pointer kumlayezo, umsebenzi uyangena. Uhlelo lwakho luzoba yiqhwa. ziphatha ngendlela efanayo ms_umugqa_olandelayo(q, m).

Ixhuma izihlungi

Ulayini ochazwe ngenhla usetshenziselwa ukudlulisa imilayezo isuka kwesinye isihlungi iye kwesinye noma isuke kwesinye iye kwezihlungi ezimbalwa. Izihlungi nokuxhumana kwazo kwakha igrafu eqondisiwe. Okokufaka noma okukhiphayo kwesihlungi kuzobizwa ngegama elivamile elithi “pin”. Ukuze uchaze indlela izihlungi ezixhunywe ngayo kwezinye, isisakazi semidiya sisebenzisa umqondo "wephoyinti lesiginali". Iphoyinti lesiginali isakhiwo _MSCPoint, equkethe i-pointer esihlungini kanye nenombolo yephini elilodwa laso; ngokufanelekile, ichaza ukuxhumeka kokukodwa kokufakwayo noma okuphumayo kwesihlungi.

Iphoyinti lesiginali legrafu yokucubungula idatha

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

Izikhonkwane zokuhlunga zinezinombolo eziqala kuziro.

Ukuxhumana kwezikhonkwane ezimbili ngomugqa womlayezo kuchazwa ngesakhiwo _MSQueue, equkethe ulayini womlayezo nezikhombisi zamaphoyinti amabili esignali ewaxhumayo:

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

Lesi sakhiwo sizobiza isixhumanisi sesignali. Isihlungi ngasinye se-media streamer siqukethe itafula lezixhumanisi zokufaka kanye nethebula lezixhumanisi zokuphumayo (I-MSQueue). Usayizi wamathebula uyasethwa uma kwakhiwa isihlungi; sesivele sikwenzile lokhu sisebenzisa uhlobo oluhlukile oluthunyelwe I-MSFilterDesc, lapho sakha isihlungi sethu. Ngezansi kunesakhiwo esichaza noma yisiphi isihlungi ku-media streamer, I-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;

Ngemuva kokuthi sixhume izihlungi kuhlelo C ngokuhambisana nohlelo lwethu (kodwa asizange sixhume ithikha), ngaleyo ndlela sidale igrafu eqondisiwe, ama-node ayizibonelo zesakhiwo. I-MSFilter, futhi imiphetho iyizibonelo zezixhumanisi I-MSQueue.

Ngemuva kwezigcawu imisebenzi yethikha

Ngesikhathi ngikutshela ukuthi ithikha isisefo somthombo wamakhizane, bekungelona iqiniso eliphelele ngakho. Ithikha into esebenzisa imisebenzi ewashini inqubo() zonke izihlungi zesekethe (igrafu) exhunywe kuyo. Uma sixhuma ithikha kusihlungi segrafu kuhlelo C, sibonisa ithikha igrafu ezoyilawula kusukela manje kuye phambili size siyivale. Ngemva kokuxhuma, ithikha iqala ukuhlola igrafu ephathiswe ukuba iyinakekele, ihlanganise uhlu lwezihlungi olulihlanganisayo. Ukuze "ungabale" isihlungi esifanayo kabili, imaka izihlungi ezitholiwe ngokubeka ibhokisi lokuthikha kuzo. wambona. Ukusesha kwenziwa kusetshenziswa amathebula esixhumanisi isihlungi ngasinye esinawo.

Phakathi nohambo lwayo lwesingeniso lwegrafu, ithikha ihlola ukuthi phakathi kwezihlungi kukhona yini okungenani eyodwa esebenza njengomthombo wamabhulokhi wedatha. Uma lingekho, igrafu ithathwa njengengalungile bese ithikha iphahlazeke.

Uma igrafu kuvela ukuthi "ilungile", kusihlungi ngasinye esitholiwe, umsebenzi ubizwa ngokuthi uqalise inqubo (). Ngokushesha nje lapho kufika isikhathi somjikelezo wokucubungula olandelayo (njalo ngama-milliseconds ayi-10 ngokuzenzakalelayo), ithikha ibiza umsebenzi. inqubo() kuzo zonke izihlungi zomthombo ezitholwe ngaphambilini, bese kuba nezihlungi ezisele ohlwini. Uma isihlungi sinezixhumanisi zokufaka, bese usebenzisa umsebenzi inqubo() iphinda kuze kube yilapho imigqa yesixhumanisi sokufaka ingenalutho. Ngemva kwalokhu, idlulela esihlungini esilandelayo ohlwini bese "iskrola" kuze kube yilapho izixhumanisi zokufaka ezingenayo imilayezo. Ithikha isuka kusihlungi iye kusihlungi kuze kuphele uhlu. Lokhu kuqeda ukucutshungulwa komjikelezo.

Manje sizobuyela kuma-tuples futhi sikhulume ngokuthi kungani ibhizinisi elinjalo lengezwe kumsakazi wemidiya. Ngokuvamile, inani ledatha elidingwa i-algorithm esebenza ngaphakathi kwesihlungi alihlangani futhi aliyona ukuphindaphinda kosayizi wamabhafa wedatha atholwe kokokufaka. Isibonelo, sibhala isihlungi esenza uguquko olusheshayo lwe-Fourier, lokho ngokwencazelo olungacubungula kuphela amabhulokhi edatha usayizi wawo ongamandla amabili. Makube yizibalo ezingama-512. Uma idatha ikhiqizwa isiteshi socingo, khona-ke isigcinalwazi sedatha yomlayezo ngamunye ekufakweni sizosilethela amasampula esignali angu-160. Kuyalinga ukungaqoqi idatha kokufakwayo kuze kube yilapho inani elidingekayo ledatha selikhona. Kodwa kulesi simo, ukungqubuzana kuzokwenzeka nethikha, okuzozama ngokuhluleka ukuskrola isihlungi kuze kube yilapho isixhumanisi sokufaka singenalutho. Ngaphambilini, sikhethe lo mthetho njengomgomo wesithathu wesihlungi. Ngokwalesi simiso, umsebenzi wesihlungi () kumele uthathe yonke idatha emigqeni yokufaka.

Ngaphezu kwalokho, ngeke kwenzeke ukuthatha amasampula angama-512 kuphela kokufakwayo, ngoba ungathatha amabhlogo aphelele, i.e. isihlungi kuyodingeka sithathe amasampula angu-640 futhi sisebenzise angu-512 awo, okusele ngaphambi kokuqongelela ingxenye entsha yedatha. Ngakho, isihlungi sethu, ngaphezu komsebenzi waso oyinhloko, kufanele sinikeze izenzo ezisizayo zokugcinwa okuphakathi kwedatha yokufaka. Abathuthukisi be-media streamer nesixazululo sale nkinga evamile baye bahlakulela into ekhethekile - i-MSBufferizer (i-bufferer), exazulula le nkinga ngokusebenzisa ama-tuples.

I-Bufferizer (MSBufferizer)

Lena into ezoqongelela idatha yokokufaka ngaphakathi kwesihlungi futhi iqale ukuyihambisa ukuze icutshungulwe ngokushesha nje lapho inani lolwazi selanele ukuqalisa i-algorithm yesihlungi. Ngenkathi isigcinalwazi siqongelela idatha, isihlungi sizosebenza kumodi yokungenzi lutho, ngaphandle kokusebenzisa amandla okucubungula ephrosesa. Kodwa ngokushesha nje lapho umsebenzi wokufunda ovela kusigcinalwazi ubuyisela inani elingelona iqanda, inqubo() umsebenzi wesihlungi uqala ukuthatha nokucubungula idatha kusuka kusigcinalwazi ngezingxenye zosayizi odingekayo, ize iphele.
Idatha engadingeki okwamanje isala ku-buffer njengento yokuqala ye-tuple, lapho amabhulokhi alandelayo edatha yokufaka anamathiselwe khona.

Isakhiwo esichaza ibhafa:

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

Imisebenzi yokusebenza nge-MSBufferizer

Ukudala isibonelo esisha sebhafa:

MSBufferizer * ms_bufferizer_new(void);

Imemori yabelwe, iqaliswe ngo ms_bufferizer_init() bese kubuyiselwa inkomba.

Umsebenzi wokuqalisa:

void ms_bufferizer_init(MSBufferizer *obj); 

Ulayini uyaqala q, insimu usayizi isethwe ku-zero.

Ukwengeza umlayezo:

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

Umlayezo m wengezwe kulayini. Usayizi obaliwe wamabhulokhi wedatha wengezwa kuwo usayizi.

Kudluliswa yonke imilayezo esuka kumugqa wedatha yesixhumanisi iye kubhafa q:

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

Idlulisela imilayezo esuka kusixhumanisi q ku-buffer yenziwa kusetshenziswa umsebenzi ms_bufferizer_put().

Ukufunda ku-buffer:

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

Uma usayizi wedatha eqoqwe ku-buffer ingaphansi kwaleyo eceliwe (idathalen), bese umsebenzi ubuyisela uziro, idatha ayikopishwa kudatha. Uma kungenjalo, ukukopishwa okulandelanayo kwedatha kuma-tuples atholakala ku-buffer kuyenziwa. Ngemva kokukopisha, i-tuple iyasuswa futhi inkumbulo iyakhululwa. Ukukopisha kuphela ngesikhathi lapho amabhayithi edatha ekopishwa. Uma isikhala siphela phakathi kwebhulokhi yedatha, khona-ke kulo mlayezo, ibhulokhi yedatha izokwehliswa ibe ingxenye esele engakopishiwe. Ngokuzayo uma ushaya ucingo, ukukopisha kuzoqhubeka kusuka kuleli phuzu.

Ukufunda inani ledatha elitholakalayo njengamanje kusigcinalwazi:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

Ibuyisela inkambu usayizi isigcinalwazi.

Ilahla ingxenye yedatha kubhafa:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

Inombolo eshiwo yamabhayithi edatha iyabuyiswa futhi ilahlwe. Idatha endala kakhulu ilahliwe.

Isusa yonke imilayezo kubhafa:

void ms_bufferizer_flush(MSBufferizer *obj); 

Ikhawunta yedatha isethwe kabusha ukuze ibe uziro.

Isusa yonke imilayezo kubhafa:

void ms_bufferizer_uninit(MSBufferizer *obj); 

Ikhawunta ayisethiwe kabusha.

Ukususa isigcinalwazi nokukhulula inkumbulo:

void ms_bufferizer_destroy(MSBufferizer *obj);  

Izibonelo zokusebenzisa i-bufferer zingatholakala kukhodi yomthombo yezihlungi ezimbalwa ze-media streamer. Isibonelo, kusihlungi se-MS_L16_ENC, esihlela kabusha amabhayithi kumasampuli ukusuka kuhlelo lwenethiwekhi ukuya ku-oda lomsingathi: l16.c

Esihlokweni esilandelayo, sizobheka udaba lokulinganisa umthwalo kuthikha nezindlela zokulwa nomthwalo wekhompyutha oweqile kumsakazi wemidiya.

Source: www.habr.com

Engeza amazwana