在使用FFMPEG的類庫進行編程的過程中,可以直接輸出解復用之後的的視頻數據碼流。只需要在每次調用av_read_frame()之後將得到的視頻的AVPacket存為本地文件即可。
經試驗,在分離MPEG2碼流的時候,直接存儲AVPacket即可。
在分離H.264碼流的時候,直接存儲AVPacket後的文件可能是不能播放的。
如果視音頻復用格式是TSMPEG2TransportStream),直接存儲後的文件是可以播放的。
復用格式是FLV,MP4則不行。
經過長時間資料搜索發現,FLV,MP4這些屬於“特殊容器”,需要經過以下處理才能得到可播放的H.264碼流:
1.第一次存儲AVPacket之前需要在前面加上H.264的SPS和PPS。這些信息存儲在AVCodecContext的extradata裡面。
並且需要使用FFMPEG中的名為"h264_mp4toannexb"的bitstreamfilter進行處理。
然後將處理後的extradata存入文件
具體代碼如下:
FILE *fp=fopen("test.264","ab"); unsigned char *dummy=NULL; //輸入的指針 int dummy_len; AVBitStreamFilterContext* bsfc = av_bitstream_filter_init("h264_mp4toannexb"); av_bitstream_filter_filter(bsfc, is->ic->streams[is->video_stream]->codec, NULL, &dummy, &dummy_len, NULL, 0, 0); fwrite(is->ic->streams[is->video_stream]->codec->extradata,is->ic->streams[is->video_stream]->codec->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碼流
本文出自 “leixiaohua1020視音頻技術” 博客,請務必保留此出處http://leixiaohua1020.blog.51cto.com/3974648/1303852