生活随笔
收集整理的這篇文章主要介紹了
开启 JM 的 trace 功能
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[JM代碼] 開啟 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里面都沒有看到,暈了好久! 今天終于明白了 | |
| ? |
總結
以上是生活随笔為你收集整理的开启 JM 的 trace 功能的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。