【H264解析Demo】1、提取一个Nal Unit单元

0、前言

本文指在从一个H.264码流中提取出一个一段一段的NAL Unit单元

1、理论依据:

H.264码流结构

2、编码提取思路:

将码流中字节依次保存在一个数组中进行判断,如果不等一001或者0001则将读取的下一个字节存放在数组的第一成员

/*
[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}
*/

3、代码:

// MyAnalyzer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "stdlib.h"
#include <vector>

using namespace std;

typedef unsigned char uint8;

/* 使用C++的vector容器进行保存 */
vector<uint8> vecNal;

/*
[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}
*/
static int find_nal_prefix(FILE *pFile)
{
	int i = 0;
	int i32Pos = 0;
	uint8 ui8Prefix[3];

	vecNal.clear();

	for (i = 0; i < 3; i++)
	{
		ui8Prefix[i] = getc(pFile);
		vecNal.push_back(ui8Prefix[i]);
	}
	
	/* 判断当前是否为文件尾 */
	while (!feof(pFile))
	{
		if (ui8Prefix[i32Pos % 3] == 0 && ui8Prefix[(i32Pos+1) % 3] == 0 && ui8Prefix[(i32Pos+2) % 3] == 1)/* 此处注意(i32Pos+1) % 3计算需要加括号 */
		{
			vecNal.pop_back();		/* 将起始码pop出去,不属于NAL单元 */
			vecNal.pop_back();
			vecNal.pop_back();
			break;
		}
		else if (ui8Prefix[i32Pos % 3] == 0 && ui8Prefix[(i32Pos+1) % 3] == 0 && ui8Prefix[(i32Pos+2) % 3] == 0)
		{
			if (1 == getc(pFile))
			{
				vecNal.pop_back();
				vecNal.pop_back();
				vecNal.pop_back();
				break;
			}
		}
		else
		{
			ui8Prefix[i32Pos%3] = getc(pFile);
			vecNal.push_back(ui8Prefix[i32Pos % 3]);
			i32Pos++;
		}
	}

	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int i = 0;
	FILE *m_inputFile = NULL;

	_tfopen_s(&m_inputFile, argv[1], _T("rb"));
	if (NULL != m_inputFile)
	{
		cout << "open:" << argv[1] << "sucess!" << endl;
	}
	else
	{
		cout << "open:" << argv[1] << "failed!" << endl;
		return 0;
	}

	find_nal_prefix(m_inputFile);	/* 第一次调用完都是0,因为码流的头部就是一个NAL的起始码 */
	find_nal_prefix(m_inputFile);

	for (i = 0; i < vecNal.size(); i++)
	{
		printf("%x ", vecNal.at(i));
	}

	printf("\n");
	find_nal_prefix(m_inputFile);

	for (i = 0; i < vecNal.size(); i++)
	{
		printf("%x ", vecNal.at(i));
	}

	fclose(m_inputFile);

	system("pause");

	return 0;
}


程序输出:
在这里插入图片描述
码流16进制文件:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值