H.264 入门知识

大家如果有做过音视频相关的项目,那么肯定对 H.264 相关的概念了解的比较通透,这里我为什么还要写这样一篇文章呢?一来是为了对知识的总结,二来是为了给刚入门音视频的同学一个参考。

基础概念

H.264 又称为 MPEG-4 , 它是一种面向块,基于运动补偿的视频编码标准,是目前市面上最常用的一种视频编码格式,在 Android 中你可以通过 MediaCodec.createEncoderByType("video/avc") 的形式来创建一个编码器,也可以通过软编 avcodec_find_encoder(AV_CODEC_ID_H264) / avcodec_find_encoder_by_name("libx264") 的形式来创建一个编码器。因为该篇文章的主题是分析 H.264 码流,就不再过多介绍怎么来进行编码了。现在就直接来了解一些常用概念吧。

文章最后领取免费音视频学习资料

GOP

两个 I 帧之间形成的一组图片,就是 GOP (Group Of Picture) 的概念。

I 帧

I 帧又称为视频的关键帧,你可以理解为它是一帧画面的完整图像,可以直接拿这个 I 帧来解码

特点:

1、它是一个全帧压缩编码帧,它将全帧图像信息进行 JPEG 压缩编码及传输

2、解码时仅用 I 帧的数据就可以重构完整图像

3、I 帧描述了图像背景和运动主体的详情

4、I 帧不需要参考其它画面而生成

5、I 帧是 P/B 帧的参考帧(其质量直接影响到同组中以后个帧的质量)

6、I 帧是帧组 GOP 的第一帧,在一组中只有一个 I 帧

7、I 帧不需要考虑运动矢量

8、I 帧所占数据的信息量比较大

B 帧

B 帧又称为双向差别帧,也就是本帧与前后帧的差别,大白话的意思就是要解码 B 帧,不仅要拿到之前缓存的画面,还要解码之后的画面,通过前后画面的叠加来还原最终的画面。

特点:

1、B 帧是由前面的 I 帧或 P 帧和后面的 P 帧来进行预测的

2、B 帧传送的是它前面的 I 帧或 P 帧和后面的 P 帧之前的预测误差及运动矢量

3、B 帧是双向预测编码帧

4、B 帧压缩率最高,因为它只反映参考帧间运动主体的变化情况,预测比较准确

5、B 帧不是参考帧,不会造成解码错误的扩散

P 帧

P 帧又称为前预测编码帧。P 帧表示的是这一帧跟之前的一个 I 或 P 帧的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,来生成最终画面。

特点:

1、P 帧是 I 帧后面相隔 1~2 帧的编码帧

2、P 帧采用运动补偿的方法传送它与前面的 I 或 P 真的差值及运动矢量

3、解码时必须将 I 帧中的预测值与预测误差求和后才能重构完整的 P 帧图像

4、P 帧属于前向预测的帧间编码。它只参考前面最靠近它的 I 或者 P 帧

5、P 帧可以是其后面的 P 帧的参考帧,也可以是其前后的 B 帧的参考帧

6、由于 P 帧是参考帧,所以它可能造成解码错误的扩散

7、由于是差值传送,所以 P 帧的压缩率比较高

基本的帧概念了解的差不多了,下一步我们基于代码来分析码流

码流分析

H.264 又称为裸流,是由多个 NALU 组成。如果 NALU 对应的 Slice 为一帧的开始,那么就用 4 个 字节表示,即 0x00 00 00 01 , 否则用 3 字节表示,0x00 00 01。要分析 H.264 码流首先是从码流中搜索起始位,也就是刚刚说的 0x00 00 00 01 或者 0x00 00 01 起始位,然后在分离 NALU, 最后再解析各个字段。下面我们先来看下 NALU Header type 代表的含义:
 

type 说明
0 保留
1 非 IDR 图像中不采用数据划分的片段
2 非 IDR 图像中 A 类数据划分的片段
3 非 IDR 图像中 B 类数据划分的片段
4 非 IDR 图像中 C 类数据划分的片段
5 IDR 图像的片段
6 补充增强信心 (SEI)
7 SPS (序列参数集)
8 PPS (图像参数集)
9 分割符
10 序列结束符
11 流结束符
12 填充数据
13 序列参数集扩展
14 带前缀的 NAL 单元
15 子序列参数集
16 - 18 保留
19 不采用数据划分的辅助编码图像片段
20 编码片段扩展
21 - 23 保留
24 - 31 保留

在实际开发中用的最多的也就是 1 、5 、7、8 , 下面我们用代码来进行分析:

代码分析

代码很简单,就是读文件,搜索起始码然后一个字节一个字节读,这里直接贴结果吧,详细代码可以直接看 传送门

参考

猜你喜欢

转载自blog.csdn.net/yinshipin007/article/details/126237213