MPEG2视频解码

MPEG-2视频解码

 

Ffmpegmpeg-2视频解码(mpeg_decode_frame)过程如下:

 

1、读取前4个字节的头信息,一般为00 00 01 xx,其中xx 表示:

00    —— picture_start_code //表示一帧图像的开始

01~AF —— slice_start_code//表示一个slice的开始

B0B1—— reserved

B2    —— user_data_start_code

B3    —— sequence_header_code//表示一个sequence的开始

B4    —— sequence_error_code

B5    —— extention_start_code

B6    —— reserved

B7    —— sequence_end_code//表示一个sequence的结束

B8    —— group_start_code

B9~FF —— system_start_code

 

2、判断以上头信息,如果xx= B7,表示前一个sequence结束,如果解码器中的next_picture_ptr还保存了一帧图像时,则输出该帧,且结束该次解码过程。

 

3、如果xx= B7时,判断当前解码器是否支持内部组帧操作,如果支持,则组帧开始。组帧时用到两个函数:

²  int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL, avctx->parserRtStart, avctx);

²  ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size)

以下为这两个函数的说明:

函数ff_mpeg1_find_frame_end

输入参数:

码流解析上下文指针parse_context

传入的码流指针buf

传入的码流大小buf_size

音视频解码的统一上下文指针

返回值:

如果找到头的位置,则返回头位置+4(即00 00 01 xx之后的字节);否则,返回错误信息

函数功能:

查找一个帧(xx==00)头。

说明:

根据状态机所处的不同状态进行转换。如果没有找到下一个帧开始符,则只将当前的数据拷贝入解析器的buffer中;如果找到了下一个帧的开始符,则返回;

 

函数ff_combine_frame

输入参数:

码流解析上下文指针parse_context

函数ff_mpeg1_find_frame_end返回的下一个帧头的起始位置信息

输出参数:

组帧之后的buf

组帧之后的数据大小

返回值:

0 —— 组帧完成;

-1—— 没有得到组完的一帧数据;

 

4、主体解码过程(decode_chunks)(状态机的转换)

4.1  寻找起始码,根据起始码的不同,进入不同的解码流程:

SEQ_START_CODE

表示一个序列的开始,进入mpeg1_decode_sequence过程。在改过程中,可以获取视频图像的大小、帧率索引、图像宽高比、比特率信息等,对解码用到的参数进行进一步赋值等。

PICTURE_START_CODE

首先进行mpeg_decode_postinit,即进行该帧解码前的初始化工作;

之后进行mpeg1_decode_picture,即解码当前帧信息,获取视频的图像类型(注:图像类型的获取方法为:去掉00 00 01 00之后的第一、二个字节,取第11、12、13位,该三位即为图像类型信息,1——I帧,2——P帧,3——B帧)、vbv_delay、是否关键帧等信息;

EXT_START_CODE

解码一些扩展信息,如:

mpeg_decode_sequence_extension

mpeg_decode_sequence_display_extension

mpeg_decode_quant_matrix_extension

mpeg_decode_picture_display_extension

mpeg_decode_picture_coding_extension

USER_START_CODE

    用户数据信息解码,mpeg_decode_user_data

GOP_START_CODE

图像组信息解码,mpeg_decode_gop

SLICE_MIN_START_CODE

Slice信息解码,主函数为mpeg_decode_slice,即对每一个slice进行解码操作,之后会分解为一个宏块,再到一个子块。

 

5、当解码完一帧信息后,需要根据当前解码的图像类型判断是否需要输出

如果当前解码的视频序列中没有B帧,则每编完一帧即可进行输出;

如果当前解码的视频序列中有B帧,则需要进行判断:

如果当前解码完成的帧为IP帧,并且该帧之前还有一个IP帧没有输出,则输出其前一个IP帧(若当前帧为第一帧则不用输出);如果当前解码完成的帧为B帧,则输出该帧。参考如下:

I B B P B B P B B P B B P……(显示顺序)

I P B B P B B P B B P B B……(编码顺序)

同样,

I P B B P B B P B B P B B……(解码顺序)

I B B P B B P B B P B B P……(还原显示顺序)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值