1. 程式人生 > >FFMPEG系列之五:H264視訊流直播

FFMPEG系列之五:H264視訊流直播

原理和程式碼都很簡單,寫完之後在接收端,解碼時就開始報錯了:

12345non-existing PPS0referenceddecode_slice_header errornon-existing PPS0referenceddecode_slice_header errorno frame!

搜尋資料得知,報這個錯的原因是傳送的H264 AVPacket裡面沒有包含SPS(Sequence Parameter Sets)和PPS(Picture Parameter Set)。在H264中,SPS和PPS存在於NALU header中,而在MP4容器中,SPS和PPS存在於AVCDecoderConfigurationRecord中。當然這些專業的知識我也不是特別明白,總之大意是MP4容器中的H264 AVPacket不包含SPS和PPS,這些資訊被放置到了容器頭部裡面,所有解碼器缺少這些引數無法解碼。

再繼續搜尋資料,大部分資料都提到了使用“h264_mp4toannexb”這個filter來處理AVPacket,可以使它重新帶上SPS和PPS。於是在傳送端的程式碼裡面,在傳送之前用“h264_mp4toannexb”對AVPacket進行了一次處理,但處理時總是報錯:

1 Packet header isnotcontained inglobal extradata,corrupted stream orinvalid MP4/AVCC bitstream

這下又進入了撓頭階段,看到有些資料提到SPS和PPS資訊存在於AVCodecContext的extradata欄位中,於是嘗試著把AVCodecContext的extradata直接複製到了傳送出去的AVPacket的位元組流前面,這個時候接收端不報解碼錯誤了,正在欣喜呢,接收端又報出了這個錯誤:

1concealing655DC,655AC,655MVerrors inPframe

這個錯誤大意是P幀也就是關鍵幀有錯誤… 因此又做了無用功。

幾乎要放棄的時候,看著之前的錯誤資訊:”Packet header is not contained in global extradata”,想起前面的AVCodecContext不都設定過一個GLOBAL HEADER嗎?!

1 pCodecCtx->flags|=AV_CODEC_FLAG_GLOBAL_HEADER;

那把這行程式碼去掉會怎麼樣呢?

去掉之後,果然,接收端解碼全部成功了! 只是傳送端會報個warning,大意是容器格式要求使用Global Header但流的AVCodecContext上未設定Global Header,但生成的視訊完全不受影響仍然可以正常播放!

其實這次只是因為一個特殊需求因此做了一個“直播”的Demo,正常情況下完成這個需求一般是使用RTSP/RTMP等。音視訊這些東西,不研究清楚了,還真是難以下手呢。