一、视频采集
视频采集将模拟视频转换为数字视频,并以数字视频文件的格式保存。所谓视频采集,就是模拟摄像机、录像机。LD视盘机和电视机输出的视频信号通过特殊的模拟和数字转换设备转换为二进制数字信息。视频采集卡是视频采集的主要设备,分为专业和家庭两个层次。专业视频采集卡不仅可以进行视频采集,还可以实现硬件视频压缩和视频编辑。家用级视频采集卡只能实现视频采集和初步硬件压缩,而更低端的电视卡可以采集视频,但通常节省了硬件级视频压缩功能。
隔行扫描和逐行扫描的区别 扫描:无论是逐行扫描还是分行扫描,都是显示设备中运动图像的方法。说到扫描,液晶电视显示屏的常用扫描方法是从左到右从上到下,每秒扫描固定帧数。 隔行扫描(Interlaced):隔行扫描方法是将每帧分成两个图片交替显示。 隔行扫描(Interlaced)也就是说,每帧分为两个游戏,每个游戏包括一帧中所有的奇数扫描线或偶数扫描线。通常,第一次扫描奇数线,然后第二次扫描偶数线。由于视觉暂留效应,人眼会看到平滑的运动而不是闪烁的半帧半帧图像。但在这个时候,会有几乎没有注意到的闪烁,使人眼容易疲劳。当屏幕的内容是横条纹时,这种闪烁特别容易被注意到。 逐行扫描(Progressive):逐行扫描是同时显示每帧的所有图片。每次显示整个扫描帧时,如果逐行扫描的帧率与单独扫描的场率相同,人眼会看到比单独扫描更光滑的图像,闪烁小于单独扫描。每一帧图像都是由电子束连续扫描,称为单独扫描。
隔行扫描(Interlaced)和逐行扫描(Progressive)在显示设备中表示运动图像的方法。为了获得稳定的逐行扫描图像,每帧图像必须扫描整数行。例如,一帧图像由连续扫描625行组成,每秒扫描50帧图像,即50帧/秒或50帧Hz(赫芝),扫描频率为 31.25kHz。
每一帧图像都是由电子束连续扫描而成,称为逐行扫描。通过两次扫描完成每帧图像是隔行扫描。在两次扫描中,第一次(奇数场)只扫描奇数线,依次扫描1、3、5…第二场(偶数场)只扫描偶数行,依次扫描2、4、6…行。分离扫描技术在传输信号带宽不足的情况下起着重要作用。分离扫描和分离扫描的显示效果主要不同于稳定性。分离扫描的行间闪烁明显。分离扫描克服了分离扫描的缺点,画面光滑自然。在电视的标准显示模式中,i表示隔行扫描,p表示逐行扫描。
i隔行扫描,1秒=25帧=50场
NTSC制作:规定每秒需要30帧,每帧需要525行 1秒=30帧,每帧扫两次,每秒60次,所以N系统的扫描频率是60hz。标准扫描线需要525行,水平频率为30*525=15750hz=15.75mhz
PAL标准下:规定每秒需要25帧,每帧需要625行 1秒=25帧,每帧扫两次,每秒50次,所以P系统的扫描频率是50hz。标准扫描线需要625行,水平频率为25*625=15625hz=15.625mhz
每帧需要625行,很明显pal比n制内容多,所以扫得慢,每秒规定25帧画面。
分行扫描的行扫描频率是分行扫描的一半,因此电视信号的频谱和传输信号的信道带宽也是分行扫描的一半。采用隔行扫描后,当图像质量下降不大时,信道利用率提高了一倍。由于信道带宽的减小,使系统及设备的复杂性与成本也相应减少,这就是为什么世界上早期的电视制式均采用隔行扫描的原因。然而,分离扫描也会带来许多缺点,如行间闪烁、并行和垂直边缘锯齿化。自数字电视发展以来,逐行扫描已成为数字电视扫描的首选,以获得高质量的图像质量。
ffmpeg将视频从隔行扫描转变为逐行扫描
其实主要是这个参数-deinterlace 隔行扫描的视频通常在播放时播放 会有横条感 逐行扫描的视频播放时感觉好多了,感觉清晰多了。
ffmpeg -i 1.mts -strict -2 -vcodec libx264-vb 2000k -deinterlace -r 30 -vprofile high -vlevel 5.1 -acodec aac -ar 44100-ab 128k a.mp4
二、视频采集处理YUV数据格式
一般来说,视频采集芯片输出的码流是YUV从视频处理(如数据流)的形式H.264、MPEG从视频编解码的角度来看,它也是原始的YUV编码和分析代码流,所以,了解如何分析YUV对于视频领域的人来说,数据流非常重要。
YUV亮度信息Y和色度信息的原理UV分离,其中"Y"表示明亮度(Lumina nce或Luma),也就是灰阶值;和"U"和"V"表示色度(Chrominance或Chroma),其功能是描述图像颜色和饱和度,用于指定像素颜色。当只提取Y信息时,视频呈现黑白图像,通常称为灰度图像。
下面我将介绍几种常用的。YUV码流格式,供您参考。
1. 采样方式
YUV码流的存储格式实际上与采样方式密切相关,主流采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0,可以通过网上其他文章了解其详细原理。我想强调的是如何根据其采样格式从码流中恢复每个像素点YUV值,因为每个像素点只能正确恢复YUV值,才能通过YUV与RGB提取每个像素点的转换公式RGB值,然后显示。
用三个图来直观地表示采集的方式吧,以黑点表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量。
记住以下段落,然后提取每个像素YUV将使用重量。
YUV 4:4:4采样,每个Y对应一组UV分量。 YUV 4:2:2采样,每两个Y共用一组UV分量。
YUV 4:2:0采样,每四个Y共用一组UV分量。
2. 存储方式
下面我以图片的形式给出常见的形式YUV码流的存储模式,每个像素点的取样都附在存储模式后面YUV其中,数据的方法,Cb、Cr意思等于U、V。
(1) YUVY 格式 (属于YUV422)
YUYV为YUV422采样的存储格式之一,相邻的两个Y共用相邻的两个Cb、Cr,对像素点进行分析Y'00、Y'01 而言,其Cb、Cr的值均为 Cb00、Cr00,其他的像素点的YUV依次类推取值。
(2) UYVY 格式 (属于YUV422)
UYVY格式也是YUV422采样的存储格式中的一种,只不过与YUYV不同的是UV排列顺序不同,恢复每个像素点YUV值的方法和上面一样。
(3) YUV422P(属于YUV422)
YUV422P也属于YUV一种422,是一种Plane模式,即包装模式,不是YUV数据交错存储,但首先存储所有Y重量,然后存储所有Y重量U(Cb)重量,最后存储所有V(Cr)重量,如上图所示。每一个像素点YUV还遵循了提取值的方法YUV最基本的422格式提取方法,即两个Y共用一个UV。比如像素点Y'00、Y'01 而言,其Cb、Cr的值均为 Cb00、Cr00。
(4)YV12,YU12格式(属于YUV420)
YU12和YV12属于YUV420格式,也是一种Plane模式,将Y、U、V分别打包,依次存放。每一个像素点YUV遵循数据提取YUV420格式的提取方法,即4个Y分量共用一组UV。注意,上图中,Y'00、Y'01、Y'10、Y'11共用Cr00、Cb其他的依次类推。
(5)NV12、NV21(属于YUV420)
NV12和NV21属于YUV420格式,是一种two-plane模式,即Y和UV分为两个Plane,但是UV(CbCr)交错存储,而不是三种plane。其提取方法与上一种相似,即Y'00、Y'01、Y'10、Y'11共用Cr00、Cb00
3. 总结
几种常见的YUV码流格式简单列在上面,大家都在处理YUV在码流之前,先了解自己的码流属于哪一种,再相应处理。
最后,回答另一个问题,即分析清楚YUV码流格式,我们能做什么?最常用的一点是提取所有Y分量,然后使用vc或者matlab你收集的图像的灰度值(Y重量)显示处理,这样你就可以很快知道你收集的图像是否有问题。以后我会继续写一些关于如何提取、转换和显示的文章YUV如果您感兴趣,可以继续关注原始码流。欢迎留言讨论。
from:http://ticktick.blog.51cto.com/823160/555791
=====================================================================================================
概述 YUV(亦称YCrCb)是欧洲电视系统采用的一种颜色编码方法(属于PAL),是PAL和SECAM模拟彩色电视系统中使用的颜色空间。其中的Y,U,V几个字母不是英语单词的组合词,Y代表亮度,uv代表色差,u和v是构成颜色的两个重量。在现代彩色电视系统中,像头通常用于现代彩色电视系统CCD摄像机取像,然后将获得的彩色图像信号分得的彩色图像信号RGB,然后通过矩阵变换电路获得亮度信号Y和两个色差信号R-Y(即U)、B-Y(即V),最后,发送端分别编码亮度和色差三个信号,并通过同一信道发送。表达这种颜色的方法叫做YUV色彩空间表。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有 Y信号分量而没有U、V信号分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的相容问题,使黑白电视机也能接收彩色电视信号。 优点作用 YUV主要用于优化彩色 视频信号的传输,使其向后相容老式黑白电视。与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立的视频信号同时传输)。其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和CB来表示。其中,Cr反映了GB输入信号红色部分与RGB信号亮度值之间的差异。而CB反映的是RGB输入信号蓝色部分与RGB信号亮度值之同的差异。 采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。 YUV与RGB相互转换的公式如下(RGB取值范围均为0-255)︰ Y = 0.299R + 0.587G + 0.114B U = -0.147R - 0.289G + 0.436B V = 0.615R - 0.515G - 0.100B R = Y + 1.14V G = Y - 0.39U - 0.58V B = Y + 2.03U 在DirectShow中,常见的RGB格式有RGB1、RGB4、RGB8、RGB565、RGB555、RGB24、RGB32、ARGB32等;常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等。 YUV主要的采样格式 主要的采样格式有YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和 YCbCr 4:4:4。其中YCbCr 4:1:1 比较常用,其含义为:每个点保存一个 8bit 的亮度值(也就是Y值),每 2x2 个点保存一个 Cr 和Cb 值, 图像在肉眼中的感觉不会起太大的变化。所以, 原来用 RGB(R,G,B 都是 8bit unsigned) 模型, 4 个点需要 8x3=24 bites(如下图第一个图)。而现在仅需要 8+(8/4)+(8/4)=12bites, 平均每个点占12bites(如下图第二个图)。这样就把图像的数据压缩了一半。 上边仅给出了理论上的示例,在实际数据存储中是有可能是不同的,下面给出几种具体的存储形式: (1) YUV 4:4:4 YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节。 下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] 存放的码流为: Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3 (2) YUV 4:2:2 每个色差信道的抽样率是亮度信道的一半,所以水平方向的色度抽样率只是4:4:4的一半。对非压缩的8比特量化的图像来说,每个由两个水平方向相邻的像素组成的宏像素需要占用4字节内存。 下面的四个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] 存放的码流为:Y0 U0 Y1 V1 Y2 U2 Y3 V3 映射出像素点为:[Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3] (3) YUV 4:1:1 4:1:1的色度抽样,是在水平方向上对色度进行4:1抽样。对于低端用户和消费类产品这仍然是可以接受的。对非压缩的8比特量化的视频来说,每个由4个水平方向相邻的像素组成的宏像素需要占用6字节内存。 下面的四个像素为: [Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] 存放的码流为: Y0 U0 Y1 Y2 V2 Y3 映射出像素点为:[Y0 U0 V2] [Y1 U0 V2] [Y2 U0 V2] [Y3 U0 V2] (4)YUV4:2:0 4:2:0并不意味着只有Y,Cb而没有Cr分量。它指得是对每行扫描线来说,只有一种色度分量以2:1的抽样率存储。相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0...以此类推。对每个色度分量来说,水平方向和竖直方向的抽样率都是2:1,所以可以说色度的抽样率是4:1。对非压缩的8比特量化的视频来说,每个由2x2个2行2列相邻的像素组成的宏像素需要占用6字节内存。 下面八个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] [Y5 U5 V5] [Y6 U6 V6] [Y7U7 V7] [Y8 U8 V8] 存放的码流为:Y0 U0 Y1 Y2 U2 Y3 Y5 V5 Y6 Y7 V7 Y8 映射出的像素点为:[Y0 U0 V5] [Y1 U0 V5] [Y2 U2 V7] [Y3 U2 V7] [Y5 U0 V5] [Y6 U0 V5] [Y7U2 V7] [Y8 U2 V7] 各种YUV格式(图) YUV格式通常有两大类:打包(packed)格式和平面(planar)格式。前者将YUV分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素(macro-pixel);而后者使用三个数组分开存放YUV三个分量,就像是一个三维平面一样。表2.3中的YUY2到Y211都是打包格式,而IF09到YVU9都是平面格式。(注意:在介绍各种具体格式时,YUV各分量都会带有下标,如Y0、U0、V0表示第一个像素的YUV分量,Y1、U1、V1表示第二个像素的YUV分量,以此类推。) ¨ YUY2(和YUYV)格式为每个像素保留Y分量,而UV分量在水平方向上每两个像素采样一次。一个宏像素为4个字节,实际表示2个像素。(4:2:2的意思为一个宏像素中有4个Y分量、2个U分量和2个V分量。)图像数据中YUV分量排列顺序如下: Y0 U0 Y1 V0 Y2 U2 Y3 V2 … ¨ YVYU格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同: Y0 V0 Y1 U0 Y2 V2 Y3 U2 … ¨ UYVY格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同: U0 Y0 V0 Y1 U2 Y2 V2 Y3 … ¨ AYUV格式带有一个Alpha通道,并且为每个像素都提取YUV分量,图像数据格式如下: A0 Y0 U0 V0 A1 Y1 U1 V1 … ¨ Y41P(和Y411)格式为每个像素保留Y分量,而UV分量在水平方向上每4个像素采样一次。一个宏像素为12个字节,实际表示8个像素。图像数据中YUV分量排列顺序如下: U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y8 … ¨ Y211格式在水平方向上Y分量每2个像素采样一次,而UV分量每4个像素采样一次。一个宏像素为4个字节,实际表示4个像素。图像数据中YUV分量排列顺序如下: Y0 U0 Y2 V0 Y4 U4 Y6 V4 … ¨ YVU9格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个4 x 4的宏块,然后每个宏块提取一个U分量和一个V分量。图像数据存储时,首先是整幅图像的Y分量数组,然后就跟着U分量数组,以及V分量数组。IF09格式与YVU9类似。 ¨ IYUV格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个2 x 2的宏块,然后每个宏块提取一个U分量和一个V分量。YV12格式与IYUV类似。
¨ YUV411、YUV420格式多见于DV数据中,前者用于NTSC制,后者用于PAL制。YUV411为每个像素都提取Y分量,而UV分量在水平方向上每4个像素采样一次。YUV420并非V分量采样为0,而是跟YUV411相比,在水平方向上提高一倍色差采样频率,在垂直方向上以U/V间隔的方式减小一半色差采样,如上图所示。
三、常见视频编码格式
常用的有Xvid,H264,MPEG1,MPEG2。
Xvid:与RMVB格式差不多的压缩率,通用性很强,特别是用于家用DVD和便携式MP4等设备。
H264:压缩率最高的视频压缩格式,与其他编码格式相比,同等画面质量,文件体积最小,远远超过RMVB编码格式,电脑都可以播放,部分便携式视频设备也支持,如苹果播放器。PDA/PPC等设备也可以使用
MPEG1:其实就是VCD编码格式。
MPEG2:DVD编码格式。比MPEG1强,与MPEG1一样,已经落后的编码格式,压缩率都不高,编码后的文件体积大。
视频编码方式就是指通过特定的压缩技术,将某个视频格式的文件转换成另 一种视频格式文件的方式。目前视频流传输中最为重要的编解码标准有国际电联的H.264,运动静止图像专家组的M-JPEG和国际标准化组织运动图像专家 组的MPEG系列标准,此外在互联网上被广泛应用的还有Real-Networks的RealVideo、微软公司的WMV以及Apple公司的 QuickTime等,到目前google力推的WebM格式都收到了我们的关注。以下我们会为大家就主流的视频编码做一下讲解。
编码对比
视频国际标准化相关组织的的ISO和ITU-T
格式的统一肯定会极大地提高人们的生活的便利以及数据的传播,为什么还会有如此繁多的视频编码的方式,难道就没有专门机构或者组织来管理一下吗?带着这些疑问我们认识一下底下的两个机构。
■ ITU-T
ITU-T的中文名称是国际电信联盟远程通信标准化组织(ITU-T for ITU Telecommunication Standardization Sector), 它是国际电信联盟管理下的专门制定远程通信相关国际标准的组织。由ITU-T指定的国际标准通常被称为建议(Recommendations)。由于 ITU-T是ITU的一部分,而ITU是联合国下属的组织,所以由该组织提出的国际标准比起其它的组织提出的类似的技术规范更正式一些。
它制定的标准有H.261、H.263、H.263+等,目前流行最广的,影响也是最大的H.264也有他的一份功劳。底下附上
H - 视频音频以及多媒体系统复合方法
H.223 低码率多媒体通信复合协议
H.225.0 也被称为实时传输协议
H.261 视频压缩标准, 约1991年
H.262 视频压缩标准(和MPEG-2第二部分内容相同), 约1994年
H.263 视频压缩标准, 约1995年
H.263v2 (也就是 H.263+) 视频压缩标准, 约1998年
H.264 视频压缩标准(和MPEG-4第十部分内容相同), 约2003年
H.323 基于包传输的多媒体通信系统
■ ISO
国际标准化组织(ISO)是由各国标准化团体(ISO成员团体)组成的世界性的联合会。负责各种标准的制定,当然也少不了关于视频编码方面的。它制定的标准有MPEG-1、MPEG-2、MPEG-4等。并且已经制定出来了最新的MPEG-7,并且计划公布MPEG-21。
国际标准化组织(ISO)制定的标准主要集中在MPEG系列。也就是由动态的图像专家组制定的一系列的标准。
由ISO下属的MPEG运动图象专家组开发视频编码方面主要是Mpeg1(vcd用的就是它)、Mpeg2(DVD使用)、Mpeg4(现在的DVDRIP使用的都是它的变种,如:divx,xvid等)、Mpeg4 AVC(现在正热门也就是H.264)
了解一下这两家机构是我们了解视频编码之所以会对现在所采用的主流视频的编码有着重要的作用。正是这两家机构根据不同的时期对于视频编码的不断地调整才使 得目前的视频编码看起来混乱的原因。其实本意是为了满足目前互联网的快速发展以及随着电脑性能的提高做得调整,随着时间的推移,可以预见的是短时间内视频 的编码还是会多家并存,随着google、微软等巨头的涌入,可能会在不久的将来也发生一定的变化。
国际标准化组织制定的MPEG-4
ISO国际标准化组织制定的MPEG-4
MPEG 全称是Moving Pictures Experts Group,它是“动态图象专家组”的英文缩写,该专家组成立于1988年,致力于运动图像及其伴音的压缩编码标准化工作,原先他们打算开发MPEG1、 MPEG2、MPEG3和MPEG4四个版本,以适用于不同带宽和数字影像质量的要求。
MPEG系列标准已成为国际上影响最大的多媒体技术标准,其中MPEG-1和MPEG-2是采用以香农信息论为基础的预测编码、变换编码、熵编码及运 动补偿等第一代数据压缩编码技术;MPEG-4(ISO/IEC 14496)则是基于第二代压缩编码技术制定的国际标准,它以视听媒体对象为基本单元,采用基于内容的压缩编码,以实现数字视音频、图形合成应用及交互式 多媒体的集成。MPEG系列标准对VCD、DVD等视听消费电子及数字电视和高清晰度电视(DTV和HDTV)、多媒体通信等信息产业的发展产生了巨大而深远的影响。
MPEG1已经在VCD上得到了广泛的应用,而MPEG2在DVD以及广播电视上面得到了利用,而MPEG3最初是为HDTV开发的编码和压缩标准,但由于MPEG2的出色性能表现,MPEG3并没有得到重用,只好在半路就被pass掉了。
MPEG-4的规范
MPEG-4于1999年初正式成为国际标准。它是一个适用于低传输速率应用的方案。与MPEG1和MPEG2相比,MPEG4更加注重多媒体系统的交 互性和灵活性。MPEG-4(同时也是ISO/IEC 14496)的制订并非只有动态视频的编解码而已,其中还包括诸多的环节与项目,真正与视频直接且密切相关的,其实就是MPEG-4 Part 2(也称为MPEG-4 Visual)的部分,其余还有用于传送时的整合架构规范、文件格式、软件规范、相关定义等。
MPEG1、MPEG2技术当初制定时,它们定位的标准均为高层媒体表示与结构,但随着计算机软件及网络技术的快速发展,MPEG1.MPEG2技术的弊 端就显示出来了:交互性及灵活性较低,压缩的多媒体文件体积过于庞大,难以实现网络的实时传播。而MPEG4技术的标准是对运动图像中的内容进行编码,其 具体的编码对象就是图像中的音频和视频,术语称为“AV对象”,而连续的AV对象组合在一起又可以形成AV场景。因此,MPEG4标准就是围绕着AV对象 的编码、存储、传输和组合而制定的,高效率地编码、组织、存储、传输AV对象是MPEG4标准的基本内容。AV对象(AVO,Audio Visual Object)是MPEG-4为支持基于内容编码而提出的重要概念。对象是指在一个场景中能够访问和操纵的实体,对象的划分可根据其独特的纹理、运动、形 状、模型和高层语义为依据。在MPEG-4中所见的视音频已不再是过去MPEG-1、MPEG-2中图像帧的概念,而是一个个视听场景(AV场景),这些 不同的AV场景由不同的AV对象组成。AV对象是听觉、视觉、或者视听内容的表示单元,其基本单位是原始AV对象,它可以是自然的或合成的声音、图像。原 始AV对象具有高效编码、高效存储与传输以及可交互操作的特性,它又可进一步组成复合AV对象。因此MPEG-4标准的基本内容就是对AV对象进行高效编 码、组织、存储与传输。AV对象的提出,使多媒体通信具有高度交互及高效编码的能力,AV对象编码就是MPEG-4的核心编码技术.
在视频编码方面,MPEG4支持对自然和合成的视觉对象的编码。(合成的视觉对象包括2D、3D动画和人面部表情动画等)。在音频编码上,MPEG4可以在一组编码工具支持下,对语音、音乐等自然声音对象和具有回响、空间方位感的合成声音对象进行音频编码。
由于MPEG4只处理图像帧与帧之间有差异的元素,而舍弃相同的元素,因此大大减少了合成多媒体文件的体积。应用MPEG4技术的影音文件最显著特点就是 压缩率高且成像清晰,一般来说,一小时的影像可以被压缩为350M左右的数据,而一部高清晰度的DVD电影, 可以压缩成两张甚至一张650M CD光碟来存储。
做一个对比就可以清楚地看到MPEG-4(part2)的优点,如果传输一个1920×1080的HD高分辨率、24fps(每秒更新24张画面)传输频 宽上MPEG-2需要12~20Mbps,相对的MPEG-4 SP(第二部分)只要10Mbps多点,更直接地说,若将MPEG-2的频宽视为基准100%,MPEG-4 SP要达相同体验效果只需60%频宽。
■MPEG-4的技术特点
MPEG-4则代表了基于模型/对象的第二代压缩编码技术,它充分利用了人眼视觉特性,抓住了图像信息传输的本质,从轮廓、纹理思路出发,支持基于视觉内容的交互功能,这适应了多媒体信息的应用由播放型转向基于内容的访问、检索及操作的发展趋势。
MPEG-4不仅可提供高压缩率,同时也可实现更好的多媒体内容互动性及全方位的存取性,它采用开放的编码系统,可随时加入新的编码算法模块,同时也可根据不同应用需求现场配置解码器,以支持多种多媒体应用。
MPEG-4 采用了新一代视频编码技术,它在视频编码发展史上第一次把编码对象从图像帧拓展到具有实际意义的任意形状视频对象,从而实现了从基于像素的传统编码向基于对象和内容的现代编码的转变,因而引领着新一代智能图像编码的发展潮流。
MPEG-4作为新一代多媒体数据压缩编码的典型代表,它第一次提出了基于内容、基于对象的压缩编码思想。它要求对自然或合成视听对象作更多分析甚至是理解,这正是信息处理的高级阶段,因而代表了现代数据压缩编码技术的发展方向。
MPEG-4实现了从矩形帧到VOP的转变以及基于像素的传统编码向基于对象和内容的现代编码的转变,这正体现了传统视频编码与新一代视频编码的有机统一。基于内容的交互性是MPEG-4的核心思想,这对于视频编码技术的发展方向及广泛应用都具有特别重要的意义。
目前的主流H.264
■ 目前主流占优势的H.264
H.264 是由ITU-T 的VCEG(视频编码专家组)和ISO/IEC 的MPEG(活动图像编码专家组)联合组建的联合视频组(JVT:joint video team)提出的一个新的数字视频编码标准,它既是ITU-T 的H.264,又是ISO/IEC 的MPEG-4 的第10 部分。而国内业界通常所说的MPEG-4 是MPEG-4 的第2 部分。即:
H.264=MPEG-4(第十部分,也叫ISO/IEC 14496-10)=MPEG-4 AVC
因此,不论是MPEG-4 AVC、MPEG-4 Part 10,还是ISO/IEC 14496-10,都是指H.264。H.264也是MPEG-4的一部分。
H.264标准从1998 年1 月份开始草案征集,到2003 年7 月,整套H.264 (ISO/IEC 14496-10)规范定稿。2005年1 月,MPEG 组织正式发布了H.264 验证报告,从各个方面论证了H.264 的可用性以及各种工具集的效果,从标准的角度,印证H.264 的成熟性。
H.264
关于该技术的视频编码方案,现在正式命名为ITU-T H.264或“JVT/AVC草案”。H.264/MPEG-4 AVC作为MPEG-4标准的扩展(MPEG-4 Part 10),充分利用了现有MPEG-4标准中的各个环节。H.264/MPEG-4 AVC就在现有MPEG-4 Advanced Simple Profile的基础之上进行发展的。它即保留了以往压缩技术的优点和精华又具有其他压缩技术无法比拟的许多优点。
H.264的技术特点:
H.264 使图像压缩技术上升到了一个更高的阶段,能够在较低带宽上提供高质量的图像传输,该优点非常适合国内运营商用户量大、接入网/骨干网带宽相对有限的状况。 在同等的画质下,H.264 比上一代编码标准MPEG2 平均节约64%的传输码流,而比MPEG4 ASP 要平均节约39%的传输码流。全球很多IPTV业务运营商都将H.264 作为编解码格式的标准,包括比利时电信,荷兰KPN,泰国ADC 电信,中国电信等等。
根据中国电信上海研究院的实际测试结果表明:国内普遍采用的MPEG-4 编码技术在3Mbps 的带宽下尚达不到标清的图像质量,而H.264 编码技术可以在2M 带宽下提供要求的图像效果。因而运营商希望引入更先进的H.264 编码技术,在有限的带宽资源下进一步提高图像质量。其主要的特点是:
1.更高的编码效率:同H.263等标准的特率效率相比,能够平均节省大于50%的码率。
2.高质量的视频画面:H.264能够在低码率情况下提供高质量的视频图像,在较低带宽上提供高质量的图像传输是H.264的应用亮点。和MPEG2和 MPEG4 ASP等压缩技术相比,在同等图像质量下,采用H.264技术压缩后的数据量只有MPEG2的1/8,MPEG4的1/3。显然,H.264压缩技术的采 用将大大节省用户的下载时间和数据流量收费。
3.提高网络适应能力:H.264可以工作在实时通信应用(如视频会议)低延时模式下,也可以工作在没有延时的视频存储或视频流服务器中。
4.采用混合编码结构:同H.263相同,H.264也使用采用DCT变换编码加DPCM的差分编码的混合编码结构,还增加了如多模式运动估计、帧内预测、多帧预测、基于内容的变长编码、4x4二维整数变换等新的编码方式,提高了编码效率。
5.H.264的编码选项较少:在H.263中编码时往往需要设置相当多选项,增加了编码的难度,而H.264做到了力求简洁的“回归基本”,降低了编码时复杂度。
6.H.264可以应用在不同场合:H.264可以根据不同的环境使用不同的传输和播放速率,并且提供了丰富的错误处理工具,可以很好的控制或消除丢包和误码。
7.错误恢复功能:H.264提供了解决网络传输包丢失的问题的工具,适用于在高误码率传输的无线网络中传输视频数据。
8.较高的复杂度:264性能的改进是以增加复杂性为代价而获得的。据估计,H.264编码的计算复杂度大约相当于H.263的3倍,解码复杂度大约相当于H.263的2倍。
技术上,它集中了以往标准的优点,并吸收了标准制定中积累的经验。与H.263v2(H.263+) 或MPEG-4简单类(Simple Profile)相比,H.264在使用与上述编码方法类似的最佳编码器时,在大多数码率下最多可节省50%的码率。H.264在所有码率下都能持续提供 较高的视频质量。H.264能工作在低延时模式以适应实时通信的应用(如视频会议),同时又能很好地工作在没有延时限制的应用,如视频存储和以服务器为基 础的视频流式应用。H.264提供包传输网中处理包丢失所需的工具,以及在易误码的无线网中处理比特误码的工具。
在系统层面上,H.264提出了一个新的概念,在视频编码层(Video Coding Layer, VCL)和网络提取层(Network Abstraction Layer, NAL)之间进行概念性分割,前者是视频内容的核心压缩内容之表述,后者是通过特定类型网络进行递送的表述,这样的结构便于信息的封装和对信息进行更好的 优先级控制。
既生瑜何生亮?
其 实通过上面的讨论我们也看到了H.264跟MPEG-4(part2)都是为了互联网而生,而且有许多共同的特点,那么既生MPEG-4?何生 H.264?有了MPEG-4(第二部分)为什么还要H.264,岂不是多此一举?两者到底有多大的区别呢?为何需要再订制出MPEG-4 Part 10呢?直接沿用MPEG-4 Part 2难道不行?
虽然MPEG-4已针对Internet传送而设计,提供比MPEG-2更高的视频压缩效率,更灵活与弹性变化的播放取样率,但就视频会议而言总希望有更进一步的压缩,所以才需要出现了H.264。
首 先就是上文提到的H.264对于带宽的要求低,在带宽比较吃紧的情况下一样可以正常的工作,只相当于MPEG-4第二部分的2/3,不要小看这些,这些就 可以决定你看视频是否流畅。更具体地说,H.264力求在40kbps~300kbps的有限带宽下尽可能得到流畅、清晰的表现。
那么到底压缩了更小的H.264能够有更高的压缩率,播放效果是不是大打折扣呢?播放效果与MPEG-2、MPEG-4近乎相同嘛?是的,其实视频的质量 我们看不出多大的差别,之所以出现这种现象答案在于H.264采用了更复杂的编码算法,当然对于解码也提出了更高的要求。
以前之所以未采用更复杂的算法,是考虑到解码(播放)端的运算能力不足,就会导致播放不流畅,失去视频娱乐观赏的意义,但如今不同,无论桌面电脑、移动终 端的性能都突飞猛进,即便运用更复杂的压缩编码都可以实时解码、流畅地播放,这正是MEPG-4、H.264能够流行的一项先决条件。
但是其实这些都不是关键,目前的宽带已经完全满足了mpeg-4第二部分的使用,但是为什么还要H.264呢?就是因为授权的问题。关于这个问 题,H.264不仅压缩算法比以往的MPEG-4更优异,带宽耗用更低,还有一项最诱人的特点:授权费用比较合理,因为H.264晚于MPEG-4问世, 且两者定位接近,既然如此,H.264只好在授权费上降低定位,期盼以较宽厚的授权方式争取被采用,而这正是对了运营商的胃口,当初许多运营商对 MPEG-4的授权深表反感,之后也都热烈拥护H.264。
MPEG-7视频编解码技术标准
MPEG-7为多媒体内容描述接口(Multimedia content description interface),是基于内容表示的多媒体内容描述标准。2001年9月成为国际标准ISO/IEC 15938-1。
目的是制定一套描述符标准,用来描述各种类型的多媒体信息及它们之间的关系,以便更快更有效地检索信息。这些媒体材料可包括静态图像、图形、3D模型、声音、话音、电视以及在多媒体演示中它们之间的组合关系。在某些情况下,数据类型还可包括面部特性和个人特性的表达。
MPEG-7致力于视听数据信息编码的表达(表达内容的信息,而不是内容本身)。这一点与目标集中在视频/音频数据的压缩与编码的MPEG-1/2/4不同,MPEG-7所表达的不是内容/信息本身,而是表示信息的信息。
MPEG-7聚焦于多媒体材料的通用接口的标准化,关注数据资源的交互性与全球化、数据管理的灵活性。MPEG-7只关心描述本身,而将描述的生成、特征的提取、索引的处理等都排除在标准之外。
MPEG-7提供了可视内容的标准结构和联接机制、以及对可视内容表述的标准化,为实现基于内容的检索提供了应用框架,并使对多媒体数据的创建、交换、检索和重用更加有效。巨头微软的VC-1(WMV)
■巨头微软力推的VC-1
VC-1是软件巨头微软力推的一种视频编码的格式,但是它的发展并不是很顺利,可以说是历经坎坷。直到2006年初,活动图像和电视工程师协会(SMPTE)才正式颁布了由微软提出并开发的VC-1视频编码标准。
VC-1
微软是在2003年9月递交VC-1编码格式(开发代号Corona)的,目前已经得到了MovieBeam、Modeo等不少公司的采纳,同时也包含在 HDDVD和 蓝光中,包括华纳和环球等影业公司也有采用这种格式的意向。VC-1基于微软Windows Media Video 9(WMV9)格式,而WMV9格式现在已经成为VC-1标准的实际执行部分。WMV(Windows Media Video)是微软公司的视频编解码器家族,包括WMV 7、WMV 8、WMV 9、WPV 10。这一族的编解码器可以应用在从拨号上网的窄带视频到高清晰度电视(HDTV)的宽带视频。使用Windows Media Video用户还可以将视频文件刻录到CD、DVD或者其它一些设备上。它也适用于用作媒体服务器。WMV 可以被看作是MPEG-4的一个增强版本。最新的由SMPTE(电视电影工程师协会)承认的WMV-9,也就是我们说的上面的VC-1。
VC-1是最后被认可的高清编码格式,不过因为有微软的后台,所以这种编码格式不能小窥。相对于MPEG2,VC-1的压缩比更高,但相对于H.264而 言,编码解码的计算则要稍小一些,目前来看,VC-1可能是一个比较好的平衡,辅以微软的支持,应该是一只不可忽视的力量。一般来说,VC-1多为 “.wmv”后缀,但这都不是绝对的,具体的编码格式还是要通过软件来查询。
WMV
总的来说,从压缩比上来看,H.264的压缩比率更高一些,也就是同样的视频,通过H.264编码算法压出来的视频容量要比VC-1的更小,但是VC-1 格式的视频在解码计算方面则更小一些,一般通过高性能的CPU就可以很流畅的观看高清视频。
VC-1的发展有利方面以及发展中的障碍
VC-1具备迅速缩小差距的潜力,因为VC-1是在WM9压缩系统的基础上建立的,与MPEG-4存在众多解释分歧的情况相比,该规范的分歧空间较小。另 一个对VC-1有力的重要因素是许多电信公司(包括SBC)已宣布支持微软的IPTV平台。虽然H.264可以部署在微软的IPTV平台上,但已经采用微 软IPTV的电信公司强烈倾向于实现完全集成的微软方案。保证VC-1互操作性的过程也有可能更加简单,因为不同于由许多供应商给出不同解释的 H.264,微软是该标准的最终裁定者。
不过,VC-1目前的气势依然弱于H.264,也弱于MPEG-4,一方面是VC-1在技术层面上的实际表现与H.264无太大差异,VC-1同样以MPEG-4为基础,但并没有特别的突出点或优越性,运营商从技术角度考虑没有必要非选择VC-1。
另外,从授权角度来看VC-1是否有优势呢?答案是三者中最不利的,碍于Microsoft一贯的推行策略,VC-1的授权来源仅只一家,授权价格与方式调整,以及后续版本的改进方向,都由微软一手掌握,无人能左右,眼前为与MPGE-4、H.264等竞争,VC-1授权自然不敢过高,但运营商依然对未来是否会涨价表示担心。
开源免费的WebM
新势力的WebM
如果说H.264的出现是对于MPEG-4第二部分的视频编码收费过高的宣战,那么google力推的WebM则就是对于收版权费的视频编码的宣战。尽管 在视频的质量上WebM没有多大的优势,但是WebM的标准更倾向于开源,因此也就是对于网络更加的便利化的一个催进剂。WebM所使用的VP8视频格 式,相对于H.264而言并无技术上的优势,但胜在免费;而H.264不仅技术优势明显,并且已经成为一种事实标准,获得了广泛的应用。
WEBM
WebM标准的网络视频更加偏向于开源并且是基于HTML5标准的。最为可怕的是WebM标准受到了包括 Opera,Mozilla,adobe等软件巨头和AMD,ARM,NVIDIA,qualcomm在内硬件巨头的支持,在未来潜力巨大。而且google自己的全球第一大视频网站YouTube目前80%的视频支持全新的WebM标准。
WebM是一个由Google资助的项目,目标是构建一个开放的、免版权使用费的视频文件格式。该视频文件格式应能提供高质量的视频压缩以配合 HTML 5使用。WebM项目是一个使用BSD许可证的开源项目,它采用了On2 Technologies开发的VP8视频编解码器和Xiph.Org基金会开发的Vorbis音频编解码器(一种开源且无专利限制的音频压缩格式),其 使用的封装格式则以Matroska(MKV)开源格式为基础。
这是一个极好的解决方案,因为它在可能是最进步的开源协议之下提供WebM源代码,允许几乎任何背景下的代码重用,而又克服了BSD许可中的一大弱点--专利授权机制的缺乏。”
不幸的是,问题还没有被彻底地划清。仅管许可问题已经被解决,WebM现在下享受着广大技术界的支持,MPEG LA问题依然存在。MPEG LA有一个管理着H.264许可发放(H.264 licensing的组织。这一组织说它在考虑为VP8集成一个专利池(gathering a patent pool for VP8),声明说codec可能被属于与MPEG LA相关的公司的专利覆盖。如果这一组织最终这么做,这将意味着V8将不再免专利税。
写在最后:
目前的视频发展中,可以说老的视频格式并没有死去,而是正当年。而新的视频由于适应了网络时代的发展,前途光明。
目前的MPEG-2的视频在蓝光时代一样是得到了重用,MPEG-2不是MPEG -1的简单升级,MPEG-2在系统和传送方面作了更加详细的规定和进一步的完善。MPEG-2特别适用于广播级的数字电视的编码和传送,被认定为SDTV和HDTV的编码标准。DVD影碟就是采用MPEG-2压缩标准。
而H.264虽然收费问题仍让人不满,但是由于普及的面大,加上其算法上面的领先,在短时间内不会让别人追上。而MPEG-4{2}由于目前网络速度的发展,加上费用的下降甚至于以后的费用可能为零来竞争,也很有发展前途。
而google与微软自己力推的WMV以及WebM都有着巨头强大的实力作为后盾。特别是WMV这几年已经在日常中比较常见了,而WebM由于开源加上免费的优点,再加上其最大的视频网站YOutobe作为后盾,加上许多厂家的力捧,很有希望在以后后来居上。
四、视频文件格式
封装容器
视频流编码格式
音频流编码格式
AVI
Xvid
MP3
Divx
MP3
H264
AAC
MKV
Xvid
MP3
Xvid
AAC
H264
AAC
MP4
Xvid
MP3
H264
AAC
3GP
H.263
AAC
AVI文件格式详细介绍参考https://blog.csdn.net/happydeer/article/details/8775
mp4文件格式解析参考https://www.cnblogs.com/ranson7zop/p/7889272.html
mkv文件格式解析参考https://www.cnblogs.com/ranson7zop/p/7048882.html
五、动态码率、固定码率
动态就是在压制时由压制者设定一个范围,比如500K~1200K之间,这样碰到简单的画面软件就会自动选用较低的码率如600K这样来缩小文件大小,碰到复杂的画面就提高码率比如1100或者1200这样,保证画面的质量。而固定码率的话碰到简单画面就会给文件增加不必要的体积,复杂画面就会因为码率不足而变的粗糙。
动态码率的好处就是在保证画面质量的前提下尽可能的缩小文件体积。
六、H264编码 H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成。 H264编码过程中的三种不同的数据形式:
SODB 数据比特串 ---->最原始的编码数据,即VCL数据;RBSP 原始字节序列载荷 ---->在SODB的后面填加了结尾比特(RBSP trailing bits 一个bit“1”)若干比特“0”,以便字节对齐;EBSP 扩展字节序列载荷 ---- > 在RBSP基础上填加了仿校验字节(0X03)它的原因是: 在NALU加到Annexb上时,需要添加每组NALU之前的开始码StartCodePrefix,如果该NALU对应的slice为一帧的开始则用4位字节表示,ox00000001,否则用3位字节表示ox000001(是一帧的一部分)。另外,为了使NALU主体中不包括与开始码相冲突的,在编码时,每遇到两个字节连续为0,就插入一个字节的0x03。解码时将0x03去掉。也称为脱壳操作。 NAL
NAL全称Network Abstract Layer,即网络抽象层。在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。NAL单元是NAL的基本语法结构,它包含一个字节的头信息和一系列来自VCL的称为原始字节序列载荷(RBSP)的字节流。 帧格式
H264在网络传输的是NALU,NALU的结构是:NAL头+RBSP,实际传输中的数据流如图所示:
264句法元素的分层结构
H264帧由NALU头和NALU主体组成。NALU头由一个字节组成,它的语法如下:
+---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +---------------+
F: 1个比特. forbidden_zero_bit. 在 H.264 规范中规定了这一位必须为 0.
NRI: 2个比特. nal_ref_idc. 取00~11,似乎指示这个NALU的重要性,如00的NALU解码器可以丢弃它而不影响图像的回放,0~3,取值越大,表示当前NAL越重要,需要优先受到保护。如果当前NAL是属于参考帧的片,或是序列参数集,或是图像参数集这些重要的单位时,本句法元素必需大于0。
Type: 5个比特.
标识NAL单元中的RBSP数据类型,其中,nal_unit_type为1, 2, 3, 4, 5的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL单元。
nal_unit_type. 这个NALU单元的类型,1~12由H.264使用,24~31由H.264以外的应用使用,简述如下:
0 没有定义 1-23 NAL单元 单个 NAL 单元包 1 不分区,非IDR图像的片 2 片分区A 3 片分区B 4 片分区C 5 IDR图像中的片 6 补充增强信息单元(SEI) 7 SPS 8 PPS 9 序列结束 10 序列结束 11 码流借宿 12 填充 13-23 保留
24 STAP-A 单一时间的组合包 25 STAP-B 单一时间的组合包 26 MTAP16 多个时间的组合包 27 MTAP24 多个时间的组合包 28 FU-A 分片的单元 29 FU-B 分片的单元 30-31 没有定义
由于NAL的语法中没有给出长度信息,实际的传输、存储系统需要增加额外的头实现各个NAL单元的定界。
其中,AVI文件和MPEG TS广播流采取的是字节流的语法格式,即在NAL单元之前增加0x00000001的同步码,则从AVI文件或MPEG TS PES包中读出的一个H.264视频帧以下面的形式存在:
00 00 00 01 06 ... 00 00 00 01 67 ... 00 00 00 01 68 ... 00 00 00 01 65 ... SEI信息 SPS PPS IDR Slice
而对于MP4文件,NAL单元之前没有同步码,却有若干字节的长度码,来表示NAL单元的长度,这个长度码所占用的字节数由MP4文件头给出;此外,从MP4读出来的视频帧不包含PPS和SPS,这些信息位于MP4的文件头中,解析器必须在打开文件的时候就获取它们。从MP4文件读出的一个H.264帧往往是下面的形式(假设长度码为2字节):
00 19 06 [... 25 字节...] 24 aa 65 [... 9386 字节...] SEI信息 IDR Slice
分包
H264 over RTP基本上分三种类型:
(1)Single NAL unit packet 也就是实际的NAL类型,可以理解为一个包就是一帧H264数据,这个在实际中是比较多的。
(2)Aggregation packet 一包数据中含有多个H264帧。
STAP-A 包内的帧含有相同的NALU-Time,没有DON
STAP-B 包内的帧含有相同的NALU-Time,有DON
MTAP16 包内的帧含有不同的NALU-Time,timestamp offset = 16
MTAP24 包内的帧含有不同的NALU-Time,timestamp offset = 24
封装在Aggregation packet中的 NAL单元大小为65535字节
(3) Fragmentation unit 一帧数据被分为多个RTP包,这也是很常见的,特别是对于关键帧。现存两个版本FU-A,FU-B。
h264包在传输的时候,如果包太大,会被分成多个片。NALU头会被如下的2个自己代替。
The FU indicator octet has the following format:
+---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +---------------+
别被名字吓到这个格式就是上面提到的RTP h264负载类型,Type为FU-A
The FU header has the following format:
+---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |S|E|R| Type | +---------------+
S bit为1表示分片的NAL开始,当它为1时,E不能为1 E bit为1表示结束,当它为1,S不能为1
R bit保留位 Type就是NALU头中的Type,取1-23的那个值
AUD
一般文档没有对AUD进行描叙,其实这是一个帧开始的标志,字节顺序为:00 00 00 01 09 f0 从结构上看,有start code, 所以确实是一个NALU,类型09在H264定义里就是AUD(分割器)。大部分播放器可以在没有AUD的情况下正常播放。 紧随AUD,一般是SPS/PPS/SEI/IDR的组合或者简单就是一个SLICE,也就是一个帧的开始。像Flash这样的播放器,每次需要一个完整的帧数据,那么把2个AUD之间的数据按照格式打包给播放器就可以了。
H.264编码时,在每个NAL前添加起始码 0x000001,解码器在码流中检测到起始码,当前NAL结束。为了防止NAL内部出现0x000001的数据,h.264又提出'防止竞争 emulation prevention"机制,在编码完一个NAL时,如果检测出有连续两个0x00字节,就在后面插入一个0x03。当解码器在NAL内部检测到0x000003的数据,就把0x03抛弃,恢复原始数据。 0x000000 >>>>>> 0x00000300 0x000001 >>>>>> 0x00000301 0x000002 >>>>>> 0x00000302 0x000003 >>>>>> 0x00000303
总的来说H264的码流的打包方式有两种,一种为annex-b byte stream format 的格式,这个是绝大部分编码器的默认输出格式,就是每个帧的开头的3~4个字节是H264的start_code,0x00000001或者0x000001。 另一种是原始的NAL打包格式,就是开始的若干字节(1,2,4字节)是NAL的长度,而不是start_code,此时必须借助某个全局的数据来获得编 码器的profile,level,PPS,SPS等信息才可以解码。 SPS,PPS的解析
SPS profile_idc和level_idc是指比特流所遵守的配置和级别。
constraint_set0_flag 等于1是指比特流遵从某节中的所有规定。constraint_set0_flag 等于0是指该比特流可以遵从也可以不遵从某节中的所有规定。当profile_idc等于100、110、122或144时,constraint_set0_flag、constraint_set1_flag和constraint_set2_flag都应等于0。
log2_max_frame_num_minus4的值应在0-12范围内(包括0和12),这个句法元素主要是为读取另一个句法元素 frame_num 服务的,frame_num 是最重要的句法元素之一,它标识所属图像的解码顺序 。这个句法元素同时也指明了 frame_num 的所能达到的最大值: MaxFrameNum = 2*exp( log2_max_frame_num_minus4 + 4 ) 。
pic_order_cnt_type 是指解码图像顺序的计数方法。pic_order_cnt_type 的取值范围是0到2(包括0和2)。
log2_max_pic_order_cnt_lsb_minus4表示用于某节规定的图像顺序数解码过程中的变量MaxPicOrderCntLsb的值,
num_ref_frames规定了可能在视频序列中任何图像帧间预测的解码过程中用到的短期参考帧和长期参考帧、互补参考场对以及不成对的参考场的最大数量。num_ref_frames 的取值范围应该在0到MaxDpbSize。
gaps_in_frame_num_value_allowed_flag 表示某节给出的frame_num 的允许值以及在某节给出的frame_num 值之间存在推测的差异的情况下进行的解码过程。
pic_width_in_mbs_minus1加1是指以宏块为单元的每个解码图像的宽度。 pic_height_in_map_units_minus1 的语义依赖于变量frame_mbs_only_flag,规定如下:-— 如果 frame_mbs_only_flag 等于0,
pic_height_in_map_units_minus1加1就表示以宏块为单位的一场的高度。-— 否则(frame_mbs_only_flag等于1),pic_height_in_map_units_minus1加1就表示
以宏块为单位的一帧的高度。变量 FrameHeightInMbs 由下列公式得出:FrameHeightInMbs = ( 2 – frame_mbs_only_flag ) * PicHeightInMapUnits。
mb_adaptive_frame_field_flag 等于0表示在一个图像的帧和场宏块之间没有交换。mb_adaptive_frame_field_flag 等于1表示在帧和帧内的场宏块之间可能会有交换。当mb_adaptive_frame_field_flag没有特别规定时,默认其值为0。
direct_8x8_inference_flag 表示在某节中规定的B_Skip、B_Direct_16x16和B_Direct_8x8亮度运动矢量的计算过程使用的方法。当frame_mbs_only_flag 等于0时
direct_8x8_inference_flag 应等于1。
frame_cropping_flag 等于1表示帧剪切偏移参数遵从视频序列参数集中的下一个值。frame_cropping_flag 等于0表示不存在帧剪切偏移参数。
vui_parameters_present_flag 等于1 表示存在如附录E 提到的vui_parameters( ) 语法结构。vui_parameters_present_flag 等于0表示不存在如附录E提到的vui_parameters( ) 语法结构。
PPS seq_parameter_set_id是指活动的序列参数集。变量seq_parameter_set_id的值应该在0到31的范围内(包括0和31)。
entropy_coding_mode_flag 用于选取语法元素的熵编码方式,在语法表中由两个标识符代表,具体如下:如果entropy_coding_mode_flag 等于0,那么采用语法表中左边的描述符所指定的方法。 pic_order_present_flag等于1 表示与图像顺序数有关的语法元素将出现于条带头中,pic_order_present_flag 等于0表示条带头中不会出现与图像顺序数有关的语法元素。
num_slice_groups_minus1加1表示一个图像中的条带组数。当num_slice_groups_minus1 等于0时,图像中所有的条带属于同一个条带组。
num_ref_idx_l0_active_minus1表示参考图像列表0 的最大参考索引号,该索引号将用来在一幅图像中num_ref_idx_active_override_flag 等于0 的条带使用列表0 预测时,解码该图像的这些条带。当MbaffFrameFlag等于1时,num_ref_idx_l0_active_minus1 是帧宏块解码的最大索引号值,而2 *num_ref_idx_l0_active_minus1 + 1是场宏块解码的最大索引号值。num_ref_idx_l0_active_minus1 的值应该在0到31的范围内(包括0和31)。
weighted_pred_flag等于0表示加权的预测不应用于P和SP条带。weighted_pred_flag等于1表示在P和SP条带中应使用加权的预测。
weighted_bipred_idc等于0表示B条带应该采用默认的加权预测。weighted_bipred_idc等于1表示B条带应该采用具体指明的加权预测。weighted_bipred_idc 等于2表示B 条带应该采用隐含的加权预测。 weighted_bipred_idc 的值应该在0到2之间(包括0和2)。
pic_init_qp_minus26表示每个条带的SliceQPY 初始值减26。当解码非0值的slice_qp_delta 时,该初始值在条带层被修正,并且在宏块层解码非0 值的mb_qp_delta 时进一步被修正。pic_init_qp_minus26 的值应该在-(26 + QpBdOffsetY ) 到 +25之间(包括边界值)。
pic_init_qs_minus26表示在SP 或SI 条带中的所有宏块的SliceQSY 初始值减26。当解码非0 值的slice_qs_delta 时,该初始值在条带层被修正。pic_init_qs_minus26 的值应该在-26 到 +25之间(包括边界值)。
chroma_qp_index_offset表示为在QPC 值的表格中寻找Cb色度分量而应加到参数QPY 和 QSY 上的偏移。chroma_qp_index_offset的值应在-12 到 +12范围内(包括边界值)。
deblocking_filter_control_present_flag等于1 表示控制去块效应滤波器的特征的一组语法元素将出现在条带头中。deblocking_filter_control_present_flag 等于0 表示控制去块效应滤波器的特征的一组语法元素不会出现在条带头中,并且它们的推定值将会生效。
constrained_intra_pred_flag等于0 表示帧内预测允许使用残余数据,且使用帧内宏块预测模式编码的宏块的预测可以使用帧间宏块预测模式编码的相邻宏块的解码样值。constrained_intra_pred_flag 等于1 表示受限制的帧内预测,在这种情况下,使用帧内宏块预测模式编码的宏块的预测仅使用残余数据和来自I或SI宏块类型的解码样值。
redundant_pic_cnt_present_flag等于0 表示redundant_pic_cnt 语法元素不会在条带头、图像参数集中指明(直接或与相应的数据分割块A关联)的数据分割块B和数据分割块C中出现。redundant_pic_cnt_present_flag等于1表示redundant_pic_cnt 语法元素将出现在条带头、图像参数集中指明(直接或与相应的数据分割块A关联)的数据分割块B和数据分割块C中。
SPS解析宽高
UINT Ue(BYTE *pBuff, UINT nLen, UINT &nStartBit) { //计算0bit的个数 UINT nZeroNum = 0; while (nStartBit < nLen * 8) { if (pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8))) //&:按位与,%取余 { break; } nZeroNum++; nStartBit++; } nStartBit++;
//计算结果 DWORD dwRet = 0; for (UINT i=0; i<nZeroNum; i++) { dwRet <<= 1; if (pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8))) { dwRet += 1; } nStartBit++; } return (1 << nZeroNum) - 1 + dwRet; }
int Se(BYTE *pBuff, UINT nLen, UINT &nStartBit) { int UeVal=Ue(pBuff,nLen,nStartBit); double k=UeVal; int nValue=ceil(k/2);//ceil函数:ceil函数的作用是求不小于给定实数的最小整数。ceil(2)=ceil(1.2)=cei(1.5)=2.00 if (UeVal % 2==0) nValue=-nValue; return nValue; }
DWORD u(UINT BitCount,BYTE * buf,UINT &nStartBit) { DWORD dwRet = 0; for (UINT i=0; i<BitCount; i++) { dwRet <<= 1; if (buf[nStartBit / 8] & (0x80 >> (nStartBit % 8))) { dwRet += 1; } nStartBit++; } return dwRet; }
bool h264_decode_seq_parameter_set(BYTE * buf,UINT nLen,int &Width,int &Height) { UINT StartBit=0; int forbidden_zero_bit=u(1,buf,StartBit); int nal_ref_idc=u(2,buf,StartBit); int nal_unit_type=u(5,buf,StartBit); if(nal_unit_type == 7) { int profile_idc=u(8,buf,StartBit); int constraint_set0_flag=u(1,buf,StartBit);//(buf[1] & 0x80)>>7; int constraint_set1_flag=u(1,buf,StartBit);//(buf[1] & 0x40)>>6; int constraint_set2_flag