1
0
Fork 0

Experimental - Fixed D3D11 + VC1 freeze. Fixed D3D9 playback. Win7 is functional too. Need some more testing for release. This commit contains some code cosmetics too.

git-svn-id: svn://svn.code.sf.net/p/qsdecoder/code/trunk/IntelQuickSyncDecoder@86 dfccccb7-dd81-40b7-a334-5a7ba89c2b1d
This commit is contained in:
egur 2013-05-16 19:46:37 +00:00
parent 18e36fae96
commit 16f7888f92
9 changed files with 83 additions and 59 deletions

View File

@ -106,14 +106,27 @@ CQuickSync::CQuickSync() :
// m_Config.nVppDenoiseStrength = 16; // 0-64
// m_Config.bDropDuplicateFrames = true;
#if MFX_D3D11_SUPPORT
// m_Config.bEnableD3D11 = true;
#endif
DWORD dwVersion = GetVersion();
DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
// No QS support for Windows version older than Vista
if (dwMajorVersion < 6)
{
sts = MFX_ERR_UNSUPPORTED;
return;
}
// D3D11 decode was introduced with Win8 (Windows 6.2)
// Window Vidta and 7 can use D3D9
else if ((dwMajorVersion == 6 && dwMinorVersion >= 2) || (dwMajorVersion > 6))
{
#if MFX_D3D11_SUPPORT
m_Config.bEnableD3D11 = true;
#endif
}
m_pDecoder = new CQuickSyncDecoder(m_Config, sts);
m_OK = (sts == MFX_ERR_NONE);
m_OK = MSDK_SUCCEEDED(sts);
}
CQuickSync::~CQuickSync()
@ -243,11 +256,11 @@ HRESULT CQuickSync::TestMediaType(const AM_MEDIA_TYPE* mtIn, FOURCC fourCC)
MSDK_SAFE_DELETE(pFrameConstructor);
MSDK_CHECK_RESULT_P_RET(hr, S_OK);
// If SW emulation is disabled - check if HW accelaration is supported
// If SW emulation is disabled - check if HW acceleration is supported
if (!m_Config.bEnableSwEmulation)
{
mfxStatus sts = m_pDecoder->CheckHwAcceleration(&videoParams);
if (sts != MFX_ERR_NONE)
if (MSDK_FAILED(sts))
{
MSDK_TRACE("HW accelration is not supported. Aborting!\n");
hr = E_FAIL;
@ -350,19 +363,19 @@ HRESULT CQuickSync::DecodeHeader(
if (nVideoInfoSize < nSampleSize)
{
sts = pFrameConstructor->ConstructHeaders(vih2, guidFormat, nSampleSize, nVideoInfoSize);
if (MFX_ERR_NONE == sts)
if (MSDK_SUCCEEDED(sts))
{
sts = m_pDecoder->DecodeHeader(&pFrameConstructor->GetHeaders(), &videoParams);
if (sts != MFX_ERR_NONE)
if (MSDK_FAILED(sts))
{
MSDK_TRACE("QsDecoder: Warning DecodeHeader failed!\n");
// ASSERT(sts == MFX_ERR_NONE);
// ASSERT(MSDK_SUCCEEDED(sts));
}
}
}
// Simple info header (without extra data) or DecodeHeader failed (usually not critical, in many cases header will appear later in the stream)
if (nVideoInfoSize == nSampleSize || sts != MFX_ERR_NONE)
if (nVideoInfoSize == nSampleSize || MSDK_FAILED(sts))
{
mfx.FrameInfo.CropW = (mfxU16)vih2->bmiHeader.biWidth;
mfx.FrameInfo.CropH = (mfxU16)vih2->bmiHeader.biHeight;
@ -388,7 +401,7 @@ HRESULT CQuickSync::DecodeHeader(
sts = MFX_ERR_NONE;
}
hr = (sts == MFX_ERR_NONE) ? S_OK : E_FAIL;
hr = (MSDK_SUCCEEDED(sts)) ? S_OK : E_FAIL;
if (FAILED(hr))
{
@ -521,7 +534,7 @@ HRESULT CQuickSync::InitDecoder(const AM_MEDIA_TYPE* mtIn, FOURCC fourCC)
// Initialization of Media SDK decoder is done in OnSeek to allow late initialization needed
// by full screen exclusive (FSE) mode since D3D devices can't be created. The DS filter must send
// the D3D device manager to this decoder for surface allocation.
if (sts == MFX_ERR_NONE)
if (MSDK_SUCCEEDED(sts))
{
m_pDecoder->SetConfig(m_Config);
size_t surfaceCount = max(8, m_Config.nOutputQueueLength);
@ -538,7 +551,7 @@ HRESULT CQuickSync::InitDecoder(const AM_MEDIA_TYPE* mtIn, FOURCC fourCC)
"Intel\xae QuickSync Decoder (%s)" , ::GetCodecName(m_DecVideoParams.mfx.CodecId));
delete[] (mfxU8*)vih2;
m_OK = (sts == MFX_ERR_NONE);
m_OK = MSDK_SUCCEEDED(sts);
return (m_OK) ? S_OK : E_FAIL;
}
@ -558,7 +571,7 @@ void CQuickSync::SetAspectRatio(VIDEOINFOHEADER2& vih2, mfxFrameInfo& frameInfo)
frameInfo.CropW, frameInfo.CropH,
frameInfo.AspectRatioW, frameInfo.AspectRatioH);
if (sts != MFX_ERR_NONE)
if (MSDK_FAILED(sts))
{
frameInfo.AspectRatioW = frameInfo.AspectRatioH = 1;
}
@ -625,7 +638,7 @@ HRESULT CQuickSync::Decode(IMediaSample* pSample)
// Decode the bitstream
sts = m_pDecoder->Decode(&mfxBS, pSurfaceOut);
if (MFX_ERR_NONE == sts)
if (MSDK_SUCCEEDED(sts))
{
// Sync decode - pSurfaceOut holds decoded surface
if (NULL != pSurfaceOut)
@ -690,7 +703,7 @@ HRESULT CQuickSync::Decode(IMediaSample* pSample)
memcpy(&m_DecVideoParams, &VideoParams, sizeof(mfxVideoParam));
m_nPitch = MSDK_ALIGN32(m_DecVideoParams.mfx.FrameInfo.Width);
sts = m_pDecoder->Reset(&m_DecVideoParams, m_nPitch);
if (MFX_ERR_NONE == sts)
if (MSDK_SUCCEEDED(sts))
{
continue;
}
@ -879,12 +892,12 @@ HRESULT CQuickSync::Flush(bool deliverFrames)
FlushOutputQueue();
// Flush HW decoder by sending NULL bitstreams.
while (MFX_ERR_NONE == sts || MFX_ERR_MORE_SURFACE == sts)
while (MSDK_SUCCEEDED(sts) || MFX_ERR_MORE_SURFACE == sts)
{
mfxFrameSurface1* pSurf = NULL;
sts = m_pDecoder->Decode(NULL, pSurf);
if (MFX_ERR_NONE == sts && !m_bNeedToFlush)
if (MSDK_SUCCEEDED(sts) && !m_bNeedToFlush)
{
ProcessDecodedFrame(pSurf);
}
@ -953,7 +966,7 @@ HRESULT CQuickSync::OnSeek(REFERENCE_TIME /* segmentStart */)
}
sts = m_pDecoder->Reset(&m_DecVideoParams, m_nPitch);
if (sts != MFX_ERR_NONE)
if (MSDK_FAILED(sts))
{
MSDK_TRACE("QsDecoder: reset failed!\n");
return E_FAIL;
@ -964,7 +977,7 @@ HRESULT CQuickSync::OnSeek(REFERENCE_TIME /* segmentStart */)
m_bNeedToFlush = false;
MSDK_TRACE("QsDecoder: OnSeek complete\n");
return (sts == MFX_ERR_NONE) ? S_OK : E_FAIL;
return (MSDK_SUCCEEDED(sts)) ? S_OK : E_FAIL;
}
bool CQuickSync::SetTimeStamp(mfxFrameSurface1* pSurface, REFERENCE_TIME& rtStart)

View File

@ -58,7 +58,7 @@ CQuickSyncDecoder::CQuickSyncDecoder(const CQsConfig& cfg, mfxStatus& sts) :
//impl = MFX_IMPL_SOFTWARE;
sts = InitSession(impl);
if (sts == MFX_ERR_NONE && !m_Config.bEnableD3D11 && 0 > GetIntelAdapterIdD3D9(NULL))
if (MSDK_SUCCEEDED(sts) && !m_Config.bEnableD3D11 && 0 > GetIntelAdapterIdD3D9(NULL))
{
MSDK_TRACE("QsDecoder: can't create HW decoder, the iGPU is not connected to a screen!\n");
sts = MFX_ERR_UNSUPPORTED;
@ -81,7 +81,7 @@ mfxStatus CQuickSyncDecoder::InitSession(mfxIMPL impl)
m_mfxVideoSession = new MFXVideoSession;
mfxStatus sts = m_mfxVideoSession->Init(impl, &m_ApiVersion);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
{
MSDK_TRACE("QsDecoder: failed to initialize MSDK session!\n");
return sts;
@ -101,12 +101,15 @@ mfxStatus CQuickSyncDecoder::InitSession(mfxIMPL impl)
{
int nAdapterID = GetMSDKAdapterNumber(*m_mfxVideoSession);
m_HwDevice = new CD3D11Device();
if (MFX_ERR_NONE != (sts = m_HwDevice->Init(nAdapterID)))
if (NULL == m_HwDevice)
{
MSDK_TRACE("QsDecoder: D3D11 init have failed!\n");
MSDK_SAFE_DELETE(m_HwDevice);
return sts;
m_HwDevice = new CD3D11Device();
if (MSDK_FAILED(sts = m_HwDevice->Init(nAdapterID)))
{
MSDK_TRACE("QsDecoder: D3D11 init have failed!\n");
MSDK_SAFE_DELETE(m_HwDevice);
return sts;
}
}
mfxHDL h = m_HwDevice->GetHandle(MFX_HANDLE_D3D11_DEVICE);
@ -254,16 +257,24 @@ mfxStatus CQuickSyncDecoder::InternalReset(mfxVideoParam* pVideoParams, mfxU32 n
MSDK_CHECK_RESULT_P_RET(sts, MFX_ERR_NONE);
if (m_bUseD3DAlloc)
{
// get relevant handle from HW device and notify the session
mfxHandleType hType = (m_bUseD3D11Alloc) ? MFX_HANDLE_D3D11_DEVICE : MFX_HANDLE_D3D9_DEVICE_MANAGER;
mfxHDL h = m_HwDevice->GetHandle(hType);
m_mfxVideoSession->SetHandle(hType, h);
// get D3D9 handle from HW device and notify the session
if (!m_bUseD3D11Alloc)
{
mfxHDL h = m_HwDevice->GetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER);
sts = m_mfxVideoSession->SetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER, h);
if (MSDK_FAILED(sts))
{
MSDK_TRACE("QsDecoder: Session SetHandle failed!\n");
return sts;
}
}
// Note - setting the session allocator can be done only once (per session)!
sts = m_mfxVideoSession->SetFrameAllocator(m_pFrameAllocator);
if (sts != MFX_ERR_NONE)
if (MSDK_FAILED(sts))
{
MSDK_TRACE("QsDecoder: Session SetFrameAllocator failed!\n");
return sts;
}
}
@ -273,7 +284,7 @@ mfxStatus CQuickSyncDecoder::InternalReset(mfxVideoParam* pVideoParams, mfxU32 n
{
sts = m_pmfxDEC->Reset(pVideoParams);
// Need to reset the frame allocator
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
{
m_pmfxDEC->Close();
FreeFrameAllocator();
@ -376,12 +387,12 @@ mfxStatus CQuickSyncDecoder::Decode(mfxBitstream* pBS, mfxFrameSurface1*& pOutSu
} while (MFX_WRN_DEVICE_BUSY == sts || MFX_ERR_MORE_SURFACE == sts);
// Output will be shortly available
if (MFX_ERR_NONE == sts)
if (MSDK_SUCCEEDED(sts))
{
// Wait for the asynch decoding to finish
sts = m_mfxVideoSession->SyncOperation(syncp, 0xFFFF);
if (MFX_ERR_NONE == sts)
if (MSDK_SUCCEEDED(sts))
{
// The surface is locked from being reused in another Decode call
LockSurface(pOutSurface);
@ -597,7 +608,7 @@ mfxStatus CQuickSyncDecoder::CreateAllocator()
// Having the D3D9 device manager from the renderer allows working in full screen exclusive mode
// This parameter can be NULL for other usages
m_HwDevice = new CD3D9Device(m_pRendererD3dDeviceManager);
if (MFX_ERR_NONE != (sts = m_HwDevice->Init(nAdapterID)))
if (MSDK_FAILED(sts = m_HwDevice->Init(nAdapterID)))
{
MSDK_TRACE("QsDecoder: D3D9 init have failed!\n");
MSDK_SAFE_DELETE(m_HwDevice);
@ -605,8 +616,8 @@ mfxStatus CQuickSyncDecoder::CreateAllocator()
}
// Set the pointer to the HW device (or device manager) to the session
mfxHDL h = m_HwDevice->GetHandle(MFX_HANDLE_D3D11_DEVICE);
sts = m_mfxVideoSession->SetHandle(MFX_HANDLE_D3D11_DEVICE, h);
mfxHDL h = m_HwDevice->GetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER);
sts = m_mfxVideoSession->SetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER, h);
MSDK_CHECK_NOT_EQUAL(sts, MFX_ERR_NONE, sts);
D3DAllocatorParams* p = new D3DAllocatorParams;
@ -624,11 +635,11 @@ mfxStatus CQuickSyncDecoder::CreateAllocator()
}
sts = m_pFrameAllocator->Init(pParam.get());
if (sts == MFX_ERR_NONE)
if (MSDK_SUCCEEDED(sts))
{
// Note - setting the session allocator can be done only once per session!
sts = m_mfxVideoSession->SetFrameAllocator(m_pFrameAllocator);
if (sts != MFX_ERR_NONE)
if (MSDK_FAILED(sts))
{
MSDK_TRACE("QsDecoder: Session SetFrameAllocator failed!\n");
}

View File

@ -105,7 +105,7 @@ DWORD __stdcall check()
// Test SW emulation
pSession->Close();
sts = pSession->Init(MFX_IMPL_SOFTWARE, &apiVersion);
if (MFX_ERR_NONE == sts)
if (MSDK_SUCCEEDED(sts))
{
caps |= QS_CAP_SW_EMULATION;
}

View File

@ -243,7 +243,7 @@ mfxStatus CQuickSyncVPP::Reset(const CQsConfig& config, MFXVideoSession* pVideoS
sts = m_pVPP->Reset(&m_VppVideoParams);
MSDK_IGNORE_MFX_STS(sts, MFX_WRN_PARTIAL_ACCELERATION);
MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
if (sts == MFX_ERR_NONE)
if (MSDK_SUCCEEDED(sts))
{
return MFX_ERR_NONE;
}
@ -483,5 +483,5 @@ mfxFrameSurface1* CQuickSyncVPP::FlushFrame()
// Run VPP
mfxStatus sts = Process(NULL, pOutSurface);
return (MFX_ERR_NONE == sts || MFX_ERR_MORE_SURFACE == sts) ? pOutSurface : NULL;
return (MSDK_SUCCEEDED(sts) || MFX_ERR_MORE_SURFACE == sts) ? pOutSurface : NULL;
}

View File

@ -51,6 +51,8 @@
OutputDebugString(msg); \
_tperror(msg);\
}
#define MSDK_SUCCEEDED(P) (MFX_ERR_NONE == (P))
#define MSDK_FAILED(P) (MFX_ERR_NONE != (P))
#define MSDK_CHECK_ERROR(P, X, ERR) { if ((X) == (P)) { MSDK_PRINT_RET_MSG(ERR); return ERR; } }
#define MSDK_CHECK_NOT_EQUAL(P, X, ERR) { if ((X) != (P)) { MSDK_PRINT_RET_MSG(ERR); return ERR; } }
#define MSDK_CHECK_RESULT_P_RET(P, X) { if ((X) != (P)) { return P; } }
@ -67,8 +69,6 @@
#define MSDK_ALIGN16(SZ) ((SZ + 15) & (~15)) // round up to a multiple of 16
#define MSDK_ALIGN32(SZ) ((SZ + 31) & (~31)) // round up to a multiple of 32
#define MSDK_MEMCPY_VAR(dstVarName, src, count) memcpy_s(&(dstVarName), sizeof(dstVarName), (src), (count))
#ifdef _DEBUG
# define ASSERT(_x_) { if (!(_x_)) DebugAssert(_T(#_x_),_T(__FILE__),__LINE__); }
#else

View File

@ -126,7 +126,7 @@ mfxStatus BaseFrameAllocator::AllocFrames(mfxFrameAllocRequest *request, mfxFram
if (0 == request || 0 == response || 0 == request->NumFrameSuggested)
return MFX_ERR_MEMORY_ALLOC;
if (MFX_ERR_NONE != CheckRequestType(request))
if (MSDK_FAILED(CheckRequestType(request)))
return MFX_ERR_UNSUPPORTED;
mfxStatus sts = MFX_ERR_NONE;
@ -152,7 +152,7 @@ mfxStatus BaseFrameAllocator::AllocFrames(mfxFrameAllocRequest *request, mfxFram
else
{
sts = AllocImpl(request, response);
if (sts == MFX_ERR_NONE)
if (MSDK_SUCCEEDED(sts))
{
m_ExtResponses.push_back(UniqueResponse(*response, request->Info.CropW, request->Info.CropH, request->Type & MEMTYPE_FROM_MASK));
}
@ -166,7 +166,7 @@ mfxStatus BaseFrameAllocator::AllocFrames(mfxFrameAllocRequest *request, mfxFram
m_responses.push_back(mfxFrameAllocResponse());
sts = AllocImpl(request, response);
if (sts == MFX_ERR_NONE)
if (MSDK_SUCCEEDED(sts))
{
m_responses.back() = *response;
}

View File

@ -276,7 +276,7 @@ mfxStatus D3D11FrameAllocator::GetFrameHDL(mfxMemId mid, mfxHDL *handle)
mfxStatus D3D11FrameAllocator::CheckRequestType(mfxFrameAllocRequest *request)
{
mfxStatus sts = BaseFrameAllocator::CheckRequestType(request);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
return sts;
if ((request->Type & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)) != 0)

View File

@ -243,7 +243,7 @@ mfxStatus D3DFrameAllocator::GetFrameHDL(mfxMemId mid, mfxHDL *handle)
mfxStatus D3DFrameAllocator::CheckRequestType(mfxFrameAllocRequest *request)
{
mfxStatus sts = BaseFrameAllocator::CheckRequestType(request);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
return sts;
if ((request->Type & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)) != 0)
@ -267,7 +267,7 @@ mfxStatus D3DFrameAllocator::ReleaseResponse(mfxFrameAllocResponse *response)
{
IDirect3DSurface9* handle = 0;
sts = GetFrameHDL(response->mids[i], (mfxHDL *)&handle);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
return sts;
handle->Release();
}
@ -378,7 +378,7 @@ mfxStatus D3DFrameAllocator::AllocImpl(mfxFrameAllocRequest *request, mfxFrameAl
for (mfxU32 i = 0; i < request->NumFrameSuggested; i++)
{
mfxFrameData pData;
if (MFX_ERR_NONE == LockFrame(mids.get()[i], &pData))
if (MSDK_SUCCEEDED(LockFrame(mids.get()[i], &pData)))
{
if (format == D3DFMT_NV12 ||
format == D3DFMT_YV12)

View File

@ -97,7 +97,7 @@ mfxStatus SysMemFrameAllocator::LockFrame(mfxMemId mid, mfxFrameData *ptr)
sFrame *fs = 0;
mfxStatus sts = m_pBufferAllocator->Lock(m_pBufferAllocator->pthis, mid,(mfxU8 **)&fs);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
return sts;
if (ID_FRAME != fs->id)
@ -152,7 +152,7 @@ mfxStatus SysMemFrameAllocator::UnlockFrame(mfxMemId mid, mfxFrameData *ptr)
mfxStatus sts = m_pBufferAllocator->Unlock(m_pBufferAllocator->pthis, mid);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
return sts;
if (NULL != ptr)
@ -174,7 +174,7 @@ mfxStatus SysMemFrameAllocator::GetFrameHDL(mfxMemId mid, mfxHDL *handle)
mfxStatus SysMemFrameAllocator::CheckRequestType(mfxFrameAllocRequest *request)
{
mfxStatus sts = BaseFrameAllocator::CheckRequestType(request);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
return sts;
if ((request->Type & MFX_MEMTYPE_SYSTEM_MEMORY) != 0)
@ -223,13 +223,13 @@ mfxStatus SysMemFrameAllocator::AllocImpl(mfxFrameAllocRequest *request, mfxFram
mfxStatus sts = m_pBufferAllocator->Alloc(m_pBufferAllocator->pthis,
nbytes + MSDK_ALIGN32(sizeof(sFrame)), request->Type, &(mids.get()[numAllocated]));
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
break;
sFrame *fs;
sts = m_pBufferAllocator->Lock(m_pBufferAllocator->pthis, mids.get()[numAllocated], (mfxU8 **)&fs);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
break;
fs->id = ID_FRAME;
@ -266,7 +266,7 @@ mfxStatus SysMemFrameAllocator::ReleaseResponse(mfxFrameAllocResponse *response)
if (response->mids[i])
{
sts = m_pBufferAllocator->Free(m_pBufferAllocator->pthis, response->mids[i]);
if (MFX_ERR_NONE != sts)
if (MSDK_FAILED(sts))
return sts;
}
}