( School of Computer Science & Technology, Soochow University,SuZhou 215006;)
Abstract: H.264 is the newest video coding standard, and it will be widely used. In this article, the problem of the structure of coding streaming in H.264 is discussed. Firstly, the simple profile of H.264 video is introduced. Secondly, the structure of coding streaming is discussed , and then give the graph on it. Finally, by a simple experiment, give the method of getting picture’s width and height from the coding stream.
Keywords: H.264;NAL;structure of coding streaming
引言
H.264是新一代视频编码标准,具有广泛的应用前景,是ITU-T的视频编码专家组(VCEG)和 ISO/IEC的活动图像编码专家组(MPEG)的联合视频组开发的一个新的数字视频编码标准,它既是ITU -T的H.264,又是ISO/IEC的MPEG-4的第10部分。H.264和以前的标准一样,也是DPCM加变换编码的混合编码模式。它的应用目标广泛,可满足各种不同速率、不同场合的视频应用,具有较好的抗误码和抗丢包的处理能力。H.264的基本系统无需使用版权,具有开放的性质,能很好地适应IP和无线网络的使用,这对目前因特网传输多媒体信息、移动网中传输宽带信息等都具有重要意义。
1 H.264框架介绍  
H.264中定义了3个框架[2],每个框架都支持一系列的编解码功能,相应的有一系列的应用。下面作下简单的介绍:
(1) 基线框架(Baseline Profile):它作为H.264的一个简单版本,应用面很广。它支持帧间和帧内编码,支持I帧和P帧,支持CAVLC等,其主要应用是可视电话视频会议,无线通信等。
(2) 主框架(Main Profile):包括支持交错视频,支持B帧,主要是在帧间编码时使用,权重预测,熵编码使用,支持CABAC等。它的主要应用是视频存储和电视广播。采用了多项提高图像质量和增加压缩比的技术措施,可用于SDTV,HDTV,DVD等。
(3) 扩展框架(Extended Profile):不支持交错视频和CABAC,但增加了一些在进行比特流切换时有效的帧模式,SI Switching I帧和SP Switching P帧,能够有效的提高从错误中恢复的能力。它的主要应用是各种网络的视频流传输应用。
2 H264码流结构
2.1 H264分层结构
H.263定义的码流结构是分级结构,共四层。自上而下分别为:图像层(picturelayer)、块组层(GOB layer)、宏块层(macroblock layer)和块层(block layer)。而与H.263相比,H.264的码流结构和H.263的有很大的区别,它采用的不再是严格的分级结构。
H.264的功能分为两层,视频编码层(VCL)和网络提取层(NAL)VCL数据即被压缩编码后的视频数据序列。在VCL数据要封装到NAL单元中之后,才可以用来传输或存储。
NAL单元格式[2] 表1所示:
| 
 表1 NAL单元格式 
 | 
| NAL头 | 
RBSP | 
NAL头 | 
RBSP | 
RBSP:封装于网络抽象单元的数据称之为原始字节序列载荷RBSP,它是NAL的基本传输单元。其中,RBSP又分为视频编码数据和控制数据。其基本结构是:在原始编码数据的后面填加了结尾比特。一个bit“1”若干比特“0”,以便字节对齐。
2.2 H.264码流结构图
通过相关知识的查阅,概括出H.264的码流结构图[2]如图1所示:

3 H.264码流分析的应用
在有些时候,需要从H.264码流中直接取得相关信息(如:图像的宽度和图像的高度等等信息)。下面介绍下取得相关信息的方法:
图像的相关信息存储在网络提取层(NAL)的RBSP结构中,要取得图像的相关信息,既要获得图像的相关位。需依据RBSP结构,获得pic_width_in_mbs_minus1和pic_height_in_map_units_minus1两个值,那么宽度为(pic_width_in_mbs_minus1+1)*16,高度为(pic_height_in_map_units_minus1+1)*16,但是有些情况还得考虑nNum_Ref_Frames的值,一般为1。
3.1获得试验数据
设备:SUNNIC (IP Cam)
名字:ST100factory
Firmware版本:p8b8
视频格式:H.264
(1) 将设备分辨率设成176*144,使用Ethereal等抓包工具抓得一组数据,并去掉相应的RTP头后,该数据为0x00,0x00,0x00,0x01,0x67,0x42,0x00,0x1E,0x99,0xA0,0xB1,0x31。
(2) 将设备分辨率设成720*240,使用Ethereal等抓包工具抓得一组数据,并去掉相应的RTP头后,该数据为0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x1E,0xDA,0x82,0xD1,0xF1。
(3) 将设备分辨率设成720*480,使用Ethereal等抓包工具抓得一组数据,并去掉相应的RTP头后,该数据为0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x1E,0xDB,0x82,0xD1,0xF1。
3.2 相关程序的书写
程序的关键代码如下:
void GetH264Resolution(BYTE*pInBuf,int&nHeight,int&nWidth,int&nNum_Ref_Frames)
{
       ……      
       UE_V(nIndex,nShiftCount,nShiftBuffer,nNum_Ref_Frames,pFrameHead);             
       DWORD gaps_in_frame_num_value_allowed_flag=0;               MyShift(1,nIndex,nShiftCount,nShiftBuffer,gaps_in_frame_num_value_allowed_flag,pFrameHead);
DWORD pic_width_in_mbs_minus1=0;
UE_V(nIndex,nShiftCount,nShiftBuffer,pic_width_in_mbs_minus1,pFrameHead);
       DWORD pic_height_in_map_units_minus1=0;                  UE_V(nIndex,nShiftCount,nShiftBuffer,pic_height_in_map_units_minus1,pFrameHead);
       UE_V(nIndex,nShiftCount,nShiftBuffer,pic_height_in_map_units_minus1,pFrameHead);
       nWidth=(pic_width_in_mbs_minus1+1)*16; //图像的宽度
       nHeight=(pic_height_in_map_units_minus1+1)*16;     //图像的高度
}
voidMyShift(intnCount,int&nIndex,int&nShiftCount,BYTE&nShiftBuffer,DWORD&nRecv,BYTE*pInBuf)
{//从数据流取得相应位的值。
       while (nCount!=0)
       {
              if(nCount>nShiftCount)
              {     nRecv=nRecv<<nShiftCount;
                     nRecv|=nShiftBuffer>>(8-nShiftCount);
                     nShiftBuffer=pInBuf[++nIndex];
                     nCount-=nShiftCount;
                     nShiftCount=8;     
              }else
              {     nRecv=nRecv<<nCount;
                     nRecv|=nShiftBuffer>>(8-nCount);                   
                     nShiftCount-=nCount;
                     nShiftBuffer<<=nCount;
                     nCount=0;
       }}
}
3.3 试验结果与结论
(1)将数据流0x00,0x00,0x00,0x01,0x67,0x42,0x00,0x1E,0x99,0xA0,0xB1,0x31放入GetH264Resolution,取得nWidth为176, nHeight为144,nNum_Ref_Frames为1。跟原数据比对,结果正确。
(2)将数据流0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x1E,0xDA,0x82,0xD1,0xF1放入GetH264Resolution,取得nWidth为720, nHeight为240,nNum_Ref_Frames为1。跟原数据比对,结果正确。
(3)将数据流0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x1E,0xDB,0x82,0xD1,0xF1放入GetH264Resolution,取得nWidth为720, nHeight为240,nNum_Ref_Frames为2。跟原数据比对,240正好是480的一半,而这里的nNum_Ref_Frames正好是2。查阅相关资料发现,这里为了让数据能够正常显示,需要将2帧数据进行Interleave操作后,方能正常显示。
H.264是新一代视频编码标准,具有广泛的应用前景。应用此种方法,在解码前,取得图像的高度和宽度,在某些需要知道图像的宽度和高度的场合,特别是在一些播放H264视频的应用程序中,会有很大帮助。
 
 
												
												
								- 元素高度、宽度获取 style  currentStyle  getComputedStyle  getBoundingClientRect
		
1.示例代码 (1)html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
		 
						- 多媒体开发之---H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
		
一.MP4格式基本概念 MP4格式对应标准MPEG-4标准(ISO/IEC14496) 二.MP4封装格式核心概念 1  MP4封装格式对应标准为 ISO/IEC 14496-12(信息技术 视听对象 ...
		 
						- 多媒体开发之--- h264 图像、帧、片、NALU
		
图像.帧.片.NALU 是学习 H.264的人常常感到困惑的一些概念,我在这里对自己的理解做一些阐述,欢迎大家讨论: H.264 是一次概念的革新,它打破常规,完全没有 I 帧.P帧.B 帧的概念,也 ...
		 
						- 多媒体开发之---h264格式slice_header
		
从Slice_Header学习H.264 写在前面: $     H.264我是结合标准和毕厚杰的书一块学的.看句法语义时最是头疼,一大堆的元素,很需要耐心.标准中在介绍某个元素的语义时,经常会突然冒 ...
		 
						- 多媒体开发之---H264 RTSP交互过程
		
OPTIONS rtsp://192.168.1.154:8557/h264 RTSP/1.0 CSeq: 1 User-Agent: VLC media player (LIVE555 Stream ...
		 
						- 多媒体开发之---h264 rtp打包
		
http://blog.csdn.net/newthinker_wei/article/details/8997440 http://blog.csdn.net/dengzikun/article/d ...
		 
						- 多媒体开发之---h264 NALU 语法结构
		
补充笔记: 关于VCL:VCL层是指视频编码层,VCL NAL 单元是指那些nal_unit_type 值等于 1 到 5(包括 1 和 5)的 NAL 单元,这些单元都包含了视频数据.所有其他的 N ...
		 
						- 多媒体开发之---h264中 的RTP PAYLOAD 格式
		
H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +---------------+      |0|1|2|3|4|5|6|7 ...
		 
						- 多媒体开发之---h264 取流解码实现
		
解码器在解码时,首先逐个字节读取NAL的数据,统计NAL的长度,然后再开始解码. nal_unit( NumBytesInNALunit ) {  /* NumBytesInNALunit为统计出来的 ...
		 
		
	
随机推荐
	
									- PHPCMS V9 采集实例
			
采集目标: 列表: http://www.cnys.com/zixun/list_2_2.html
			 
						- nodejs后台启动
			
可避免关闭窗口,程序就关闭,可在后台运行 安装forever包,一般用于服务器,调试环境可不安装 npm install forever -g 启动方式如图: 查询后台运行哪些程序 forever l ...
			 
						- ORACLE的字符串操作函数
			
字符函数——返回字符值 这些函数全都接收的是字符族类型的参数(CHR 除外)并且返回字符值.除了特别说明的之外,这些函数大部分返回VARCHAR2类型的数值.字符函数的返回类型所受的限制和基本数据库类 ...
			 
						- Codeforces 743D Chloe and pleasant prizes(树型DP)
			
                                                            D. Chloe and pleasant prizes             ...
			 
						- linux挂载新磁盘、分区和开机自动挂载
			
今天在阿里云虚拟主机里新加了一块磁盘,需要单独挂载到centos7. 挂载过程中遇到了不少问题,记录如下: 查看分区 fdisk -l 其中第一个框和第二个框,是已经分好区的磁盘,第三个硬盘没有分区. ...
			 
						- bzoj1455&&luogu2713罗马游戏
			
罗马游戏 题目描述 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻.  ...
			 
						- luogu P1489 猫狗大战
			
题目描述 新一年度的猫狗大战通过SC(星际争霸)这款经典的游戏来较量,野猫和飞狗这对冤家为此已经准备好久了,为了使战争更有难度和戏剧性,双方约定只能选择Terran(人族)并且只能造机枪兵. 比赛开始 ...
			 
						- (入门SpringBoot)SpringBoot结合logback(六)
			
SpringBoot结合logback日志: 1.配置资源文件: #日志配置信息logbacklogging.config=classpath:logback-spring.xmllog.path=E ...
			 
						- Mysql乱码问题解决历程
			
可能是因为看了太多网上的关于这个问题的解决办法,可能当时是我自己没有看明白也或许是情况不一样,反正都没有解决我当初遇到的问题,现在想想可能是自己当初太无知了,第二个原因是原来大多数情况下是在windo ...
			 
						- 查询执行慢的SQL
			
--执行慢的SQL: SELECT S.SQL_TEXT, S.SQL_FULLTEXT, S.SQL_ID, ROUND(ELAPSED_TIME / 1000000 / (CASE WHEN (E ...