Ngajalajah mesin Mediastreamer2 VoIP. Bagian 11

Materi artikel dicokot ti abdi saluran zen.

Ngajalajah mesin Mediastreamer2 VoIP. Bagian 11

Mékanisme gerak data

  • Blok data dblk_t
  • Pesen mblk_t
  • Fungsi pikeun gawé bareng pesen mblk_t
  • Antrian antrian_t
  • Fungsi pikeun gawé bareng antrian queue_t
  • Nyambungkeun saringan
  • Titik sinyal grafik ngolah data
  • Di balik layar kagiatan ticker
  • Panyangga (MSBufferizer)
  • Fungsi pikeun gawé bareng MSBufferizer

Di tempo anu kalangkung artikel kami geus ngembangkeun filter sorangan. Artikel ieu bakal difokuskeun mékanisme internal pikeun mindahkeun data antara saringan streamer média. Ieu bakal ngidinan Anjeun pikeun nulis saringan canggih kalawan kirang usaha dina mangsa nu bakal datang.

Mékanisme gerak data

Gerakan data dina streamer média dipigawé maké antrian digambarkeun ku struktur antrian_t. String pesen sapertos mblk_t, nu sorangan teu ngandung data sinyal, tapi ngan numbu ka saméméhna, pesen salajengna jeung ka blok data. Sajaba ti éta, abdi hoyong utamana ngantebkeun yén aya ogé sawah pikeun tumbu ka pesen tina tipe sarua, nu ngidinan Anjeun pikeun ngatur daptar pesen numbu tunggal. Kami bakal nyauran grup pesen anu dihijikeun ku daptar sapertos kitu tuple. Ku kituna, sagala unsur antrian tiasa pesen tunggal mblk_t, sarta meureun kapala tuple pesen mblk_t. Unggal pesen tuple tiasa gaduh blok data bangsal sorangan. Urang bakal ngabahas naha tuples diperlukeun saeutik engké.

Sakumaha didadarkeun di luhur, suratna sorangan henteu ngandung blok data, tapi ngan ngandung pointer ka wewengkon memori dimana blok disimpen. Dina bagian ieu, gambar sakabéh karya streamer média téh reminiscent tina gudang panto dina kartun "Monsters, Inc.," dimana panto (numbu ka data - kamar) gerak dina laju gélo sapanjang conveyors overhead, sedengkeun kamar sorangan. tetep teu obah.

Ayeuna, pindah sapanjang hirarki ti handap ka luhur, hayu urang mertimbangkeun sacara rinci éntitas didaptarkeun mékanisme pangiriman data dina streamer média.

Blok data dblk_t

Blok data diwangun ku header sareng panyangga data. lulugu digambarkeun ku struktur handap,

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

Widang struktur ngandung pointers ka awal panyangga, tungtung panyangga, sarta fungsi pikeun mupus panyangga data. Unsur pamungkas dina lulugu db_ref - counter rujukan, lamun ngahontal enol, ieu boga fungsi minangka sinyal pikeun mupus blok ieu ti memori. Lamun blok data dijieun ku fungsi datab_alloc() , teras panyangga data bakal disimpen dina mémori langsung saatos lulugu. Dina sakabeh kasus sejenna, panyangga bisa lokasina wae misah. Panyangga data bakal ngandung conto sinyal atanapi data sanés anu badé diolah ku saringan.

Hiji conto anyar tina blok data dijieun ngagunakeun fungsi:

dblk_t *datab_alloc(int size);

Salaku parameter input, éta dibéré ukuran data anu blok bakal disimpen. Langkung seueur mémori dialokasikeun pikeun nempatkeun header - struktur - dina awal mémori anu dialokasikeun datab. Tapi nalika nganggo fungsi anu sanés, ieu henteu salawasna kajantenan; dina sababaraha kasus, panyangga data tiasa ditempatkeun sacara misah ti header blok data. Nalika nyieun struktur, sawah dikonpigurasi supados sawahna db_base nunjuk ka awal wewengkon data, jeung db_lim ka tungtung na. Jumlah link db_ref disetel ka hiji. Pointer fungsi jelas data disetel ka nol.

pesen mblk_t

Sakumaha anu dinyatakeun, unsur antrian mangrupikeun jinis mblk_t, eta didefinisikeun kieu:

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 ngandung pointers di awal b_saméméhna, b_next, anu diperlukeun pikeun ngatur daptar numbu ganda (anu mangrupa antrian antrian_t).

Lajeng datang pointer b_terus, nu ngan dipaké nalika pesen mangrupa bagian tina tuple a. Pikeun pesen panungtungan dina tuple, pointer ieu tetep null.

Salajengna urang ningali pointer ka blok data b_datap, nu pesen aya. Ieu dituturkeun ku pointers ka wewengkon jero panyangga data block. Sawah b_rptr nangtukeun lokasi ti mana data ti panyangga bakal dibaca. Sawah b_wptr nunjukkeun lokasi ti mana nyerat kana panyangga bakal dilaksanakeun.

Widang sésana nyaéta sipat jasa sareng henteu aya hubunganana sareng operasi mékanisme transfer data.

Di handap ieu pesen tunggal kalawan ngaran m1 jeung blok data d1.
Ngajalajah mesin Mediastreamer2 VoIP. Bagian 11
Gambar di handap nembongkeun tuple tina tilu pesen m1, m1_1, m1_2.
Ngajalajah mesin Mediastreamer2 VoIP. Bagian 11

fungsi talatah mblk_t

Pesen anyar mblk_t dijieun ku fungsi:

mblk_t *allocb(int size, int pri); 

manehna nempatkeun pesen anyar dina mémori mblk_t kalayan blok data tina ukuran anu ditangtukeun ukuran, argumen kadua - pri teu dipaké dina versi ieu perpustakaan. Sakuduna tetep nol. Salila operasi fungsi, memori bakal dialokasikeun pikeun struktur pesen anyar jeung fungsi bakal disebut mblk_init(), anu bakal ngareset sadaya widang tina conto anu didamel tina struktur teras, nganggo anu disebatkeun di luhur datab_alloc(), bakal nyieun panyangga data. Saatos éta widang dina struktur bakal dikonpigurasi:

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

Dina kaluaran kami nampi pesen anyar kalayan widang anu diinisialisasi sareng panyangga data kosong. Pikeun nambihan data kana pesen, anjeun kedah nyalin kana panyangga blok data:

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

di mana data mangrupa pointer kana sumber data, jeung ukuran - ukuran maranéhanana.
teras anjeun kedah ngapdet pointer ka titik nyerat supados nunjuk deui ka awal daérah bébas dina panyangga:

msg->b_wptr = msg->b_wptr + size

Upami anjeun kedah nyiptakeun pesen tina panyangga anu tos aya, tanpa nyalin, teras nganggo fungsina:

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

Fungsina, saatos nyiptakeun pesen sareng struktur blok data, bakal ngonpigurasikeun petunjukna kana data dina alamatna tukang meuli. Jelema. Dina hal ieu, panyangga data henteu aya saatos kolom header blok data, sapertos anu aya nalika nyiptakeun blok data kalayan fungsina. datab_alloc(). Panyangga sareng data anu disayogikeun kana fungsina bakal tetep dimana éta, tapi kalayan bantosan petunjuk éta bakal napel kana header blok data anu nembé diciptakeun, sareng éta, sasuai, kana pesen.

Ka hiji pesen mblk_t Sababaraha blok data tiasa dihijikeun sacara berurutan. Hal ieu dilakukeun ku fungsi:

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

mp - pesen anu bakal ditambah blok data anu sanés;
data - pointer ka blok, salinan nu bakal ditambahkeun kana pesen;
ukuran - ukuran data;
Pad - a bandéra yén ukuran memori disadiakeun kudu Blok sapanjang wates 4-bait (padding bakal dilakukeun kalawan nol).

Upami aya cukup rohangan dina panyangga data pesen anu tos aya, maka data énggal bakal ditempelkeun di tukangeun data anu parantos aya. Lamun aya kirang spasi bébas dina panyangga data pesen ti ukuran, teras pesen anyar didamel kalayan ukuran panyangga anu cekap sareng data disalin kana panyangga na. Ieu pesen anyar, numbu ka aslina maké pointer a b_terus. Dina hal ieu, pesen robah jadi tuple a.

Upami anjeun kedah nambihan blok data anu sanés kana tuple, maka anjeun kedah nganggo fungsina:

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

anjeunna bakal mendakan pesen anu terakhir dina tuple (anjeunna gaduh b_terus bakal null) sarta bakal nelepon fungsi pikeun pesen ieu appendb().

Anjeun tiasa mendakan ukuran data dina pesen atanapi tuple nganggo fungsi:

int msgdsize(const mblk_t *mp);

eta bakal loop ngaliwatan sagala pesen dina tuple jeung balik jumlah total data dina buffers data pesen maranéhanana. Pikeun unggal pesen, jumlah data diitung kieu:

 mp->b_wptr - mp->b_rptr

Pikeun ngagabungkeun dua tuple, paké fungsi:

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

manehna nambahan tuple newm kana buntut tuple mp sarta mulih pointer ka pesen panungtungan tina tuple hasilna.

Upami diperlukeun, tuple tiasa janten hiji pesen kalayan blok data tunggal; ieu dilakukeun ku fungsi:

void msgpullup(mblk_t *mp,int len);

lamun argumen Ilen nyaeta -1, lajeng ukuran panyangga disadiakeun ditangtukeun otomatis. Lamun Ilen mangrupakeun angka positif, panyangga tina ukuran ieu bakal dijieun jeung data pesen tuple bakal disalin kana eta. Lamun panyangga béak, nyalin bakal eureun di dinya. Pesen mimiti tuple bakal nampi panyangga ukuran énggal sareng data anu disalin. Sesa seratan bakal dipupus sarta mémori balik ka numpuk.

Nalika ngahapus struktur mblk_t jumlah rujukan tina blok data dicokot kana akun lamun, nalika nelepon bébasb() tétéla enol, teras panyangga data dihapus babarengan jeung conto mblk_t, nu nunjuk ka eta.

Initializing widang pesen anyar:

void mblk_init(mblk_t *mp);

Nambahkeun sapotong data anu sanés kana pesen:

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

Upami data anyar henteu pas kana rohangan bébas tina panyangga data pesen, maka pesen anu diciptakeun sacara misah sareng panyangga ukuran anu diperyogikeun dipasang dina pesen (penunjuk kana pesen anu ditambahan diatur dina pesen anu munggaran) sareng pesen robah jadi tuple a.

Nambahkeun sapotong data kana tuple a:

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

Fungsi nelepon appendb () dina loop a.

Ngagabungkeun dua tuple jadi hiji:

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

pesen newm bakal napel na mp.

Nyieun salinan hiji pesen:

mblk_t *copyb(const mblk_t *mp);

Nyalin lengkep tuple sareng sadaya blok data:

mblk_t *copymsg(const mblk_t *mp);

Unsur tuple disalin ku fungsi copyb().

Jieun salinan gampang pesen mblk_t. Dina hal ieu, blok data teu disalin, tapi counter rujukan na ngaronjat db_ref:

mblk_t *dupb(mblk_t *mp);

Nyieun salinan lightweight tina tuple a. Blok data henteu ditiron, ngan ukur konter rujukanna ditambah db_ref:

mblk_t *dupmsg(mblk_t* m);

Gluing sadaya pesen tina tuple kana hiji pesen:

void msgpullup(mblk_t *mp,size_t len);

Lamun argumen Ilen nyaeta -1, lajeng ukuran panyangga disadiakeun ditangtukeun otomatis.

Ngahapus pesen, tuple:

void freemsg(mblk_t *mp);

Jumlah rujukan blok data dikurangan ku hiji. Lamun ngahontal enol, blok data ogé dihapus.

Itungan jumlah total data dina pesen atawa tuple.

size_t msgdsize(const mblk_t *mp);

Meunangkeun pesen tina buntut antrian:

mblk_t *ms_queue_peek_last (q);

Nyalin eusi kolom anu dicadangkeun tina hiji pesen ka pesen anu sanés (saleresna, kolom ieu ngandung bandéra anu dianggo ku streamer média):

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

Ngalieuk antrian_t

Antrian pesen dina streamer média dilaksanakeun salaku daptar sirkular doubly numbu. Unggal unsur daptar ngandung hiji pointer ka blok data jeung sampel sinyal. Tétéla éta ngan pointers ka blok data pindah dina gilirannana, bari data sorangan tetep teu gerak. Jelema. ngan Tumbu ka aranjeunna dipindahkeun.
Struktur ngajéntrékeun antrian antrian_t, ditémbongkeun di handap:

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

Struktur ngandung widang - pointer a _q_stoper ngetik *mblk_t, eta nunjuk ka unsur kahiji (pesen) dina antrian. Widang kadua struktur nyaéta counter pesen dina antrian.
Gambar di handap nembongkeun antrian ngaranna q1 ngandung 4 pesen m1, m2, m3, m4.
Ngajalajah mesin Mediastreamer2 VoIP. Bagian 11
Gambar di handap nembongkeun antrian ngaranna q1 ngandung 4 seratan m1,m2,m3,m4. Pesen m2 nyaéta kapala tuple anu ngandung dua deui pesen m2_1 sareng m2_2.

Ngajalajah mesin Mediastreamer2 VoIP. Bagian 11

Fungsi pikeun gawé bareng antrian queue_t

Inisialisasi antrian:

void qinit(queue_t *q);

médan _q_stoper (hereinafter urang bakal nelepon deui "stopper") ieu initialized ku fungsi mblk_init(), elemen saméméhna sarta pointer unsur salajengna disaluyukeun pikeun nunjuk ka sorangan. Counter unsur antrian direset kana nol.

Nambahkeun unsur anyar (pesen):

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

Unsur anyar m ditambahkeun kana tungtung daptar, nu pointers unsur disaluyukeun supados stopper jadi unsur hareup pikeun eta, tur janten unsur saméméhna pikeun stopper nu. The antrian unsur counter ieu incremented.

Retrieving hiji unsur tina antrian:

mblk_t * getq(queue_t *q); 

Pesen nu datang sanggeus stopper nu dicandak, sarta counter unsur ieu decremented. Mun euweuh elemen dina antrian iwal stopper, lajeng 0 balik.

Nyelapkeun pesen kana antrian:

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

Unsur mp diselapkeun saméméh unsur emp. Upami emp=0, teras seratan ditambahkeun kana buntut antrian.

Retrieving pesen ti lulugu antrian:

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

The counter unsur ieu decremented.

Maca pointer ka unsur kahiji dina antrian:

mblk_t * peekq(queue_t *q); 

Nyoplokkeun sadaya elemen tina antrian bari mupus elemen sorangan:

void flushq(queue_t *q, int how);

Argumen kumaha teu dipaké. The counter unsur antrian disetel ka nol.

Makro pikeun maca pointer ka elemen panungtungan antrian:

mblk_t * qlast(queue_t *q);

Nalika damel sareng antrian pesen, perhatikeun yén nalika anjeun nelepon ms_queue_put (q, m) kalawan pointer null mun pesen, fungsi puteran. Program anjeun bakal beku. behaves sarupa ms_queue_next(q, m).

Nyambungkeun saringan

Antrian ditétélakeun di luhur dipaké pikeun ngirimkeun pesen ti hiji saringan ka nu sejen atawa ti hiji ka sababaraha saringan. Saringan sareng sambunganna ngabentuk grafik anu diarahkeun. Input atanapi kaluaran saringan bakal disebut kecap umum "pin". Pikeun ngajelaskeun urutan saringan disambungkeun ka silih, streamer média ngagunakeun konsép "titik sinyal". Titik sinyal nyaéta struktur _MSCPpoint, anu ngandung pointer kana saringan sareng jumlah salah sahiji pin na; sasuai, éta ngajelaskeun sambungan salah sahiji input atanapi kaluaran saringan.

Titik sinyal grafik ngolah data

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

Pin filter nu wilanganana mimitian ti enol.

Sambungan dua pin ku antrian pesen digambarkeun ku struktur _MSQueue, anu ngandung antrian pesen sareng nunjuk kana dua titik sinyal anu dihubungkeun:

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

Urang bakal nelepon struktur ieu link sinyal. Unggal saringan streamer média ngandung tabel link input sareng tabel tautan kaluaran (MSQueue). Ukuran tabel disetél nalika nyiptakeun saringan; kami parantos ngalaksanakeun ieu nganggo variabel anu diékspor MSFilterDesc, nalika urang ngembangkeun filter sorangan. Di handap ieu struktur anu ngajelaskeun saringan naon waé dina streamer média, 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;

Saatos kami nyambungkeun saringan dina program C saluyu sareng rencana kami (tapi henteu nyambungkeun ticker), kami ku kituna nyiptakeun grafik anu diarahkeun, titik-titik anu mangrupikeun conto tina struktur. MSFilter, sarta edges mangrupakeun conto Tumbu MSQueue.

Di balik layar kagiatan ticker

Nalika kuring bébéja yén ticker mangrupikeun saringan pikeun sumber ticks, éta sanés kabeneran ngeunaan éta. Ticker mangrupikeun obyék anu ngajalankeun fungsi dina jam prosés () kabéh saringan sirkuit (grafik) nu disambungkeun. Nalika urang nyambungkeun ticker ka saringan grafik dina program C, urang némbongkeun ticker grafik nu bakal ngadalikeun ti ayeuna nepi ka urang mareuman. Saatos nyambungkeun, ticker mimiti mariksa grafik anu dipercayakeun ka jagana, nyusun daptar saringan anu kalebet éta. Pikeun henteu "ngitung" saringan anu sami dua kali, éta nandaan saringan anu dideteksi ku cara nempatkeun kotak centang di dinya. ditempo. Pilarian dilaksanakeun nganggo tabel tautan anu masing-masing saringan.

Salila tur bubuka na grafik, ticker nu mariksa naha diantara saringan aya sahanteuna hiji nu tindakan minangka sumber blok data. Upami teu aya, maka grafikna dianggap lepat sareng tickerna ngadat.

Lamun grafik tétéla jadi "bener", pikeun tiap filter kapanggih, fungsi disebut pikeun initialization prosés (). Pas momen datang pikeun siklus processing salajengna (unggal 10 milidetik sacara standar), ticker nu nelepon fungsi prosés () pikeun sakabéh saringan sumber kapanggih saméméhna, lajeng pikeun saringan sésana dina daptar. Upami saringan ngagaduhan tautan input, teras jalankeun fungsina prosés () diulang nepi ka antrian link input kosong. Saatos ieu, éta ngalih ka saringan salajengna dina daptar sareng "ngagulung" dugi ka tautan input bébas tina pesen. Ticker pindah ti saringan ka filter nepi ka daptar ends. Ieu nyampurnakeun ngolah siklus.

Ayeuna urang bakal uih deui ka tuples sareng ngobrol ngeunaan naha éntitas sapertos kitu ditambah kana streamer média. Sacara umum, jumlah data diperlukeun ku algoritma operasi di jero filter nu teu coincide jeung teu kakalian tina ukuran buffers data narima di input. Salaku conto, urang nyerat saringan anu ngalaksanakeun transformasi Fourier gancang, anu ku harti ngan ukur tiasa ngolah blok data anu ukuranna kakuatan dua. Hayu éta 512 cacah. Upami data dibangkitkeun ku saluran telepon, maka panyangga data unggal pesen dina inputna bakal mawa urang 160 conto sinyal. Éta pikabitaeun pikeun henteu ngumpulkeun data tina input dugi ka jumlah data anu diperyogikeun aya. Tapi dina hal ieu, tabrakan bakal kajantenan sareng ticker, anu bakal gagal nyobian ngagulung saringan dugi ka tautan input kosong. Saméméhna, urang ditunjuk aturan ieu salaku prinsip katilu filter nu. Numutkeun prinsip ieu, prosés filter urang () fungsi kedah nyandak sakabeh data tina antrian input.

Sajaba ti éta, moal mungkin nyandak ngan 512 sampel tina input, saprak anjeun ngan bisa nyandak sakabeh blok, i.e. saringan kudu nyandak 640 sampel sarta ngagunakeun 512 di antarana, sésana saméméh accumulating bagian anyar data. Ku kituna, saringan urang, sajaba karya utama na, kudu nyadiakeun lampah bantu pikeun neundeun panengah data input. Pamekar tina streamer média jeung solusi pikeun masalah umum ieu geus ngembangkeun hiji objek husus - MSBufferizer (bufferer), nu solves masalah ieu ngagunakeun tuples.

Panyangga (MSBufferizer)

Ieu mangrupikeun obyék anu bakal ngumpulkeun data input dina saringan sareng ngawitan ngirimkeunana pikeun diolah pas jumlah inpormasi cekap pikeun ngajalankeun algoritma saringan. Nalika panyangga ngumpulkeun data, saringan bakal beroperasi dina modeu dianggurkeun, tanpa nganggo kakuatan pamrosésan prosésor. Tapi pas fungsi bacaan ti panyangga nu mulih hiji nilai lian ti enol, prosés () fungsi filter nu dimimitian nyandak tur ngolah data ti panyangga dina porsi tina ukuran diperlukeun, nepika exhausted.
Data anu henteu acan diperyogikeun tetep aya dina panyangga salaku unsur mimiti tuple, dimana blok data input salajengna napel.

Struktur anu ngajelaskeun panyangga:

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

Fungsi pikeun gawé bareng MSBufferizer

Nyieun conto panyangga anyar:

MSBufferizer * ms_bufferizer_new(void);

Mémori dialokasikeun, diinisialisasi dina ms_bufferizer_init() sareng pointer dipulangkeun.

Fungsi Initialization:

void ms_bufferizer_init(MSBufferizer *obj); 

Antrian ieu initializing q, sawah ukuran disetel ka nol.

Nambahkeun pesen:

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

Pesen m ditambahkeun kana antrian. Ukuran diitung tina blok data ditambahkeun kana ukuran.

Mindahkeun sadaya pesen tina antrian data link ka panyangga q:

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

Mindahkeun pesen tina tautan q dina panyangga dipigawé ngagunakeun fungsi ms_bufferizer_put().

Bacaan tina panyangga:

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

Upami ukuran data anu akumulasi dina panyangga kirang ti anu dipénta (datalen), teras fungsina mulih enol, data henteu disalin kana data. Upami teu kitu, nyalin sequential data tina tuples lokasina di panyangga anu dipigawé. Saatos nyalin, tuple dipupus sareng mémori dibébaskeun. Niron ends dina momen nalika bait datalen disalin. Lamun spasi béak di tengah blok data, teras dina pesen ieu, blok data bakal diréduksi jadi bagian uncopyed sésana. Dina waktos salajengna basa Anjeun nelepon, nyalin bakal neruskeun ti titik ieu.

Maca jumlah data anu ayeuna aya dina panyangga:

int ms_bufferizer_get_avail(MSBufferizer *obj); 

Mulih sawah ukuran panyangga.

Piceun bagian tina data dina panyangga:

void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);

Jumlah bait data anu ditangtukeun dicandak sareng dipiceun. Data pangkolotna dipiceun.

Mupus sadaya pesen dina panyangga:

void ms_bufferizer_flush(MSBufferizer *obj); 

Counter data direset ka nol.

Mupus sadaya pesen dina panyangga:

void ms_bufferizer_uninit(MSBufferizer *obj); 

counter teu reset.

Nyoplokkeun panyangga sareng ngabébaskeun mémori:

void ms_bufferizer_destroy(MSBufferizer *obj);  

Conto ngagunakeun panyangga tiasa dipendakan dina kode sumber sababaraha saringan streamer media. Contona, dina saringan MS_L16_ENC, anu nyusun ulang bait dina sampel tina urutan jaringan ka urutan host: l16.c

Dina artikel salajengna, urang bakal ningali masalah estimasi beban dina ticker sareng cara pikeun merangan beban komputasi anu kaleuleuwihan dina streamer média.

sumber: www.habr.com

Tambahkeun komentar