您的位置:首页 > 其它

FFMPEG和H.264相关开发笔记

2009-08-01 19:19 239 查看
解码应用过程:
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 参考帧

<未完>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: