H264包解析

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

VCL负责表示视频数据的内容,NAL则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。

在VCL数据传输或存储之前,这些编码的VCL数据,先被映射或封装进NAL单元中。

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

H264码流结构图:

起始码:如果NALU对应的slice为一帧的开始,NAL则用4字节表示,即0x00 00 00 01,负责用3字节表示:0x00 00 01。

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

脱壳操作:为了使NALU主体不包括起始码,在编码时每遇到两个字节(连续)的0,就插入一字节0x03,以和起始码区别。

NAL单元解码流程:

流程为:首先从NAL单元中提取出RBSP结构流,然后根据NALU类型处理RBSP数据。

从h264原文件中分离出NAL数据,用c代码的一种实现方式:

int FindStartCode (unsigned char *Buf, int zeros_in_startcode)
{
  int info;
  int i;

  info = 1;
  for (i = 0; i < zeros_in_startcode; i++)
    if(Buf[i] != 0)
      info = 0;

  if(Buf[i] != 1)
    info = 0;
  return info;
}

int getNextNal(FILE* inpf, unsigned char* Buf)//打开的文件句柄,和将读取的字节存储到Buf中
{
	int pos = 0;
	int StartCodeFound = 0;
	int info2 = 0;
	int info3 = 0;
	int i = 0;
	while (!feof(inpf) && (Buf[pos++] = fgetc(inpf)) == 0);//跳过NAL头

<span style="white-space:pre">	</span>/*通过查找下一次的NAL头来计算本次的NAL的长度,根据长度来读取NAL数据包*/
	while (!StartCodeFound)
	{
		if (feof (inpf))
		{
			return pos-1;
		}
		Buf[pos++] = fgetc (inpf);
		printf("%02X\n", Buf[pos - 1]);
		info3 = FindStartCode(&Buf[pos-4], 3);
		if(info3 != 1)
			info2 = FindStartCode(&Buf[pos-3], 2);
		StartCodeFound = (info2 == 1 || info3 == 1);
	}
	fseek (inpf, -4, SEEK_CUR);
	return pos - 4;//返回的就是一个NAL的长度
}

得到NAL就可以去做相应的解码处理了。X264提供的仅是对于h264的编码操作,FFMPEG有解码的实现,具体的请看我的另一篇博文,

时间: 2024-11-02 06:51:31

H264包解析的相关文章

Android实习札记(3)---Fragment用app包还是v4包解析

Android实习札记(3)---Fragment用app包还是v4包解析 1)问题简述 相信很多的朋友在调用Fragment都会遇到下面的情况: 这个时候问题来了... 到底是用android.app下的Fragment还是用的android.support.v4.app包下的Fragment? 答:其实都可以,没错,都可以!!!我们都知道Fragment是3.0(API 11)后引入的 那么如果开发的app需要在3.0以下的版本运行呢?比如还有一点点市场份额的2.3! 于是乎,v4包就这样应

Struts2+hibernate 配置环境 架包解析

hibernate 配置需要jar的注释. antlr -2.7.6.jar   //一个语言转换工具,没有此包,hibernate不会执行hql语句,hibernate用它实现hql到sql的转换模板相关操作需要包. asm.jar  //asm是小巧轻便的java字节码操控框架,它能方便地生成和改造java代码.hibernate和spring在底层叠 都用到了 asm. asm-attrs.jar//ASM字节码库,如果使用cglib则必要 ehcache-1.2.jar//如果想使用缓存

Android做法说明(3)---Fragment使用app袋或v4包解析

Android做法说明(3)---Fragment使用app袋或v4包解析 1)问题简述 相信非常多的朋友在调用Fragment都会遇到以下的情况: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY29kZXJfcGln/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" > 这个时候问题来了... 究竟是用android.app下的Fragmen

dbms_tdb包解析

The procedure or function in this package checks if a database is ready to be transported to a target platform. and if a database has external tables, directories or BFILEs. It will use dbms_output.put_line to output the external objects and their ow

Linux命令行抓包及包解析工具tshark(wireshark)使用实例解析

在Linux下,当我们需要抓取网络数据包分析时,通常是使用tcpdump抓取网络raw数据包存到一个文件,然后下载到本地使用wireshark界面网络分析工具进行网络包分析. 最近才发现,原来wireshark也提供有Linux命令行工具-tshark.tshark不仅有抓包的功能,还带了解析各种协议的能力.下面我们以两个实例来介绍tshark工具.1.安装方法 CentOS: yum install -y wireshark    Ubuntu: apt-get install -y tsha

蓝牙4.0BLE抓包(二) – 广播包解析

本文转自:http://www.cnblogs.com/aikm/p/5022502.html 感谢原创作者! SleepingBug评论:这篇文档写的相当好,受教了,多谢了!   作者:强光手电[艾克姆科技-无线事业部] 在使用EN-Dongle捕获和解析广播包之前,我们先了解一下BLE报文的结构,之后,再对捕获的广播包进行分析.在学习BLE的时候,下面两个文档是极其重要的,这是SIG发布的蓝牙的核心协议和核心协议增补. 核心协议Core_v4.2. 核心协议增补CSS v6. 虽然这两个文档

C#百度图片识别API调用返回数据包解析

百度图片识别api接口 public static JObject GeneralBasic(string apikey,string secretkey,string path) { var client = new Baidu.Aip.Ocr.Ocr(apikey, secretkey); var image = File.ReadAllBytes(path); // 通用文字识别 var result = client.GeneralBasic(image, null); return r

C++版的网络数据包解析策略(升级版)

初版:http://www.cnblogs.com/wjshan0808/p/6580638.html 说明:在实现了对应的接口后该策略可以适合绝大多数的网络数据包结构 首先,是三个接口 IProduceProxy.h #ifndef _I_PRODUCE_PROXY_H_ #define _I_PRODUCE_PROXY_H_ //Code #define CODE_PRODUCE_PROXY_OK 0x00 //OK #define CODE_PRODUCE_PROXY_NI 0x01 //

H264 NAL解析

NAL全称Network Abstract Layer,即网络抽象层.在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL).其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输.NAL单元是NAL的基本语法结构,它包含一个字节的头信息和一系列来自VCL的称为原始字节序列载荷(RBSP)的字节流. 如果NALU对应的Slice为一帧的开始,则用4字节表示,即0x00000001