生活随笔
收集整理的這篇文章主要介紹了
开启 JM 的 trace 功能
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
[JM代碼] 開(kāi)啟 JM 的 trace 功能 本帖最后由 firstime 于 2009-6-15 11:16 AM 編輯
城里漢子說(shuō)過(guò): trace文件對(duì)分析碼流結(jié)構(gòu)很有效。我說(shuō)的是trace文件,不是一步一步跟蹤,就是編解碼同時(shí)生成的 trace_enc.txt 這個(gè)文件,里面對(duì)每個(gè)比特位是什么都有記錄。
本論壇的帖子“H.264編解碼手冊(cè)”里的 H.264_MPEG-4 AVC Reference Software Manua 建議大家去看看。這個(gè)文件對(duì)編解碼的所有參數(shù)做了詳細(xì)介紹
trace_enc.txt 是編碼的文件 trace_dec.txt 是解碼的文件??
運(yùn)行編解碼器之后才會(huì)生成相應(yīng)的 trace 文件
在代碼中有個(gè)參數(shù)要設(shè)置一下才行:
在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# 發(fā)表于 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)
以此為例,對(duì)應(yīng)碼流中的 NALU 單元為:67??58??00??1E.........,其中 0X67 是 NALU 頭,從 0X58 開(kāi)始為 NALU 體
第一行含義:從 NALU 體第 0 個(gè)比特開(kāi)始的比特串為 SPS 中的語(yǔ)法元素 profile_idc ,其十進(jìn)制表示值為 88 。標(biāo)準(zhǔn) 7.3.2.1 小節(jié)表格中規(guī)定該語(yǔ)法元素編碼方式為U(8),因此 88 按 U(無(wú)符號(hào)數(shù)) 方式編碼的二進(jìn)制值為 1011000。 因?yàn)樵撜Z(yǔ)法元素編碼方式為 U(8),即采用 8 比特?zé)o符號(hào)數(shù)編碼,因此,最終在碼流中應(yīng)該補(bǔ)足 8 位,結(jié)果為 01011000;
第二行含義:從 NALU 體第 8 個(gè)比特開(kāi)始的比特串為 SPS 中的語(yǔ)法元素 constrained_set0_flag ,其十進(jìn)制表示值為 0 。標(biāo)準(zhǔn) 7.3.2.1 小節(jié)表格中規(guī)定該語(yǔ)法元素編碼方式為 U(1),因此 0 按 U(1) 方式編碼的二進(jìn)制值為 0;
第三行含義:從 NALU 體第 9 個(gè)比特開(kāi)始的比特串為 SPS 中的語(yǔ)法元素 constrained_set1_flag ,其十進(jìn)制表示值為 0 。標(biāo)準(zhǔn) 7.3.2.1 小節(jié)表格中規(guī)定該語(yǔ)法元素編碼方式為 U(1),因此 0 按 U(1) 方式編碼的二進(jìn)制值為 0;
第四行含義:從 NALU 體第 10 個(gè)比特開(kāi)始的比特串為 SPS 中的語(yǔ)法元素 constrained_set2_flag ,其十進(jìn)制表示值為 0 。標(biāo)準(zhǔn) 7.3.2.1 小節(jié)表格中規(guī)定該語(yǔ)法元素編碼方式為 U(1),因此 0 按 U(1) 方式編碼的二進(jìn)制值為 0;
第五行含義:從 NALU 體第 11 個(gè)比特開(kāi)始的比特串為 SPS 中的語(yǔ)法元素 constrained_set3_flag ,其十進(jìn)制表示值為 0 。標(biāo)準(zhǔn) 7.3.2.1 小節(jié)表格中規(guī)定該語(yǔ)法元素編碼方式為 U(1),因此 0 按 U(1) 方式編碼的二進(jìn)制值為 0;
第六行含義:從 NALU 體第 12 個(gè)比特開(kāi)始的比特串為 SPS 中的語(yǔ)法元素 reserved_zero,其十進(jìn)制表示值為 0 。標(biāo)準(zhǔn) 7.3.2.1 小節(jié)表格中規(guī)定該語(yǔ)法元素編碼方式為 U(4),因此 0 按 U(無(wú)符號(hào)數(shù)) 方式編碼的二進(jìn)制值為 0; 因?yàn)樵撜Z(yǔ)法元素編碼方式為 U(4),即采用 4 比特?zé)o符號(hào)數(shù)編碼,因此,最終在碼流中應(yīng)該補(bǔ)足 4 位,結(jié)果為 0000;
第七行含義:從 NALU 體第 16 個(gè)比特開(kāi)始的比特串為 SPS 中的語(yǔ)法元素 level_idc,其十進(jìn)制表示值為 30 。標(biāo)準(zhǔn) 7.3.2.1 小節(jié)表格中規(guī)定該語(yǔ)法元素編碼方式為U(8),因此 30 按 U(無(wú)符號(hào)數(shù)) 方式編碼的二進(jìn)制值為 11110; 因?yàn)樵撜Z(yǔ)法元素編碼方式為 U(8),即采用 8 比特?zé)o符號(hào)數(shù)編碼,因此,最終在碼流中應(yīng)該補(bǔ)足 8 位,結(jié)果為 00011110;
將上述結(jié)果的二進(jìn)制串連起來(lái): 01011000? ?0? ?0? ?0? ?0? ?0000? ?00011110
按每 8 個(gè)比特劃分為一段: 01011000? ?00000000? ?00011110
將其轉(zhuǎn)換為 16 進(jìn)制: 58??00??1E
實(shí)際傳輸?shù)拇a流就是上面的二進(jìn)制串,而我們用 ultraedit 看到的碼流正是其 16 進(jìn)制表示方式
[ 本帖最后由 firstime 于 2006-12-15 11:57 AM 編輯 ] | |
| ? |
| ? |
3# 謝謝牛人啊! | 嘿嘿,這個(gè)是我很想看到的啊,十分感謝啊!! | |
| ? |
| ? |
4# 舉個(gè)例子 這個(gè)里面怎么那么多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的編碼信息急需都沒(méi)有 那應(yīng)該在解碼的trace里面 但是解碼的trace怎么打開(kāi) 怎么看skip解碼的時(shí)候copy的是那一塊 skip模式的 運(yùn)動(dòng)矢量要不要編碼的? 編碼的運(yùn)動(dòng) | |
| ? |
| ? |
5# 1:這個(gè)里面怎么那么多MVD? —— @108392 mb_type (P_SLICE) ( 7, 4) =? ?1? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? 1 (??1)
這行說(shuō)明該宏塊為 P_L0_L0_16x8 類(lèi)型宏塊(參見(jiàn)標(biāo)準(zhǔn)表 7-13 第 2 行) 既然宏塊被分割為兩個(gè) 16*8,那么當(dāng)然就有兩個(gè) MV 值(上面 8 個(gè) 4*4 共用一個(gè),下面 8 個(gè) 4*4 共用一個(gè)),當(dāng)然就有兩個(gè)的 MVD 值,即: @108393mvd_l0 (0) =? ?2??(org_mv? ?2 pred_mv? ?0)? ?? ?? ?? ?? ?010110 (??2) @108399mvd_l0 (1) =? ?0??(org_mv? ?0 pred_mv? ?0)? ?? ?? ?? ?? ?? ?? ? (??0)
同時(shí)可見(jiàn)該宏塊并不是 SKIP 宏塊,因?yàn)樵摵陦K mb_type??= 1
2:解碼的trace怎么打開(kāi) ——解碼 trace 打開(kāi)方式與編碼相同
3:skip模式的 運(yùn)動(dòng)矢量要不要編碼 ——請(qǐng)你先認(rèn)真學(xué)習(xí)本論壇帖子“[原創(chuàng)] Skip、Direct宏塊淺析” 。而且請(qǐng)你注意不要混淆概念。H.264 中的預(yù)測(cè)模式?jīng)]有 skip,因此不能說(shuō)“一個(gè)宏塊是 skip 模式”,只能說(shuō)“一個(gè)宏塊是 skip 類(lèi)型”。skip 類(lèi)型宏塊采用的是 direct 模式。
4:怎么看skip解碼的時(shí)候copy的是那一塊 ——每個(gè)宏塊都有一個(gè)參考索引。該參考索引表示了當(dāng)前宏塊解碼的參考圖像是參考列表中的哪一幅。然后解碼器根據(jù)這個(gè)參考索引和計(jì)算出的 MV 確定 copy 參考圖像中的哪個(gè) “宏塊”。這是由兩個(gè)條件一起決定的一個(gè)計(jì)算過(guò)程。在 trace 文件中是直接看不出來(lái)的。
5:僅僅靠分析 trace 文件是不夠的,也是很累的。請(qǐng)你用一段已壓縮碼流跟蹤解碼過(guò)程。看樣子你有點(diǎn)急躁。急躁是解決不了問(wèn)題的。另外,看樣子你的這個(gè)碼流采用的是 CABAC 熵編碼方式。請(qǐng)你試驗(yàn)時(shí)候先采用 CAVLC 熵編碼的碼流。應(yīng)該從易到難,先通過(guò) CAVLC 理解了 skip 再研究 CABAC 的情況。
[ 本帖最后由 firstime 于 2007-9-16 03:38 PM 編輯 ] | |
| ? |
| ? |
6# 非常感謝!!!!!!!!!!!!!!!!! 多謝firsttime的精辟解疑釋惑! 受益 匪淺 | |
| ? |
| ? |
8# 找出skip塊的copy的塊 可真麻煩阿 找了好久了 跟蹤編碼部分 什么都沒(méi)有找到 對(duì)于skip宏塊 是不是運(yùn)動(dòng)矢量在解碼端才會(huì)出現(xiàn)(根據(jù)相鄰塊的運(yùn)動(dòng)矢量預(yù)測(cè)出來(lái)),然后copy該運(yùn)動(dòng)矢量對(duì)應(yīng)的macroblock
跟蹤解碼部分 半天了 還沒(méi)有發(fā)現(xiàn)在哪一部分針對(duì)skip解碼
| |
| ? |
| ? |
9# 本帖最后由 firstime 于 2009-6-15 06:47 PM 編輯
你用我加了注釋的 JM 解碼器代碼,進(jìn) interpret_mb_mode_B 或 interpret_mb_mode_P 函數(shù)就能看見(jiàn)了。interpret_mb_mode_B 的第二個(gè) if 就是 B_skip , interpret_mb_mode_P 的第一個(gè) if 就是 P_skip。
[ 本帖最后由 firstime 于 2006-12-16 10:32 AM 編輯 ] | |
| ? |
| ? |
10# 發(fā)表于 2006-12-18 11:48 AM | 只看該作者 樓主 強(qiáng) ! 早就想看trace了 ,打開(kāi)開(kāi)關(guān),居然不知道trace是存成文件的,害的我在cmd里面都沒(méi)有看到,暈了好久! 今天終于明白了 | |
| ? |
總結(jié)
以上是生活随笔為你收集整理的开启 JM 的 trace 功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。