H264学习三:H.264码流结构

H.264的码流封装格式

Annex-B字节流格式(大部分是这种):
大部分编码器的默认输出格式;
每个NAL Unit以规定格式的起始码分割;
起始码:0x 00 00 00 01 或0x 00 00 01

RTP数据包格式:
直接封装NAL Unit,无起始码
每个NAL Unit之前以几个字节表示NAL Unit的长度

NAL Unit字节流格式

标准协议文档:“Annex B - Byte stream format”
描述符:f(n) – n位定长编码
语法元素:
leading_zero_8bits:前缀0,值为0x00,仅在第一个NAL Unit中出现;
zero_byte:0字节;
start_code_prefix_one_3bytes:固定值0x 00 00 01,标记一个NAL Unit的起始位置;
trailing_zero_8bits:后缀0;
在这里插入图片描述

查找start_code_prefix之间的数据,是为一个NAL Unit的有效数据;
如:“00 00 00 01 67 42 00 1E E8 58 58 98 80 00 00 00 01 68 C8 ……”
该NAL Unit的实际内容:“67 42 00 1E E8 58 58 98 80”
start_code_prefix:0x00 00 00 01或0x 00 00 01

码流信息提取程序

思路:循环读取字节然后检测是否为00 00 00或00 00 01若是则删除,若不是则存入有效值

int CStreamFile::find_nal_prefix()//提取NAL有效信息
{
	UINT8 prefix[3] = { 0 };
	UINT8 fileByte;//读进来的字节数值
	/*
	[0][1][2] = {0 0 0} -> [1][2][0] ={0 0 0} -> [2][0][1] = {0 0 0}
	getc() = 1 -> 0 0 0 1
	[0][1][2] = {0 0 1} -> [1][2][0] ={0 0 1} -> [2][0][1] = {0 0 1}
	*/

	m_nalVec.clear();

	int pos = 0, getPrefix = 0;
	for (int idx = 0; idx < 3; idx++)
	{
		prefix[idx] = getc(m_inputFile);
		m_nalVec.push_back(prefix[idx]);//将读到的内容push到vector
	}

	while (!feof(m_inputFile))
	{
		if ((prefix[pos % 3] == 0) && (prefix[(pos + 1) % 3] == 0) && (prefix[(pos + 2) % 3] == 1))
		{
			//0x 00 00 01 found
			getPrefix = 1;
			m_nalVec.pop_back();//将起始码从容器中移出来
			m_nalVec.pop_back();
			m_nalVec.pop_back();
			break;
		}
		else if ((prefix[pos % 3] == 0) && (prefix[(pos + 1) % 3] == 0) && (prefix[(pos + 2) % 3] == 0))
		{
			if (1 == getc(m_inputFile))
			{
				//0x 00 00 00 01 found
				getPrefix = 2;
				m_nalVec.pop_back();//将起始码从容器中移出来
				m_nalVec.pop_back();
				m_nalVec.pop_back();
				break;
			}
		}
		else
		{
			fileByte = getc(m_inputFile);//获取一个字节
			prefix[(pos++) % 3] = fileByte;//将获取到的字节存到prefix(有点像循环缓冲区)
			m_nalVec.push_back(fileByte);//将非起始码字节送进vector容器
		}
	}

	return getPrefix;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值