The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.
Creating a DXVA-HD Video Processor
Microsoft DirectX Video Acceleration High Definition (DXVA-HD) uses two primary interfaces:
- IDXVAHD_Device. Represents the DXVA-HD device. Use this interface to query the device capabilities and create the video processor.
- IDXVAHD_VideoProcessor. Represents a set of video processing capabilities. Use this interface to perform the video processing blit.
In the code that follows, the following global variables are assumed:
IDirect3D9Ex *g_pD3D = NULL; IDirect3DDevice9Ex *g_pD3DDevice = NULL; // Direct3D device. IDXVAHD_Device *g_pDXVAHD = NULL; // DXVA-HD device. IDXVAHD_VideoProcessor *g_pDXVAVP = NULL; // DXVA-HD video processor. IDirect3DSurface9 *g_pSurface = NULL; // Video surface. const D3DFORMAT RENDER_TARGET_FORMAT = D3DFMT_X8R8G8B8; const D3DFORMAT VIDEO_FORMAT = D3DFMT_X8R8G8B8; const UINT VIDEO_FPS = 60; const UINT VIDEO_WIDTH = 640; const UINT VIDEO_HEIGHT = 480;
To create a DXVA-HD video processor:
- Fill in a DXVAHD_CONTENT_DESC structure with a description of the video content. The driver uses this information as a hint to optimize the capabilities of the video processor. The structure does not contain a complete format description.
DXVAHD_RATIONAL fps = { VIDEO_FPS, 1 }; DXVAHD_CONTENT_DESC desc; desc.InputFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE; desc.InputFrameRate = fps; desc.InputWidth = VIDEO_WIDTH; desc.InputHeight = VIDEO_HEIGHT; desc.OutputFrameRate = fps; desc.OutputWidth = VIDEO_WIDTH; desc.OutputHeight = VIDEO_HEIGHT; - Call DXVAHD_CreateDevice to create the DXVA-HD device. This function returns a pointer to the IDXVAHD_Device interface.
hr = DXVAHD_CreateDevice(g_pD3DDevice, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &pDXVAHD); - Call IDXVAHD_Device::GetVideoProcessorDeviceCaps. This method fills in a DXVAHD_VPDEVCAPS structure with the device capabilities. If you require specific video processing features, such as luma keying or image filtering, check their availability by using this structure.
DXVAHD_VPDEVCAPS caps; hr = pDXVAHD->GetVideoProcessorDeviceCaps(&caps); - Check whether the DXVA-HD device supports the input video formats that you require. The topic Checking Supported DXVA-HD Formats describes this step in more detail.
- Check whether the DXVA-HD device supports the output format that you require. The section Checking Supported DXVA-HD Formats describes this step in more detail.
- Allocate an array of DXVAHD_VPCAPS structures. The number of array elements that must be allocated is given by the VideoProcessorCount member of the DXVAHD_VPDEVCAPS structure, obtained in step 3.
// Create the array of video processor caps. DXVAHD_VPCAPS *pVPCaps = new (std::nothrow) DXVAHD_VPCAPS[ caps.VideoProcessorCount ]; if (pVPCaps == NULL) { return E_OUTOFMEMORY; } - Each DXVAHD_VPCAPS structure represents a distinct video processor. You can loop through this array to discover the capabilities of each video processor. The structure includes information about the deinterlacing, telecine, and frame-rate conversion capabilities of the video processor.
- Select a video processor to create. The VPGuid member of the DXVAHD_VPCAPS structure contains a GUID that uniquely identifies the video processor. Pass this GUID to the IDXVAHD_Device::CreateVideoProcessor method. The method returns an IDXVAHD_VideoProcessor pointer.
HRESULT hr = pDXVAHD->GetVideoProcessorCaps( caps.VideoProcessorCount, pVPCaps); - Optionally, call IDXVAHD_Device::CreateVideoSurface to create an array of input video surfaces.
The following code example shows the complete sequence of steps:
// Initializes the DXVA-HD video processor. // NOTE: The following example makes some simplifying assumptions: // // 1. There is a single input stream. // 2. The input frame rate matches the output frame rate. // 3. No advanced DXVA-HD features are needed, such as luma keying or IVTC. // 4. The application uses a single input video surface. HRESULT InitializeDXVAHD() { if (g_pD3DDevice == NULL) { return E_FAIL; } HRESULT hr = S_OK; IDXVAHD_Device *pDXVAHD = NULL; IDXVAHD_VideoProcessor *pDXVAVP = NULL; IDirect3DSurface9 *pSurf = NULL; DXVAHD_RATIONAL fps = { VIDEO_FPS, 1 }; DXVAHD_CONTENT_DESC desc; desc.InputFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE; desc.InputFrameRate = fps; desc.InputWidth = VIDEO_WIDTH; desc.InputHeight = VIDEO_HEIGHT; desc.OutputFrameRate = fps; desc.OutputWidth = VIDEO_WIDTH; desc.OutputHeight = VIDEO_HEIGHT; #ifdef USE_SOFTWARE_PLUGIN HMODULE hSWPlugin = LoadLibrary(L"C:\\dxvahdsw.dll"); PDXVAHDSW_Plugin pSWPlugin = (PDXVAHDSW_Plugin)GetProcAddress(hSWPlugin, "DXVAHDSW_Plugin"); hr = DXVAHD_CreateDevice(g_pD3DDevice, &desc,DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, pSWPlugin, &pDXVAHD); #else hr = DXVAHD_CreateDevice(g_pD3DDevice, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &pDXVAHD); #endif if (FAILED(hr)) { goto done; } DXVAHD_VPDEVCAPS caps; hr = pDXVAHD->GetVideoProcessorDeviceCaps(&caps); if (FAILED(hr)) { goto done; } // Check whether the device supports the input and output formats. hr = CheckInputFormatSupport(pDXVAHD, caps, VIDEO_FORMAT); if (FAILED(hr)) { goto done; } hr = CheckOutputFormatSupport(pDXVAHD, caps, RENDER_TARGET_FORMAT); if (FAILED(hr)) { goto done; } // Create the VP device. hr = CreateVPDevice(pDXVAHD, caps, &pDXVAVP); if (FAILED(hr)) { goto done; } // Create the video surface for the primary video stream. hr = pDXVAHD->CreateVideoSurface( VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_FORMAT, caps.InputPool, 0, // Usage DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, // Number of surfaces to create &pSurf, // Array of surface pointers NULL ); if (FAILED(hr)) { goto done; } g_pDXVAHD = pDXVAHD; g_pDXVAHD->AddRef(); g_pDXVAVP = pDXVAVP; g_pDXVAVP->AddRef(); g_pSurface = pSurf; g_pSurface->AddRef(); done: SafeRelease(&pDXVAHD); SafeRelease(&pDXVAVP); SafeRelease(&pSurf); return hr; }
The CreateVPDevice function show in this example creates the video processor (steps 5–7):
// Creates a DXVA-HD video processor. HRESULT CreateVPDevice( IDXVAHD_Device *pDXVAHD, const DXVAHD_VPDEVCAPS& caps, IDXVAHD_VideoProcessor **ppDXVAVP ) { // Create the array of video processor caps. DXVAHD_VPCAPS *pVPCaps = new (std::nothrow) DXVAHD_VPCAPS[ caps.VideoProcessorCount ]; if (pVPCaps == NULL) { return E_OUTOFMEMORY; } HRESULT hr = pDXVAHD->GetVideoProcessorCaps( caps.VideoProcessorCount, pVPCaps); // At this point, an application could loop through the array and examine // the capabilities. For purposes of this example, however, we simply // create the first video processor in the list. if (SUCCEEDED(hr)) { // The VPGuid member contains the GUID that identifies the video // processor. hr = pDXVAHD->CreateVideoProcessor(&pVPCaps[0].VPGuid, ppDXVAVP); } delete [] pVPCaps; return hr; }
Related topics
Show: