參考http://blog.csdn.net/leixiaohua1020/article/details/11800877
在分離H.264碼流的時候,直接存儲AVPacket后的文件可能是不能播放的。
如果視音頻復用格式是TS(MPEG2 Transport Stream),直接存儲后的文件是可以播放的。
復用格式是FLV,MP4則不行。
經過長時間資料搜索發現,FLV,MP4這些屬於“特殊容器”,需要經過以下處理才能得到可播放的H.264碼流:
1.分離某些封裝格式(例如MP4/FLV/MKV等)中的H.264的時候,需要首先寫入SPS和PPS,否則會導致分離出來的數據沒有SPS、PPS而無法播放。H.264碼流的SPS和PPS信息存儲在AVCodecContext結構體的extradata中。需要使用ffmpeg中名稱為“h264_mp4toannexb”的bitstream filter(比特流過濾器)處理。有兩種處理方式:
(1)使用bitstream filter處理每個AVPacket(簡單)
把每個AVPacket中的數據(data字段)經過bitstream filter“過濾”一遍。關鍵函數是av_bitstream_filter_filter()。示例代碼如下

上述代碼中,把av_bitstream_filter_filter()的輸入數據和輸出數據(分別對應第4,5,6,7個參數)都設置成AVPacket的data字段就可以了。
需要注意的是bitstream filter需要初始化和銷毀,分別通過函數av_bitstream_filter_init()和av_bitstream_filter_close()。
經過上述代碼處理之后,AVPacket中的數據有如下變化:
*每個AVPacket的data添加了H.264的NALU的起始碼{0,0,0,1}
*每個IDR幀數據前面添加了SPS和PPS
(2)手工添加SPS,PPS(稍微復雜)
將AVCodecContext的extradata數據經過bitstream filter處理之后得到SPS、PPS,拷貝至每個IDR幀之前。下面代碼示例了寫入SPS、PPS的過程。通過查看FFMPEG源代碼我們發現,AVPacket中的數據起始處沒有分隔符(0x00000001), 也不是0x65、0x67、0x68、0x41等字節,所以可以AVPacket肯定這不是標准的nalu。其實,AVPacket前4個字表示的是nalu的長度,從第5個字節開始才是nalu的數據。所以直接將AVPacket前4個字節替換為0x00000001即可得到標准的nalu數據。
具體代碼如下:

拷貝4個字節(0x00000001)
當封裝格式為MPEG2TS的時候,不存在上述問題。
SDP中的H.264的SPS和PPS串,包含了初始化H.264解碼器所需要的信息參數,包括編碼所用的profile,level,圖像的寬和高,deblock濾波器等。3、相關函數介紹




