aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwsoltys <wiso@xbmc.org>2013-12-07 08:21:48 -0800
committerwsoltys <wiso@xbmc.org>2013-12-07 08:21:48 -0800
commit04bb49cc4475778a82da86673d3f3486193c5354 (patch)
tree1ba36ed5a4839bd4a5cba36891b263918fb45706
parente4fcdc6331aa91aad920ffbf813be84475ae2f67 (diff)
parent416c613423acf6658e361c03c57ec9fa9a3218fc (diff)
Merge pull request #3589 from afedchin/dxva-hd
[dxva] added dxva-hd renderer as alternative native dxva video processing.
-rwxr-xr-xlanguage/English/strings.po7
-rw-r--r--project/VS2010Express/XBMC.vcxproj2
-rw-r--r--project/VS2010Express/XBMC.vcxproj.filters6
-rw-r--r--xbmc/cores/VideoRenderers/BaseRenderer.cpp2
-rw-r--r--xbmc/cores/VideoRenderers/BaseRenderer.h1
-rw-r--r--xbmc/cores/VideoRenderers/WinRenderer.cpp77
-rw-r--r--xbmc/cores/VideoRenderers/WinRenderer.h5
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h24
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp691
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h114
10 files changed, 888 insertions, 41 deletions
diff --git a/language/English/strings.po b/language/English/strings.po
index 0cb5e05d0f..bab2c1288d 100755
--- a/language/English/strings.po
+++ b/language/English/strings.po
@@ -7145,7 +7145,12 @@ msgctxt "#16325"
msgid "VDPAU - Bob"
msgstr ""
-#empty strings from id 16326 to 16399
+#: xbmc/cores/VideoRenderers/BaseRenderer.cpp
+msgctxt "#16326"
+msgid "DXVA-HD"
+msgstr ""
+
+#empty strings from id 16327 to 16399
#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
msgctxt "#16400"
diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj
index 1ab7191062..3d3b73fae5 100644
--- a/project/VS2010Express/XBMC.vcxproj
+++ b/project/VS2010Express/XBMC.vcxproj
@@ -1742,6 +1742,7 @@
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecLibMpeg2.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoPPFFmpeg.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVA.cpp" />
+ <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVAHD.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodec.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodecCC.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodecFFmpeg.cpp" />
@@ -2534,6 +2535,7 @@
<ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecLibMpeg2.h" />
<ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoPPFFmpeg.h" />
<ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVA.h" />
+ <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVAHD.h" />
<ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlay.h" />
<ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodec.h" />
<ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodecCC.h" />
diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters
index 2686e76a57..007ffb99f5 100644
--- a/project/VS2010Express/XBMC.vcxproj.filters
+++ b/project/VS2010Express/XBMC.vcxproj.filters
@@ -426,6 +426,9 @@
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVA.cpp">
<Filter>cores\dvdplayer\DVDCodecs\Video</Filter>
</ClCompile>
+ <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVAHD.cpp">
+ <Filter>cores\dvdplayer\DVDCodecs\Video</Filter>
+ </ClCompile>
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodec.cpp">
<Filter>cores\dvdplayer\DVDCodecs\Overlay</Filter>
</ClCompile>
@@ -3241,6 +3244,9 @@
<ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVA.h">
<Filter>cores\dvdplayer\DVDCodecs\Video</Filter>
</ClInclude>
+ <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVAHD.h">
+ <Filter>cores\dvdplayer\DVDCodecs\Video</Filter>
+ </ClInclude>
<ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlay.h">
<Filter>cores\dvdplayer\DVDCodecs\Overlay</Filter>
</ClInclude>
diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoRenderers/BaseRenderer.cpp
index 85dde4ab5b..40a2a80129 100644
--- a/xbmc/cores/VideoRenderers/BaseRenderer.cpp
+++ b/xbmc/cores/VideoRenderers/BaseRenderer.cpp
@@ -731,6 +731,8 @@ void CBaseRenderer::SettingOptionsRenderMethodsFiller(const CSetting *setting, s
list.push_back(make_pair(g_localizeStrings.Get(13416), RENDER_METHOD_AUTO));
#ifdef HAS_DX
+ if (CSysInfo::IsWindowsVersionAtLeast(CSysInfo::WindowsVersionWin7))
+ list.push_back(make_pair(g_localizeStrings.Get(16326), RENDER_METHOD_DXVAHD));
list.push_back(make_pair(g_localizeStrings.Get(16319), RENDER_METHOD_DXVA));
list.push_back(make_pair(g_localizeStrings.Get(13431), RENDER_METHOD_D3D_PS));
list.push_back(make_pair(g_localizeStrings.Get(13419), RENDER_METHOD_SOFTWARE));
diff --git a/xbmc/cores/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoRenderers/BaseRenderer.h
index a61d3cfd77..5a21fece55 100644
--- a/xbmc/cores/VideoRenderers/BaseRenderer.h
+++ b/xbmc/cores/VideoRenderers/BaseRenderer.h
@@ -63,6 +63,7 @@ enum RenderMethods
RENDER_METHOD_SOFTWARE,
RENDER_METHOD_D3D_PS,
RENDER_METHOD_DXVA,
+ RENDER_METHOD_DXVAHD,
RENDER_OVERLAYS = 99 // to retain compatibility
};
diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp
index 599f3f42d0..525027d3b8 100644
--- a/xbmc/cores/VideoRenderers/WinRenderer.cpp
+++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp
@@ -20,24 +20,25 @@
#ifdef HAS_DX
-#include "WinRenderer.h"
+#include "DllSwScale.h"
#include "Util.h"
+#include "WinRenderer.h"
+#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h"
+#include "dialogs/GUIDialogKaiToast.h"
+#include "filesystem/File.h"
+#include "guilib/LocalizeStrings.h"
+#include "guilib/Texture.h"
+#include "settings/AdvancedSettings.h"
#include "settings/DisplaySettings.h"
#include "settings/MediaSettings.h"
#include "settings/Settings.h"
-#include "guilib/Texture.h"
-#include "windowing/WindowingFactory.h"
-#include "settings/AdvancedSettings.h"
#include "threads/SingleLock.h"
#include "utils/log.h"
-#include "filesystem/File.h"
#include "utils/MathUtils.h"
+#include "utils/SystemInfo.h"
#include "VideoShaders/WinVideoFilter.h"
-#include "DllSwScale.h"
-#include "guilib/LocalizeStrings.h"
-#include "dialogs/GUIDialogKaiToast.h"
#include "win32/WIN32Util.h"
-#include "cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h"
+#include "windowing/WindowingFactory.h"
typedef struct {
RenderMethod method;
@@ -91,6 +92,7 @@ CWinRenderer::CWinRenderer()
m_bConfigured = false;
m_clearColour = 0;
m_format = RENDER_FMT_NONE;
+ m_processor = NULL;
}
CWinRenderer::~CWinRenderer()
@@ -135,12 +137,12 @@ void CWinRenderer::SelectRenderMethod()
// Force dxva renderer after dxva decoding: PS and SW renderers have performance issues after dxva decode.
if (g_advancedSettings.m_DXVAForceProcessorRenderer && m_format == RENDER_FMT_DXVA)
{
- CLog::Log(LOGNOTICE, "D3D: rendering method forced to DXVA2 processor");
+ CLog::Log(LOGNOTICE, "D3D: rendering method forced to DXVA processor");
m_renderMethod = RENDER_DXVA;
- if (!m_processor.Open(m_sourceWidth, m_sourceHeight, m_iFlags, m_format, m_extended_format))
+ if (!m_processor->Open(m_sourceWidth, m_sourceHeight, m_iFlags, m_format, m_extended_format))
{
- CLog::Log(LOGNOTICE, "D3D: unable to open DXVA2 processor");
- m_processor.Close();
+ CLog::Log(LOGNOTICE, "D3D: unable to open DXVA processor");
+ m_processor->Close();
m_renderMethod = RENDER_INVALID;
}
}
@@ -150,14 +152,15 @@ void CWinRenderer::SelectRenderMethod()
switch(m_iRequestedMethod)
{
+ case RENDER_METHOD_DXVAHD:
case RENDER_METHOD_DXVA:
m_renderMethod = RENDER_DXVA;
- if (m_processor.Open(m_sourceWidth, m_sourceHeight, m_iFlags, m_format, m_extended_format))
+ if (m_processor->Open(m_sourceWidth, m_sourceHeight, m_iFlags, m_format, m_extended_format))
break;
else
{
- CLog::Log(LOGNOTICE, "D3D: unable to open DXVA2 processor");
- m_processor.Close();
+ CLog::Log(LOGNOTICE, "D3D: unable to open DXVA processor");
+ m_processor->Close();
}
// Drop through to pixel shader
case RENDER_METHOD_AUTO:
@@ -277,7 +280,7 @@ bool CWinRenderer::AddVideoPicture(DVDVideoPicture* picture, int index)
return false;
DXVABuffer *buf = (DXVABuffer*)m_VideoBuffers[source];
- buf->id = m_processor.Add(picture);
+ buf->id = m_processor->Add(picture);
return true;
}
return false;
@@ -388,11 +391,6 @@ unsigned int CWinRenderer::PreInit()
g_Windowing.Get3DDevice()->GetDeviceCaps(&m_deviceCaps);
- m_iRequestedMethod = CSettings::Get().GetInt("videoplayer.rendermethod");
-
- if ((g_advancedSettings.m_DXVAForceProcessorRenderer || m_iRequestedMethod == RENDER_METHOD_DXVA) && !m_processor.PreInit())
- CLog::Log(LOGNOTICE, "CWinRenderer::Preinit - could not init DXVA2 processor - skipping");
-
m_formats.push_back(RENDER_FMT_YUV420P);
if(g_Windowing.IsTextureFormatOk(D3DFMT_L16, 0))
{
@@ -403,6 +401,29 @@ unsigned int CWinRenderer::PreInit()
m_formats.push_back(RENDER_FMT_YUYV422);
m_formats.push_back(RENDER_FMT_UYVY422);
+ m_iRequestedMethod = CSettings::Get().GetInt("videoplayer.rendermethod");
+
+ if (g_advancedSettings.m_DXVAForceProcessorRenderer || m_iRequestedMethod == RENDER_METHOD_DXVA
+ || m_iRequestedMethod == RENDER_METHOD_DXVAHD)
+ {
+ if (m_iRequestedMethod != RENDER_METHOD_DXVA && CSysInfo::IsWindowsVersionAtLeast(CSysInfo::WindowsVersionWin7))
+ {
+ m_processor = new DXVA::CProcessorHD();
+ if (!m_processor->PreInit())
+ {
+ CLog::Log(LOGNOTICE, "CWinRenderer::Preinit - could not init DXVA-HD processor - skipping");
+ SAFE_DELETE(m_processor);
+ m_processor = new DXVA::CProcessor();
+ }
+ else
+ return 0;
+ }
+ else
+ m_processor = new DXVA::CProcessor();
+
+ if (!m_processor->PreInit())
+ CLog::Log(LOGNOTICE, "CWinRenderer::Preinit - could not init DXVA2 processor - skipping");
+ }
return 0;
}
@@ -435,7 +456,11 @@ void CWinRenderer::UnInit()
}
SAFE_DELETE(m_dllSwScale);
- m_processor.UnInit();
+ if (m_processor)
+ {
+ m_processor->UnInit();
+ SAFE_DELETE(m_processor);
+ }
}
bool CWinRenderer::CreateIntermediateRenderTarget(unsigned int width, unsigned int height)
@@ -982,7 +1007,7 @@ void CWinRenderer::RenderProcessor(DWORD flags)
}
}
- m_processor.Render(m_sourceRect, destRect, target, image->id, flags);
+ m_processor->Render(m_sourceRect, destRect, target, image->id, flags);
target->Release();
@@ -1217,8 +1242,8 @@ EINTERLACEMETHOD CWinRenderer::AutoInterlaceMethod()
unsigned int CWinRenderer::GetProcessorSize()
{
- if (m_format == RENDER_FMT_DXVA)
- return m_processor.Size();
+ if (m_format == RENDER_FMT_DXVA && m_processor)
+ return m_processor->Size();
else
return 0;
}
diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h
index 045a010b61..ca0d788179 100644
--- a/xbmc/cores/VideoRenderers/WinRenderer.h
+++ b/xbmc/cores/VideoRenderers/WinRenderer.h
@@ -30,6 +30,7 @@
#include "RenderCapture.h"
#include "settings/VideoSettings.h"
#include "cores/dvdplayer/DVDCodecs/Video/DXVA.h"
+#include "cores/dvdplayer/DVDCodecs/Video/DXVAHD.h"
#include "cores/VideoRenderers/RenderFlags.h"
#include "cores/VideoRenderers/RenderFormats.h"
@@ -203,7 +204,7 @@ protected:
bool m_bConfigured;
SVideoBuffer *m_VideoBuffers[NUM_BUFFERS];
RenderMethod m_renderMethod;
- DXVA::CProcessor m_processor;
+ DXVA::CProcessor *m_processor;
std::vector<ERenderFormat> m_formats;
// software scale libraries (fallback if required pixel shaders version is not available)
@@ -226,7 +227,7 @@ protected:
ESCALINGMETHOD m_scalingMethod;
ESCALINGMETHOD m_scalingMethodGui;
- D3DCAPS9 m_deviceCaps;
+ D3DCAPS9 m_deviceCaps;
bool m_bFilterInitialized;
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h
index 263e672d26..3bafe92eb5 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h
@@ -119,13 +119,13 @@ public:
CProcessor();
~CProcessor();
- bool PreInit();
- void UnInit();
- bool Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format);
- void Close();
- REFERENCE_TIME Add(DVDVideoPicture* picture);
- bool Render(CRect src, CRect dst, IDirect3DSurface9* target, const REFERENCE_TIME time, DWORD flags);
- unsigned Size() { if (m_service) return m_size; return 0; }
+ virtual bool PreInit();
+ virtual void UnInit();
+ virtual bool Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format);
+ virtual void Close();
+ virtual REFERENCE_TIME Add(DVDVideoPicture* picture);
+ virtual bool Render(CRect src, CRect dst, IDirect3DSurface9* target, const REFERENCE_TIME time, DWORD flags);
+ virtual unsigned Size() { if (m_service) return m_size; return 0; }
virtual void OnCreateDevice() {}
virtual void OnDestroyDevice() { CSingleLock lock(m_section); Close(); }
@@ -133,11 +133,11 @@ public:
virtual void OnResetDevice() { CSingleLock lock(m_section); Close(); }
protected:
- bool UpdateSize(const DXVA2_VideoDesc& dsc);
- bool CreateSurfaces();
- bool OpenProcessor();
- bool SelectProcessor();
- void EvaluateQuirkNoDeintProcForProg();
+ virtual bool UpdateSize(const DXVA2_VideoDesc& dsc);
+ virtual bool CreateSurfaces();
+ virtual bool OpenProcessor();
+ virtual bool SelectProcessor();
+ virtual void EvaluateQuirkNoDeintProcForProg();
IDirectXVideoProcessorService* m_service;
IDirectXVideoProcessor* m_process;
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp
new file mode 100644
index 0000000000..581c8824f8
--- /dev/null
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp
@@ -0,0 +1,691 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAS_DX
+
+// setting that here because otherwise SampleFormat is defined to AVSampleFormat
+// which we don't use here
+#define FF_API_OLD_SAMPLE_FMT 0
+
+#include <windows.h>
+#include <d3d9.h>
+#include <Initguid.h>
+#include <dxva.h>
+#include <dxva2api.h>
+#include "libavcodec/dxva2.h"
+#include "../DVDCodecUtils.h"
+
+#include "DXVAHD.h"
+#include "windowing/WindowingFactory.h"
+#include "../../../VideoRenderers/WinRenderer.h"
+#include "settings/Settings.h"
+#include "settings/MediaSettings.h"
+#include "boost/shared_ptr.hpp"
+#include "utils/AutoPtrHandle.h"
+#include "utils/StringUtils.h"
+#include "settings/AdvancedSettings.h"
+#include "settings/MediaSettings.h"
+#include "cores/VideoRenderers/RenderManager.h"
+#include "win32/WIN32Util.h"
+
+#define ALLOW_ADDING_SURFACES 0
+
+using namespace DXVA;
+using namespace AUTOPTR;
+using namespace std;
+
+typedef HRESULT (__stdcall *DXVAHDCreateVideoServicePtr)(IDirect3DDevice9Ex *pD3DDevice, const DXVAHD_CONTENT_DESC *pContentDesc, DXVAHD_DEVICE_USAGE Usage, PDXVAHDSW_Plugin pPlugin, IDXVAHD_Device **ppDevice);
+static DXVAHDCreateVideoServicePtr g_DXVAHDCreateVideoService;
+
+#define CHECK(a) \
+do { \
+ HRESULT res = a; \
+ if(FAILED(res)) \
+ { \
+ CLog::Log(LOGERROR, __FUNCTION__" - failed executing "#a" at line %d with error %x", __LINE__, res); \
+ return false; \
+ } \
+} while(0);
+
+#define LOGIFERROR(a) \
+do { \
+ HRESULT res = a; \
+ if(FAILED(res)) \
+ { \
+ CLog::Log(LOGERROR, __FUNCTION__" - failed executing "#a" at line %d with error %x", __LINE__, res); \
+ } \
+} while(0);
+
+static bool LoadDXVAHD()
+{
+ static CCriticalSection g_section;
+ static HMODULE g_handle;
+
+ CSingleLock lock(g_section);
+ if(g_handle == NULL)
+ {
+ g_handle = LoadLibraryEx("dxva2.dll", NULL, 0);
+ }
+ if(g_handle == NULL)
+ {
+ return false;
+ }
+ g_DXVAHDCreateVideoService = (DXVAHDCreateVideoServicePtr)GetProcAddress(g_handle, "DXVAHD_CreateDevice");
+ if(g_DXVAHDCreateVideoService == NULL)
+ {
+ return false;
+ }
+ return true;
+}
+
+static std::string GUIDToString(const GUID& guid)
+{
+ std::string buffer = StringUtils::Format("%08X-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+ , guid.Data1, guid.Data2, guid.Data3
+ , guid.Data4[0], guid.Data4[1]
+ , guid.Data4[2], guid.Data4[3], guid.Data4[4]
+ , guid.Data4[5], guid.Data4[6], guid.Data4[7]);
+ return buffer;
+}
+
+CProcessorHD::CProcessorHD()
+{
+ m_pDXVAHD = NULL;
+ m_pDXVAVP = NULL;
+ m_index = 0;
+ m_frame = 0;
+ g_Windowing.Register(this);
+
+ m_surfaces = NULL;
+ m_context = NULL;
+}
+
+CProcessorHD::~CProcessorHD()
+{
+ g_Windowing.Unregister(this);
+ UnInit();
+}
+
+void CProcessorHD::UnInit()
+{
+ CSingleLock lock(m_section);
+ Close();
+ SAFE_RELEASE(m_pDXVAHD);
+}
+
+void CProcessorHD::Close()
+{
+ CSingleLock lock(m_section);
+ SAFE_RELEASE(m_pDXVAVP);
+
+ for(unsigned i = 0; i < m_frames.size(); i++)
+ {
+ SAFE_RELEASE(m_frames[i].context);
+ SAFE_RELEASE(m_frames[i].pSurface);
+ }
+ m_frames.clear();
+
+ SAFE_RELEASE(m_context);
+ if (m_surfaces)
+ {
+ for (unsigned i = 0; i < m_size; i++)
+ {
+ SAFE_RELEASE(m_surfaces[i]);
+ }
+ free(m_surfaces);
+ m_surfaces = NULL;
+ }
+}
+
+bool CProcessorHD::UpdateSize(const DXVA2_VideoDesc& dsc)
+{
+ return true;
+}
+
+bool CProcessorHD::PreInit()
+{
+ if (!LoadDXVAHD())
+ {
+ CLog::Log(LOGWARNING, __FUNCTION__" - DXVAHD not loaded.");
+ return false;
+ }
+
+ UnInit();
+
+ CSingleLock lock(m_section);
+
+ DXVAHD_RATIONAL fps = { 60, 1 };
+ DXVAHD_CONTENT_DESC desc;
+ desc.InputFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
+ desc.InputFrameRate = fps;
+ desc.InputWidth = 640;
+ desc.InputHeight = 480;
+ desc.OutputFrameRate = fps;
+ desc.OutputWidth = 640;
+ desc.OutputHeight = 480;
+
+ CHECK(g_DXVAHDCreateVideoService( (IDirect3DDevice9Ex*)g_Windowing.Get3DDevice()
+ , &desc
+ , DXVAHD_DEVICE_USAGE_OPTIMAL_QUALITY
+ , NULL
+ , &m_pDXVAHD ));
+
+ CHECK(m_pDXVAHD->GetVideoProcessorDeviceCaps( &m_caps ));
+
+ if (m_caps.VideoProcessorCount == 0)
+ {
+ CLog::Log(LOGWARNING, __FUNCTION__" - unable to find any video processor. GPU drivers doesn't support DXVA-HD.");
+ return false;
+ }
+
+ // Create the array of video processor caps.
+ DXVAHD_VPCAPS* pVPCaps = new (std::nothrow) DXVAHD_VPCAPS[ m_caps.VideoProcessorCount ];
+ if (pVPCaps == NULL)
+ {
+ CLog::Log(LOGERROR, __FUNCTION__" - unable to create video processor caps array. Out of memory.");
+ return false;
+ }
+
+ HRESULT hr = m_pDXVAHD->GetVideoProcessorCaps( m_caps.VideoProcessorCount, pVPCaps );
+ if(FAILED(hr))
+ {
+ CLog::Log(LOGERROR, __FUNCTION__" - failed get processor caps with error %x.", hr);
+
+ delete [] pVPCaps;
+ return false;
+ }
+
+ m_max_back_refs = 0;
+ m_max_fwd_refs = 0;
+
+ for (unsigned int i = 0; i < m_caps.VideoProcessorCount; i++)
+ {
+ if (pVPCaps[i].FutureFrames > m_max_fwd_refs)
+ {
+ m_max_fwd_refs = pVPCaps[i].FutureFrames;
+ }
+
+ if (pVPCaps[i].PastFrames > m_max_back_refs)
+ {
+ m_max_back_refs = pVPCaps[i].PastFrames;
+ }
+ }
+
+ m_size = m_max_back_refs + 1 + m_max_fwd_refs + 2; // refs + 1 display + 2 safety frames
+
+ // Get the image filtering capabilities.
+ for (long i = 0; i < NUM_FILTERS; i++)
+ {
+ if (m_caps.FilterCaps & (1 << i))
+ {
+ m_pDXVAHD->GetVideoProcessorFilterRange(PROCAMP_FILTERS[i], &m_Filters[i].Range);
+ m_Filters[i].bSupported = true;
+ }
+ else
+ {
+ m_Filters[i].bSupported = false;
+ }
+ }
+
+ m_VPCaps = pVPCaps[0];
+ m_device = m_VPCaps.VPGuid;
+
+ delete [] pVPCaps;
+
+ return true;
+}
+
+bool CProcessorHD::Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format)
+{
+ Close();
+
+ CSingleLock lock(m_section);
+
+ if (!m_pDXVAHD)
+ {
+ return false;
+ }
+
+ m_width = width;
+ m_height = height;
+ m_flags = flags;
+ m_renderFormat = format;
+
+ if (g_advancedSettings.m_DXVANoDeintProcForProgressive)
+ {
+ CLog::Log(LOGNOTICE, __FUNCTION__" - Auto deinterlacing mode workaround activated. Deinterlacing processor will be used only for interlaced frames.");
+ }
+
+ if (format == RENDER_FMT_DXVA)
+ {
+ m_format = (D3DFORMAT)extended_format;
+ }
+ else
+ {
+ // Only NV12 software colorspace conversion is implemented for now
+ m_format = (D3DFORMAT)MAKEFOURCC('N','V','1','2');
+ if (!CreateSurfaces())
+ return false;
+ }
+
+ if (!OpenProcessor())
+ {
+ return false;
+ }
+
+ m_frame = 0;
+
+ return true;
+}
+
+bool CProcessorHD::ReInit()
+{
+ return PreInit() && (m_renderFormat == RENDER_FMT_DXVA || CreateSurfaces());
+}
+
+bool CProcessorHD::OpenProcessor()
+{
+ // restore the device if it was lost
+ if (!m_pDXVAHD && !ReInit())
+ {
+ return false;
+ }
+
+ SAFE_RELEASE(m_pDXVAVP);
+
+ CLog::Log(LOGDEBUG, __FUNCTION__" - processor selected %s.", GUIDToString(m_device).c_str());
+
+ CHECK(m_pDXVAHD->CreateVideoProcessor(&m_device, &m_pDXVAVP));
+
+ DXVAHD_STREAM_STATE_D3DFORMAT_DATA d3dformat = { m_format };
+ LOGIFERROR(m_pDXVAVP->SetVideoProcessStreamState( 0, DXVAHD_STREAM_STATE_D3DFORMAT
+ , sizeof(d3dformat), &d3dformat ));
+
+ DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA data =
+ {
+ 0, // Type: 0=Video, 1=Graphics
+ m_flags & CONF_FLAGS_YUV_FULLRANGE ? 0 : 1, // RGB_Range: 0=Full, 1=Limited
+ m_flags & CONF_FLAGS_YUVCOEF_BT709 ? 1 : 0, // YCbCr_Matrix: 0=BT.601, 1=BT.709
+ 1 // YCbCr_xvYCC: 0=Conventional YCbCr, 1=xvYCC
+ };
+ LOGIFERROR(m_pDXVAVP->SetVideoProcessStreamState( 0, DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE
+ , sizeof(data), &data ));
+
+ DXVAHD_COLOR_YCbCrA bgColor = { 0.0625f, 0.5f, 0.5f, 1.0f }; // black color
+ DXVAHD_COLOR backgroundColor;
+ backgroundColor.YCbCr = bgColor;
+ DXVAHD_BLT_STATE_BACKGROUND_COLOR_DATA backgroundData = { true, backgroundColor }; // {YCbCr, DXVAHD_COLOR}
+ LOGIFERROR(m_pDXVAVP->SetVideoProcessBltState( DXVAHD_BLT_STATE_BACKGROUND_COLOR
+ , sizeof (backgroundData), &backgroundData ));
+
+ DXVAHD_STREAM_STATE_ALPHA_DATA alpha = { true, 1.0f };
+ LOGIFERROR(m_pDXVAVP->SetVideoProcessStreamState( 0, DXVAHD_STREAM_STATE_ALPHA
+ , sizeof(alpha), &alpha ));
+
+ return true;
+}
+
+bool CProcessorHD::CreateSurfaces()
+{
+ LPDIRECT3DDEVICE9 pD3DDevice = g_Windowing.Get3DDevice();
+ m_surfaces = (LPDIRECT3DSURFACE9*)calloc(m_size, sizeof(LPDIRECT3DSURFACE9));
+ for (unsigned idx = 0; idx < m_size; idx++)
+ CHECK(pD3DDevice->CreateOffscreenPlainSurface(
+ (m_width + 15) & ~15,
+ (m_height + 15) & ~15,
+ m_format,
+ m_caps.InputPool,
+ &m_surfaces[idx],
+ NULL));
+
+ m_context = new CSurfaceContext();
+
+ return true;
+}
+
+REFERENCE_TIME CProcessorHD::Add(DVDVideoPicture* picture)
+{
+ CSingleLock lock(m_section);
+
+ IDirect3DSurface9* surface = NULL;
+ CSurfaceContext* context = NULL;
+
+ if (picture->iFlags & DVP_FLAG_DROPPED)
+ {
+ return 0;
+ }
+
+ switch (picture->format)
+ {
+ case RENDER_FMT_DXVA:
+ {
+ surface = (IDirect3DSurface9*)picture->data[3];
+ context = picture->context;
+ break;
+ }
+
+ case RENDER_FMT_YUV420P:
+ {
+ if (!m_surfaces)
+ {
+ CLog::Log(LOGWARNING, __FUNCTION__" - not initialized.");
+ return 0;
+ }
+
+ surface = m_surfaces[m_index];
+ m_index = (m_index + 1) % m_size;
+
+ context = m_context;
+
+ D3DLOCKED_RECT rectangle;
+ if (FAILED(surface->LockRect(&rectangle, NULL, 0)))
+ {
+ return 0;
+ }
+
+ // Convert to NV12 - Luma
+ // TODO: Optimize this later using shaders/swscale/etc.
+ uint8_t *s = picture->data[0];
+ uint8_t* bits = (uint8_t*)(rectangle.pBits);
+ for (unsigned y = 0; y < picture->iHeight; y++)
+ {
+ memcpy(bits, s, picture->iWidth);
+ s += picture->iLineSize[0];
+ bits += rectangle.Pitch;
+ }
+
+ D3DSURFACE_DESC desc;
+ if (FAILED(surface->GetDesc(&desc)))
+ {
+ return 0;
+ }
+
+ // Convert to NV12 - Chroma
+ uint8_t *s_u, *s_v, *d_uv;
+ for (unsigned y = 0; y < picture->iHeight/2; y++)
+ {
+ s_u = picture->data[1] + (y * picture->iLineSize[1]);
+ s_v = picture->data[2] + (y * picture->iLineSize[2]);
+ d_uv = ((uint8_t*)(rectangle.pBits)) + (desc.Height + y) * rectangle.Pitch;
+ for (unsigned x = 0; x < picture->iWidth/2; x++)
+ {
+ *d_uv++ = *s_u++;
+ *d_uv++ = *s_v++;
+ }
+ }
+
+ if (FAILED(surface->UnlockRect()))
+ {
+ return 0;
+ }
+ break;
+ }
+
+ default:
+ {
+ CLog::Log(LOGWARNING, __FUNCTION__" - colorspace not supported by processor, skipping frame.");
+ return 0;
+ }
+ }
+
+ if (!surface || !context)
+ {
+ return 0;
+ }
+ m_frame += 2;
+
+ surface->AddRef();
+ context->Acquire();
+
+ SFrame frame = {};
+ frame.index = m_frame;
+ frame.pSurface = surface;
+ frame.context = context;
+ frame.format = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
+
+ if (picture->iFlags & DVP_FLAG_INTERLACED)
+ {
+ frame.format = picture->iFlags & DVP_FLAG_TOP_FIELD_FIRST
+ ? DXVAHD_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST
+ : DXVAHD_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST;
+ }
+
+ m_frames.push_back(frame);
+
+ if (m_frames.size() > m_size)
+ {
+ SAFE_RELEASE(m_frames.front().context);
+ SAFE_RELEASE(m_frames.front().pSurface);
+
+ m_frames.pop_front();
+ }
+
+ return m_frame;
+}
+
+bool CProcessorHD::ApplyFilter(DXVAHD_FILTER filter, int value, int min, int max, int def)
+{
+ if (filter > NUM_FILTERS)
+ {
+ return false;
+ }
+ // Unsupported filter. Ignore.
+ if (!m_Filters[filter].bSupported)
+ {
+ return false;
+ }
+
+ DXVAHD_FILTER_RANGE_DATA range = m_Filters[filter].Range;
+ int val;
+
+ if(value > def)
+ {
+ val = range.Default + (range.Maximum - range.Default) * (value - def) / (max - def);
+ }
+ else if(value < def)
+ {
+ val = range.Default + (range.Minimum - range.Default) * (value - def) / (min - def);
+ }
+ else
+ {
+ val = range.Default;
+ }
+
+ DXVAHD_STREAM_STATE_FILTER_DATA data = { true, val };
+ DXVAHD_STREAM_STATE state = static_cast<DXVAHD_STREAM_STATE>(DXVAHD_STREAM_STATE_FILTER_BRIGHTNESS + filter);
+
+ return !FAILED( m_pDXVAVP->SetVideoProcessStreamState( 0, state, sizeof(data), &data ) );
+}
+
+bool CProcessorHD::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFERENCE_TIME frame, DWORD flags)
+{
+ CSingleLock lock(m_section);
+
+ // buffering frames
+ frame -= m_VPCaps.FutureFrames * 2;
+ if (frame <= 0)
+ {
+ return false;
+ }
+
+ // restore processor if it was lost
+ if(!m_pDXVAVP && !OpenProcessor())
+ {
+ return false;
+ }
+
+ EDEINTERLACEMODE deinterlace_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
+ if (g_advancedSettings.m_DXVANoDeintProcForProgressive)
+ deinterlace_mode = (flags & RENDER_FLAG_FIELD0 || flags & RENDER_FLAG_FIELD1) ? VS_DEINTERLACEMODE_FORCE : VS_DEINTERLACEMODE_OFF;
+ EINTERLACEMETHOD interlace_method = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);
+
+ bool progressive = deinterlace_mode == VS_DEINTERLACEMODE_OFF
+ || ( interlace_method != VS_INTERLACEMETHOD_DXVA_BOB
+ && interlace_method != VS_INTERLACEMETHOD_DXVA_BEST);
+
+ // minFrame is the first samples to keep. Delete the rest.
+ REFERENCE_TIME minFrame = frame - m_max_back_refs * 2;
+
+ SFrames::iterator it = m_frames.begin();
+ while (it != m_frames.end())
+ {
+ if (it->index < minFrame)
+ {
+ SAFE_RELEASE(it->context);
+ SAFE_RELEASE(it->pSurface);
+ it = m_frames.erase(it);
+ }
+ else
+ ++it;
+ }
+
+ if(m_frames.empty())
+ {
+ return false;
+ }
+
+ D3DSURFACE_DESC desc;
+ CHECK(target->GetDesc(&desc));
+ CRect rectTarget(0, 0, desc.Width, desc.Height);
+ CWIN32Util::CropSource(src, dst, rectTarget);
+ RECT sourceRECT = { src.x1, src.y1, src.x2, src.y2 };
+ RECT dstRECT = { dst.x1, dst.y1, dst.x2, dst.y2 };
+
+ // MinTime and MaxTime are now the first and last samples to feed the processor.
+ minFrame = frame - m_VPCaps.PastFrames * 2;
+ REFERENCE_TIME maxFrame = frame + m_VPCaps.FutureFrames * 2;
+
+ bool isValid(false);
+ DXVAHD_FRAME_FORMAT dxvaFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
+
+ DXVAHD_STREAM_DATA stream_data = { 0 };
+ stream_data.Enable = TRUE;
+ stream_data.PastFrames = 0;
+ stream_data.FutureFrames = 0;
+ stream_data.ppPastSurfaces = new IDirect3DSurface9*[m_VPCaps.PastFrames];
+ stream_data.ppFutureSurfaces = new IDirect3DSurface9*[m_VPCaps.FutureFrames];
+
+ for(it = m_frames.begin(); it != m_frames.end(); ++it)
+ {
+ if (it->index >= minFrame && it->index <= maxFrame)
+ {
+ if (it->index < frame)
+ {
+ // frames order should be { .., T-3, T-2, T-1 }
+ stream_data.ppPastSurfaces[m_VPCaps.PastFrames - (frame - it->index)/2] = it->pSurface;
+ stream_data.PastFrames++;
+ }
+ else if (it->index == frame)
+ {
+ stream_data.pInputSurface = it->pSurface;
+ dxvaFrameFormat = (DXVAHD_FRAME_FORMAT) it->format;
+ isValid = true;
+ }
+ else if (it->index > frame)
+ {
+ // frames order should be { T+1, T+2, T+3, .. }
+ stream_data.ppFutureSurfaces[(it->index - frame)/2 - 1] = it->pSurface;
+ stream_data.FutureFrames++;
+ }
+ }
+ }
+
+ // no present frame, skip
+ if (!isValid)
+ {
+ CLog::Log(LOGWARNING, __FUNCTION__" - uncomplete stream data, skipping frame.");
+ return false;
+ }
+
+ // rewind uncomplete array
+ if (stream_data.PastFrames < m_VPCaps.PastFrames)
+ {
+ stream_data.ppPastSurfaces += (m_VPCaps.PastFrames - stream_data.PastFrames);
+ }
+
+ // Override the sample format when the processor doesn't need to deinterlace or when deinterlacing is forced and flags are missing.
+ if (progressive)
+ {
+ dxvaFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
+ }
+ else if (deinterlace_mode == VS_DEINTERLACEMODE_FORCE
+ && dxvaFrameFormat == DXVAHD_FRAME_FORMAT_PROGRESSIVE)
+ {
+ dxvaFrameFormat = DXVAHD_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST;
+ }
+
+ bool frameProgressive = dxvaFrameFormat == DXVAHD_FRAME_FORMAT_PROGRESSIVE;
+
+ // Progressive or Interlaced video at normal rate.
+ stream_data.InputFrameOrField = frame + (flags & RENDER_FLAG_FIELD1 ? 1 : 0);
+ stream_data.OutputIndex = flags & RENDER_FLAG_FIELD1 && !frameProgressive ? 1 : 0;
+
+ DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA frame_format = { dxvaFrameFormat };
+ LOGIFERROR( m_pDXVAVP->SetVideoProcessStreamState( 0, DXVAHD_STREAM_STATE_FRAME_FORMAT
+ , sizeof(frame_format), &frame_format ) );
+
+ DXVAHD_STREAM_STATE_DESTINATION_RECT_DATA dstRect = { true, dstRECT };
+ LOGIFERROR( m_pDXVAVP->SetVideoProcessStreamState( 0, DXVAHD_STREAM_STATE_DESTINATION_RECT
+ , sizeof(dstRect), &dstRect));
+
+ DXVAHD_STREAM_STATE_SOURCE_RECT_DATA srcRect = { true, sourceRECT };
+ LOGIFERROR( m_pDXVAVP->SetVideoProcessStreamState( 0, DXVAHD_STREAM_STATE_SOURCE_RECT
+ , sizeof(srcRect), &srcRect));
+
+ ApplyFilter( DXVAHD_FILTER_BRIGHTNESS, CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness
+ , 0, 100, 50);
+ ApplyFilter( DXVAHD_FILTER_CONTRAST, CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast
+ , 0, 100, 50);
+
+ unsigned int uiRange = g_Windowing.UseLimitedColor() ? 1 : 0;
+ DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA colorData =
+ {
+ 0, // 0 = playback, 1 = video processing
+ uiRange, // 0 = 0-255, 1 = 16-235
+ 1, // 0 = BT.601, 1 = BT.709
+ 1 // 0 = Conventional YCbCr, 1 = xvYCC
+ };
+
+ LOGIFERROR( m_pDXVAVP->SetVideoProcessBltState( DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE
+ , sizeof(colorData), &colorData ));
+
+ DXVAHD_BLT_STATE_TARGET_RECT_DATA targetRect = { true, dstRECT };
+ LOGIFERROR( m_pDXVAVP->SetVideoProcessBltState( DXVAHD_BLT_STATE_TARGET_RECT
+ , sizeof(targetRect), &targetRect ) );
+
+ HRESULT hr = m_pDXVAVP->VideoProcessBltHD(target, frame, 1, &stream_data);
+ if(FAILED(hr))
+ {
+ CLog::Log(LOGERROR, __FUNCTION__" - failed executing VideoProcessBltHD with error %x", hr);
+ }
+
+ // rewind back before delete
+ if (stream_data.PastFrames < m_VPCaps.PastFrames)
+ {
+ stream_data.ppPastSurfaces -= (m_VPCaps.PastFrames - stream_data.PastFrames);
+ }
+
+ delete [] stream_data.ppPastSurfaces;
+ delete [] stream_data.ppFutureSurfaces;
+
+ return !FAILED(hr);
+}
+
+#endif
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h
new file mode 100644
index 0000000000..5919543fdc
--- /dev/null
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "DllAvCodec.h"
+#include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h"
+#include "guilib/D3DResource.h"
+#include "threads/Event.h"
+#include "DVDResource.h"
+#include "DXVA.h"
+#include <dxva2api.h>
+#include <deque>
+#include <vector>
+#include "settings/VideoSettings.h"
+#include "guilib/Geometry.h"
+#include <dxvahd.h>
+
+namespace DXVA {
+
+// ProcAmp filters
+const DXVAHD_FILTER PROCAMP_FILTERS[] =
+{
+ DXVAHD_FILTER_BRIGHTNESS,
+ DXVAHD_FILTER_CONTRAST,
+ DXVAHD_FILTER_HUE,
+ DXVAHD_FILTER_SATURATION
+};
+
+const DWORD NUM_FILTERS = ARRAYSIZE(PROCAMP_FILTERS);
+
+class CProcessorHD
+ : public CProcessor
+{
+public:
+ CProcessorHD();
+ ~CProcessorHD();
+
+ virtual bool PreInit();
+ virtual void UnInit();
+ virtual bool Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format);
+ virtual void Close();
+ virtual REFERENCE_TIME Add(DVDVideoPicture* picture);
+ virtual bool Render(CRect src, CRect dst, IDirect3DSurface9* target, const REFERENCE_TIME time, DWORD flags);
+ virtual unsigned Size() { if (m_pDXVAHD) return m_size; return 0; }
+
+ virtual void OnCreateDevice() {}
+ virtual void OnDestroyDevice() { CSingleLock lock(m_section); UnInit(); }
+ virtual void OnLostDevice() { CSingleLock lock(m_section); UnInit(); }
+ virtual void OnResetDevice() { CSingleLock lock(m_section); Close(); }
+
+protected:
+ virtual bool UpdateSize(const DXVA2_VideoDesc& dsc);
+ virtual bool ReInit();
+ virtual bool CreateSurfaces();
+ virtual bool OpenProcessor();
+ virtual bool ApplyFilter(DXVAHD_FILTER filter, int value, int min, int max, int def);
+
+ IDXVAHD_Device *m_pDXVAHD; // DXVA-HD device.
+ IDXVAHD_VideoProcessor *m_pDXVAVP; // DXVA-HD video processor.
+ DXVAHD_VPDEVCAPS m_caps;
+ DXVAHD_VPCAPS m_VPCaps;
+ GUID m_device;
+ unsigned int m_width;
+ unsigned int m_height;
+ D3DFORMAT m_format;
+ REFERENCE_TIME m_frame;
+ unsigned int m_flags;
+ unsigned int m_renderFormat;
+
+ struct ProcAmpInfo
+ {
+ bool bSupported;
+ DXVAHD_FILTER_RANGE_DATA Range;
+ };
+ ProcAmpInfo m_Filters[NUM_FILTERS];
+
+ struct SFrame
+ {
+ IDirect3DSurface9* pSurface;
+ CSurfaceContext* context;
+ unsigned int index;
+ unsigned format;
+ };
+ typedef std::deque<SFrame> SFrames;
+ SFrames m_frames;
+
+ CSurfaceContext* m_context;
+ unsigned m_size;
+ unsigned m_max_back_refs;
+ unsigned m_max_fwd_refs;
+ unsigned m_index;
+
+ LPDIRECT3DSURFACE9* m_surfaces;
+ CCriticalSection m_section;
+};
+
+};