2015年3月23日 星期一

H.264



原文 http://blog.sina.com.cn/s/blog_8fb8cd4801018yyo.html


----------------------
前言
-----------------------
        H264是新一代的編碼標準,以高壓縮高質量和支持多種網絡的流媒體傳輸著稱,在編碼方面,我理解的他的理論依據是:參照一段時間內圖像的統計結果表明,在相鄰幾幅圖像畫面中,一般有差別的像素只有10%以內的點,亮度差值變化不超過2%,而色度差值的變化只有1%以內。所以對於一段變化不大圖像畫面,我們可以先編碼出一個完整的圖像幀A,隨後的B幀就不編碼全部圖像,只寫入與A幀的差別,這樣B幀的大小就只有完整幀的1/10或更小!B幀之後的C幀如果變化不大,我們可以繼續以參考B的方式編碼C幀,這樣循環下去。這段圖像我們稱為一個序列(序列就是有相同特點的一段數據),當某個圖像與之前的圖像變化很大,無法參考前面的幀來生成,那我們就結束上一個序列,開始下一段序列,也就是對這個圖像生成一個完整幀A1,隨後的圖像就參考A1生成,只寫入與A1的差別內容。
        在H264協議裡定義了三種幀,完整編碼的幀叫I幀,參考之前的I幀生成的只包含差異部分編碼的幀叫P幀,還有一種參考前後的幀編碼的幀叫B幀。
        H264採用的核心算法是幀內壓縮和幀間壓縮,幀內壓縮是生成I幀的算法,幀間壓縮是生成B幀和P幀的算法。



----------------------
序列的說明
----------------------
        在H264中圖像以序列為單位進行組織,一個序列是一段圖像編碼後的數據流,以I幀開始,到下一個I幀結束。
        一個序列的第一個圖像叫做IDR圖像(立即刷新圖像),IDR圖像都是I幀圖像。H.264引入IDR圖像是為了解碼的重同步,當解碼器解碼到IDR圖像時,立即將參考幀隊列清空,將已解碼的數據全部輸出或拋棄,重新查找參數集,開始一個新的序列。這樣,如果前一個序列出現重大錯誤,在這裡可以獲得重新同步的機會。IDR圖像之後的圖像永遠不會使用IDR之前的圖像的數據來解碼。
        一個序列就是一段內容差異不太大的圖像編碼後生成的一串數據流。當運動變化比較少時,一個序列可以很長,因為運動變化少就代表圖像畫面的內容變動很小,所以就可以編一個I幀,然後一直P幀、B幀了。當運動變化多時,可能一個序列就比較短了,比如就包含一個I幀和3、4個P幀。


-----------------------
三種幀的說明
-----------------------
I幀:幀內編碼幀,I幀表示關鍵幀,你可以理解為這一幀畫面的完整保留;解碼時只需要本幀數據就可以完成(因為包含完整畫面)

I幀特點: 
1.它是一個全幀壓縮編碼幀。它將全幀圖像信息進行JPEG壓縮編碼及傳輸; 
2.解碼時僅用I幀的數據就可重構完整圖像; 
3.I幀描述了圖像背景和運動主體的詳情; 
4.I幀不需要參考其他畫面而生成; 
5.I幀是P幀和B幀的參考幀(其質量直接影響到同組中以後各幀的質量); 
6.I幀是幀組GOP的基礎幀(第一幀),在一組中只有一個I幀; 
7.I幀不需要考慮運動矢量; 
8.I幀所佔數據的信息量比較大。 

P幀:前向預測編碼幀。P幀表示的是這一幀跟之前的一個關鍵幀(或P幀)的差別,解碼時需要用之前緩存的畫面疊加上本幀定義的差別,生成最終畫面。(也就是差別幀,P幀沒有完整畫面數據,只有與前一幀的畫面差別的數據)

P幀的預測與重構:P幀是以I幀為參考幀,在I幀中找出P幀“某點”的預測值和運動矢量,取預測差值和運動矢量一起傳送。在接收端根據運動矢量從I幀中找出P幀“某點”的預測值並與差值相加以得到P幀“某點”樣值,從而可得到完整的P幀。 

P幀特點: 
1.P幀是I幀後面相隔1~2幀的編碼幀; 
2.P幀採用運動補償的方法傳送它與前面的I或P幀的差值及運動矢量(預測誤差); 
3.解碼時必須將I幀中的預測值與預測誤差求和後才能重構完整的P幀圖像; 
4.P幀屬於前向預測的幀間編碼。它只參考前面最靠近它的I幀或P幀; 
5.P幀可以是其後面P幀的參考幀,也可以是其前後的B幀的參考幀; 
6.由於P幀是參考幀,它可能造成解碼錯誤的擴散; 
7.由於是差值傳送,P幀的壓縮比較高。 

B幀:雙向預測內插編碼幀。B幀是雙向差別幀,也就是B幀記錄的是本幀與前後幀的差別(具體比較複雜,有4種情況,但我這樣說簡單些),換言之,要解碼B幀,不僅要取得之前的緩存畫面,還要解碼之後的畫面,通過前後畫面的與本幀數據的疊加取得最終的畫面。B幀壓縮率高,但是解碼時CPU會比較累。 

B幀的預測與重構 B幀以前面的I或P幀和後面的P幀為參考幀,“找出”B幀“某點”的預測值和兩個運動矢量,並取預測差值和運動矢量傳送。接收端根據運動矢量在兩個參考幀中“找出(算出)”預測值並與差值求和,得到B幀“某點”樣值,從而可得到完整的B幀。 

B幀特點 
1.B幀是由前面的I或P幀和後面的P幀來進行預測的; 
2.B幀傳送的是它與前面的I或P幀和後面的P幀之間的預測誤差及運動矢量; 
3.B幀是雙向預測編碼幀; 
4.B幀壓縮比最高,因為它只反映丙參考幀間運動主體的變化情況,預測比較準確; 
5.B幀不是參考幀,不會造成解碼錯誤的擴散。 

注:I、B、P各幀是根據壓縮算法的需要,是人為定義的,它們都是實實在在的物理幀。一般來說,I幀的壓縮率是7(跟JPG差不多),P幀是20,B幀可以達到50。可見使用B幀能節省大量空間,節省 出來的空間可以用來保存多一些I幀,這樣在相同碼率下,可以提供更好的畫質。


--------------------------------
壓縮算法的說明
--------------------------------
h264的壓縮方法:
1.分組:把幾幀圖像分為一組(GOP,也就是一個序列),為防止運動變化,幀數不宜取多。
2.定義幀:將每組內各幀圖像定義為三種類型,即I幀、B幀和P幀; 
3.預測幀:以I幀做為基礎幀,以I幀預測P幀,再由I幀和P幀預測B幀; 
4.數據傳輸:最後將I幀數據與預測的差值信息進行存儲和傳輸。
        幀內(Intraframe)壓縮也稱為空間壓縮(Spatial compression)。當壓縮一幀圖像時,僅考慮本幀的數據而不考慮相鄰幀之間的冗餘信息,這實際上與靜態圖像壓縮類似。幀內一般採用有損壓縮算法,由於幀內壓縮是編碼一個完整的圖像,所以可以獨立的解碼、顯示。幀內壓縮一般達不到很高的壓縮,跟編碼jpeg差不多。
  
        幀間(Interframe)壓縮的原理是:相鄰幾幀的數據有很大的相關性,或者說前後兩幀信息變化很小的特點。也即連續的視頻其相鄰幀之間具有冗餘信息,根據這一特性,壓縮相鄰幀之間的冗餘量就可以進一步提高壓縮量,減小壓縮比。幀間壓縮也稱為時間壓縮(Temporal compression),它通過比較時間軸上不同幀之間的數據進行壓縮。幀間壓縮一般是無損的。幀差值(Frame differencing)算法是一種典型的時間壓縮法,它通過比較本幀與相鄰幀之間的差異,僅記錄本幀與其相鄰幀的差值,這樣可以大大減少數據量。

        順便說下有損(Lossy )壓縮和無損(Lossy less)壓縮。無損壓縮也即壓縮前和解壓縮後的數據完全一致。多數的無損壓縮都採用RLE行程編碼算法。有損壓縮意味著解壓縮後的數據與壓縮前的數據不一致。在壓縮的過程中要丟失一些人眼和人耳所不敏感的圖像或音頻信息,而且丟失的信息不可恢復。幾乎所有高壓縮的算法都採用有損壓縮,這樣才能達到低數據率的目標。丟失的數據率與壓縮比有關,壓縮比越小,丟失的數據越多,解壓縮後的效果一般越差。此外,某些有損壓縮算法採用多次重複壓縮的方式,這樣還會引起額外的數據丟失。

2015年3月12日 星期四

不應該在建構函數中呼叫虛擬函數(Virtual function)


程式執行到一個衍生物件並開始建構時, 它的基底物件會先被建構起來並產生其VTABLE. 如果衍生類別有重新定義某個虛擬函數, 則衍生物件的建構函數會在該衍生物件的;VTABLE中更新被重新定義虛擬函數之位址. 這就是你不應該在建構函數中呼叫虛擬函數的原因: 衍生物件中被重定義的虛擬函數之位址可能還沒有被放入/更改到衍生物件之VTABLE中. 你可能執行到舊的虛擬函數.

完整原文

Modern C++ in embedded systems Part 1 : Myth and Reality


Modern C++ in embedded systems Part 1 : Myth and Reality
by 

References
A reference in C++ is physically identical to a pointer. Only the syntax is different. References are safer than pointers because they can’t be null, they can’t be uninitialized, and they can’t be changed to point to something else. The closest thing to a reference in C is a const pointer. Note that this is not a pointer to a const value, but a pointer that can’t be modified. Listing 3 shows a C++ code fragment with a reference. 

     // C++ reference example
     void accumulate(int& i, int j) {
         i += j;
     }


Listing 3: C++ reference


2015年3月7日 星期六

[NTFS, Win7] Symbolic link














mklink:Creates a symbolic link.
適用平台:Windows Server 2008, Windows Vista、Windows 7 等以上版本

Syntax:

mklink [[/d] | [/h] | [/j]]

Parameters:

ParameterDescription
/dCreates a directory symbolic link. By default, mklink creates a file symbolic link.
/hCreates a hard link instead of a symbolic link.
/jCreates a Directory Junction.
Specifies the name of the symbolic link that is being created.
Specifies the path (relative or absolute) that the new symbolic link refers to.
/?Displays help at the command prompt.

Examples:
mklink /d C:\Users\eric_c_huang\Desktop\AAA C:\Document\ABC
在桌面上建立名為 AAA 的 symbolic link ,連結至 C:\Document  的 ABC 目錄…

建立 symbolic link 需要管理者權限,否則會出現「you do not have sufficient privilege to perform this operation」的錯誤訊息

2012年5月23日 星期三

How to find variants of "%f" ?

In UltraEdit, how to find C-language printf format specifier %f variants ?

such as
sprintf(str,"FPS=%2.2f",fps);
printf("%f\n",fps);
... and so on.

Mofi@Vienna :
With UltraEdit regular expression engine run a Find with Match Case enabled with search string
^%[0-9.]++f
 

2012年1月16日 星期一

[XP] 關閉"最近的文件"(Recent)

1. 開始 > 執行 > GPEDIT.MSC
2. 使用者設定 > 系統管理範本 >「開始」功能表和工作列
3. 「不保留最近開啟文件的記錄」此選項的值改成「已啟用」> 確定
4. 重開機

WinHEX launch takes too long time.

Possible solutions (or):
1. Close anti-virus daemons.
2. Delete files created after this situation occurs in WinHEX folder.
3. Delete files inside C:\Documents and Settings\user\ associated to WinHEX.