個純虛函數 ChecklnputType、CheckTransform、DecideBufferSize、GetMediaType外,只需根據媒體轉換需求改寫Transform函數,在其中實現媒體轉換邏輯即可。但這種方式實現的媒體轉換Filter的媒體轉換過程只有一個線程在運行,此線程來自于上游Filter調用本Filter的Receive函數。在CTransformFilter的Receive函數實現中,會調用Transform函數進行媒體轉換,等待媒體轉換完畢,Transform函數返回后,將輸出的Sample通過輸出Pin傳遞到下游Filter中。這種實現要求每次從上游Filter接收到一個Sample后都能產生一個輸出Sample傳遞到下游Filter中,這與視頻解碼過程的工作方式并不適配。視頻解碼過程中除了需要之前已經重構的參考圖像外,還需要輸入多個Frame才能重構一幅完整的圖像,而這些Frame可能被上游Filter封裝在多個Sample中進行數據傳遞。所以不能采用改寫Transform函數的方式來實現HEVC解碼過程。
[0035]UVD HEVC Decoder通過改寫Receive函數實現自定義數據接收方式和媒體轉換流程。UVD HEVC Decoder通過AMD Media SDK中的API,使用UVD視頻硬件解碼模塊對輸入HEVC視頻流進行硬件解碼。在解碼過程中,除了 UVD解碼器線程外,還有兩個線程在運行。一個線程在此稱之為輸入線程,負責接收從上游Filter傳遞的Sample數據,并進行媒體類型檢查和數據解析等預處理后,將Sample中的HEVC視頻流數據和相關信息傳輸到UVD解碼器中;另一個線程在此稱之為輸出線程,負責不斷從UVD解碼器中獲取解碼輸出的圖像數據,并將其根據輸出媒體類型封裝為Sample后,將Sample傳遞到下游Filter中。輸入線程直接利用上游Filter調用本Filter中的Receive函數的線程,輸出線程在UVD HEVCDecoder被創建時的初始化過程中被創建并初始化,在UVD HEVC Decoder從上游Filter接收到第一個Sample后被啟動。
[0036]輸入線程調用Receive函數后的處理流程如圖2所示。從上游Filter接收到Sample后,先從輸入Pin獲取Sample的相關屬性信息,檢查其是否為媒體流數據,如果Sample不是媒體流數據,則將Sample通過輸出Pin直接傳遞到下游Filter中讓其處理。對于媒體流數據的Sample,檢查其媒體類型是否與當前設置的媒體類型是否相符。如果Sample的媒體類型與當前設置的媒體類型不相符則需要進行動態媒體類型變化處理,先等待UVD解碼器中的所有解碼輸出的圖像數據都輸出完畢后,根據Sample的媒體類型重新設置媒體類型。如果Sample的媒體類型與當前設置的媒體類型相符,則無需做額外處理。之后解析Sample的數據,從中獲取HEVC視頻流數據和相關信息,再將這些數據和信息不斷嘗試傳輸到UVD解碼器中。直到成功將HEVC視頻流數據傳輸到UVD解碼器中后Receive函數對上游Filter返回成功信息。這樣做可以使得UVD解碼器的輸入隊列緩沖區已滿的時候,對上游Filter的數據傳輸起到阻塞作用。
[0037]輸出線程啟動后的處理邏輯如圖3所示。循環不斷地嘗試從UVD解碼器中獲取解碼輸出的圖像數據,直到UVD解碼器返回文件結束信息時,結束循環并終止線程。當成功從UVD解碼器中獲取到解碼輸出的圖像數據,則將圖像數據從顯存里取回到系統內存中,并根據輸出媒體類型將其封裝成Sample。最后將封裝好的Sample通過輸出Pin傳遞到下游Filter中,并進入下一次嘗試從UVD解碼器中獲取解碼輸出的圖像數據的循環中。
[0038](二)UVD 的調用
[0039]初始化89' #
[0040]調用Media SDK相關API,創建AMF上下文和AMF HEVC硬件解碼器。之后以AMF上下文和解碼器作為初始化參數創建解碼流輸出線程。
[0041]將視頻流輸入到8Y #
[0042]將接收到的視頻流數據封裝成AMFData類型數據,并設置時間戳信息。之后將封裝好的AMFData數據輸入到UVD解碼器中。如果解碼器中的輸入隊列已滿,則循環等待并嘗試輸入,直到將視頻流數據輸入到UVD解碼器中后返回,對上游Filter的數據傳輸起到阻塞的效果。
[0043](三)推送輸出數據OutputThread類定義
[0044]OutputThread類繼承AMFThread 類,AMFThread類的定義與實現在 AMD Media SDK的示例代碼中通用類集中。OutputThread類中有三個指針成員屬性,將用來分別指向AMF上下文對象和AMF解碼器對象和HEVCDecoder對象。其中成員函數Run是OutputThread對象線程啟動后會調用執行的線程計算邏輯函數。
[0045]解碼圖像輸出#
[0046]OutputThread對象線程啟動后,其成員函數Run將會被調用執行。在Run函數中,不斷循環訪問AMF解碼器對象指針指向的UVD解碼器,嘗試從中取出解碼圖像。如果從UVD解碼器中取出的數據非空,即成功取出解碼圖像,則將解碼圖像數據從顯存轉換到系統內存中存放,并轉換成AMFSurface類型。之后根據輸出媒體類型創建一個輸出Sample,根據解碼圖像數據中的時間戳信息設置輸出Sample的時間戳,并將解碼圖像數據從AMFSurface對象中復制填充到輸出Sample對象中。最后將封裝好的輸出Sample對象通過輸出Pin傳輸到下游Filter中。如果從UVD解碼器中取出的數據為空,即仍未有解碼數據輸出,則循環等待并進行下一次嘗試從UVD解碼器中取出解碼數據。如果訪問UVD解碼器取出解碼數據時遇到文件結束符,并返回AMF_E0F值,則結束循環,Run函數將返回,線程將會終結。
[0047]上述實施例為本發明較佳的實施方式,但本發明的實施方式并不受上述實施例的限制,其他的任何未背離本發明的精神實質與原理下所作的改變、修飾、替代、組合、簡化,均應為等效的置換方式,都包含在本發明的保護范圍之內。
【主權項】
1.一種基于UVD的HEVC視頻解碼方法,其特征在于,包含以下順序的步驟: 利用AMD Media SDK 1.1對AMD異構計算平臺中的UVD視頻硬解碼模塊進行調用,將接收到的HEVC視頻數據進行解析和處理后投放到UVD中,同時不斷從UVD中獲取解碼后圖像并推送出去。2.根據權利要求1所述的基于UVD的HEVC視頻解碼方法,其特征在于,所述的UVD視頻硬解碼模塊為基于UVD的HEVC解碼功能的DirectShow Filter,DirectShow Filter命名為UVD HEVC Decoder,屬于Transform Filter,其具有一個輸入Pin和一個輸出Pin,主媒體類型均為視頻MEDIATYPE_Video ;在UVD HEVC Decoder中,輸入Pin暫時僅接受HEVC視頻的兩種媒體類型的上游輸出Pin與之連接,輸出Pin僅提供MEDIASUBTYPE_NV12 —種媒體類型的輸出Pin連接;UVD HEVC Decoder的整體對外功能為接收從上游Filter輸入的HEVC視頻流,并將其解碼為YUV 4:2:0圖像數據的NV12格式碼流,輸出到下游Filter中。3.根據權利要求2所述的基于UVD的HEVC視頻解碼方法,其特征在于,所述的UVDHEVC Decoder繼承自DirectShow Filter的基類庫中CtransformFilter,利用其中的輸入和輸出Pin實現Pin的連接和數據傳輸和其他DirectShow Filter基本功能的實現,數據傳輸方式屬于Push模式。4.根據權利要求1所述的基于UVD的HEVC視頻解碼方法,其特征在于,所述的利用AMDMedia SDK 1.1對AMD異構計算平臺中的UVD視頻硬解碼模塊進行調用,具體包含以下步驟: (1)初始化UVD:調用Media SDK相關API,創建AMF上下文和AMF HEVC硬件解碼器;之后以AMF上下文和解碼器作為初始化參數創建解碼流輸出線程; (2)將視頻流輸入到UVD:將接收到的視頻流數據封裝成AMFData類型數據,并設置時間戳信息;之后將封裝好的AMFData數據輸入到UVD解碼器中;如果解碼器中的輸入隊列已滿,則循環等待并嘗試輸入,直到將視頻流數據輸入到UVD解碼器中后返回。5.根據權利要求1所述的基于UVD的HEVC視頻解碼方法,其特征在于,所述的不斷從UVD中獲取解碼后圖像并推送出去,具體如下: OutputThread對象線程啟動后,其成員函數Run將會被調用執行; 在Run函數中,不斷循環訪問AMF解碼器對象指針指向的UVD解碼器,嘗試從中取出解碼圖像;如果從UVD解碼器中取出的數據非空,即成功取出解碼圖像,則將解碼圖像數據從顯存轉換到系統內存中存放,并轉換成AMFSurface類型;之后根據輸出媒體類型創建一個輸出Sample,根據解碼圖像數據中的時間戳信息設置輸出Sample的時間戳,并將解碼圖像數據從AMFSurface對象中復制填充到輸出Sample對象中; 最后將封裝好的輸出Sample對象通過輸出Pin傳輸到下游Filter中;如果從UVD解碼器中取出的數據為空,即仍未有解碼數據輸出,則循環等待并進行下一次嘗試從UVD解碼器中取出解碼數據;如果訪問UVD解碼器取出解碼數據時遇到文件結束符,并返回AMF_EOF值,則結束循環,Run函數將返回,線程將會終結。
【專利摘要】本發明公開的一種基于UVD的HEVC視頻解碼方法,包含以下順序的步驟:利用AMD?Media?SDK?1.1對AMD異構計算平臺中的UVD視頻硬解碼模塊進行調用,將接收到的HEVC視頻數據進行解析和處理后投放到UVD中,同時不斷從UVD中獲取解碼后圖像并推送出去。本發明的視頻解碼方法,提高了HEVC視頻解碼的效率,支持高質量HEVC視頻的實時解碼,并且使用了通用圖像數據傳輸方法,具有更好的通用性和兼容性,對AMD異構計算平臺下的HEVC視頻解碼有重要的實踐指導價值。
【IPC分類】H04N19/42, H04N19/44
【公開號】CN105263021
【申請號】CN201510671074
【發明人】陸璐, 古偉楷
【申請人】華南理工大學
【公開日】2016年1月20日
【申請日】2015年10月13日