开启 JM 的 trace 功能
本帖最后由 firstime 于 2009-6-15 11:16 AM 编辑
城里汉子说过: trace文件对分析码流结构很有效。我说的是trace文件,不是一步一步跟踪,就是编解码同时生成的 trace_enc.txt 这个文件,里面对每个比特位是什么都有记录。
本论坛的帖子“H.264编解码手册”里的 H.264_MPEG-4 AVC Reference Software Manua 建议大家去看看。这个文件对编解码的所有参数做了详细介绍
trace_enc.txt 是编码的文件 trace_dec.txt 是解码的文件
运行编解码器之后才会生成相应的 trace 文件
在代码中有个参数要设置一下才行:
在defines.h文件中把
#if defined _DEBUG #define TRACE 0 //!< 0:Trace off 1:Trace on #else
改成 #if defined _DEBUG #define TRACE 1 //!< 0:Trace off 1:Trace on #else
[ 本帖最后由 firstime 于 2007-3-9 08:17 PM 编辑 ] | |
|
|
2# 发表于 2006-12-15 11:09 AM | 只看该作者 如何阅读 trace 文件 @0 SPS: profile_idc 01011000 ( 88) @8 SPS: constrained_set0_flag 0 ( 0) @9 SPS: constrained_set1_flag 0 ( 0) @10 SPS: constrained_set2_flag 0 ( 0) @11 SPS: constrained_set3_flag 0 ( 0) @12 SPS: reserved_zero 0000 ( 0) @16 SPS: level_idc 00011110 ( 30)
以此为例,对应码流中的 NALU 单元为:67 58 00 1E.........,其中 0X67 是 NALU 头,从 0X58 开始为 NALU 体
第一行含义:从 NALU 体第 0 个比特开始的比特串为 SPS 中的语法元素 profile_idc ,其十进制表示值为 88 。标准 7.3.2.1 小节表格中规定该语法元素编码方式为U(8),因此 88 按 U(无符号数) 方式编码的二进制值为 1011000。 因为该语法元素编码方式为 U(8),即采用 8 比特无符号数编码,因此,最终在码流中应该补足 8 位,结果为 01011000;
第二行含义:从 NALU 体第 8 个比特开始的比特串为 SPS 中的语法元素 constrained_set0_flag ,其十进制表示值为 0 。标准 7.3.2.1 小节表格中规定该语法元素编码方式为 U(1),因此 0 按 U(1) 方式编码的二进制值为 0;
第三行含义:从 NALU 体第 9 个比特开始的比特串为 SPS 中的语法元素 constrained_set1_flag ,其十进制表示值为 0 。标准 7.3.2.1 小节表格中规定该语法元素编码方式为 U(1),因此 0 按 U(1) 方式编码的二进制值为 0;
第四行含义:从 NALU 体第 10 个比特开始的比特串为 SPS 中的语法元素 constrained_set2_flag ,其十进制表示值为 0 。标准 7.3.2.1 小节表格中规定该语法元素编码方式为 U(1),因此 0 按 U(1) 方式编码的二进制值为 0;
第五行含义:从 NALU 体第 11 个比特开始的比特串为 SPS 中的语法元素 constrained_set3_flag ,其十进制表示值为 0 。标准 7.3.2.1 小节表格中规定该语法元素编码方式为 U(1),因此 0 按 U(1) 方式编码的二进制值为 0;
第六行含义:从 NALU 体第 12 个比特开始的比特串为 SPS 中的语法元素 reserved_zero,其十进制表示值为 0 。标准 7.3.2.1 小节表格中规定该语法元素编码方式为 U(4),因此 0 按 U(无符号数) 方式编码的二进制值为 0; 因为该语法元素编码方式为 U(4),即采用 4 比特无符号数编码,因此,最终在码流中应该补足 4 位,结果为 0000;
第七行含义:从 NALU 体第 16 个比特开始的比特串为 SPS 中的语法元素 level_idc,其十进制表示值为 30 。标准 7.3.2.1 小节表格中规定该语法元素编码方式为U(8),因此 30 按 U(无符号数) 方式编码的二进制值为 11110; 因为该语法元素编码方式为 U(8),即采用 8 比特无符号数编码,因此,最终在码流中应该补足 8 位,结果为 00011110;
将上述结果的二进制串连起来: 01011000 0 0 0 0 0000 00011110
按每 8 个比特划分为一段: 01011000 00000000 00011110
将其转换为 16 进制: 58 00 1E
实际传输的码流就是上面的二进制串,而我们用 ultraedit 看到的码流正是其 16 进制表示方式
[ 本帖最后由 firstime 于 2006-12-15 11:57 AM 编辑 ] | |
|
|
4# 举个例子 这个里面怎么那么多MVD? ********* Pic: 33 (I/P) MB: 51 Slice: 0 ********** @108388mb_skip_flag 0000 ( 1) @108392mb_type (P_SLICE) ( 7, 4) = 1 1 ( 1) @108393ref_idx_l0 = 0 ( 0) @108393mvd_l0 (0) = 2 (org_mv 2 pred_mv 0) 010110 ( 2) @108399mvd_l0 (1) = 0 (org_mv 0 pred_mv 0) ( 0) @108399CBP ( 7, 4) = 31 00001001111 ( 31) @108410transform size 8x8 flag = 1 11 ( 1) @108412Delta QP ( 7, 4) = 0 ( 0) @108412Luma8x8 sng( 0) level = -2 run = 0 ( -2) @108412Luma8x8 sng( 1) level = 0 run = 0 00001001111 ( 0) @108423Luma8x8 sng( 0) level = -3 run = 0 ( -3) @108423Luma8x8 sng( 1) level = 0 run = 1 000001001110 ( 0) @108435Luma8x8 sng( 0) level = -2 run = 0 ( -2) @108435Luma8x8 sng( 1) level = 0 run = 1 1001010 ( 0) @108442Luma8x8 sng( 0) level = -3 run = 0 ( -3) @108442Luma8x8 sng( 1) level = 0 run = 1 001001001 ( 0) @108451DC Chroma 0: level = 1 run = 0 ( 1) @108451DC Chroma 1: level = 0 run = 2 1010 ( 0) @108455DC Chroma 0: level = -1 run = 0 ( -1) @108455DC Chroma 1: level = 0 run = 1 0101 ( 0) CABAC terminating bit = 0 ======================================================================= *********** Pic: 33 (I/P) MB: 53 Slice: 0 ********** @108461mb_skip_flag ( 0) CABAC terminating bit = 0 思skip的编码信息急需都没有 那应该在解码的trace里面 但是解码的trace怎么打开 怎么看skip解码的时候copy的是那一块 skip模式的 运动矢量要不要编码的? 编码的运动 | |
|
|
5# 1:这个里面怎么那么多MVD? —— @108392 mb_type (P_SLICE) ( 7, 4) = 1 1 ( 1)
这行说明该宏块为 P_L0_L0_16x8 类型宏块(参见标准表 7-13 第 2 行) 既然宏块被分割为两个 16*8,那么当然就有两个 MV 值(上面 8 个 4*4 共用一个,下面 8 个 4*4 共用一个),当然就有两个的 MVD 值,即: @108393mvd_l0 (0) = 2 (org_mv 2 pred_mv 0) 010110 ( 2) @108399mvd_l0 (1) = 0 (org_mv 0 pred_mv 0) ( 0)
同时可见该宏块并不是 SKIP 宏块,因为该宏块 mb_type = 1
2:解码的trace怎么打开 ——解码 trace 打开方式与编码相同
3:skip模式的 运动矢量要不要编码 ——请你先认真学习本论坛帖子“[原创] Skip、Direct宏块浅析” 。而且请你注意不要混淆概念。H.264 中的预测模式没有 skip,因此不能说“一个宏块是 skip 模式”,只能说“一个宏块是 skip 类型”。skip 类型宏块采用的是 direct 模式。
4:怎么看skip解码的时候copy的是那一块 ——每个宏块都有一个参考索引。该参考索引表示了当前宏块解码的参考图像是参考列表中的哪一幅。然后解码器根据这个参考索引和计算出的 MV 确定 copy 参考图像中的哪个 “宏块”。这是由两个条件一起决定的一个计算过程。在 trace 文件中是直接看不出来的。
5:仅仅靠分析 trace 文件是不够的,也是很累的。请你用一段已压缩码流跟踪解码过程。看样子你有点急躁。急躁是解决不了问题的。另外,看样子你的这个码流采用的是 CABAC 熵编码方式。请你试验时候先采用 CAVLC 熵编码的码流。应该从易到难,先通过 CAVLC 理解了 skip 再研究 CABAC 的情况。
[ 本帖最后由 firstime 于 2007-9-16 03:38 PM 编辑 ] | |
|
|
6# 非常感谢!!!!!!!!!!!!!!!!! 多谢firsttime的精辟解疑释惑! 受益 匪浅 | |
|
|
太感谢了阿 | |
|
|
8# 找出skip块的copy的块 可真麻烦阿 找了好久了 跟踪编码部分 什么都没有找到 对于skip宏块 是不是运动矢量在解码端才会出现(根据相邻块的运动矢量预测出来),然后copy该运动矢量对应的macroblock
跟踪解码部分 半天了 还没有发现在哪一部分针对skip解码
| |
|
|
9# 本帖最后由 firstime 于 2009-6-15 06:47 PM 编辑
你用我加了注释的 JM 解码器代码,进 interpret_mb_mode_B 或 interpret_mb_mode_P 函数就能看见了。interpret_mb_mode_B 的第二个 if 就是 B_skip , interpret_mb_mode_P 的第一个 if 就是 P_skip。
[ 本帖最后由 firstime 于 2006-12-16 10:32 AM 编辑 ] | |
|
|
10# 发表于 2006-12-18 11:48 AM | 只看该作者 楼主 强 ! 早就想看trace了 ,打开开关,居然不知道trace是存成文件的,害的我在cmd里面都没有看到,晕了好久! 今天终于明白了 | |
|
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/455220.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!