H.264 NAL层解析(0x00000001,编码,打包,NALU)

合集下载

RTP协议全解(H264码流和PS流)-2015-4-22

RTP协议全解(H264码流和PS流)-2015-4-22

RTP协议全解(H264码流和PS流)写在前面:RTP的解析,网上找了很多资料,但是都不全,所以我力图整理出一个比较全面的解析,其中借鉴了很多文章,我都列在了文章最后,在此表示感谢。

互联网的发展离不开大家的无私奉献,我决定从我做起,希望大家支持。

原创不易,转载请附上链接,谢谢/chen495810242/article/details/392073051、RTP Header解析图11) V:RTP协议的版本号,占2位,当前协议版本号为22) P:填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。

3) X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头4) CC:CSRC计数器,占4位,指示CSRC 标识符的个数5) M: 标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。

6) PT: 有效荷载类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等,在流媒体中大部分是用来区分音频流和视频流的,这样便于客户端进行解析。

7) 序列号:占16位,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。

这个字段当下层的承载协议用UDP的时候,网络状况不好的时候可以用来检查丢包。

同时出现网络抖动的情况可以用来对数据进行重新排序,序列号的初始值是随机的,同时音频包和视频包的sequence是分别记数的。

8) 时戳(Timestamp):占32位,必须使用90 kHz 时钟频率。

时戳反映了该RTP报文的第一个八位组的采样时刻。

接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。

9) 同步信源(SSRC)标识符:占32位,用于标识同步信源。

该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。

10) 特约信源(CSRC)标识符:每个CSRC标识符占32位,可以有0~15个。

H264编解码协议详解

H264编解码协议详解

H264编解码协议详解H.264编解码协议,也被称为AVC(Advanced Video Coding),是一种广泛应用于视频压缩的标准。

它是一种基于帧的压缩算法,可以将高质量的视频数据以较低的比特率传输和存储。

以下是H.264编解码协议的详细解释:1.压缩结构H.264使用了多种技术来实现高效率的视频压缩。

它使用了预测编码、变换编码和熵编码等多种技术。

预测编码通过利用帧间和帧内的冗余性,对视频进行空间和时间上的预测。

变换编码则通过对预测误差进行离散余弦变换(DCT),在频域上进行编码。

最后,熵编码使用了熵编码表将变换后的数据进行进一步的压缩。

2.帧结构H264将视频数据划分为一系列的帧,每个帧包含了许多宏块(macroblock)。

其中,关键帧(I帧)是完全独立的帧,它包含了视频的全局信息。

预测帧(P帧)和双向预测帧(B帧)则通过对前一帧和前后一帧进行预测来进行编码。

P帧只依赖前一帧,而B帧则依赖前后两帧。

这种结构可以进一步提高视频压缩的效率。

3.量化参数H.264使用量化参数对预测误差进行编码。

量化参数决定了每个预测误差值的精度,较大的量化参数会导致更高的压缩率,但也会导致较大的失真。

编码器和解码器可以通过动态调整量化参数来平衡压缩率和失真。

4.帧间预测帧间预测是H.264压缩的核心技术之一、它通过对前后帧的像素进行比较,预测当前帧的像素值。

如果在帧间没有大的运动,那么预测误差就会较小,从而达到更好的压缩效果。

帧间预测有多种模式,包括帧间直接模式(inter-direct mode)、帧间双向模式(inter-bidirect mode)和帧间skip模式(inter-skip mode)等。

5.熵编码H.264使用了基于上下文的自适应变长编码(CAVLC)和基于上下文的自适应二进制算术编码(CABAC)两种熵编码技术。

CAVLC主要用于编码量化系数和运动矢量等数据,而CABAC主要用于编码预测模式和其他语法元素。

H264编码原理详解

H264编码原理详解

H264编码原理详解前言•在日常生活中我们知道,电脑中的视频文件先要通过视频采集设备对物体进行采集,然后通过编码核心部件得到mp4,rmvb等格式进行保存。

有没有可能不经过上述核心编码部件采集之后直接进行显示呢?答案是可以的。

那为什么还要进行编码呢?答案是原始采集到的视频数据为YUV格式,这种格式不经过处理的话特别大,对于网络传输和永久保存非常不利,为了解决这个问题,就需要对原原始的视频数据进行压缩处理。

而H264则是目前一种流传广泛,成熟的视频压缩算法。

•先来看一个例子在学习H.264编码之前,我们先了解一下在手机相机拍摄视频的过程,如果Camera采集的YUV图像不做任何处理进行传输,那么每秒钟需要传输的数据量是多少?Camera采集的YUV图像通常为YUV420,根据YUV420的采样结构,YUV图像中的一个像素中Y、U、V分量所占比例为1:1/4:1/4,而一个Y分量占1个字节,也就是说对于YUV图像,它的一个像素的大小为(1+1/4+1/4)Y=3/2个字节。

如果直播时的帧率设置为30fps,当分辨率为1280x720,那么每秒需要传输的数据量为1280720(像素)30(帧)3/2(字节)=39.5MB;当分辨率为1920x720,那么每秒需要传输的数据量接近60MB,这对于手机的存储空间有很大考验,因此,我们就必须在拍摄形成视频文件保存在本地之前对采集的视频数据进行压缩编码。

H26X简介H261•目前国际上制定视频编解码技术的组织有两个,一个是“国际电联(ITU-T)”,它制定的标准有H.261、H.263、H.263+等,另一个是“国际标准化组织(ISO)”它制定的标准有MPEG-1、MPEG-2、MPEG-4等。

•H.261是1990年ITU-T制定的一个视频编码标准,属于视频编解码器。

设计的目的是能够在带宽为64kbps的倍数的综合业务数字网(ISDN forIntegrated Services Digital Network)上质量可接受的视频信号。

数字视频压缩技术H264详解

数字视频压缩技术H264详解

数字视频压缩技术H264详解一个基于分组方式的接口,打包和相应的信令属于NAL的一部分。

这样,高编码效率和网络友好性的任务分别由VCL和NAL来完成。

VCL层包括基于块的运动补偿混合编码和一些新特性。

与前面的视频编码标准一样,H.264没有把前处理和后处理等功能包括在草案中,这样可以增加标准的灵活性。

NAL负责使用下层网络的分段格式来封装数据,包括组帧、逻辑信道的信令、定时信息的利用或序列结束信号等。

例如,NAL支持视频在电路交换信道上的传输格式,支持视频在Internet上利用RTP/UDP/IP传输的格式。

NAL包括自己的头部信息、段结构信息和实际载荷信息,即上层的VCL数据。

(如果采用数据分割技术,数据可能由几个部分组成)。

(2)高精度、多模式运动估计H.264支持1/4或1/8像素精度的运动矢量。

在1/4像素精度时可使用6抽头滤波器来减少高频噪声,对于1/8像素精度的运动矢量,可使用更为复杂的8抽头的滤波器。

在进行运动估计时,编码器还可选择“增强”内插滤波器来提高预测的效果。

在H.264的运动预测中,一个宏块(MB)可以按图2被分为不同的子块,形成7种不同模式的块尺寸。

这种多模式的灵活和细致的划分,更切合图像中实际运动物体的形状,大大提高了运动估计的精确程度。

在这种方式下,在每个宏块中可以包含有1、2、4、8或16个运动矢量。

在H.264中,允许编码器使用多于一帧的先前帧用于运动估计,这就是所谓的多帧参考技术。

例如2帧或3帧刚刚编码好的参考帧,编码器将选择对每个目标宏块能给出更好的预测帧,并为每一宏块指示是哪一帧被用于预测。

(3)4某4块的整数变换H.264与先前的标准相似,对残差采用基于块的变换编码,但变换是整数操作而不是实数运算,其过程和DCT基本相似。

这种方法的优点在于:在编码器中和解码器中允许精度相同的变换和反变换,便于使用简单的定点运算方式。

也就是说,这里没有“反变换误差”。

变换的单位是4某4块,而不是以往常用的8某8块。

【知识点】H264,H265硬件编解码基础及码流分析

【知识点】H264,H265硬件编解码基础及码流分析

【知识点】H264,H265硬件编解码基础及码流分析前⾔⾳视频开发需要你懂得⾳视频中⼀些基本概念,针对编解码⽽⾔,我们必须提前懂得编解码器的⼀些特性,码流的结构,码流中⼀些重要信息如sps,pps,vps,start code以及基本的⼯作原理,⽽⼤多同学都只是⼀知半解,所以导致代码中的部分内容虽可以简单理解却不知其意,所以,在这⾥总结出了当前主流的H.264,H.265编码相关的原理,以供学习.1. 概览1.1. 为什么要编码众所周知,视频数据原始体积是巨⼤的,以720P 30fps的视频为例,⼀个像素⼤约3个字节,如下所得,每秒钟产⽣87MB,这样计算可得⼀分钟就将产⽣5.22GB。

数据量/每秒=1280*720*33*3/1024/1024=87MB因此,像这样体积重⼤的视频是⽆法在⽹络中直接传输的.⽽视频编码技术也就因运⽽⽣.关于视频编码原理的技术可以参考本⼈其他⽂章,这⾥不做过多描述.1.2. 编码技术经过很多年的开发迭代,已经有很多⼤⽜实现了视频编码技术,其中最主流的有H.264编码,以及新⼀代的H.265编码,⾕歌也开发了VP8,VP9编码技术.对移动端⽽⾔,苹果内部已经实现了如H.264,H.265编码,我们需要使⽤苹果提供的VideoToolbox框架来实现它.1.3. 编码分类软件编码(简称软编):使⽤CPU进⾏编码。

硬件编码(简称硬编):不使⽤CPU进⾏编码,使⽤显卡GPU,专⽤的DSP、FPGA、ASIC芯⽚等硬件进⾏编码。

优缺点软编:实现直接、简单,参数调整⽅便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常⽐硬编码要好⼀点。

硬编:性能⾼,低码率下通常质量低于硬编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。

iOS系统中的硬编码苹果在iOS 8.0系统之前,没有开放系统的硬件编码解码功能,不过Mac OS系统⼀直有,被称为Video ToolBox的框架来处理硬件的编码和解码,终于在iOS 8.0后,苹果将该框架引⼊iOS系统。

H264编码原理以及I帧、B和P帧详解,H264码流结构分析

H264编码原理以及I帧、B和P帧详解,H264码流结构分析

H264编码原理以及I帧、B和P帧详解,H264码流结构分析H264码流结构分析/chenchong_219/article/details/379905411、码流总体结构:h264的功能分为两层,视频编码层(VCL)和⽹络提取层(NAL)。

H.264 的编码视频序列包括⼀系列的NAL 单元,每个NAL 单元包含⼀个RBSP。

⼀个原始的H.264 NALU 单元常由 [StartCode] [NALU Header] [NALU Payload] 三部分组成,其中 Start Code ⽤于标⽰这是⼀个NALU 单元的开始,必须是"00 00 00 01" 或"0000 01"。

其中RBPS有分为⼏种类型:NAL的解码单元的流程如下:2、 NAL Header:占⼀个字节,由三部分组成forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)。

forbidden_bit:禁⽌位。

nal_reference_bit:当前NAL的优先级,值越⼤,该NAL越重要。

nal_unit_type :NAL类型。

参见下表⼏个例⼦:3、 ffmpeg解析H264流程分析这是⼀段实际的码流在上⾯的图⽚中,共有三个起始码:0x00 0000 01const uint8_t*ff_h264_decode_nal(H264Context*h, const uint8_t *src,int *dst_length, int*consumed, int length)中分析过程为:h->nal_ref_idc= src[0] >> 5;h->nal_unit_type= src[0] & 0x1F;此处src[0]即为06,写成⼆进制位0000 0110,则h->nal_ref_idc = 0,h->nal_unit_type = 6可以判断这个NALU类型为SEI,重要性优先级为0。

【IT专家】我如何解析H264文件和帧

【IT专家】我如何解析H264文件和帧

本文由我司收集整编,推荐下载,如有疑问,请与我司联系我如何解析H264 文件和帧2012/04/12 9373 An H264 file is a stream of NAL (Network Abstraction Layer) units, each encoding a frame (I, B, or P). What is the best way to parse this file and toextract sizes and detect ends of each NAL unit in the file, as well as detect the type offrame the NAL unit contains?H264 文件是NAL(网络抽象层)单元的流,每个单元编码帧(I,B 或P)。

解析此文件以及提取文件中每个NAL 单元的大小和检测结束的最佳方法是什么,以及检测NAL 单元包含的帧类型?20If you’re not actually trying to decode the frames, you can write a simple ‘parser’ by reading the h.264 byte stream and looking for NAL unit signature.如果您实际上没有尝试解码帧,可以通过读取h.264 字节流并查找NAL 单元签名来编写一个简单的“解析器”。

Here’s what you need to know:这是你需要知道的:NAL Units start code: 00 00 01 X Y NAL 单位起始码:00 00 01 X Y. X = IDR Picture NAL Units (e.g 25, 45, 65) X = IDR 图片NAL 单位(例如25,45,65)Y = Non IDR Picture NAL Units (e.g. 01, 21, 41, 61) Y =非IDR 图片NAL 单位(例如01,21,41,61)So, if you find 3 bytes [00 00 01] in sequence, very likely it’s the beginning of the NAL unit. Then you will need to parse the the next two bytes [X Y] to find out the type of frame. Please refer to the spec for more details.因此,如果您按顺序找到3 个字节[00 00 01],很可能它是NAL 单元的开头。

H264编码+打包+解码相关知识

H264编码+打包+解码相关知识

H264编码+打包+解码相关知识1)ES流(Elementary Stream): 也叫基本码流,包含视频、音频或数据的连续码流.2)PES流(Packet Elementary Stream): 也叫打包的基本码流, 是将基本的码流ES流根据需要分成长度不等的数据包, 并加上包头就形成了打包的基本码流PES流.3)TS流(Transport Stream): 也叫传输流, 是由固定长度为188字节的包组成, 含有独立时基的一个或多个program, 一个program又可以包含多个视频、音频、和文字信息的ES流; 每个ES流会有不同的PID标示. 而又为了可以分析这些ES流, TS有一些固定的PID用来间隔发送program和ES流信息的表格: PAT和PMT表,(在MPEG-2系统中,由视频, 音频的ES流和辅助数据复接生成的用于实际传输的标准信息流称为MPEG-2传送流)封装 : 就是捆绑打包, 将画面视频文件和音轨文件打包在一起, 并按照一定规则建立排序和索引, 便于播放器或播放软件来索引播放. 包括AVI / PS(Program Stream)/ TS(Transport Stream)/ MKV (Matroska)等。

4)I frame :帧内编码帧又称intra picture,I帧通常是每个GOP(MPEG所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。

I帧可以看成是一个图像经过压缩后的产物。

5)P frame:前向预测编码帧又称predictive-frame,通过充分将低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧;6)B frame:双向预测内插编码帧又称bi-directional interpolated predictionframe,既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧;7)PTS:PresentationTime Stamp。

H.264基础及RTP封包详解

H.264基础及RTP封包详解

H.264基础及RTP封包详解一. h264基础概念1、NAL、Slice与frame意思及相互关系1 frame的数据可以分为多个slice.每个slice中的数据,在帧内预测只用到自己slice的数据,与其他slice 数据没有依赖关系。

NAL 是用来将编码的数据进行大包的。

比如,每一个slice 数据可以放在NAL 包中。

I frame 是自己独立编码,不依赖于其他frame 数据。

P frame 依赖 I frame 数据。

B frame 依赖 I frame, P frame 或其他 B frame 数据。

一个frame是可以分割成多个Slice来编码的,而一个Slice编码之后被打包进一个NAL单元,不过NAL单元除了容纳Slice编码的码流外,还可以容纳其他数据,比如序列参数集SPS。

NAL指网络提取层,里面放一些与网络相关的信息Slice是片的意思,264中把图像分成一帧(frame)或两场(field),而帧又可以分成一个或几个片(Slilce);片由宏块(MB)组成。

宏块是编码处理的基本单元。

2、NAL nal_unit_type中的1(非IDR图像的编码条带)、2(编码条带数据分割块A)、3(编码条带数据分割块B)、4(编码条带数据分割块C)、5(IDR图像的编码条带)种类型与 Slice种的三种编码模式:I_slice、P_slice、B_sliceNAL nal_unit_type 里的五种类型,代表接下来数据是表示啥信息的和具体如何分块。

I_slice、P_slice、B_slice 表示I类型的片、P类型的片,B类型的片.其中I_slice为帧内预测模式编码;P_slice为单向预测编码或帧内模式;B_slice 中为双向预测或帧内模式。

3、还有frame的3种类型:I frame、P frame、 B frame之间有什么映射关系么?I frame、P frame、 B frame关系同 I_slice、P_slice、B_slice,slice和frame区别在问题1中已经讲明白。

H264 NAL层解析

H264 NAL层解析
编码视频序列
一个编码视频序列由一串连续的存储单元组成,使用同一序列参数集。每个视频序列可独立解码。编码序列的开始是即时刷新存储单元(ID R)。IDR是一个I帧图像,表示后面的图像不用参考以前的图像。一个NAL单元流可包含一个或更多的编码视频序列。
RTP协议:
实时传输协议(Real-time Transport Protocol,RTP)是在Internet上处理多媒体数据流的一种网络协议,利用它能够在一对一(单播)或者 一对多(multicast,多播)的网络环境中实现传流媒体数据的实时传输。RTP通常使用UDP来进行多媒体数据的传输,但如果需要的话可以使用 TCP或者ATM等其它协议,整个RTP协议由两个密切相关的部分组成:RTP数据协议和RTP控制协议。实时流协议(Real Time Streaming Protoco l, RTSP)最早由Real Networks和Netscape公司共同提出,它位于RTP和RTCP之上,其目的是希望通过IP网络有效地传输多媒体数据。
存储单元:
一组指定格式的NAL单元称为存储单元,每个存储单元对应一个图像。每个存储单元包含一组VCL NAL单元,组成一个主编码图像,VCL NAL单元 由表示视频图像采样的像条所组成。存储单元前面可以加一个前缀,分界存储单元,附加增强信息(SEI)(如图像定时信息)也可以放在主编 码图像的前面。主编码图像后附加的VCL NAL单元,包含同一图像的冗余表示,称为冗余编码图像,当主编码图像数据丢失或损坏时,可用冗余 编码图像解码。
边界定位。还有一种可选特性,在字节流中增加附加数据,用做扩充发送数据量,能实现快速边界定位,恢复同步 Case2:IP网络的RTP打包封装 分组打包的规则
(1)额外开销要少,使MTU尺寸在100~64k字节范围都可以; (2)不用对分组内的数据解码就可以判别该分组的重要性; (3)载荷规范应当保证不用解码就可识别由于其他的比特丢失而造成的分组不可解码; (4)支持将NALU分割成多个RTP分组; (5)支持将多个NALU汇集在一个RTP分组中。 RTP的头标可以是NALU的头标,并可以实现以上的打包规则。 一个RTP分组里放入一个NALU,将NALU(包括同时作为载荷头标的NALU头)放入RTP的载荷中,设置RTP头标值。为了避免IP层对大分组的再一 次分割,片分组的大小一般都要小于MTU尺寸。由于包传送的路径不同,解码端要重新对片分组排序,RTP包含的次序信息可以用来解决这一问 题。 NALU分割 对于预先已经编码的内容,NALU可能大于MTU尺寸的限制。虽然IP层的分割可以使数据块小于64千字节,但无法在应用层实现保护,从而降 低了非等重保护方案的效果。由于UDP数据包小于64千字节,而且一个片的长度对某些应用场合来说太小,所以应用层打包是RTP打包方案的一 部分。 新的讨论方案(IETF)应当符合以下特征: (1)NALU的分块以按RTP次序号升序传输; (2)能够标记第一个和最后一个NALU分块; (3)可以检测丢失的分块。 NALU合并 一些NALU如SEI、参数集等非常小,将它们合并在一起有利于减少头标开销。已有两种集合分组: (1)单一时间集合分组(STAP),按时间戳进行组合; (2)多时间集合分组(MTAP),不同时间戳也可以组合。 NAL规范视频数据的格式,主要是提供头部信息,以适合各种媒体的传输和存储。NAL支持各种网络,包括: 1.任何使用RTP/IP协议的实时有线和无线Internet 服务 2.作为MP4文件存储和多媒体信息文件服务 3.MPEG-2系统 4.其它网 NAL规定一种通用的格式,既适合面向包传输,也适合流传送。实际上,包传输和流传输的方式是相同的,不同之处是传输前面增加了一个起始 码前缀 在类似Internet/RTP面向包传送协议系统中,包结构中包含包边界识别字节,在这种情况下,不需要同步字节。 NAL单元分为VCL和非VCL两种 VCL NAL单元包含视频图像采样信息, 非VCL包含各种有关的附加信息,例如参数集(头部信息,应用到大量的VCL NAL单元)、提高性能的附加信息、定时信息等 参数集:

ts流解析规则专业资料

ts流解析规则专业资料

HLS, Http Live Streaming 是由Apple公司定义的用于实时流传输的协议, HLS基于HTTP协议实现, 传输内容涉及两部分, 一是M3U8描述文献, 二是TS媒体文献。

1.M3U8文献用文本方式对媒体文献进行描述, 由一系列标签组成。

#EXTM3U#EXT-X-TARGETDURATION:5#EXTINF:5,./0.ts#EXTINF:5,./1.ts#EXTM3U: 每个M3U8文献第一行必须是这个tag。

#EXT-X-TARGETDURATION: 指定最大的媒体段时间长度(秒), #EXTINF中指定的时间长度必须小于或等于这个最大值。

该值只能出现一次。

#EXTINF:描述单个媒体文献的长度。

后面为媒体文献, 如./0.ts2.ts文献ts文献为传输流文献, 视频编码重要格式h264/mpeg4, 音频为acc/MP3。

ts文献分为三层:ts层Transport Stream、pes层 Packet Elemental Stream、es层 Elementary Stream.es层就是音视频数据,pes层是在音视频数据上加了时间戳等对数据帧的说明信息,ts层就是在pes层加入数据流的辨认和传输必须的信息注: 详解如下(1)ts层 ts包大小固定为188字节, ts层分为三个部分:ts header、adaptation field、payload。

ts header固定4个字节;adaptation field也许存在也也许不存在, 重要作用是给局限性188字节的数据做填充;payload是pes数据。

ts headersync_byte 8b同步字节, 固定为0x47transport_error_indicator 1b 传输错误指示符, 表白在ts头的adapt域后由一个无用字节, 通常都为0, 这个字节算在adapt域长度内payload_unit_start_indicator 1b 负载单元起始标示符, 一个完整的数据包开始时标记为1• ts层的内容是通过PID值来标记的, 重要内容涉及: PAT表、PMT表、音频流、视频流。

H.264详解

H.264详解

H.264详解为什么叫H.264H.264是一种视频高压缩技术,全称是MPEG-4 A VC,用中文说是“活动图像专家组-4的高等视频编码”,或称为MPEG-4 Part10。

它是由国际电信标准化部门ITU-T和规定MPEG的国际标准化组织ISO/国际电工协会IEC共同制订的一种活动图像编码方式的国际标准格式,这是我们叫惯了的MPEG中的一种,那为什么叫H.264呢?原来国际电信标准化部门从1998年就H.26L的H.26S两个分组,前者研制节目时间较长的高压缩编码技术,后者则指短节目标准制订部门。

H.26S 的标准化技术的名称为H.263,听起来很耳生,但实质上却早在用了,还被骂得很激烈。

因为,H.263先入为大,一直以MPEG-4大内涵的名字在用。

H.263的全称为MPEG-4 Visual或MPEG-4 Pall Ⅱ,即MPEG-4视频简单层面的基础编码方式。

2001年后,国际电信标准化部门ITU-T和MPEG的上级组织国际标准化组织ISO/国际电气标准会议IEC成立了联合视频组JVT,在H.26L基础进行H.264的标准化。

2002年12月9日~13日,在日本香川县淡路岛举行的MPEG聚会上确定了相关技术的规格。

规格书定稿后,2003年3月17日,H.364的技术格式最终稿国际标准规格(FDIS)被确立。

目前软件和LSI芯片,服务及设备也都进入了使用阶段。

格式书中,列出了比特流规定,解码必要格式,和可供参考的编码记载。

为了不引起误解,ITU-T推荐使用H.264作为这一标准的正式名称。

实际上,MPEG-4里还有MPEG-4 Audio和MPEG-4 System的不同规格。

MPEG-4挨骂是因为MPEG-4 Visual许可收费离谱引起的。

别以为有了专利就可以随意向人要钱了,专利的最终目的的是使全社会的智力资料更合理地使用,防止重复劳动,并不是犒赏最先发明者。

按唯美史观,当社会技术发展到某一阶段时,新技术必然会出现。

h.264nalu语法结构

h.264nalu语法结构

H.264 NALU语法结构补充笔记:关于VCL:VCL层是指视频编码层,VCL NAL 单元是指那些nal_unit_type 值等于1 到5(包括1 和5)的NAL 单元,这些单元都包含了视频数据。

所有其他的NAL 单元都称作非VCL NAL 单元,PPS和SPS都是非VCLNAL单元。

关于字节流NAL单元的格式:(起始码中0的长度)除了流开头的字节流NAL单元,大多字节流NAL单元的开头没有leading_zero_8bits (一个字节的0);nal_unit_type等于7(SPS)或8(PPS)时,或字节流NAL 单元语法结构在解码顺序时包含一个访问单元的第一个NAL单元,码流中会出现zero_byte (一个字节的0);所有字节流NAL的单元的开头,都会存在start_code_prefix_one_3bytes (三个000001字节)。

所以,如果不考虑流的开头,没有特殊性的字节流NAL单元,都是只有3字节的起始码(即起始码中0的个数为2)。

一个访问单元的第一个NAL单元是指:在基本编码图像的最后一个VCL NAL 单元之后的第一个任何下列NAL 单元代表了一个新的访问单元的开始:—访问单元分隔NAL 单元(存在时)—序列参数集NAL 单元(存在时)—图像参数集NAL 单元(存在时)— SEI NAL 单元(存在时)— nal_unit_type 值在14-18 之间(包括)的NAL 单元—基本编码图像的第一个VCL NAL 单元(总是存在)下文转自:/yangzhongxuan/article/details/800349 4名词解释场和帧:视频的一场或一帧可用来产生一个编码图像。

在电视中,为减少大面积闪烁现象,把一帧分成两个隔行的场。

片:每个图象中,若干宏块被排列成片的形式。

片分为I片、B片、P片和其他一些片。

I片只包含I宏块,P片可包含P和I宏块,而B片可包含B和I宏块。

I宏块利用从当前片中已解码的像素作为参考进行帧内预测。

H.264简介

H.264简介

H.264简介H.264原始码流由NALU组成。

功能分为两层:VCL(video coding layer)、NAL(network abstraction layer)其中每个NALU之间通过startcode(起始码)进⾏分隔,起始码分成两种:0x000001或者0x00000001。

如果NALU对应的Slice为⼀帧的开始就⽤0x00000001,否则就⽤0x000001。

NALU = NALU Header + BRSP(Raw Byte Squence Payload)1、NALU Header(1Byte)2、RBSPSODB与RBSPSODB 数据⽐特串 -> 是编码后的原始数据.RBSP 原始字节序列载荷 -> 在原始编码数据的后⾯添加了结尾⽐特。

⼀个 bit“1”若⼲⽐特“0”,以便字节对齐。

H.264全⾯观1 frame = n slice;1 slice = n Macroblock;1 Macroblock= 16 * 16yuv。

3、SliceSlice = Slice Header + Slice Data⽚是H.264提出的新概念,通过编码图⽚后切分通过⾼效的⽅式整合出来的概念。

⼀张图⽚有⼀个或者多个⽚,⽽⽚由NALU装载并进⾏⽹络传输的。

但是NALU不⼀定是切⽚,这是充分不必要条件,因为 NALU 还有可能装载着其他⽤作描述视频的信息.那么为什么要设置⽚呢?设置⽚的⽬的是为了限制误码的扩散和传输,应使编码⽚相互间是独⽴的。

某⽚的预测不能以其他⽚中的宏块为参考图像,这样某⼀⽚中的预测误差才不会传播到其他⽚中。

可以看到上图中,每个图像中,若⼲宏块(Macroblock)被排列成⽚。

⼀个视频图像可编程⼀个或更多个⽚,每⽚包含整数个宏块 (MB),每⽚⾄少包含⼀个宏块。

⽚有⼀下五种类型:4、Macroblock1 macroblock = 16*16Y + 8*8 Cb + 8*8 Crtypedef enum {NALU_TYPE_SLICE = 1,NALU_TYPE_DPA = 2,NALU_TYPE_DPB = 3,8NALU_TYPE_DPC = 4,NALU_TYPE_IDR = 5,NALU_TYPE_SEI = 6,NALU_TYPE_SPS = 7,NALU_TYPE_PPS = 8,NALU_TYPE_AUD = 9,NALU_TYPE_EOSEQ = 10,NALU_TYPE_EOSTREAM = 11,NALU_TYPE_FILL = 12,} NaluType;typedef enum {NALU_PRIORITY_DISPOSABLE = 0,NALU_PRIRITY_LOW = 1,NALU_PRIORITY_HIGH = 2,NALU_PRIORITY_HIGHEST = 3} NaluPriority;typedef struct{int startcodeprefix_len; //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested)unsigned len; //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU) unsigned max_size; //! Nal Unit Buffer sizeint forbidden_bit; //! should be always FALSEint nal_reference_idc; //! NALU_PRIORITY_xxxxint nal_unit_type; //! NALU_TYPE_xxxxchar *buf; //! contains the first byte followed by the RBSP} NALU_t;FILE *h264bitstream = NULL; //!< the bit stream fileint info2 = 0, info3 = 0;static int FindStartCode2(unsigned char *Buf) {if (Buf[0] != 0 || Buf[1] != 0 || Buf[2] != 1) return0; //0x000001?else return1;}static int FindStartCode3(unsigned char *Buf) {if (Buf[0] != 0 || Buf[1] != 0 || Buf[2] != 0 || Buf[3] != 1) return0;//0x00000001?else return1;}int GetAnnexbNALU(NALU_t *nalu) {int pos = 0;int StartCodeFound, rewind;unsigned char *Buf;if ((Buf = (unsigned char*)calloc(nalu->max_size, sizeof(char))) == NULL)printf("GetAnnexbNALU: Could not allocate Buf memory\n");nalu->startcodeprefix_len = 3;if (3 != fread(Buf, 1, 3, h264bitstream)) {free(Buf);return0;}info2 = FindStartCode2(Buf);if (info2 != 1) {if (1 != fread(Buf + 3, 1, 1, h264bitstream)) {free(Buf);return0;}info3 = FindStartCode3(Buf);if (info3 != 1) {free(Buf);return -1;}else {pos = 4;nalu->startcodeprefix_len = 4;}}else {nalu->startcodeprefix_len = 3;pos = 3;}StartCodeFound = 0;info2 = 0;info3 = 0;while (!StartCodeFound) {if (feof(h264bitstream)) {nalu->len = (pos - 1) - nalu->startcodeprefix_len;memcpy(nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bitnalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bitnalu->nal_unit_type = (nalu->buf[0]) & 0x1f;// 5 bitfree(Buf);return pos - 1;}Buf[pos++] = fgetc(h264bitstream);info3 = FindStartCode3(&Buf[pos - 4]);if (info3 != 1)info2 = FindStartCode2(&Buf[pos - 3]);StartCodeFound = (info2 == 1 || info3 == 1);}// Here, we have found another start code (and read length of startcode bytes more than we should// have. Hence, go back in the filerewind = (info3 == 1) ? -4 : -3;if (0 != fseek(h264bitstream, rewind, SEEK_CUR)) {free(Buf);printf("GetAnnexbNALU: Cannot fseek in the bit stream file");}// Here the Start code, the complete NALU, and the next start code is in the Buf.// The size of Buf is pos, pos+rewind are the number of bytes excluding the next// start code, and (pos+rewind)-startcodeprefix_len is the size of the NALU excluding the start code nalu->len = (pos + rewind) - nalu->startcodeprefix_len;memcpy(nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);//nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bitnalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bitnalu->nal_unit_type = (nalu->buf[0]) & 0x1f;// 5 bitfree(Buf);return (pos + rewind);}/*** Analysis H.264 Bitstream* @param url Location of input H.264 bitstream file.*/int simplest_h264_parser(char *url) {NALU_t *n;int buffersize = 100000;FILE *myout = stdout;h264bitstream = fopen(url, "rb+");if (h264bitstream == NULL) {printf("Open file error\n");return0;}n = (NALU_t*)calloc(1, sizeof(NALU_t));if (n == NULL) {printf("Alloc NALU Error\n");return0;}n->max_size = buffersize;n->buf = (char*)calloc(buffersize, sizeof(char));if (n->buf == NULL) {free(n);printf("AllocNALU: n->buf");return0;}int data_offset = 0;int nal_num = 0;printf("-----+-------- NALU Table ------+---------+\n");printf(" NUM | POS | IDC | TYPE | LEN |\n");printf("-----+---------+--------+-------+---------+\n");while (!feof(h264bitstream)){int data_lenth;data_lenth = GetAnnexbNALU(n);char type_str[20] = { 0 };switch (n->nal_unit_type) {case NALU_TYPE_SLICE:sprintf(type_str, "SLICE"); break;case NALU_TYPE_DPA:sprintf(type_str, "DPA"); break;case NALU_TYPE_DPB:sprintf(type_str, "DPB"); break;case NALU_TYPE_DPC:sprintf(type_str, "DPC"); break;case NALU_TYPE_IDR:sprintf(type_str, "IDR"); break;case NALU_TYPE_SEI:sprintf(type_str, "SEI"); break;case NALU_TYPE_SPS:sprintf(type_str, "SPS"); break;case NALU_TYPE_PPS:sprintf(type_str, "PPS"); break;case NALU_TYPE_AUD:sprintf(type_str, "AUD"); break;case NALU_TYPE_EOSEQ:sprintf(type_str, "EOSEQ"); break;case NALU_TYPE_EOSTREAM:sprintf(type_str, "EOSTREAM"); break;case NALU_TYPE_FILL:sprintf(type_str, "FILL"); break;}char idc_str[20] = { 0 };switch (n->nal_reference_idc >> 5) {case NALU_PRIORITY_DISPOSABLE:sprintf(idc_str, "DISPOS"); break;case NALU_PRIRITY_LOW:sprintf(idc_str, "LOW"); break;case NALU_PRIORITY_HIGH:sprintf(idc_str, "HIGH"); break;case NALU_PRIORITY_HIGHEST:sprintf(idc_str, "HIGHEST"); break;}fprintf(myout, "%5d| %8d| %7s| %6s| %8d|\n", nal_num, data_offset, idc_str, type_str, n->len);data_offset = data_offset + data_lenth; nal_num++;}//Freeif (n) {if (n->buf) {free(n->buf);n->buf = NULL;}free(n);}return0;}。

h264 NAL头解析

h264 NAL头解析

H264 NAL 头解析分类: linux 学习 2013-06-06 20:43 2535 人阅读 评论(0) 收藏 举报NAL 全称 Network Abstract Layer,即网络抽象层。

在 H.264/AVC 视频编码标准中,整个 系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。

其中,前者 负责有效表示视频数据的内容, 而后者则负责格式化数据并提供头信息, 以保证数据适合各 种信道和存储介质上的传输。

NAL 单元是 NAL 的基本语法结构,它包含一个字节的头信息 和一系列来自 VCL 的称为原始字节序列载荷(RBSP)的字节流。

如果 NALU 对应的 Slice 为一帧的开始,则用 4 字节表示,即 0x00000001;否则用 3 字节 表示,0x000001。

NAL Header: forbidden_bit, nal_reference_bit (优先级) 2bit, nal_unit_type (类型) 5bit。

标 识 NAL 单元中的 RBSP 数据类型,其中,nal_unit_type 为 1, 2, 3, 4, 5 的 NAL 单 元称为 VCL 的 NAL 单元,其他类型的 NAL 单元为非 VCL 的 NAL 单元。

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:未规定 NAL 的头占用了一个字节,按照比特自高至低排列可以表示如下: 0AABBBBB其中,AA 用于表示该 NAL 是否可以丢弃(有无被其后的 NAL 参考),00b 表示没有参 考作用,可丢弃,如 B slice、SEI 等,非零——包括 01b、10b、11b——表示该 NAL 不可丢弃,如 SPS、PPS、I Slice、P Slice 等。

H.264 NAL层解析(0x00000001,编码,打包,NALU)

H.264 NAL层解析(0x00000001,编码,打包,NALU)
20:编码片段扩展
21 – 23:保留
24 – 31:未规定
3.H.264的NAL层处理
结构示意图:
NAL以NALU(NAL unit)为单元来支持编码数据在基于分组交换技术网络中传输。它定义了符合传输层或存储介质要求的数据格式,同时给出头信息,从而提供了视频编码和外部世界的接口。
NALU:定义了可用于基于分组和基于比特流系统的基本格式
Nal_unit_type:当前NAL 单元的类型
标识NAL单元中的RBSP数据类型,其中,nal_unit_type为1, 2, 3, 4, 5的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL单元。
0:未规定
1:非IDR图像中不采用数据划分的片段
2:非IDR图像中A类数据划分片段
RTP封装:只针对基于NAL单元的本地NAL接口。
三w)
RBSP原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSP trailing bits一个bit“1”)若干比特“0”,以便字节对齐
EBSP扩展字节序列载荷-->在RBSP基础上填加了仿校验字节(0X03)它的原因是: 在NALU加到Annexb上时,需要添加每组NALU之前的开始码StartCodePrefix,如果该NALU对应的slice为一帧的开始则用4位字节表示,0x00000001,否则用3位字节表示0x000001.为了使NALU主体中不包括与开始码相冲突的,在编码时,每遇到两个字节连续为0,就插入一个字节的0x03。解码时将0x03去掉。也称为脱壳操作
解决方案:为了防止NAL内部出现0x000001的数据,h.264又提出'防止竞争 emulation prevention"机制,在编码完一个NAL时,如果检测出有连续两个0x00字节,就在后面插入一个0x03,则在NAL数据内肯定不会存在NAL起始码0x000001。当解码器在NAL内部检测到0x000003的数据,就把0x03抛弃,恢复原始数据。

H.264中的AnnexB格式和AVCC格式

H.264中的AnnexB格式和AVCC格式

H.264中的AnnexB格式和AVCC格式⾸先要理解的是没有标准的H.264基本流格式。

⽂档中的确包含了⼀个Annex,特别是描述了⼀种可能的格式Annex B格式,但是这个并不是⼀个必须要求的格式。

标准⽂档中指定了视频怎样编码成独⽴的包,但是这些包是怎样存储和传输的却是开放的。

⼀. Annex B1. Network Abstraction Layer Units 视频编码成的包叫做Network Abstraction Layer Units, 也简称为NALU、NAL,每个NALU包都可以被单独的解析和处理,每个NALU包的第⼀个字节包含了NALU类型,bit3-bit7包含的内容尤其重要(bit 0⼀定是off的,bit1-2指定了这个NALU是否被其他NALU引⽤)。

NALU格式分为2类,VCL和non-VCL,总共有19种不同的NALU格式。

VCL Video Coding Layer packets contain the actual visual information. 即视频编码后的数据 Non-VCL Contain metadata that may or may not be required to decode the video. ⾮视频数据,配置信息 ⼀个单独的NALU包、或者甚⾄⼀个VCL NALU包都不意味着是⼀个独⽴的帧,⼀帧数据可以被分割成⼏个NALU,⼀个或多个NALU组成了⼀个Access Units(AU),AU包含了⼀个完整的帧。

把帧分割成⼏个独⽴的NALU需要耗费许多CPU资源,所以分割帧数据并不经常使⽤。

以下是所有定义了的NALU类型,如表 7-1 所⽰。

VCL NAL 单元是指那些 nal_unit_type 值等于 1 到 5(包括 1 和 5)的 NAL 单元。

所有其他的 NAL 单元都称作⾮ VCL NAL 单元。

:2. NALU Start Codes, NALU包开始码 ⼀个NALU包中的数据并不包含它的⼤⼩(长度)信息,因此不能简单的连接NALU包来建⽴⼀个流,因为你不知道⼀个包从哪⾥结束,另⼀个包从哪⾥开始。

H264码流的NAL起始字节分析

H264码流的NAL起始字节分析
NALU_TYPE_SLICE = 1,
NALU_TYPE_DPA = 2,
NALU_TYPE_DPB = 3,
NALU_TYPE_DPC = 4,
NALU_TYPE_IDR = 5,
NALU_TYPE_SEI = 6,
NALU_TYPE_SPS = 7,
NALU_TYPE_PPS = 8,
NALU_TYPE_AUD = 9,
H264码流的NAL起始字节分析
在收到h264码流的每个NAL数据(Buffer指针)时,对于如下代码的理解:
if((*(Buffer) == 0) && (*(Buffer+1) == 0) && (*(Buffer+2) == 0) && (*(Buffer+3) == 1))//NAL头的0x00 00 00 01起始码
frame_type = P_FRAME;
}
if((*(Buffer+5) & 0x80) == 0x80)
{
start_frame = 1;
}
}
00 00 00 01是Start code后面的ox67为0110 0111
forbidden_zero_bit是禁止位,应该是第一位即f(1)=0,1为语法有错误
{
if(*(Buffer+4) == SPS_FRAME)
{//ox67为0110 0111(nal_unit_type为低5位,u(5)= 0 0111 = 7)
frame_type = SPS_FRAME;
}
else if(*(Buffer+4) == PPS_FRAME)
{//ox68为0110 1000(nal_unit_type为低5位,u(5)= 0 1000 = 8)

HEVC学习(十九)——NALunit的解码过程之三

HEVC学习(十九)——NALunit的解码过程之三

H EVC_CJL的专栏H EVC学习(十九) —— NAL unit 的解码过程之三分类: HEVC 2013-01-03 20:43 663人阅读 评论(1) 收藏举报HEVCHMNAL解码过程前面两篇已经将NAL的解析过程的核心部分介绍完了,本篇主要讨论如何将NAL的payload部分转化为原始数据,即从EBSP到RBSP的过程。

该过程由TAppDecTop::decode()的子函数read(nalu, nalUnit)调用convertPayloadToRBSP(nalUnitBuf, pcBitstream, (nalUnitBuf[0] & 64) == 0)实现。

read(nalu, nalUnit); //!< nalUnit-->nalu (EBSP-->RBSP)/*** create a NALunit structure with given header values and storage for* a bitstream*/void read(InputNALUnit& nalu, vector<uint8_t>& nalUnitBuf){/* perform anti-emulation prevention */TComInputBitstream *pcBitstream = new TComInputBitstream(NULL);#if HM9_NALU_TYPESconvertPayloadToRBSP(nalUnitBuf, pcBitstream, (nalUnitBuf[0] & 64) == 0); //!< 实现真正的EBSP-->RBSP#elseconvertPayloadToRBSP(nalUnitBuf, pcBitstream);#endifnalu.m_Bitstream = new TComInputBitstream(&nalUnitBuf);delete pcBitstream;readNalUnitHeader(nalu); //!< 解析NAL的头部}#if HM9_NALU_TYPESstatic void convertPayloadToRBSP(vector<uint8_t>& nalUnitBuf, TComInputBitstream *pcBitstream, Bool isVclNalUnit)#elsestatic void convertPayloadToRBSP(vector<uint8_t>& nalUnitBuf, TComInputBitstream *pcBitstream)#endif{UInt zeroCount = 0;vector<uint8_t>::iterator it_read, it_write;for (it_read = it_write = nalUnitBuf.begin(); it_read != nalUnitBuf.end(); it_read++, it_write++){assert(zeroCount < 2 || *it_read >= 0x03);if (zeroCount == 2 && *it_read == 0x03) //!< 读到0x000003时,丢弃0x03{it_read++;zeroCount = 0;if (it_read == nalUnitBuf.end()){break;}}zeroCount = (*it_read == 0x00) ? zeroCount+1 : 0;*it_write = *it_read;}assert(zeroCount == 0);#if HM9_NALU_TYPESif (isVclNalUnit){// Remove cabac_zero_word from payload if presentInt n = 0;while (it_write[-1] == 0x00){it_write--;n++;}if (n > 0){printf("\nDetected %d instances of cabac_zero_word", n/2);}}#endifnalUnitBuf.resize(it_write - nalUnitBuf.begin());}下面这个函数可对照draft 7.3.1.2 NAL unit header syntax进行分析,如下:Void readNalUnitHeader(InputNALUnit& nalu){TComInputBitstream& bs = *nalu.m_Bitstream;Bool forbidden_zero_bit = bs.read(1); // forbidden_zero_bitassert(forbidden_zero_bit == 0);nalu.m_nalUnitType = (NalUnitType) bs.read(6); // nal_unit_typenalu.m_reservedZero6Bits = bs.read(6); // nuh_reserved_zero_6bits assert(nalu.m_reservedZero6Bits == 0);nalu.m_temporalId = bs.read(3) - 1; // nuh_temporal_id_plus1 if ( nalu.m_temporalId ){assert( nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_BLA&& nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_BLANT&& nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_BLA_N_LP&& nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR&& nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR_N_LP&& nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_CRA&& nalu.m_nalUnitType != NAL_UNIT_VPS&& nalu.m_nalUnitType != NAL_UNIT_SPS&& nalu.m_nalUnitType != NAL_UNIT_EOS&& nalu.m_nalUnitType != NAL_UNIT_EOB );}else{assert( nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_TLA&& nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_TSA_N&& nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_STSA_R&& nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_STSA_N );}}。

nalu header格式

nalu header格式

NALU Header是一种用于标识NALU(网络抽象层单元)的头部格式。

NALU是
H.264/AVC视频编码标准中使用的网络抽象层协议的数据传输单位。

NALU Header的格式包括以下三个部分:
1.forbidden_zero_bit:这是一个禁止位,用于指示该NALU是否可以被丢
弃。

如果该位为0,则表示该NALU不能被丢弃;如果该位为1,则表示该
NALU可以被丢弃。

2.nal_ref_idc:这是一个指示NALU重要性的标识符。

该标识符的数值越大,
表示该NALU越重要。

根据该标识符的值,解码器可以决定是否忽略该NALU 或者优先处理该NALU。

3.nal_unit_type:这是一个标识NALU类型的标识符。

不同类型的NALU具有
不同的功能和用途,例如,有的NALU用于表示视频参数集,有的NALU用于表示编码的图像数据等。

综上所述,NALU Header格式是用于标识NALU的重要性和类型的头部格式,它包括禁止位、NALU重要性标识符和NALU类型标识符三个部分。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
处理过程:
1.将VCL层输出的SODB封装成nal_unit,Nal_unit是一个通用封装格式,可以适用于有序字节流方式和IP包交换方式。
2.针对不同的传送网络(电路交换|包交换),将nal_unit 封装成针对不同网络的封装格式。
第一步的具体过程:
VCL层输出的比特流SODB(String Of Data Bits),到nal_unit之间,经过了以下三步处理:
20:编码片段扩展
21 – 23:保留
24 – 31:未规定
3.H.264的NAL层处理
结构示意图:
NAL以NALU(NAL unit)为单元来支持编码数据在基于分组交换技术网络中传输。它定义了符合传输层或存储介质要求的数据格式,同时给出头信息,从而提供了视频编码和外部世界的接口。
NALU:定义了可用于基于分组和基于比特流系统的基本格式
(1)NALU的分块以按RTP次序号升序传输;
(2)能够标记第一个和最后一个NALU分块;
(3)可以检测丢失的分块。
NALU合并
一些NALU如SEI、参数集等非常小,将它们合并在一起有利于减少头标开销。已有两种集合分组:
(1)单一时间集合分组(STAP),按时间戳进行组合;
(2)多时间集合分组(MTAP),不同时间戳也可以组合。
具体方法:
nal_unit( NumBytesInNALunit ) {
forbidden_zero_bit
nal_ref_idc
nal_unit_type
NumBytesInRBSP = 0
for( i = 1; i < NumBytesInNALunit; i++ ) {
if( i + 2 < NumBytesInNALunit && next_bits( 24 ) = = 0x000003 ) {
解决方案:在每个NAL前添加起始码:0X000001
在某些类型的介质上,为了寻址的方便,要求数据流在长度上对齐,或某个常数的整数倍。所以在起始码前添加若干字节的0来填充。
检测NAL的开始:
0X000001和0X00000001
我们必须考虑当NAL内部出现了0X000001和0X000000
如果NALU对应的Slice为一帧的开始,则用4字节表示,即0x00000001;否则用3字节表示,0x000001。
NALU头结构:NALU类型(5bit)、重要性指示位(2bit)、禁止位(1bit)。
NALU类型:1~12由H.264使用,24~31由H.264以外的应用使用。
重要性指示:标志该NAL单元用于重建时的重要性,值越大,越重要。
禁止位:网络发现NAL单元有比特错误时可设置该比特为1,以便接收方丢掉该单元。
NAL规范视频数据的格式,主要是提供头部信息,以适合各种媒体的传输和存储。NAL支持各种网络,包括:
1.任何使用RTP/IP协议的实时有线和无线Internet 服务
2.作为MP4文件存储和多媒体信息文件服务
3.MPEG-2系统
4.其它网
NAL规定一种通用的格式,既适合面向包传输,也适合流传送。实际上,包传输和流传输的方式是相同的,不同之处是传输前面增加了一个起始码前缀
0X000001——0X00000301
0X000002——0X00000302
0X000003——0X00000303
为此,我们可以知道:
在NAL单元中,下面的三字节序列不应在任何字节对齐的位置出现
0X000000
0X000001
0X000002
Forbidden_zero_bit =0;
Nal_ref_idc:表示NAL的优先级。0~3,取值越大,表示当前NAL越重要,需要优先受到保护。如果当前NAL是属于参考帧的片,或是序列参数集,或是图像参数集这些重要的单位时,本句法元素必需大于0。
序列和图像参数集可以在发送VCL NAL单元以前发送,并且重复传送,大大提高纠错能力。序列和图像参数集可以在“带内”,也可以用更为可靠的其他“带外”通道传送。
存储单元:
一组指定格式的NAL单元称为存储单元,每个存储单元对应一个图像。每个存储单元包含一组VCL NAL单元,组成一个主编码图像,VCL NAL单元由表示视频图像采样的像条所组成。存储单元前面可以加一个前缀,分界存储单元,附加增强信息(SEI)(如图像定时信息)也可以放在主编码图像的前面。主编码图像后附加的VCL NAL单元,包含同一图像的冗余表示,称为冗余编码图像,当主编码图像数据丢失或损坏时,可用冗余编码图像解码。
rbsp_byte[ NumBytesInRBSP++ ]
rbsp_byte[ NumBytesInRBSP++ ]
i += 2
emulation_prevention_three_byte /* equal to 0x03 */
} else
rbsp_byte[ NumBytesInRBSP++ ]
解决方案:为了防止NAL内部出现0x000001的数据,h.264又提出'防止竞争 emulation prevention"机制,在编码完一个NAL时,如果检测出有连续两个0x00字节,就在后面插入一个0x03,则在NAL数据内肯定不会存在NAL起始码0x000001。当解码器在NAL内部检测到0x000003的数据,就把0x03抛弃,恢复原始数据。
0x000000 >>>>>> 0x00000300(结束码)
0x000001 >>>>>> 0x00000301(起始码)
0x000002 >>>>>> 0x00000302(保留)
0x000003 >>>>>> 0x00000303(保证解码器正常工作)
H.264提出了“防止竞争”机制:
0X000000——0X00000300
RTP封装:只针对基于NAL单元的本地NAL接口。
三种不同的数据形式:
SODB数据比特串-->最原始的编码数据 (raw)
RBSP原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSP trailing bits一个bit“1”)若干比特“0”,以便字节对齐
EBSP扩展字节序列载荷-->在RBSP基础上填加了仿校验字节(0X03)它的原因是: 在NALU加到Annexb上时,需要添加每组NALU之前的开始码StartCodePrefix,如果该NALU对应的slice为一帧的开始则用4位字节表示,0x00000001,否则用3位字节表示0x000001.为了使NALU主体中不包括与开始码相冲突的,在编码时,每遇到两个字节连续为0,就插入一个字节的0x03。解码时将0x03去掉。也称为脱壳操作
while( next_bits( 24 ) != 0x000001 )
zero_byte /* equal to 0x00 */
if( more_data_in_byte_stream( ) ) {
start_code_prefix_one_3bytes /* equal to 0x000001 */ nal_unit( NumBytesInNALunit )
H.264 NAL层解析(0x00000001,编码,打包,NALU)
1.引言
H.264的主要目标:
1.高的视频压缩比
2.良好的网络亲和性
解决方案:
VCL video coding layer 视频编码层
NAL network abstraction layer 网络提取层
VCL:核心算法引擎,块,宏块及片的语法级别的定义
Nal_unit_type:当前NAL 单元的类型
标识NAL单元中的RBSP数据类型,其中,nal_unit_type为1, 2, 3, 4, 5的NAL单元称为VCL的NAL单元,其他类型的NAL单元为非VCL的NAL单元。
0:未规定
1:非IDR图像中不采用数据划分的片段
2:非IDR图像中A类数据划分片段
2.NAL语法语义
NAL层句法:
在编码器输出的码流中,数据的基本单元是句法元素。
句法表征句法元素的组织结构。
语义阐述句法元素的具体含义。
分组都有头部,解码器可以很方便的检测出NAL的分界,依次取出NAL进行解码。
但为了节省码流,H.264没有另外在NAL的头部设立表示起始位置的句法元素。
如果编码数据是存储在介质上的,由于NAL是依次紧密相连的,解码器就无法在数据流中分辨出每个NAL的起始位置和终止位置。
参数集:
参数集是很少变化的信息,用于大量VCL NAL单元的解码,分为两种类型:
1.序列参数集,作用于一串连续的视频图像,即视频序列。两个IDR图像之间为序列参数集。IDR和I帧的区别见下面。
2.图像参数集,作用于视频序列中的一个或多个个别的图像序列和图像参数集机制,减少了重复参数的传送,每个VCL NAL单元包含一个标识,指向有关的图像参数集,每个图像参数集包含一个标识,指向有关的序列参数集的内容因此,只用少数的指针信息,引用大量的参数,大大减少每个VCL NAL单元重复传送的信息。
1.SODB字节对齐处理后封装成RBSP(Raw Byte Sequence Payload)。
2.为防止RBSP的字节流与有序字节流传送方式下的SCP(start_code_prefix_one_3bytes,0x000001)出现字节竞争情形,循环检测RBSP前三个字节,在出现字节竞争时在第三字节前加入emulation_prevention_three_byte (0x03)
NAL:片级以上的语法级别(如序列参数集和图像参数集),同时支持以下功能:独立片解码,起始码唯一保证,SEI以及流格式编码数据传送
相关文档
最新文档