亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

ts demuxer的加入記錄

系統 1839 0

文件夾

1 初衷

2 ts demux的功能介紹


1 初衷


????之前打算給dtplayer加入一些亮點功能,最初的想法是:bt下載播放 + hls支持

????bt下載因為以來libtorrent庫,盡管搞懂了怎樣加入,但須要改動libtorrent庫來集成,

????若將libtorrent集成到代碼中,會將代碼變得龐大,框架清晰度會變差,隨機臨時取消了bt功能的開發/

? ?

????后面開始加入hls支持,hls支持打算加入例如以下模塊: stream - hls ? demuxer - ts ?decoder - h264 這樣加上之前的faad

????對于特定網絡流就能夠不依賴ffmpeg來播放了。

????ts demuxer便是第一步功能。

????憑借之前對ts的理解,感覺應該比較快完畢的,當時從github中找到了一個開源的ts解析庫: https://github.com/nevali/tsdemux

????但不幸的是這個庫僅僅提供了 section的解析功能,并沒有提供讀取es包的功能。遂打算自行將這部分功能補全。


代碼:? https://github.com/peterfuture/dtplayer/blob/dev-ts/dtdemux/demuxer/demuxer_ts.c



2 ts demux的功能

????ts demux符合dtplayer demuxer的標準接口,

????先看下定義:

      

demuxer_wrapper_t demuxer_ts = {

???? . name = "ts demuxer" ,

???? . id = DEMUXER_TS ,

???? . probe = ts_probe ,

???? . open = ts_open ,

???? . read_frame = ts_read_frame ,

???? . setup_info = ts_setup_info ,

???? . seek_frame = ts_seek_frame ,

???? . close = ts_close

};

以下依次介紹各個功能。


2.1 probe

      

static int ts_probe ( demuxer_wrapper_t * wrapper , dt_buffer_t * probe_buf )

{

???? const uint8_t * buf = probe_buf -> data ;

???? const uint8_t * end = buf + probe_buf -> level - 7 ;

????

???? if ( probe_buf -> level < 10 )

???????? return 0 ;

???? int retry_times = 100 ;

???? for (; buf < end ; buf ++ )

???? {

???????? uint32_t header = DT_RB8 ( buf );

???????? if (( header & 0xFF ) != 0x47 )

???????? {

???????????? if ( retry_times -- == 0 )

???????????????? return 0 ;

???????????? continue ;

???????? }

???????? //found 0x47

???????? if ( buf + 188 > end )

???????????? return 0 ;

???????? header = DT_RB8 ( buf + 188 );

???????? if (( header & 0xFF ) == 0x47 )

???????? {

???????????? dt_info ( TAG , "ts detect \n " );

???????????? return 1 ;

???????? }

???????? else

???????????? return 0 ;

???? }

???? return 0 ;

}

這里實現了一個比較簡單的probe功能,先找到同步字0x47,若后面188字節后面也是0x47,則覺得是ts流,臨時probe有些流還不能解析

主要問題有: a 有些流的包大小并非188, 這樣的流會出錯 b 單純的僅僅推斷一次會有偶然性的問題

但這些修正起來比較簡單,因為功能還未實現,這里僅僅介紹思想,還有面會完好

2 ts_open

這里是解析ts頭信息,主要功能包含:

pat解析

pmt解析

stream 信息解析: duration - bitrate

es信息解析:audio: channel-samplerate-bps ?video: width-height-fmt

這里代碼比較多就僅僅說下思想,感興趣的自己去讀代碼就能夠了

首先pat pmt的解析是通過之前說的開源庫完畢的,通過解析pat pmt能夠得到文件里有幾個流,各自是什么格式

得到后一般若有video stream,則以video為參考來計算流信息(正確的做法是找到流的pcr_pid,也就是參考流來計算,但普通情況下參考流都是video)

計算duration: 首先找到第一幀的pts , 然后找到最后一幀的pts, 通過pts差距得到duration

計算bitrate: 有了stream size和 duration, 直接計算得到bitrate

當中計算pts的時候,這里介紹下,詳細代碼在ts/stream.c中,是后面我自己加的

        

if ( packet -> payloadlen > 0 && packet -> unitstart )

???? {

???????? uint8_t * pcrbuf = packet -> payload ;

???????? int len = pcrbuf [ 0 ];

????????if ( len <= 0 || len > 183 ) //broken from the stream layer or invalid

???????????? goto QUIT ;

???????? pcrbuf ++ ;

int flags = pcrbuf [ 0 ];

int has_pcr ;

has_pcr = flags & 0x10 ;

???????? pcrbuf ++ ;

???????? if ( ! has_pcr )

???????????? goto QUIT ;

???????? int64_t pcr = - 1 ;

???????? int64_t pcr_ext = - 1 ;

???????? unsigned int v = 0 ;

? ? //v = (uint32_t)pcrbuf[3]<<24 | pcrbuf[2]<<16 | pcrbuf[1]<<8 |pcrbuf[0];

v = ( uint32_t ) pcrbuf [ 0 ] << 24 | pcrbuf [ 1 ] << 16 | pcrbuf [ 2 ] << 8 | pcrbuf [ 3 ];

???????? pcr = (( int64_t ) v << 1 ) | ( pcrbuf [ 4 ] >> 7 );

pcr_ext = ( pcrbuf [ 4 ] & 0x01 ) << 8 ;

pcr_ext |= pcrbuf [ 5 ];

????????pcr = pcr * 300 + pcr_ext

???????? packet -> pts = pcr / 300 ;

???????? //printf("get pts:%lld \n",pcr);

???? }


這里是去掉了ts包開頭的四個字節,首先看是否是一幀的開頭,若是的話推斷是否有pcr flag

若有則直接解析,解析方法比較簡單,依照標準就可以

這里介紹下ts的編碼參考時鐘為:27M HZ,而pts的單位與時間s的換算為:90000

因此獲取參考時間(也就是上面的pcr后),換算為pts的計算方式為: pts = pcr * 9000 / 27000000 = pcr / 300

這里得到的就直接是pts了。


另一個問題是:這里直接解析es流貌似不能獲取 視頻: width height ?音頻:channel samplerate等信息,

對于ffmpeg來講沒有問題,因此在av_find_stream_info中能夠通過decode one frame來獲取, 但dtplayer框架上是不方便直接啟動解碼器的

對于mplayer 的ts 也是沒有decode的, 知道的同學能夠指導下最好,不勝感激 ,否則得自己扒mplayer的代碼了。


3 ts_setup_info

這里根據ts_open獲取的信息,來setup dtplayer的media info

然后選擇av視頻流就能夠了,比較簡單


4 ts_read_frame

這里比較重要,也是花了比較多時間的地方,一開始的時候,以為拿到av的pid后,后面直接組裝數據就能夠了

流程為: 解析ts包獲取pid -> 若是選擇的pid,直接將payload保存下來,通過簡單的推斷是否是unit_start來推斷是否讀取到了完整幀 --> 返回完整幀

但實際情況并非這樣,保存在ts包中的是實際的pes包,而不是es流,在讀包的時候須要將pes包頭去掉


這里參考ffmpeg進行了模擬,詳細代碼在: handle_ts_pkt 中,詳細邏輯不說了,僅僅是更正自己的一個認知誤區

只是這里還有個問題,讀取的數據包會摻雜錯誤信息: 經過跟代碼,大體定位了問題,在解析pes包頭的時候,是能夠知道這個包的大小的

但讀取ts包的時候都是依照188,即payload通常是184字節,這樣非常有可能就超過了pes包的大小

此時應該怎樣處理: 若僅僅讀取固定大小湊足包大小返回,則聲音是錯的

若將全部payload都打包進去,則播放過程會有雜音。

這里還須要研究下。 有熟悉的同學也請指教 。


5 ts_seek

這里seek就比較簡單了,盡管還未完畢,但思想能夠說下,參考ffmpeg,一句bitrate seek到某個位置,讀取ts包,計算pts

若不匹配,則依照二分查找算法,繼續seek

來達到seek的目的。(后面會實現)


這里ts demux僅僅是為了實現一個簡單的功能,給后面基于dtplayer開發簡單的應用的開發人員提供便利: 若服務端也自己做的話,能夠非常方便的改造dtplayer中的ts demux達到字節的要求,

同一時候去掉了ffmpeg的負擔,豈不非常方便,這也是dtplayer會一直遵循的目標。


github: https://github.com/avplayer/dtplayer ? ?# C++

github https://github.com/peterfuture/dtplayer ?# C

bug report:? peter_future@outlook.com

blog:? http://blog.csdn.net/dtplayer

bbs:? http://avboost.com/

wiki:? http://wiki.avplayer.org/Dtplayer


因為后面隨著開發的進行文章會進行細節的更新,因此為了保證讀者隨時讀到最新的內容,文章禁止轉載,多謝大家支持!















ts demuxer的加入記錄


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!??!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 天天透天天操 | 色资源网站| 九九热视频在线 | 开心片色99xxxx | 伊人99在线 | 久久99视频精品 | 久操国产视频 | 欧美不卡精品中文字幕日韩 | 国产这里只有精品 | 神马影院不卡不卡在线观看 | 久久精品天天中文字幕人 | 国产精品一区二区久久精品 | 国产成人精品综合网站 | 日韩高清在线二区 | 亚洲 欧美 精品 | 亚洲精品一区二区深夜福利 | 波多野结衣免费免费视频一区 | 欧美午夜在线视频 | 国产精品福利视频手机免费观看 | 亚洲精品成人7777在线观看 | 天天射天天干天天插 | 成人三级做爰在线观看男女 | 91精品免费观看老司机 | 伊人免费视频网 | 中国美女hdxxxxx | 亚洲天天干 | 欧美日韩久久 | 久久久精品国产四虎影视 | 成人欧美精品一区二区不卡 | 92精品国产成人观看免费 | 国产大尺度福利视频在线观看 | 未成人做爰视频www 我爱52avαv永久网站 | 在线你懂得 | 麻豆精品久久精品色综合 | 波多野结衣亚洲一区二区三区 | 欧美毛片一级 | 在线观看日韩欧美 | 日本欧美在线视频 | 男人边吃奶边爱边做视频日韩 | 久久99爱re热视 | 色偷偷要色偷偷网站视频在线 |