Ukuphonononga injini yeMediastreamer2 VoIP. Icandelo 11

Izinto zenqaku zithathwe kum zen channel.

Ukuphonononga injini yeMediastreamer2 VoIP. Icandelo 11

Indlela yokuhambisa idatha

  • Ibhloko yedatha dblk_t
  • Umyalezo mblk_t
  • Imisebenzi yokusebenza ngemiyalezo mblk_t
  • Emgceni_t
  • Imisebenzi yokusebenza ngemigca emgceni_t
  • Ukuqhagamshela izihluzi
  • Indawo yomqondiso wegrafu yokusetyenzwa kwedatha
  • Ngasemva kwemiboniso imisebenzi yeticker
  • I-Bufferizer (MSBufferizer)
  • Imisebenzi yokusebenza kunye ne-MSBufferizer

Ekugqibeleni nqaku siye saphuhlisa esethu isihluzo. Eli nqaku liza kugxila kwindlela yangaphakathi yokuhambisa idatha phakathi kwezihluzo zemidiya yemidiya. Oku kuya kukuvumela ukuba ubhale izihluzi eziphucukileyo kunye nomzamo omncinci kwixesha elizayo.

Indlela yokuhambisa idatha

Ukunyakaza kwedatha kwi-media streamer kwenziwa ngokusebenzisa imigca echazwe yisakhiwo umgca_t. Imitya yemiyalezo efana mblk_t, zona ngokwazo aziqukethe idatha yesignali, kodwa zidibanisa kuphela ngaphambili, umyalezo olandelayo kunye nebhloko yedatha. Ukongeza, ndifuna ukugxininisa ngokukodwa ukuba kukho intsimi yekhonkco kumyalezo wohlobo olufanayo, okuvumela ukuba uququzelele uluhlu lwemiyalezo edibeneyo. Siya kubiza iqela lemiyalezo edityaniswe luluhlu olunjalo i-tuple. Ngaloo ndlela, nayiphi na into yomgca inokuba ngumyalezo omnye mblk_t, kwaye mhlawumbi intloko yomyalezo tuple mblk_t. Umyalezo we-tuple ngamnye unokuba nebhloko yedata yewadi. Siza kuxubusha ukuba kutheni ii-tuples zifuneka kamva.

Njengoko kukhankanyiwe ngasentla, umyalezo ngokwawo awunayo ibhloko yedatha; endaweni yoko, iqulethe kuphela isalathisi kwindawo yememori apho ibhloko igcinwe khona. Kweli candelo, umfanekiso opheleleyo womsebenzi wosasazo lwemithombo yeendaba usikhumbuza indawo yokugcina umnyango kwikhathuni "Monsters, Inc.," apho iingcango (amakhonkco kumagumbi edatha) zihamba ngesantya esiphambeneyo kunye nabahambisi abangaphezulu, ngelixa amagumbi ngokwawo. hlala ungashukumi.

Ngoku, sihamba ngoluhlu ukusuka ezantsi ukuya phezulu, makhe siqwalasele ngokweenkcukacha amaziko adwelisiweyo omatshini wokuhambisa idatha kumjelo weendaba.

Ibhloko yedatha dblk_t

Ibhloko yedatha inesihloko kunye nesithinteli sedatha. Iheda ichazwa ngolu lwakhiwo lulandelayo,

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

Imihlaba yesakhiwo iqulathe izalathisi ukuya ekuqaleni kwesithinteli, isiphelo sesithinteli, kunye nomsebenzi wokucima idata buffer. Into yokugqibela kwiheda db_ref — ikhawuntala yereferensi, ukuba ifikelela ku-zero, oku kusebenza njengophawu lokucima le block kwinkumbulo. Ukuba ibhloko yedatha yenziwe ngumsebenzi idathab_alloc() , ngoko isikhuseli sedatha siyakubekwa kwinkumbulo ngoko nangoko emva kweheader. Kuzo zonke ezinye iimeko, isithinteli sinokubekwa kwindawo ethile ngokwahlukileyo. Isithinteli sedatha siya kuqulatha iisampulu zomqondiso okanye enye idata esifuna ukuyiqhuba ngezihluzi.

Umzekelo omtsha webhloko yedatha yenziwa kusetyenziswa umsebenzi:

dblk_t *datab_alloc(int size);

Njengeparameter yokufaka, inikwe ubungakanani bedatha ukuba ibhloko iya kugcina. Imemori eyongezelelekileyo yabelwe ukuze kubekwe iheader - isakhiwo - ekuqaleni kwememori eyabelweyo idathab. Kodwa xa usebenzisa eminye imisebenzi, oku akusoloko kusenzeka, kwezinye iimeko, isithinteli sedatha sinokubekwa ngokwahlukileyo kwiheader block data. Xa udala isakhiwo, amasimi aqwalaselwe ukwenzela ukuba intsimi yayo db_base yalatha ekuqaleni kwendawo yedatha, kwaye db_lim ukuya esiphelweni sayo. Ubalo lwekhonkco db_ref isetwe kwenye. Isalathisi somsebenzi wedatha simiselwe ku-zero.

umyalezo mblk_t

Njengoko kukhankanyiwe, izinto ezikuluhlu luhlobo mblk_t, ichazwa ngolu hlobo lulandelayo:

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;

ulwakhiwo mblk_t iqulethe izikhombisi ekuqaleni b_prev, b_okulandelayo, eziyimfuneko ukulungiselela uluhlu oludityaniswe kabini (oluluhlu umgca_t).

Emva koko kuza isalathisi b_qhubeka, esetyenziswa kuphela xa umyalezo uyinxalenye ye-tuple. Kumyalezo wokugqibela kwi-tuple, esi salathisi sihlala singenanto.

Okulandelayo sibona isalathisi kwibhloko yedatha b_data, apho umyalezo ukhona. Ilandelwa zizalathisi kwindawo engaphakathi kwi-block data buffer. Intsimi b_rptr ixela indawo apho idatha esuka kwisithinteli iya kufundwa khona. Intsimi b_wptr ibonisa indawo ekuya kubhalelwa kuyo isithinteli.

Iinkalo ezishiyekileyo zezobume benkonzo kwaye azinxulumananga nokusebenza kwendlela yokudlulisela idatha.

Apha ngezantsi ngumyalezo omnye onegama m1 kunye nebhloko yedatha d1.
Ukuphonononga injini yeMediastreamer2 VoIP. Icandelo 11
Lo mfanekiso ulandelayo ubonisa uluhlu lwemiyalezo emithathu m1, Zonke iinkonzo ze-intanethi, Zonke iinkonzo ze-intanethi.
Ukuphonononga injini yeMediastreamer2 VoIP. Icandelo 11

Imisebenzi yemiyalezo mblk_t

Umyalezo omtsha mblk_t yenziwe ngumsebenzi:

mblk_t *allocb(int size, int pri); 

ubeka umyalezo omtsha kwinkumbulo mblk_t ngebhloko yedatha yobungakanani obuchaziweyo ubungakanani, impikiswano yesibini - kuqala ayisetyenziswanga kolu guqulelo lwethala leencwadi. Kufuneka ihlale ingu-zero. Ngexesha lokusebenza komsebenzi, imemori iya kwabelwa ulwakhiwo lomyalezo omtsha kwaye umsebenzi uya kubizwa mblk_init(), eya kusetha ngokutsha yonke imimandla yomzekelo owenziwe wesakhiwo kwaye emva koko, usebenzisa okukhankanywe ngasentla idathab_alloc(), iyakwenza isithinteli sedatha. Emva koko imihlaba kulwakhiwo iya kuqwalaselwa:

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

Kwisiphumo sifumana umyalezo omtsha onemihlaba eqalwayo kunye nedatha engenanto. Ukongeza idatha kumyalezo, kufuneka uyikope kwibhloko yedatha yebhloko:

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

apho idata sisalathisi kumthombo wedatha, kwaye ubungakanani - ubungakanani babo.
emva koko kufuneka uhlaziye isalathisi kwindawo yokubhala ukuze ilathe kwakhona ekuqaleni kwendawo ekhululekileyo kwisithinteli:

msg->b_wptr = msg->b_wptr + size

Ukuba ufuna ukwenza umyalezo osuka kwisithinteli esele sikhona, ngaphandle kokukopa, sebenzisa umsebenzi:

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

Umsebenzi, emva kokudala umyalezo kunye nesakhiwo sebhloko yedatha, iya kuqwalasela izikhombisi zayo kwidatha kwidilesi. buff. Ezo. kulo mzekelo, i data buffer ayibekwa emva kwemihlaba yeheader yebloko yedata, njengokuba kwakunjalo xa usenza ibhloko yedata ngomsebenzi. idathab_alloc(). I-buffer enedatha egqithiselwe kumsebenzi iya kuhlala apho yayikhona, kodwa ngoncedo lwezikhombisi iya kuqhotyoshelwa kwi-header esanda kwenziwa yebhloko yedatha, kwaye, ngokufanelekileyo, kumyalezo.

Kumyalezo omnye mblk_t Iibhloko zedatha ezininzi zinokudityaniswa ngokulandelelanayo. Oku kwenziwa ngumsebenzi:

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

mp — umyalezo apho enye ibhlokhi yedatha iya kongezwa;
idata — isalathisi kwibhloko, ikopi yayo eya kongezwa kumyalezo;
ubungakanani - ubungakanani bedatha;
ipaki - iflegi yokuba ubungakanani bememori eyabelwe kufuneka ihambelane nomda we-4-byte (i-padding iya kwenziwa nge-zero).

Ukuba kukho isithuba esaneleyo kwisithinteli sedatha yomyalezo ekhoyo, ngoko idatha entsha iya kuncamathiselwa ngasemva kwedatha esele ikhona. Ukuba kukho isithuba esikhululekileyo esincinci kwi-buffer yedatha yomyalezo kune ubungakanani, ngoko umyalezo omtsha wenziwa ngobungakanani obaneleyo bebuffer kwaye idata ikhutshelwa kwisithinteli sayo. Lo ngumyalezo omtsha, odityaniswe kulowo wokuqala usebenzisa isalathisi b_qhubeka. Kule meko, umyalezo ujika ube yi-tuple.

Ukuba ufuna ukongeza enye ibhloko yedatha kwi-tuple, kufuneka usebenzise umsebenzi:

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

uya kufumana umyalezo wokugqibela kwi-tuple (unayo b_qhubeka izakuba lilize) kwaye izakubiza umsebenzi walo myalezo appendb().

Ungafumana ubungakanani bedatha kumyalezo okanye kwi-tuple usebenzisa umsebenzi:

int msgdsize(const mblk_t *mp);

izakulophu kuyo yonke imiyalezo kwi tuple kwaye ibuyise isixa sisonke sedata kwi data buffers yaloo miyalezo. Kumyalezo ngamnye, inani ledatha libalwa ngolu hlobo lulandelayo:

 mp->b_wptr - mp->b_rptr

Ukudibanisa ii-tuples ezimbini, sebenzisa umsebenzi:

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

udibanisa i-tuple entsham ukuya emsileni we tuple mp kwaye ibuyisela isalathisi kumyalezo wokugqibela wesiphumo se tuple.

Ukuba kuyimfuneko, i-tuple ingajikwa ibe ngumyalezo omnye ngebhloko enye yedatha, oku kwenziwa ngumsebenzi:

void msgpullup(mblk_t *mp,int len);

ukuba ingxabano lenani ngu -1, ngoko ubungakanani besikhuseli esinikezelweyo simiselwa ngokuzenzekelayo. Ukuba lenani linani elivumayo, ibuffer yalo bungakanani iyakwenziwa kwaye idata yomyalezo we tuple izakukhutshelwa kuyo. Ukuba isithinteli siyaphela, ukukopa kuyakuyeka apho. Umyalezo wokuqala we-tuple uya kufumana isithinteli sobungakanani obutsha kunye nedatha ekhutshelweyo. Imiyalezo eseleyo iya kucinywa kwaye imemori ibuyiselwe kumfumba.

Xa ucima isakhiwo mblk_t ukubalwa kwereferensi yebhloko yedatha kuthathelwa ingqalelo ukuba, xa ufowuna simahla () ijike ibe nguziro, emva koko idata buffer iyacinywa kunye nomzekelo mblk_t, esalatha kuyo.

Ukuqala imihlaba yomyalezo omtsha:

void mblk_init(mblk_t *mp);

Ukongeza elinye iqhekeza ledatha kumyalezo:

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

Ukuba idatha entsha ayingeni kwindawo ekhululekileyo yedatha yedatha yomyalezo, ngoko umyalezo owenziwe ngokwahlukileyo onesithinteli sobungakanani obufunekayo uncamathele kumyalezo (isalathisi kumyalezo owongezelelweyo sisetiwe kumyalezo wokuqala) kwaye umyalezo ujika ube yi-tuple.

Ukongeza iqhekeza ledatha kwi-tuple:

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

Umsebenzi ubiza appendb () kwiluphu.

Ukudibanisa ii-tuples ezimbini zibe nye:

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

umyalezo entsham iya kuncanyathiselwa kwi mp.

Ukwenza ikopi yomyalezo omnye:

mblk_t *copyb(const mblk_t *mp);

Gqibezela ukukopa i-tuple nazo zonke iibhloko zedatha:

mblk_t *copymsg(const mblk_t *mp);

Izinto ze-tuple zikhutshelwa ngumsebenzi ikopib().

Yenza ikopi elula yomyalezo mblk_t. Kule meko, ibhloko yedatha ayikopishwa, kodwa i-counter counter counter iyanda db_ref:

mblk_t *dupb(mblk_t *mp);

Ukwenza ikopi elula ye-tuple. Iibhloko zedatha azikhutshelwa, kuphela ii-reference counters zazo zinyuswa db_ref:

mblk_t *dupmsg(mblk_t* m);

Ukuncamathisela yonke imiyalezo ye-tuple kumyalezo omnye:

void msgpullup(mblk_t *mp,size_t len);

Ukuba ingxabano lenani ngu -1, ngoko ubungakanani besikhuseli esinikezelweyo simiselwa ngokuzenzekelayo.

Cima umyalezo, tuple:

void freemsg(mblk_t *mp);

Ubalo lwereferensi yebhloko yedatha luncitshiswa ngenye. Ukuba ifikelela ku-zero, ibhloko yedatha nayo iyacinywa.

Ukubalwa kwexabiso lilonke lwedatha kumyalezo okanye i-tuple.

size_t msgdsize(const mblk_t *mp);

Ukufumana kwakhona umyalezo ukusuka kumsila womgca:

mblk_t *ms_queue_peek_last (q);

Ukukhuphela imixholo yemimandla egciniweyo yomyalezo omnye komnye umyalezo (enyanisweni, le mihlaba iqulathe iiflegi ezisetyenziswa ngumsinga weendaba):

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

Umgceni umgca_t

Umgca womyalezo kumjelo weendaba uphunyezwa njengoluhlu oludityaniswe ngokuphindwe kabini. Uluhlu ngalunye luqulethe isalathisi kwibhloko yedatha kunye neesampuli zesignali. Kuvela ukuba kuphela izikhombisi kwibhloko yedatha zihamba ngokulandelelana, ngelixa idatha ngokwayo ihlala ingashukumi. Ezo. amakhonkco kuzo kuphela asusiweyo.
Ulwakhiwo oluchaza umgca umgca_t, iboniswe ngezantsi:

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

Isakhiwo siqulethe intsimi - isalathisi _q_isithinteli chwetheza *mblk_t, ilatha kwinto yokuqala (umyalezo) emgceni. Indawo yesibini yesakhiwo sisibali semiyalezo emgceni.
Lo mfanekiso ungezantsi ubonisa umgca ogama lingu-q1 oqulethe imiyalezo emi-4 m1, m2, m3, m4.
Ukuphonononga injini yeMediastreamer2 VoIP. Icandelo 11
Lo mfanekiso ulandelayo ubonisa umgca obizwa ngokuba ngu-q1 oqulethe imiyalezo emi-4 m1,m2,m3,m4. Umyalezo m2 yintloko ye-tuple equlethe imiyalezo emibini ngaphezulu m2_1 kunye ne-m2_2.

Ukuphonononga injini yeMediastreamer2 VoIP. Icandelo 11

Imisebenzi yokusebenza ngemigca emgceni_t

Ukuqaliswa komgca:

void qinit(queue_t *q);

Intsimi _q_isithinteli (emva koku siyakuyibiza "isithinteli") iqalwa ngumsebenzi mblk_init(), isiqalelo saso sangaphambili kunye nesalathi sento elandelayo zilungelelanisiwe ukuze zalathe kuyo. Icounter element yequeue iphinda imiselwe ku-zero.

Ukongeza into entsha (imiyalezo):

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

Into entsha m idityaniswe ekupheleni koluhlu, izikhombisi ze element zilungelelanisiwe ukuze isithinteli sibe sisiqalelo esilandelayo kuso, kwaye sibe sisiqalelo sangaphambili sesithinteli. Ikhawuntara yesiqalelo somgca siyandiswa.

Ifumana kwakhona into emgceni:

mblk_t * getq(queue_t *q); 

Umyalezo oza emva kokuba isithinteli sibuyisiwe, kunye nekhawuntara ye elementi ithotyiwe. Ukuba akukho ziqalelo emgceni ngaphandle kwesithinteli, u-0 uyabuyiswa.

Ukufakwa komyalezo emgceni:

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

Into mp ifakwe phambi kwendawo EMP. ukuba EMP=0, ngoko umyalezo wongezwa kumsila womgca.

Ukufumana kwakhona umyalezo ovela kwintloko yomgca:

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

Ikhawuntara yeelementi iyancipha.

Ukufunda isalathisi kwindawo yokuqala emgceni:

mblk_t * peekq(queue_t *q); 

Ukususa zonke izinto emgceni ngelixa ucima iziqalelo ngokwazo:

void flushq(queue_t *q, int how);

Impikiswano njani ayisetyenziswanga. Icounter element yequeue isetelwe ku-zero.

Imakhro yokufunda isalathisi kwindawo yokugqibela yomgca:

mblk_t * qlast(queue_t *q);

Xa usebenza ngomgca wemiyalezo, qaphela ukuba xa ufowuna ms_queue_beka(q, m) ngesalathisi esingenanto kumyalezo, umsebenzi uyajika. Inkqubo yakho iya kuba ngumkhenkce. yenza okufanayo ms_umgca_olandelayo(q, m).

Ukuqhagamshela izihluzi

Umgca ochazwe ngasentla usetyenziselwa ukudlulisa imiyalezo ukusuka kwesinye isihluzo ukuya kwesinye okanye ukusuka kwesinye ukuya kwizihluzo ezininzi. Izihluzi kunye noqhagamshelwano lwazo zenza igrafu echanekileyo. Igalelo okanye imveliso yesihluzi iya kubizwa ngokuba ligama eliqhelekileyo "pin". Ukuchaza umyalelo apho izihlungi zixhunywe omnye komnye, i-media streamer isebenzisa ingcamango ye "signal point". Indawo yomqondiso sisakhiwo _MSCPpoint, equlathe isalathisi kwisihluzi kunye nenani lesinye sezikhonkwane zaso, ngokufanelekileyo, ichaza uxhulumaniso lwelinye lamagalelo okanye iziphumo zesihluzi.

Indawo yomqondiso wegrafu yokusetyenzwa kwedatha

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

Izikhonkwane zesihluzi zinenombolo ukusuka ku-zero.

Ukudityaniswa kwezikhonkwane ezibini ngomgca womyalezo kuchazwa sisakhiwo _MSQueue, equlathe umgca womyalezo kunye nezalathisi kwiindawo zomqondiso ezimbini ezizidibanisayo:

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

Siza kubiza esi sakhiwo ikhonkco lomqondiso. Isihluzo ngasinye semidiya yemidiya siqulathe itheyibhile yongeniso lwamakhonkco kunye netafile yemveliso yekhonkco (MQueue). Ubungakanani betafile bucwangciswa xa kuyilwa isihluzo, sele sikwenzile oku sisebenzisa uhlobo oluthunyelweyo lohlobo MSFilterDesc, xa siye saphuhlisa esethu isihluzo. Apha ngezantsi sisakhiwo esichaza nasiphi na isihluzi kumsinga weendaba, 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;

Emva kokuba siqhagamshele izihluzi kwiprogram ye-C ngokuhambelana nesicwangciso sethu (kodwa asizange sidibanise i-ticker), ngoko ke senza igrafu eqondisiweyo, iinqununu zazo ziyimizekelo yesakhiwo. I-MSFilter, kwaye imiphetho yimizekelo yamakhonkco MQueue.

Ngasemva kwemiboniso imisebenzi yeticker

Xa ndikuxelela ukuba iticker sisihluzo somthombo wamakhalane, ibingeyonyani yonke loo nto. Iticker yinto eqhuba imisebenzi kwiwotshi inkqubo() zonke izihluzi zesekethe (igrafu) eqhagamshelwe kuyo. Xa sidibanisa iticker kwisihluzo segrafu kwiprogram ye-C, sibonisa iticker igrafu eya kuyilawula ukusuka ngoku ukuya phambili de siyicime. Emva kokudibanisa, i-ticker iqala ukuhlola igrafu ephathiswe ukunyamekela kwayo, iqulunqa uluhlu lwezihluzi ezibandakanya. Ukuze "ungabale" isihluzo esifanayo kabini, iphawula izihluzo ezichongiweyo ngokubeka ibhokisi yokukhangela kuzo. kubonwa. Uphendlo lwenziwa kusetyenziswa iitafile zekhonkco isihluzo ngasinye esinazo.

Ngexesha lotyelelo lwentshayelelo lwegrafu, iticker ijonga ukuba phakathi kwezihluzo kukho noko enye esebenza njengomthombo weebhloko zedatha. Ukuba akukho nanye, ngoko ke igrafu ithathwa njengengalunganga kwaye iticker iyawa.

Ukuba igrafu ijika ibe "chanekile", kwisihluzo ngasinye esifunyenweyo, umsebenzi ubizelwa ukuqaliswa qhubekeka (). Ngokukhawuleza ukuba umzuzu ufikile kumjikelo olandelayo wokuqhubekeka (rhoqo nge-10 millisecond ngokungagqibekanga), iticker ibiza umsebenzi. inkqubo() kuzo zonke izihluzi zemvelaphi ezifunyenwe ngaphambili, kwaye ke kwizihluzo eziseleyo kuluhlu. Ukuba isihluzo sinamakhonkco egalelo, ngoko uqhuba umsebenzi inkqubo() iphinda ide ingeniso imigca yekhonkco ingabinanto. Emva koku, iqhubela phambili kwisihluzo esilandelayo kuluhlu kwaye "iskrole" de amakhonkco egalelo akhululeke kwimiyalezo. Iticker iyashukuma ukusuka kwisihluzo ukuya kwisihluzo kude kuphele uluhlu. Oku kugqiba ukuqhubekekiswa komjikelo.

Ngoku siza kubuyela kwii-tuples kwaye sithethe malunga nokuba kutheni iqumrhu elinjalo longezwa kumsasazi weendaba. Ngokubanzi, ubungakanani bedatha efunwa yi-algorithm esebenza ngaphakathi kwesihluzi ayihambelani kwaye ayiphindi yobungakanani bedatha yedatha efunyenwe kwigalelo. Umzekelo, sibhala isihluzo esenza uguqulo olukhawulezayo lweFourier, olunokuthi ngenkcazo luqhubekisele kuphela iibhloko zedatha ezinobungakanani bamandla amabini. Mayibe ngama-512 amanani. Ukuba idatha iveliswa ngumtshaneli wefowuni, ngoko i-buffer yedatha yomyalezo ngamnye kwigalelo iya kusizisa iisampuli zesignali ze-160. Kuyahenda ukuba ungaqokeleli idatha kwigalelo kude kubekho inani elifunekayo ledatha. Kodwa kulo mzekelo, ungquzulwano luyakwenzeka kunye nenqaku, eliza kuzama ngokungenampumelelo ukuskrola isihluzi de ikhonkco longeniso lingabinanto. Ngaphambili, sikhethe lo mgaqo njengomgaqo wesithathu wesihluzo. Ngokwalo mgaqo, inkqubo yesihluzi () umsebenzi kufuneka ithathe yonke idata kwimigca yongeniso.

Ukongezelela, akunakwenzeka ukuthatha iisampuli ze-512 kuphela kwigalelo, ekubeni unokuthatha kuphela iibhloko ezipheleleyo, i.e. icebo lokucoca kuyakufuneka lithathe iisampulu ezingama-640 kwaye zisebenzise i512 yazo, intsalela phambi kokuqokelela inxalenye entsha yedatha. Ngaloo ndlela, isihluzo sethu, ngaphezu komsebenzi walo oyintloko, kufuneka sinikeze izenzo ezincedisayo zokugcinwa kwedatha yokufaka phakathi. Abaphuhlisi be-media streamer kunye nesisombululo kule ngxaki ngokubanzi baye baphuhlisa into ekhethekileyo - i-MSBufferizer (i-bufferer), eyisombulula le ngxaki ngokusebenzisa i-tuples.

I-Bufferizer (MSBufferizer)

Le yinto eza kuqokelela idata yegalelo ngaphakathi kwesihluzi kwaye iqalise ukuyithumela ukuba iqhubekeke ngokukhawuleza ukuba isixa solwazi sanele ukuqhuba i-algorithm yokucoca. Ngelixa isithinteli siqokelela idatha, isihluzi siya kusebenza kwimowudi engasebenziyo, ngaphandle kokusebenzisa amandla okulungisa umqhubekekisi. Kodwa kamsinya nje umsebenzi wofundo ovela kwisithinteli ubuyisela ixabiso elingelilo ngaphandle kuka-zero, inkqubo () umsebenzi wecebo lokucoca uqalisa ukuthatha nokuqhubekekisa idata ukusuka kwisithinteli kwizahlulo zobungakanani obufunekayo, ide iphele.
Idatha engekafunwa isala kwi-buffer njengento yokuqala ye-tuple, apho iibhloko ezilandelayo zedatha yegalelo ziqhotyoshelweyo.

Isakhiwo esichaza isithinteli:

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

Imisebenzi yokusebenza kunye ne-MSBufferizer

Ukwenza umzekelo omtsha we-buffer:

MSBufferizer * ms_bufferizer_new(void);

Imemori yabelwe, iqaliswe ngo ms_bufferizer_init() kwaye isalathisi siyabuyiswa.

Umsebenzi wokuqalisa:

void ms_bufferizer_init(MSBufferizer *obj); 

Umgca uyaqalisa q, ibala ubungakanani isetelwe ku-zero.

Ukongeza umyalezo:

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

Umyalezo m wongezwa emgceni. Ubungakanani obaliweyo beebhloko zedatha zongezwa kuyo ubungakanani.

Kugqithiselwa yonke imiyalezo ukusuka kumgca wedatha yekhonkco ukuya kwi-buffer q:

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

Ukuhanjiswa kwemiyalezo kwikhonkco q kwisithinteli kwenziwa kusetyenziswa umsebenzi ms_bufferizer_beka().

Ukufunda kwisithinteli:

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

Ukuba ubungakanani bedatha eqokelelwe kwi-buffer ingaphantsi kweceliweyo (datalen), ngoko umsebenzi ubuyisela i-zero, idatha ayikhutshelwanga kwidatha. Kungenjalo, ukhuphelo olulandelelanayo lwedatha olusuka kwii-tuples ezibekwe kwi-buffer luyenziwa. Emva kokukopa, i-tuple iyacinywa kwaye imemori iyakhululwa. Ukukhuphela kuphela ngexesha xa ii-byte zedatha zikotshwa. Ukuba isithuba siphela phakathi kwebhloko yedatha, ngoko kulo myalezo, ibhloko yedatha iya kuncitshiswa ibe yindawo eseleyo engabhalwanga. Ngexesha elizayo xa ufowuna, ukukopa kuya kuqhubeka ukusuka kweli nqaku.

Ukufunda isixa sedatha ekhoyo ngoku kwisithinteli:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

Ibuyisela ibala ubungakanani isithinteli.

Ukulahla inxalenye yedatha kwisithinteli:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

Inani elichaziweyo leebhayithi zedatha ziyafunyanwa kwaye ilahlwe. Eyona datha indala ilahliwe.

Kucinywa yonke imiyalezo kwi-buffer:

void ms_bufferizer_flush(MSBufferizer *obj); 

Ikhawuntara yedatha iphinda imiselwe ku-zero.

Kucinywa yonke imiyalezo kwi-buffer:

void ms_bufferizer_uninit(MSBufferizer *obj); 

Ikhawuntara ayisetwanga ngokutsha.

Ukususa isithinteli kunye nokukhulula imemori:

void ms_bufferizer_destroy(MSBufferizer *obj);  

Imizekelo yokusebenzisa isithinteli inokufunyanwa kwikhowudi yemvelaphi yezihluzi ezininzi zemidiya yemidiya. Umzekelo, kwisihluzi se-MS_L16_ENC, esiphinda sihlengahlengise ii-byte kwiisampulu ukusuka kumyalelo wothungelwano ukuya kumyalelo womamkeli: l16.c

Kwinqaku elilandelayo, siza kujonga umba wokuqikelela umthwalo kwi-ticker kunye neendlela zokulwa nomthwalo ogqithisileyo wekhompyutha kwi-media streamer.

umthombo: www.habr.com

Yongeza izimvo