上篇中,我们已经解析出了Slice_Header的句法元素,下面我们就可以根据前面已经解析出的SPS、PPS、Slice_Header的句法元素,来做一些准备性的工作。

我们首先要做的,就是要确定当前Slice所采用的编码方式,即当前Slice进行的是帧编码还是场编码,如果是帧编码,又是不是宏块级的帧场自适应?如果是场编码,那么当前Slice是作为顶场,还是底场?

为了要彻底弄清楚这些问题,我们先来介绍下,上面讨论的帧场及帧场自适应到底是什么意思。为此呢,我们就先来看下,什么是逐行扫描(progressive scan)和隔行扫描(interlaced scan)?

1、逐行扫描和隔行扫描

我们曾在【显示器是如何显示图形数据的】中,介绍过逐行扫描,并在【彩色电视制】中略提过隔行扫描。但是无论从显示器的角度,还是从电视机的角度,我们都是站在显示端(接收端)的角度,来看待逐行扫描和隔行扫描的。

事实上,逐行扫描和隔行扫描从最初的摄像端,到中间的逐行/隔行扫描信号传输,再到最后的显示端,它们的问题一直存在。在最原始的时候,从摄像端选择用隔行还是逐行采集图像之后,扫描方式在中间的信号传输,直到显示在屏幕上,都不会发生改变。

而科技发展到现在,可能最开始逐行扫描采集的视频,传输的时候转换成了隔行扫描,显示的时候又变成了逐行扫描。总之,隔行或逐行扫描的视频,它们之间是可以通过编码和解码相互转换的。

为了方便理解,我们画一个,从摄像到显示的最简单的一个模型图来看下:


从采集到显示

如果你乍一看这个流程有点陌生,请联系目前非常火爆的手机直播。左边摄像机就相当于主播的手机,主播打开摄像头采集图像,通过编码器实时编码后,图像通过网络传输到服务器,然后服务器将播放地址下发到用户端。此刻我们拿到播放地址进行播放,实时解码并显示在手机屏幕上。

与之类似,电视直播、网络在线视频也是同样的道理。

讲这一段是因为,我们要注意到,我们今天要讲的帧场编码模式,其实主要发生在上图左侧,也即摄像机采集图像然后进行编码的阶段。下面我们会体会到,站在摄像机的角度来理解逐行/隔行的编码方式非常好理解。

而为了引入逐行和隔行扫描这两个概念,我们还是先从右侧的显示端开始讲起。

1.1 逐行扫描

逐行扫描应用广泛,在我们目前的各类电脑显示屏、外接的显示器上,使用的都是逐行扫描。逐行扫描非常易于理解,它就是在光栅图像下,从图像的第一行顺序扫描到最后一行,也即下图:


原始图像(左) 和 逐行扫描帧(右)

逐行扫描的结果,就是产生完整的一帧图像,因此它进行的通常是帧编码。逐行扫描虽然现在应用广泛,但是在最初电视机刚刚兴起,还没有电脑的时代,逐行扫描确实是不实用的。主要有以下两点原因:

  • (1)逐行扫描产生的完整的一帧图像,占据的电视信号的带宽较大
  • (2)在【彩色电视制】中我们知道,PAL制的帧频为25帧每秒,NTSC的为30帧每秒。在这种情况下,如果采用逐行扫描的方式,人眼是会察觉到闪烁的。

因此聪明的人们想到,可以将一帧图像先扫描奇数场显示在屏幕上,然后再扫描偶数场。这样在相同的时间内,PAL制每秒可显示50场,NTSC可显示60场,这样既降低了带宽,又解决了闪烁的问题,隔行扫描也就这样产生了。

1.2 隔行扫描

就像刚才说的那样,隔行扫描是先扫描奇数场,然后扫描偶数场,也即顶场和底场。如下图:


隔行扫描的经典之处,就在这个先后上!

可以想象,当从第1行隔行扫到15行,扫描完顶场后,又重头开始扫底场,也即回到第2行开始扫,这中间是有个时间差的。这个时间差,如果站在摄像机采集图像的立场来理解,那么就是接下来理解隔行扫描下的视频编码方式的关键。

上面我们说,逐行扫描一般进行的是帧编码,而隔行扫描,则可以在帧编码和场编码之间做选择,那选择的依据是什么呢?接着往下看。

2、帧编码和场编码

现在我们就要回到,摄像机采集图像到编码器的阶段了。我们已经知道,摄像机采集图像的扫描方式有两种,但是因为隔行扫描的出现,它们的编码方式却不只两种。我们先来介绍最容易想到的情况,那就是针对一部视频,全部使用帧编码或全部使用场编码。

一般而言,对逐行扫描的视频全部进行帧编码。对隔行扫描的视频,就要选择是使用帧编码还是场编码,注意这里是只选择一次,然后整个视频序列都采用帧编码或场编码。如果隔行扫描采用帧编码,则是将顶场和底场合为一帧进行编码。

此时对于帧编码,在做帧间预测时,参考图像为帧图像,运动补偿也为帧运动补偿。对于场编码,则是两个场分别进行编码,在做帧间预测时,参考图像为场图像,运动补偿也为场运动补偿。

以目前二者应用的场合来看:

帧编码应用广泛,因为目前我们无论在手机端录的视频、还是在电脑端、显示器上播放的视频,基本都是逐行扫描。因此在我们这个系列教程里,很有可能并不会涉及到场编码。

由隔行扫描引出的场编码,多应用在电视业,所以对于从事互联网的人士来说,几乎碰不到场编码的情况。

不过即使如此,我们还是要继续介绍一下隔行扫描的编码方式,因为这样便于我们接下来理解H264中的几个重要的句法元素。这里我们介绍隔行扫描的前提,是整个视频序列只采用一种编码方式。

事实上,在整个视频编码中,编码方式的选择可以更灵活,这从我们上篇解析到的片层Slice_Header的field_pic_flag和bottom_field_flag就可以体会到。

3、 PAFF和MBAFF

【注】(Picture adaptive field-frame 和 Macro-block adaptive field-frame)

第2小节中,我们说的是整个视频序列只采用一种编码方式。但实际上对于隔行扫描的视频,我们还可以更灵活,通常可以分为以下三种编码方式:

  • (1)将两个场合为一帧进行帧编码
  • (2)两个场分别进行场编码
  • (3)将两个场合为一帧,但是在宏块级别上,两个上下相邻的场宏块组合成一个宏块对(MB pair,MBP),这种编码方式也称宏块级的帧场自适应,也即MBAFF,这是H264引入的一个新的编码特性。

其中前两点,不同于第2节的是,第1点和第2点是可以进行自适应切换的。也即在一个视频序列中,通过对编码效果的不同,选择是使用帧编码还是场编码,因此这种方式也称图像级的帧场自适应(PAFF)

这就是PAFF和MBAFF,下面我们更加细致一点来说明,为什么有了PAFF还需要MBAFF。

3.1 使用PAFF进行编码

在隔行扫描中,一个视频序列的运动图像部分,和非运动图像部分的编码,区别是很大的。

在开始时我们就说过,摄像机在进行隔行扫描时,顶场和底场的扫描时间上,是有一个时间差的。这个时间差是什么呢?就是当摄像机扫描完顶场的最后一行后,又回过头来扫描底场的第一行。

这样就导致,如果将顶场和底场合为一帧,那么顶场的第一行和底场的第一行就变成了相邻行,而实际上相邻行的扫描时间,整整差了一个场的扫描时间。

这对于非运动图像没什么,但是对于一个正在运动的图像而言,会导致合为一帧后,相邻两行的空间相关性比较低。所以对于运动的图像,两个场分别进行编码,相对合为一帧来编码更加节省码流。

对于非运动图像,两个场合为一帧后,空间相关性也很大,因此合为一帧进行帧编码更加节省码流。

这就是PAFF的工作方式,它会根据编码效果,调整整个图像的编码方式。

但这同时也变成了它的缺点,因为调整整个图像的编码方式,是个粒度非常粗的工作方式。对于视频序列而言,可能某些图像,同时存在运动区域和非运动区域,这时PAFF的缺点就很明显了,对这些图像使用帧编码或场编码似乎都不恰当,这时MBAFF就产生了。

3.2 使用MBAFF进行编码

MBAFF将两个场合为一帧,但是在宏块级别上,使用宏块对(MBAFF)为基本编码单元。这样在图像的运动区域,采用场编码,对于非运动区域,采用帧编码,比较两种方式产生的码流大小,就能在宏块级别选择更节省码流的编码方式。

4、H264中的帧场编码模式

前面三节,都是为这一节做铺垫。我们已经知道了,编码方式有帧编码、场编码、图像级的帧场自适应编码和宏块级的帧场自适应编码,看起来真的挺麻烦,那是因为我们没确定我们的立场。

当我们把立场放在Slice上,一个Slice的编码方式就只有三种:帧编码、场编码或MBAFF。

这就需要用到几个句法元素,分别为:SPS中的frame_mbs_only_flagmb_adaptive_frame_field_flag,Slice_Header中的field_pic_flagbottom_field_flag。具体流程如下:


H264帧场编码模式判断

判断出当前Slice的编码方式后,如果是宏块级的帧场自适应,通常用字段MbaffFrameFlag等于1来表示,这也是我们在理解Slice_Header中first_mb_in_slice的语义时需要用到的字段。

写到这里,很多人会问,编码模式是计算出来了,但我怎么知道它是逐行扫描还是隔行扫描呢?其实这已经比较能明显推断出来了,frame_mbs_only_flag等于1就代表逐行扫描,否则代表隔行扫描。当然这也是我个人的一个推断,因为资料较少也没找到地儿去验证,如果不对还请指正。

5、计算视频属性

根据句法元素判断出编码模式之后,就可以去计算视频的帧宽高、图像(帧/场)宽高了。

5.1 帧宽高

//(1)frame_width_in_mbs(以宏块为单位的帧/场宽,也是视频的宽度)
frame_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1
//(2)frame_height_in_mbs(以宏块为单位的帧高度,也是视频的高度)
frame_height_in_mbs = (2 - sps->frame_mbs_only_flag) *
(sps->pic_height_in_map_units_minus1 + 1)
//(3)frame_size_in_mbs(以宏块为单位的帧尺寸,也是视频的尺寸)
frame_size_in_mbs = frame_width_in_mbs * frame_height_in_mbs
//(4)frame_width(以像素为单位的帧/场宽,也是视频的宽度)
frame_width = frame_width_in_mbs * 16
//(5)frame_height(以像素为单位的帧高,也是视频的高度)
frame_height_in_mbs * 16
//(6)frame_width_chroma(色度所占的帧宽,假设采用格式为4:2:0)
frame_width_chroma = frame_width / 2
//(7)frame_height_chroma(色度所占的帧高,假设采用格式为4:2:0)
frame_height_chroma = frame_height / 2

5.2 图像宽高

对当前图像而言,在不知道它是帧或场的情况下,只有其高度才能受影响。

//(1)pic_height_in_mbs(以宏块为单位的图像高度)
pic_height_in_mbs = frame_height_in_mbs / (1 + field_pic_flag)
//(2)pic_size_in_mbs(以宏块为单位的图像尺寸)
pic_size_in_mbs = frame_width_in_mbs * pic_height_in_mbs

【H.264/AVC 句法和语义详解】(十二):H264中的帧场编码模式详解相关推荐

  1. 【H.264/AVC视频编解码技术】第五章【哈夫曼编码】

    本文章所需要的内容需要自行准备一个名为input.txt的文本文件作为案例演示.内容选择英语小短文即可 第一步,建立哈夫曼数 #include <iostream> #include &l ...

  2. 【H264/AVC 句法和语义详解】(二):h264码流格式与NALU详解一

    上一篇中,我们站在句法元素(或称语法元素)的角度,介绍了H.264的句法和语义,和句法元素的分层结构.在这篇中,我们更进一步,从比特的角度出发,来探索h264码流的组成.通过这篇的学习,我们会初步具备 ...

  3. 音视频编解码技术(一):MPEG-4/H.264 AVC 编解码标准

    一.H264 概述 H.264,通常也被称之为H.264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC) 1. H.264视频编解码的意义 H.264的出现就是为了创 ...

  4. H.264/AVC视频编解码技术

    一.基本概念 1.GOP GOP即Group of picture,是一组连续的图像,由一个I帧和多个B/P帧组成,是编解码器存取的基本单位.GOP结构常用的两个参数M和N,M指定GOP中首个P帧和I ...

  5. H.264/AVC技术进展及其务实发展策略思考

    随着NGN.3G及3G演进和NGBW等对视频.多媒体业务与网络应用的飞速发展需求,作为视频业务及存储应用核心技术的高效率 视频数字压缩编(译码)技术,愈来愈引起人们的关注,成为目前广播.视频与多媒体通 ...

  6. 在FPGA上实现H.264/AVC视频编码标准

    尽管H.264/AVC承诺将此已有视频编码标准具有更高的编码效率,它仍为系统架构师.DSP 工程师和硬件设计人员带来了巨大的工程设计挑战.H.264/AVC 标准引入了自 1990 年推出 H.261 ...

  7. 【H264/AVC 句法和语义详解】(五):Exp-Golomb指数哥伦布编码(理论篇)

    版权声明:本文为博主原创文章,未经博主允许不得转载.    https://blog.csdn.net/u011399342/article/details/80472399 本篇隶属于文集:< ...

  8. 【H.264/AVC视频编解码技术详解】十九:熵编码算法(5)——H.264的CABAC(上):语法元素的二值化方法...

    <H.264/AVC视频编解码技术详解>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战工程的形式对H.264的标准进行 ...

  9. H.264/AVC视频编解码技术详解 第一章 视频信息与压缩编码

    H.264/AVC视频编解码技术详解系列笔记 是对 H.264/AVC视频编解码技术详解 课程的学习 文章目录 人与世界的交互 视频信号的表示方法 视频压缩编码 视频信息为什么可以被压缩? 视频压缩编 ...

  10. 【H.264/AVC视频编解码技术详解】七、 熵编码算法(1):基础知识

    <H.264/AVC视频编解码技术详解>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战工程的形式对H.264的标准进行 ...

最新文章

  1. java list多字段排序_java中list通过多条件排序
  2. QT实现minheap(简单图形界面掌握)
  3. 通过FM CO_VB_ORDER_POST更新生产订单的Components数据
  4. ElasticSearch2.3.1环境搭建哪些不为人知的坑
  5. python importlib_metadata_Python 动态导入对象,importlib.import_module()的使用方法
  6. STEAM 97%好评,体验堪比《杀戮尖塔》,为什么玩家说这是2020年上半年最超值的游戏?
  7. QG3系统无法创建SAP employee的原因
  8. C++11标准出现后,函数指针写法汇总
  9. 算法 --- 递归生成括号
  10. Linux——CentOS建立一个最高权限的用户
  11. 妙趣横生的算法--二叉树
  12. SpringCloud实现一个模块调用另一个模块的服务
  13. 全局钩子原理以及操作流程
  14. JAVA 通过wContour和geotools实现等值面分析、裁切、出图
  15. 是香蕉还是芭蕉,芭蕉和香蕉的区别
  16. 标志寄存器FLAGS----小总结
  17. 线上连锁线下整合 连锁电商建设方案
  18. html文件如何设置右键菜单,windows系统使用小技巧,创建属于自己的右键新建菜单-右键菜单设置...
  19. DNS是如何进行域名解析的?
  20. HashMap是如何遍历的

热门文章

  1. 3dsMax一渲染就卡住、3DMAX渲染完卡死怎么办?解决方法来了
  2. 【c语言】求方程式 ax^2+bx+c=0 的根,分别考虑:1、有两个不等的实根 2、有两个相等的实根
  3. 微信公众平台、微信公众平台.小程序、微信.开放平台
  4. Pr对图像元素进行裁剪
  5. 计算机课件制作技能,PPT技能制作大比拼
  6. 毕业论文参考文献格式及引用设置
  7. 技术美术个人笔记(五)——体素距离场及体积雾
  8. 通过 prosody 搭建 XMPP 服务器
  9. 软件项目管理 1.3.敏捷项目管理概念
  10. 空间换时间,轻松提高性能100倍