C 廣播TS流精確計時傳送

2021-09-27 21:29:20 字數 1764 閱讀 9458

廣播傳輸相關的專案,需求是udp傳送ts到ip/asi閘道器,閘道器經過asi輸出到激勵器,再由激勵器通過射頻天線輸出,接收端為終端機頂盒。

因為以前沒有怎麼接觸過廣播相關的東西,一開始認為用c#寫個udp的程式將ts發出即可。ts的規範是每188個位元組為乙個packet,我用固定位元速率計算出100毫秒要傳送的packet的個數,傳送一定量的packet後如果還未到100毫秒則進行等待,超過100毫秒則重新傳送下一組packet。但測試發現,傳送的資料可以到達閘道器,但激勵器卻接收不到。在閘道器上看到有asi輸出的位元速率但不是太精確。所幸手頭上有乙個夥伴公司用vc寫的ts傳送測試工具,該工具傳送的位元速率可以正確到達激勵器並被機頂盒接收。於是想到用wireshark抓包工具抓包看一下和我的程式有什麼區別。

經過抓髮發現夥伴公司寫的ts傳送工具傳送packet十分均勻,而我的程式傳送的時間間隔則有跳躍。後來想到,傳送的時間如果不均勻,可能會造成裝置緩衝區溢位發生,所以無法正確接收。我的程式是一下子吧固定的一組包全部發出去,然後等待,但夥伴公司的工具則是每個包固定的傳送時間,可以肯定我寫的程式,傳送ts時,packet沒有均勻的離開傳送端,造成位元速率錯誤。知道了問題,那麼如何修改呢?抓包工具看到,每個包傳送的時間及間隔的最小單位是微秒,然而sleep及普通的定時器是無法做到微秒級的精確計時的。

於是求助度娘了解到,要像達到精確計時就需要獲取cpu的相關計時資訊進行精確計算。於是參考vc上精確計時和別人的文章找到了精確到微妙級計時的方法。【參考[.net] 如何用c#做高精度計時器》 

namespace

accuratetimer

//////

定時函式

/// public

class

accuratetimer

//引數_wait_count:要等待的時間,根據時間內部換算可換成秒,毫秒或微秒,_wait_count2:實際回傳的等待時間,精度不大於1微妙

public

static

void accuratesleep(int _wait_count, ref

double

_wait_count2)

accuratetimer.queryperformancecounter(

reft_i8endtime);

//*1000000 微妙 1000毫秒 1秒=1000毫秒=1000000微妙

//等待時計算,乘於1000是毫秒,乘於1000000則是微妙

_wait_count2= ((double)(t_i8endtime - t_i8starttime) / (double)t_i8frequency) * 1000000

; }

while (t_r8passedmsec <=_wait_count);} }

}

於是修改程式,根據位元速率計算出平均每個packet傳送使用的微妙數:

//

100毫秒內需要傳送的packet數量,4000000為傳送的位元速率,ts_over_ip_size為固定的常量188

double _packet_count = 4000000 / 10) / (ts_over_ip_size * 8

);

//傳送間隔計算,每個包傳送的毫秒數乘1000即是微秒

int _duration = (int)((100 / _packet_count)*1000);

編譯程式,測試通過。不過要說c#本身的託管機制,**執行效率自然比不上vc,所以實際到達裝置的位元速率還是有一定誤差的,但對我來說是不影響業務的使用。

廣播TS流精確計時傳送

廣播傳輸相關的專案,需求是udp傳送ts到ip asi閘道器,閘道器經過asi輸出到激勵器,再由激勵器通過射頻天線輸出,接收端為終端機頂盒。因為以前沒有怎麼接觸過廣播相關的東西,一開始認為用c 寫個udp的程式將ts發出即可。ts的規範是每188個位元組為乙個packet,我用固定位元速率計算出10...

c 準確計時 C 精確計時

include large integer m freq,m timestart,m timenow queryperformancefrequency m freq queryperformancecounter m timestart double time double m timestart...

C 利用UdpClient傳送廣播訊息

首先寫個接受訊息的客戶端。這裡偷了點懶,new udpclient 11000 就是用udp方式偵聽11000埠,偵聽任何傳送到11000埠的訊息都會接收到。udpclient udpclient new udpclient 11000 try ipendpoint remoteipendpoint...