提交 b276b163 编写于 作者: A Alexandre Biny 提交者: jp9000

obs-qsv11: Use d3d9 allocator on Win7

Use a d3d9 device and allocator to encode in QSV.

This fixes a random crash that could only happen on Windows 7. The QSV
Deviced returned a DEVICE_FAILURE after a random amount of time with the
old method.

This fix is totally based on Shinck's QSVHelper.exe patch for OBS
Classic (see
https://obsproject.com/forum/threads/0-633b-qsvhelper-exe-was-killed-encode-failed.19230/page-3#post-161984
for more information)

This is more like a proof of concept, but that fix is currently stable
and tested more than 50 hours, with a single session of +14 hours.

That commit doesn't respect all OBS Guidelines. It is currently
recommended to wait for a more "cleaner" implementation.
上级 2278782c
......@@ -48,9 +48,11 @@ set(obs-qsv11_libmfx_HEADERS
)
set(obs-qsv11_SOURCES
common_directx9.cpp
common_directx11.cpp
common_utils.cpp
common_utils_windows.cpp
device_directx9.cpp
QSV_Encoder.cpp
QSV_Encoder_Internal.cpp
obs-qsv11.c
......@@ -59,7 +61,9 @@ set(obs-qsv11_SOURCES
set(obs-qsv11_HEADERS
bits/linux_defs.h
bits/windows_defs.h
common_directx9.h
common_directx11.h
device_directx9.h
common_utils.h
QSV_Encoder.h
QSV_Encoder_Internal.h)
......@@ -72,7 +76,9 @@ add_library(obs-qsv11 MODULE
)
target_link_libraries(obs-qsv11
libobs
d3d9
d3d11
dxva2
dxgi
)
......
......@@ -83,6 +83,7 @@ QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL& impl, mfxVersion& version) :
m_bIsWindows8OrGreater = IsWindows8OrGreater();
m_bUseD3D11 = false;
m_bD3D9HACK = true;
if (m_bIsWindows8OrGreater) {
tempImpl = impl | MFX_IMPL_VIA_D3D11;
......@@ -107,6 +108,21 @@ QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL& impl, mfxVersion& version) :
return;
}
}
else if (m_bD3D9HACK) {
tempImpl = impl | MFX_IMPL_VIA_D3D9;
sts = m_session.Init(tempImpl, &version);
if (sts == MFX_ERR_NONE) {
m_session.QueryVersion(&version);
m_session.Close();
blog(LOG_INFO, "\timpl: D3D09\n"
"\tsurf: Hack");
m_impl = tempImpl;
m_ver = version;
return;
}
}
// Either windows 7 or D3D11 failed at this point.
tempImpl = impl | MFX_IMPL_VIA_D3D9;
......@@ -136,11 +152,14 @@ mfxStatus QSV_Encoder_Internal::Open(qsv_param_t * pParams)
if (m_bUseD3D11)
// Use D3D11 surface
sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator);
sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator, false, false);
else if (m_bD3D9HACK)
// Use hack
sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator, false, true);
else
// Use system memory
sts = Initialize(m_impl, m_ver, &m_session, NULL);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
m_pmfxENC = new MFXVideoENCODE(m_session);
......@@ -260,7 +279,7 @@ bool QSV_Encoder_Internal::InitParams(qsv_param_t * pParams)
m_mfxEncParams.mfx.FrameInfo.Width = MSDK_ALIGN16(pParams->nWidth);
m_mfxEncParams.mfx.FrameInfo.Height = MSDK_ALIGN16(pParams->nHeight);
if (m_bUseD3D11)
if (m_bUseD3D11 || m_bD3D9HACK)
m_mfxEncParams.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
else
m_mfxEncParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
......@@ -282,7 +301,7 @@ mfxStatus QSV_Encoder_Internal::AllocateSurfaces()
EncRequest.NumFrameSuggested += m_mfxEncParams.AsyncDepth;
// Allocate required surfaces
if (m_bUseD3D11) {
if (m_bUseD3D11 || m_bD3D9HACK) {
sts = m_mfxAllocator.Alloc(m_mfxAllocator.pthis, &EncRequest,
&m_mfxResponse);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
......@@ -498,14 +517,14 @@ mfxStatus QSV_Encoder_Internal::Encode(uint64_t ts, uint8_t *pDataY,
}
mfxFrameSurface1 *pSurface = m_pmfxSurfaces[nSurfIdx];
if (m_bUseD3D11)
if (m_bUseD3D11 || m_bD3D9HACK)
sts = m_mfxAllocator.Lock(m_mfxAllocator.pthis,
pSurface->Data.MemId, &(pSurface->Data));
sts = LoadNV12(pSurface, pDataY, pDataUV, strideY, strideUV);
pSurface->Data.TimeStamp = ts;
if (m_bUseD3D11)
if (m_bUseD3D11 || m_bD3D9HACK)
sts = m_mfxAllocator.Unlock(m_mfxAllocator.pthis,
pSurface->Data.MemId, &(pSurface->Data));
......@@ -538,7 +557,7 @@ mfxStatus QSV_Encoder_Internal::Drain()
{
mfxStatus sts = MFX_ERR_NONE;
while (m_pTaskPool[m_nFirstSyncTask].syncp) {
while (m_pTaskPool && m_pTaskPool[m_nFirstSyncTask].syncp) {
sts = m_session.SyncOperation(m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
......@@ -556,11 +575,11 @@ mfxStatus QSV_Encoder_Internal::ClearData()
sts = m_pmfxENC->Close();
if (m_bUseD3D11)
if (m_bUseD3D11 || m_bD3D9HACK)
m_mfxAllocator.Free(m_mfxAllocator.pthis, &m_mfxResponse);
for (int i = 0; i < m_nSurfNum; i++) {
if (!m_bUseD3D11)
if (!m_bUseD3D11 && !m_bD3D9HACK)
delete m_pmfxSurfaces[i]->Data.Y;
delete m_pmfxSurfaces[i];
......@@ -578,7 +597,7 @@ mfxStatus QSV_Encoder_Internal::ClearData()
m_pmfxENC = NULL;
}
if (m_bUseD3D11)
if (m_bUseD3D11 || m_bD3D9HACK)
Release();
m_session.Close();
......
......@@ -108,5 +108,6 @@ private:
mfxBitstream m_outBitstream;
bool m_bIsWindows8OrGreater;
bool m_bUseD3D11;
bool m_bD3D9HACK;
};
#include "common_directx9.h"
#include "device_directx9.h"
#include <objbase.h>
#include <initguid.h>
#include <d3d9.h>
#include <map>
#include <atlbase.h>
#define D3DFMT_NV12 (D3DFORMAT)MAKEFOURCC('N','V','1','2')
#define D3DFMT_YV12 (D3DFORMAT)MAKEFOURCC('Y','V','1','2')
#define D3DFMT_P010 (D3DFORMAT)MAKEFOURCC('P','0','1','0')
#define MSDK_SAFE_FREE(X) {if (X) { free(X); X = NULL; }}
std::map<mfxMemId*, mfxHDL> dx9_allocResponses;
std::map<mfxHDL, mfxFrameAllocResponse> dx9_allocDecodeResponses;
std::map<mfxHDL, int> dx9_allocDecodeRefCount;
CComPtr<IDirect3DDeviceManager9> m_manager;
CComPtr<IDirectXVideoDecoderService> m_decoderService;
CComPtr<IDirectXVideoProcessorService> m_processorService;
HANDLE m_hDecoder;
HANDLE m_hProcessor;
DWORD m_surfaceUsage;
CD3D9Device* g_hwdevice;
const struct {
mfxIMPL impl; // actual implementation
mfxU32 adapterID; // device adapter number
} implTypes[] = {
{ MFX_IMPL_HARDWARE, 0 },
{ MFX_IMPL_HARDWARE2, 1 },
{ MFX_IMPL_HARDWARE3, 2 },
{ MFX_IMPL_HARDWARE4, 3 }
};
struct mfxAllocatorParams
{
virtual ~mfxAllocatorParams(){};
};
struct D3DAllocatorParams : mfxAllocatorParams
{
IDirect3DDeviceManager9 *pManager;
DWORD surfaceUsage;
D3DAllocatorParams()
: pManager()
, surfaceUsage()
{
}
};
mfxStatus DX9_Alloc_Init(D3DAllocatorParams *pParams)
{
D3DAllocatorParams *pd3dParams = 0;
pd3dParams = dynamic_cast<D3DAllocatorParams *>(pParams);
if (!pd3dParams)
return MFX_ERR_NOT_INITIALIZED;
m_manager = pd3dParams->pManager;
m_surfaceUsage = pd3dParams->surfaceUsage;
return MFX_ERR_NONE;
}
mfxStatus DX9_CreateHWDevice(mfxSession session, mfxHDL* deviceHandle, HWND, bool)
{
mfxStatus result;
g_hwdevice = new CD3D9Device;
mfxU32 adapterNum = 0;
mfxIMPL impl;
MFXQueryIMPL(session, &impl);
mfxIMPL baseImpl = MFX_IMPL_BASETYPE(impl); // Extract Media SDK base implementation type
// get corresponding adapter number
for (mfxU8 i = 0; i < sizeof(implTypes) / sizeof(implTypes[0]); i++) {
if (implTypes[i].impl == baseImpl) {
adapterNum = implTypes[i].adapterID;
break;
}
}
POINT point = { 0, 0 };
HWND window = WindowFromPoint(point);
result = g_hwdevice->Init(window, 0, adapterNum);
if (result != MFX_ERR_NONE) {
return result;
}
g_hwdevice->GetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER, deviceHandle);
D3DAllocatorParams dx9_allocParam;
dx9_allocParam.pManager = reinterpret_cast<IDirect3DDeviceManager9 *>(*deviceHandle);
DX9_Alloc_Init(&dx9_allocParam);
return MFX_ERR_NONE;
}
void DX9_CleanupHWDevice()
{
if (g_hwdevice) {
// g_hwdevice->Close();
delete g_hwdevice;
g_hwdevice = NULL;
}
if (m_manager && m_hDecoder) {
m_manager->CloseDeviceHandle(m_hDecoder);
m_manager = NULL;
m_hDecoder = NULL;
}
if (m_manager && m_hProcessor) {
m_manager->CloseDeviceHandle(m_hProcessor);
m_manager = NULL;
m_hProcessor = NULL;
}
if (m_decoderService) {
// delete m_decoderService;
m_decoderService = NULL;
}
if (m_processorService) {
// delete m_processorService;
m_processorService = NULL;
}
}
D3DFORMAT ConvertMfxFourccToD3dFormat(mfxU32 fourcc)
{
switch (fourcc)
{
case MFX_FOURCC_NV12:
return D3DFMT_NV12;
case MFX_FOURCC_YV12:
return D3DFMT_YV12;
case MFX_FOURCC_YUY2:
return D3DFMT_YUY2;
case MFX_FOURCC_RGB3:
return D3DFMT_R8G8B8;
case MFX_FOURCC_RGB4:
return D3DFMT_A8R8G8B8;
case MFX_FOURCC_P8:
return D3DFMT_P8;
case MFX_FOURCC_P010:
return D3DFMT_P010;
case MFX_FOURCC_A2RGB10:
return D3DFMT_A2R10G10B10;
default:
return D3DFMT_UNKNOWN;
}
}
mfxStatus dx9_simple_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr)
{
pthis; // To suppress warning for this unused parameter
if (!ptr || !mid)
return MFX_ERR_NULL_PTR;
mfxHDLPair *dxmid = (mfxHDLPair*)mid;
IDirect3DSurface9 *pSurface = static_cast<IDirect3DSurface9*>(dxmid->first);
if (pSurface == 0)
return MFX_ERR_INVALID_HANDLE;
D3DSURFACE_DESC desc;
HRESULT hr = pSurface->GetDesc(&desc);
if (FAILED(hr))
return MFX_ERR_LOCK_MEMORY;
if (desc.Format != D3DFMT_NV12 &&
desc.Format != D3DFMT_YV12 &&
desc.Format != D3DFMT_YUY2 &&
desc.Format != D3DFMT_R8G8B8 &&
desc.Format != D3DFMT_A8R8G8B8 &&
desc.Format != D3DFMT_P8 &&
desc.Format != D3DFMT_P010 &&
desc.Format != D3DFMT_A2R10G10B10)
return MFX_ERR_LOCK_MEMORY;
D3DLOCKED_RECT locked;
hr = pSurface->LockRect(&locked, 0, D3DLOCK_NOSYSLOCK);
if (FAILED(hr))
return MFX_ERR_LOCK_MEMORY;
switch ((DWORD)desc.Format)
{
case D3DFMT_NV12:
ptr->Pitch = (mfxU16)locked.Pitch;
ptr->Y = (mfxU8 *)locked.pBits;
ptr->U = (mfxU8 *)locked.pBits + desc.Height * locked.Pitch;
ptr->V = ptr->U + 1;
break;
case D3DFMT_YV12:
ptr->Pitch = (mfxU16)locked.Pitch;
ptr->Y = (mfxU8 *)locked.pBits;
ptr->V = ptr->Y + desc.Height * locked.Pitch;
ptr->U = ptr->V + (desc.Height * locked.Pitch) / 4;
break;
case D3DFMT_YUY2:
ptr->Pitch = (mfxU16)locked.Pitch;
ptr->Y = (mfxU8 *)locked.pBits;
ptr->U = ptr->Y + 1;
ptr->V = ptr->Y + 3;
break;
case D3DFMT_R8G8B8:
ptr->Pitch = (mfxU16)locked.Pitch;
ptr->B = (mfxU8 *)locked.pBits;
ptr->G = ptr->B + 1;
ptr->R = ptr->B + 2;
break;
case D3DFMT_A8R8G8B8:
case D3DFMT_A2R10G10B10:
ptr->Pitch = (mfxU16)locked.Pitch;
ptr->B = (mfxU8 *)locked.pBits;
ptr->G = ptr->B + 1;
ptr->R = ptr->B + 2;
ptr->A = ptr->B + 3;
break;
case D3DFMT_P8:
ptr->Pitch = (mfxU16)locked.Pitch;
ptr->Y = (mfxU8 *)locked.pBits;
ptr->U = 0;
ptr->V = 0;
break;
case D3DFMT_P010:
ptr->PitchHigh = (mfxU16)(locked.Pitch / (1 << 16));
ptr->PitchLow = (mfxU16)(locked.Pitch % (1 << 16));
ptr->Y = (mfxU8 *)locked.pBits;
ptr->U = (mfxU8 *)locked.pBits + desc.Height * locked.Pitch;
ptr->V = ptr->U + 1;
break;
}
return MFX_ERR_NONE;
}
mfxStatus dx9_simple_unlock(mfxHDL, mfxMemId mid, mfxFrameData* ptr)
{
if (!mid)
return MFX_ERR_NULL_PTR;
mfxHDLPair *dxmid = (mfxHDLPair*)mid;
IDirect3DSurface9 *pSurface = static_cast<IDirect3DSurface9*>(dxmid->first);
if (pSurface == 0)
return MFX_ERR_INVALID_HANDLE;
pSurface->UnlockRect();
if (NULL != ptr)
{
ptr->Pitch = 0;
ptr->Y = 0;
ptr->U = 0;
ptr->V = 0;
}
return MFX_ERR_NONE;
}
mfxStatus dx9_simple_gethdl(mfxHDL, mfxMemId mid, mfxHDL* handle)
{
if (!mid || !handle)
return MFX_ERR_NULL_PTR;
mfxHDLPair *dxMid = (mfxHDLPair*)mid;
*handle = dxMid->first;
return MFX_ERR_NONE;
}
mfxStatus _dx9_simple_free(mfxFrameAllocResponse* response)
{
if (!response)
return MFX_ERR_NULL_PTR;
mfxStatus sts = MFX_ERR_NONE;
if (response->mids) {
for (mfxU32 i = 0; i < response->NumFrameActual; i++) {
if (response->mids[i]) {
mfxHDLPair *dxMids = (mfxHDLPair*)response->mids[i];
static_cast<IDirect3DSurface9*>(dxMids->first)->Release();
}
}
MSDK_SAFE_FREE(response->mids[0]);
}
MSDK_SAFE_FREE(response->mids);
return sts;
}
mfxStatus dx9_simple_free(mfxHDL pthis, mfxFrameAllocResponse* response)
{
if (NULL == response)
return MFX_ERR_NULL_PTR;
if (dx9_allocResponses.find(response->mids) == dx9_allocResponses.end()) {
// Decode free response handling
if (--dx9_allocDecodeRefCount[pthis] == 0) {
_dx9_simple_free(response);
dx9_allocDecodeResponses.erase(pthis);
dx9_allocDecodeRefCount.erase(pthis);
}
} else {
// Encode and VPP free response handling
dx9_allocResponses.erase(response->mids);
_dx9_simple_free(response);
}
return MFX_ERR_NONE;
}
mfxStatus _dx9_simple_alloc(mfxFrameAllocRequest* request, mfxFrameAllocResponse* response)
{
HRESULT hr;
MSDK_CHECK_POINTER(request, MFX_ERR_NULL_PTR);
if (request->NumFrameSuggested == 0)
return MFX_ERR_UNKNOWN;
D3DFORMAT format = ConvertMfxFourccToD3dFormat(request->Info.FourCC);
if (format == D3DFMT_UNKNOWN)
return MFX_ERR_UNSUPPORTED;
DWORD target;
if (MFX_MEMTYPE_DXVA2_DECODER_TARGET & request->Type)
{
target = DXVA2_VideoDecoderRenderTarget;
}
else if (MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET & request->Type)
{
target = DXVA2_VideoProcessorRenderTarget;
}
else
return MFX_ERR_UNSUPPORTED;
IDirectXVideoAccelerationService* videoService = NULL;
if (target == DXVA2_VideoProcessorRenderTarget) {
if (!m_hProcessor) {
hr = m_manager->OpenDeviceHandle(&m_hProcessor);
if (FAILED(hr))
return MFX_ERR_MEMORY_ALLOC;
hr = m_manager->GetVideoService(m_hProcessor, IID_IDirectXVideoProcessorService, (void**)&m_processorService);
if (FAILED(hr))
return MFX_ERR_MEMORY_ALLOC;
}
videoService = m_processorService;
}
else {
if (!m_hDecoder)
{
hr = m_manager->OpenDeviceHandle(&m_hDecoder);
if (FAILED(hr))
return MFX_ERR_MEMORY_ALLOC;
hr = m_manager->GetVideoService(m_hDecoder, IID_IDirectXVideoDecoderService, (void**)&m_decoderService);
if (FAILED(hr))
return MFX_ERR_MEMORY_ALLOC;
}
videoService = m_decoderService;
}
mfxHDLPair *dxMids = NULL, **dxMidPtrs = NULL;
dxMids = (mfxHDLPair*)calloc(request->NumFrameSuggested, sizeof(mfxHDLPair));
dxMidPtrs = (mfxHDLPair**)calloc(request->NumFrameSuggested, sizeof(mfxHDLPair*));
if (!dxMids || !dxMidPtrs) {
MSDK_SAFE_FREE(dxMids);
MSDK_SAFE_FREE(dxMidPtrs);
return MFX_ERR_MEMORY_ALLOC;
}
response->mids = (mfxMemId*)dxMidPtrs;
response->NumFrameActual = request->NumFrameSuggested;
if (request->Type & MFX_MEMTYPE_EXTERNAL_FRAME) {
for (int i = 0; i < request->NumFrameSuggested; i++) {
hr = videoService->CreateSurface(request->Info.Width, request->Info.Height, 0, format,
D3DPOOL_DEFAULT, m_surfaceUsage, target, (IDirect3DSurface9**)&dxMids[i].first, &dxMids[i].second);
if (FAILED(hr)) {
_dx9_simple_free(response);
MSDK_SAFE_FREE(dxMids);
return MFX_ERR_MEMORY_ALLOC;
}
dxMidPtrs[i] = &dxMids[i];
}
}
else {
safe_array<IDirect3DSurface9*> dxSrf(new IDirect3DSurface9*[request->NumFrameSuggested]);
if (!dxSrf.get())
{
MSDK_SAFE_FREE(dxMids);
return MFX_ERR_MEMORY_ALLOC;
}
hr = videoService->CreateSurface(request->Info.Width, request->Info.Height, request->NumFrameSuggested - 1, format,
D3DPOOL_DEFAULT, m_surfaceUsage, target, dxSrf.get(), NULL);
if (FAILED(hr))
{
MSDK_SAFE_FREE(dxMids);
return MFX_ERR_MEMORY_ALLOC;
}
for (int i = 0; i < request->NumFrameSuggested; i++) {
dxMids[i].first = dxSrf.get()[i];
dxMidPtrs[i] = &dxMids[i];
}
}
return MFX_ERR_NONE;
}
mfxStatus dx9_simple_alloc(mfxHDL pthis, mfxFrameAllocRequest* request, mfxFrameAllocResponse* response)
{
mfxStatus sts = MFX_ERR_NONE;
if (request->Type & MFX_MEMTYPE_SYSTEM_MEMORY)
return MFX_ERR_UNSUPPORTED;
if (dx9_allocDecodeResponses.find(pthis) != dx9_allocDecodeResponses.end() &&
MFX_MEMTYPE_EXTERNAL_FRAME & request->Type &&
MFX_MEMTYPE_FROM_DECODE & request->Type) {
// Memory for this request was already allocated during manual allocation stage. Return saved response
// When decode acceleration device (DXVA) is created it requires a list of d3d surfaces to be passed.
// Therefore Media SDK will ask for the surface info/mids again at Init() stage, thus requiring us to return the saved response
// (No such restriction applies to Encode or VPP)
*response = dx9_allocDecodeResponses[pthis];
dx9_allocDecodeRefCount[pthis]++;
} else {
sts = _dx9_simple_alloc(request, response);
if (MFX_ERR_NONE == sts) {
if ( MFX_MEMTYPE_EXTERNAL_FRAME & request->Type &&
MFX_MEMTYPE_FROM_DECODE & request->Type) {
// Decode alloc response handling
dx9_allocDecodeResponses[pthis] = *response;
dx9_allocDecodeRefCount[pthis]++;
} else {
// Encode and VPP alloc response handling
dx9_allocResponses[response->mids] = pthis;
}
}
}
return sts;
}
/*********************************************************************************
INTEL CORPORATION PROPRIETARY INFORMATION
This software is supplied under the terms of a license agreement or nondisclosure
agreement with Intel Corporation and may not be copied or disclosed except in
accordance with the terms of that agreement
Copyright(c) 2011-2014 Intel Corporation. All Rights Reserved.
**********************************************************************************/
#pragma once
#include "common_utils.h"
#include <initguid.h>
#include <d3d9.h>
#include <dxva2api.h>
#include <dxva.h>
#include <windows.h>
#define VIDEO_MAIN_FORMAT D3DFMT_YUY2
class IGFXS3DControl;
/** Direct3D 9 device implementation.
@note Can be initilized for only 1 or two 2 views. Handle to
MFX_HANDLE_GFXS3DCONTROL must be set prior if initializing for 2 views.
@note Device always set D3DPRESENT_PARAMETERS::Windowed to TRUE.
*/
template <class T>
class safe_array
{
public:
safe_array(T *ptr = 0):m_ptr(ptr)
{ // construct from object pointer
};
~safe_array()
{
reset(0);
}
T* get()
{ // return wrapped pointer
return m_ptr;
}
T* release()
{ // return wrapped pointer and give up ownership
T* ptr = m_ptr;
m_ptr = 0;
return ptr;
}
void reset(T* ptr)
{ // destroy designated object and store new pointer
if (m_ptr)
{
delete[] m_ptr;
}
m_ptr = ptr;
}
protected:
T* m_ptr; // the wrapped object pointer
};
mfxStatus dx9_simple_alloc(mfxHDL pthis, mfxFrameAllocRequest* request, mfxFrameAllocResponse* response);
mfxStatus dx9_simple_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr);
mfxStatus dx9_simple_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData* ptr);
mfxStatus dx9_simple_gethdl(mfxHDL pthis, mfxMemId mid, mfxHDL* handle);
mfxStatus dx9_simple_free(mfxHDL pthis, mfxFrameAllocResponse* response);
mfxStatus DX9_CreateHWDevice(mfxSession session, mfxHDL* deviceHandle, HWND hWnd, bool bCreateSharedHandles);
void DX9_CleanupHWDevice();
......@@ -95,7 +95,7 @@ typedef struct {
int GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize);
// Initialize Intel Media SDK Session, device/display and memory manager
mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mfxFrameAllocator* pmfxAllocator, bool bCreateSharedHandles = false);
mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mfxFrameAllocator* pmfxAllocator, bool bCreateSharedHandles = false, bool dx9hack = false);
// Release resources (device/display)
void Release();
......
......@@ -16,13 +16,14 @@ Copyright(c) 2005-2014 Intel Corporation. All Rights Reserved.
#include "common_directx.h"
#elif DX11_D3D
#include "common_directx11.h"
#include "common_directx9.h"
#endif
/* =======================================================
* Windows implementation of OS-specific utility functions
*/
mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mfxFrameAllocator* pmfxAllocator, bool bCreateSharedHandles)
mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mfxFrameAllocator* pmfxAllocator, bool bCreateSharedHandles, bool dx9hack)
{
bCreateSharedHandles; // (Hugh) Currently unused
pmfxAllocator; // (Hugh) Currently unused
......@@ -30,10 +31,10 @@ mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mf
mfxStatus sts = MFX_ERR_NONE;
// If mfxFrameAllocator is provided it means we need to setup DirectX device and memory allocator
if (pmfxAllocator) {
// Initialize Intel Media SDK Session
sts = pSession->Init(impl, &ver);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
if (pmfxAllocator && !dx9hack) {
// Initialize Intel Media SDK Session
sts = pSession->Init(impl, &ver);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
// Create DirectX device context
mfxHDL deviceHandle;
......@@ -54,13 +55,37 @@ mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession* pSession, mf
// Since we are using video memory we must provide Media SDK with an external allocator
sts = pSession->SetFrameAllocator(pmfxAllocator);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
} else if (pmfxAllocator && dx9hack) {
// Initialize Intel Media SDK Session
sts = pSession->Init(impl, &ver);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
// Create DirectX device context
mfxHDL deviceHandle;
sts = DX9_CreateHWDevice(*pSession, &deviceHandle, NULL, bCreateSharedHandles);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
// Provide device manager to Media SDK
sts = pSession->SetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER, deviceHandle);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
pmfxAllocator->pthis = *pSession; // We use Media SDK session ID as the allocation identifier
pmfxAllocator->Alloc = dx9_simple_alloc;
pmfxAllocator->Free = dx9_simple_free;
pmfxAllocator->Lock = dx9_simple_lock;
pmfxAllocator->Unlock = dx9_simple_unlock;
pmfxAllocator->GetHDL = dx9_simple_gethdl;
// Since we are using video memory we must provide Media SDK with an external allocator
sts = pSession->SetFrameAllocator(pmfxAllocator);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
} else {
// Initialize Intel Media SDK Session
sts = pSession->Init(impl, &ver);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
}
else
{
// Initialize Intel Media SDK Session
sts = pSession->Init(impl, &ver);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
}
return sts;
}
......@@ -68,6 +93,7 @@ void Release()
{
#if defined(DX9_D3D) || defined(DX11_D3D)
CleanupHWDevice();
DX9_CleanupHWDevice();
#endif
}
......
/*********************************************************************************
INTEL CORPORATION PROPRIETARY INFORMATION
This software is supplied under the terms of a license agreement or nondisclosure
agreement with Intel Corporation and may not be copied or disclosed except in
accordance with the terms of that agreement
Copyright(c) 2011-2015 Intel Corporation. All Rights Reserved.
**********************************************************************************/
// #include "mfx_samples_config.h"
#if defined(WIN32) || defined(WIN64)
//prefast singnature used in combaseapi.h
#ifndef _PREFAST_
#pragma warning(disable:4068)
#endif
#include "device_directx9.h"
// #include "igfx_s3dcontrol.h"
#include "atlbase.h"
// Macros
#define MSDK_ZERO_MEMORY(VAR) {memset(&VAR, 0, sizeof(VAR));}
#define MSDK_MEMCPY_VAR(dstVarName, src, count) memcpy_s(&(dstVarName), sizeof(dstVarName), (src), (count))
CD3D9Device::CD3D9Device()
{
m_pD3D9 = NULL;
m_pD3DD9 = NULL;
m_pDeviceManager9 = NULL;
MSDK_ZERO_MEMORY(m_D3DPP);
m_resetToken = 0;
m_nViews = 0;
m_pS3DControl = NULL;
MSDK_ZERO_MEMORY(m_backBufferDesc);
m_pDXVAVPS = NULL;
m_pDXVAVP_Left = NULL;
m_pDXVAVP_Right = NULL;
MSDK_ZERO_MEMORY(m_targetRect);
MSDK_ZERO_MEMORY(m_VideoDesc);
MSDK_ZERO_MEMORY(m_BltParams);
MSDK_ZERO_MEMORY(m_Sample);
// Initialize DXVA structures
DXVA2_AYUVSample16 color = {
0x8000, // Cr
0x8000, // Cb
0x1000, // Y
0xffff // Alpha
};
DXVA2_ExtendedFormat format = { // DestFormat
DXVA2_SampleProgressiveFrame, // SampleFormat
DXVA2_VideoChromaSubsampling_MPEG2, // VideoChromaSubsampling
DXVA_NominalRange_0_255, // NominalRange
DXVA2_VideoTransferMatrix_BT709, // VideoTransferMatrix
DXVA2_VideoLighting_bright, // VideoLighting
DXVA2_VideoPrimaries_BT709, // VideoPrimaries
DXVA2_VideoTransFunc_709 // VideoTransferFunction
};
// init m_VideoDesc structure
MSDK_MEMCPY_VAR(m_VideoDesc.SampleFormat, &format, sizeof(DXVA2_ExtendedFormat));
m_VideoDesc.SampleWidth = 0;
m_VideoDesc.SampleHeight = 0;
m_VideoDesc.InputSampleFreq.Numerator = 60;
m_VideoDesc.InputSampleFreq.Denominator = 1;
m_VideoDesc.OutputFrameFreq.Numerator = 60;
m_VideoDesc.OutputFrameFreq.Denominator = 1;
// init m_BltParams structure
MSDK_MEMCPY_VAR(m_BltParams.DestFormat, &format, sizeof(DXVA2_ExtendedFormat));
MSDK_MEMCPY_VAR(m_BltParams.BackgroundColor, &color, sizeof(DXVA2_AYUVSample16));
// init m_Sample structure
m_Sample.Start = 0;
m_Sample.End = 1;
m_Sample.SampleFormat = format;
m_Sample.PlanarAlpha.Fraction = 0;
m_Sample.PlanarAlpha.Value = 1;
m_bIsA2rgb10 = FALSE;
}
bool CD3D9Device::CheckOverlaySupport()
{
D3DCAPS9 d3d9caps;
D3DOVERLAYCAPS d3doverlaycaps = {0};
IDirect3D9ExOverlayExtension *d3d9overlay = NULL;
bool overlaySupported = false;
memset(&d3d9caps, 0, sizeof(d3d9caps));
HRESULT hr = m_pD3D9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3d9caps);
if (FAILED(hr) || !(d3d9caps.Caps & D3DCAPS_OVERLAY))
{
overlaySupported = false;
}
else
{
hr = m_pD3D9->QueryInterface(IID_PPV_ARGS(&d3d9overlay));
if (FAILED(hr) || (d3d9overlay == NULL))
{
overlaySupported = false;
}
else
{
hr = d3d9overlay->CheckDeviceOverlayType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
m_D3DPP.BackBufferWidth,
m_D3DPP.BackBufferHeight,
m_D3DPP.BackBufferFormat, NULL,
D3DDISPLAYROTATION_IDENTITY, &d3doverlaycaps);
MSDK_SAFE_RELEASE(d3d9overlay);
if (FAILED(hr))
{
overlaySupported = false;
}
else
{
overlaySupported = true;
}
}
}
return overlaySupported;
}
mfxStatus CD3D9Device::FillD3DPP(mfxHDL hWindow, mfxU16 nViews, D3DPRESENT_PARAMETERS &D3DPP)
{
mfxStatus sts = MFX_ERR_NONE;
D3DPP.Windowed = true;
D3DPP.hDeviceWindow = (HWND)hWindow;
D3DPP.Flags = D3DPRESENTFLAG_VIDEO;
D3DPP.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // note that this setting leads to an implicit timeBeginPeriod call
D3DPP.BackBufferCount = 1;
D3DPP.BackBufferFormat = (m_bIsA2rgb10) ? D3DFMT_A2R10G10B10 : D3DFMT_X8R8G8B8;
if (hWindow)
{
RECT r;
GetClientRect((HWND)hWindow, &r);
int x = GetSystemMetrics(SM_CXSCREEN);
int y = GetSystemMetrics(SM_CYSCREEN);
D3DPP.BackBufferWidth = min(r.right - r.left, x);
D3DPP.BackBufferHeight = min(r.bottom - r.top, y);
}
else
{
D3DPP.BackBufferWidth = GetSystemMetrics(SM_CYSCREEN);
D3DPP.BackBufferHeight = GetSystemMetrics(SM_CYSCREEN);
}
//
// Mark the back buffer lockable if software DXVA2 could be used.
// This is because software DXVA2 device requires a lockable render target
// for the optimal performance.
//
{
D3DPP.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
}
bool isOverlaySupported = CheckOverlaySupport();
if (2 == nViews && !isOverlaySupported)
return MFX_ERR_UNSUPPORTED;
bool needOverlay = (2 == nViews) ? true : false;
D3DPP.SwapEffect = needOverlay ? D3DSWAPEFFECT_OVERLAY : D3DSWAPEFFECT_DISCARD;
return sts;
}
mfxStatus CD3D9Device::Init(
mfxHDL hWindow,
mfxU16 nViews,
mfxU32 nAdapterNum)
{
mfxStatus sts = MFX_ERR_NONE;
if (2 < nViews)
return MFX_ERR_UNSUPPORTED;
m_nViews = nViews;
HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_pD3D9);
if (!m_pD3D9 || FAILED(hr))
return MFX_ERR_DEVICE_FAILED;
ZeroMemory(&m_D3DPP, sizeof(m_D3DPP));
sts = FillD3DPP(hWindow, nViews, m_D3DPP);
MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
hr = m_pD3D9->CreateDeviceEx(
nAdapterNum,
D3DDEVTYPE_HAL,
(HWND)hWindow,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
&m_D3DPP,
NULL,
&m_pD3DD9);
if (FAILED(hr))
return MFX_ERR_NULL_PTR;
if(hWindow)
{
hr = m_pD3DD9->ResetEx(&m_D3DPP, NULL);
if (FAILED(hr))
return MFX_ERR_UNDEFINED_BEHAVIOR;
hr = m_pD3DD9->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
if (FAILED(hr))
return MFX_ERR_UNDEFINED_BEHAVIOR;
}
UINT resetToken = 0;
hr = DXVA2CreateDirect3DDeviceManager9(&resetToken, &m_pDeviceManager9);
if (FAILED(hr))
return MFX_ERR_NULL_PTR;
hr = m_pDeviceManager9->ResetDevice(m_pD3DD9, resetToken);
if (FAILED(hr))
return MFX_ERR_UNDEFINED_BEHAVIOR;
m_resetToken = resetToken;
return sts;
}
mfxStatus CD3D9Device::Reset()
{
HRESULT hr = NO_ERROR;
MSDK_CHECK_POINTER(m_pD3DD9, MFX_ERR_NULL_PTR);
if (m_D3DPP.Windowed)
{
RECT r;
GetClientRect((HWND)m_D3DPP.hDeviceWindow, &r);
int x = GetSystemMetrics(SM_CXSCREEN);
int y = GetSystemMetrics(SM_CYSCREEN);
m_D3DPP.BackBufferWidth = min(r.right - r.left, x);
m_D3DPP.BackBufferHeight = min(r.bottom - r.top, y);
}
else
{
m_D3DPP.BackBufferWidth = GetSystemMetrics(SM_CXSCREEN);
m_D3DPP.BackBufferHeight = GetSystemMetrics(SM_CYSCREEN);
}
// Reset will change the parameters, so use a copy instead.
D3DPRESENT_PARAMETERS d3dpp = m_D3DPP;
hr = m_pD3DD9->ResetEx(&d3dpp, NULL);
if (FAILED(hr))
return MFX_ERR_UNDEFINED_BEHAVIOR;
hr = m_pDeviceManager9->ResetDevice(m_pD3DD9, m_resetToken);
if (FAILED(hr))
return MFX_ERR_UNDEFINED_BEHAVIOR;
return MFX_ERR_NONE;
}
void CD3D9Device::Close()
{
MSDK_SAFE_RELEASE(m_pDXVAVP_Left);
MSDK_SAFE_RELEASE(m_pDXVAVP_Right);
MSDK_SAFE_RELEASE(m_pDXVAVPS);
MSDK_SAFE_RELEASE(m_pDeviceManager9);
MSDK_SAFE_RELEASE(m_pD3DD9);
MSDK_SAFE_RELEASE(m_pD3D9);
m_pS3DControl = NULL;
}
CD3D9Device::~CD3D9Device()
{
Close();
}
mfxStatus CD3D9Device::GetHandle(mfxHandleType type, mfxHDL *pHdl)
{
if (MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9 == type && pHdl != NULL)
{
*pHdl = m_pDeviceManager9;
return MFX_ERR_NONE;
}
else if (MFX_HANDLE_GFXS3DCONTROL == type && pHdl != NULL)
{
*pHdl = m_pS3DControl;
return MFX_ERR_NONE;
}
return MFX_ERR_UNSUPPORTED;
}
mfxStatus CD3D9Device::SetHandle(mfxHandleType type, mfxHDL hdl)
{
if (MFX_HANDLE_GFXS3DCONTROL == type && hdl != NULL)
{
m_pS3DControl = (IGFXS3DControl*)hdl;
return MFX_ERR_NONE;
}
else if (MFX_HANDLE_DEVICEWINDOW == type && hdl != NULL) //for render window handle
{
m_D3DPP.hDeviceWindow = (HWND)hdl;
return MFX_ERR_NONE;
}
return MFX_ERR_UNSUPPORTED;
}
mfxStatus CD3D9Device::RenderFrame(mfxFrameSurface1 * pSurface, mfxFrameAllocator * pmfxAlloc)
{
HRESULT hr = S_OK;
if (!(1 == m_nViews || (2 == m_nViews && NULL != m_pS3DControl)))
return MFX_ERR_UNDEFINED_BEHAVIOR;
MSDK_CHECK_POINTER(pSurface, MFX_ERR_NULL_PTR);
MSDK_CHECK_POINTER(m_pDeviceManager9, MFX_ERR_NOT_INITIALIZED);
MSDK_CHECK_POINTER(pmfxAlloc, MFX_ERR_NULL_PTR);
// don't try to render second view if output rect changed since first view
if (2 == m_nViews && (0 != pSurface->Info.FrameId.ViewId))
return MFX_ERR_NONE;
hr = m_pD3DD9->TestCooperativeLevel();
switch (hr)
{
case D3D_OK :
break;
case D3DERR_DEVICELOST :
{
return MFX_ERR_DEVICE_LOST;
}
case D3DERR_DEVICENOTRESET :
{
return MFX_ERR_UNKNOWN;
}
default :
{
return MFX_ERR_UNKNOWN;
}
}
CComPtr<IDirect3DSurface9> pBackBuffer;
hr = m_pD3DD9->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
mfxHDLPair* dxMemId = (mfxHDLPair*)pSurface->Data.MemId;
hr = m_pD3DD9->StretchRect((IDirect3DSurface9*)dxMemId->first, NULL, pBackBuffer, NULL, D3DTEXF_LINEAR);
if (FAILED(hr))
{
return MFX_ERR_UNKNOWN;
}
if (SUCCEEDED(hr)&& (1 == m_nViews || pSurface->Info.FrameId.ViewId == 1))
{
hr = m_pD3DD9->Present(NULL, NULL, NULL, NULL);
}
return SUCCEEDED(hr) ? MFX_ERR_NONE : MFX_ERR_DEVICE_FAILED;
}
/*
mfxStatus CD3D9Device::CreateVideoProcessors()
{
if (!(1 == m_nViews || (2 == m_nViews && NULL != m_pS3DControl)))
return MFX_ERR_UNDEFINED_BEHAVIOR;
MSDK_SAFE_RELEASE(m_pDXVAVP_Left);
MSDK_SAFE_RELEASE(m_pDXVAVP_Right);
HRESULT hr ;
if (2 == m_nViews && NULL != m_pS3DControl)
{
hr = m_pS3DControl->SetDevice(m_pDeviceManager9);
if (FAILED(hr))
{
return MFX_ERR_DEVICE_FAILED;
}
}
ZeroMemory(&m_backBufferDesc, sizeof(m_backBufferDesc));
IDirect3DSurface9 *backBufferTmp = NULL;
hr = m_pD3DD9->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBufferTmp);
if (NULL != backBufferTmp)
backBufferTmp->GetDesc(&m_backBufferDesc);
MSDK_SAFE_RELEASE(backBufferTmp);
if (SUCCEEDED(hr))
{
// Create DXVA2 Video Processor Service.
hr = DXVA2CreateVideoService(m_pD3DD9,
IID_IDirectXVideoProcessorService,
(void**)&m_pDXVAVPS);
}
if (2 == m_nViews)
{
// Activate L channel
if (SUCCEEDED(hr))
{
hr = m_pS3DControl->SelectLeftView();
}
if (SUCCEEDED(hr))
{
// Create VPP device for the L channel
hr = m_pDXVAVPS->CreateVideoProcessor(DXVA2_VideoProcProgressiveDevice,
&m_VideoDesc,
m_D3DPP.BackBufferFormat,
1,
&m_pDXVAVP_Left);
}
// Activate R channel
if (SUCCEEDED(hr))
{
hr = m_pS3DControl->SelectRightView();
}
}
if (SUCCEEDED(hr))
{
hr = m_pDXVAVPS->CreateVideoProcessor(DXVA2_VideoProcProgressiveDevice,
&m_VideoDesc,
m_D3DPP.BackBufferFormat,
1,
&m_pDXVAVP_Right);
}
return SUCCEEDED(hr) ? MFX_ERR_NONE : MFX_ERR_DEVICE_FAILED;
}
*/
#endif // #if defined(WIN32) || defined(WIN64)
\ No newline at end of file
/*********************************************************************************
INTEL CORPORATION PROPRIETARY INFORMATION
This software is supplied under the terms of a license agreement or nondisclosure
agreement with Intel Corporation and may not be copied or disclosed except in
accordance with the terms of that agreement
Copyright(c) 2011-2014 Intel Corporation. All Rights Reserved.
**********************************************************************************/
#pragma once
#if defined( _WIN32 ) || defined ( _WIN64 )
#include "common_utils.h"
#pragma warning(disable : 4201)
#include <initguid.h>
#include <d3d9.h>
#include <dxva2api.h>
#include <dxva.h>
#include <windows.h>
#define VIDEO_MAIN_FORMAT D3DFMT_YUY2
class IGFXS3DControl;
/// Base class for hw device
class CHWDevice
{
public:
virtual ~CHWDevice(){}
/** Initializes device for requested processing.
@param[in] hWindow Window handle to bundle device to.
@param[in] nViews Number of views to process.
@param[in] nAdapterNum Number of adapter to use
*/
virtual mfxStatus Init(
mfxHDL hWindow,
mfxU16 nViews,
mfxU32 nAdapterNum) = 0;
/// Reset device.
virtual mfxStatus Reset() = 0;
/// Get handle can be used for MFX session SetHandle calls
virtual mfxStatus GetHandle(mfxHandleType type, mfxHDL *pHdl) = 0;
/** Set handle.
Particular device implementation may require other objects to operate.
*/
virtual mfxStatus SetHandle(mfxHandleType type, mfxHDL hdl) = 0;
virtual mfxStatus RenderFrame(mfxFrameSurface1 * pSurface, mfxFrameAllocator * pmfxAlloc) = 0;
virtual void Close() = 0;
};
enum {
MFX_HANDLE_GFXS3DCONTROL = 0x100, /* A handle to the IGFXS3DControl instance */
MFX_HANDLE_DEVICEWINDOW = 0x101 /* A handle to the render window */
}; //mfxHandleType
/** Direct3D 9 device implementation.
@note Can be initilized for only 1 or two 2 views. Handle to
MFX_HANDLE_GFXS3DCONTROL must be set prior if initializing for 2 views.
@note Device always set D3DPRESENT_PARAMETERS::Windowed to TRUE.
*/
class CD3D9Device : public CHWDevice
{
public:
CD3D9Device();
virtual ~CD3D9Device();
virtual mfxStatus Init(
mfxHDL hWindow,
mfxU16 nViews,
mfxU32 nAdapterNum);
virtual mfxStatus Reset();
virtual mfxStatus GetHandle(mfxHandleType type, mfxHDL *pHdl);
virtual mfxStatus SetHandle(mfxHandleType type, mfxHDL hdl);
virtual mfxStatus RenderFrame(mfxFrameSurface1 * pSurface, mfxFrameAllocator * pmfxAlloc);
virtual void UpdateTitle(double /*fps*/) { }
virtual void Close() ;
void DefineFormat(bool isA2rgb10) { m_bIsA2rgb10 = (isA2rgb10) ? TRUE : FALSE; }
protected:
mfxStatus CreateVideoProcessors();
bool CheckOverlaySupport();
virtual mfxStatus FillD3DPP(mfxHDL hWindow, mfxU16 nViews, D3DPRESENT_PARAMETERS &D3DPP);
private:
IDirect3D9Ex* m_pD3D9;
IDirect3DDevice9Ex* m_pD3DD9;
IDirect3DDeviceManager9* m_pDeviceManager9;
D3DPRESENT_PARAMETERS m_D3DPP;
UINT m_resetToken;
mfxU16 m_nViews;
IGFXS3DControl* m_pS3DControl;
D3DSURFACE_DESC m_backBufferDesc;
// service required to create video processors
IDirectXVideoProcessorService* m_pDXVAVPS;
//left channel processor
IDirectXVideoProcessor* m_pDXVAVP_Left;
// right channel processor
IDirectXVideoProcessor* m_pDXVAVP_Right;
// target rectangle
RECT m_targetRect;
// various structures for DXVA2 calls
DXVA2_VideoDesc m_VideoDesc;
DXVA2_VideoProcessBltParams m_BltParams;
DXVA2_VideoSample m_Sample;
BOOL m_bIsA2rgb10;
};
#endif // #if defined( _WIN32 ) || defined ( _WIN64 )
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册