x264函數調用關系圖

1 encoder

?

2 slice write

?

3?analyse

?



FFMPEG中MPEG-2編解碼函數調用關系圖

1 Encoder

?

(函數調用從左到右,下同;圖片顯示不全時,請下載顯示)

?

2 P幀運動估計流程圖

3 B幀運動估計流程圖

?

?

4 decoder

?

?

ffmpeg的mpeg2編碼I幀代碼解讀

首先說一下編碼的函數層次:
MPV_encode_picture
—encode_thread
———encode_mb_hq
————encode_mb(編碼一個宏塊)
——————encode_mb_internal(編碼I幀宏塊,在這個函數里面選擇不同的宏塊編碼器)
————————mpeg1_encode_mb(由于YUV的比例不一樣,4:4:4或者4:2:0,進行宏塊編碼)
——————————mpeg1_encode_mb_internal(對宏塊進行編碼)
————————————mpeg1_encode_block(對一個block進行編碼,注意這里面的宏塊都是經過DCT和量化之后的數據):這個函數就是最需要看的咯:包括DC編碼和AC編碼,會選擇不同的碼表進行編碼(詳細過程看代碼)

其次,所有的編碼后的數據都是通過函數put_bits寫到比特流中

第三,以上的代碼解讀都不包括諸如圖片頭之類的編碼,相應的格式編碼可以在相應層次中的函數里面找到。

第 四,libavcodec/mpegvideo_enc.c里面MPV_encode_init對編碼進行初始化,主要是初始化,根據 avctx->codec_id選擇不同的編碼標準,進行不同的初始化,在656行,根據s->dct_quantize選擇了DCT系數和 量化器(因為不同的編碼標準,量化器是不一樣的),然而在程序里面,統一由函數指針指向的函數dct_quantize完成

第五,在encode_mb_internal里面首先,進行了DCT和量化,然后進行霍夫曼編碼——根據(s->codec_id)選擇不同的編碼器。DCT & quantize在1629行。

第五,在mpeg1_encode_block函數里面的block并沒有進行zig-zag掃描,而 zig-zag掃描的過程,是在不斷的產生新的索引index,這個步驟是在885行的j = s->intra_scantable.permutated[i];完成的,j就是zig-zag掃描之后的索引,根據j索引出block中的數據。

簡單的說一下編碼的過程:
1.初始化,包括選擇DCT和量化器等等
2.編碼一個圖像(picture),將picture分成若干的mb(MacroBlock),這個時候要寫入相應的圖片頭信息
3. 編碼I幀MacroBlock,將MacroBlock分成若個小的block,由于YUV的比例不一樣,因此每次需要編碼的block的數量也是不一樣 的,在函數mpeg1_encode_mb里面,就區分了CHROMA_420和其他格式擁有不同的block數量。
4.編碼block,一個block包含三個編碼對象:DC系數,AC系數(level)和游程長度。DC系數單獨用差分編碼,AC和run
聯合在一起編碼。這個過程都是在函數mpeg1_encode_block里面完成的。
1.MpegEncContext這個struct類型,一定要吃透,雖然代碼是用C寫得,但是寫得很C++,這個MpegEncContext其實可以看做一個C++的類,里面定義了很多指針,這些指針指又指向了一些strcut,而這個struct其實相當于C++的成員函數,成員函數的初始化,一般是在XX_init函數里面初始化的。這一點,可以在后面的敘述中體現出來。

2.再說一下編碼的過程,encode_mb_internal函數,做了MarcoBlock的編碼,在1629行,開始做DCT&quant,1686行,開始做霍夫曼編碼,而霍夫曼編碼,對不同的標準來說,碼表是不一樣的,因此在1687行做了一個switch的選擇,mpeg1和mpeg2,都是用的相同的mpeg1_encode_mb函數進行block的編碼,而block內的編碼,在以前的筆記中已經提到,過程這里不重復。

3.現在說DCT&quant,其中,1635行s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow);,就是做DCT&quant。正如第1點中說的,dct_quantize本來只是MpegEncContext中的一個元素,類型為指針,指向一個struct,而這個struct就相當于C++里面的成員函數。現在,我們知道了在這個地方,相當于調用了一個成員函數,做了DCT&quant這件事情,接下來,討論這個成員函數在哪里初始化的。

4.在Mpegvideo.c的MPV_encode_init函數里面,對編碼所需要的一些“成員函數”進行了初始化。前面一堆東西,是做編碼器的選擇。在第656行,dct_quant這成員函數被初始化為dct_quant_c這個函數。于是,接下去找dct_quant_c這個函數的定義。發現,3649行,又調用了dsp.fdct這個成員函數,做離散余弦變換。接下來找dsp.fdct這個成員函數的初始化地方。
這個非常費勁,我找了半天才找到——在函數dsputil_init里面做了fdct的初始化,一步一步的跟蹤調用關系,可以發現過程是這樣的:
MPV_encode_init調用MPV_common_init,再調用dsputil_init,在dsputil_init里面初始化了fdct,而MPV_encode_init緊接著,執行前面提到的dct_quantize的初始化。
至此,整個初始化完成。
1.完整的初始化過程,函數調用關系如下:
encode_init
MPV_encode_init:里面要根據不同的Codec_ID來配置一些數據
MPV_common_init:基本的結構體的初始化,在此之前,高度寬度等變量已經設置好了
dsputil_init初始化了fdct而MPV_encode_init緊接著,執行前面提到的dct_quantize的初始化。
然而,這個時候量化表并沒有初始化,量化表的初始化是用函數ff_set_qscale進行的。而這個函數的調用關系,在第二點中講到
2.編碼器運行的函數調用關系如下:
MPV_encode_picture:頂層函數
encode_picture:編碼一副圖像,這個時候首先要編碼圖像頭,調用mpeg1_encode_picture_header函數,然后在2912行,通過s指針調用了encode_thread函數,開始編碼
encode_thread里面,調用了ff_set_qscale,進行qscale的初始化,然后調用encode_mb_hq進行編碼
encode_mb_hq調用encode_mb進行宏塊編碼
encode_mb調用encode_mb_internal進行幀內編碼
encode_mb_internal調用mpeg1_encode_mb進行編碼
mpeg1_encode_mb調用mpeg1_encode_mb_internal進行編碼
mpeg1_encode_mb_internal調用mpeg1_encode_block進行16x16的塊編碼
3.關于header
mpeg1_encode_picture_header調用了mpeg1_encode_sequence_header寫入了序列的頭
mpeg1_encode_sequence_header調用了ff_write_quant_matrix這里面,包括了要填的量化表的寫入,這個量化表是用戶自定義的。在后面又調用了ff_mpeg1_encode_slice_header。
ff_mpeg1_encode_slice_header又調用了寫header,寫qscale的函數,寫文件頭。
下面解釋一個block的編碼以及編碼碼表
1.首先編碼的是DC系數,在函數encode_dc里面進行。由于DC系數的碼表有兩個,分別針對Y幀和(Cr,Cb)幀。編碼的時候,編碼的是非負的系數,但是原始的DC系數有正有負,因此需要做一個映射。這一個映射,在encode_dc里面,首先就用
if(((unsigned) (diff+255)) >= 511)
分成了兩部分,表示正負數的映射。而碼表的選擇,是根據component變量來選擇的。整個編碼過程和標準完全一樣。但是代碼中diff為正和為負的情況,表面上采用了不同的編碼方法,但是實質上是完全一樣的。
mpeg1_lum_dc_uni的初始化在ff_mpeg1_encode_init里面完成,查看這個初始化過程,其實就是一個編碼過程。
2.對于其他系數的編碼,根據標準,存在兩種不同的情況:
a.(level,run)較小的情況,直接進行查表
b.(level,run)較大的情況,進行所謂的換碼編碼,首先是寫入一個Escape code,然后在加上level和run
因此,首先需要判斷(level,run)是否足夠大,代碼中用
if (alevel <= mpeg1_max_level[0][run])
來解決這個問題。mpeg1_max_level這個矩陣的構成在ff_mpeg1_encode_init函數中,通過調用init_rl函數來實現,至于這個具體怎么初始化的,很容易看懂的(如果這個都看不懂,那ffmpeg代碼也就不要想看懂了)
3.在一個block的最后,需要編碼end of block,也是通過查表
4.現在解釋碼表,所有要用到的vlc的碼表存放在文件mpeg12data.c里面,
mpeg1_vlc就是標準中的碼表B-14
mpeg2_vlc就是標準中的碼表B-15
兩個碼表,第一列表示碼字,第二列表示碼字長度,對照標準上面的碼表,很容易發現這兩個數組的構成方法(具體是什么,看一下就知道了,很容易的)
看懂了這里,也就很容易看懂在mpeg12enc.c里面對于其他系數的編碼了
最后要說的是,ffmpeg的代碼寫的非常的晦澀,寫得非常的不對稱,比如encode_dc就是這樣的,碼表的初始化也比較混亂,因而看起來很費勁


MPEG-4 AVC/H.264 信息

作者:haibara????來源:pcicp.com????DVDrip制作????2006-6-15 14:13:02?

?

本FAQ系列由(haibara)翻譯,期間受到kaito_mkid(pcicp)幫助,在此感謝,由于Newbie的關系,如有翻譯錯誤,還請各位指出,由Doom9的bond編撰的原文

譯者注:基本專業名稱我都以小括號形式加以解釋,詳細信息請自行查閱資料。

什么是MPEG-4?

MPEG-4(ISO 14496)是由制定了我們熟知的MPEG-1(MP3, VCD)和MPEG-2(DVD, SVCD)標準,并力于使各種音頻/視頻壓縮格式和更多內容標準化的國際標準化組織(International Organization for Standardization/ISO)的工作組,即運動圖像專家組(Moving Picture Experts Group/MPEG)發展的廣泛的開放標準。
本質上MPEG-4標準不僅把目標定為標準化某些有發展前途的產品(例如達到DVD性能),而且含蓋了一個能讓產品供應商根據需要選擇適當標準去執行的廣泛的次級標準。

MPEG-4標準,如上所說,被分成許多不同的次級標準,在Doom9里我們使用者可能最感興趣的部分如下:
- ISO 14496-1(Systems/系統),動畫/交互性(類DVD菜單)
- ISO 14496-2(Video/視頻),如Advanced Simple Profile(ASP/高級簡單類),由XviD, DivX5, 3ivx...執行
- ISO 14496-3(Audio/音頻),Advanced Audio Coding(AAC/先進音頻編碼)
- ISO 14496-10(Video/視頻),Advanced Video Coding(AVC/進階視頻編碼),著名有H.264
- ISO 14496-14(Container/容器),MP4容器格式(使用.mp4作擴展名)
- ISO 14496-17(Subtitles/字幕),MPEG-4時標文本字幕格式

這些信息頁面正力于提供這些標準的大部分有用的信息,尤其是作為焦點的MPEG-4 ASP和AVC/H.264。


與封閉格式如Micro$oft的Windows Media相比,象MPEG-4一樣的開放標準有什么可能的優勢?

開放標準的一個好處是當創建產品時允許向所有人開放并遵循它。因此我們已經有許多不同的符合MPEG-4標準并可互相兼容的產品。
其次是互通性大范圍的產品選擇性,一個開放標準導致競爭,對顧客而言這意味著產品在競爭市場中能更好地提高品質,更少的價格和更關注顧客需求

但不要忘記這也許對我們來說最重要的一點:
一個開放標準允許開源發展,例如我們熟知的XviD。

ISO 14496-10 (Video) - 進階視頻編碼(Advanced Video Coding/AVC)

有著AVC/H.264的MPEG-4標準定義了一個擁有最新,最高技術的實用的,充滿尖端科技的視頻編碼格式。

2003年,ISO的MPEG(Moving Pictures Experts Group/運動圖像專家組)與聯合國(United Nations/UNO)下設的ITU(International Telecommunication Union/國際電信聯盟)的VCEG(Video Coding Experts Group/視頻編碼專家組)這2大組織最終完成并共同規定了AVC/H.264視頻編碼標準,其中后者曾標準化H.263格式(現主用于視頻會議)。
AVC/H.264標準它自身是由MPEG和VCEG的專家構成的Joint Video Team(JVT/聯合視頻組)發展的。

由MPEG來看,該標準被叫做MPEG-4 Part 10(ISO 14496-10);由ITU來看,它叫做H.264(ITU的公文號) 其中作為后者已廣泛流傳開來。
新標準選擇Advanced Video Coding(AVC/進階視頻編碼)作為“官方”名 - 因為對應視頻的音頻格式是Advanced Audio Coding(AAC/先進音頻編碼)。


AVC/H.264 Profile

AVC/H.264定義了4種不同的Profile(類):Baseline(基線類), Main(主要類), Extended(擴展類)和High Profile(高端類)(它們各自下分成許多個 層):

- Baseline Profile 提供I/P幀,僅支持progressive(逐行掃描)和CAVLC
- Extended Profile 提供I/P/B/SP/SI幀,僅支持progressive(逐行掃描)和CAVLC
- Main Profile 提供I/P/B幀,支持progressive(逐行掃描)和interlaced(隔行掃描),提供CAVLC或CABAC
- High Profile (也就是FRExt)在Main Profile基礎上新增:8x8 intra prediction(8x8 幀內預測), custom quant(自定義量化), lossless video coding(無損視頻編碼), 更多的yuv格式(4:4:4...)

只有未來會告訴我們哪一種框架和工具最可能被用于DVD備份,但是我猜想會是有著以下的工具大力幫助的Main和/或High Profile(同樣請核實 MPEG-4 ASP的工具描述,除了GMC,所有的工具在AVC下都是可用的):

CAVLC/CABAC:
AVC/H.264定義了2種先進的重構數據流(包括macroblock-type(宏塊), motionvectors(運動矢量) + reference-index(參考索引)...)的熵編碼工具,一舉超越MPEG-4 ASP:
Context-Adaptive Variable Length Coding(CAVLC/上下文自適應變長編碼)和 Context-Adaptive Binary Arithmetic Coding(CABAC/上下文自適應二進制算術編碼)
CABAC,與AVC/H.264中只是默認算法的CAVLC(也叫UVLC)相比,是個壓縮率更強大的算法,據說能額外降低10-15%的比特率(特別在高碼率)。CABAC(同CAVLC一樣)是一種無損算法,因此不會降低質量,但會減緩編碼和解碼速度。

Loop/Deblocking Filter(循環/去塊濾波器):
與預處理濾波器(例如通過avisynth作用于輸入端),或后處理濾波器(通過解碼器作用于最終輸出端)相反,循環濾波器在編碼過程中對每楨進行濾波,編碼完成后被用于下一楨的參考。它能消除塊效應,尤其在低碼率時,但同樣會減緩編碼和解碼速度。

Variable Block Sizes/Macroblock Partitions(塊大小可變/宏塊劃分):
與MPEG-4 ASP(僅Inter4V/4MV能作16x16和8x8塊變換)相比,AVC/H.264把動態搜尋精度(Motion Search Precision)提高到4x4(包含的步驟有8x4...)。子塊大小是自適應/可變的,一個優秀的編碼器應能對每個宏塊明智地作出最恰當的劃分大小決定。

Multiple Reference Frames(多重參考楨):
與MPEG-4 ASP(僅允許當前楨的前一楨作為參考楨)相比,AVC/H.264使用幀間搜索方式并提供成倍的參考楨選擇,它意味著AVC/H.264編碼能決定是否只是簡單地參考前一楨或甚至參考比前楨更過去的楨。因此(例如某個P楨能參考最近I楨前的某楨)不得不提出一種新型楨型:IDR楨,是種其后的楨不允許參考其前的楨的I楨。使用多重參考楨會減慢編碼和解碼速度并且可能導致只能在IDR楨剪切。

Weighted Prediction(加權預測):
有了加權預測就能對參考楨進行加權(例如你能測量前一幅圖象的亮度程度)。它特別有助于在那些隨時可能淡入或淡出的場景中前后圖象極為相似,只是畫面變暗的圖象的處理。WP對于同時出現淡入及淡出的圖象沒有效果(例如當圖象從一個場景轉到另一個場景就會同時出現淡入及淡出)。

Rate Distortion Optimisation(RDO/碼率-失真/損耗最佳化):
只要編碼器不得不在眾多選擇中作出絕擇時,RDO允許選擇最有效的編碼方式(例如面臨采用楨間/楨內的動態搜尋的決定...)
RDO不是AVC/H.264本身定義的工具,它是第一個由H.264參考軟件引入的工具,可謂一種新的途徑。其他的編碼也能利用RDO,如XviD'的VHQ模式能使用RDO


AVC/H.264與其他流行的視頻編碼格式的比較測評:
?

現有的AVC/H.264編碼

可用于終端用戶的AVC/H.264執行者有 x264, Nero, Apple, Sorenson, Elecard, Moonlight, VSS, mpegable, Envivio, Hdot264 ( binary), DSPR, JM (參考軟件) ( binary), ffmpeg, Philips, FastVDO, Skal, Sony和 更多

編碼器

- x264:第一個公開的可使用High Profile的編碼器,開源(GPL)( 源碼),使用VFW的有: x264vfw, ffdshow(輸出.avi),命令行的: x264cli(輸出raw的.mp4), mencoder(輸出raw的.avi)(Doom9的 MeGUI)或 ffmpeg
x264支持2pass, CABAC, 循環濾波, 多重B幀, 雙向參考(B-Reference), 多重參考楨, 4x4 P幀塊變換, 8x8 B幀塊劃分, 失真信號化(anamorphic signalling)和High Profile:8x8 dtc(離散余弦變換)與幀內預測, 無損視頻編碼和自定義無損量化矩陣(custom quant matrix)
- NeroDigital AVC: Nero Recode2內含,輸出為.mp4
ND AVC支持2pass, CABAC, 自適應循環濾波, 多重B幀, 多重參考楨, 加權預測, 8x8 B幀塊劃分, 16x16 B幀塊劃分, 自適應量化(高度Psy)
- Sorenson: Sorenson Squeeze 4內含,輸出.mp4,
Sorenson支持2pass, 最大2連續B幀, 雙向參考, 循環濾波和多重Slice
- Apple: Quicktime 7內含,輸出.mp4, .3gp和.mov,編碼速度很慢
支持2pass, 最大1連續B幀, 循環濾波(0,0), 8x8 P幀塊變換, 8x8 B幀塊變換, 4x4 I幀塊變換, 自適應量化, 5級Slice, 沒有CABAC, 沒有加權預測, 沒有多重參考楨
- JM:此AVC參考軟件v9.3版提供Main和High Profile:B/SP幀, CABAC, 循環濾波器, 4x4 塊劃分, 多重參考楨, 自適應量化, 差錯修復(Error Resilience), RDO, 無損視頻編碼, 自定義量化), 比率控制(Rate Control)等...
- Hdot264:由doom9會員charact3r發展的開源(GPL)的VFW版參考軟件,仍然以很老的參考軟件(JM 4.0c)為基礎
- VSS:免費的VFW編碼器(可預覽5天),以參考編碼器為基礎
- Elecard: Elecard Mobile Converter內含,輸出.mp4, MainConcept's v2 encoder也內含,輸出.264和.mpg PS/TS
不再公開的:
- Moonlight:Moonlight的 OneClick Compressor v1.1和CyberLink的 PowerEncoder內含,輸出.mpg
Moonlight支持1pass(VBR/CBR/預設 量化), CABAC, 循環濾波, 最大2連續B幀, 8x8 B幀塊劃分, 自適應量化, 自動調整PAR(Pixel Aspect Ratio/象素縱橫比), 隔行掃描
- MainConcept:免費的編碼器(有水印),輸出.264和.mpg PS/TS
1pass(CBR/VBR/預設 量化), P幀重排(P-Frame Reorder), CABAC, 循環濾波, 多重B-Vops(Bidirectional Video Object Planes/雙向視頻對象平面), 多重參考楨, 4x4 P幀塊劃分), PAR, RDO
- mpegable:提供試用有限的免費VFW編碼器(不以參考軟件為基礎),不支持YV12
mpegable支持僅限P幀的1pass(預設量化), 8x8 P幀塊劃分, 只支持CAVLC, 循環濾波
- Envivio: 4Coder內含,輸出.mp4

解碼器 ( 比較測評)

- ffmpeg:開源(LGPL),包含在 ffdshow(VFW和DShow編碼器), mplayer和 VideoLAN等
支持B幀, 雙向參考, CABAC, 循環濾波, 加權預測和High Profile (8x8 dct與幀內預測, 無損視頻編碼)
- Apple:Quicktime 7支持AVC解碼,支持.mp4/.mov,解碼速度很慢
僅支持最大1連續B幀, CABAC, 不作后幀參考的循環濾波, 多重B幀和隔行掃描
- NeroDigital AVC:Recode2附帶DShow解碼器和.mp4 Parser
支持Main和High Profile
- VSS:VFW解碼器 (預覽5天) 和 DShow解碼器 (限制30天)
VSS DShow支持.avi (支持VSSH和H264 fourcc), CABAC, 循環濾波, B幀
- Elecard: Elecard's MPEG Player v4.0和 MainConcept's v2 encoder內含
- Envivio:有個名叫EnvivioTV的非免費AVC DShow解碼器,(從2.0版開始,當前版本為2-1-181)支持混合AVC的.mp4
- Philips: AVC Alliance播放器內含免費的DShow AVC解碼器(只支持raw AVC)
- FastVDO:有時間限制(每個視頻文件5分鐘)的High Profile DShow解碼器
- Pegasus: 這里有發展不成熟的DShow AVC解碼器
- Basic AVC Decoder用C編寫,是一所大學的工程,見 這里
不再公開的:
- Moonlight:DShow解碼器/Parser支持混合AVC的.mpg, .mp4和.264 Moonlight's MPEG Player v3.0內含
支持Main和High Profile
- MainConcept:v1預覽版提供免費DShow AVC解碼器(有水印) 并且Parser支持AVC和.mpg PS/TS
- mpegable:提供試用有限的VFW解碼器 (可用于DShow),支持.avi (支持 DAVC fourcc)


預覽樣本

NeroDigital: mp4, mp4
Sorenson: mp4
AVC Alliance: raw
Moonlight: raw/中碼率, raw/低碼率, raw, mpg
FastVDO: raw/high profile
Apple: mov
Videosoft: avi, avi/新, avi/老
Lead: ogm


當前AVC/H.264的爭論

- 互通性:大多數執行者支持多種容器格式:
.mp4:由MPEG-4標準(ISO 14496-15)定義的AVC容器,Apple, Nero, Sorenson, Envivio, Elecard/Moonlight和x264都支持
.mpg PS/TS:由MPEG-2標準(ISO 13818-1, AMD3)定義的AVC容器,Mainconcept和Elecard/Moonlight支持
.avi:采取AVC-in-AVI的方式非標準,因此會造成不兼容問題。 AVI和VFW的局限(如關于B幀或任意幀的編碼順序),混合這兩種格式混合會完全阻礙AVC提供的所有可能特性的執行,因此可能降低質量,或至少降低處理速度和互通性,其競爭性也因此下降。當前VSS和x264(mencoder 和vfw)支持使用AVI
.264/.h264:未混合入容器的原始數據流。JM參考軟件, x264cli, mencoder和mainconcept都可輸出

- 速度:當前一些執行者編碼器速度不敢恭維,依然只有x264和NeroDigital's AVC的編碼器看上去能提供不俗的速度與品質。但這不會改變AVC是種先進的視頻編碼方式的事實。所以老的CPU編解碼AVC會非常耗時


MPEG-4 AVC/H.264的硬件應用化 - HD-DVD/藍光(Blu-ray)

DVD論壇(DVD Forum)和藍光光盤協會(Blu-ray Disc Association)正在討論能支持高清晰(High Definition)內容(存儲容量完全超過當前的DVD)下一代DVD格式的繼承人選:HD-DVD和BD-ROM

據 這里報道HD-DVD會強制采用MPEG-4 AVC/H.264,而藍光支持老早被MPEG-4 AVC/H.264 High Profile納入- 這里

因此AVC/H.264極有可能成為下一代視頻格式,會被廣泛地使用和支持,就象今天MPEG-2(用于DVD)的情形一樣

FFMPEG 學習筆記


一 Encoder函數調用圖


1 avcodec_encode_video
? |___ avcodec_check_dimensions
? |___ avctx->codec->encode(for mpeg-2 call MPV_encode_picture)
????? |___ init_put_bits(for multiple thread)
????? |___ load_input_picture(copy data from input pic_arg)
????? |___ select_input_picture(I,B,P)
????? |___ MPV_frame_start
????? |___ encode_picture
????? |???????????????? |___ s->avctx->execute
????? |???????????????? |___ encode_thread
????? |????????????????????? |___ encode_mb
????? |????????????????????? |___ MPV_decode_mb
????? |
????? |
????? |___ MPV_frame_end


x264中的Decoder

在早期的x264版本中,包括decoder和encoder兩部分,后來不知道出于什么原因,decoder部分的代碼沒有再繼續維護,這部分代碼一直保留到了20061009的版本(?X264_BUILD 53);但因為期間encoder部分的代碼有較大的改動,包括數據結構的變化,導致兩部分代碼只有在較低版本時才可以同時正常編譯。

?

我使用#define X264_BUILD 0x0002版本的代碼進行了測試。發現Decoder代碼存在以下問題:

1 僅支持BaseLine的解碼,因為其中沒有B幀和CABAC的解碼部分。

2 代碼中有兩個BUG需要自己解決一下。

?? a. x264_realloc函數中,把

??????????? *( (int*) ( (uint8_t*) p ) - sizeof( void ** ) -
???????????????????????? sizeof( int ) );

?????? 改為

??????????? *( (int*) (( (uint8_t*) p ) - sizeof( void ** ) -
???????????????????????? sizeof( int ) ));

??? b. x264_slice_header_ref_pic_reordering函數中,把

??? if( h->i_ref0 > h->pps->i_num_ref_idx_l0_active )
??? {
??????? h->i_ref0 = h->pps->i_num_ref_idx_l0_active;
??? }
??? if( h->i_ref1 > h->pps->i_num_ref_idx_l1_active )
??? {
??????? h->i_ref1 = h->pps->i_num_ref_idx_l1_active;
??? }
改為:

?if( h->i_ref0 > h->sh.i_num_ref_idx_l0_active )
?{
??h->i_ref0 = h->sh.i_num_ref_idx_l0_active;
?}
?if( h->i_ref1 > h->sh.i_num_ref_idx_l1_active )
?{
??h->i_ref1 = h->sh.i_num_ref_idx_l1_active;
?}

?

?

3 其它一些頭文件的改動,因為兩部分代碼中有一些同名的文件,需要在include時加上相應的目錄名。

x264 代碼下載信息

2011-08-11

1 不同版本的x264下載地址:http://download.videolan.org/pub/videolan/x264/snapshots/

2 x264從20061010起(即這個版本x264-snapshot-20061010-2245.tar.bz2)不再支持decoder代碼。

H.264/AVC中CAVLC編碼方法簡介

H.264/AVC中CAVLC編碼方法簡介

?

一 名詞

?????? TotalCoeffs:全部非零系數個數。(0~16)

?????? TotalZeros:最后一個非零系數前的零的個數。

?????? TrailingOnes:拖尾系數(即1)的個數。(0~3)

?????? NC:當前塊值。除色度的直流系數外(常數-1),其它系數類型NC值是根據當前左邊4x4塊的非零系數數目(NA)和當前塊上面4x4的非零系數的數目(NB求得的。

?????? 計算NC的值

上面的塊(NB)

左達的塊(NA)

NC

X

X

(NA+NB)/2

X

?

NA

?

X

NB

?

?

0

?????? 選擇非零系數個數和拖尾系數個數的編碼表格(表格見畢書附錄):

NC

表格

0<=NC<2

變長表格1

2<=NC<4

變長表格2

5<=NC<8

變長表格3

NC=-1

變長表格4

NC>=8

定長表格

?

?

二 編碼過程

?????? 1. 對TotalCoeffs和TrailingOnes進行組合編碼,稱為Coeff_token。

?????? 2. 對拖尾系數的符號進行編碼,+為1,-為0,從右向左。

?????? 3. 對非零系數(不包括拖尾系數,拖尾系數已經編碼)進行編碼,從右向左。

?????? 4. 對TotalZeros進行編碼。

?????? 5. 對非零系數前的零的個數進行編碼,從右向左,最后一個(從左邊數第一個)非零系數前的零的個數不需要編碼(剩下的零都是這個位置的)。

以下4x4塊為例(畢書P123,原例有誤):

0? 0 ?-1 ?0

5? 2? 0? 0

3? 0? 0? 0

1? 0? 0? 0

Z掃描完成后: 0,0,5,3,2,-1,0,0,0,1…

No

元素

數值

編碼

說明

1

Coeff_token

TotalCoeffs=5,TrailingOnes=2

0000101

TotalCoeffs ,和TrailingOnes的組合進行編碼

2-1

TrailingOnes_sign_flag

+

1

拖尾系數的符號,從右向左

2-2

TrailingOnes_sign_flag

0

?

3-1

Level(2)

1(suffixLength=0)

1

?

3-2

Level(1)

3(suffixLength=1)

0010

?

3-3

Level(0)

5(suffixLength=1)

000010

?

4

Total_zeros

5

101

?

5-1

Run_before(4)

ZeroLeft=5, run_before=3

010

?

5-2

Run_before(3)

ZeroLeft=2, run_before=0

1

?

5-3

Run_before(2)

ZeroLeft=2, run_before=0

1

?

5-4

Run_before(1)

ZeroLeft=2, run_before=0

1

?

5-5

Run_before(0)

ZeroLeft=2, run_before=2

?

最后一個不需要編碼

?

編碼輸出:00001011010010000010101010111


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453962.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453962.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453962.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Tensorflow 加載預訓練模型和保存模型

使用tensorflow過程中&#xff0c;訓練結束后我們需要用到模型文件。有時候&#xff0c;我們可能也需要用到別人訓練好的模型&#xff0c;并在這個基礎上再次訓練。這時候我們需要掌握如何操作這些模型數據。看完本文&#xff0c;相信你一定會有收獲&#xff01; 一、Tensorfl…

在 ActiveReports 中嵌入 Spread 控件

Spread 是一款很出色的表格控件&#xff0c;Spread 可以使開發人員把具有兼容 Microsoft Excel 的電子表格添加到程序中。ActiveReports 提供了一個非常靈活的、簡單的報表環境。下面將展示怎樣在 ActiveReports 中使用 Spread for WinForm。和其他三方控件一樣&#xff0c;Spr…

sort()函數、C++

Sort&#xff08;&#xff09;函數是c一種排序方法之一&#xff0c;它使用的排序方法是類似于快排的方法&#xff0c;時間復雜度為n*log2(n) &#xff08;1&#xff09;Sort函數包含在頭文件為#include<algorithm>的c標準庫中。 II&#xff09;Sort函數有三個參數&#x…

python waitkey_python中VideoCapture(),read(),waitKey()的使用

有以下程序import cv2cap cv2.VideoCapture(0)while cap.isOpened():ret,frame cap.read()cv2.imshow(frame,frame)c cv2.waitKey(1)if c 27:breakcap.release()cv2.destroyAllWindows()說明&#xff1a;程序段里&#xff0c;1、cv2.VideoCapture()函數&#xff1a;cap cv…

深度學習案例之 驗證碼識別

本項目介紹利用深度學習技術&#xff08;tensorflow&#xff09;&#xff0c;來識別驗證碼&#xff08;4位驗證碼&#xff0c;具體的驗證碼的長度可以自己生成&#xff0c;可以在自己進行訓練&#xff09; 程序分為四個部分 1、生成驗證碼的程序&#xff0c;可生成數字字母大…

windows下使用pthread庫

最近在看《C多核高級編程》這本書&#xff0c;收集了些有用的東西&#xff0c;方便在windows下使用POSIX標準進行Pthread開發&#xff0c;有利于跨平臺。 -------------------------------------------------- windows下使用pthread庫時間:2010-01-27 07:41來源:羅索工作室 作…

day 05 多行輸出與多行注釋、字符串的格式化輸出、預設創建者和日期

msg"hello1 hello2 hello3 " print(msg) 顯示結果為&#xff1a; # " "只能進行單行的字符串 多行字符串用 ,前面設置變量&#xff0c;可以用 表示多行 msghello1 hello2 hello3print(msg) 顯示結果為&#xff1a; 當然如果沒有設置變量&#xff0c;…

python數值計算guess_【python】猜數字game,旨在提高初學者對Python循環結構的使用...

import random #引入生成隨機數的模塊需求&#xff1a;程序設定生成 1-20 之間的一個隨機數&#xff0c;讓用戶猜日期&#xff1a;2019-10-21作者&#xff1a;xiaoxiaohui目的&#xff1a;猜數字game&#xff0c;旨在提高初學者對Python 變量類型以及循環結構的使用。secretNu…

調試九法-總體規則

調試規則規則1 理解系統規則2 制造失敗規則3 不要想&#xff0c;而要看規則4 分而治之規則5 一次只改一個地方規則6 保持審計跟蹤規則7 檢查插頭規則8 獲得全新觀點規則9 如果你不修復bug&#xff0c;它將依然存在轉載于:https://www.cnblogs.com/uetucci/p/7987805.html

深度學習之循環神經網絡(Recurrent Neural Network,RNN)

遞歸神經網絡和循環神經網絡 循環神經網絡&#xff08;recurrent neural network&#xff09;&#xff1a;時間上的展開&#xff0c;處理的是序列結構的信息&#xff0c;是有環圖遞歸神經網絡&#xff08;recursive neural network&#xff09;&#xff1a;空間上的展開&#…

從北京回來的年輕人,我該告訴你點什么?

前言 就在上周末&#xff0c;我與公眾號里的一個當地粉絲見面了&#xff0c;一起吃了頓飯&#xff0c;順便聊了聊。先來簡單交代下我們這位粉絲&#xff08;以下簡稱小L&#xff09;的經歷以及訴求。 小L之前在北京八維研修學院培訓的PHP&#xff0c;因為家庭原因&#xff0c;沒…

Linphone編譯【轉載】

Linphone依賴太多的庫&#xff0c;以致于稍有疏失&#xff0c;就會在編譯&#xff0c;運行出錯&#xff0c;都是由于依賴庫安裝的問題。 1 基礎知識 1.1 動態庫的連接 很多人安裝完庫后&#xff0c;configure依然報告這個庫沒有。這是對linux動態庫知識匱乏造成&#xff0c;也就…

python助教的面試題_python面試題----持續更新中

為什么學習Python&#xff1f;通過什么途徑學習的Python&#xff1f;Python和Java、PHP、C、C#、C等其他語言的對比&#xff1f;python 解釋型語言&#xff0c;語法簡潔優雅。C C 編譯型語言&#xff0c;先編譯后運行&#xff0c;偏底層。簡述解釋型和編譯型編程語言&#xff1…

python3模塊: requests

Python標準庫中提供了&#xff1a;urllib等模塊以供Http請求&#xff0c;但是&#xff0c;它的 API 太渣了。它是為另一個時代、另一個互聯網所創建的。它需要巨量的工作&#xff0c;甚至包括各種方法覆蓋&#xff0c;來完成最簡單的任務。 發送GET請求 import urllib.requestf…

SUSE12系統安裝及LVM設置詳解

SUSE12自定義安裝跟以往版本差不多&#xff0c;只是調整了一些功能安裝順序&#xff0c;例如網絡設置放到很靠前&#xff0c;SUSE11的時候幾乎是在后半部分&#xff0c;自定義分區也調整到網絡設置之后&#xff0c;入口設置也隱秘&#xff0c;如果是熟悉suse11安裝&#xff0c;…

在windows下編譯FFMPEG-最新2009版本

轉】在windows下編譯FFMPEG-最新2009版本2010-11-17 18:50大家可以看到&#xff0c;此篇之前有很多個版本的“在windows下編譯FFMPEG”&#xff0c;那些都是我在網上搜羅來的&#xff0c;在看了無數篇那些過期的、有借鑒價值的文章后&#xff0c;我終于成功在windows下編譯出了…

CentOS7 安裝nginx

1、官網下載安裝包 官網&#xff1a;http://nginx.org/en/download.html 選擇適合Linux的版本&#xff0c;這里選擇最新的版本&#xff0c;下載到本地后上傳到服務器或者centos下直接wget命令下載。 切換到/usr/local目錄&#xff0c;下載軟件包 # cd /usr/local # wget htt…

dvwa如何打開_DVWA詳細 安裝

Wamp就是Windows Apache Mysql PHP集成安裝環境&#xff0c;即在window下的apache、php和mysql的服務器軟件。PHP擴展、Apache模塊&#xff0c;開啟/關閉鼠標點點就搞定&#xff0c;再也不用親自去修改配置文件了&#xff0c;WAMP它會去做。再也不用到處詢問php的安裝問題了&am…

CentOS7安裝OpenFire

下載openfire wget http://download.igniterealtime.org/openfire/openfire-3.9.3-1.i386.rpm安裝openfire yum install -y /home/openfire-3.9.3-1.i386.rpm安裝運行庫 yum install -y glibc.i686添加開啟啟動 chkconfig openfire on啟動openfire服務 systemctlstart openfire…

CentOS 安裝 php

大致步驟&#xff1a;下載–解壓–編譯–安裝–配置 php官網&#xff1a; https://www.php.net/releases/ php5.6連接地址 http://hk1.php.net/get/php-5.6.36.tar.gz/from/this/mirror http://hk2.php.net/get/php-5.6.36.tar.gz/from/this/mirror 1.安裝php 所依賴的軟件 yu…