【轉(zhuǎn)】關(guān)于 DXVA 2.0


關(guān)于 DXVA 2.0
項(xiàng)目
DirectX 視頻加速 (DXVA) 是一個 API 和相應(yīng)的 DDI,用于使用硬件加速來加快視頻處理。 軟件編解碼器和軟件視頻處理器可以使用 DXVA 將某些 CPU 密集型操作卸載到 GPU。 例如,軟件解碼器可以將反向離散余弦變換 (iDCT) 卸載到 GPU。
在 DXVA 中,某些解碼操作由圖形硬件驅(qū)動程序?qū)崿F(xiàn)。 這組功能稱為?加速器。 其他解碼操作由稱為?主機(jī)解碼器?或?軟件解碼器的用戶模式應(yīng)用程序軟件實(shí)現(xiàn)。 (術(shù)語主機(jī)解碼器和軟件解碼器是等效的。) 加速器執(zhí)行的處理稱為主機(jī)外處理。 通常,加速器使用 GPU 來加速某些操作。 每當(dāng)加速器執(zhí)行解碼操作時(shí),主機(jī)解碼器必須向包含執(zhí)行操作所需信息的加速器緩沖區(qū)傳達(dá)
DXVA 2 API 需要 Windows Vista 或更高版本。 為了向后兼容,Windows Vista 仍支持 DXVA 1 API。 提供了一個仿真層,用于在 API 的任一版本與相反版本的 DDI 之間進(jìn)行轉(zhuǎn)換:
如果圖形驅(qū)動程序符合 Windows 顯示驅(qū)動程序模型 (WDDM) ,則 DXVA 1 API 調(diào)用將轉(zhuǎn)換為 DXVA 2 DDI 調(diào)用。
如果圖形驅(qū)動程序使用較舊的 Windows XP 顯示驅(qū)動程序模型 (XPDM) ,則 DXVA 2 API 調(diào)用將轉(zhuǎn)換為 DXVA 1 DDI 調(diào)用。
下表顯示了每個版本的 DXVA API 的操作系統(tǒng)要求和支持的視頻呈現(xiàn)器。
API 版本要求視頻呈現(xiàn)器支持DXVA 1Windows 2000 或更高版本覆蓋混合器、VMR-7、VMR-9 (DirectShow 僅)DXVA 2Windows VistaEVR (DirectShow 和 Media Foundation)
?
在 DXVA 1 中,軟件解碼器必須通過視頻呈現(xiàn)器訪問 API。 如果不調(diào)用視頻呈現(xiàn)器,就無法使用 DXVA 1 API。 DXVA 2 中已刪除此限制。 使用 DXVA 2,主機(jī)解碼器 (或任何應(yīng)用程序) 都可以通過?IDirectXVideoDecoderService?接口直接訪問 API。
DXVA 1 文檔介紹了用于以下視頻標(biāo)準(zhǔn)的解碼結(jié)構(gòu):
ITU-T Rec. H.261
ITU-T Rec. H.263
MPEG-1 視頻
MPEG-2 主配置文件視頻
以下規(guī)范定義了其他視頻標(biāo)準(zhǔn)的 DXVA 擴(kuò)展:
H.264/AVC 解碼的 DXVA 規(guī)范
H.264/MPEG-4 AVC 多視圖視頻編碼 (MVC) 的 DXVA 規(guī)范,包括立體聲高調(diào)
MPEG-1 VLD 和組合 MPEG-1/MPEG-2 VLD 視頻解碼的 DXVA 規(guī)范。
MPEG-4 第 2 部分視頻解碼Off-Host VLD 模式的 DXVA 規(guī)范
Windows Media Video? v8、v9 和 vA 解碼 (的 DXVA 規(guī)范,包括 SMPTE 421M “VC-1”)
適用于 H.264/MPEG-4 可縮放視頻編碼 (SVC) Off-Host VLD 模式解碼的 DirectX 視頻加速 (DXVA) 規(guī)范
VP8 和 VP9 視頻編碼的 DirectX 視頻加速規(guī)范
DXVA 1 和 DXVA 2 使用相同的數(shù)據(jù)結(jié)構(gòu)進(jìn)行解碼。 但是,配置解碼會話的過程已更改。 DXVA 1 使用“探測和鎖定”機(jī)制,其中主機(jī)解碼器可以在加速器上設(shè)置所需配置之前測試各種配置。 在 DXVA 2 中,加速器返回受支持的配置列表,主機(jī)解碼器從列表中選擇一個。 以下部分提供了詳細(xì)信息:
在 DirectShow 中支持 DXVA 2.0
在 Media Foundation 中支持 DXVA 2.0
相關(guān)主題
DirectX 視頻加速 2.0
DXVA 1.0 規(guī)范
?
【硬件解碼系列】之DXVA2

walkingMa

于?2019-02-10 16:49:14?發(fā)布

5571

?收藏?3版權(quán)
序
?本文小編也是在學(xué)習(xí)dxva2解碼,所以很多資料都是來源網(wǎng)上搜集加自己理解。
1. DXVA2解碼過程
(1)、調(diào)用DXVA2CreateDirect3DDeviceManager9函數(shù)獲取到IDirect3DDeviceManager9接口的一個對象。
(2)、調(diào)用IDirect3DDeviceManager9::OpenDeviceHandle?函數(shù)獲取到一個Direct3D 設(shè)備對象句柄。
(3)、調(diào)用IDirect3DDeviceManager9::GetVideoService?函數(shù)并且傳遞Direct3D設(shè)備句柄,這個函數(shù)返回IDirectXVideoDecoderService接口對象指針。
(4)、調(diào)用?IDirectXVideoDecoderService::GetDecoderDeviceGuids?函數(shù)返回解碼設(shè)備GUID的數(shù)組。
(5)、循環(huán)遍歷解碼設(shè)備GUID數(shù)組找到一個目前硬件驅(qū)動能支持的GUID解碼設(shè)備。例如,如果驅(qū)動只支持MPEG-2 解碼,則需要找到DXVA2_ModeMPEG2_MOCOMP, DXVA2_ModeMPEG2_IDCT, or DXVA2_ModeMPEG2_VLD這幾個GUID才能解碼。
(6)、如果你找到了一個解碼設(shè)備GUID,傳遞這個GUID給IDirectXVideoDecoderService::GetDecoderRenderTargets?函數(shù),這個函數(shù)返回一個類型為D3DFORMAT 的渲染目標(biāo)格式數(shù)組(render target format)。
(7)、循環(huán)遍歷渲染目標(biāo)格式數(shù)組,找到一個匹配的輸出格式。通常一個解碼設(shè)備只支持一個渲染目標(biāo)輸出格式。
(8)、調(diào)用IDirectXVideoDecoderService::GetDecoderConfigurations函數(shù),并且傳遞解碼設(shè)備GUID和DXVA2_VideoDesc結(jié)構(gòu)體(描述視頻信息)。這個函數(shù)返回一個?DXVA2_ConfigPictureDecode結(jié)構(gòu)體的數(shù)組,這個數(shù)組中的每一項(xiàng)描述一個可能的解碼配置信息。
(9)、調(diào)用IDirectXVideoDecoderService::CreateVideoDecoder函數(shù),并且傳遞解碼設(shè)備GUID和DXVA2_VideoDesc結(jié)構(gòu)體,?DXVA2_ConfigPictureDecode,渲染目標(biāo)surface數(shù)組。這個函數(shù)將返回一個IDirectXVideoDecoder?接口對象。
(10)、調(diào)用函數(shù)?IDirectXVideoDecoder::BeginFrame。
(11)、調(diào)用下面過程多次:
調(diào)用IDirectXVideoDecoder::GetBuffer?函數(shù)得到一個DXVA解碼緩沖區(qū)( DXVA decoder buffer )。
將數(shù)據(jù)填充到這個DXVA解碼緩沖區(qū)中。
調(diào)用?IDirectXVideoDecoder::ReleaseBuffer?釋放這個DXVA解碼緩沖區(qū)。
(12)、調(diào)用?IDirectXVideoDecoder::Execute?函數(shù)執(zhí)行這一幀的解碼操作。
(13)、調(diào)用IDirectXVideoDecoder::EndFrame?。
注意:在每一幀解碼之前必須調(diào)用函數(shù)IDirect3DDeviceManager9::TestDevice測試設(shè)備句柄是否修改。如果設(shè)備已經(jīng)修改,此函數(shù)將返回DXVA2_E_NEW_VIDEO_DEVICE。如果這種情況發(fā)生,執(zhí)行下面操作:
通過調(diào)用IDirect3DDeviceManager9::CloseDeviceHandle函數(shù)關(guān)閉設(shè)備句柄對象。
釋放?IDirectXVideoDecoderService?和?IDirectXVideoDecoder?對象指針。
打開一個新的設(shè)備句柄。
協(xié)商一個新的解碼配置項(xiàng)。
創(chuàng)建一個新的解碼設(shè)備。
摘抄自參考網(wǎng)址:https://www.cnblogs.com/betterwgo/p/6125507.html?, 此參考網(wǎng)址將dxva的調(diào)用流程說的很清楚。
上面的函數(shù)是為創(chuàng)建IDirectXVideoDecoder 接口對象使用的。而實(shí)際的解碼函數(shù),主要由2個函數(shù)組成:
ff_dxva2_common_end_frame
ff_dxva2_commit_buffer
此2個函數(shù)由不同的函數(shù)調(diào)用,例如對于h264格式的碼流是由ff_h264_dxva2_hwaccel 中的.end_frame = dxva2_h264_end_frame函數(shù)調(diào)用。
AVHWAccel ff_h264_dxva2_hwaccel = { ? ? .name ? ? ? ? ? = "h264_dxva2", ? ? .type ? ? ? ? ? = AVMEDIA_TYPE_VIDEO, ? ? .id ? ? ? ? ? ? = AV_CODEC_ID_H264, ? ? .pix_fmt ? ? ? ?= AV_PIX_FMT_DXVA2_VLD, ? ? .start_frame ? ?= dxva2_h264_start_frame, ? ? .decode_slice ? = dxva2_h264_decode_slice, ? ? .end_frame ? ? ?= dxva2_h264_end_frame, ? ? .frame_priv_data_size = sizeof(struct dxva2_picture_context), };
1
2
3
4
5
6
7
8
9
10
ff_h264_dxva2_hwaccel結(jié)構(gòu)體是由int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)函數(shù)中的if (!setup_hwaccel(avctx, ret, desc->name)) 調(diào)用(此函數(shù)源自 libavcodec/utils.c),
可參考目前網(wǎng)上已有的工程:
也可參考ffmpeg自帶的sample:例如ffmpeg-3.2中的ffmpeg_dxva2.c
?視頻編解碼硬件方案最早是在嵌入式領(lǐng)域中廣泛存在,如采用DSP,FPGA,ASIC等,用來彌補(bǔ)嵌入式系統(tǒng)CPU等資源能力不足問題,但隨著視頻分辨率越來越高(從CIF經(jīng)歷720P,1080P發(fā)展到4K,8K),編碼算法越來越復(fù)雜(從mpeg2經(jīng)歷h264,發(fā)展到h265),PC的軟件規(guī)模也越來越龐大,視頻應(yīng)用也越來也豐富,單獨(dú)靠CPU來編解碼已經(jīng)顯得勉為其難,一種集成在顯卡中g(shù)pu用來參與編解碼工作已經(jīng)成為主流。
一) gpu存在的形式
gpu主要駐留在顯卡上,配合顯卡參與顯示,繪圖,編解碼,并行計(jì)算等工作。常見形式有以下3類。
1) 獨(dú)立顯卡形式,如AMD和NVIDIA獨(dú)立顯卡。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??獨(dú)立顯卡
2)集成在CPU中的核顯,如intel的某些帶核顯處理器和AMD某些帶核顯處理器
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???帶核顯的處理器
3) 視頻加速卡
專門用來在服務(wù)器端進(jìn)行編解碼使用,如Intel的 VCA卡等。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 專用視頻加速卡
二)gpu編解碼的常用技術(shù)方案
1)廠家SDK方案
對應(yīng)gpu編解碼,硬件廠家都有相應(yīng)SDK方案,應(yīng)用開發(fā)者可以直接調(diào)用廠家的SDK 來完成編解碼器工作。
?
NVIDIA
AMD
??INTEL
編碼器
?NVENC
?UVD
參考sample_encode
解碼器
?NVDEC
?VCE
參考sample_decode
對應(yīng)的SDK
Video_Codec_SDK
?AMF SDK
?Intel Media SDK
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??硬件編解碼SDK方案
2)FFMPEG方案
ffmpeg對廠家SDK進(jìn)行封裝和集成,實(shí)現(xiàn)部分的硬件編解碼
?
NVIDIA
AMD
INTEL
編碼器
xxx_nvenc
xxx_amf
xxxx_qsv
解碼器
xxx_ cuvid
暫未實(shí)現(xiàn)
xxxx_qsv
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ffmpeg硬解編解碼應(yīng)用
其中xxx標(biāo)識編碼類型,如h264,h265,mpeg2,vp8,vp9等。其次在ffmpeg中軟件編解碼器可以實(shí)現(xiàn)相關(guān)硬解加速。如在h264解碼器中可以使用cuda 加速,qsv加速,dxva2 加速,d3d11va加速,opencl加速等。
?
cuda
qsv
dxva2/d3d11va
opencl
應(yīng)用場景
適應(yīng)NVIDIA顯卡平臺,但跨OS
適應(yīng)Intel顯卡平臺,但跨OS
適用Windows OS,但跨硬件平臺
僅僅支持opencl的硬件平臺
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ffmpeg硬解加速應(yīng)用
3)gstreamer方案
?
gst-msdk
gst-vaapi
gst-d3d11
編碼器
msdkxxxenc
vaapixxxenc
無
解碼器
msdkxxxdec
vaapixxxdec
d3d11xxxdec
?
應(yīng)用場景
僅限intel gpu
僅限intel gpu的linux系統(tǒng)
僅限Windows D3D加速,跨硬件平臺
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Gstreamer硬件加速編解碼方案
其中xxx標(biāo)識編碼類型,如h264,h265,mpeg2,vp8,vp9等。
在Linux關(guān)于gst-msdk和gst-vaapi的差異如下:

以上是關(guān)于視頻在PC上的硬解硬編的常見方案。
參考網(wǎng)址:https://blog.csdn.net/xiaoyafang123/article/details/82905452
參考網(wǎng)址:https://blog.csdn.net/lishuzhai/article/details/52497110