使用FFMPEG類庫分離出多媒體檔案中的H 264碼流
阿新 • • 發佈:2018-12-20
在使用FFMPEG的類庫進行程式設計的過程中,可以直接輸出解複用之後的的視訊資料碼流。只需要在每次呼叫av_read_frame()之後將得到的視訊的AVPacket存為本地檔案即可。
經試驗,在分離MPEG2碼流的時候,直接儲存AVPacket即可。
在分離H.264碼流的時候,直接儲存AVPacket後的檔案可能是不能播放的。
如果視音訊複用格式是TS(MPEG2 Transport Stream),直接儲存後的檔案是可以播放的。
複用格式是FLV,MP4則不行。
經過長時間資料搜尋發現,FLV,MP4這些屬於“特殊容器”,需要經過以下處理才能得到可播放的H.264碼流:
1.第一次儲存AVPacket之前需要在前面加上H.264的SPS和PPS。這些資訊儲存在AVCodecContext的extradata裡面。
並且需要使用FFMPEG中的名為"h264_mp4toannexb"的bitstream filter 進行處理。
然後將處理後的extradata存入檔案
具體程式碼如下:
- FILE *fp=fopen("test.264","ab");
- AVCodecContext *pCodecCtx=...
- unsigned char *dummy=NULL; //輸入的指標
- int dummy_len;
- AVBitStreamFilterContext* bsfc = av_bitstream_filter_init("h264_mp4toannexb");
- av_bitstream_filter_filter(bsfc, pCodecCtx
- fwrite(pCodecCtx->extradata,pCodecCtx-->extradata_size,1,fp);
- av_bitstream_filter_close(bsfc);
- free(dummy);
2.通過檢視FFMPEG原始碼我們發現,AVPacket中的資料起始處沒有分隔符(0x00000001), 也不是0x65、0x67、0x68、0x41等位元組,所以可以AVPacket肯定這不是標準的nalu。其實,AVPacket前4個字表示的是nalu的長度,從第5個位元組開始才是nalu的資料。所以直接將AVPacket前4個位元組替換為0x00000001即可得到標準的nalu資料。
具體程式碼如下:
- char nal_start[]={0,0,0,1};
- fwrite(nal_start,4,1,fp);
- fwrite(pkt->data+4,pkt->size-4,1,fp);
- fclose(fp);
經過以上兩步處理之後,我們就得到了可以正常播放的H.264碼流