【视頻编编解码·学习培训手记】6. H.264视频比特
摘要: 【视頻编编解码·学习培训手记】6. H.264视频比特率剖析工程项目建立在建一个VS工程项目SimpleH264analyzer, 改动工程项目特性主要参数- 輸出文件目录:$(SolutionDir)bin\$(Configuration)\,工作...
在建一个VS工程项目SimpleH264analyzer, 改动工程项目特性主要参数- 輸出文件目录:$(SolutionDir)bin\$(Configuration)\,工作中文件目录:$(SolutionDir)bin\$(Configuration)\ 编译程序一下工程项目,工程项目文件目录下能转化成bin文档夹,在其中的debug文档夹中有刚刚编译程序转化成的exe文档。将一个.264视頻文档复制到这一文档夹中(此次应用的还是学习培训手记3中转化成的.264文档)。 将这一文档做为键入主要参数传入工程项目中:特性 - 调节 - 指令主要参数:test.264 (最终哪个文档名依据自身的改) 变更文件目录构造,并在建2个文档Stream.h Stream.cpp,变更后文件目录构造以下:

#ifndef _STREAM_H_ #define _STREAM_H_ #include vector class CStreamFile public: CStreamFile(TCHAR *fileName); ~CStreamFile(); // Open API int Parse_h264_bitstream(); private: FILE *m_InputFile; TCHAR *m_fileName; std::vector uint8 m_nalVec; // 用于复印系统日志 (); void file_error(int dex); // 获取NAL合理数据信息 int find_nal_prefix(); #endif在Stream.cpp文档中,完成其结构方式及组员涵数:
#include stdafx.h #include Stream.h #include iostream using namespace std; // 结构涵数进行开启文档实际操作 CStreamFile::CStreamFile(TCHAR * fileName) m_fileName = fileName; (); // 开启视頻文档(写保护二进制) _tfopen_s( m_InputFile, m_fileName, _T( rb )); if (NULL == m_InputFile) file_error(0); // 析构涵数进行关掉文档实际操作 CStreamFile::~CStreamFile() if (NULL != m_InputFile) fclose(m_InputFile); m_InputFile = NULL; int CStreamFile::Parse_h264_bitstream() return 0; int CStreamFile::find_nal_prefix() return 0; // 复印文档信息内容 void CStreamFile::() if (m_fileName) wcout L File name: m_fileName endl; // 复印不正确信息内容 void CStreamFile::file_error(int idx) switch (idx) case 0: wcout L Error: opening input file failed. endl; break; default: break; }以后在主涵数中,撰写开启文档编码,检测之上编码可否一切正常实行:
#include stdafx.h #include Stream.h int _tmain(int argc, _TCHAR* argv[]) CStreamFile h264stream(argv[1]); // 此涵数做为最顶层涵数,实行全部作用(临时还未写一切作用完成) h264stream.Parse_h264_bitstream(); return 0; }编译程序实行后,在cmd对话框中,可以复印出文档名字,即是恰当实行。 接下去,设定一个全局性的头文档,用于界定全部文档上都用到到的数据信息种类。
在Application文件目录下,在建Global.h头文档,键入下列编码:
#ifndef _GLOBAL_H_ #define _GLOBAL_H_ typedef unsigned char uint8; typedef unsigned int uint32; #endif // !_GLOBAL_H_在stdafx.h文档中,引进刚刚在建的头文档:
#include Global.h
完成find_nal_prefix()涵数。完成方式与学习培训手记4中编码基本一致,仅改动一些自变量名字。(学习培训手记4中有详尽解读,这儿已不表明)。Stream.cpp文档中,涵数完成以下:
int CStreamFile::find_nal_prefix() uint8 prefix[3] = { 0 }; uint8 fileByte;改动Stream.cpp中Parse_h264_bitstream()涵数,循环系统启用find_nal_prefix()涵数,持续获得起止码中间数据信息。
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; m_nalVec.push_back(fileByte); return getPrefix; }
int CStreamFile::Parse_h264_bitstream() int ret = 0; ret = find_nal_prefix(); } while (ret); return 0; }对于此事文档编译程序、调节,查询之上所敲代码是不是不太好:
第一次循环系统时,文档指针移动到第一个起止码后;第二次循环系统时,载入到2个起止码间的合理数据信息,根据调节可见到以下数据信息,与test.264中第一组合理数据信息同样:

int CStreamFile::Parse_h264_bitstream() int ret = 0; ret = find_nal_prefix(); // 分析NAL UNIT // 第一次实行循环系统的情况下,m_nalVec为空,因而加个分辨 if (m_nalVec.size()) // 鉴别NAL Unit类型 // NAL Unit第一个字节数为NAL Header,后边5位表明NAL Type(应用按位与计算,提取后边五十位数据) uint8 nalType = m_nalVec[0] 0x1F; wcout L NAL Unit Type: nalType endl; } while (ret); return 0; }编译程序运作后,結果以下:

其所相匹配的种类为(可从H.264官方网文本文档,表7-1中查出):

简单点来说,便是除去2个连零后边的03。00 00 03 xx xx xx (在其中的03即是市场竞争校检位,在拆包的情况下必须除去) 在 CStreamFile 类中加上独享涵数 void ebsp_to_rbsp();
涵数完成以下:
void CStreamFile::ebsp_to_rbsp() // 00 00 03 持续2个零零后面的03是避免市场竞争校检字节数,必须除掉 // 在编码序列中找03,在查询前边2个不是是00,假如是,就要掉03 if (m_nalVec.size() 3) return; for (vector uint8 ::iterator itor = m_nalVec.begin() + 2; itor != m_nalVec.end(); ) // 迭代更新器提高力度为空,写在循环系统內部,便捷删掉原素 if ((3 == *itor) (0 == *(itor - 1)) (0 == *(itor - 2))) // 这里应用erase()时要要留意: // 1、当启用erase()后Itor迭代更新器就无效了,变为了一野指针 // 2、而erase()这一涵数会回到一个指针,仍偏向消除原素的部位,只不过是后边全部的数据信息都往前移动 itor = m_nalVec.erase(itor); else itor++; }
这儿本应也有RBSP - SODB的一部分,也便是除去 rbsp_trailing_bits ,但针对剖析 NAL Body 內部英语的语法原素不容易导致具体危害,这一部分临时缺口,有兴趣爱好的能够自身完成一下。
仙桃云科潜心于网站设计制作,自始至终追求完美“用更快的速率订制出最比较好的网站”。懂您需要、做您所感!大家一直在思索怎样为顾客造就更大的使用价值,让顾客更放心!