天天看點

FFMPEG和H.264相關開發筆記

解碼應用過程: 1. 用以下過程應用H264解碼器 main()

{

AVFrame pic;

dsputil_static_init(); // 跟蹤了很深才發現的,如果不調用,内部算法資料都沒初始化

AVCodecContext *pAVCtx = avcodec_alloc_context(); // 建立解碼context,傳回建立後指針

avcodec_open(pAVCtx, &h264_decoder);

bool framegot;

while (...)

{

while (!framegot)

{

從pBuf開始解析收集将近1幀資料,長度bytesCollected

bytesDecoded = avcodec_decode_video(pAVCtx, &pic, &framegot, pBuf, bytesCollected);

if (bytesDecoded < 0)

{

說明解碼錯誤,退出;或可能因為收集不足一幀造成,可重新傳回上述代碼再次收集

}

pBuf += bytesDecoded;

}

将pic.data[0,1,2]三個分量輸出,其行跨度分别為pic.linesize[0,1,2]

}

avcodec_close(pAVCtx); // 關閉銷毀解碼context

} 2. H264解碼器中有關低profile容錯-圖像品質改進 目前考慮到的一些改進: 2.1 在函數execute_ref_pic_marking()中有: ... if (h->long_ref_count + h->short_ref_count > h->sps.ref_frame_count){ ... 這裡h->sps.ref_frame_count表示參考幀總數,低檔級中均為前向參考,如果又能确定隻參考前一幀,可以在判斷前強制該值為1: h->sps.ref_frame_count = 1 由于在判斷内部會丢棄多餘的較舊的參考幀,這樣就能確定總是參考前一幀,而不因誤碼造成參考錯誤,提高畫面主觀品質。 但這個改進不作建議,即使低檔級H264視訊,未必确定參考幀隻是1幀。 2.2 在函數decode_frame()中有: ... if(out_of_order || pics > s->avctx->has_b_frames){     ... 在沒有B幀的情況下,誤碼可能會導緻視訊幀在這裡堆積,是以要在這個判斷之前将s->avctx->has_b_frames強制設為0。 2.3 部分field_end()函數中: 會調用ff_er_frame_end()函數用于容錯。部分事實證明,該容錯在這些條件下反而嚴重影響解碼圖像品質,是以可将這個函數調用去掉。 2.4 調試過程中關閉log(調整log等級)可以提高效率表現 3. H264解碼器幀序列處理詳情 3.1 delayed_pic H264解碼器主要資料執行個體位于H264Context中,以下是在decode_frame中使用的H264Context引用 H264Context *h; 和幀序相關的資料為:h->delayed_pic,定義為:Picture *delayed_pic[MAX_DELAYED_PIC_COUNT+2]; 這裡MAX_DELAYED_PIC_COUNT定義為2 這個結構體主要是用于在出現顯示序和解碼序颠倒的情況,如B幀。 函數中以下語句用于判斷方才的NALs解析是否得到一幀,如非,傳回-1,以通知上層可以重新組織滿足一幀的碼流(但此次輸入的有效rbsp都是采納的) if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){      return -1; } 3.2 目前幀 在解碼器内部,目前幀用規定在MpegEncContext結構體中,具體如下擷取: MpegEncContext *s = &h->s; s中有一個指針指向目前幀: s->current_picture_ptr 3.3 參考幀 <未完>

繼續閱讀