{"id":79540,"date":"2020-04-28T07:42:01","date_gmt":"2020-04-28T05:42:01","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11"},"modified":"2020-04-28T07:42:01","modified_gmt":"2020-04-28T05:42:01","slug":"izuchaem-voip-dvizhok-mediastreamer2-chast-11","status":"publish","type":"post","link":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11","title":{"rendered":"A Mediastreamer2 VoIP motor tanulm\u00e1nyoz\u00e1sa. 11. r\u00e9sz","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>A cikk anyaga az \u00e9n <noindex><a rel=\"nofollow\" href=\"https:\/\/zen.yandex.ru\/profile\/editor\/id\/5e3f8e0751f5346faab4fc7a\">Dzen csatorn\u00e1mb\u00f3l sz\u00e1rmazik<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"A Mediastreamer2 VoIP motor tanulm\u00e1nyoz\u00e1sa. 11. r\u00e9sz\" src=\"\/wp-content\/uploads\/2020\/04\/b66fab43eb45c626c50f0383dcfa7cca.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Adatok \u00e1thelyez\u00e9si mechanizmusa<\/p>\n<p><\/p>\n<ul>\n<li>dblk_t adatblokk<\/li>\n<li>mblk_t \u00fczenet<\/li>\n<li>mblk_t \u00fczenetekkel kapcsolatos funkci\u00f3k<\/li>\n<li>queue_t sor<\/li>\n<li>queue_t sorokkal kapcsolatos funkci\u00f3k<\/li>\n<li>Sz\u0171r\u0151k kapcsolata<\/li>\n<li>Jelz\u00e9si pont az adatfeldolgoz\u00f3 gr\u00e1fban<\/li>\n<li>A ticker m\u00f6g\u00f6tti tev\u00e9kenys\u00e9g<\/li>\n<li>Pufferel\u0151 (MSBufferizer)<\/li>\n<li>MSBufferizer-rel kapcsolatos funkci\u00f3k<\/li>\n<\/ul>\n<p><\/p>\n<p>A m\u00faltban <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/497932\/\">a Spotify d\u00f6nt\u00e9shozatali m\u00f3dszertan\u00e1r\u00f3l. Egyre t\u00f6bb felhaszn\u00e1l\u00f3 prefer\u00e1lja a zenehallgat\u00e1st mobilon a streaming szolg\u00e1ltat\u00e1sban, de a c\u00e9gn\u00e9l t\u00falnyom\u00f3r\u00e9szt webprogramoz\u00f3k dolgoznak. A Spotify elemezte ezt a helyzetet, \u00e9s \u00fagy d\u00f6nt\u00f6tt, hogy t\u00f6bb mobilfejleszt\u0151t vesz fel, valamint \u00e1tnevezi a webes szakembereket \u00faj ir\u00e1nyba:<\/a><\/noindex> Kifejlesztett\u00fck a saj\u00e1t sz\u0171r\u0151nket. Ehhez a cikkhez az adatok sz\u0171r\u0151k k\u00f6z\u00f6tti bels\u0151 \u00e1thelyez\u00e9si mechanizmus\u00e1ra f\u00f3kusz\u00e1lunk. Ez lehet\u0151v\u00e9 teszi, hogy a j\u00f6v\u0151ben kifinomultabb sz\u0171r\u0151ket \u00edrjunk kevesebb er\u0151fesz\u00edt\u00e9ssel.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"mehanizm-peremescheniya-dannyh\">Adatok \u00e1thelyez\u00e9si mechanizmusa<\/h2>\n<p><\/p>\n<p>Az adatok \u00e1thelyez\u00e9se a mediastreamerben a k\u00f6vetkez\u0151 strukt\u00far\u00e1val le\u00edrt sorok seg\u00edts\u00e9g\u00e9vel t\u00f6rt\u00e9nik <em>queue_t<\/em>. A sorokban \u00fczenetl\u00e1ncok mozognak, amelyek t\u00edpusa <em>mblk_t<\/em>, amelyek \u00f6n\u00e1ll\u00f3an nem tartalmazz\u00e1k a jeladatszign\u00e1lt, hanem csak hivatkoz\u00e1sokat a megel\u0151z\u0151, k\u00f6vetkez\u0151 \u00fczenetre \u00e9s az adatblokkokra. Tov\u00e1bb\u00e1 k\u00fcl\u00f6n\u00f6s hangs\u00falyt szeretn\u00e9k fektetni arra, hogy van egy mez\u0151, amely hivatkozhat egy azonos t\u00edpus\u00fa \u00fczenetre, amely lehet\u0151v\u00e9 teszi az \u00fczenetekb\u0151l \u00e1ll\u00f3 egyir\u00e1ny\u00fa lista l\u00e9trehoz\u00e1s\u00e1t. Az ilyen list\u00e1val \u00f6sszekapcsolt \u00fczenetek csoportj\u00e1t halmaznak nevezz\u00fck. \u00cdgy b\u00e1rmely sorban l\u00e9v\u0151 elem lehet egyetlen \u00fczenet <em>mblk_t<\/em>, vagy lehet a halmaz els\u0151 \u00fczenete <em>mblk_t<\/em>. Minden halmazbeli \u00fczenetnek lehet saj\u00e1t adatblokkjai. Az\u00e9rt van sz\u00fcks\u00e9g a halmazokra, ezt k\u00e9s\u0151bb meg fogjuk vitatni.<\/p>\n<p><\/p>\n<p>Ahogy az el\u0151bb eml\u00edtett\u00fck, a saj\u00e1t mag\u00e1ban vett \u00fczenet nem tartalmaz adatblokkot, csup\u00e1n egy hivatkoz\u00e1st tartalmaz arra a mem\u00f3riater\u00fcletre, ahol a blokk t\u00e1rol\u00f3dik. Ez a r\u00e9sz a m\u00e9dia streamel\u0151 m\u0171k\u00f6d\u00e9s\u00e9nek \u00f6sszk\u00e9p\u00e9t egy mes\u00e9beli ajt\u00f3 rakt\u00e1rhoz hasonl\u00edtja, ahol az ajt\u00f3k (az adatok hivatkoz\u00e1sai \u2014 szob\u00e1k) \u0151r\u00fclt sebess\u00e9ggel mozognak felf\u00fcggesztett sz\u00e1ll\u00edt\u00f3szalagokon, mik\u00f6zben maguk a szob\u00e1k mozdulatlanok maradnak. <\/p>\n<p><\/p>\n<p>Most, l\u00e9p\u00e9sr\u0151l l\u00e9p\u00e9sre magyar\u00e1zzuk el az adatok \u00e1tad\u00e1s\u00e1nak mechanizmus\u00e1nak r\u00e9szleteit a mediastreamerben.<\/p>\n<p><\/p>\n<h3 id=\"blok--dannyh-dblk_t\">Adatblokk <em>dblk_t<\/em><\/h3>\n<p><\/p>\n<p>Az adatblokk egy fejl\u00e9cb\u0151l \u00e9s egy adatpufferb\u0151l \u00e1ll. A fejl\u00e9cet az al\u00e1bbi strukt\u00fara \u00edrja le,<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct datab\n{\nunsigned char *db_base; \/\/ Pointer az adatpuffer kezdet\u00e9re.\nunsigned char *db_lim;  \/\/ Pointer az adatpuffer v\u00e9g\u00e9re.\nvoid (*db_freefn)(void*); \/\/ Mem\u00f3riafelszabad\u00edt\u00f3 f\u00fcggv\u00e9ny a blokk t\u00f6rl\u00e9s\u00e9n\u00e9l.\nint db_ref; \/\/ Hivatkoz\u00e1ssz\u00e1ml\u00e1l\u00f3.\n} dblk_t;<\/code><\/pre>\n<p><\/p>\n<p>A strukt\u00far\u00e1k mez\u0151i tartalmazz\u00e1k a puffer kezdet\u00e9nek \u00e9s v\u00e9g\u00e9nek mutat\u00f3it, valamint az adatpuffer elt\u00e1vol\u00edt\u00e1s\u00e1nak funkci\u00f3j\u00e1t. Az utols\u00f3 elem a fejl\u00e9cben <em>db_ref<\/em> \u2014 hivatkoz\u00e1si sz\u00e1ml\u00e1l\u00f3, ha null\u00e1ra cs\u00f6kken, ez a jelz\u00e9s az \u00e9rintett blokk mem\u00f3ri\u00e1b\u00f3l val\u00f3 elt\u00e1vol\u00edt\u00e1s\u00e1ra. Ha az adatblokkot a <em>datab_alloc() <\/em>f\u00fcggv\u00e9ny hozta l\u00e9tre, akkor az adatpuffer k\u00f6zvetlen\u00fcl a fejl\u00e9c ut\u00e1n helyezkedik el a mem\u00f3ri\u00e1ban. Minden m\u00e1s esetben az adatpuffer k\u00fcl\u00f6n helyen lehet. Az adatpufferben a jelz\u00e9si sz\u00e1ml\u00e1l\u00f3k vagy m\u00e1s adatok tal\u00e1lhat\u00f3k, amelyeket sz\u0171r\u0151k\u00f6n kereszt\u00fcl szeretn\u00e9nk feldolgozni.<\/p>\n<p><\/p>\n<p>Egy \u00faj adatblokk p\u00e9ld\u00e1ny\u00e1t a k\u00f6vetkez\u0151 f\u00fcggv\u00e9nnyel hozzuk l\u00e9tre:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">dblk_t *datab_alloc(int size);<\/code><\/pre>\n<p><\/p>\n<p>A bemeneti param\u00e9terk\u00e9nt az adat m\u00e9ret\u00e9t adjuk meg, amelyet a blokk t\u00e1rolni fog. A mem\u00f3ria egy r\u00e9sze t\u00f6bbet foglal mag\u00e1ba, hogy a lefoglalt mem\u00f3ria elej\u00e9n elhelyezhess\u00fck a fejl\u00e9cet - a <em>datab<\/em>strukt\u00far\u00e1t. De m\u00e1s f\u00fcggv\u00e9nyek haszn\u00e1latakor ez nem mindig \u00edgy van, bizonyos esetekben az adatpuffer k\u00fcl\u00f6n helyen helyezkedik el az adatblokk fejl\u00e9c\u00e9t\u0151l. A vil\u00e1gban a strukt\u00far\u00e1k mez\u0151it \u00fagy \u00e1ll\u00edtj\u00e1k be, hogy a <em>db_base<\/em> a adatok ter\u00fclet\u00e9nek kezdet\u00e9re mutasson, m\u00edg <em>db_lim<\/em> a v\u00e9ge fel\u00e9 mutasson. A hivatkoz\u00e1si sz\u00e1ml\u00e1l\u00f3 <em>db_ref<\/em> 1-re van be\u00e1ll\u00edtva. Az adat t\u00f6rl\u00e9si funkci\u00f3 mutat\u00f3j\u00e1t null\u00e1ra \u00e1ll\u00edtj\u00e1k.<\/p>\n<p><\/p>\n<h3 id=\"soobschenie-mblk_t\">\u00dczenet <em>mblk_t<\/em><\/h3>\n<p><\/p>\n<p>Ahogy mondtuk, a sor elemei a k\u00f6vetkez\u0151 t\u00edpus\u00faak: <em>mblk_t,<\/em> \u00e9s a k\u00f6vetkez\u0151k\u00e9ppen van meghat\u00e1rozva:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct msgb\n{\n  struct msgb *b_prev;   \/\/ A lista el\u0151z\u0151 elem\u00e9re mutat\u00f3 mutat\u00f3.\n  struct msgb *b_next;   \/\/ A lista k\u00f6vetkez\u0151 elem\u00e9re mutat\u00f3 mutat\u00f3.\n  struct msgb *b_cont;   \/\/ Egy m\u00e1sik \u00fczenethez val\u00f3 kapcsol\u00f3d\u00e1sra szolg\u00e1l\u00f3 mutat\u00f3, \u00fczenetcsomagok l\u00e9trehoz\u00e1s\u00e1hoz.\n  struct datab *b_datap; \/\/ Az adatblokk strukt\u00far\u00e1j\u00e1ra mutat\u00f3 mutat\u00f3.\n  unsigned char *b_rptr; \/\/ Az b_datap pufferrel kapcsolatos adatok olvas\u00e1s\u00e1ra szolg\u00e1l\u00f3 ter\u00fclet kezdet\u00e9re mutat\u00f3 mutat\u00f3.\n  unsigned char *b_wptr; \/\/ Az b_datap pufferrel kapcsolatos adatok \u00edr\u00e1s\u00e1ra szolg\u00e1l\u00f3 ter\u00fclet kezdet\u00e9re mutat\u00f3 mutat\u00f3.\n  uint32_t reserved1;    \/\/ 1. fenntartott mez\u0151, amelybe a m\u00e9diastreamer seg\u00e9dinform\u00e1ci\u00f3t helyez el.\n  uint32_t reserved2;    \/\/ 2. fenntartott mez\u0151, amelybe a m\u00e9diastreamer seg\u00e9dinform\u00e1ci\u00f3t helyez el.\n  #if defined(ORTP_TIMESTAMP)\n  struct timeval timestamp;\n  #endif\n  ortp_recv_addr_t recv_addr;\n} mblk_t;<\/code><\/pre>\n<p><\/p>\n<p>Strukt\u00fara <em>mblk_t<\/em> a kezdeti mutat\u00f3k tartalmazz\u00e1k <em>b_prev<\/em>, <em>b_next<\/em>, amelyek a k\u00e9tszeres l\u00e1ncolt lista (amely a sor) kialak\u00edt\u00e1s\u00e1hoz sz\u00fcks\u00e9gesek, <em>queue_t<\/em>). <\/p>\n<p><\/p>\n<p>Ezut\u00e1n a mutat\u00f3 k\u00f6vetkezik <em>b_cont<\/em>, amely csak akkor haszn\u00e1latos, amikor az \u00fczenet beleker\u00fcl a tuple-be. Az utols\u00f3 \u00fczenetben a tuple-ben ez a mutat\u00f3 null\u00e1t ad meg. <\/p>\n<p><\/p>\n<p>Ezut\u00e1n l\u00e1tjuk az adatr\u00e9sz blokkra mutat\u00f3 mutat\u00f3t <em>b_datap<\/em>, amely miatt az \u00fczenet l\u00e9tezik. Ezt k\u00f6vet\u0151en mutat\u00f3k k\u00f6vetkeznek, amelyek a blokk adataira mutatnak a bufferben. A mez\u0151 <em>b_rptr<\/em> megmutatja azt a helyet, ahonnan az adatokat olvasni fogj\u00e1k a bufferr\u0151l. A mez\u0151 <em>b_wptr<\/em> megmutatja azt a helyet, ahonnan az adatok \u00edr\u00e1sra ker\u00fclnek a bufferbe. <\/p>\n<p><\/p>\n<p>A fennmarad\u00f3 mez\u0151k szolg\u00e1lati jelleg\u0171ek, \u00e9s nem kapcsol\u00f3dnak az adat\u00e1tviteli mechanizmus m\u0171k\u00f6d\u00e9s\u00e9hez.<\/p>\n<p><\/p>\n<p>Az al\u00e1bbiakban l\u00e1that\u00f3 egyetlen \u00fczenet neve <em>m1<\/em> \u00e9s az adatr\u00e9sz <em>d1<\/em>.<br \/>\n<img decoding=\"async\" alt=\"A Mediastreamer2 VoIP motor tanulm\u00e1nyoz\u00e1sa. 11. r\u00e9sz\" src=\"\/wp-content\/uploads\/2020\/04\/e6a726b13491832258c1228f03bde802.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nA k\u00f6vetkez\u0151 \u00e1br\u00e1n h\u00e1rom \u00fczenet tuple-je l\u00e1that\u00f3 <em>m1<\/em>, <em>m1_1<\/em>, <em>m1_2<\/em>.<br \/>\n<img decoding=\"async\" alt=\"A Mediastreamer2 VoIP motor tanulm\u00e1nyoz\u00e1sa. 11. r\u00e9sz\" src=\"\/wp-content\/uploads\/2020\/04\/9613feefe9684b9551cd98115faa9a08.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"funkcii-raboty-s-soobscheniyami--mblk_t\">Az \u00fczenetekkel kapcsolatos funkci\u00f3k <em>mblk_t<\/em><\/h3>\n<p><\/p>\n<p>\u00daj \u00fczenet <em>mblk_t<\/em> a k\u00f6vetkez\u0151 funkci\u00f3 seg\u00edts\u00e9g\u00e9vel j\u00f6n l\u00e9tre:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *allocb(int size, int pri); <\/code><\/pre>\n<p><\/p>\n<p>ez \u00faj \u00fczenetet helyez el a mem\u00f3ri\u00e1ban <em>mblk_t<\/em> a megadott m\u00e9ret\u0171 adatblokk <em>m\u00e9ret<\/em>, a m\u00e1sodik argumentum \u2014 <em>pri<\/em> nem haszn\u00e1latos a vizsg\u00e1lt verzi\u00f3ban. Ennek null\u00e1nak kell maradnia. A f\u00fcggv\u00e9ny fut\u00e1sa sor\u00e1n mem\u00f3ria lesz lefoglalva az \u00faj \u00fczenet strukt\u00far\u00e1j\u00e1nak, \u00e9s megh\u00edv\u00e1sra ker\u00fcl a <em>mblk_init()<\/em>, amely null\u00e1zza az \u00f6sszes mez\u0151t a l\u00e9trehozott strukt\u00fara p\u00e9ld\u00e1ny\u00e1ban, majd az el\u0151bb eml\u00edtett m\u00f3don <em>datab_alloc()<\/em>, l\u00e9trehozza az adatbufert. Ezt k\u00f6vet\u0151en a mez\u0151k be\u00e1ll\u00edt\u00e1sa fog megt\u00f6rt\u00e9nni a strukt\u00far\u00e1ban: <\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mp-&gt;b_datap=datab;\nmp-&gt;b_rptr=mp-&gt;b_wptr=datab-&gt;db_base;\nmp-&gt;b_next=mp-&gt;b_prev=mp-&gt;b_cont=NULL;<\/code><\/pre>\n<p><\/p>\n<p>A kimeneten \u00faj \u00fczenetet kapunk inicializ\u00e1lt mez\u0151kkel \u00e9s \u00fcres adatbuferral. Az \u00fczenethez adatok hozz\u00e1ad\u00e1s\u00e1hoz m\u00e1solni kell \u0151ket az adatblokk buffer\u00e9be:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">memcpy(msg-&gt;b_rptr, data, size);<\/code><\/pre>\n<p><\/p>\n<p>ahol <em>data<\/em> \u2014 a forr\u00e1sra mutat\u00f3 mutat\u00f3, \u00e9s <em>m\u00e9ret<\/em> \u2014 az adatok m\u00e9rete.<br \/>\nezut\u00e1n friss\u00edteni kell a \u00edr\u00e1si mutat\u00f3t, hogy ism\u00e9t a buffer szabad ter\u00fcleteinek kezdet\u00e9re mutasson:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">msg-&gt;b_wptr = msg-&gt;b_wptr + size<\/code><\/pre>\n<p><\/p>\n<p>Ha \u00fczenetet kell l\u00e9trehozni egy m\u00e1r megl\u00e9v\u0151 bufferb\u0151l m\u00e1sol\u00e1s n\u00e9lk\u00fcl, akkor a k\u00f6vetkez\u0151 funkci\u00f3 haszn\u00e1lhat\u00f3:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *esballoc(uint8_t *buf, int size, int pri, void (*freefn)(void*)); <\/code><\/pre>\n<p><\/p>\n<p>A funkci\u00f3 az \u00fczenet \u00e9s az adatblokk strukt\u00fara l\u00e9trehoz\u00e1sa ut\u00e1n be\u00e1ll\u00edtja a mutat\u00f3kat az adatokra a c\u00edmhez <em>buf<\/em>. Teh\u00e1t, ebben az esetben az adatbuffer nem helyezkedik el a h\u00f3lyag adatainak c\u00edmkec\u00edm\u00e9t k\u00f6vet\u0151en, ahogy az adatblokknak a funkci\u00f3 \u00e1ltal t\u00f6rt\u00e9n\u0151 l\u00e9trehoz\u00e1sakor volt. <em>datab_alloc()<\/em>A funkci\u00f3nak \u00e1tadott adatpuffer ott marad, ahol volt, de mutat\u00f3k seg\u00edts\u00e9g\u00e9vel az \u00fajonnan l\u00e9trehozott adatblokk fejl\u00e9c\u00e9re utal, amely a kapcsol\u00f3d\u00f3 \u00fczenetre mutat.<\/p>\n<p><\/p>\n<p>Egy \u00fczenethez <em>mblk_t<\/em> t\u00f6bb adatblokk is hozz\u00e1f\u0171zhet\u0151. Ezt a k\u00f6vetkez\u0151 f\u00fcggv\u00e9ny v\u00e9gzi:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t * appendb(mblk_t *mp, const char *data, int size, bool_t pad); <\/code><\/pre>\n<p><\/p>\n<p><em>mp<\/em> \u2014 az \u00fczenet, amelyhez egy \u00faj adatblokkot fognak hozz\u00e1adni;<br \/>\n<em>data<\/em> \u2014 egy blokk mutat\u00f3ja, amelynek a m\u00e1solata ker\u00fcl be az \u00fczenetbe;<br \/>\n<em>m\u00e9ret<\/em> \u2014 az adatok m\u00e9rete;<br \/>\n<em>pad<\/em> \u2014 a mem\u00f3ria m\u00e9ret\u00e9nek 4 b\u00e1jtos hat\u00e1rra val\u00f3 igaz\u00edt\u00e1s\u00e1nak jelz\u0151je (a kieg\u00e9sz\u00edt\u00e9st null\u00e1kkal v\u00e9gzi). <\/p>\n<p><\/p>\n<p>Ha az \u00fczenet megl\u00e9v\u0151 adatpuffer\u00e9ben elegend\u0151 hely van, akkor az \u00faj adatok a m\u00e1r ott l\u00e9v\u0151 adatok v\u00e9g\u00e9hez f\u0171z\u0151dnek. Ha az \u00fczenet adatpuffer\u00e9ben kevesebb mint <em>m\u00e9ret<\/em>szabad hely \u00e1ll rendelkez\u00e9sre, akkor \u00faj \u00fczenetet hoz l\u00e9tre, elegend\u0151 puffer m\u00e9rettel, \u00e9s az adatokat ennek a puffer\u00e9be m\u00e1solja. Ez az \u00faj \u00fczenet az eredetire mutat a mutat\u00f3val <em>b_cont<\/em>. Ebben az esetben az \u00fczenet tuple-\u00e9 alakul. <\/p>\n<p><\/p>\n<p>Ha a tuple-hez \u00fajabb adatblokkot kell hozz\u00e1adni, akkor a k\u00f6vetkez\u0151 f\u00fcggv\u00e9nyt kell haszn\u00e1lni:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void msgappend(mblk_t *mp, const char *data, int size, bool_t pad);<\/code><\/pre>\n<p><\/p>\n<p>Ez megkeresi a tuple utols\u00f3 \u00fczenet\u00e9t (amelynek <em>b_cont<\/em> nulla lesz) \u00e9s megh\u00edvja a f\u00fcggv\u00e9nyt az \u00fczenethez <em>appendb()<\/em>.<\/p>\n<p><\/p>\n<p>Azt az adatm\u00e9retet, amely az \u00fczenetben vagy a tuple-ben van, a k\u00f6vetkez\u0151 f\u00fcggv\u00e9nnyel lehet lek\u00e9rdezni:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">int msgdsize(const mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Ez v\u00e9gigfut az \u00f6sszes \u00fczeneten a tuple-\u00e9rt \u00e9s visszaadja az ezekben a pufferekben l\u00e9v\u0151 adatok \u00f6sszmennyis\u00e9g\u00e9t. Minden \u00fczenet eset\u00e9ben az adatok mennyis\u00e9ge \u00edgy sz\u00e1molhat\u00f3:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\"> mp-&gt;b_wptr - mp-&gt;b_rptr<\/code><\/pre>\n<p><\/p>\n<p>K\u00e9t tuple egyes\u00edt\u00e9s\u00e9re a k\u00f6vetkez\u0151 f\u00fcggv\u00e9nyt haszn\u00e1ljuk:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *concatb(mblk_t *mp, mblk_t *newm);<\/code><\/pre>\n<p><\/p>\n<p>Ez a tuple-hez f\u0171zi <em>newm<\/em> a tuple v\u00e9g\u00e9hez, <em>mp<\/em> \u00e9s visszaadja a kapott tuple utols\u00f3 \u00fczenet\u00e9nek mutat\u00f3j\u00e1t.<\/p>\n<p><\/p>\n<p>Sz\u00fcks\u00e9g eset\u00e9n a tuple-t egyetlen \u00fczenett\u00e9 is lehet alak\u00edtani egyetlen adatblokkra, ezt a k\u00f6vetkez\u0151 f\u00fcggv\u00e9ny v\u00e9gzi:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void msgpullup(mblk_t *mp,int len);<\/code><\/pre>\n<p><\/p>\n<p>ha az argumentum <em>len<\/em> \u22121-re van \u00e1ll\u00edtva, akkor a lefoglalt puffer m\u00e9rete automatikusan ker\u00fcl meghat\u00e1roz\u00e1sra. Ha <em>len<\/em> Ha pozit\u00edv sz\u00e1mot adunk meg, akkor l\u00e9trehoz\u00e1sra ker\u00fcl egy ilyen m\u00e9ret\u0171 puffermem\u00f3ria, \u00e9s ebbe m\u00e1solj\u00e1k a tuple \u00fczeneteinek adatait. Ha a puffermem\u00f3ria megtelik, akkor a m\u00e1sol\u00e1s ezen a ponton le\u00e1ll. Az els\u0151 tuple \u00fczenete egy \u00faj m\u00e9ret\u0171 puffert kap az \u00e1tm\u00e1solt adatokkal. A tov\u00e1bbi \u00fczenetek t\u00f6rl\u0151dnek, \u00e9s a mem\u00f3ria visszaker\u00fcl a heap-re.<\/p>\n<p><\/p>\n<p>Strukt\u00fara t\u00f6rl\u00e9sekor <em>mblk_t<\/em> figyelembe kell venni az adatblokk hivatkoz\u00e1si sz\u00e1m\u00e1t, ha a h\u00edv\u00e1skor <em>freeb()<\/em> az null\u00e1ra cs\u00f6kken, akkor az adatpuffer t\u00f6rl\u0151dik azzal az esem\u00e9nnyel egy\u00fctt <em>mblk_t<\/em>, amire hivatkozik.<\/p>\n<p><\/p>\n<p>\u00daj \u00fczenet mez\u0151inek inicializ\u00e1l\u00e1sa:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void mblk_init(mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Tov\u00e1bbi adatcsomag hozz\u00e1f\u0171z\u00e9se az \u00fczenethez: <\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t * appendb(mblk_t *mp, const char *data, size_t size, bool_t pad);<\/code><\/pre>\n<p><\/p>\n<p>Ha az \u00faj adatok nem f\u00e9rnek el a h\u00edr puffermem\u00f3ri\u00e1j\u00e1nak szabad hely\u00e9n, akkor egy k\u00fcl\u00f6n l\u00e9trehozott \u00fczenet csatlakozik az \u00fczenethez a megfelel\u0151 m\u00e9ret\u0171 pufferral (az els\u0151 \u00fczenetben be\u00e1ll\u00edt\u00f3dik a hivatkoz\u00f3 a hozz\u00e1adott \u00fczenetre) az \u00fczenetet tuple-lev\u00e9 alak\u00edtja.<\/p>\n<p><\/p>\n<p>Adatr\u00e9sz hozz\u00e1ad\u00e1sa a tuple-hoz:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void msgappend(mblk_t *mp, const char *data, size_t size, bool_t pad); <\/code><\/pre>\n<p><\/p>\n<p>A f\u00fcggv\u00e9ny ciklikusan h\u00edvja az appendb()-t.<\/p>\n<p><\/p>\n<p>K\u00e9t tuple egyes\u00edt\u00e9se egybe:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *concatb(mblk_t *mp, mblk_t *newm);<\/code><\/pre>\n<p><\/p>\n<p>\u00dczenet <em>newm<\/em> az lesz csatolva <em>mp<\/em>.<\/p>\n<p><\/p>\n<p>Egyetlen \u00fczenet m\u00e1solat\u00e1nak l\u00e9trehoz\u00e1sa:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *copyb(const mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>A tuple teljes m\u00e1solata az \u00f6sszes adatblokkal:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *copymsg(const mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>A tuple elemei a k\u00f6vetkez\u0151 f\u00fcggv\u00e9ny seg\u00edts\u00e9g\u00e9vel m\u00e1soland\u00f3k <em>copyb()<\/em>.<\/p>\n<p><\/p>\n<p>Egy k\u00f6nny\u0171 m\u00e1solat l\u00e9trehoz\u00e1s\u00e1ra az \u00fczenetr\u0151l <em>mblk_t<\/em>. Ekkor az adatblokk nem m\u00e1sol\u00f3dik, hanem a hivatkoz\u00e1si sz\u00e1m\u00e1t n\u00f6velik <em>db_ref<\/em>:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *dupb(mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Egy k\u00f6nny\u0171 m\u00e1solat l\u00e9trehoz\u00e1sa a tuple-r\u00f3l. Az adatblokkok nem m\u00e1sol\u00f3dnak, csak a hivatkoz\u00e1si sz\u00e1maik n\u00f6vekednek. <em>db_ref<\/em>:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *dupmsg(mblk_t* m);<\/code><\/pre>\n<p><\/p>\n<p>Az \u00f6sszes \u00fczenet \u00f6sszef\u0171z\u00e9se egyetlen \u00fczenett\u00e9:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void msgpullup(mblk_t *mp, size_t len);<\/code><\/pre>\n<p><\/p>\n<p>Ha az argumentum <em>len<\/em> egyenl\u0151 -1-el, akkor a fenntartott puffer m\u00e9rete automatikusan ker\u00fcl meghat\u00e1roz\u00e1sra.<\/p>\n<p><\/p>\n<p>\u00dczenet t\u00f6rl\u00e9se, a tuple t\u00f6rl\u00e9se:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void freemsg(mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Az adatblokk hivatkoz\u00e1si sz\u00e1ma cs\u00f6kken egy egys\u00e9ggel. Ha ezzel egy\u00fctt null\u00e1ra cs\u00f6kken, akkor az adatblokk is t\u00f6rl\u0151dik.<\/p>\n<p><\/p>\n<p>Az \u00fczenet vagy tuple teljes adatmennyis\u00e9g\u00e9nek megsz\u00e1ml\u00e1l\u00e1sa.<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">size_t msgdsize(const mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>\u00dczenet kinyer\u00e9se a sor v\u00e9g\u00e9r\u0151l:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *ms_queue_peek_last (q);<\/code><\/pre>\n<p><\/p>\n<p>Egy \u00fczenet fenntartott mez\u0151inek tartalm\u00e1nak \u00e1tm\u00e1sol\u00e1sa egy m\u00e1sik \u00fczenetbe (val\u00f3j\u00e1ban ezekben a mez\u0151kben a m\u00e9diastreamer \u00e1ltal haszn\u00e1lt z\u00e1szl\u00f3k tal\u00e1lhat\u00f3k):<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_meta_copy(const mblk_t *source, mblk *dest);<\/code><\/pre>\n<p><\/p>\n<h3 id=\"ochered-queue_t\">Sor <em>queue_t<\/em><\/h3>\n<p><\/p>\n<p>A m\u00e9diastreamer \u00fczenetsor egy gy\u0171r\u0171s k\u00e9tdimenzi\u00f3s listak\u00e9nt val\u00f3sul meg. Minden listaelem egy mutat\u00f3t tartalmaz a jel adatait tartalmaz\u00f3 blokkra. Teh\u00e1t csak a blokkokra mutat\u00f3 mutat\u00f3k mozognak a sorban, m\u00edg az adatok maguk mozdulatlanok maradnak. Vagyis csak a r\u00e1juk mutat\u00f3 hivatkoz\u00e1sok mozdulnak.<br \/>\nA sor strukt\u00far\u00e1ja <em>queue_t<\/em>az al\u00e1bbiak szerint l\u00e1that\u00f3:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct _queue\n{\n   mblk_t _q_stopper; \/* \"\u00dcres\" sor elem, nem mutat adatokra, csak a sor kezel\u00e9s\u00e9re szolg\u00e1l. A sor inicializ\u00e1l\u00e1sakor (qinit()) az elk\u00e9pzel\u00e9sei \u00f6nmag\u00e1ra mutatnak. *\/\n   int q_mcount;        \/\/ A sorban l\u00e9v\u0151 elemek sz\u00e1ma.\n} queue_t;<\/code><\/pre>\n<p><\/p>\n<p>A strukt\u00fara tartalmaz egy mez\u0151t \u2014 mutat\u00f3t <em>_q_stopper<\/em> t\u00edpus\u00fa *mblk_t, amely az els\u0151 elemre (\u00fczenetre) mutat a sorban. A strukt\u00fara m\u00e1sodik mez\u0151je a sorban l\u00e9v\u0151 \u00fczenetek sz\u00e1ml\u00e1l\u00f3ja.<br \/>\nAz al\u00e1bbi \u00e1br\u00e1n a q1 nev\u0171 sor l\u00e1that\u00f3, amely 4 \u00fczenetet tartalmaz: m1, m2, m3, m4.<br \/>\n<img decoding=\"async\" alt=\"A Mediastreamer2 VoIP motor tanulm\u00e1nyoz\u00e1sa. 11. r\u00e9sz\" src=\"\/wp-content\/uploads\/2020\/04\/07fc043861edf15e5eb40e49c8ec5e3e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nA k\u00f6vetkez\u0151 \u00e1br\u00e1n a q1 nev\u0171 sor l\u00e1that\u00f3, amely 4 \u00fczenetet tartalmaz: m1, m2, m3, m4. Az m2 \u00fczenet a p\u00e1r headje, amelyhez m\u00e9g k\u00e9t \u00fczenet, m2_1 \u00e9s m2_2 csatlakozik.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"A Mediastreamer2 VoIP motor tanulm\u00e1nyoz\u00e1sa. 11. r\u00e9sz\" src=\"\/wp-content\/uploads\/2020\/04\/8fa7667f3690674a2ee321b4a6c39e1d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"funkcii-raboty-s-ocheredyami-queue_t\">queue_t sorokkal kapcsolatos funkci\u00f3k<\/h3>\n<p><\/p>\n<p>A sor inicializ\u00e1l\u00e1sa:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void qinit(queue_t *q);<\/code><\/pre>\n<p><\/p>\n<p>Mez\u0151 <em>_q_stopper<\/em> (a tov\u00e1bbiakban \"stopper\"-nek nevezve) a funkci\u00f3 inicializ\u00e1lja <em>mblk_init()<\/em>a mutat\u00f3ja az el\u0151z\u0151 \u00e9s a k\u00f6vetkez\u0151 elemnek a saj\u00e1t mag\u00e1ra val\u00f3 mutat\u00e1sra van be\u00e1ll\u00edtva. Az elemek sz\u00e1ml\u00e1l\u00f3ja 0-ra van \u00e1ll\u00edtva.<\/p>\n<p><\/p>\n<p>\u00daj elem (\u00fczenet) hozz\u00e1ad\u00e1sa:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void putq(queue_t *q, mblk_t *m);<\/code><\/pre>\n<p><\/p>\n<p>Az \u00faj elem <em>m<\/em> a lista v\u00e9g\u00e9re van hozz\u00e1adva, a mutat\u00f3k be\u00e1ll\u00edt\u00e1sra ker\u00fclnek, hogy a stopper legyen a k\u00f6vetkez\u0151 elem, m\u00edg \u0151 legyen a stopper el\u0151z\u0151 eleme. Az elemek sz\u00e1ml\u00e1l\u00f3ja n\u00f6vekszik.<\/p>\n<p><\/p>\n<p>Elem elt\u00e1vol\u00edt\u00e1sa a sorb\u00f3l:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t * getq(queue_t *q); <\/code><\/pre>\n<p><\/p>\n<p>azt az \u00fczenetet vonja ki, amely a stoppert k\u00f6veti, az elemek sz\u00e1ml\u00e1l\u00f3ja cs\u00f6kken. Ha a stoppert lesz\u00e1m\u00edtva a sorban nincsenek elemek, akkor 0-t ad vissza.<\/p>\n<p><\/p>\n<p>\u00dczenet besz\u00far\u00e1sa a sorba:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void insq(queue_t *q, mblk_t *emp, mblk_t *mp); <\/code><\/pre>\n<p><\/p>\n<p>Elem <em>mp<\/em> besz\u00far\u00e1sra ker\u00fcl az <em>emp<\/em>. Ha <em>emp<\/em>=0, akkor a \u00fczenet a sor v\u00e9g\u00e9re ker\u00fcl.<\/p>\n<p><\/p>\n<p>\u00dczenet elt\u00e1vol\u00edt\u00e1sa a sor elej\u00e9r\u0151l:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void remq(queue_t *q, mblk_t *mp); <\/code><\/pre>\n<p><\/p>\n<p>Az elemek sz\u00e1ml\u00e1l\u00f3ja cs\u00f6kken.<\/p>\n<p><\/p>\n<p>Az els\u0151 elem mutat\u00f3j\u00e1nak kiolvas\u00e1sa a sorban:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t * peekq(queue_t *q); <\/code><\/pre>\n<p><\/p>\n<p>Minden elem elt\u00e1vol\u00edt\u00e1sa a sorb\u00f3l, maguknak az elemeknek az elt\u00e1vol\u00edt\u00e1s\u00e1val:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void flushq(queue_t *q, int how);<\/code><\/pre>\n<p><\/p>\n<p>Az argumentum <em>how<\/em> nem haszn\u00e1lhat\u00f3. A sorba \u00e1ll\u00edt\u00e1s elemeinek sz\u00e1ml\u00e1l\u00f3ja null\u00e1ra van \u00e1ll\u00edtva.<\/p>\n<p><\/p>\n<p>Makr\u00f3 a sor utols\u00f3 elem\u00e9nek olvas\u00e1si c\u00edm\u00e9re:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t * qlast(queue_t *q);<\/code><\/pre>\n<p><\/p>\n<p>\u00dczenetsorokkal val\u00f3 munka sor\u00e1n figyelembe kell venni, hogy a k\u00f6vetkez\u0151 h\u00edv\u00e1skor <em>ms_queue_put(q, m)<\/em> nulla \u00fczenetre mutat\u00f3 mutat\u00f3val a f\u00fcggv\u00e9ny v\u00e9gtelen ciklusba ker\u00fcl. A programja lefagy. Hasonl\u00f3an viselkedik <em>ms_queue_next(q, m)<\/em>.<\/p>\n<p><\/p>\n<h3 id=\"soedinenie-filtrov\">Sz\u0171r\u0151k kapcsolata<\/h3>\n<p><\/p>\n<p>A fent le\u00edrt sor arra szolg\u00e1l, hogy \u00fczeneteket tov\u00e1bb\u00edtson egyik sz\u0171r\u0151r\u0151l a m\u00e1sikra, vagy egyt\u0151l t\u00f6bb sz\u0171r\u0151h\u00f6z. A sz\u0171r\u0151k \u00e9s k\u00f6zt\u00fck l\u00e9v\u0151 kapcsolatok ir\u00e1ny\u00edtott gr\u00e1fot alkotnak. A sz\u0171r\u0151 bel\u00e9p\u00e9s\u00e9t vagy kil\u00e9p\u00e9s\u00e9t \u00e1ltal\u00e1nos \u00e9rtelemben \"pin\"-nek nevezz\u00fck. A sz\u0171r\u0151k k\u00f6z\u00f6tti kapcsolatok le\u00edr\u00e1s\u00e1ra a m\u00e9dia streamel\u0151 a \"jelz\u0151pont\" fogalm\u00e1t haszn\u00e1lja. A jelz\u0151pont egy strukt\u00fara <em>_MSCPoint<\/em>, amely tartalmazza a sz\u0171r\u0151re mutat\u00f3 mutat\u00f3t \u00e9s a t\u0171 sz\u00e1m\u00e1t, \u00edgy le\u00edrja a sz\u0171r\u0151 egyik bemenet\u00e9nek vagy kimenet\u00e9nek \u00f6sszek\u00f6ttet\u00e9s\u00e9t. <\/p>\n<p><\/p>\n<h4 id=\"signalnaya-tochka-grafa-obrabotki-dannyh\">Jelz\u00e9si pont az adatfeldolgoz\u00f3 gr\u00e1fban<\/h4>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct _MSCPoint{\nstruct _MSFilter *filter; \/\/ A m\u00e9diastream sz\u0171r\u0151re mutat\u00f3 mutat\u00f3.\nint pin; \/\/ Egy bemenet vagy kimenet sz\u00e1m\u00e1t jelenti, azaz a t\u0171t.\n} MSCPoint;\n<\/code><\/pre>\n<p><\/p>\n<p>A sz\u0171r\u0151k t\u0171it null\u00e1r\u00f3l kezd\u0151d\u0151en sz\u00e1mozz\u00e1k. <\/p>\n<p><\/p>\n<p>K\u00e9t t\u0171 \u00f6sszek\u00f6ttet\u00e9s\u00e9t \u00fczenetsoron kereszt\u00fcl a k\u00f6vetkez\u0151 strukt\u00fara \u00edrja le <em>_MSQueue<\/em>, amely tartalmazza az \u00fczenetsort \u00e9s a k\u00e9t jelz\u0151pontra mutat\u00f3 mutat\u00f3kat, amelyeket \u00f6sszekapcsol:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct _MSQueue\n{\nqueue_t q;\nMSCPoint prev;\nMSCPoint next;\n}MSQueue;\n<\/code><\/pre>\n<p><\/p>\n<p>Ezt a strukt\u00far\u00e1t jelz\u0151 linknek nevezz\u00fck. Minden m\u00e9diastream sz\u0171r\u0151 tartalmaz egy bels\u0151 \u00e9s egy k\u00fcls\u0151 linkek t\u00e1bl\u00e1zat\u00e1t (<em>MSQueue<\/em>). A t\u00e1bl\u00e1zatok m\u00e9rete a sz\u0171r\u0151 l\u00e9trehoz\u00e1sakor van megadva, amit m\u00e1r megtett\u00fcnk az export\u00e1lt \"MSFilterDesc\" t\u00edpus\u00fa v\u00e1ltoz\u00f3 seg\u00edts\u00e9g\u00e9vel, amikor a saj\u00e1t sz\u0171r\u0151nket fejlesztett\u00fck. Az al\u00e1bbiakban bemutatott strukt\u00fara le\u00edrja b\u00e1rmely sz\u0171r\u0151t a m\u00e9diastreamben, <em>MSFilterDesc<\/em>, amelyeket n\u00e1lunk saj\u00e1t sz\u0171r\u0151 fejleszt\u00e9se sor\u00e1n figyelembe vettek. A k\u00f6vetkez\u0151 szerkezet bemutatja b\u00e1rmely sz\u0171r\u0151 le\u00edr\u00e1s\u00e1t a m\u00e9diastreamben, <em>MSFilter<\/em>:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">\nstruct _MSFilter{\n    MSFilterDesc *desc;    \n    \/* Mutat\u00f3 a sz\u0171r\u0151 le\u00edr\u00e1s\u00e1ra. *\/\n    \/* V\u00e9dett attrib\u00fatumok, amelyeket nem lehet elmozd\u00edtani vagy elt\u00e1vol\u00edtani, k\u00fcl\u00f6nben megszakad a pluginek m\u0171k\u00f6d\u00e9se. *\/\n    ms_mutex_t lock;      \/* Szelet. *\/\n    MSQueue **inputs;     \/* Bemeneti linkek t\u00e1bl\u00e1ja. *\/\n    MSQueue **outputs;    \/* Kimeneti linkek t\u00e1bl\u00e1ja. *\/\n    struct _MSFactory *factory; \/* Mutat\u00f3 a gy\u00e1rra, amely l\u00e9trehozta ezt a sz\u0171r\u0151 p\u00e9ld\u00e1nyt. *\/\n    void *padding;              \/* Nem haszn\u00e1lt, ha v\u00e9dett mez\u0151ket adnak hozz\u00e1, akkor ker\u00fcl felhaszn\u00e1l\u00e1sra. *\/\n    void *data;                 \/* Mutat\u00f3 egy tetsz\u0151leges strukt\u00far\u00e1ra a sz\u0171r\u0151 bels\u0151 \u00e1llapot\u00e1nak \u00e9s k\u00f6ztes sz\u00e1m\u00edt\u00e1sainak t\u00e1rol\u00e1s\u00e1ra. *\/\n    struct _MSTicker *ticker;   \/* Mutat\u00f3 az \u00f3r\u00e1s objektumra, amelynek nem null\u00e1nak kell lennie, amikor a process() f\u00fcggv\u00e9nyt h\u00edvj\u00e1k. *\/\n    \/*priv\u00e1t attrib\u00fatumok, amelyek b\u00e1rmikor mozgathat\u00f3k \u00e9s megv\u00e1ltoztathat\u00f3k*\/\n    MSList *notify_callbacks; \/* A sz\u0171r\u0151 esem\u00e9nyeinek feldolgoz\u00e1s\u00e1ra haszn\u00e1lt visszah\u00edv\u00e1sok list\u00e1ja. *\/\n    uint32_t last_tick;       \/* Az utols\u00f3 \u00f3ra sz\u00e1ma, amikor a process() h\u00edv\u00e1s t\u00f6rt\u00e9nt. *\/\n    MSFilterStats *stats;     \/* A sz\u0171r\u0151 statisztik\u00e1ja.*\/\n    int postponed_task; \/*Elhalasztott feladatok sz\u00e1ma. Egyes sz\u0171r\u0151k elhalaszthatj\u00e1k az adatok feldolgoz\u00e1s\u00e1t (a process() h\u00edv\u00e1s\u00e1t) t\u00f6bb \u00f3ra alatt.*\/\n    bool_t seen;  \/* A z\u00e1szl\u00f3, amelyet a ticker haszn\u00e1l, hogy jel\u00f6lje, hogy ezt a sz\u0171r\u0151 p\u00e9ld\u00e1nyt m\u00e1r kezelte az adott \u00f3r\u00e1ban.*\/\n};\ntypedef struct _MSFilter MSFilter;\n<\/code><\/pre>\n<p><\/p>\n<p>Miut\u00e1n a C-programunkban a sz\u0171r\u0151ket a sz\u00e1nd\u00e9kunk szerint \u00f6sszekapcsoltuk (de nem csatlakoztattuk a ticert), ezzel egy ir\u00e1ny\u00edtott gr\u00e1fot hoztunk l\u00e9tre, amelynek cs\u00facsai a strukt\u00fara p\u00e9ld\u00e1nyai, <em>MSFilter<\/em>, az \u00e9lek pedig a linkek p\u00e9ld\u00e1nyai. <em>MSQueue<\/em>. <\/p>\n<p><\/p>\n<h3 id=\"zakulisnaya-deyatelnost-tikera\">A ticker m\u00f6g\u00f6tti tev\u00e9kenys\u00e9g<\/h3>\n<p><\/p>\n<p>Amikor azt mondtam, hogy a ticker egy \u00fctemezett sz\u0171r\u0151, akkor nem mondtam el r\u00f3la mindent. A ticker egy objektum, amely f\u00e9rcel a funkci\u00f3k elind\u00edt\u00e1s\u00e1ra. <em>process()<\/em> az \u00f6sszes sz\u0171r\u0151h\u00f6z (gr\u00e1fhoz), amelyhez csatlakozik. Amikor C programunkban csatlakoztatjuk a tickert a gr\u00e1f sz\u0171r\u0151j\u00e9hez, megmutatjuk a tickernak a gr\u00e1fot, amelyet ezent\u00fal kezelni fog, am\u00edg le nem v\u00e1lasztjuk. A csatlakoz\u00e1s ut\u00e1n a ticker elkezdi figyelni az \u00e1ltala megb\u00edzott grafikont, list\u00e1t k\u00e9sz\u00edtve azokr\u00f3l a sz\u0171r\u0151kr\u0151l, amelyek bele tartoznak. An\u00e9lk\u00fcl, hogy k\u00e9tszer \"megsz\u00e1ml\u00e1lna\" egy sz\u0171r\u0151t, megjel\u00f6li a felfedezett sz\u0171r\u0151ket, jel\u00f6l\u0151t \u00e1ll\u00edtva be r\u00e1juk <em>seen<\/em>. A keres\u00e9s az egyes sz\u0171r\u0151k linkjeit tartalmaz\u00f3 t\u00e1bl\u00e1kban t\u00f6rt\u00e9nik. <\/p>\n<p><\/p>\n<p>A bemutat\u00f3 t\u00far\u00e1ja sor\u00e1n a ticker ellen\u0151rzi, hogy van-e a sz\u0171r\u0151k k\u00f6z\u00f6tt legal\u00e1bb egy, amely adatblokk-forr\u00e1sk\u00e9nt m\u0171k\u00f6dik. Ha nincs ilyen, akkor a gr\u00e1f hib\u00e1snak min\u0151s\u00fcl, \u00e9s a ticker v\u00e9szhelyzetben le\u00e1ll.<\/p>\n<p><\/p>\n<p>Ha a gr\u00e1f \"helyesnek\" bizonyul, minden megtal\u00e1lt sz\u0171r\u0151h\u00f6z inicializ\u00e1l\u00f3 f\u00fcggv\u00e9nyt h\u00edvunk meg <em>preprocess()<\/em>. Amikor el\u00e9rkezik a k\u00f6vetkez\u0151 feldolgoz\u00e1si ciklus pillanata (alap\u00e9rtelmezett esetben 10 millisekundumonk\u00e9nt), a ticker el\u0151h\u00edvja a f\u00fcggv\u00e9nyt <em>process()<\/em> minden kor\u00e1bban megtal\u00e1lt forr\u00e1ssz\u0171r\u0151 sz\u00e1m\u00e1ra, majd a lista tov\u00e1bbi sz\u0171r\u0151ire is. Ha a sz\u0171r\u0151nek vannak bel\u00e9p\u0151 linkjei, akkor a f\u00fcggv\u00e9ny megh\u00edv\u00e1sa <em>process()<\/em> ez addig folytat\u00f3dik, am\u00edg a bej\u00f6v\u0151 l\u00e1ncszemek sorai ki nem \u00fcr\u00fclnek. Ezut\u00e1n tov\u00e1bb l\u00e9p a lista k\u00f6vetkez\u0151 sz\u0171r\u0151j\u00e9re, \u00e9s \"\u00e1tforgatja\" azt, am\u00edg a bej\u00f6v\u0151 l\u00e1ncszemek meg nem szabadulnak az \u00fczenetekt\u0151l. A ticker sz\u0171r\u0151r\u0151l sz\u0171r\u0151re l\u00e9p, am\u00edg a lista v\u00e9get nem \u00e9r. Ezzel befejez\u0151dik a ciklus kezel\u00e9se. <\/p>\n<p><\/p>\n<p>Most t\u00e9rj\u00fcnk vissza a tuple-\u00f6kh\u00f6z, \u00e9s besz\u00e9lj\u00fcnk arr\u00f3l, mi\u00e9rt ker\u00fclt be egy ilyen entit\u00e1s a m\u00e9diastreamerbe. \u00c1ltal\u00e1nosan elmondhat\u00f3, hogy az algoritmus sz\u00e1m\u00e1ra sz\u00fcks\u00e9ges adatmennyis\u00e9g, amely a sz\u0171r\u0151n bel\u00fcl m\u0171k\u00f6dik, nem egyezik meg, \u00e9s nem oszthat\u00f3 meg a bej\u00f6v\u0151 adatok puffer\u00e9nek m\u00e9ret\u00e9vel. P\u00e9ld\u00e1ul \u00edrnunk kell egy sz\u0171r\u0151t, amely gyors Fourier-transzform\u00e1ci\u00f3t v\u00e9gez, ami miatt csak olyan adatblokkokat k\u00e9pes kezelni, amelyek m\u00e9rete a kettes hatv\u00e1nyai. Legyen ez 512 minta. Ha az adatokat telefoncsatorna gener\u00e1lja, akkor a bej\u00f6v\u0151 \u00fczenetek adatpuffer\u00e9nek m\u00e9rete 160 minta jelet szolg\u00e1ltat sz\u00e1munkra. K\u00eds\u00e9rt\u00e9sbe eshet\u00fcnk, hogy ne vegy\u00fck le az adatokat a bemenetr\u0151l, am\u00edg el\u00e9rj\u00fck a sz\u00fcks\u00e9ges mennyis\u00e9g\u0171 adatot. De ebben az esetben \u00fctk\u00f6z\u00e9s keletkezik a tickeren, amely eredm\u00e9nytelen\u00fcl pr\u00f3b\u00e1lja meg elforgatni a sz\u0171r\u0151t az bel\u00e9p\u0151 link ki\u00fcr\u00fcl\u00e9s\u00e9ig. Kor\u00e1bban ezt a szab\u00e1lyt a sz\u0171r\u0151 munkafolyamat\u00e1nak harmadik elv\u00e9nek nevezt\u00fck. E szerint az elv szerint a sz\u0171r\u0151 process() f\u00fcggv\u00e9ny\u00e9nek el kell vinnie az \u00f6sszes adatot a bemeneti sorokb\u00f3l.<\/p>\n<p><\/p>\n<p>Ezen k\u00edv\u00fcl a bemenetr\u0151l csak 512 adatot nem lehet kivenni, mivel az adatokat csak eg\u00e9sz blokkokban lehet megszerezni, azaz a sz\u0171r\u0151nek 640 adatot kell megszereznie, \u00e9s az ezekb\u0151l felhaszn\u00e1lt 512 mellett a h\u00e1tral\u00e9v\u0151 r\u00e9szt \u00faj adatok gy\u0171jt\u00e9s\u00e9hez. \u00cdgy a sz\u0171r\u0151nknek, a f\u0151 feladata mellett, seg\u00e9dfeladatokat is kell biztos\u00edtania a bemeneti adatok \u00e1tmeneti t\u00e1rol\u00e1s\u00e1hoz. A m\u00e9diastreamer fejleszt\u0151i ez\u00e9rt kifejlesztett\u00e9k a speci\u00e1lis objektumot \u2013 MSBufferizer (pufferel\u0151), amely ezt a feladatot tuple-\u00f6k seg\u00edts\u00e9g\u00e9vel oldja meg. <\/p>\n<p><\/p>\n<h3 id=\"buferizator-msbufferizer\">Pufferel\u0151 (MSBufferizer)<\/h3>\n<p><\/p>\n<p>Ez az objektum az adatokat felhalmozza a sz\u0171r\u0151 belsej\u00e9ben, \u00e9s elkezdi azokat visszaadni a feldolgoz\u00e1sra, amint az inform\u00e1ci\u00f3 mennyis\u00e9ge elegend\u0151 a sz\u0171r\u0151 algoritmus\u00e1nak v\u00e9grehajt\u00e1s\u00e1hoz. Am\u00edg a pufferel\u0151 adatokat gy\u0171jt, a sz\u0171r\u0151 \u00fcresj\u00e1ratban m\u0171k\u00f6dik, nem terheli a processzor sz\u00e1m\u00edt\u00e1si teljes\u00edtm\u00e9ny\u00e9t. De amint a pufferel\u0151 olvas\u00e1si funkci\u00f3ja nem nulla \u00e9rt\u00e9ket ad vissza, a sz\u0171r\u0151 process() funkci\u00f3ja elkezdi az adatokat puffereli a sz\u00fcks\u00e9ges m\u00e9ret\u0171 adagokban, a felhaszn\u00e1l\u00e1sukig.<br \/>\nA m\u00e9g nem haszn\u00e1lt adatok a pufferel\u0151ben maradnak, mint a tuple els\u0151 eleme, amelyhez a k\u00e9s\u0151bbi bemeneti adatblokkok csatlakoznak. <\/p>\n<p><\/p>\n<p>A pufferel\u0151 le\u00edr\u00f3 strukt\u00far\u00e1ja: <\/p>\n<p><\/p>\n<pre><code class=\"cpp\">struct _MSBufferizer{\nqueue_t q; \/* \u00dczenetk\u00fcld\u0151 sor. *\/\nint size; \/* Jelenleg a pufferel\u0151ben l\u00e9v\u0151 adatok \u00f6sszege. *\/\n};\ntypedef struct _MSBufferizer MSBufferizer;<\/code><\/pre>\n<p><\/p>\n<h3 id=\"funkcii-raboty-s-msbufferizer\">MSBufferizer-rel kapcsolatos funkci\u00f3k<\/h3>\n<p><\/p>\n<p>\u00daj pufferel\u0151 p\u00e9ld\u00e1ny l\u00e9trehoz\u00e1sa:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">MSBufferizer * ms_bufferizer_new(void);<\/code><\/pre>\n<p><\/p>\n<p>Mem\u00f3ria allok\u00e1l\u00f3dik, inicializ\u00e1l\u00f3dik a <em>ms_bufferizer_init()<\/em> \u00e9s a mutat\u00f3 visszat\u00e9r.<\/p>\n<p><\/p>\n<p>Inicializ\u00e1l\u00f3 funkci\u00f3:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_init(MSBufferizer *obj); <\/code><\/pre>\n<p><\/p>\n<p>Az \u00fczenetsor inicializ\u00e1lva <em>q<\/em>, mez\u0151 <em>m\u00e9ret<\/em> null\u00e1ra \u00e1ll\u00edt\u00f3dik.<\/p>\n<p><\/p>\n<p>\u00dczenet hozz\u00e1ad\u00e1sa:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_put(MSBufferizer *obj, mblk_t *m); <\/code><\/pre>\n<p><\/p>\n<p>Az m \u00fczenet hozz\u00e1ad\u00f3dik a sorhoz. A kisz\u00e1m\u00edtott adatmennyis\u00e9g hozz\u00e1ad\u00f3dik a <em>m\u00e9ret<\/em>.<\/p>\n<p><\/p>\n<p>Minden \u00fczenet sorba helyez\u00e9se a linken a pufferel\u0151be <em>q<\/em>:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_put_from_queue(MSBufferizer *obj, MSQueue *q);   <\/code><\/pre>\n<p><\/p>\n<p>\u00dczenet \u00e1tvitel a linken <em>q<\/em> a pufferel\u0151be a <em>ms_bufferizer_put()<\/em>.<\/p>\n<p><\/p>\n<p>funkci\u00f3 seg\u00edts\u00e9g\u00e9vel t\u00f6rt\u00e9nik.<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">Olvas\u00e1s a pufferel\u0151b\u0151l: <\/code><\/pre>\n<p><\/p>\n<p>int ms_bufferizer_read(MSBufferizer *obj, uint8_t *data, int datalen);<em>Ha a pufferel\u0151ben felhalmozott adatok m\u00e9rete kisebb, mint a k\u00e9rt (<\/em>), akkor a funkci\u00f3 nulla \u00e9rt\u00e9ket ad vissza, az adatok m\u00e1sol\u00e1sa a data-ba nem t\u00f6rt\u00e9nik meg. Ellenkez\u0151 esetben az adatok sorozatos m\u00e1sol\u00e1sa v\u00e9gbemegy a pufferekben l\u00e9v\u0151 tuple-\u00f6kb\u0151l. A m\u00e1sol\u00e1s befejez\u0151dik, amikor datalen b\u00e1jt m\u00e1sol\u00e1sa t\u00f6rt\u00e9nik meg. Ha a hely elfogy a data blokk k\u00f6zep\u00e9n, akkor ebben az \u00fczenetben a data blokk a m\u00e9g \u00e1t nem m\u00e1solt r\u00e9szre lesz ler\u00f6vid\u00edtve. A k\u00f6vetkez\u0151 h\u00edv\u00e1sn\u00e1l a m\u00e1sol\u00e1s ett\u0151l a helyt\u0151l folytat\u00f3dik.<\/p>\n<p><\/p>\n<p>Az aktu\u00e1lisan a puffert tartalmaz\u00f3 adatok sz\u00e1ma:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">int ms_bufferizer_get_avail(MSBufferizer *obj); <\/code><\/pre>\n<p><\/p>\n<p>Visszaadja a mez\u0151t <em>m\u00e9ret<\/em> a puffert\u0151l.<\/p>\n<p><\/p>\n<p>Az aktu\u00e1lisan a bufert tartalmaz\u00f3 adatok egy r\u00e9sz\u00e9nek eldob\u00e1sa:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_skip_bytes(MSBufferizer *obj, int bytes);<\/code><\/pre>\n<p><\/p>\n<p>A megadott mennyis\u00e9g\u0171 b\u00e1jt kinyer\u00e9sre ker\u00fcl \u00e9s eldob\u00e1sra. A legr\u00e9gebbi adatok lesznek eldobva.<\/p>\n<p><\/p>\n<p>A puffert tartalmaz\u00f3 \u00f6sszes \u00fczenet t\u00f6rl\u00e9se:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_flush(MSBufferizer *obj); <\/code><\/pre>\n<p><\/p>\n<p>Az adatsz\u00e1ml\u00e1l\u00f3 null\u00e1ra \u00e1ll\u00edt\u00f3dik.<\/p>\n<p><\/p>\n<p>A puffert tartalmaz\u00f3 \u00f6sszes \u00fczenet t\u00f6rl\u00e9se:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_uninit(MSBufferizer *obj); <\/code><\/pre>\n<p><\/p>\n<p>A sz\u00e1ml\u00e1l\u00f3 null\u00e1z\u00e1sa nem t\u00f6rt\u00e9nik meg.<\/p>\n<p><\/p>\n<p>A buffer elt\u00e1vol\u00edt\u00e1sa \u00e9s a mem\u00f3ria felszabad\u00edt\u00e1sa:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_destroy(MSBufferizer *obj);  <\/code><\/pre>\n<p><\/p>\n<p>A buffert haszn\u00e1l\u00f3 p\u00e9ld\u00e1k a m\u00e9diastreamer n\u00e9h\u00e1ny sz\u0171r\u0151j\u00e9nek forr\u00e1sk\u00f3dj\u00e1ban tal\u00e1lhat\u00f3k. P\u00e9ld\u00e1ul az MS_L16_ENC sz\u0171r\u0151, ami a b\u00e1jtok \u00e1trendez\u00e9s\u00e9t v\u00e9gzi a h\u00e1l\u00f3zati sorrendb\u0151l a gazdag\u00e9p sorrendj\u00e9be:<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/BelledonneCommunications\/mediastreamer2\/blob\/1a9e8dec369a65ed10db975f5b77b92dc999b096\/src\/audiofilters\/l16.c\"> l16.c<\/a><\/noindex><\/p>\n<p><\/p>\n<p>A k\u00f6vetkez\u0151 cikkben a ticker terhel\u00e9s\u00e9nek \u00e9rt\u00e9kel\u00e9s\u00e9vel \u00e9s a m\u00e9diastreamerben jelentkez\u0151 t\u00falzott sz\u00e1m\u00edt\u00e1si terhel\u00e9s kezel\u00e9s\u00e9nek m\u00f3djaival foglalkozunk.<\/p>\n<p>Forr\u00e1s: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/499010\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u0437\u044f\u0442 \u0441 \u043c\u043e\u0435\u0433\u043e \u0434\u0437\u0435\u043d-\u043a\u0430\u043d\u0430\u043b\u0430. \u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0411\u043b\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 dblk_t \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 mblk_t \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 mblk_t \u041e\u0447\u0435\u0440\u0435\u0434\u044c queue_t \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043e\u0447\u0435\u0440\u0435\u0434\u044f\u043c\u0438 queue_t \u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u0421\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0433\u0440\u0430\u0444\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0417\u0430\u043a\u0443\u043b\u0438\u0441\u043d\u0430\u044f \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043a\u0435\u0440\u0430 \u0411\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0442\u043e\u0440 (MSBufferizer) \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 MSBufferizer \u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440. \u042d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u044b \u043f\u043e\u0441\u0432\u0435\u0442\u0438\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":79541,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-79540","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u0437\u044f\u0442 \u0441 \u043c\u043e\u0435\u0433\u043e \u0434\u0437\u0435\u043d-\u043a\u0430\u043d\u0430\u043b\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"hu_HU\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0418\u0437\u0443\u0447\u0430\u0435\u043c VoIP-\u0434\u0432\u0438\u0436\u043e\u043a Mediastreamer2. \u0427\u0430\u0441\u0442\u044c 11 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u0437\u044f\u0442 \u0441 \u043c\u043e\u0435\u0433\u043e \u0434\u0437\u0435\u043d-\u043a\u0430\u043d\u0430\u043b\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-04-28T05:42:01+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-04-28T05:42:01+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Fedezz\u00fck fel a Mediastreamer2 VoIP motort. 11. r\u00e9sz | ProHoster","description":"A cikk anyaga a Dzen-csatorn\u00e1mb\u00f3l sz\u00e1rmazik.","canonical_url":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hu_HU","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0418\u0437\u0443\u0447\u0430\u0435\u043c VoIP-\u0434\u0432\u0438\u0436\u043e\u043a Mediastreamer2. \u0427\u0430\u0441\u0442\u044c 11 | ProHoster","og:description":"\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u0437\u044f\u0442 \u0441 \u043c\u043e\u0435\u0433\u043e \u0434\u0437\u0435\u043d-\u043a\u0430\u043d\u0430\u043b\u0430.","og:url":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-04-28T05:42:01+00:00","article:modified_time":"2020-04-28T05:42:01+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"79540","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:40:33","updated":"2022-10-06 16:26:59","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/79540","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/comments?post=79540"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/79540\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media\/79541"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media?parent=79540"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/categories?post=79540"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/tags?post=79540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}