本文共 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#endiftrace_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/