{"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\/sq\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11","title":{"rendered":"Po studiojm\u00eb motorin VoIP Mediastreamer2. Pjesa 11","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Materiali i artikujt \u00ebsht\u00eb marr\u00eb nga kanali im <noindex><a rel=\"nofollow\" href=\"https:\/\/zen.yandex.ru\/profile\/editor\/id\/5e3f8e0751f5346faab4fc7a\">Dzen<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Po studiojm\u00eb motorin VoIP Mediastreamer2. Pjesa 11\" src=\"\/wp-content\/uploads\/2020\/04\/b66fab43eb45c626c50f0383dcfa7cca.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mekanizmi i transferit t\u00eb t\u00eb dh\u00ebnave<\/p>\n<p><\/p>\n<ul>\n<li>Blloku i t\u00eb dh\u00ebnave dblk_t<\/li>\n<li>Mesazhi mblk_t<\/li>\n<li>Funksionet e pun\u00ebs me mesazhet mblk_t<\/li>\n<li>Rradh\u00eb queue_t<\/li>\n<li>Funksionet e pun\u00ebs me rradh\u00ebt queue_t<\/li>\n<li>Lidhja e filtrave<\/li>\n<li>Pika e sinjalizimit n\u00eb grafikun e p\u00ebrpunimit t\u00eb t\u00eb dh\u00ebnave<\/li>\n<li>Aktiviteti pas sken\u00ebs i ticker-it<\/li>\n<li>Bufferi (MSBufferizer)<\/li>\n<li>Funksionet e pun\u00ebs me MSBufferizer<\/li>\n<\/ul>\n<p><\/p>\n<p>N\u00eb t\u00eb kaluar\u00ebn <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/497932\/\">artikulli yn\u00eb<\/a><\/noindex> Ne kemi zhvilluar filtrin ton\u00eb. Ky artikull do t\u00eb p\u00ebrqendrohet n\u00eb strukturen e mekanizmit t\u00eb transferit t\u00eb t\u00eb dh\u00ebnave midis filtreve t\u00eb mediastream-it. Kjo do t\u00eb lejoj\u00eb zhvillimin e filtrave m\u00eb t\u00eb sofistikuar me p\u00ebrpjekje m\u00eb t\u00eb vogla.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"mehanizm-peremescheniya-dannyh\">Mekanizmi i transferit t\u00eb t\u00eb dh\u00ebnave<\/h2>\n<p><\/p>\n<p>Transferi i t\u00eb dh\u00ebnave n\u00eb mediastream b\u00ebhet p\u00ebrmes rradh\u00ebve t\u00eb p\u00ebrshkruara nga struktura <em>queue_t<\/em>. N\u00ebp\u00ebrmjet rradh\u00ebve kalojn\u00eb seri mesazhesh t\u00eb tipit <em>mblk_t<\/em>, t\u00eb cilat nuk p\u00ebrmbajn\u00eb t\u00eb dh\u00ebna sinjali, por vet\u00ebm referenca p\u00ebr mesazhin e m\u00ebparsh\u00ebm, mesazhin e ardhsh\u00ebm dhe bllokun e t\u00eb dh\u00ebnave. P\u00ebr m\u00eb tep\u00ebr, dua t\u00eb theksoj se ka edhe nj\u00eb fush\u00eb q\u00eb referon n\u00eb nj\u00eb mesazh t\u00eb k\u00ebtij lloji, e cila lejon organizimin e nj\u00eb liste t\u00eb lidhur t\u00eb mesazheve. Grupin e mesazheve t\u00eb bashkuara n\u00eb k\u00ebt\u00eb list\u00eb do ta quajm\u00eb tuple. K\u00ebshtu, \u00e7do element i rradh\u00ebs mund t\u00eb jet\u00eb nj\u00eb mesazh individual <em>mblk_t<\/em>, ose mund t\u00eb jet\u00eb edhe krye i tuple-ve t\u00eb mesazheve <em>mblk_t<\/em>. \u00c7do mesazh i tuple-ve mund t\u00eb ket\u00eb bllokun e tij t\u00eb dh\u00ebnave. Pse na nevojiten tuple-t do t\u00eb diskutojm\u00eb pak m\u00eb von\u00eb.<\/p>\n<p><\/p>\n<p>Si e tha m\u00eb par\u00eb, mesazhi vet\u00eb nuk p\u00ebrmban bllok t\u00eb dh\u00ebnash, p\u00ebrkundrazi, ai p\u00ebrmban vet\u00ebm nj\u00eb tregues n\u00eb nj\u00eb zon\u00eb memorjeje ku ruhet blloku. N\u00eb k\u00ebt\u00eb pjes\u00eb, pamja e p\u00ebrgjithshme e funksionimit t\u00eb mediastreamer-it ngjan me depot e dyerve n\u00eb filmin \"Korporata e Monsters\", ku dyert (treguesit e t\u00eb dh\u00ebnave \u2014 dhomat) l\u00ebvizin me nj\u00eb shpejt\u00ebsi t\u00eb \u00e7mendur n\u00ebp\u00ebr konveyor\u00eb t\u00eb varur, nd\u00ebrkoh\u00eb q\u00eb vet\u00eb dhomat mbeten t\u00eb pal\u00ebvizshme. <\/p>\n<p><\/p>\n<p>Tani, duke u ngritur n\u00eb hierarki nga posht\u00eb lart, do t\u00eb shqyrtojm\u00eb n\u00eb detaje entitetet e p\u00ebrmendura t\u00eb mekanizmit t\u00eb transferit t\u00eb t\u00eb dh\u00ebnave n\u00eb mediastream.<\/p>\n<p><\/p>\n<h3 id=\"blok--dannyh-dblk_t\">Blloku i t\u00eb dh\u00ebnave <em>dblk_t<\/em><\/h3>\n<p><\/p>\n<p>Blloku i t\u00eb dh\u00ebnave p\u00ebrb\u00ebhet nga nj\u00eb krye dhe nj\u00eb bufer t\u00eb dh\u00ebnash. Kryesori p\u00ebrshkruhet nga struktura e m\u00ebposhtme,<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct datab\n{\nunsigned char *db_base; \/\/ Tregues p\u00ebr fillimin e buferit t\u00eb t\u00eb dh\u00ebnave.\nunsigned char *db_lim;  \/\/ Tregues p\u00ebr fundin e buferit t\u00eb t\u00eb dh\u00ebnave.\nvoid (*db_freefn)(void*); \/\/ Funksioni i lirimit t\u00eb memories gjat\u00eb fshirjes s\u00eb bllokut.\nint db_ref; \/\/ Numri i referencave.\n} dblk_t;<\/code><\/pre>\n<p><\/p>\n<p>Fushat e struktorit p\u00ebrmbajn\u00eb tregues p\u00ebr fillimin e buffers, p\u00ebrfundimin e buffers, dhe funksionin p\u00ebr t\u00eb fshir\u00eb buffers t\u00eb t\u00eb dh\u00ebnave. Elementi p\u00ebrfundimtar n\u00eb titull <em>db_ref<\/em> \u2014 numri i referencave, n\u00ebse arrin zero, k\u00ebt\u00eb e sh\u00ebnon si sinjal p\u00ebr t\u00eb fshir\u00eb k\u00ebt\u00eb bllok nga memoria. N\u00ebse blloku i t\u00eb dh\u00ebnave \u00ebsht\u00eb krijuar nga funksioni <em>datab_alloc() <\/em>, at\u00ebher\u00eb bufferi i t\u00eb dh\u00ebnave do t\u00eb vendoset n\u00eb memorie menj\u00ebher\u00eb pas titullit. N\u00eb t\u00eb gjitha rastet e tjera, bufferi mund t\u00eb ndodhet n\u00eb ndonj\u00eb vend tjet\u00ebr. N\u00eb bufferin e t\u00eb dh\u00ebnave do t\u00eb vendosen sinjalizime ose t\u00eb dh\u00ebna t\u00eb tjera q\u00eb d\u00ebshirojm\u00eb t'i p\u00ebrpunojm\u00eb me filtre.<\/p>\n<p><\/p>\n<p>Nj\u00eb ekzemplar i ri i bllokut t\u00eb t\u00eb dh\u00ebnave krijohet me funksionin:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">dblk_t *datab_alloc(int size);<\/code><\/pre>\n<p><\/p>\n<p>Si nj\u00eb paramet\u00ebr hyr\u00ebs, i kalon madh\u00ebsin\u00eb e t\u00eb dh\u00ebnave q\u00eb do t\u00eb ruaj\u00eb blloku. Memoria ndahet m\u00eb shum\u00eb, n\u00eb m\u00ebnyr\u00eb q\u00eb n\u00eb fillim t\u00eb memories s\u00eb ndar\u00eb t\u00eb vendoset titulli \u2014 struktura <em>datab<\/em>. Por kur p\u00ebrdoren funksione t\u00eb tjera kjo nuk ndodh gjithmon\u00eb, n\u00eb disa raste bufferi i t\u00eb dh\u00ebnave mund t\u00eb ndodhet ve\u00e7mas nga titulli i bllokut t\u00eb t\u00eb dh\u00ebnave. Fushat e struktur\u00ebs gjat\u00eb krijimit rregullohen n\u00eb m\u00ebnyr\u00eb q\u00eb fusha e saj <em>db_base<\/em> t\u00eb tregoj\u00eb p\u00ebr fillimin e zon\u00ebs s\u00eb t\u00eb dh\u00ebnave, dhe <em>db_lim<\/em> p\u00ebrfundimin e saj. Numri i referencave <em>db_ref<\/em> vendoset n\u00eb nj\u00eb. Treguesi i funksionit p\u00ebr pastrimin e t\u00eb dh\u00ebnave vendoset n\u00eb zero.<\/p>\n<p><\/p>\n<h3 id=\"soobschenie-mblk_t\">Mesazhi <em>mblk_t<\/em><\/h3>\n<p><\/p>\n<p>Si\u00e7 u tha, element\u00ebt e radh\u00ebs kan\u00eb tipin <em>mblk_t,<\/em> \u00ebsht\u00eb p\u00ebrcaktuar si m\u00eb posht\u00eb:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct msgb\n{\n  struct msgb *b_prev;   \\\/\\\/ Treguesi p\u00ebr elementin e m\u00ebparsh\u00ebm t\u00eb list\u00ebs.\n  struct msgb *b_next;   \\\/\\\/ Treguesi p\u00ebr elementin e ardhsh\u00ebm t\u00eb list\u00ebs.\n  struct msgb *b_cont;   \\\/\\\/ Treguesi p\u00ebr t\u00eb lidhur mesazhe t\u00eb tjera me mesazhin, p\u00ebr t\u00eb krijuar nj\u00eb tuple mesazhesh.\n  struct datab *b_datap; \\\/\\\/ Treguesi p\u00ebr struktur\u00ebn e bllokut t\u00eb t\u00eb dh\u00ebnave.\n  unsigned char *b_rptr; \\\/\\\/ Treguesi p\u00ebr fillimin e zon\u00ebs s\u00eb t\u00eb dh\u00ebnave p\u00ebr t\u00eb lexuar t\u00eb dh\u00ebnat e bufferit b_datap.\n  unsigned char *b_wptr; \\\/\\\/ Treguesi p\u00ebr fillimin e zon\u00ebs s\u00eb t\u00eb dh\u00ebnave p\u00ebr t\u00eb shkruar t\u00eb dh\u00ebnat e bufferit b_datap.\n  uint32_t reserved1;    \\\/\\\/ Fushe e rezervuar1, mediastreamer vendos informacion sh\u00ebrbimi aty. \n  uint32_t reserved2;    \\\/\\\/ Fushe e rezervuar2, mediastreamer vendos informacion sh\u00ebrbimi aty.\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>Struktura <em>mblk_t<\/em> n\u00eb fillim p\u00ebrmban treguesit <em>b_prev<\/em>, <em>b_next<\/em>, t\u00eb cil\u00ebt jan\u00eb t\u00eb nevojsh\u00ebm p\u00ebr organizimin e nj\u00eb liste dy-foljesh (cila \u00ebsht\u00eb radha <em>queue_t<\/em>). <\/p>\n<p><\/p>\n<p>Pastaj vjen treguesi <em>b_cont<\/em>, i cili p\u00ebrdoret vet\u00ebm kur mesazhi hyn n\u00eb tupl\u00eb. P\u00ebr mesazhin e fundit n\u00eb tupl\u00eb, ky tregues mbetet zero. <\/p>\n<p><\/p>\n<p>M\u00eb pas shohim nj\u00eb tregues p\u00ebr bllokun e t\u00eb dh\u00ebnave <em>b_datap<\/em>, p\u00ebr t\u00eb cilin ekziston mesazhi. Pas tij vijn\u00eb treguesit n\u00eb zon\u00ebn brenda buffer-it t\u00eb bllokut. Fusha <em>b_rptr<\/em> tregon vendin nga ku do t\u00eb lexohen t\u00eb dh\u00ebnat nga buffer-i. Fusha <em>b_wptr<\/em> tregon vendin nga ku do t\u00eb shkruhen t\u00eb dh\u00ebnat n\u00eb buffer. <\/p>\n<p><\/p>\n<p>Fushat e mbetura jan\u00eb funksionale dhe nuk lidhen me funksionimin e mekanizmit t\u00eb transferimit t\u00eb t\u00eb dh\u00ebnave.<\/p>\n<p><\/p>\n<p>M\u00eb posht\u00eb tregohet nj\u00eb mesazh i vet\u00ebm me emrin <em>m1<\/em> dhe bllokun e t\u00eb dh\u00ebnave <em>d1<\/em>.<br \/>\n<img decoding=\"async\" alt=\"Po studiojm\u00eb motorin VoIP Mediastreamer2. Pjesa 11\" src=\"\/wp-content\/uploads\/2020\/04\/e6a726b13491832258c1228f03bde802.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nN\u00eb figur\u00ebn e ardhshme \u00ebsht\u00eb ilustruar nj\u00eb tupl\u00eb e tre mesazheve <em>m1<\/em>, <em>m1_1<\/em>, <em>m1_2<\/em>.<br \/>\n<img decoding=\"async\" alt=\"Po studiojm\u00eb motorin VoIP Mediastreamer2. Pjesa 11\" 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\">Funksionet e pun\u00ebs me mesazhet <em>mblk_t<\/em><\/h3>\n<p><\/p>\n<p>Nj\u00eb mesazh i ri <em>mblk_t<\/em> krijohet nga funksioni:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *allocb(int size, int pri); <\/code><\/pre>\n<p><\/p>\n<p>ai alokon n\u00eb memorie nj\u00eb mesazh t\u00eb ri <em>mblk_t<\/em> me bllok t\u00eb dh\u00ebnash t\u00eb madh\u00ebsis\u00eb s\u00eb caktuar <em>size<\/em>, argumenti i dyt\u00eb \u2014 <em>pri<\/em> nuk p\u00ebrdoret n\u00eb versionin e shqyrtuar t\u00eb bibliotek\u00ebs. Ai duhet t\u00eb mbetet zero. Gjat\u00eb pun\u00ebs s\u00eb funksionit do t\u00eb alokohet memorie p\u00ebr struktur\u00ebn e mesazhit t\u00eb ri dhe do t\u00eb thirret funksioni <em>mblk_init()<\/em>, i cili do t\u00eb zeroj\u00eb t\u00eb gjitha fushat e instanc\u00ebs s\u00eb krijuar t\u00eb struktur\u00ebs dhe m\u00eb pas, p\u00ebrmes <em>datab_alloc()<\/em>, do t\u00eb krijoj\u00eb buffer-in e t\u00eb dh\u00ebnave. Pas k\u00ebsaj do t\u00eb kryhet konfigurimi i fushave n\u00eb struktur\u00eb: <\/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>N\u00eb dalje marrim nj\u00eb mesazh t\u00eb ri me fusha t\u00eb inicializuara dhe nj\u00eb buffer t\u00eb t\u00eb dh\u00ebnave bosh. P\u00ebr t\u00eb shtuar t\u00eb dh\u00ebna n\u00eb mesazh, duhet t\u00eb kryhet kopjimi i tyre n\u00eb buffer-in e bllokut t\u00eb t\u00eb dh\u00ebnave:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">memcpy(msg-&gt;b_rptr, data, size);<\/code><\/pre>\n<p><\/p>\n<p>ku <em>data<\/em> \u2014 treguesi n\u00eb burimin e t\u00eb dh\u00ebnave, dhe <em>size<\/em> \u2014 madh\u00ebsia e tyre.<br \/>\nM\u00eb pas duhet t\u00eb p\u00ebrdit\u00ebsohet treguesi p\u00ebr pik\u00ebn e shkruar, n\u00eb m\u00ebnyr\u00eb q\u00eb t\u00eb tregonte p\u00ebrs\u00ebri p\u00ebr fillimin e zon\u00ebs s\u00eb lir\u00eb n\u00eb buffer:<\/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>N\u00ebse k\u00ebrkohet t\u00eb krijohet nj\u00eb mesazh nga nj\u00eb buffer ekzistues, pa kopjim, at\u00ebher\u00eb p\u00ebr k\u00ebt\u00eb p\u00ebrdoret funksioni:<\/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>Funksioni, pas krijimit t\u00eb mesazhit dhe struktur\u00ebs s\u00eb bllokut t\u00eb t\u00eb dh\u00ebnave, do t\u00eb konfiguroj\u00eb treguesit e saj n\u00eb t\u00eb dh\u00ebna n\u00eb adres\u00ebn <em>buf<\/em>. Pra, n\u00eb k\u00ebt\u00eb rast, buffer-i i t\u00eb dh\u00ebnave nuk ndodhet pas fushave t\u00eb titullit t\u00eb bllokut t\u00eb t\u00eb dh\u00ebnave, si\u00e7 ishte krijimi i bllokut t\u00eb t\u00eb dh\u00ebnave nga funksioni. <em>datab_alloc()<\/em>Buferi i d\u00ebrguar funksionit do t\u00eb mbetet aty ku ishte, por me ndihm\u00ebn e treguesve do t\u00eb stimulohet p\u00ebr t'u lidhur me titullin e sapo krijuar t\u00eb bllokut t\u00eb t\u00eb dh\u00ebnave, dhe ai me radh\u00eb me mesazhin.<\/p>\n<p><\/p>\n<p>P\u00ebr nj\u00eb mesazh <em>mblk_t<\/em> mund t\u00eb lidhen disa blloqe t\u00eb dh\u00ebnash n\u00eb m\u00ebnyr\u00eb rendit\u00ebse. Kjo b\u00ebhet me funksionin:<\/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 mesazhi t\u00eb cilit do t'i shtohet nj\u00eb bllok tjet\u00ebr t\u00eb dh\u00ebnash;<br \/>\n<em>data<\/em> \u2014 treguesi p\u00ebr bllokun, kopja e t\u00eb cilit do t\u00eb shtohet n\u00eb mesazh;<br \/>\n<em>size<\/em> \u2014 madh\u00ebsia e t\u00eb dh\u00ebnave;<br \/>\n<em>pad<\/em> \u2014 flaga q\u00eb tregon se madh\u00ebsia e memories e ndar\u00eb duhet t\u00eb jet\u00eb e rregulluar n\u00eb kufirin e 4 bajt\u00ebve (plotesimi do t\u00eb kryhet me ose). <\/p>\n<p><\/p>\n<p>N\u00ebse n\u00eb buferin ekzistues t\u00eb t\u00eb dh\u00ebnave t\u00eb mesazhit ka mjaft hap\u00ebsir\u00eb, at\u00ebher\u00eb t\u00eb dh\u00ebnat e reja do t\u00eb ngjiten pas t\u00eb dh\u00ebnave ekzistuese atje. N\u00ebse hap\u00ebsira e lir\u00eb n\u00eb buferin e t\u00eb dh\u00ebnave t\u00eb mesazhit \u00ebsht\u00eb m\u00eb e vog\u00ebl se <em>size<\/em>, at\u00ebher\u00eb krijohet nj\u00eb mesazh i ri, me madh\u00ebsin\u00eb e mjaftueshme t\u00eb buferit dhe t\u00eb dh\u00ebnat kopjohen n\u00eb buferin e tij. Ky mesazh i ri lidhet me origjinalin p\u00ebrmes treguesit <em>b_cont<\/em>. N\u00eb k\u00ebt\u00eb rast, mesazhi kthehet n\u00eb nj\u00eb tuple. <\/p>\n<p><\/p>\n<p>N\u00ebse n\u00eb tuple duhen shtuar nj\u00eb bllok tjet\u00ebr t\u00eb dh\u00ebnash, at\u00ebher\u00eb duhet t\u00eb p\u00ebrdoret funksioni:<\/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>ai do t\u00eb gjej\u00eb mesazhin e fundit n\u00eb tuple (ai do t\u00eb ket\u00eb <em>b_cont<\/em> zero) dhe do t\u00eb th\u00ebrras\u00eb p\u00ebr k\u00ebt\u00eb mesazh funksionin <em>appendb()<\/em>.<\/p>\n<p><\/p>\n<p>Mund t\u00eb dihet madh\u00ebsia e t\u00eb dh\u00ebnave n\u00eb mesazh ose tuple me an\u00eb t\u00eb funksionit:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">int msgdsize(const mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>ai do t\u00eb kaloj\u00eb n\u00ebp\u00ebr t\u00eb gjitha mesazhet e tuple dhe do t\u00eb kthej\u00eb shum\u00ebn e p\u00ebrgjithshme t\u00eb t\u00eb dh\u00ebnave n\u00eb buferat e t\u00eb dh\u00ebnave t\u00eb atyre mesazheve. P\u00ebr \u00e7do mesazh, sasia e t\u00eb dh\u00ebnave llogaritet k\u00ebshtu:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\"> mp-&gt;b_wptr - mp-&gt;b_rptr<\/code><\/pre>\n<p><\/p>\n<p>P\u00ebr t\u00eb bashkuar dy tuples, p\u00ebrdoret funksioni:<\/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>ai lidh tuple-n\u00eb <em>newm<\/em> n\u00eb fund t\u00eb tuple-s\u00eb <em>mp<\/em> dhe kthen treguesin n\u00eb mesazhin e fundit t\u00eb tuple-s\u00eb s\u00eb krijuar.<\/p>\n<p><\/p>\n<p>N\u00ebse \u00ebsht\u00eb e nevojshme, tuple mund t\u00eb kthehet n\u00eb nj\u00eb mesazh t\u00eb vet\u00ebm me nj\u00eb bllok t\u00eb vet\u00ebm t\u00eb t\u00eb dh\u00ebnash, kjo b\u00ebhet me funksionin:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void msgpullup(mblk_t *mp,int len);<\/code><\/pre>\n<p><\/p>\n<p>n\u00ebse argumenti <em>len<\/em> \u00ebsht\u00eb -1, at\u00ebher\u00eb madh\u00ebsia e buferit t\u00eb ndar\u00eb p\u00ebrcaktohet automatikisht. N\u00ebse <em>len<\/em> N\u00ebse numri \u00ebsht\u00eb pozitiv, do t\u00eb krijohet nj\u00eb buffer i k\u00ebtij madh\u00ebsie dhe t\u00eb dh\u00ebnat e mesazheve t\u00eb tupleve do t\u00eb kopjohen n\u00eb t\u00eb. N\u00ebse buffer-i p\u00ebrfundon, kopjimi do t\u00eb ndalet k\u00ebtu. Mesazhi i par\u00eb i tupleve do t\u00eb marr\u00eb nj\u00eb buffer me madh\u00ebsi t\u00eb re me t\u00eb dh\u00ebnat e kopjuara. Mesazhet e tjera do t\u00eb fshihen, dhe memoria do t\u00eb kthehet n\u00eb kup\u00eb.<\/p>\n<p><\/p>\n<p>Gjat\u00eb fshirjes s\u00eb struktur\u00ebs <em>mblk_t<\/em> merren parasysh numri i referencave t\u00eb bllokut t\u00eb t\u00eb dh\u00ebnave, n\u00ebse kur thirret <em>freeb()<\/em> ai \u00ebsht\u00eb baraz me zero, at\u00ebher\u00eb buffer-i i t\u00eb dh\u00ebnave fshihet s\u00eb bashku me instanc\u00ebn <em>mblk_t<\/em>, q\u00eb e tregon at\u00eb.<\/p>\n<p><\/p>\n<p>Inicijalizimi i fushave t\u00eb mesazhit t\u00eb ri:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void mblk_init(mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Shtimi n\u00eb mesazh nj\u00eb tjet\u00ebr s\u00ebr\u00eb t\u00eb dh\u00ebnash: <\/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>N\u00ebse t\u00eb dh\u00ebnat e reja nuk hyjn\u00eb n\u00eb hap\u00ebsir\u00ebn e lir\u00eb t\u00eb buffer-it t\u00eb t\u00eb dh\u00ebnave t\u00eb mesazhit, atij i bashk\u00ebngjitet nj\u00eb mesazh i krijuar ve\u00e7mas me nj\u00eb buffer t\u00eb nevojsh\u00ebm (n\u00eb mesazhin e par\u00eb vendoset nj\u00eb tregues n\u00eb mesazhin e shtuar) dhe mesazhi shnd\u00ebrrohet n\u00eb tuple.<\/p>\n<p><\/p>\n<p>Shtimi i nj\u00eb s\u00ebr\u00eb t\u00eb dh\u00ebnash n\u00eb tuple:<\/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>Funksioni th\u00ebrret appendb() n\u00eb nj\u00eb cik\u00ebl.<\/p>\n<p><\/p>\n<p>Bashkimi i dy tupleve n\u00eb nj\u00eb:<\/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>Mesazhi <em>newm<\/em> do t\u00eb bashk\u00ebngjitet me <em>mp<\/em>.<\/p>\n<p><\/p>\n<p>Krijimi i nj\u00eb kopjeje t\u00eb nj\u00eb mesazhi t\u00eb vet\u00ebm:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *copyb(const mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Kopjimi i plot\u00eb i tupleve me t\u00eb gjitha blloqet e t\u00eb dh\u00ebnave:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *copymsg(const mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Elementet e tupleve kopjohen nga funksioni <em>copyb()<\/em>.<\/p>\n<p><\/p>\n<p>Krijimi i nj\u00eb kopjeje t\u00eb leht\u00eb t\u00eb mesazhit. <em>mblk_t<\/em>N\u00eb k\u00ebt\u00eb rast, blloku i t\u00eb dh\u00ebnave nuk kopjohet, por rritet numri i referencave t\u00eb tij. <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>Krijimi i nj\u00eb kopjeje t\u00eb leht\u00eb t\u00eb tupleve. Blloqet e t\u00eb dh\u00ebnave nuk kopjohen, vet\u00ebm numrat e referencave t\u00eb tyre rriten. <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>Ngjitja e t\u00eb gjitha mesazheve t\u00eb tupleve n\u00eb nj\u00eb mesazh:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void msgpullup(mblk_t *mp,size_t len);<\/code><\/pre>\n<p><\/p>\n<p>N\u00ebse argumenti <em>len<\/em> \u00ebsht\u00eb baraz me -1, at\u00ebher\u00eb madh\u00ebsia e buffer-it t\u00eb rezervuar p\u00ebrcaktohet automatikisht.<\/p>\n<p><\/p>\n<p>Fshirja e mesazhit, tuple:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void freemsg(mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Numri i referencave t\u00eb bllokut t\u00eb t\u00eb dh\u00ebnave zvog\u00eblohet me nj\u00ebsin\u00eb. N\u00ebse arrihet zero, at\u00ebher\u00eb blloku i t\u00eb dh\u00ebnave gjithashtu fshihet.<\/p>\n<p><\/p>\n<p>Num\u00ebrimi i volumit t\u00eb p\u00ebrgjithsh\u00ebm t\u00eb t\u00eb dh\u00ebnave n\u00eb mesazh ose tuple.<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">size_t msgdsize(const mblk_t *mp);<\/code><\/pre>\n<p><\/p>\n<p>Nxjerrja e mesazhit nga fundi i radh\u00ebs:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t *ms_queue_peek_last (q);<\/code><\/pre>\n<p><\/p>\n<p>Kopjimi i p\u00ebrmbajtjes s\u00eb fushave t\u00eb rezervuara nga nj\u00eb mesazh n\u00eb nj\u00eb tjet\u00ebr (n\u00eb t\u00eb v\u00ebrtet\u00eb k\u00ebto fusha p\u00ebrmbajn\u00eb flamuj q\u00eb p\u00ebrdoren nga mediastreamer):<\/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\">Queue <em>queue_t<\/em><\/h3>\n<p><\/p>\n<p>Nj\u00eb radh\u00eb mesazhe n\u00eb median streaming \u00ebsht\u00eb realizuar si nj\u00eb list\u00eb dyfishe lidh\u00ebse circular. \u00c7do element i list\u00ebs p\u00ebrmban nj\u00eb tregues n\u00eb nj\u00eb bllok t\u00eb dh\u00ebnash me matje sinjali. Kjo do t\u00eb thot\u00eb se l\u00ebvizin vet\u00ebm treguesit n\u00eb bllokun e t\u00eb dh\u00ebnave, nd\u00ebrsa vet\u00eb t\u00eb dh\u00ebnat mbeten t\u00eb pal\u00ebvizshme. Pra, l\u00ebvizin vet\u00ebm lidhjet e tyre.<br \/>\nStruktura q\u00eb p\u00ebrshkruan radh\u00ebn <em>queue_t<\/em>, e paraqitur m\u00eb posht\u00eb:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct _queue\n{\n   mblk_t _q_stopper; \/* \"Elementi i zbraz\u00ebt\" i radh\u00ebs, nuk tregon p\u00ebr t\u00eb dh\u00ebnat, p\u00ebrdoret vet\u00ebm p\u00ebr menaxhimin e radh\u00ebs. Gjat\u00eb inicializimit t\u00eb radh\u00ebs (qinit()), treguesit e tij rregullohen n\u00eb m\u00ebnyr\u00eb q\u00eb t\u00eb tregojn\u00eb p\u00ebr veten e tij. *\/\n   int q_mcount;        \/\/ Numri i elementeve n\u00eb radh\u00eb.\n} queue_t;<\/code><\/pre>\n<p><\/p>\n<p>Struktura p\u00ebrmban nj\u00eb fush\u00eb \u2014 nj\u00eb tregues <em>_q_stopper<\/em> t\u00eb tipit *mblk_t, ai tregon p\u00ebr elementin e par\u00eb (mesazhin) n\u00eb radh\u00eb. Fusha e dyt\u00eb e struktur\u00ebs \u00ebsht\u00eb numri i mesazheve q\u00eb ndodhen n\u00eb radh\u00eb.<br \/>\nN\u00eb figur\u00ebn m\u00eb posht\u00eb \u00ebsht\u00eb paraqitur radh\u00eb me emrin q1, q\u00eb p\u00ebrmban 4 mesazhe m1,m2, m3, m4.<br \/>\n<img decoding=\"async\" alt=\"Po studiojm\u00eb motorin VoIP Mediastreamer2. Pjesa 11\" src=\"\/wp-content\/uploads\/2020\/04\/07fc043861edf15e5eb40e49c8ec5e3e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nN\u00eb figur\u00ebn tjet\u00ebr \u00ebsht\u00eb paraqitur radh\u00eb me emrin q1, q\u00eb p\u00ebrmban 4 mesazhe m1,m2, m3, m4. Mesazhi m2 \u00ebsht\u00eb krye i tuple, n\u00eb t\u00eb cilin p\u00ebrfshihen edhe dy mesazhe m2_1 dhe m2_2.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Po studiojm\u00eb motorin VoIP Mediastreamer2. Pjesa 11\" 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\">Funksionet e pun\u00ebs me rradh\u00ebt queue_t<\/h3>\n<p><\/p>\n<p>Inicializimi i radh\u00ebs:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void qinit(queue_t *q);<\/code><\/pre>\n<p><\/p>\n<p>Fusha <em>_q_stopper<\/em> (nga tani e tutje do ta quajm\u00eb \"stop\",) inicializohet nga funksioni <em>mblk_init()<\/em>, treguesi i elementit t\u00eb kaluar dhe treguesi i elementit t\u00eb ardhsh\u00ebm konfigurohen q\u00eb t\u00eb tregojn\u00eb p\u00ebr veten e tij. Numri i elementeve n\u00eb radh\u00eb zerohet.<\/p>\n<p><\/p>\n<p>Shtimi i nj\u00eb elementi t\u00eb ri (mesazhi):<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void putq(queue_t *q, mblk_t *m);<\/code><\/pre>\n<p><\/p>\n<p>Elementi i ri <em>m<\/em> shtohet n\u00eb fund t\u00eb list\u00ebs, treguesit e elementit konfigurohen q\u00eb t\u00eb b\u00ebjn\u00eb q\u00eb stopi t\u00eb jet\u00eb elementi i ardhsh\u00ebm p\u00ebr t\u00eb, dhe ai p\u00ebr stopin elementin e kaluar. Numri i elementeve n\u00eb radh\u00eb rritet.<\/p>\n<p><\/p>\n<p>Shkarkimi i nj\u00eb elementi nga radh\u00eb:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t * getq(queue_t *q); <\/code><\/pre>\n<p><\/p>\n<p>shkarkohet ai mesazh q\u00eb ndodhet pas stopit, numri i elementeve zvog\u00eblohet. N\u00ebse n\u00eb radh\u00eb nuk ka elemente p\u00ebrve\u00e7 stopit, kthehet 0.<\/p>\n<p><\/p>\n<p>Vendosja e nj\u00eb mesazhi n\u00eb radh\u00eb:<\/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>Elementi <em>mp<\/em> vendoset p\u00ebrpara elementit <em>emp<\/em>. N\u00ebse <em>emp<\/em>=0, at\u00ebher\u00eb mesazhi shtohet n\u00eb fund t\u00eb radh\u00ebs.<\/p>\n<p><\/p>\n<p>Shkarkimi i mesazhit nga krye i radh\u00ebs:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void remq(queue_t *q, mblk_t *mp); <\/code><\/pre>\n<p><\/p>\n<p>Numri i elementeve zvog\u00eblohet.<\/p>\n<p><\/p>\n<p>Leximi i treguesit n\u00eb elementin e par\u00eb t\u00eb radh\u00ebs:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t * peekq(queue_t *q); <\/code><\/pre>\n<p><\/p>\n<p>Fshirja e t\u00eb gjitha elementeve nga radh\u00eb me fshirjen e elementeve vet\u00eb:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void flushq(queue_t *q, int how);<\/code><\/pre>\n<p><\/p>\n<p>Argumenti <em>how<\/em> nuk \u00ebsht\u00eb n\u00eb p\u00ebrdorim. Kontatori i elementeve n\u00eb radh\u00eb vendoset n\u00eb zero.<\/p>\n<p><\/p>\n<p>Makron p\u00ebr t\u00eb lexuar treguesin n\u00eb elementin e fundit t\u00eb radh\u00ebs:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">mblk_t * qlast(queue_t *q);<\/code><\/pre>\n<p><\/p>\n<p>Kur punoni me radh\u00ebt e mesazheve, duhet t\u00eb keni parasysh se kur thirret <em>ms_queue_put(q, m)<\/em> me nj\u00eb tregues null p\u00ebr mesazhin, funksioni bllokohet. Programi juaj do t\u00eb ngec\u00eb. Po ashtu sillet <em>ms_queue_next(q, m)<\/em>.<\/p>\n<p><\/p>\n<h3 id=\"soedinenie-filtrov\">Lidhja e filtrave<\/h3>\n<p><\/p>\n<p>Radh\u00eb e p\u00ebrshkruar m\u00eb sip\u00ebr p\u00ebrdoret p\u00ebr t\u00eb transmetuar mesazhe nga nj\u00eb filtr n\u00eb tjetrin ose nga nj\u00eb n\u00eb disa filtra. Filtrat dhe lidhjet e tyre midis tyre formojn\u00eb nj\u00eb grafik t\u00eb drejtuar. Hyrja ose dalja e filtrit do ta quajm\u00eb me termin e p\u00ebrgjithsh\u00ebm \"pin\". P\u00ebr t\u00eb p\u00ebrshkruar rendin e lidhjeve midis filtrave, mediastreamer-i p\u00ebrdor konceptin e \"pik\u00ebs s\u00eb sinjalit\". Pika e sinjalit \u00ebsht\u00eb nj\u00eb struktur\u00eb <em>_MSCPoint<\/em>, e cila p\u00ebrmban nj\u00eb tregues n\u00eb filtrin dhe nj\u00eb num\u00ebr t\u00eb nj\u00ebrit prej pin\u00ebve t\u00eb tij, p\u00ebrkat\u00ebsisht ajo p\u00ebrshkruan lidhjen e nj\u00ebr\u00ebs prej hyrjeve ose daljeve t\u00eb filtrit. <\/p>\n<p><\/p>\n<h4 id=\"signalnaya-tochka-grafa-obrabotki-dannyh\">Pika e sinjalizimit n\u00eb grafikun e p\u00ebrpunimit t\u00eb t\u00eb dh\u00ebnave<\/h4>\n<p><\/p>\n<pre><code class=\"cpp\">typedef struct _MSCPoint{\nstruct _MSFilter *filter; \/\/ Tregues n\u00eb filtrin e mediastreamer.\nint pin; \/\/ Numri i nj\u00ebr\u00ebs prej hyrjeve ose daljeve t\u00eb filtrit, dmth. pin.\n} MSCPoint;\n<\/code><\/pre>\n<p><\/p>\n<p>Pinat e filtruesve num\u00ebrohen duke filluar nga zero. <\/p>\n<p><\/p>\n<p>Lidhja midis dy pinave me nj\u00eb radh\u00eb mesazhesh p\u00ebrshkruhet nga struktura <em>_MSQueue<\/em>, e cila p\u00ebrmban nj\u00eb radh\u00eb mesazhesh dhe tregues p\u00ebr dy pika sinjali, t\u00eb cilat ajo i lidh:<\/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>Do ta quajm\u00eb k\u00ebt\u00eb struktur\u00eb lidhje sinjali. \u00c7do filtrues mediastreamer, p\u00ebrmban nj\u00eb tabel\u00eb t\u00eb lidhjeve hyr\u00ebse dhe nj\u00eb tabel\u00eb t\u00eb lidhjeve dal\u00ebse (<em>MSQueue<\/em>). Madh\u00ebsia e tabelave p\u00ebrcaktohet gjat\u00eb krijimit t\u00eb filtrit, ne e kemi b\u00ebr\u00eb k\u00ebt\u00eb tashm\u00eb me an\u00eb t\u00eb nj\u00eb variabli eksporti t\u00eb tipit <em>MSFilterDesc<\/em>, kur zhvilluam filtrin ton\u00eb t\u00eb vetin. M\u00eb posht\u00eb tregohet struktura q\u00eb p\u00ebrshkruan \u00e7do filtrues n\u00eb mediastreamer, <em>MSFilter<\/em>:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">\nstruct _MSFilter{\n    MSFilterDesc *desc;    \n    \/* P\u00e4rja e filtrit. *\/\n    \/* Atributet e mbrojtura, ato nuk mund t\u00eb l\u00ebvizin ose t\u00eb hiqen, ndryshe do t\u00eb prishen funksionet me plugin\u00ebt. *\/\n    ms_mutex_t lock;      \/* Semafori. *\/\n    MSQueue **inputs;     \/* Tabela e lidhjeve hyr\u00ebse. *\/\n    MSQueue **outputs;    \/* Tabela e lidhjeve dal\u00ebse. *\/\n    struct _MSFactory *factory; \/* P\u00e4rja e fabrik\u00ebs q\u00eb krijoi k\u00ebt\u00eb instanc\u00eb filtri. *\/\n    void *padding;              \/* Nuk p\u00ebrdoret, do t\u00eb angazhohet n\u00ebse shtohen fusha t\u00eb mbrojtura. *\/\n    void *data;                 \/* P\u00e4rja e struktur\u00ebs s\u00eb rastit p\u00ebr ruajtjen e t\u00eb dh\u00ebnave t\u00eb gjendjes brendshme t\u00eb filtrit dhe llogaritjeve nd\u00ebrmjet\u00ebse. *\/\n    struct _MSTicker *ticker;   \/* P\u00e4rja e objektit ticker, i cili nuk duhet t\u00eb jet\u00eb zero kur thirret funksioni process(). *\/\n    \/* atribute private, ato mund t\u00eb l\u00ebvizin dhe t\u00eb ndryshohen n\u00eb \u00e7do koh\u00eb *\/\n    MSList *notify_callbacks; \/* Lista e thirrjeve kthese, t\u00eb p\u00ebrdorura p\u00ebr trajtimin e ngjarjeve t\u00eb filtrit. *\/\n    uint32_t last_tick;       \/* Numri i ciklit t\u00eb fundit kur u thirr process(). *\/\n    MSFilterStats *stats;     \/* Statistika e pun\u00ebs s\u00eb filtrit. *\/\n    int postponed_task; \/* Numri i detyrave t\u00eb shtyra. Disa filtra mund t\u00eb vonojn\u00eb p\u00ebrpunimin e t\u00eb dh\u00ebnave (thirrja process()) p\u00ebr disa cikle. *\/\n    bool_t seen;  \/* Flagu q\u00eb p\u00ebrdor ticker p\u00ebr t\u00eb sh\u00ebnuar se ky instanc\u00eb filtri \u00ebsht\u00eb trajtuar n\u00eb k\u00ebt\u00eb cik\u00ebl. *\/\n};\ntypedef struct _MSFilter MSFilter;\n<\/code><\/pre>\n<p><\/p>\n<p>Pasi q\u00eb ne n\u00eb programin C lidh\u00ebm filtrat sipas konceptit ton\u00eb (por nuk lidhi ticker-in), ne k\u00ebshtu krijuam nj\u00eb graf t\u00eb orientuar, ku nyjet jan\u00eb instancat e struktur\u00ebs <em>MSFilter<\/em>, dhe skajet jan\u00eb instancat e lidhjeve <em>MSQueue<\/em>. <\/p>\n<p><\/p>\n<h3 id=\"zakulisnaya-deyatelnost-tikera\">Aktiviteti pas sken\u00ebs i ticker-it<\/h3>\n<p><\/p>\n<p>Kur ju thash\u00eb se ticker-i \u00ebsht\u00eb filtri burim i cikleve, nuk ishte e gjitha e v\u00ebrteta rreth tij. Ticker-i \u00ebsht\u00eb nj\u00eb objekt q\u00eb me or\u00eb ekzekuton p\u00ebrmbledhjen e funksioneve <em>process()<\/em> e t\u00eb gjitha filtrave t\u00eb skem\u00ebs (grafikut) me t\u00eb cilin \u00ebsht\u00eb i lidhur. Kur n\u00eb programin C lidhim ticker-in me filtrin e grafikut, ne i tregojm\u00eb ticker-it grafik\u00ebn, e cila do t\u00eb menaxhohet nga ai nga ky moment e n\u00eb vazhdim, deri sa ta shk\u00ebputim. Pas lidhjes, ticker-i fillon t\u00eb shqyrtoj\u00eb grafikun q\u00eb i \u00ebsht\u00eb besuar, duke p\u00ebrpiluar nj\u00eb list\u00eb t\u00eb filtrave n\u00eb t\u00eb cil\u00ebt ai p\u00ebrfshihet. P\u00ebr t\u00eb mos \"num\u00ebruar\" t\u00eb nj\u00ebjtin filtr dy her\u00eb, ai sh\u00ebnon filtrat e zbuluar duke vendosur nj\u00eb shenj\u00eb <em>seen<\/em>. K\u00ebrkimi b\u00ebhet p\u00ebrmes tabelave t\u00eb lidhjeve q\u00eb ka \u00e7do filt\u00ebr. <\/p>\n<p><\/p>\n<p>Gjat\u00eb ekskursioneve t\u00eb tij hyr\u00ebse n\u00eb grafik, ticker kontrollon n\u00ebse ka t\u00eb pakt\u00ebn nj\u00eb filtrues nga filtrat q\u00eb plot\u00ebson rolin e burimit t\u00eb blloqeve t\u00eb t\u00eb dh\u00ebnave. N\u00ebse nuk ka, grafiku konsiderohet i pasakt\u00eb dhe tickert e mbyll pun\u00ebn n\u00eb m\u00ebnyr\u00eb emergjente.<\/p>\n<p><\/p>\n<p>N\u00ebse grafiku \u00ebsht\u00eb \"i sakt\u00eb\", p\u00ebr \u00e7do filtr t\u00eb gjetur, p\u00ebr inicializimin, thirret funksioni <em>preprocess()<\/em>. Pasi t\u00eb arrij\u00eb momenti p\u00ebr ciklin e ardhsh\u00ebm t\u00eb p\u00ebrpunimit (n\u00eb m\u00ebnyr\u00eb default \u00e7do 10 milisekonda), ticker th\u00ebrret funksionin <em>process()<\/em> p\u00ebr t\u00eb gjith\u00eb filtrat burim t\u00eb gjetur m\u00eb par\u00eb, dhe pastaj p\u00ebr filtrat e tjer\u00eb n\u00eb list\u00eb. N\u00ebse filtri ka lidhje hyr\u00ebse, at\u00ebher\u00eb ekzekutimi i funksionit <em>process()<\/em> p\u00ebrs\u00ebritet derisa radh\u00ebt e lidhjeve hyr\u00ebse t\u00eb mos jen\u00eb bosh. Pas k\u00ebsaj, ai kalon n\u00eb filtrin e ardhsh\u00ebm t\u00eb listes dhe \"rrotullon\" at\u00eb deri n\u00eb \u00e7lirimin e lidhjeve hyr\u00ebse nga mesazhet. Ticker-i kalon nga filtri n\u00eb filtra derisa t\u00eb p\u00ebrfundoj\u00eb lista. N\u00eb k\u00ebt\u00eb pik\u00eb, p\u00ebrpunimi i taktit p\u00ebrfundon. <\/p>\n<p><\/p>\n<p>Tani, do t\u00eb kthehemi te tuple dhe do t\u00eb flasim p\u00ebr arsye se p\u00ebrse nj\u00eb entitet i till\u00eb u shtua n\u00eb streamerin multimedia. N\u00eb rastin e p\u00ebrgjithsh\u00ebm, sasia e t\u00eb dh\u00ebnave e nevojshme p\u00ebr algoritmin q\u00eb funksionon brenda filtrit nuk p\u00ebrputhet dhe nuk \u00ebsht\u00eb shum\u00ebfish i madh\u00ebsis\u00eb s\u00eb bufeve t\u00eb t\u00eb dh\u00ebnave q\u00eb vijn\u00eb n\u00eb hyrje. P\u00ebr shembull, ne shkruajm\u00eb nj\u00eb filtru q\u00eb kryen nj\u00eb transformim t\u00eb shpejt\u00eb t\u00eb Fourier-it, i cili sipas p\u00ebrkufizimit mund t\u00eb p\u00ebrpunoj\u00eb vet\u00ebm blloqe t\u00eb dh\u00ebnash me madh\u00ebsi q\u00eb jan\u00eb fuqi e dysh\u00ebs. Le t\u00eb jet\u00eb ky 512 mostra. N\u00ebse t\u00eb dh\u00ebnat gjenerohen nga nj\u00eb kanal telefoni, at\u00ebher\u00eb buffer-i i t\u00eb dh\u00ebnave p\u00ebr \u00e7do mesazh n\u00eb hyrje do t\u00eb na sjell\u00eb 160 mostra t\u00eb sinjalit. Ka nj\u00eb tundim p\u00ebr t\u00eb mos marr\u00eb t\u00eb dh\u00ebna nga hyrja derisa t\u00eb ket\u00eb numrin e nevojsh\u00ebm t\u00eb t\u00eb dh\u00ebnave. Por n\u00eb k\u00ebt\u00eb rast do t\u00eb ndodhte nj\u00eb kolizion me ticker-in, i cili do t\u00eb p\u00ebrpiqej pa sukses t\u00eb rrotullonte filtrin deri sa t\u00eb zbrazte lidhjen hyr\u00ebse. M\u00eb par\u00eb ne e kemi quajtur k\u00ebt\u00eb rregull si parimi i tret\u00eb i funksionimit t\u00eb filtrit. Sipas k\u00ebtij parimi, funksioni process() i filtrit duhet t\u00eb marr\u00eb t\u00eb gjitha t\u00eb dh\u00ebnat nga radh\u00ebt hyr\u00ebse.<\/p>\n<p><\/p>\n<p>P\u00ebrve\u00e7 k\u00ebsaj, nga hyrja nuk do t\u00eb jet\u00eb e mundur t\u00eb merret vet\u00ebm 512 matje, pasi ato mund t\u00eb merren vet\u00ebm n\u00eb blloqe t\u00eb t\u00ebra, dmth filtri do t\u00eb duhet t\u00eb marr\u00eb 640 matje dhe duke p\u00ebrdorur 512 nga to, mbetja deri n\u00eb grumbullimin e nj\u00eb partie t\u00eb re t\u00eb t\u00eb dh\u00ebnave. K\u00ebshtu, filtri yn\u00eb, p\u00ebrve\u00e7 detyr\u00ebs s\u00eb tij kryesore, duhet t\u00eb siguroj\u00eb veprime ndihm\u00ebse p\u00ebr ruajtjen nd\u00ebrmjet\u00ebse t\u00eb t\u00eb dh\u00ebnave hyr\u00ebse. Zhvilluesit e mediastream-it p\u00ebr k\u00ebt\u00eb detyr\u00eb t\u00eb p\u00ebrgjithshme kan\u00eb zhvilluar nj\u00eb objekt t\u00eb ve\u00e7ant\u00eb - MSBufferizer (bufruesi), i cili zgjidh k\u00ebt\u00eb problem me an\u00eb t\u00eb tupave. <\/p>\n<p><\/p>\n<h3 id=\"buferizator-msbufferizer\">Bufferi (MSBufferizer)<\/h3>\n<p><\/p>\n<p>Ky \u00ebsht\u00eb nj\u00eb objekt q\u00eb do t\u00eb akumulloj\u00eb t\u00eb dh\u00ebnat hyr\u00ebse brenda filtrit dhe do t\u00eb filloj\u00eb t'i jap\u00eb ato p\u00ebr p\u00ebrpunim, sa her\u00eb q\u00eb sasia e informacionit t\u00eb jet\u00eb e mjaftueshme p\u00ebr t\u00eb zhvilluar algoritmin e filtrit. Nd\u00ebrsa bufruesi akumulon t\u00eb dh\u00ebna, filtri do t\u00eb punoj\u00eb n\u00eb modin e zbraz\u00ebt, pa shpenzuar fuqin\u00eb llogarit\u00ebse t\u00eb procesorit. Por sapo funksioni i leximit nga bufruesi kthehet me nj\u00eb vler\u00eb t\u00eb ndryshme nga zero, funksioni process() i filtrit fillon t\u00eb marr\u00eb dhe t\u00eb p\u00ebrpunoj\u00eb t\u00eb dh\u00ebnat nga bufruesi n\u00eb porcione t\u00eb nevojshme, deri n\u00eb shterimin e tyre.<br \/>\nT\u00eb dh\u00ebnat e pap\u00ebrdorura mbeten n\u00eb bufrues si elementi i par\u00eb i tup\u00ebs, t\u00eb cilit i bashkohen blloqet e tjera t\u00eb t\u00eb dh\u00ebnave hyr\u00ebse. <\/p>\n<p><\/p>\n<p>Struktura q\u00eb p\u00ebrshkruan bufruesin: <\/p>\n<p><\/p>\n<pre><code class=\"cpp\">struct _MSBufferizer{\nqueue_t q; \/* Rreshti i mesazheve. *\/\nint size; \/* Shuma totale e t\u00eb dh\u00ebnave n\u00eb bufrues n\u00eb k\u00ebt\u00eb moment. *\/\n};\ntypedef struct _MSBufferizer MSBufferizer;<\/code><\/pre>\n<p><\/p>\n<h3 id=\"funkcii-raboty-s-msbufferizer\">Funksionet e pun\u00ebs me MSBufferizer<\/h3>\n<p><\/p>\n<p>Krijimi i nj\u00eb ekzemplar t\u00eb ri t\u00eb bufruesit:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">MSBufferizer * ms_bufferizer_new(void);<\/code><\/pre>\n<p><\/p>\n<p>P\u00ebr allocated_memory, inicializohet n\u00eb <em>ms_bufferizer_init()<\/em> dhe kthehet nj\u00eb tregues.<\/p>\n<p><\/p>\n<p>Funksioni i inicializimit:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_init(MSBufferizer *obj); <\/code><\/pre>\n<p><\/p>\n<p>Inicializohet rreshti <em>q<\/em>, fusha <em>size<\/em> dhe vendoset n\u00eb zero.<\/p>\n<p><\/p>\n<p>Shtimi i mesazhit:<\/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>Mesazhi m shtohet n\u00eb rresht. Sasia e llogaritur e blloqeve t\u00eb t\u00eb dh\u00ebnave shtohet n\u00eb <em>size<\/em>.<\/p>\n<p><\/p>\n<p>Shk\u00ebmbimi n\u00eb bufruesin e t\u00eb gjith\u00eb mesazheve t\u00eb rreshtit t\u00eb t\u00eb dh\u00ebnave t\u00eb lidhjes <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>Transferimi i mesazheve nga lidhja <em>q<\/em> n\u00eb bufrues b\u00ebhet me an\u00eb t\u00eb funksionit <em>ms_bufferizer_put()<\/em>.<\/p>\n<p><\/p>\n<p>Leximi nga bufruesi:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">int ms_bufferizer_read(MSBufferizer *obj, uint8_t *data, int datalen); <\/code><\/pre>\n<p><\/p>\n<p>N\u00ebse p\u00ebrmasat e t\u00eb dh\u00ebnave t\u00eb akumuluara n\u00eb bufrues rezultojn\u00eb t\u00eb jen\u00eb m\u00eb t\u00eb vogla se sa \u00ebsht\u00eb e k\u00ebrkuar (<em>datalen<\/em>), funksioni kthen zero, kopjimi i t\u00eb dh\u00ebnave n\u00eb data nuk kryhet. N\u00eb t\u00eb kund\u00ebrt, kryhet kopjimi i radh\u00ebs s\u00eb t\u00eb dh\u00ebnave nga tabelat q\u00eb ndodhen n\u00eb bufer. Pas kopjimit, tabela fshihet dhe memoria lirohet. Kopjimi p\u00ebrfundon n\u00eb momentin kur jan\u00eb kopjuar datalen bajta. N\u00ebse vendi mbaron n\u00eb gjysm\u00eb t\u00eb bllokut t\u00eb t\u00eb dh\u00ebnave, at\u00ebher\u00eb n\u00eb k\u00ebt\u00eb mesazh, blloku i t\u00eb dh\u00ebnave do t\u00eb jet\u00eb i shkurtohet n\u00eb pjes\u00ebn e mbetur t\u00eb pap\u00ebrfunduar. N\u00eb thirrjen e ardhshme, kopjimi do t\u00eb vazhdoj\u00eb nga ky vend.<\/p>\n<p><\/p>\n<p>Leximi i sasis\u00eb s\u00eb t\u00eb dh\u00ebnave q\u00eb jan\u00eb t\u00eb disponueshme n\u00eb k\u00ebt\u00eb moment n\u00eb bufer:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">int ms_bufferizer_get_avail(MSBufferizer *obj); <\/code><\/pre>\n<p><\/p>\n<p>Kthen fush\u00ebn <em>size<\/em> e buferizatorit.<\/p>\n<p><\/p>\n<p>Hedhja e pjes\u00ebs s\u00eb t\u00eb dh\u00ebnave q\u00eb ndodhen n\u00eb bufer:<\/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>Sasia e specifikuar e bajtave t\u00eb t\u00eb dh\u00ebnave nxirret dhe hidhet. Hidhen t\u00eb dh\u00ebnat m\u00eb t\u00eb vjetra.<\/p>\n<p><\/p>\n<p>Shkarkimi i t\u00eb gjitha mesazheve q\u00eb ndodhen n\u00eb bufer:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_flush(MSBufferizer *obj); <\/code><\/pre>\n<p><\/p>\n<p>Num\u00ebruesi i t\u00eb dh\u00ebnave resetohet n\u00eb zero.<\/p>\n<p><\/p>\n<p>Shkarkimi i t\u00eb gjitha mesazheve q\u00eb ndodhen n\u00eb bufer:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_uninit(MSBufferizer *obj); <\/code><\/pre>\n<p><\/p>\n<p>Resetimi i num\u00ebruesit nuk kryhet.<\/p>\n<p><\/p>\n<p>Fshirja e buferizatorit dhe lirimi i memories:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">void ms_bufferizer_destroy(MSBufferizer *obj);  <\/code><\/pre>\n<p><\/p>\n<p>Shembujt e p\u00ebrdorimit t\u00eb buferizatorit mund t\u00eb gjenden n\u00eb kodin burimor t\u00eb disa filtra t\u00eb mediastreamerit. P\u00ebr shembull, n\u00eb filtrin MS_L16_ENC, i cili kryen rregullimin e bajtave n\u00eb mostra nga rendi rrjetor n\u00eb rendin e mikprit\u00ebsit:<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>N\u00eb artikullin q\u00eb vijon, do t\u00eb shqyrtojm\u00eb \u00e7\u00ebshtjen e vler\u00ebsimit t\u00eb ngarkes\u00ebs n\u00eb ticker dhe m\u00ebnyrat e trajtimit t\u00eb ngarkes\u00ebs s\u00eb tepruar t\u00eb llogaritjes n\u00eb mediastreamer.<\/p>\n<p>Burimi: <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.2 - 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\/sq\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\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\/sq\/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\udd47 Po studiojm\u00eb motorin VoIP Mediastreamer2. Pjesa 11 | ProHoster","description":"Materiali i artikullit \u00ebsht\u00eb marr\u00eb nga kanali im n\u00eb Dzen.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-11","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","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\/sq\/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\/sq\/wp-json\/wp\/v2\/posts\/79540","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=79540"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/79540\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/79541"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=79540"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=79540"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=79540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}