Njelajah mesin Mediastreamer2 VoIP. Bagean 11

Materi artikel dijupuk saka sandi saluran zen.

Njelajah mesin Mediastreamer2 VoIP. Bagean 11

Mekanisme gerakan data

  • Blok data dblk_t
  • Pesen mblk_t
  • Fungsi kanggo nggarap pesen mblk_t
  • Antri antrian_t
  • Fungsi kanggo nggarap queue_t
  • Nyambung saringan
  • Titik sinyal grafik pangolahan data
  • Aktivitas ing mburi layar saka ticker
  • Bufferizer (MSBufferizer)
  • Fungsi kanggo nggarap MSBufferizer

Ing pungkasan artikel kita wis dikembangaké Filter kita dhewe. Artikel iki bakal fokus ing mekanisme internal kanggo mindhah data antarane saringan streamer media. Iki bakal ngidini sampeyan nulis saringan canggih kanthi kurang gaweyan ing mangsa ngarep.

Mekanisme gerakan data

Gerakan data ing streamer media ditindakake kanthi nggunakake antrian sing diterangake dening struktur antrian_t. Strings pesen kaya mblk_t, kang dhewe ora ngemot data sinyal, nanging mung pranala menyang sadurungé, pesen sabanjuré lan kanggo pemblokiran data. Kajaba iku, aku pengin utamané nandheske sing ana uga lapangan kanggo link menyang pesen saka jinis padha, sing ngijini sampeyan kanggo ngatur dhaptar pesen singly disambung. Kita bakal nelpon klompok pesen sing digabungake karo dhaptar kasebut minangka tuple. Mangkono, unsur apa wae saka antrian bisa dadi pesen siji mblk_t, lan Mungkin kepala tuple pesen mblk_t. Saben pesen tuple bisa duwe blok data pendhapa dhewe. Kita bakal ngrembug kenapa tuple dibutuhake mengko.

Kaya sing kasebut ing ndhuwur, pesen kasebut ora ngemot blok data, nanging mung ngemot pointer menyang area memori ing ngendi blok kasebut disimpen. Ing bagean iki, gambar sakabèhé saka karya streamer media kaya gudang lawang ing kartun "Monsters, Inc.," ngendi lawang (pranala kanggo data - kamar) pindhah ing kacepetan edan bebarengan conveyor overhead, nalika kamar dhewe. tetep ora obah.

Saiki, pindhah ing hirarki saka ngisor menyang ndhuwur, ayo nimbang kanthi rinci entitas kadhaptar mekanisme transmisi data ing streamer media.

Blok data dblk_t

Blok data kasusun saka header lan buffer data. Header diterangake kanthi struktur ing ngisor iki,

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

Kothak struktur ngemot penunjuk menyang wiwitan buffer, mburi buffer, lan fungsi kanggo mbusak buffer data. Unsur pungkasan ing header db_ref - counter referensi, yen tekan nul, iki serves minangka sinyal kanggo mbusak pemblokiran iki saka memori. Yen pamblokiran data digawe dening fungsi datab_alloc() , banjur buffer data bakal diselehake ing memori sanalika sawise header. Ing kabeh kasus liyane, buffer bisa dumunung nang endi wae dhewe. Buffer data bakal ngemot conto sinyal utawa data liyane sing pengin diproses nganggo saringan.

Kayata anyar saka blok data digawe nggunakake fungsi:

dblk_t *datab_alloc(int size);

Minangka parameter input, diwenehi ukuran data sing bakal disimpen pamblokiran. Memori liyane diparengake kanggo nyelehake header - struktur - ing wiwitan memori sing diparengake datab. Nanging nalika nggunakake fungsi liyane, iki ora tansah kelakon; ing sawetara kasus, buffer data bisa dipisahake saka header blok data. Nalika nggawe struktur, lapangan dikonfigurasi supaya lapangan kasebut db_base nuding wiwitan area data, lan db_lim nganti pungkasane. Link count db_ref disetel dadi siji. Penunjuk fungsi data cetha disetel menyang nol.

Pesen mblk_t

Kaya sing wis dingerteni, unsur antrian kalebu jinis mblk_t, ditetepake kaya ing ngisor iki:

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;

struktur mblk_t ngandhut pitunjuk ing wiwitan b_prev, b_sabanjure, sing perlu kanggo ngatur dhaptar sing disambung kaping pindho (yaiku antrian antrian_t).

Banjur nerangake pointer b_terus, sing mung digunakake nalika pesen minangka bagéan saka tuple. Kanggo pesen pungkasan ing tuple, pointer iki tetep null.

Sabanjure kita ndeleng pointer menyang blok data b_datap, sing pesen ana. Iku ngiring dening penunjuk menyang wilayah nang buffer data pemblokiran. lapangan b_rptr nemtokake lokasi saka ngendi data saka buffer bakal diwaca. lapangan b_wptr nuduhake lokasi saka nulis menyang buffer bakal dileksanakake.

Kolom sing isih ana sifate layanan lan ora ana hubungane karo operasi mekanisme transfer data.

Ngisor iki pesen siji karo jeneng m1 lan blok data d1.
Njelajah mesin Mediastreamer2 VoIP. Bagean 11
Gambar ing ngisor iki nuduhake tuple saka telung pesen m1, m1_1, m1_2.
Njelajah mesin Mediastreamer2 VoIP. Bagean 11

Fungsi olahpesen mblk_t

Pesen anyar mblk_t digawe dening fungsi:

mblk_t *allocb(int size, int pri); 

dheweke nyelehake pesen anyar ing memori mblk_t kanthi blok data ukuran sing ditemtokake ukuran, argumen kapindho - pri ora digunakake ing versi perpustakaan iki. Iku kudu tetep nul. Sajrone operasi fungsi, memori bakal diparengake kanggo struktur pesen anyar lan fungsi bakal disebut mblk_init(), sing bakal ngreset kabeh kolom saka conto sing digawe saka struktur banjur, nggunakake kasebut ing ndhuwur datab_alloc(), bakal nggawe buffer data. Sawise kolom ing struktur bakal dikonfigurasi:

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

Ing output kita nampa pesen anyar karo kolom initialized lan buffer data kosong. Kanggo nambah data menyang pesen, sampeyan kudu nyalin menyang buffer blok data:

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

ngendi data minangka pointer kanggo sumber data, lan ukuran - ukurane.
banjur sampeyan kudu nganyari pointer menyang titik nulis supaya nuding maneh menyang wiwitan area gratis ing buffer:

msg->b_wptr = msg->b_wptr + size

Yen sampeyan kudu nggawe pesen saka buffer sing wis ana, tanpa nyalin, banjur gunakake fungsi:

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

Fungsi kasebut, sawise nggawe pesen lan struktur blok data, bakal ngatur penunjuk menyang data ing alamat kasebut tukang mangan. Sing. ing kasus iki, buffer data ora ana sawise kolom header blok data, kaya sing kedadeyan nalika nggawe blok data kanthi fungsi kasebut. datab_alloc(). Buffer karo data liwati kanggo fungsi bakal tetep ing ngendi iku, nanging karo bantuan saka pitunjuk bakal ditempelake ing header mentas digawe saka pamblokiran data, lan sing, patut, kanggo pesen.

Kanggo pesen siji mblk_t Sawetara blok data bisa digabung kanthi urutan. Iki ditindakake kanthi fungsi:

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

mp - pesen sing bakal ditambahake blok data liyane;
data - pointer menyang blok, salinan sing bakal ditambahake menyang pesen;
ukuran - ukuran data;
pad - gendéra sing ukuran memori sing diparengake kudu didadekake siji ing sadawane wates 4-bait (padding bakal rampung karo nul).

Yen ana cukup spasi ing buffer data pesen sing wis ana, banjur data anyar bakal ditempelake konco data wis ana. Yen ana kurang papan free ing buffer data pesen saka ukuran, banjur pesen anyar digawe kanthi ukuran buffer sing cukup lan data disalin menyang buffer. Iki pesen anyar, disambung menyang sing asli nggunakake pointer b_terus. Ing kasus iki, pesen dadi tuple.

Yen sampeyan kudu nambah blok data liyane menyang tuple, sampeyan kudu nggunakake fungsi kasebut:

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

dheweke bakal nemokake pesen pungkasan ing tuple (dheweke wis b_terus bakal null) lan bakal nelpon fungsi kanggo pesen iki lampiranb().

Sampeyan bisa ngerteni ukuran data ing pesen utawa tuple nggunakake fungsi:

int msgdsize(const mblk_t *mp);

bakal daur ulang liwat kabeh pesen ing tuple lan bali jumlah total data ing buffer data pesen sing. Kanggo saben pesen, jumlah data diitung kaya ing ngisor iki:

 mp->b_wptr - mp->b_rptr

Kanggo nggabungake rong tuple, gunakake fungsi:

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

dheweke nambahake tuple anyaran marang buntut tuple mp lan ngasilake pointer menyang pesen pungkasan saka tuple asil.

Yen perlu, tuple bisa diowahi dadi siji pesen kanthi blok data siji; iki ditindakake kanthi fungsi:

void msgpullup(mblk_t *mp,int len);

yen argumentasi len punika -1, banjur ukuran buffer diparengake ditemtokake kanthi otomatis. Yen len iku nomer positif, buffer saka ukuran iki bakal digawe lan data pesen tuple bakal disalin menyang. Yen buffer entek, nyalin bakal mandheg ana. Pesen pisanan tuple bakal nampa buffer ukuran anyar kanthi data sing disalin. Pesen sing isih ana bakal dibusak lan memori bali menyang tumpukan.

Nalika mbusak struktur mblk_t count referensi pamblokiran data dijupuk menyang akun yen, nalika nelpon gratisb() pranyata dadi nul, banjur buffer data dibusak bebarengan karo Kayata mblk_t, kang nuduhake iku.

Miwiti kolom pesen anyar:

void mblk_init(mblk_t *mp);

Nambahake potongan data liyane menyang pesen:

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

Yen data anyar ora pas karo ruang kosong buffer data pesen, pesen sing digawe kanthi kapisah karo buffer ukuran sing dibutuhake ditempelake ing pesen kasebut (pointer menyang pesen sing ditambahake disetel ing pesen pisanan) lan pesen dadi tuple.

Nambahake potongan data menyang tuple:

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

Fungsi kasebut nelpon appendb () ing daur ulang.

Nggabungake rong tuple dadi siji:

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

Pesen anyaran bakal ditempelake menyang mp.

Nggawe salinan pesen siji:

mblk_t *copyb(const mblk_t *mp);

Nyalin tuple lengkap karo kabeh blok data:

mblk_t *copymsg(const mblk_t *mp);

Unsur tuple disalin dening fungsi copyb().

Nggawe salinan pesen sing gampang mblk_t. Ing kasus iki, blok data ora disalin, nanging counter referensi tambah db_ref:

mblk_t *dupb(mblk_t *mp);

Nggawe salinan tuple sing entheng. Blok data ora disalin, mung counter referensi sing ditambahake db_ref:

mblk_t *dupmsg(mblk_t* m);

Nggabungake kabeh pesen saka tuple dadi siji pesen:

void msgpullup(mblk_t *mp,size_t len);

Yen argumentasi len punika -1, banjur ukuran buffer diparengake ditemtokake kanthi otomatis.

Mbusak pesen, tuple:

void freemsg(mblk_t *mp);

Cacah referensi blok data dikurangi siji. Yen tekan nol, blok data uga dibusak.

Pitungan jumlah total data ing pesen utawa tuple.

size_t msgdsize(const mblk_t *mp);

Njupuk pesen saka buntut antrian:

mblk_t *ms_queue_peek_last (q);

Nyalin isi kolom sing dilindhungi saka siji pesen menyang pesen liyane (nyatane, kolom kasebut ngemot gendera sing digunakake dening streamer media):

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

Saiki antrian_t

Antrian pesen ing streamer media dileksanakake minangka dhaptar bunder sing disambung kaping pindho. Saben unsur dhaptar ngemot pointer menyang blok data kanthi conto sinyal. Pranyata metu sing mung penunjuk kanggo pamblokiran data pindhah ing siji, nalika data dhewe tetep obah. Sing. mung pranala menyang wong-wong mau dipindhah.
Struktur njlèntrèhaké antrian antrian_t, kapacak ing ngisor iki:

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

Struktur kasebut ngemot lapangan - pointer _q_stopper ketik *mblk_t, nuduhake unsur pisanan (pesen) ing antrian. Kolom kapindho struktur yaiku counter pesen ing antrian.
Tokoh ing ngisor iki nuduhake antrian jenenge q1 ngemot 4 pesen m1, m2, m3, m4.
Njelajah mesin Mediastreamer2 VoIP. Bagean 11
Gambar ing ngisor iki nuduhake antrian sing jenenge q1 ngemot 4 pesen m1,m2,m3,m4. Pesen m2 minangka kepala tuple sing ngemot rong pesen liyane m2_1 lan m2_2.

Njelajah mesin Mediastreamer2 VoIP. Bagean 11

Fungsi kanggo nggarap queue_t

Inisialisasi antrian:

void qinit(queue_t *q);

lapangan _q_stopper (Sabanjure kita bakal nyebataken "stopper") punika initialized dening fungsi mblk_init(), unsur sadurunge lan pointer unsur sabanjuré diatur kanggo nuding dhewe. Counter unsur antrian direset menyang nul.

Nambahake unsur anyar (pesen):

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

Unsur anyar m ditambahake ing mburi dhaftar, unsur pitunjuk diatur supaya stopper dadi unsur sabanjuré kanggo, lan dadi unsur sadurungé kanggo stopper. Counter unsur antrian ditambahake.

Njupuk unsur saka antrian:

mblk_t * getq(queue_t *q); 

Pesen sing teka sawise stopper dijupuk, lan counter unsur decremented. Yen ora ana unsur ing antrian kajaba stopper, banjur 0 bali.

Nglebokake pesen menyang antrian:

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

Item mp dilebokake sadurunge unsur emp. Yen emp= 0, banjur pesen ditambahake menyang buntut antrian.

Njupuk pesen saka kepala antrian:

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

Counter unsur dikurangi.

Maca pointer menyang unsur pisanan ing antrian:

mblk_t * peekq(queue_t *q); 

Mbusak kabeh unsur saka antrian nalika mbusak unsur kasebut dhewe:

void flushq(queue_t *q, int how);

Argumentasi carane ora digunakake. Counter unsur antrian disetel menyang nul.

Macro kanggo maca pointer menyang unsur pungkasan antrian:

mblk_t * qlast(queue_t *q);

Nalika nggarap antrian pesen, elinga yen sampeyan nelpon ms_queue_put (q, m) kanthi null pointer kanggo pesen, fungsi puteran. Program sampeyan bakal beku. tumindak padha ms_queue_next(q, m).

Nyambung saringan

Antrian sing diterangake ing ndhuwur digunakake kanggo ngirim pesen saka siji filter menyang liyane utawa saka siji menyang sawetara filter. Filter-filter lan sambungane mbentuk grafik sing diarahake. Input utawa output panyaring bakal diarani tembung umum "pin". Kanggo njlèntrèhaké urutan saringan sing disambungake menyang saben liyane, streamer media nggunakake konsep "titik sinyal". Titik sinyal minangka struktur _MSCPpoint, sing ngemot pointer menyang saringan lan nomer salah sawijining pin; mula, iki nggambarake sambungan salah sawijining input utawa output saringan.

Titik sinyal grafik pangolahan data

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

Pin Filter diwenehi nomer wiwit saka nol.

Sambungan loro pin dening antrian pesen diterangake dening struktur _MSQueue, sing ngemot antrian pesen lan penunjuk menyang rong titik sinyal sing disambungake:

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

Kita bakal nyebut struktur iki minangka link sinyal. Saben filter streamer media ngemot tabel pranala input lan tabel pranala output (MSQueue). Ukuran tabel disetel nalika nggawe saringan; kita wis nindakake iki nggunakake variabel jinis sing diekspor MSFilterDesc, nalika kita ngembangake filter dhewe. Ing ngisor iki minangka struktur sing nggambarake saringan apa wae ing streamer 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;

Sawise kita nyambungake saringan ing program C sesuai karo rencana kita (nanging ora nyambungake ticker), mula nggawe grafik sing diarahake, simpul kasebut minangka conto struktur. MSFilter, lan pinggiran minangka conto pranala MSQueue.

Aktivitas ing mburi layar saka ticker

Nalika aku ngandhani yen ticker minangka panyaring kanggo sumber kutu, dudu kabeh bebener babagan iki. Ticker minangka obyek sing mbukak fungsi ing jam proses () kabeh saringan sirkuit (grafik) sing disambungake. Nalika kita nyambungake ticker menyang panyaring grafik ing program C, kita nuduhake ticker grafik sing bakal dikontrol wiwit saiki nganti dipateni. Sawise nyambungake, ticker wiwit nliti grafik sing dipasrahake kanggo ngurus, nyusun dhaptar saringan sing kalebu. Supaya ora "ngetung" panyaring sing padha kaping pindho, tandhani saringan sing dideteksi kanthi masang kothak centhang ing katon. Panelusuran ditindakake kanthi nggunakake tabel link sing ana saben filter.

Sajrone tur pambuka grafik kasebut, ticker mriksa apa ing antarane saringan paling ora ana sing dadi sumber pamblokiran data. Yen ora ana, mula grafik kasebut dianggep salah lan ticker nabrak.

Yen grafik dadi "bener", kanggo saben filter sing ditemokake, fungsi kasebut diarani initialization praproses(). Sanalika wayahe teka kanggo siklus pangolahan sabanjure (saben 10 milidetik minangka standar), ticker nelpon fungsi kasebut. proses () kanggo kabeh saringan sumber sing ditemokake sadurunge, banjur kanggo saringan sing isih ana ing dhaptar. Yen panyaring duwe pranala input, banjur mbukak fungsi kasebut proses () mbaleni nganti antrian link input kosong. Sawise iki, pindhah menyang saringan sabanjure ing dhaptar lan "gulung" nganti pranala input bebas saka pesen. Ticker pindhah saka saringan menyang saringan nganti dhaptar rampung. Iki ngrampungake pangolahan siklus.

Saiki kita bakal bali menyang tuples lan ngomong babagan kenapa entitas kasebut ditambahake menyang streamer media. Umumé, jumlah data sing dibutuhake dening algoritma operasi ing saringan ora pas lan ora kaping pirang-pirang ukuran buffer data sing ditampa ing input. Contone, kita nulis panyaring sing nindakake transformasi Fourier kanthi cepet, sing miturut definisi mung bisa ngolah blok data sing ukurane minangka daya loro. Ayo dadi 512 count. Yen data digawe dening saluran telpon, buffer data saben pesen ing input bakal nggawa kita 160 conto sinyal. Iku nggodho ora kanggo ngumpulake data saka input nganti jumlah sing dibutuhake data ana. Nanging ing kasus iki, tabrakan bakal kedadeyan karo ticker, sing bakal gagal nyoba nggulung filter nganti link input kosong. Sadurunge, kita nemtokake aturan iki minangka prinsip katelu saka saringan. Miturut asas iki, proses Filter () fungsi kudu njupuk kabeh data saka antrian input.

Kajaba iku, ora bakal bisa njupuk mung 512 conto saka input, amarga sampeyan mung bisa njupuk kabeh blok, i.e. saringan kudu njupuk 640 conto lan nggunakake 512 saka wong-wong mau, seko sadurunge accumulating bagean anyar saka data. Mangkono, saringan kita, saliyane kanggo karya utama, kudu nyedhiyakake tumindak tambahan kanggo panyimpenan intermediate data input. Pengembang streamer media lan solusi kanggo masalah umum iki wis ngembangake obyek khusus - MSBufferizer (bufferer), sing ngrampungake masalah iki kanthi nggunakake tuple.

Bufferizer (MSBufferizer)

Iki minangka obyek sing bakal nglumpukake data input ing saringan lan wiwit ngirim kanggo diproses sanalika jumlah informasi cukup kanggo mbukak algoritma panyaring. Nalika buffer nglumpukake data, panyaring bakal beroperasi ing mode nganggur, tanpa nggunakake daya pangolahan prosesor. Nanging sanalika fungsi maca saka bufferer ngasilake Nilai liyane saka nul, proses () fungsi Filter wiwit njupuk lan proses data saka bufferer ing bagean saka ukuran sing dibutuhake, nganti kesel.
Data sing durung dibutuhake tetep ana ing buffer minangka unsur pisanan saka tuple, sing disambungake pamblokiran data input sabanjure.

Struktur sing nggambarake buffer:

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

Fungsi kanggo nggarap MSBufferizer

Nggawe conto buffer anyar:

MSBufferizer * ms_bufferizer_new(void);

Memori diparengake, diwiwiti ing ms_bufferizer_init() lan pointer bali.

Fungsi Initialization:

void ms_bufferizer_init(MSBufferizer *obj); 

Antrian wis initializing q, lapangan ukuran disetel menyang nul.

Nambah pesen:

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

Pesen m ditambahake menyang antrian. Ukuran pamblokiran data sing diwilang ditambahake ukuran.

Nransfer kabeh pesen saka antrian data link menyang buffer q:

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

Transfer pesen saka link q ing buffer dileksanakake nggunakake fungsi ms_bufferizer_put().

Maca saka buffer:

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

Yen ukuran data akumulasi ing buffer kurang saka sing dijaluk (datalen), banjur fungsi ngasilake nol, data ora disalin menyang data. Yen ora, nyalin urutan data saka tuple sing ana ing buffer ditindakake. Sawise nyalin, tuple dibusak lan memori dibebasake. Nyalin ends ing wayahe nalika datalen bita disalin. Yen spasi entek ing tengah blok data, banjur ing pesen iki, blok data bakal dikurangi dadi bagean sing ora disalin. Sabanjure sampeyan nelpon, nyalin bakal terus saka titik iki.

Maca jumlah data sing saiki kasedhiya ing buffer:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

Ngasilake lapangan ukuran panyangga.

Mbuwang bagean data ing buffer:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

Jumlah bita data sing ditemtokake dijupuk lan dibuwang. Data sing paling tuwa dibuwang.

Mbusak kabeh pesen ing buffer:

void ms_bufferizer_flush(MSBufferizer *obj); 

Penghitung data direset menyang nol.

Mbusak kabeh pesen ing buffer:

void ms_bufferizer_uninit(MSBufferizer *obj); 

Counter ora direset.

Mbusak buffer lan mbebasake memori:

void ms_bufferizer_destroy(MSBufferizer *obj);  

Conto nggunakake bufferer bisa ditemokake ing kode sumber sawetara saringan streamer media. Contone, ing saringan MS_L16_ENC, sing ngatur ulang bait ing conto saka urutan jaringan menyang urutan inang: l16.c

Ing artikel sabanjure, kita bakal ndeleng masalah ngira beban ing ticker lan cara kanggo ngatasi beban komputasi sing berlebihan ing streamer media.

Source: www.habr.com

Add a comment