王小根,趙海武,李國平,滕國偉,王國中
(上海大學通信與信息工程學院,上海 200072)
視頻編碼中每一幀的編碼數(shù)據(jù)通常是不一樣的,特別是在利用視頻序列的時域相關(guān)性進行壓縮編碼時,采用幀內(nèi)模式編碼的幀和采用幀間模式編碼的幀的編碼數(shù)據(jù)量會差別很大。而信道的數(shù)據(jù)傳輸率經(jīng)常是穩(wěn)定而有限的,或者說從傳輸?shù)慕嵌?,希望視頻編碼數(shù)據(jù)的速率越穩(wěn)定越好,最好是恒定碼率。因此,利用緩沖區(qū)對視頻編碼數(shù)據(jù)的速率進行平滑是必須的。在 MPEG-2[1]和 AVS[2]等標準中,都規(guī)定了碼流緩沖區(qū)校驗?zāi)P?,來?guī)范碼流的緩沖。
緩沖區(qū)的本質(zhì)是用延遲來換取碼率的穩(wěn)定,因為緩沖必然會帶來延遲。緩沖的數(shù)據(jù)越多,碼率越穩(wěn)定,延遲也越大。然而,在電視廣播等應(yīng)用中延遲是不能太大的,當然,在其他應(yīng)用中延遲可以很大,但也是有限制的。在延遲有限,也即緩沖區(qū)有限的情況下,就需要對每一幀的編碼數(shù)據(jù)量進行控制,以達到碼率穩(wěn)定的目的。因此,緩沖和延遲最終需要用碼率控制來實現(xiàn)[3]。
本文對MPEG-2和AVS的碼流緩沖模型進行了比較詳細的分析。
首先,討論解碼器何時開始解碼的問題。解碼器開始解碼的時刻和碼流中的bbv_delay,bbv_buffer_size以及l(fā)ow_delay等3個信息相關(guān)。
當bbv_delay!=0xFFFF時,某一幀(包括開始解碼的第一幀)的解碼時刻等于該幀的編碼數(shù)據(jù)進入緩沖區(qū)的時刻加上該幀的bbv_delay(bbv_delay出現(xiàn)在每一幀的頭部),這是最常見的情況。
當bbv_delay==0xFFFF時,第一幀的解碼時刻是緩沖區(qū)被充滿的時刻。緩沖區(qū)被充滿的時間由bbv_buffer_size和bit_rate共同確定。事實上,緩沖區(qū)被充滿的時間等于二者的商。顯然,這種情況下,從第一幀的編碼數(shù)據(jù)開始進入緩沖區(qū)到第一幀被解碼的延遲是不確定的,它和第一幀以及后續(xù)若干幀的編碼數(shù)據(jù)量有關(guān)。編碼器要控制每一幀的編碼數(shù)據(jù)量,以保證開始解碼后緩沖區(qū)不會發(fā)生上溢或下溢。
當low_delay==1時(此時bbv_delay不應(yīng)等于0xFFFF),在每一幀的頭部會包含緩沖區(qū)檢測次數(shù)信息bbv_check_times。解碼器會按照規(guī)定的時間間隔檢測緩沖區(qū),檢測bbv_check_times+1次后解碼器開始解碼。通常bbv_check_times的值是0,即解碼器只檢查緩沖區(qū)1次,這和low_delay==0時是一樣的。
其次,討論開始解碼后每一幀的解碼時刻,也就是解碼時間間隔。
解碼時間間隔和解碼器的輸出是密切相關(guān)的。解碼器一旦開始輸出解碼圖像,就必須連續(xù)輸出解碼圖像,直到解碼過程結(jié)束。要想做到連續(xù)不間斷地輸出解碼圖像,就必須在輸出一個解碼圖像的同時解碼下一個圖像。因此,解碼器輸出圖像的時間間隔就是解碼圖像的時間間隔。假設(shè)第n幀圖像的解碼時刻是tn,輸出(或者說回放)第n幀圖像的時間是in,那么第n+1幀圖像的解碼時刻
通常情況下,輸出一幀的時間就是幀速率的倒數(shù),也稱幀時間間隔。輸出一場的時間就是場速率的倒數(shù),也稱場時間間隔。但是,由于存在3∶2下拉等幀速率的轉(zhuǎn)換,使得輸出一幀圖像(這里指的是碼流中的一幀,以幀頭開始,到下一幀的幀頭結(jié)束)的時間顯得有些復(fù)雜。
在AVS標準和MPEG-2標準中,圖像輸出顯示的時間和序列頭中的progressive_sequence(PSeq),progressive_frame(PF)以及幀頭中的 picture_structure(PStr),top_field_first(TFF),repeat_first_field(RFF)等幾個參數(shù)有關(guān)。為了讀者參考方便,本文將它們之間的關(guān)系整理如表1所示。其中NA表示不起作用,第一列是progressive_sequence和progressive_frame兩個參數(shù)的所有可能組合,最后一列是圖像的輸出情況。輸出一幀所需的時間是幀時間間隔,在數(shù)值上等于幀速率的倒數(shù),輸出一場所需的時間是場時間間隔,在數(shù)值上等于場速率倒數(shù)。
表1 圖像輸出顯示的時間和序列頭中參數(shù)關(guān)系
當low_delay==1時,解碼時間間隔更加復(fù)雜一些,因為碼流中可能存在大圖像。所謂大圖像,就是圖像頭中的bbv_check_times不是0的圖像。大圖像的檢測緩沖區(qū)時間間隔是幀速率的倒數(shù),其他圖像的解碼時間間隔和low_delay==0時一樣。所謂的“檢測緩沖區(qū)”,實際上就是“嘗試解碼”。
當解碼時刻到來時,被解碼圖像的所有編碼數(shù)據(jù)是瞬時移出碼流緩沖區(qū)的。一幀圖像的編碼數(shù)據(jù)包含的內(nèi)容,在AVS和MPEG-2標準中有明確的定義,這里不再贅述。第n幀圖像的編碼數(shù)據(jù)量用fn來表示。
顯然,對于一個視頻序列,每一幀的編碼數(shù)據(jù)是按照編碼順序進入緩沖區(qū)的。第n幀的編碼數(shù)據(jù)進入緩沖區(qū)的時間記為en。解碼器把收到第n幀開始碼后第一個比特的時刻記錄為en,它和編碼器把第n幀開始碼后第一個比特寫入碼流的時刻間隔一個固定的時間,這個時間是碼流通過信道產(chǎn)生的延遲。假設(shè)碼流通過信道產(chǎn)生的延遲是固定的,以此實現(xiàn)編碼器和解碼器的同步。
為方便起見,把第n幀頭部的bbv_delay所表示的時間記為dn。解碼器根據(jù)en和dn確定第一幀的解碼時刻,即
因為解碼器可能從碼流的中間某些位置開始解碼,所以上式中的序號仍然用n,而不是1。當bbv_delay==0xFFFF時,第一幀的解碼時刻是碼流緩沖區(qū)充滿的時刻,這時(2)可以表示為
式中:S是碼流緩沖區(qū)的容量,R是碼率,這兩個參數(shù)都是編碼器在序列頭中設(shè)定的。
第一幀的解碼時刻確定以后,根據(jù)式(1)確定后續(xù)各幀的解碼時刻,再根據(jù)各幀的解碼時刻,和各幀的延遲dn,倒推出各幀數(shù)據(jù)進入緩沖區(qū)的時刻,即
這是確定編碼數(shù)據(jù)進入緩沖區(qū)的時刻的過程。之所以這么復(fù)雜,是因為編碼數(shù)據(jù)進入緩沖區(qū)的速率是可變的。即不總是以序列頭中設(shè)置的速率R進入緩沖區(qū)。所以,無法根據(jù)fn和R來遞推每一幀的編碼數(shù)據(jù)進入緩沖區(qū)的時刻。
式(3)適用于解碼器。對于編碼器,具有一定的靈活性,即編碼器可以在滿足式(3)的前提下,調(diào)整dn和en。編碼器調(diào)整dn和en,是通過調(diào)整第n-1幀的編碼數(shù)據(jù)進入緩沖區(qū)的速率來實現(xiàn)的。第n-1幀的編碼數(shù)據(jù)進入緩沖區(qū)的速率高,就會早一些結(jié)束,從而第n幀的編碼數(shù)據(jù)就可以早一些開始,反之亦然。所以,這里有一個假設(shè),即第n-1幀數(shù)據(jù)結(jié)束進入緩沖區(qū)的時刻就是第n幀數(shù)據(jù)開始進入緩沖區(qū)的時刻。即
式中:τn-1是第 n-1 幀進入緩沖區(qū)所需的時間。
當某一幀的解碼時刻到來時,如果該幀的編碼數(shù)據(jù)沒有完全進入緩沖區(qū),則緩沖區(qū)發(fā)生下溢;如果在某個時刻,緩沖區(qū)沒有足夠的空間存放需要進入緩沖區(qū)的編碼數(shù)據(jù),則緩沖區(qū)發(fā)生上溢。
通常情況下,編碼器必須保證緩沖區(qū)不發(fā)生下溢和上溢。當bbv_delay==0xFFFF時,緩沖區(qū)不存在上溢,因為緩沖區(qū)被充滿以后,編碼數(shù)據(jù)可以等待,暫時不進入緩沖區(qū)。當low_delay==1時,如果某一幀的編碼數(shù)據(jù)量太大,造成該幀的編碼數(shù)據(jù)無法在按照式(1)遞推的解碼時刻完全進入緩沖區(qū),則編碼器可以將其設(shè)置成大圖像,其實就是讓解碼器進行額外的等待,以保證緩沖區(qū)不發(fā)生下溢。即使如此,緩沖區(qū)還是可能發(fā)生下溢,例如當某一幀的編碼數(shù)據(jù)量超過緩沖區(qū)的容量時,無論等待多少時間,緩沖區(qū)都會發(fā)生下溢。雖然當low_delay==1時,緩沖區(qū)下溢是允許的,但是會給解碼帶來很大的麻煩,而且標準中沒有規(guī)定緩沖區(qū)發(fā)生下溢時解碼器的處理方法,編碼器也就不知道解碼器會如何處理。因此,本文建議編碼器還是要避免緩沖區(qū)發(fā)生下溢。
編碼器可以通過控制每一幀的編碼數(shù)據(jù)量、控制每一幀的編碼數(shù)據(jù)進入緩沖區(qū)的時刻和設(shè)置合適的延遲來保證緩沖區(qū)不發(fā)生溢出。
首先考慮最常見的情況,即bbv_delay的值不是0xFFFF且low_delay的值不是1。如圖1所示(此時可能存在幀率轉(zhuǎn)換,可能是CBR,也可能是VBR)。
圖1 緩沖區(qū)模型示意圖
本節(jié)的目的是導出保證緩沖區(qū)不發(fā)生溢出的條件。
當?shù)趎-1幀編碼結(jié)束時,根據(jù)解碼時刻的遞推關(guān)系,可以確定第n幀的解碼時刻tn,即tn是已知的。根據(jù)編碼數(shù)據(jù)進入緩沖區(qū)的假設(shè)式(4),第n幀編碼數(shù)據(jù)開始進入緩沖區(qū)的時刻en也是已知的。根據(jù)(2)和(3),第n幀的延遲dn也是已知的。
由圖1可知,第n幀編碼數(shù)據(jù)在其解碼時刻到來之前全部進入緩沖區(qū)(即緩沖區(qū)不下溢)的充分必要條件是
對于解碼器,式(5)中的所有量都是已知的,可以通過上式檢驗緩沖區(qū)是否發(fā)生下溢。
緩沖區(qū)不上溢的條件是,在第n幀(n為任意值)的編碼數(shù)據(jù)被移出緩沖區(qū)之前,進入緩沖區(qū)的數(shù)據(jù)總量不超過緩沖區(qū)的容量S。從第n幀數(shù)據(jù)進入緩沖區(qū)到移出緩沖區(qū)的時間是dn,在這段時間之內(nèi),可能有若干幀數(shù)據(jù)進入緩沖區(qū)。然而,在編碼第n幀的時候,編碼器無法知道后續(xù)尚未編碼的幀的數(shù)據(jù)量。但是,編碼器知道后續(xù)各幀數(shù)據(jù)進入緩沖區(qū)的速率都小于等于R。所以,編碼器只需保證以下條件即可
但是,如前所述,當?shù)趎-1幀編碼結(jié)束時,dn已經(jīng)確定了,假設(shè)編碼器在編碼第n-1幀時已經(jīng)保證了dn<D,編碼第n幀需要做的,是保證dn+1<D。
當dn和D比較接近時,式(8)的右邊是一個正值,這就要求傳送第n幀數(shù)據(jù)的時間不能太短。
在CBR時,編碼器必須保證第n幀的數(shù)據(jù)量
在VBR時,編碼器可以通過降低第n幀數(shù)據(jù)進入緩沖區(qū)的速率來使式(8)成立,也可以像CBR時那樣通過控制fn來使式(8)成立。如圖2所示。其中rn表示第n幀數(shù)據(jù)進入緩沖區(qū)的速率。
圖2 VBR時為防止緩沖區(qū)上溢所做的處理
需要注意的是,在CBR時,式(8)或(9)是緩沖區(qū)不上溢的充分必要條件,在VBR時,式(8)是充分但非必要條件。如果式(8)不成立,編碼器可以通過降低后續(xù)各幀編碼數(shù)據(jù)進入緩沖區(qū)的速率使緩沖區(qū)不上溢。但是,既然總數(shù)據(jù)量不大于S,編碼器總是可以將這些數(shù)據(jù)放在長度不超過D的時間區(qū)間上傳送(即強制第n幀數(shù)據(jù)延后至tn-D時再進入緩沖區(qū)),以保證式(8)成立。
當bbv_delay==0xFFFF時,AVS標準規(guī)定:如果BBV緩沖區(qū)沒有充滿,數(shù)據(jù)以速率R輸入緩沖區(qū);如果BBV緩沖區(qū)充滿,則數(shù)據(jù)不能進入該緩沖區(qū)直到緩沖區(qū)中的部分數(shù)據(jù)被移出。因此,當bbv_delay==0xFFFF時,緩沖區(qū)不存在上溢的問題。
當bbv_delay==0xFFFF時,視頻序列的第1幀圖像的起始碼前的所有數(shù)據(jù)和這個起始碼輸入BBV緩沖區(qū)后,數(shù)據(jù)繼續(xù)輸入BBV緩沖區(qū)直到緩沖區(qū)充滿,并在這個時間開始解碼處理。此時,第1幀的延遲可以看成是D=S/R,這是延遲的最大值,不妨把這種緩沖模型稱為“高延遲模型”。后續(xù)各幀的解碼時間依然按照式(1)來確定。
在高延遲模型中,只需保證緩沖區(qū)不發(fā)生下溢。緩沖區(qū)下溢是有可能發(fā)生的,比如某一幀的編碼數(shù)據(jù)量大于緩沖區(qū)的容量,當該幀的解碼時刻到來時,其數(shù)據(jù)不可能完全進入緩沖區(qū),就會發(fā)生下溢。即使每一幀的編碼數(shù)據(jù)量都小于緩沖區(qū)的容量,也可能發(fā)生緩沖區(qū)下溢,比如出現(xiàn)連續(xù)兩幀的編碼數(shù)據(jù)量都很大(大到接近緩沖區(qū)的容量)的時候。當前一幀的數(shù)據(jù)被移出緩沖區(qū)時,后一幀的數(shù)據(jù)只有一小部分進入了緩沖區(qū),其余部分在兩幀的解碼時間間隔內(nèi)無法全部進入緩沖區(qū)。
準確的說,保證第n幀編碼數(shù)據(jù)能夠及時全部進入緩沖區(qū)的充分必要條件是
當low_delay=1時,是低延遲模式。此時每一幀的編碼數(shù)據(jù)頭部存在BbvCheckTimes,在從緩沖區(qū)移出該幀數(shù)據(jù)解碼之前,解碼器要檢查緩沖區(qū)BbvCheckTimes+1次。通常BbvCheckTimes=0,即解碼器只需檢查緩沖區(qū)1次,這和low_delay==0時是一樣的,如果所有幀都是只需檢查緩沖區(qū)1次,那整個碼流就和low_delay==0時是一樣的。這里所說的“檢查緩沖區(qū)”的意思是“嘗試解碼”,檢查緩沖區(qū)的時刻就是解碼時刻,檢查緩沖區(qū)的時間間隔就是解碼時間間隔。
緩沖區(qū)下溢通常是由于大圖像的編碼數(shù)據(jù)量太大造成的。然而,并非某一幀的編碼數(shù)據(jù)量大了就一定會發(fā)生下溢,根據(jù)fn<R×dn,可知是否下溢和該幀的延遲有關(guān)。而延遲又是由該幀的解碼時刻和該幀數(shù)據(jù)進入緩沖區(qū)的時刻共同確定的,該幀編碼數(shù)據(jù)進入緩沖區(qū)的時刻無法提前,因為在保證緩沖區(qū)不上溢的前提下,已經(jīng)是盡量早的進入緩沖區(qū)了。所以,發(fā)生緩沖區(qū)下溢的原因是該幀的解碼時刻過早,而該幀的解碼時刻是按照tn+1=tn+in遞推出來的,各幀的顯示時間是確定的,最終決定該幀的解碼時刻的是第1幀的解碼時刻。
實際上,解碼的第一幀在碼流中是隨機的。在低延遲模式下,編碼器會將每一幀的延遲時間盡量設(shè)得短,以達到讓解碼器盡早解碼,降低延遲的目的。這正是低延遲模式的含義。
當按照通常的設(shè)置(BbvCheckTimes=0)緩沖區(qū)發(fā)生下溢時,編碼器通過將發(fā)生下溢的幀設(shè)置成大圖像,告知解碼器等待一段時間再解碼。但是,額外的等待時間不一定能夠保證不發(fā)生下溢,如果大圖像的數(shù)據(jù)量太大,超過緩沖區(qū)的容量,或者需等待的時間超過某種上限,則只能放棄大圖像。這時,編碼器設(shè)置的等待時間不足以讓大圖像的全部數(shù)據(jù)到達。解碼器在檢測緩沖區(qū)指定的次數(shù)之后強行移出大圖像。AVS標準沒有詳細規(guī)定在緩沖區(qū)發(fā)生下溢時的處理方法。編碼器可以將大圖像數(shù)據(jù)全部寫入碼流,也可以只寫入一部分。解碼器可以不解碼大圖像,也可以強行解碼并輸出不完整的解碼圖像。建議編碼器避免緩沖區(qū)發(fā)生下溢,以避免解碼器出現(xiàn)不可控的輸出。
這里有兩個問題需要解決:1)等待大圖像解碼的這段時間解碼器如何輸出?2)大圖像解碼后解碼器如何輸出?AVS標準并未明確回答這兩個問題。但是,有一點是肯定的,即解碼器必須按照指定的速率持續(xù)輸出解碼圖像。根據(jù)這個原則,等待大圖像解碼的時候解碼器應(yīng)當有輸出,大圖像解碼后,輸出的速率不能提高。為了保持同步,編碼器應(yīng)當丟棄若干幀,否則會造成不同步。
上述3種緩沖模型對應(yīng)著不同的應(yīng)用。bbv_delay值不是0xFFFF且low_delay值不是1的模型是最常見的,主要應(yīng)用于數(shù)字電視廣播等。這種應(yīng)用的特點是各方面的要求比較均衡。需要注意的是,這種應(yīng)用可以用CBR編碼,也可以用VBR編碼。
bbv_delay==0xFFFF時是高延遲模型,主要應(yīng)用于存儲媒體。這種應(yīng)用的特點是對延遲不敏感,信道可靠性好,能提供的數(shù)據(jù)傳輸率很高,但是存儲容量有限,因此通常采用VBR編碼。
低延遲模式通常用于可視電話、視頻會議等對延遲要求很高的應(yīng)用。同時,信道能夠提供的數(shù)據(jù)傳輸率也是有限的。這就給碼率控制帶來了很大的難度,可能會出現(xiàn)某些幀數(shù)據(jù)量太大的情況。
前文列舉的基本概念對理解碼流緩沖模型是非常重要的,特別是解碼時刻的確定方式。
另外,就是關(guān)于CBR和VBR。根據(jù)前文的敘述,可知CBR,VBR和bbv_delay,low_delay的值沒有必然的聯(lián)系。
編碼器和解碼器使用同樣的碼流緩沖區(qū)模型,但是任務(wù)是不同的。解碼器是被動的,它首先要判斷自己是否有足夠的資源完成解碼,然后按照碼流中的設(shè)置實現(xiàn)對緩沖區(qū)的操作。解碼器還必須處理意外情況和標準中沒有明確規(guī)定的部分。
編碼器首先要把用戶的設(shè)置翻譯成合適的緩沖區(qū)參數(shù),然后采取合適的方法控制編碼過程,使緩沖區(qū)不發(fā)生溢出。編碼器通過控制緩沖區(qū)來控制解碼器的行為。
本文從編碼器的角度,針對3種不同的緩沖模式,給出了保證緩沖區(qū)不溢出的可操作的條件。其中,低延遲模式保證緩沖區(qū)不上溢的條件和常用的緩沖模式是一樣的。
[1] ISO/EC 13818-2,Generic coding of moving pictures and associated audio:Video[S].1996.
[2]GB/T 20090.2—2006,信息技術(shù) 先進音視頻編碼 第2部分:視頻[S].2006.
[3]楊其彤,諸巍杰,張兆揚,等.基于運動復(fù)雜度的AVS幀級碼率控制算法[J]. 電視技術(shù),2009,33(1):21-23.