H.264中NAL、Slice与frame意思及相互关系

NAL nal_unit_type中的1(非IDR图像的编码条带)、2(编码条带数据分割块A)、3(编码条带数据分割块B)、4(编码条带数据分割块C)、5(IDR图像的编码条带)种类型

与 
Slice种的三种编码模式:I_slice、P_slice、B_slice

还有frame的3种类型:I frame、P frame、 B frame之间有什么映射关系么?

最后,NAL nal_unit_type中的6(SEI)、7(SPS)、8(PPS)属于什么帧呢?

不好意思,文档看得头晕晕的了,问题比较多~~~ 
PS:偶是新人 没多少分,要是哪位达人帮忙下的话  我就给我所有的分,好像只有十几分

1 frame的数据可以分为多个slice. 
每个slice中的数据,在帧内预测只用到自己slice的数据, 与其他slice 数据没有依赖关系。 
NAL 是用来将编码的数据进行大包的。 比如,每一个slice 数据可以放在NAL 包中。 
I frame 是自己独立编码,不依赖于其他frame 数据。 
P frame 依赖 I frame 数据。 
B frame 依赖 I frame, P frame 或其他 B frame 数据。

建议楼主看一点视频编码的书吧, 自己看标准还是很难懂的。

那NAL nal_unit_type中的哪几种类型是I frame,现在只能确定nal_unit_type==5(IDR图像的编码条带)是I frame

sps、pps、SEI算不算I frame呢? 还有 属于编码条带分割的DPA、DPB、DPC呢?

能给个从视频流中提取I frame 和P frame的方法么?

谢谢楼上的回复,我也翻了两三本视频的书籍,感觉都是一个样的,都很少说到点的。楼主能推荐一两本好点的视频书籍么?

没人回答么??

直接给你代码吧 :)

////////////////////////////////////////////////////////////////////////// 
// H.264 NAL type 
enum H264NALTYPE{ 
H264NT_NAL = 0, 
H264NT_SLICE, 
H264NT_SLICE_DPA, 
H264NT_SLICE_DPB, 
H264NT_SLICE_DPC, 
H264NT_SLICE_IDR, 
H264NT_SEI, 
H264NT_SPS, 
H264NT_PPS, 
}; 
int H264GetNALType(LPVOID pBSBuf, const LONG nBSLen) 

if ( nBSLen < 5 )  // 不完整的NAL单元 
return H264NT_NAL;

UINT8* pBS = (UINT8 *)pBSBuf; 
ULONG nType = pBS[4] & 0×1F;  // NAL类型在固定的位置上  
if ( nType <= H264NT_PPS ) 
return nType;

return 0; 
}

其中 H264NT_SLICE_IDR 是关键帧,H264NT_SLICE 是P帧

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

1、NAL、Slice与frame意思及相互关系

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_slice 
NAL 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中已经讲明白。

4、最后,NAL nal_unit_type中的6(SEI)、7(SPS)、8(PPS)属于什么帧呢? 
NAL nal_unit_type 为序列参数集(SPS)、图像参数集(PPS)、增强信息(SEI)不属于啥帧的概念。表示后面的数据信息为序列参数集(SPS)、图像参数集(PPS)、增强信息(SEI)。

能给个从视频流中提取I frame 和P frame的方法么? 
可以看slice中的头信息。

查找NAL起始码,然后读取NAL类型不就可以了吗

pBS[4] & 0×1F

怎么是第5个字节的第五位啊  前面4字节分别是什么(值)?

NAL单元的第1个字节的低五位吧?

然后在问个问题,怎么在一段视频流中检测 NAL的开始和结束?

引用 5 楼 hugeice 的回复:
直接给你代码吧 :)

////////////////////////////////////////////////////////////////////////// 
// H.264 NAL type 
enum H264NALTYPE{ 
H264NT_NAL = 0, 
H264NT_SLICE, 
H264NT_SLICE_DPA, 
H264NT_SLICE_DPB, 
H264NT_SLICE_DPC, 
H264NT_SLICE_IDR, 
H264NT_SEI, 
H264NT_SPS, 
H264NT_PPS, 
}; 
int H264GetNALType(LPVOID pBSBuf, const LONG nBSLen) 

if ( nBSLen < 5 )  // 不完整的NAL单元…

H.264视频流是以NAL单元传送的。。。但在一个NAL单元里面,可能既存放I-Slice(P-Slice或B-Slice),同事也可能存放图像的其他信息 
那么 是不是说 I frame, P frame,B frame是把收到的NAL单元中的VCL的信息先提取出,然后按内容进行I、P、B frame分类?

而我们只能通过NAL nal_unit_type来判别NAL单元中数据的类型哈~~~

====================================================================
 
 
 

《如何结合H.264标准看JM代码》这个web文件,大家都应该有了吧。不过,那个web文档是“H.264乐园”群中聊天的内容,因此看的不是很方便......我在开学来的时候看的时候,做了一些总结,希望与大家分享!不对的地方请指正!

1、一个sps后,有若干个pps吗?
      这主要又编码器决定,但JM代码中只有一个

2、标准中第二栏的C是什么意思?
    请看标准7.2--分类(在表中以C标记)表明了片数据被划分为三类片数据分割的情况。片数据A类分割包含所有的2类语法元素。片数据B类分割包含所有的3类语法元素。片数据C类分割包含所有的4类语法元素。其他类语法元素取值的含义未做规定。对于某些语法元素,使用一个垂直竖线表示其包含两类语法元素。在这种情况下,该语法元素将使用的分类值将在文本中进一步确定。

3、一个NALU对应一个片吗?
    这种说法不太准确,NALU 包括一个片、SPS、PPS、SEI等等

4、decode_one_frame()包括I、P、B

5、 case NALU_TYPE_SLICE:
      case NALU_TYPE_IDR:
      case NALU_TYPE_DPA
      case NALU_TYPE_DPB:
      case NALU_TYPE_DPC
      case NALU_TYPE_SEI:
      case NALU_TYPE_PPS
      case NALU_TYPE_SPS
      case NALU_TYPE_AUD:
      case NALU_TYPE_EOSEQ:
      case NALU_TYPE_EOSTREAM:
      case NALU_TYPE_FILL
     问题:什么时候进入哪个,有什么说明的文章或书么?
        答 :进入哪个 case 是由从 NALU 头里解码出来的 nalu_type 决定的

6、解码器中的误码隐藏只对丢包有用,丢包之后,包的序号不连续,解码器一旦检测到包序号不连续就会将不连续地方的 ei_flag  置 1

7、字节流格式和RTP格式码流,具体的不同点有哪些?相关的资料哪里有?
      字节流格式主要用于文件存储,因此在该格式码流中 NALU 前面只有一个开始前缀,RTP格式码流因为需要进行网络传输, 因此 NALU 前面还有很多辅助信息

8、rtp格式就是在字节流前加包头吗?
      不是,字节流=开始前缀+NALU,而 RTP 中没有 开始前缀

9、RTP中没有开始前缀,为什么还是要插03?
       防止伪起始码、、RTP完全可以不用起始码,或许是为了与字节流格式统一吧

10、NALU是对RBSP的封装。而RTP之类的是对NALU的封装。

11、为什么要分ABC片?
        ——分ABC片主要目的是为了对重要程度不同的数据进行不同程度的保护

12、baseline没有数据分割吧?
      baseline只是如何产生RBSP,如何封装NALU。具体如何传输,RTP之类只是一种方式,文件copy也是一种方式,那一般 baseline最多有多少参考帧?任意个。

13、解码profile_idc之后解码器要做什么工作?比如baseline不支持CABAC那么后面相应的位entropy_coding_mode_flag是不是就不存在了,如果存在,相抵触怎么办?
      当然不会执行 CABAC 的代码,编码器如果是编码 baseline ,那么码流中自然就不存在与 CABAC 相关的语法元素,例如  entropy_coding_mode_flag ,解码器解码 SPS ,得知码流是 baseline 后,自然也就不会去调用与 CABAC 相关的解码程 序,也就不会出错了。profile_idc 为 baseline ,active_pps->entropy_coding_mode_flag 就不会为 CABAC,,码流是 否是 baseline 并不是由多少个参考帧决定的

14、JM 进行 CAVLC 编码时候,对于 level = 8 的情况是采用 escape suffix 处理的,我修改代码将 level = 8 的情况采用无符号数表示,结果编码出来的码流与未修改完全一样

附:RBSP、SODB、EBSP三者的区别和联系!
        SODB:最原始的编码数据,没有任何附加数据
        RBSP:在 SODB 的基础上加了rbsp_stop_ont_bit(bit 值为 1)并用 0 按字节补位对齐
        EBSP:在 RBSP 的基础上增加了防止伪起始码字节(0X03)

1、1 frame的数据可以分为多个slice.
       2、每个slice中的数据,在帧内预测只用到自己slice的数据, 与其他slice 数据没有依赖关系。
       3、NAL 是用来将编码的数据进行大包的。 比如,每一个slice 数据可以放在NAL 包中。
       4、I frame. 是自己独立编码,不依赖于其他frame. 数据。
            P frame. 依赖 I frame. 数据。
            B frame. 依赖 I frame, P frame. 或其他 B frame. 数据。

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

15、NAL、Slice与frame意思及相互关系

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

16、NAL nal_unit_type中的1(非IDR图像的编码条带)、2(编码条带数据分割块A)、3(编码条带数据分割块B)、4(编码条带数据分割块C)、5(IDR图像的编码条带)种类型与 Slice种的三种编码模式:I_slice、P_slice、B_slice NAL nal_unit_type 里的五种类型,代表接下来数据是表示啥信息的和具体如何分块。I_slice、P_slice、B_slice 表示I类型的片、P类型的片,B类型的片.其中I_slice为帧内预测模式编码;P_slice为单向预测编码或帧内模式;B_slice 中为双向预测或帧内模式。

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

18、最后,NAL nal_unit_type中的6(SEI)、7(SPS)、8(PPS)属于什么帧呢?
NAL nal_unit_type 为序列参数集(SPS)、图像参数集(PPS)、增强信息(SEI)不属于啥帧的概念。表示后面的数据信息为序列参数集(SPS)、图像参数集(PPS)、增强信息(SEI)。

========================================================
 
 
首先我觉得先要找相关书籍把基本原理搞懂,不要急于看标准和源代码。要知道什么是采样格式,什么是I、P、B,他们的原理是什么,了解CAVLC、CABAC熵编码的实现过程,一定要认认真真。这样各个主要模块攻克之后,你就可以结合标准和源代码一步一步的看下去。

下面以解码过程为例说一下具体过程:

1、 过程:码流→NALU→RBSP。

如果是字节流的码流当然就首先要对字节流进行解析,这就要看附录 B 了,如何查找起始码和去除伪起始码(为什么有伪起始码呢?);如果是 RTP 格式的码流,那就要按 RFC3984 来解析了(标准没有规定 RTP 格式码流的解析过程);字节流解析完后提取出来的就是 NALU 了,对 NALU 的解析就要看第七章了。黑色的粗体字都是在码流中可能出现的语法元素,解码器的首要任务就是要对这些语法元素进行解析。对于这些码流中的语法元素我们要进行解析必须知道三个问题:

(1)、什么时候存在于码流中?这样我们才能知道当前解析的是哪个语法元素;

(2)、采用什么样的熵编码方式?这样我们才能知道如何解析;
  (3)、含义是什么?这样我们才知道解析出来之后用来干什么。

NALU 的前面三个语法元素所组成的一个字节我们称为 NALU 头,其余部分(也就是语法表 7.3.1 中的其余部分)我们称为 NALU 体。对 NALU 体的解析要看 7.3.2 小节。因为 NALU 有很多种类型,所以要针对 NALU 的不同类型去解析 NALU 体(表 7-1 说明了不同 NALU 对应的语法表)。例如,如果当前的 NALU 是 SPS,那么当然就要看 7.3.1 小节;如果当前的 NALU 是 DPA,那么当然就要看 7.3.2.9.1 小节了;
         2、对于属于 VCL 的 NALU(哪些 NALU 是 VCL NALU 呢?如果你看了 nal_unit_type 的语义,你就应该知道),例如表 7-1 中类型为 5 的 NALU,根据表 7-1 我们知道 NALU 体的语法表是 7.3.2.8。而从 7.3.2.8 我们可以看到,对这种 NALU 的 NALU 体解析实际就是对片级语法进行解析。语法表 7.3.2.8 显示片级语法解析首先要解析 slice_header()(这种带括号的表示是另一个语法结构),那么 slice_header() 怎么解析呢?往下看,7.3.3 的所有内容都被第一行的 slice_header() 包括在内,所以 7.3.3 就是对 slice_header() 这个语法层的码流规定;
        3、按照语法表 7.3.2.8 解析完了 slice_header() 就该解析 slice_data() 了。下面以最常见的 I 帧(CAVLC 熵编码、非 MBAFF)的解析过程为例简单描述怎么继续读标准。这时在码流中出现的第一个 slice_data() 层的语法元素是语法表 7.3.4 中的 macroblock_layer(),也就是说直接到了宏块层的语法解析,那就要又要看 7.3.5 小节了;
      4、基于我们对编解码流程的了解,我们知道解码是一个预测值加残差得到重建图像的过程,那么我们下面的解码过程就要分成两步走了:首先,得到预测值;其次,得到残差。基于我们对 H.264 关键技术的了解,我们知道 intra 宏块(提醒:我们举的例子是 I 帧,因此解析的是 intra 宏块)的预测值是需要使用到预测模式的,所以我们需要解析语法表 7.3.5 中的 mb_pred(mb_type) 语法层,那么又去看 7.3.5.1 小节。按照 7.3.5.1 小节解析出宏块或块的预测方式后我们怎么计算预测值呢?去看标准 8.3 小节;得到预测值后我们继续按照语法表 7.3.5 解析语法元素直到 residual() 语法层,这就又要去看 7.3.5.3 小节;按照 7.3.5.3 小节解析出残差系数后我们如何把它还原成真实的残差呢?去看标准 8.5 小节;
        5、预测值和残差都有了,加起来就是解码图像了。解码的主要工作到此也算基本完成了。当然,上面的过程中还会用到标准其他章节的相关内容(例如,8.5 小节会用到 5.7 小节中定义的 InverseRasterScan)总体过程也就如此吧,详细内容要大家自己去认真的学习

H.264中NAL、Slice与frame意思及相互关系的更多相关文章

  1. 【转】H.264中的NAL技术

    NAL技术 1.NAL概述 NAL全称Network Abstract Layer,即网络抽象层.在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面 ...

  2. H.264中NALU、RBSP、SODB的关系 (弄清码流结构)

    NALU:Coded H.264 data is stored or transmitted as a series of packets known as NetworkAbstraction La ...

  3. H.264 中的Annex B格式和AVCC格式

    首先要理解的是没有标准的H.264基本流格式.文档中的确包含了一个Annex,特别是描述了一种可能的格式Annex B格式,但是这个并不是一个必须要求的格式.标准文档中指定了视频怎样编码成独立的包,但 ...

  4. H.264 基础及 RTP 封包详解

    转自:http://my.oschina.net/u/1431835/blog/393315 一. h264基础概念 1.NAL.Slice与frame意思及相互关系 1 frame的数据可以分为多个 ...

  5. H.264学习笔记之一(层次结构,NAL,SPS)

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

  6. (转载)H.264码流的RTP封包说明

    H.264的NALU,RTP封包说明(转自牛人) 2010-06-30 16:28 H.264 RTP payload 格式 H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) ...

  7. H.264视频的RTP荷载格式

    Status of This Memo This document specifies an Internet standards track protocol for the   Internet ...

  8. FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  9. H.264学习笔记

    1.帧和场的概念 视频的一场或一帧可用来产生一个编码图像.通常,视频帧可以分成两种类型:连续或隔行视频帧.我们平常看的电视是每秒25帧,即每秒更换25个图像,由于视觉暂留效应,所以人眼不会感到闪烁.每 ...

随机推荐

  1. window.open被IE拦截的解决办法

    由于在使用window.open时,在很多情况下,弹出的窗口会被浏览器阻止,但若是使用a链接target='_blank',则不会,基于这一特点,自己封装了一个open方法: function ope ...

  2. PHP之SQL防注入代码集合(建站常用)

    SQL防注入代码一 <?php if (!function_exists (quote)) { function quote($var) { if (strlen($var)) { $var=! ...

  3. uva 10859

    刘书例题  树形dp #include <cstdio> #include <cstdlib> #include <cmath> #include <map& ...

  4. 设置HTTP header方式

    一, Server Code JSP----> <%@ page language="java" contentType="text/html; charse ...

  5. Palindrome Partitioning II

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  6. lintcode 中等题:majority number III主元素III

    题目 主元素 III 给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的1/k. 样例 ,返回 3 注意 数组中只有唯一的主元素 挑战 要求时间复杂度为O(n),空间复杂度为O( ...

  7. compiler 学习

    一款强大的编译器LLVM:http://llvm.org/docs/GettingStarted.html#layout http://llvm.org/docs/LangRef.html http: ...

  8. platform_driver_register(),platform_device_register()区别

    设备与驱动的两种绑定方式:在设备注册时进行绑定及在驱动注册时进行绑定. 以一个USB设备为例,有两种情形: (1)先插上USB设备并挂到总线中,然后在安装USB驱动程序过程中从总线上遍历各个设备,看驱 ...

  9. C内存分配函数

    C语言跟内存分配方式(1) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量.(2) 在栈上创建.在执行函数时,函数内局部变量的 ...

  10. PowerDesigner连接Oracle数据库建表序列号实现自动增长

    原文:PowerDesigner连接Oracle数据库建表序列号实现自动增长 创建表就不说了.下面开始介绍设置自动增长列. 1 在表视图的列上创建.双击表视图,打开table properties — ...