博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
H.264码流分析入门(以第一帧为例)
阅读量:4142 次
发布时间:2019-05-25

本文共 5240 字,大约阅读时间需要 17 分钟。

       编码foreman_part_qcif.yuv的第一帧,分析生成的码流,为了便于分析,我们需要打开JM8.6编码器中的trace_enc.txt文件记录功能,怎么开启呢?在JM8.6 encoder的define.h文件中有这样的代码:

#if defined _DEBUG#define TRACE           0                   //!< 0:Trace off 1:Trace on#else#define TRACE           0                   //!< 0:Trace off 1:Trace on#endif

     

      只需要把代码改为下面的形式就可以开启trace_enc.txt文件的功能:

#if defined _DEBUG#define TRACE           1                   //!< 0:Trace off 1:Trace on#else#define TRACE           0                   //!< 0:Trace off 1:Trace on#endif

      trace_enc.txt文件对码流分析具有很大的作用,运行一下程序,看看trace_enc.txt中的内容就知道了. 我们知道,码流在test.264文件中,如果要看的话,需要用UltrlEdit来看其中二进制比特对应的十六进制,而且不能复制,这样就不太方便了. 为了便于分析码流,便于观看,本人把码流写成对应的字符形式,直观,而且可以复制. 具体在代码中的操作为:

void printDataIntoFile(FILE *fp, int i){	char str[20];	int r = 2;	int length;	int j;	assert(i >= 0 && i <= 255);	itoa(i, str, r); // 重要函数(转成二进制)	if(i <= 15)		fprintf(fp, "0%X: ", i);	else		fprintf(fp, "%X: ", i);	length = strlen(str);	for(j = length; j < 8; j++)		fprintf(fp, "0"); // 前面补0	fprintf(fp, "%s <---", str);	fprintf(fp, "(%3d)\n", i);}/*! ******************************************************************************************** * \brief  *    Writes a NALU to the Annex B Byte Stream * * \return *    number of bits written * *********************************************************************************************/int WriteAnnexbNALU (NALU_t *n){  int BitsWritten = 0;  int i;  assert (n != NULL);  assert (n->forbidden_bit == 0);  assert (f != NULL);  assert (n->startcodeprefix_len == 3 || n->startcodeprefix_len == 4);// printf ("WriteAnnexbNALU: writing %d bytes w/ startcode_len %d\n", n->len+1, n->startcodeprefix_len);   if (n->startcodeprefix_len > 3)  {    putc (0, f);    BitsWritten =+ 8;	printDataIntoFile(fp, 0);  }  putc (0, f);  printDataIntoFile(fp, 0); // 写到myData.txt中  putc (0, f);  printDataIntoFile(fp, 0); // 写到myData.txt中  putc (1, f);  printDataIntoFile(fp, 1); // 写到myData.txt中  BitsWritten += 24;  n->buf[0] =    n->forbidden_bit << 7      |    n->nal_reference_idc << 5  |    n->nal_unit_type;// printf ("First Byte %x, nal_ref_idc %x, nal_unit_type %d\n", n->buf[0], n->nal_reference_idc, n->nal_unit_type);  if (n->len != fwrite (n->buf, 1, n->len, f))  {    printf ("Fatal: cannot write %d bytes to bitstream file, exit (-1)\n", n->len);    exit (-1);  }  BitsWritten += n->len * 8;  for(i = 0; i < n->len; i++ )  {	 // 写到myData.txt中	 printDataIntoFile(fp, n->buf[i]);  }  fflush (f);#if TRACE  fprintf (p_trace, "\n\nAnnex B NALU w/ %s startcode, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d\n\n",    n->startcodeprefix_len == 4?"long":"short", n->len, n->forbidden_bit, n->nal_reference_idc, n->nal_unit_type);  fflush (p_trace);#endif  return BitsWritten;}

       在myData.txt中的部分内容为:

00: 00000000 <---(  0)

00: 00000000 <---(  0)
00: 00000000 <---(  0)
01: 00000001 <---(  1)
67: 01100111 <---(103)
42: 01000010 <---( 66)
00: 00000000 <---(  0)
1E: 00011110 <---( 30)
............

      而trace_enc.txt中的部分内容为:

@0     SPS: profile_idc                                       01000010 ( 66)

@8     SPS: constrained_set0_flag                                    0 (  0)
@9     SPS: constrained_set1_flag                                    0 (  0)
@10    SPS: constrained_set2_flag                                    0 (  0)
@11    SPS: reserved_zero                                        00000 (  0)
@16    SPS: level_idc                                         00011110 ( 30)
............

       经本人严格对比后发现:myData.txt中的内容和trace_enc.txt中的内容实际上是高度一致的. 下面参照trace_enc.txt的内容来解析码流. (由于博客的篇幅限制,故只作简要解析)

00000000

00000000

00000000

00000001       这些表示接下来的比特流是一个NALU(SPS对应的NALU)

0                     forbidden_zero = 0--->0

11                   nal_ref_idc = 11--->3

00111             nal_unit_type = 00111--->7 

       对照trace_enc.txt, 继续分析:

01000010          @0    SPS: profile_idc                                       01000010 ( 66)

0                        @8     SPS: constrained_set0_flag                                    0 (  0)

0                        @9     SPS: constrained_set1_flag                                    0 (  0)

0                        @10    SPS: constrained_set2_flag                                    0 (  0)

00000                @11   SPS: reserved_zero                                        00000 (  0)

00011110          @16   SPS: level_idc                                         00011110 ( 30)

111100010110000101100010011000

10                      补齐  (SODBtoRBSP)          第一帧共有3处补齐,从代码中可以看到SODBtoRBSP函数刚好被调用3次

 

00000000000000000000000000000001011010001100100010100001010000111000   PPS

1000                  补齐  (SODBtoRBSP) 

 

00000000000000000000000000000001011001011000100010000100000000100        SliceHeader

 

*********** Pic: 0 (I/P) MB: 0 Slice: 0 **********

1100011011000010111110000000000000111010110111011111100000000000111001111100000110000010111011100110000111100100001010000111011011001011010010001001001011101010011111000010110000001101001100000000111111111111001111100101111100101100000000010101001101010010111010011100110011011100000100101010101000110100000010110010001011001011100100001001010110011100010000001001111110000000100001000001011001001001100011010101100001001001111000001110000000010010000011101001000110111111001000100011101101010011111010100001010011011110100001110101101011111100110010100110010011110001011000000111001001000001100000000101110100011011010010011111001011100111000000100000101000111010100001000101000111001011111111

 

*********** Pic: 0 (I/P) MB: 98 Slice: 0 **********

110011101110111010010111011111111001000010101110011011011100110111010001101010000011101001001101010010110000100011010010011100011011111101110010011100101100001001000001100101010000110011011010010001110011010111110101100000111000111100000100110011111110101001010000010100000011001101000001100110011111101011101000101100111010110000000101100000101010011010000101001111010101110100111000000110101101000110010110001110000110000011111110111000110110011000001110011101

100                  补齐  (SODBtoRBSP)

 

转载地址:http://fjzti.baihongyu.com/

你可能感兴趣的文章
Kubernetes集群搭建之CNI-Flanneld部署篇
查看>>
k8s web终端连接工具
查看>>
手绘VS码绘(一):静态图绘制(码绘使用P5.js)
查看>>
手绘VS码绘(二):动态图绘制(码绘使用Processing)
查看>>
基于P5.js的“绘画系统”
查看>>
《达芬奇的人生密码》观后感
查看>>
论文翻译:《一个包容性设计的具体例子:聋人导向可访问性》
查看>>
基于“分形”编写的交互应用
查看>>
《融入动画技术的交互应用》主题博文推荐
查看>>
链睿和家乐福合作推出下一代零售业隐私保护技术
查看>>
Unifrax宣布新建SiFAB™生产线
查看>>
艾默生纪念谷轮™在空调和制冷领域的百年创新成就
查看>>
NEXO代币持有者获得20,428,359.89美元股息
查看>>
Piper Sandler为EverArc收购Perimeter Solutions提供咨询服务
查看>>
RMRK筹集600万美元,用于在Polkadot上建立先进的NFT系统标准
查看>>
JavaSE_day14 集合中的Map集合_键值映射关系
查看>>
异常 Java学习Day_15
查看>>
Mysql初始化的命令
查看>>
MySQL关键字的些许问题
查看>>
浅谈HTML
查看>>