一 H.264句法1.1元素分层结构H.264编码器输出的Bit流中,每一个Bit都隶属于某个句法元素。句法元素被组织成有层次的结构,分别描写叙述各个
一 H.264句法
1.1元素分层结构

H.264编码器输出的Bit流中,每一个Bit都隶属于某个句法元素。句法元素被组织成有层次的结构,分别描写叙述各个层次的信息。

图1

H.264分层结构由五层组成,各自是序列參数集、图像參数集、片(Slice)、和宏块和子块。參数集是一个独立的数据单位,不依赖于參数集外的其他句法元素。图2描写叙述了參数集与參数集外的句法元素之间的关系。

图2

一个參数集不正确应某一个特定的图像或序列,同一序列參数集能够被多个图像參数集引用,同理,同一个图像參数集也能够被多个图像引用。仅仅在编码器觉得须要更新參数集的内容时,才会发出新的參数集。

在H.264中,图像以序列为单位进行组织。一个序列的第一个图像叫做IDR图像,IDR图像都是I帧,H.264引入IDR图像为了解码的同步,当解码 器解码到IDR图像时,马上将參考帧队列清空,将已解码的数据所有输出或抛弃,又一次查找參数集,開始一个新的序列。这样,假设前一个序列出现重大错误,在 这里能够获得又一次同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。

IDR是I帧,但I帧不一定是IDR。I帧之后的图像有可能会使用I帧之前的图像做运动參考。

1.2描写叙述子

描写叙述子描写叙述从Bit流中取出句法元素的方法。
编号
语法
说明

1
ae(e)
CABAC

2
b(8)
读进连续的8个Bit

3
ce(v)
CAvlc

4
f(n)
读进连续的n个Bit

5
i(n)/i(v)
读进连续的若干Bit,并把它们解释为有符号整数

6
me(v)
映射指数Golomb熵编码

7
se(v)
有符号指数Golomb熵编码

8
te(v)
截断指数Golomb熵编码

9
u(n)/u(v)
读进连续的若干Bit,并把它们解释为无符号整数

10
ue(v)
无符号指数Golomb熵编码

表1
1.3句法的表示方法

句法元素的名称由小写字母和一系列下划线组成,变量名称是大写和小写字母组成,中间没有下划线。
二 句法表

定义了H.264的句法,指明在码流中依次出现的句法元素及它们出现的条件、提取描写叙述子等。句法表是分层嵌套的。

句法表中的C字段表示该句法元素的分类,这是为片区服务,分类的详细含义例如以下表描写叙述。
nal_unit_type
NAL类型
C

0
未使用

1
不分区、非IDR的片
2,3,4

2
片分区A
2

3
片分区B
3

4
版分区C
4

5
IDR图像中的片
2,3

6
补充增强信息单元(SEI)
5

7
序列參数集
0

8
图像參数集
1

9
分界符
6

10
序列结束
7

11
码流结束
8

12
填充
9

13..23
保留

24..31
不保留

表2
2.1 NAL语法

编码器将每一个NAL各自独立、完整地放入一个分组,由于分组都有头部,解码器能够方便地检測出NAL的分界,并依次取出NAL进行解码。

每一个NAL前有一个起始码 0x000001,解码器检測每一个起始码,作为一个NAL的起始标识,当检測到下一个起始码时,当前NAL结束。同一时候H.264规定,当检測到 0x000000时,也能够表征当前NAL的结束。对于NAL中数据出现0x000001或0x000000时,H.264引入了防止竞争机制,假设编码 器检測到NAL数据存在0x000001或0x000000时,编码器会在最后个字节前插入一个新的字节0x03,这样:

0x000000->0x00000300

0x000001->0x00000301

0x000002->0x00000302

0x000003->0x00000303

解码器检測到0x000003时,把03抛弃,恢复原始数据。

解码器在解码时,首先逐个字节读取NAL的数据,统计NAL的长度,然后再開始解码。

句法
C
Desc

nal_nuit(NumBytesInNALunit){/* NumBytesInNALunit为统计出来的数据长度 */

forbidden_zero_bit /* 等于0 */
All
f(1)

nal_ref_idc/* 当前NAL的优先级,取值范围0-3 */
All
u(2)

nal_unit_type /* NAL类型,见表2描写叙述 */
All
u(5)

NumBytesInRBSP=0

for(i=1;i<NumBytesInNALunit;i++){

if(i+2<NumBytesInNALunit && next_bits(24)==0x000003{

/* 0x000003伪起始码,须要删除0x03这个字节 */

rbsp_byte[NumBytesInRBSP++]
All
b(8)

rbsp_byte[NumBytesInRBSP++]
All
b(8)

i+=2/* 取出前两个0x00后,跳过0x03 */

emulation_prevention_three_byte/* equal to 0x03 */
All
f(8)

}else{

rbsp_byte[NumBytesInRBSP++] /* 继续读取后面的字节 */
All
b(8)

}

}

表3
2.2序列參数集(SPS)
句法
C
Desc

seq_parameter_set_rbsp(){

profile_idc/* 指明所用的Profile */
0
u(8)

constraint_set0_flag
0
u(1)

constraint_set1_flag
0
u(1)

constraint_set1_flag
0
u(1)

reserved_zero_5bits /* equal to 0 */
0
u(5)

level_idc /* 指明所用的Level */
0
u(8)

seq_parameter_set_id /* 指明本序列參数集的id号,0-31,被图像集引用,编码须要产生新的序列集时,使用新的id,而不是改变原来參数集的内容 */
0
ue(v)

log2_max_frame_num_minus4/* 为读取元素frame_num服务,frame_num标识图像的解码顺序,frame_num的解码函数是ue(v),当中 v=log2_max_frame_num_minus4+4,该元素同一时候指明frame_num的最大值MaxFrameNum=2( log2_max_frame_num_minus4+4)*/
0
ue(v)

pic_order_cnt_type /* 指明poc的编码方法,poc标识图像的播放顺序,poc能够由frame_num计算,也能够显示传送。poc共三种计算方式 */
0
ue(v)

if(pic_order_cnt_type==0)

log2_max_pic_order_cnt_lsb_minus4 /* 指明变量MaxPicOrderCntLsb的值, MaxPicOrderCntLsb=2(log2_max_pic_order_cnt_lsb_minus4+4) */
0
ue(v)

else if(pic_order_cnt_type==1){

delta_pic_order_always_zero_flag /* 等于1时,元素delta_pic_order_cnt[0]和delta_pic_order_cnt[1]不在片头中出现,而且它们的默认值是0,等于0时,上述两元素出现的片头中 */
0
u(1)

offset_for_non_ref_pic /* 用来计算非參考帧或场的poc,[-231,231-1] */
0
se(v)

offset_for_top_to_bottom_field/* 计算帧的底场的poc */
0
se(v)

num_ref_frames_inpic_order_cnt_cycle /* 用来解码poc,[0.255] */
0
ue(v)

for(i=0;i<num_ref_frames_inpic_order_cnt_cycle;i++)

offset_for_ref_frame[i]/* 用来解码poc,对于循环中的每一个元素指定一个偏移 */
0
se(v)

}

num_ref_frames /* 參考帧队列可达到的最大长度,[0,16] */
0
ue(v)

gaps_in_frame_num_value_allowed_flag /* 为1,同意slice header中的frame_num不连续 */
0
u(1)

pic_width_inmbs_minus1 /* 本元素加1,指明以宏块为单位的图像宽度 PicWidthInMbs=pic_width_in_mbs_minus1+1 */
0
ue(v)

pic_height_in_map_units_minus1 /* 本元素加1,指明以宏块为单位的图像高宽度 PicHeightInMapUnitsMbs=pic_height_in_map_units_minus1+1 */
0
ue(v)

frame_mbs_only_flag /* 等于0表示本序列中全部图像均为帧编码;等于1,表示可能是帧,也可能场或帧场自适应,详细编码方式由其他元素决定。结合前一元 素:FrameHeightInMbs=(2-frame_mbs_only_flag)*PicHeightInMapUnits */
0
ue(v)

if(frame_mbs_only_flag)

mb_adaptiv_frame_field_flag /* 指明本序列是否是帧场自适应模式:

frame_mbs_only_flag=1,所有是帧

frame_mbs_only_flag=0, mb_adaptiv_frame_field_flag=0,帧场共存

frame_mbs_only_flag=0, mb_adaptiv_frame_field_flag=1,帧场自适应和场共存*/
0
u(1)

direct_8x8_inference_flag /* 用于指明B片的直接和skip模式下的运动矢量的计算方式 */
0
u(1)

frame_cropping_flag /* 解码器是否要将图像裁剪后输出,假设是,后面为裁剪的左右上下的宽度 */
0
u(1)

if(frame_cropping_flag){

frame_crop_left_offset
0
ue(1)

frame_crop_right_offset
0
ue(1)

frame_crop_top_offset
0
ue(1)

frame_crop_bottom_offset
0
ue(1)

}

vui_parameters_present_flag /* 指明vui子结构是否出如今码流中,vui子结构在附录中指明,用于表征视频 格式的信息 */
0
u(1)

if(vui_parameters_present_flag)

vui_parameters()
0

rbsp_trailing_bits()
0

}

表4

H264格式具体说明相关推荐

  1. yuv编码成h264格式写成文件

    yuv编码成h264格式写成文件 (使用ffmpeg 编码yuv420p编码成h264格式) #include <stdio.h> #include <stdlib.h> #i ...

  2. EasyPusher安卓Android手机直播推送之MediaCodec 硬编码H264格式

    EasyPusher安卓Android手机直播推送之MediaCodec 硬编码H264格式 最近在研究EasyDarwin的Push库EasyPusher,EasyPusher可以推送H264视频到 ...

  3. 实现H264格式视频的流媒体播放

    http://bbs.chinavideo.org/forum.php?mod=viewthread&tid=7575&extra=&page=1 相信有不少人和我一样,希望实 ...

  4. Android使用MediaCodec硬解码播放H264格式视频文件

    前些时间,通过各种搜索加请教了好几个同行的朋友,在他们的指点下实现: RTSP+H264实时视频播放播放及把实时视频流保存到手机SD卡中,再对保存的H264格式文件进行播放等基本功能.非常感谢这些朋友 ...

  5. ffmpeg学习日记604-指令-将视频格式转为H264格式

    ffmpeg学习日记604-指令-将视频格式转为H264格式 在第四篇中,想要解码视频,缺没有弄清楚怎样的一个数据流,现在又明晰了一点,所谓的h264编解码,并不是直接将视频格式,通过h264编解码为 ...

  6. [opencv][原创]关于opencv-python的cv2保存视频不支持H264格式问题探讨

    项目有个不合理要求,能够在chrome浏览器打开播放,但是cv2根本不支持H264,由于版权原因,官方不支持h264格式所以当你使用诸如XVID,MJPG等虽然不影响使用和正常播放,但是就是无法在浏览 ...

  7. ffmpeg将yuv数据编码为H264格式数据

    1.yuv->H264经过编码后可以明显缩小视频文件的体积,例如我们经常看到的MP4文件其实就是由H264格式的视频文件和aac音频格式文件打包而成. 2.整个编码流程: 网上的一个关于AVFo ...

  8. Java 解码 H264 格式视频流中的图片

    引入依赖 <dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artif ...

  9. Android多媒体:H264格式文件转MP4格式文件

    项目有Rtsp实时视频播放功能 ,现在要实现边播放边保存的功能要求.我在音视频方面技术处理白痴水平,所以 只能简单地实现先把h264格式的视频流保存到SD卡,再把对应地h264文件转码成MP4格式文件 ...

  10. AVC/H264格式压缩编码原理

    1. H.264/AVC框架流程图 1.1 H.264/AVC框架图 H.264的功能分两层 VCL (VideoCoding Layer,视频编码层):负责高效的视频内容表示,其中包括了: 帧间和帧 ...

最新文章

  1. SecureCRT中文绿色免安装版修改字体颜色
  2. 行内元素与块级元素,以及区别
  3. [攻防世界][CTF][2020][MISC] 攻防世界 MISC writeup
  4. 设计模式----Adapter(适配器)
  5. python图标的演变_python day 22 CSS拾遗之箭头,目录,图标
  6. Python学习笔记:创建分数类
  7. 1.极限——介绍_1
  8. 注册表系列之恶作剧之吻
  9. 190217每日一句
  10. 高速电路设计与仿真之PCB篇(二)
  11. angular4之管道
  12. CFGAN--基于生成对抗神经网络的协同过滤推荐
  13. C盘爆红,一个操作将微信缓存踢走
  14. amoeba mysql_mysql中间件-amoeba
  15. android o bln-al10,华为荣耀BLN-AL10是什么型号
  16. STM32L151缓慢上断电-电源控制模块的使用(PVD、BOR、POR/PDR)
  17. Stardust 案例:制作散景光斑
  18. 程序员工具大全【持续更新】
  19. js实现抽奖滚动效果
  20. jQuery动画序列

热门文章

  1. springboot 防重复 提交
  2. String Manipulation
  3. UVA - 11478 Halum 二分+差分约束
  4. 基于android的设备故障诊断终端
  5. shaderlab学习一
  6. Oracle bootstrap$ 详解
  7. 《JAVA练习题目4》 训练要点:String和StringTokenizer的使用,以及排序算法。
  8. java 最少使用(lru)置换算法_「面试」LRU了解么?看看LinkedHashMap如何实现LRU算法...
  9. git 强制更新远程_版本控制管理工具git的常见指令合集
  10. linux怎么重命名多个文件,在Linux中如何一次重命名多个文件详解