[dxva] split decoder and renderer to different files and move renderers to cores...
authorAnton Fedchin <afedchin@ruswizards.com>
Wed, 4 Jun 2014 15:16:16 +0000 (19:16 +0400)
committerAnton Fedchin <afedchin@ruswizards.com>
Tue, 9 Sep 2014 08:29:17 +0000 (12:29 +0400)
project/VS2010Express/XBMC.vcxproj
project/VS2010Express/XBMC.vcxproj.filters
xbmc/cores/VideoRenderers/DXVA.cpp [new file with mode: 0644]
xbmc/cores/VideoRenderers/DXVA.h [new file with mode: 0644]
xbmc/cores/VideoRenderers/DXVAHD.cpp [new file with mode: 0644]
xbmc/cores/VideoRenderers/DXVAHD.h [new file with mode: 0644]
xbmc/cores/VideoRenderers/WinRenderer.h
xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h
xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp [deleted file]
xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.h [deleted file]

index e0b0231..4af2c43 100644 (file)
     <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" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\RenderFlags.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\RenderManager.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\WinRenderer.cpp" />
+    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\DXVA.cpp" />
+    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\DXVAHD.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\ConvolutionKernels.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\YUV2RGBShader.cpp" />
     <ClCompile Include="..\..\xbmc\cores\ExternalPlayer\ExternalPlayer.cpp" />
     <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" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\RenderFlags.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\RenderManager.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\WinRenderer.h" />
+    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\DXVA.h" />
+    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\DXVAHD.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\ConvolutionKernels.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\YUV2RGBShader.h" />
     <ClInclude Include="..\..\xbmc\cores\ExternalPlayer\ExternalPlayer.h" />
index d984c2d..2e43d7c 100644 (file)
     <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>
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\WinRenderer.cpp">
       <Filter>cores\VideoRenderers</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\DXVA.cpp">
+      <Filter>cores\VideoRenderers</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\DXVAHD.cpp">
+      <Filter>cores\VideoRenderers</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\ConvolutionKernels.cpp">
       <Filter>cores\VideoRenderers\Shaders</Filter>
     </ClCompile>
     <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>
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\WinRenderer.h">
       <Filter>cores\VideoRenderers</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\DXVA.h">
+      <Filter>cores\VideoRenderers</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\DXVAHD.h">
+      <Filter>cores\VideoRenderers</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\ConvolutionKernels.h">
       <Filter>cores\VideoRenderers\Shaders</Filter>
     </ClInclude>
diff --git a/xbmc/cores/VideoRenderers/DXVA.cpp b/xbmc/cores/VideoRenderers/DXVA.cpp
new file mode 100644 (file)
index 0000000..8d57509
--- /dev/null
@@ -0,0 +1,808 @@
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://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
+
+#include <windows.h>
+#include <d3d9.h>
+#include <Initguid.h>
+#include <dxva.h>
+#include <dxva2api.h>
+
+#include "DXVA.h"
+#include "windowing/WindowingFactory.h"
+#include "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"
+#include "utils/Log.h"
+
+using namespace DXVA;
+using namespace AUTOPTR;
+using namespace std;
+
+DEFINE_GUID(DXVA2_VideoProcATIVectorAdaptiveDevice,   0x3C5323C1,0x6fb7,0x44f5,0x90,0x81,0x05,0x6b,0xf2,0xee,0x44,0x9d);
+DEFINE_GUID(DXVA2_VideoProcATIMotionAdaptiveDevice,   0x552C0DAD,0xccbc,0x420b,0x83,0xc8,0x74,0x94,0x3c,0xf9,0xf1,0xa6);
+DEFINE_GUID(DXVA2_VideoProcATIAdaptiveDevice,         0x6E8329FF,0xb642,0x418b,0xbc,0xf0,0xbc,0xb6,0x59,0x1e,0x25,0x5f);
+DEFINE_GUID(DXVA2_VideoProcNVidiaAdaptiveDevice,      0x6CB69578,0x7617,0x4637,0x91,0xE5,0x1C,0x02,0xDB,0x81,0x02,0x85);
+DEFINE_GUID(DXVA2_VideoProcIntelEdgeDevice,           0xBF752EF6,0x8CC4,0x457A,0xBE,0x1B,0x08,0xBD,0x1C,0xAE,0xEE,0x9F);
+DEFINE_GUID(DXVA2_VideoProcNVidiaUnknownDevice,       0xF9F19DA5,0x3B09,0x4B2F,0x9D,0x89,0xC6,0x47,0x53,0xE3,0xEA,0xAB);
+
+typedef struct {
+    const char   *name;
+    const GUID   *guid;
+} dxva2_device_t;
+
+static const dxva2_device_t dxva2_devices[] = {
+  { "Progressive Device",           &DXVA2_VideoProcProgressiveDevice         },
+  { "Bob Device",                   &DXVA2_VideoProcBobDevice                 },
+  { "Vector Adaptative Device",     &DXVA2_VideoProcATIVectorAdaptiveDevice   },
+  { "Motion Adaptative Device",     &DXVA2_VideoProcATIMotionAdaptiveDevice   },
+  { "Adaptative Device",            &DXVA2_VideoProcATIAdaptiveDevice         },
+  { "Spatial-temporal device",      &DXVA2_VideoProcNVidiaAdaptiveDevice      },
+  { "Edge directed device",         &DXVA2_VideoProcIntelEdgeDevice           },
+  { "Unknown device (nVidia)",      &DXVA2_VideoProcNVidiaUnknownDevice       },
+  { NULL, NULL }
+};
+
+typedef struct {
+    const char   *name;
+    unsigned      flags;
+} dxva2_deinterlacetech_t;
+
+static const dxva2_deinterlacetech_t dxva2_deinterlacetechs[] = {
+  { "Inverse Telecine",                   DXVA2_DeinterlaceTech_InverseTelecine        },
+  { "Motion vector steered",              DXVA2_DeinterlaceTech_MotionVectorSteered    },
+  { "Pixel adaptive",                     DXVA2_DeinterlaceTech_PixelAdaptive          },
+  { "Field adaptive",                     DXVA2_DeinterlaceTech_FieldAdaptive          },
+  { "Edge filtering",                     DXVA2_DeinterlaceTech_EdgeFiltering          },
+  { "Median filtering",                   DXVA2_DeinterlaceTech_MedianFiltering        },
+  { "Bob vertical stretch 4-tap",         DXVA2_DeinterlaceTech_BOBVerticalStretch4Tap },
+  { "Bob vertical stretch",               DXVA2_DeinterlaceTech_BOBVerticalStretch     },
+  { "Bob line replicate",                 DXVA2_DeinterlaceTech_BOBLineReplicate       },
+  { "Unknown",                            DXVA2_DeinterlaceTech_Unknown                },
+  { NULL, 0 }
+};
+
+// Prefered targets must be first
+static const D3DFORMAT render_targets[] = {
+    (D3DFORMAT)MAKEFOURCC('N','V','1','2'),
+    (D3DFORMAT)MAKEFOURCC('Y','V','1','2'),
+    D3DFMT_UNKNOWN
+};
+
+typedef struct {
+    DWORD VendorID;
+    DWORD DeviceID;
+} pci_device;
+
+// List of devices that drop frames with a deinterlacing processor for progressive material.
+static const pci_device NoDeintProcForProgDevices[] = {
+  { PCIV_nVidia, 0x0865 }, // ION
+  { PCIV_nVidia, 0x0874 }, // ION
+  { PCIV_nVidia, 0x0876 }, // ION
+  { PCIV_nVidia, 0x087D }, // ION
+  { PCIV_nVidia, 0x087E }, // ION LE
+  { PCIV_nVidia, 0x087F }, // ION LE
+  { 0          , 0x0000 }
+};
+
+static CStdString GUIDToString(const GUID& guid)
+{
+  CStdString 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;
+}
+
+static const dxva2_device_t *dxva2_find_device(const GUID *guid)
+{
+    for (unsigned i = 0; dxva2_devices[i].name; i++) {
+        if (IsEqualGUID(*dxva2_devices[i].guid, *guid))
+            return &dxva2_devices[i];
+    }
+    return NULL;
+}
+
+static const dxva2_deinterlacetech_t *dxva2_find_deinterlacetech(unsigned flags)
+{
+    for (unsigned i = 0; dxva2_deinterlacetechs[i].name; i++) {
+        if (dxva2_deinterlacetechs[i].flags == flags)
+            return &dxva2_deinterlacetechs[i];
+    }
+    return NULL;
+}
+
+#define SCOPE(type, var) boost::shared_ptr<type> var##_holder(var, CoTaskMemFree);
+
+CCriticalSection CProcessor::m_dlSection;
+HMODULE CProcessor::m_dlHandle = NULL;
+DXVA2CreateVideoServicePtr CProcessor::m_DXVA2CreateVideoService = NULL;
+
+CProcessor::CProcessor()
+{
+  m_service = NULL;
+  m_process = NULL;
+  m_time    = 0;
+  g_Windowing.Register(this);
+
+  m_surfaces = NULL;
+  m_context = NULL;
+  m_index = 0;
+  m_progressive = true;
+}
+
+CProcessor::~CProcessor()
+{
+  g_Windowing.Unregister(this);
+  UnInit();
+}
+
+void CProcessor::UnInit()
+{
+  CSingleLock lock(m_section);
+  Close();
+  SAFE_RELEASE(m_service);
+}
+
+void CProcessor::Close()
+{
+  CSingleLock lock(m_section);
+  SAFE_RELEASE(m_process);
+  for(unsigned i = 0; i < m_sample.size(); i++)
+  {
+    SAFE_RELEASE(m_sample[i].context);
+    SAFE_RELEASE(m_sample[i].sample.SrcSurface);
+  }
+  m_sample.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 CProcessor::UpdateSize(const DXVA2_VideoDesc& dsc)
+{
+  // TODO: print the D3FORMAT text version in log
+  CLog::Log(LOGDEBUG, "DXVA - checking samples array size using %d render target", dsc.Format);
+
+  GUID* deint_guid_list = NULL;
+  unsigned guid_count = 0;
+  if (FAILED(m_service->GetVideoProcessorDeviceGuids(&dsc, &guid_count, &deint_guid_list)))
+    return false;
+
+  SCOPE(GUID, deint_guid_list);
+  
+  for (unsigned i = 0; i < guid_count; i++)
+  {
+    DXVA2_VideoProcessorCaps caps;
+    CHECK(m_service->GetVideoProcessorCaps(deint_guid_list[i], &dsc, D3DFMT_X8R8G8B8, &caps));
+    if (caps.NumBackwardRefSamples + caps.NumForwardRefSamples > m_size)
+    {
+      m_size = caps.NumBackwardRefSamples + caps.NumForwardRefSamples;
+      CLog::Log(LOGDEBUG, "DXVA - updated maximum samples count to %d", m_size);
+    }
+    m_max_back_refs = std::max(caps.NumBackwardRefSamples, m_max_back_refs);
+    m_max_fwd_refs = std::max(caps.NumForwardRefSamples, m_max_fwd_refs);
+  }
+
+  return true;
+}
+
+bool CProcessor::PreInit()
+{
+  if (!LoadSymbols())
+    return false;
+
+  UnInit();
+
+  CSingleLock lock(m_section);
+
+  if (FAILED(m_DXVA2CreateVideoService(g_Windowing.Get3DDevice(), IID_IDirectXVideoProcessorService, (void**)&m_service)))
+    return false;
+
+  m_size = 0;
+
+  // We try to find the maximum count of reference frames using a standard resolution and all known render target formats
+  DXVA2_VideoDesc dsc = {};
+  dsc.SampleWidth = 640;
+  dsc.SampleHeight = 480;
+  dsc.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedOddFirst;
+
+  m_max_back_refs = 0;
+  m_max_fwd_refs = 0;
+
+  for (unsigned i = 0; render_targets[i] != D3DFMT_UNKNOWN; i++)
+  {
+    dsc.Format = render_targets[i];
+    if (!UpdateSize(dsc))
+      CLog::Log(LOGDEBUG, "DXVA - render target not supported by processor");
+  }
+
+  m_size = m_max_back_refs + 1 + m_max_fwd_refs + 2;  // refs + 1 display + 2 safety frames
+
+  return true;
+}
+
+bool CProcessor::Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format)
+{
+  Close();
+
+  CSingleLock lock(m_section);
+
+  if (!m_service)
+    return false;
+
+  DXVA2_VideoDesc dsc;
+  memset(&dsc, 0, sizeof(DXVA2_VideoDesc));
+
+  dsc.SampleWidth = width;
+  dsc.SampleHeight = height;
+  dsc.SampleFormat.VideoLighting = DXVA2_VideoLighting_dim;
+
+  switch (CONF_FLAGS_CHROMA_MASK(flags))
+  {
+    case CONF_FLAGS_CHROMA_LEFT:
+      dsc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_Horizontally_Cosited
+                                              | DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes;
+      break;
+    case CONF_FLAGS_CHROMA_CENTER:
+      dsc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes;
+      break;
+    case CONF_FLAGS_CHROMA_TOPLEFT:
+      dsc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_Horizontally_Cosited
+                                              | DXVA2_VideoChromaSubsampling_Vertically_Cosited;
+      break;
+    default:
+      dsc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_Unknown;
+  }
+
+  if (flags & CONF_FLAGS_YUV_FULLRANGE)
+    dsc.SampleFormat.NominalRange = DXVA2_NominalRange_0_255;
+  else
+    dsc.SampleFormat.NominalRange = DXVA2_NominalRange_16_235;
+
+  switch (CONF_FLAGS_YUVCOEF_MASK(flags))
+  {
+    case CONF_FLAGS_YUVCOEF_240M:
+      dsc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_SMPTE240M;
+      break;
+    case CONF_FLAGS_YUVCOEF_BT601:
+      dsc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT601;
+      break;
+    case CONF_FLAGS_YUVCOEF_BT709:
+      dsc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT709;
+      break;
+    default:
+      dsc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_Unknown;
+  }
+
+  switch (CONF_FLAGS_COLPRI_MASK(flags))
+  {
+    case CONF_FLAGS_COLPRI_BT709:
+      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT709;
+      break;
+    case CONF_FLAGS_COLPRI_BT470M:
+      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT470_2_SysM;
+      break;
+    case CONF_FLAGS_COLPRI_BT470BG:
+      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT470_2_SysBG;
+      break;
+    case CONF_FLAGS_COLPRI_170M:
+      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_SMPTE170M;
+      break;
+    case CONF_FLAGS_COLPRI_240M:
+      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_SMPTE240M;
+      break;
+    default:
+      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_Unknown;
+  }
+
+  switch (CONF_FLAGS_TRC_MASK(flags))
+  {
+    case CONF_FLAGS_TRC_BT709:
+      dsc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_709;
+      break;
+    case CONF_FLAGS_TRC_GAMMA22:
+      dsc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_22;
+      break;
+    case CONF_FLAGS_TRC_GAMMA28:
+      dsc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_28;
+      break;
+    default:
+      dsc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_Unknown;
+  }
+
+  m_desc = dsc;
+
+  if (format == RENDER_FMT_DXVA)
+    m_desc.Format = (D3DFORMAT)extended_format;
+  else
+  {
+    // Only NV12 software colorspace conversion is implemented for now
+    m_desc.Format = (D3DFORMAT)MAKEFOURCC('N','V','1','2');
+    if (!CreateSurfaces())
+      return false;
+  }
+
+  // frame flags are not available to do the complete calculation of the deinterlacing mode, as done in Render()
+  // It's OK, as it doesn't make any difference for all hardware except the few GPUs on the quirk list.
+  // And for those GPUs, the correct values will be calculated with the first Render() and the correct processor
+  // will replace the one allocated here, before the user sees anything.
+  // It's a bit inefficient, that's all.
+  m_deinterlace_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
+  m_interlace_method = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);;
+
+  EvaluateQuirkNoDeintProcForProg();
+
+  if (g_advancedSettings.m_DXVANoDeintProcForProgressive || m_quirk_nodeintprocforprog)
+    CLog::Log(LOGNOTICE, "DXVA: Auto deinterlacing mode workaround activated. Deinterlacing processor will be used only for interlaced frames.");
+
+  if (!OpenProcessor())
+    return false;
+
+  m_time = 0;
+
+  return true;
+}
+
+void CProcessor::EvaluateQuirkNoDeintProcForProg()
+{
+  D3DADAPTER_IDENTIFIER9 AIdentifier = g_Windowing.GetAIdentifier();
+
+  for (unsigned idx = 0; NoDeintProcForProgDevices[idx].VendorID != 0; idx++)
+  {
+    if(NoDeintProcForProgDevices[idx].VendorID == AIdentifier.VendorId
+    && NoDeintProcForProgDevices[idx].DeviceID == AIdentifier.DeviceId)
+    {
+      m_quirk_nodeintprocforprog = true;
+      return;
+    }
+  }
+  m_quirk_nodeintprocforprog = false;
+}
+
+bool CProcessor::SelectProcessor()
+{
+  // The CProcessor can be run after dxva or software decoding, possibly after software deinterlacing.
+
+  // Deinterlace mode off: force progressive
+  // Deinterlace mode auto or force, with a dxva deinterlacing method: create an deinterlacing capable processor. The frame flags will tell it to deinterlace or not.
+  m_progressive = m_deinterlace_mode == VS_DEINTERLACEMODE_OFF
+                  || (   m_interlace_method != VS_INTERLACEMETHOD_DXVA_BOB
+                      && m_interlace_method != VS_INTERLACEMETHOD_DXVA_BEST);
+
+  if (m_progressive)
+    m_desc.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
+  else
+    m_desc.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst;
+
+  GUID*    guid_list;
+  unsigned guid_count;
+  CHECK(m_service->GetVideoProcessorDeviceGuids(&m_desc, &guid_count, &guid_list));
+  SCOPE(GUID, guid_list);
+
+  if(guid_count == 0)
+  {
+    CLog::Log(LOGDEBUG, "DXVA - unable to find any processors");
+    return false;
+  }
+
+  for(unsigned i = 0; i < guid_count; i++)
+  {
+    const GUID* g = &guid_list[i];
+    const dxva2_device_t* device = dxva2_find_device(g);
+
+    if (device)
+    {
+      CLog::Log(LOGDEBUG, "DXVA - processor found %s", device->name);
+    }
+    else
+    {
+      CHECK(m_service->GetVideoProcessorCaps(*g, &m_desc, D3DFMT_X8R8G8B8, &m_caps));
+      const dxva2_deinterlacetech_t* tech = dxva2_find_deinterlacetech(m_caps.DeinterlaceTechnology);
+      if (tech != NULL)
+        CLog::Log(LOGDEBUG, "DXVA - unknown processor %s found, deinterlace technology %s", GUIDToString(*g).c_str(), tech->name);
+      else
+        CLog::Log(LOGDEBUG, "DXVA - unknown processor %s found, unknown technology", GUIDToString(*g).c_str());
+    }
+  }
+
+  if (m_progressive)
+    m_device = DXVA2_VideoProcProgressiveDevice;
+  else if(m_interlace_method == VS_INTERLACEMETHOD_DXVA_BEST)
+    m_device = guid_list[0];
+  else
+    m_device = DXVA2_VideoProcBobDevice;
+
+  return true;
+}
+
+bool CProcessor::OpenProcessor()
+{
+  if (!SelectProcessor())
+    return false;
+
+  SAFE_RELEASE(m_process);
+
+  const dxva2_device_t* device = dxva2_find_device(&m_device);
+  if (device)
+    CLog::Log(LOGDEBUG, "DXVA - processor selected %s", device->name);
+  else
+    CLog::Log(LOGDEBUG, "DXVA - processor selected %s", GUIDToString(m_device).c_str());
+
+  D3DFORMAT rtFormat = D3DFMT_X8R8G8B8;
+  CHECK(m_service->GetVideoProcessorCaps(m_device, &m_desc, rtFormat, &m_caps))
+
+  /* HACK for Intel Egde Device. 
+   * won't work if backward refs is equals value from the capabilities *
+   * Possible reasons are:                                             *
+   * 1) The device capabilities are incorrectly reported               *
+   * 2) The device is broken                                           */
+  if (IsEqualGUID(m_device, DXVA2_VideoProcIntelEdgeDevice))
+    m_caps.NumBackwardRefSamples = 0;
+
+  if (m_caps.DeviceCaps & DXVA2_VPDev_SoftwareDevice)
+    CLog::Log(LOGDEBUG, "DXVA - processor is software device");
+
+  if (m_caps.DeviceCaps & DXVA2_VPDev_EmulatedDXVA1)
+    CLog::Log(LOGDEBUG, "DXVA - processor is emulated dxva1");
+
+  CLog::Log(LOGDEBUG, "DXVA - processor requires %d past frames and %d future frames", m_caps.NumBackwardRefSamples, m_caps.NumForwardRefSamples);
+
+  if (m_caps.NumBackwardRefSamples + m_caps.NumForwardRefSamples + 3 > m_size)
+  {
+    CLog::Log(LOGERROR, "DXVA - used an incorrect number of reference frames creating processor");
+    return false;
+  }
+
+  CHECK(m_service->CreateVideoProcessor(m_device, &m_desc, rtFormat, 0, &m_process));
+
+  CHECK(m_service->GetProcAmpRange(m_device, &m_desc, rtFormat, DXVA2_ProcAmp_Brightness, &m_brightness));
+  CHECK(m_service->GetProcAmpRange(m_device, &m_desc, rtFormat, DXVA2_ProcAmp_Contrast  , &m_contrast));
+  CHECK(m_service->GetProcAmpRange(m_device, &m_desc, rtFormat, DXVA2_ProcAmp_Hue       , &m_hue));
+  CHECK(m_service->GetProcAmpRange(m_device, &m_desc, rtFormat, DXVA2_ProcAmp_Saturation, &m_saturation));
+
+  return true;
+}
+
+bool CProcessor::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_desc.SampleWidth + 15) & ~15,
+                                (m_desc.SampleHeight + 15) & ~15,
+                                m_desc.Format,
+                                D3DPOOL_DEFAULT,
+                                &m_surfaces[idx],
+                                NULL));
+
+  m_context = new CSurfaceContext();
+
+  return true;
+}
+
+REFERENCE_TIME CProcessor::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:
+    {
+      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
+      for (unsigned y = 0; y < picture->iHeight/2; y++)
+      {
+        uint8_t *s_u = picture->data[1] + (y * picture->iLineSize[1]);
+        uint8_t *s_v = picture->data[2] + (y * picture->iLineSize[2]);
+        uint8_t *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, "DXVA - colorspace not supported by processor, skipping frame");
+      return 0;
+    }
+  }
+
+  if (!surface || !context)
+    return 0;
+
+  m_time += 2;
+
+  surface->AddRef();
+  context->Acquire();
+
+  SVideoSample vs = {};
+  vs.sample.Start          = m_time;
+  vs.sample.End            = 0; 
+  vs.sample.SampleFormat   = m_desc.SampleFormat;
+
+  if (picture->iFlags & DVP_FLAG_INTERLACED)
+  {
+    if (picture->iFlags & DVP_FLAG_TOP_FIELD_FIRST)
+      vs.sample.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst;
+    else
+      vs.sample.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedOddFirst;
+  }
+  else
+  {
+    vs.sample.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
+  }
+
+  vs.sample.PlanarAlpha    = DXVA2_Fixed32OpaqueAlpha();
+  vs.sample.SampleData     = 0;
+  vs.sample.SrcSurface     = surface;
+
+
+  vs.context = context;
+
+  if(!m_sample.empty())
+    m_sample.back().sample.End = vs.sample.Start;
+
+  m_sample.push_back(vs);
+  if (m_sample.size() > m_size)
+  {
+    SAFE_RELEASE(m_sample.front().context);
+    SAFE_RELEASE(m_sample.front().sample.SrcSurface);
+    m_sample.pop_front();
+  }
+
+  return m_time;
+}
+
+static DXVA2_Fixed32 ConvertRange(const DXVA2_ValueRange& range, int value, int min, int max, int def)
+{
+  if(value > def)
+    return DXVA2FloatToFixed( DXVA2FixedToFloat(range.DefaultValue)
+                            + (DXVA2FixedToFloat(range.MaxValue) - DXVA2FixedToFloat(range.DefaultValue))
+                            * (value - def) / (max - def) );
+  else if(value < def)
+    return DXVA2FloatToFixed( DXVA2FixedToFloat(range.DefaultValue)
+                            + (DXVA2FixedToFloat(range.MinValue) - DXVA2FixedToFloat(range.DefaultValue)) 
+                            * (value - def) / (min - def) );
+  else
+    return range.DefaultValue;
+}
+
+bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFERENCE_TIME time, DWORD flags)
+{
+  CSingleLock lock(m_section);
+
+  // With auto deinterlacing, the Ion Gen. 1 drops some frames with deinterlacing processor + progressive flags for progressive material.
+  // For that GPU (or when specified by an advanced setting), use the progressive processor.
+  // This is at the expense of the switch speed when video interlacing flags change and a deinterlacing processor is actually required.
+  EDEINTERLACEMODE mode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
+  if (g_advancedSettings.m_DXVANoDeintProcForProgressive || m_quirk_nodeintprocforprog)
+    mode = (flags & RENDER_FLAG_FIELD0 || flags & RENDER_FLAG_FIELD1) ? VS_DEINTERLACEMODE_FORCE : VS_DEINTERLACEMODE_OFF;
+  EINTERLACEMETHOD method = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);
+  if(m_interlace_method != method
+  || m_deinterlace_mode != mode
+  || !m_process)
+  {
+    m_deinterlace_mode = mode;
+    m_interlace_method = method;
+
+    if (!OpenProcessor())
+      return false;
+  }
+  
+  // MinTime and MaxTime are the first and last samples to keep. Delete the rest.
+  REFERENCE_TIME MinTime = time - m_max_back_refs*2;
+  REFERENCE_TIME MaxTime = time + m_max_fwd_refs*2;
+
+  SSamples::iterator it = m_sample.begin();
+  while (it != m_sample.end())
+  {
+    if (it->sample.Start < MinTime)
+    {
+      SAFE_RELEASE(it->context);
+      SAFE_RELEASE(it->sample.SrcSurface);
+      it = m_sample.erase(it);
+    }
+    else
+      ++it;
+  }
+
+  if(m_sample.empty())
+    return false;
+
+  // MinTime and MaxTime are now the first and last samples to feed the processor.
+  MinTime = time - m_caps.NumBackwardRefSamples*2;
+  MaxTime = time + m_caps.NumForwardRefSamples*2;
+
+  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 };
+
+
+  // How to prepare the samples array for VideoProcessBlt
+  // - always provide current picture + the number of forward and backward references required by the current processor.
+  // - provide the surfaces in the array in increasing temporal order
+  // - at the start of playback, there may not be enough samples available. Use SampleFormat.SampleFormat = DXVA2_SampleUnknown for the missing samples.
+
+  int count = 1 + m_caps.NumBackwardRefSamples + m_caps.NumForwardRefSamples;
+  int valid = 0;
+  auto_aptr<DXVA2_VideoSample> samp(new DXVA2_VideoSample[count]);
+
+  for (int i = 0; i < count; i++)
+    samp[i].SampleFormat.SampleFormat = DXVA2_SampleUnknown;
+
+  for(it = m_sample.begin(); it != m_sample.end() && valid < count; ++it)
+  {
+    if (it->sample.Start >= MinTime && it->sample.Start <= MaxTime)
+    {
+      DXVA2_VideoSample& vs = samp[(it->sample.Start - MinTime) / 2];
+      vs = it->sample;
+      vs.SrcRect = sourceRECT;
+      vs.DstRect = dstRECT;
+      if(vs.End == 0)
+        vs.End = vs.Start + 2;
+
+      // Override the sample format when the processor doesn't need to deinterlace or when deinterlacing is forced and flags are missing.
+      if (m_progressive)
+        vs.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
+      else if (m_deinterlace_mode == VS_DEINTERLACEMODE_FORCE && vs.SampleFormat.SampleFormat == DXVA2_SampleProgressiveFrame)
+        vs.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst;
+
+      valid++;
+    }
+  }
+  
+  // MS' guidelines above don't work. The blit fails when the processor is given DXVA2_SampleUnknown samples (with ATI at least).
+  // The ATI driver works with a reduced number of samples though, support that for now.
+  // Problem is an ambiguity if there are future refs requested by the processor. There are no such implementations at the moment.
+  int offset = 0;
+  if(valid < count)
+  {
+    CLog::Log(LOGWARNING, __FUNCTION__" - did not find all required samples, adjusting the sample array.");
+
+    for (int i = 0; i < count; i++)
+    {
+      if (samp[i].SampleFormat.SampleFormat == DXVA2_SampleUnknown)
+        offset = i+1;
+    }
+    count -= offset;
+    if (count == 0)
+    {
+      CLog::Log(LOGWARNING, __FUNCTION__" - no usable samples.");
+      return false;
+    }
+  }
+
+  DXVA2_VideoProcessBltParams blt = {};
+  blt.TargetFrame = time;
+  if (flags & RENDER_FLAG_FIELD1)
+    blt.TargetFrame += 1;
+  blt.TargetRect  = dstRECT;
+  blt.ConstrictionSize.cx = 0;
+  blt.ConstrictionSize.cy = 0;
+
+  blt.DestFormat.VideoTransferFunction = DXVA2_VideoTransFunc_sRGB;
+  blt.DestFormat.SampleFormat          = DXVA2_SampleProgressiveFrame;
+  if(g_Windowing.UseLimitedColor())
+    blt.DestFormat.NominalRange          = DXVA2_NominalRange_16_235;
+  else
+    blt.DestFormat.NominalRange          = DXVA2_NominalRange_0_255;
+  blt.Alpha = DXVA2_Fixed32OpaqueAlpha();
+
+  blt.ProcAmpValues.Brightness = ConvertRange( m_brightness, CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness
+                                             , 0, 100, 50);
+  blt.ProcAmpValues.Contrast   = ConvertRange( m_contrast, CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast
+                                             , 0, 100, 50);
+  blt.ProcAmpValues.Hue        = m_hue.DefaultValue;
+  blt.ProcAmpValues.Saturation = m_saturation.DefaultValue;
+
+  blt.BackgroundColor.Y     = 0x1000;
+  blt.BackgroundColor.Cb    = 0x8000;
+  blt.BackgroundColor.Cr    = 0x8000;
+  blt.BackgroundColor.Alpha = 0xffff;
+
+  /* HACK to kickstart certain DXVA drivers (poulsbo) which oddly  *
+   * won't render anything until someting else have been rendered. */
+  g_Windowing.Get3DDevice()->SetFVF( D3DFVF_XYZ );
+  float verts[2][3]= {};
+  g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 1, verts, 3*sizeof(float));
+
+  CHECK(m_process->VideoProcessBlt(target, &blt, &samp[offset], count, NULL));
+  return true;
+}
+
+bool CProcessor::LoadSymbols()
+{
+  CSingleLock lock(m_dlSection);
+
+  if(m_dlHandle == NULL)
+    m_dlHandle = LoadLibraryEx("dxva2.dll", NULL, 0);
+  if(m_dlHandle == NULL)
+    return false;
+  m_DXVA2CreateVideoService = (DXVA2CreateVideoServicePtr)GetProcAddress(m_dlHandle, "DXVA2CreateVideoService");
+  if(m_DXVA2CreateVideoService == NULL)
+    return false;
+  return true;
+}
+
+#endif
diff --git a/xbmc/cores/VideoRenderers/DXVA.h b/xbmc/cores/VideoRenderers/DXVA.h
new file mode 100644 (file)
index 0000000..38da6f7
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://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 "libavcodec/avcodec.h"
+#include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h"
+#include "DVDCodecs/Video/DXVA.h"
+#include "guilib/D3DResource.h"
+#include "threads/Event.h"
+#include "DVDResource.h"
+#include <dxva2api.h>
+#include <deque>
+#include <vector>
+#include "settings/VideoSettings.h"
+#include "guilib/Geometry.h"
+
+namespace DXVA {
+
+class CProcessor
+  : public ID3DResource
+{
+public:
+  CProcessor();
+ ~CProcessor();
+
+  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(); }
+  virtual void OnLostDevice()    { CSingleLock lock(m_section); Close(); }
+  virtual void OnResetDevice()   { CSingleLock lock(m_section); Close(); }
+
+protected:
+  virtual bool LoadSymbols();
+  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;
+  GUID                           m_device;
+
+  DXVA2_VideoProcessorCaps m_caps;
+  DXVA2_VideoDesc  m_desc;
+
+  DXVA2_ValueRange m_brightness;
+  DXVA2_ValueRange m_contrast;
+  DXVA2_ValueRange m_hue;
+  DXVA2_ValueRange m_saturation;
+  REFERENCE_TIME   m_time;
+  unsigned         m_size;
+  unsigned         m_max_back_refs;
+  unsigned         m_max_fwd_refs;
+  EDEINTERLACEMODE m_deinterlace_mode;
+  EINTERLACEMETHOD m_interlace_method;
+  bool             m_progressive; // true for progressive source or to force ignoring interlacing flags.
+  unsigned         m_index;
+
+  struct SVideoSample
+  {
+    DXVA2_VideoSample sample;
+    CSurfaceContext* context;
+  };
+  typedef std::deque<SVideoSample> SSamples;
+  SSamples         m_sample;
+
+  CCriticalSection    m_section;
+  LPDIRECT3DSURFACE9* m_surfaces;
+  CSurfaceContext*    m_context;
+  bool                m_quirk_nodeintprocforprog;
+  static CCriticalSection    m_dlSection;
+  static HMODULE      m_dlHandle;
+  static DXVA2CreateVideoServicePtr m_DXVA2CreateVideoService;
+};
+
+};
diff --git a/xbmc/cores/VideoRenderers/DXVAHD.cpp b/xbmc/cores/VideoRenderers/DXVAHD.cpp
new file mode 100644 (file)
index 0000000..e9ac51c
--- /dev/null
@@ -0,0 +1,670 @@
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://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 "DXVAHD.h"
+#include "windowing/WindowingFactory.h"
+#include "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"
+#include "utils/Log.h"
+
+using namespace DXVA;
+using namespace AUTOPTR;
+using namespace std;
+
+#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 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;
+}
+
+DXVAHDCreateVideoServicePtr CProcessorHD::m_DXVAHDCreateVideoService = NULL;
+
+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 (!LoadSymbols())
+  {
+    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;
+
+  HRESULT cvres = m_DXVAHDCreateVideoService( (IDirect3DDevice9Ex*)g_Windowing.Get3DDevice()
+                                              , &desc
+                                              , DXVAHD_DEVICE_USAGE_OPTIMAL_QUALITY
+                                              , NULL
+                                              , &m_pDXVAHD );
+
+  if(FAILED(cvres))
+  {
+    if(cvres == E_NOINTERFACE)
+      CLog::Log(LOGNOTICE, __FUNCTION__" - The Direct3d device doesn't support DXVA-HD.");
+    else
+      CLog::Log(LOGERROR, __FUNCTION__" - failed to create DXVAHD device %x", cvres);
+
+    return false;
+  }
+
+  CHECK(m_pDXVAHD->GetVideoProcessorDeviceCaps( &m_VPDevCaps ));
+
+  if (m_VPDevCaps.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_VPDevCaps.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_VPDevCaps.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_VPDevCaps.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_VPDevCaps.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
+    0,                                          // RGB_Range: 0=Full, 1=Limited
+    m_flags & CONF_FLAGS_YUVCOEF_BT709 ? 1 : 0, // YCbCr_Matrix: 0=BT.601, 1=BT.709
+    m_flags & CONF_FLAGS_YUV_FULLRANGE ? 1 : 0  // 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_VPDevCaps.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);
+
+  // 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-1, T-2, T-3 }
+        stream_data.ppPastSurfaces[(frame - it->index)/2 - 1] = 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;
+  }
+
+  // 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);
+  }
+
+  delete [] stream_data.ppPastSurfaces;
+  delete [] stream_data.ppFutureSurfaces;
+
+  return !FAILED(hr);
+}
+
+bool CProcessorHD::LoadSymbols()
+{
+  CSingleLock lock(m_dlSection);
+  if(m_dlHandle == NULL)
+    m_dlHandle = LoadLibraryEx("dxva2.dll", NULL, 0);
+  if(m_dlHandle == NULL)
+    return false;
+  m_DXVAHDCreateVideoService = (DXVAHDCreateVideoServicePtr)GetProcAddress(m_dlHandle, "DXVAHD_CreateDevice");
+  if(m_DXVAHDCreateVideoService == NULL)
+    return false;
+  return true;
+}
+
+#endif
diff --git a/xbmc/cores/VideoRenderers/DXVAHD.h b/xbmc/cores/VideoRenderers/DXVAHD.h
new file mode 100644 (file)
index 0000000..11cb194
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://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 "libavcodec/avcodec.h"
+#include "DVDCodecs/Video/DVDVideoCodecFFmpeg.h"
+#include "DVDCodecs/Video/DXVA.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);
+
+typedef HRESULT (__stdcall *DXVAHDCreateVideoServicePtr)(IDirect3DDevice9Ex *pD3DDevice, const DXVAHD_CONTENT_DESC *pContentDesc, DXVAHD_DEVICE_USAGE Usage, PDXVAHDSW_Plugin pPlugin, IDXVAHD_Device **ppDevice);
+
+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 LoadSymbols();
+  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_VPDevCaps;
+  DXVAHD_VPCAPS            m_VPCaps;
+  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;
+  static DXVAHDCreateVideoServicePtr m_DXVAHDCreateVideoService;
+};
+
+};
index 63eb3cd..10d7613 100644 (file)
@@ -29,8 +29,8 @@
 #include "guilib/D3DResource.h"
 #include "RenderCapture.h"
 #include "settings/VideoSettings.h"
-#include "cores/dvdplayer/DVDCodecs/Video/DXVA.h"
-#include "cores/dvdplayer/DVDCodecs/Video/DXVAHD.h"
+#include "DXVA.h"
+#include "DXVAHD.h"
 #include "cores/VideoRenderers/RenderFlags.h"
 #include "cores/VideoRenderers/RenderFormats.h"
 
index 2059f33..380cf23 100644 (file)
@@ -124,50 +124,6 @@ static const dxva2_mode_t dxva2_modes[] = {
     { NULL, NULL, 0 }
 };
 
-DEFINE_GUID(DXVA2_VideoProcATIVectorAdaptiveDevice,   0x3C5323C1,0x6fb7,0x44f5,0x90,0x81,0x05,0x6b,0xf2,0xee,0x44,0x9d);
-DEFINE_GUID(DXVA2_VideoProcATIMotionAdaptiveDevice,   0x552C0DAD,0xccbc,0x420b,0x83,0xc8,0x74,0x94,0x3c,0xf9,0xf1,0xa6);
-DEFINE_GUID(DXVA2_VideoProcATIAdaptiveDevice,         0x6E8329FF,0xb642,0x418b,0xbc,0xf0,0xbc,0xb6,0x59,0x1e,0x25,0x5f);
-DEFINE_GUID(DXVA2_VideoProcNVidiaAdaptiveDevice,      0x6CB69578,0x7617,0x4637,0x91,0xE5,0x1C,0x02,0xDB,0x81,0x02,0x85);
-DEFINE_GUID(DXVA2_VideoProcIntelEdgeDevice,           0xBF752EF6,0x8CC4,0x457A,0xBE,0x1B,0x08,0xBD,0x1C,0xAE,0xEE,0x9F);
-DEFINE_GUID(DXVA2_VideoProcNVidiaUnknownDevice,       0xF9F19DA5,0x3B09,0x4B2F,0x9D,0x89,0xC6,0x47,0x53,0xE3,0xEA,0xAB);
-
-typedef struct {
-    const char   *name;
-    const GUID   *guid;
-} dxva2_device_t;
-
-static const dxva2_device_t dxva2_devices[] = {
-  { "Progressive Device",           &DXVA2_VideoProcProgressiveDevice         },
-  { "Bob Device",                   &DXVA2_VideoProcBobDevice                 },
-  { "Vector Adaptative Device",     &DXVA2_VideoProcATIVectorAdaptiveDevice   },
-  { "Motion Adaptative Device",     &DXVA2_VideoProcATIMotionAdaptiveDevice   },
-  { "Adaptative Device",            &DXVA2_VideoProcATIAdaptiveDevice         },
-  { "Spatial-temporal device",      &DXVA2_VideoProcNVidiaAdaptiveDevice      },
-  { "Edge directed device",         &DXVA2_VideoProcIntelEdgeDevice           },
-  { "Unknown device (nVidia)",      &DXVA2_VideoProcNVidiaUnknownDevice       },
-  { NULL, NULL }
-};
-
-typedef struct {
-    const char   *name;
-    unsigned      flags;
-} dxva2_deinterlacetech_t;
-
-static const dxva2_deinterlacetech_t dxva2_deinterlacetechs[] = {
-  { "Inverse Telecine",                   DXVA2_DeinterlaceTech_InverseTelecine        },
-  { "Motion vector steered",              DXVA2_DeinterlaceTech_MotionVectorSteered    },
-  { "Pixel adaptive",                     DXVA2_DeinterlaceTech_PixelAdaptive          },
-  { "Field adaptive",                     DXVA2_DeinterlaceTech_FieldAdaptive          },
-  { "Edge filtering",                     DXVA2_DeinterlaceTech_EdgeFiltering          },
-  { "Median filtering",                   DXVA2_DeinterlaceTech_MedianFiltering        },
-  { "Bob vertical stretch 4-tap",         DXVA2_DeinterlaceTech_BOBVerticalStretch4Tap },
-  { "Bob vertical stretch",               DXVA2_DeinterlaceTech_BOBVerticalStretch     },
-  { "Bob line replicate",                 DXVA2_DeinterlaceTech_BOBLineReplicate       },
-  { "Unknown",                            DXVA2_DeinterlaceTech_Unknown                },
-  { NULL, 0 }
-};
-
-
 // Prefered targets must be first
 static const D3DFORMAT render_targets[] = {
     (D3DFORMAT)MAKEFOURCC('N','V','1','2'),
@@ -243,22 +199,6 @@ static DWORD VP3DeviceID [] = {
   0x0000
 };
 
-typedef struct {
-    DWORD VendorID;
-    DWORD DeviceID;
-} pci_device;
-
-// List of devices that drop frames with a deinterlacing processor for progressive material.
-static const pci_device NoDeintProcForProgDevices[] = {
-  { PCIV_nVidia, 0x0865 }, // ION
-  { PCIV_nVidia, 0x0874 }, // ION
-  { PCIV_nVidia, 0x0876 }, // ION
-  { PCIV_nVidia, 0x087D }, // ION
-  { PCIV_nVidia, 0x087E }, // ION LE
-  { PCIV_nVidia, 0x087F }, // ION LE
-  { 0          , 0x0000 }
-};
-
 static std::string GUIDToString(const GUID& guid)
 {
   std::string buffer = StringUtils::Format("%08X-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
@@ -278,24 +218,6 @@ static const dxva2_mode_t *dxva2_find_mode(const GUID *guid)
     return NULL;
 }
 
-static const dxva2_device_t *dxva2_find_device(const GUID *guid)
-{
-    for (unsigned i = 0; dxva2_devices[i].name; i++) {
-        if (IsEqualGUID(*dxva2_devices[i].guid, *guid))
-            return &dxva2_devices[i];
-    }
-    return NULL;
-}
-
-static const dxva2_deinterlacetech_t *dxva2_find_deinterlacetech(unsigned flags)
-{
-    for (unsigned i = 0; dxva2_deinterlacetechs[i].name; i++) {
-        if (dxva2_deinterlacetechs[i].flags == flags)
-            return &dxva2_deinterlacetechs[i];
-    }
-    return NULL;
-}
-
 CDXVAContext *CDXVAContext::m_context = NULL;
 CCriticalSection CDXVAContext::m_section;
 HMODULE CDXVAContext::m_dlHandle = NULL;
@@ -608,16 +530,6 @@ void CDecoder::Close()
   m_dxva_context = NULL;
 }
 
-#define CHECK(a) \
-do { \
-  HRESULT res = a; \
-  if(FAILED(res)) \
-  { \
-    CLog::Log(LOGERROR, "DXVA - failed executing "#a" at line %d with error %x", __LINE__, res); \
-    return false; \
-  } \
-} while(0);
-
 static bool CheckH264L41(AVCodecContext *avctx)
 {
     unsigned widthmbs  = (avctx->coded_width + 15) / 16;  // width in macroblocks
@@ -1128,675 +1040,5 @@ void CDecoder::CloseDXVADecoder()
   SAFE_RELEASE(m_decoder);
 }
 
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-//------------------------ PROCESSING SERVICE -------------------------------
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-
-#define SCOPE(type, var) boost::shared_ptr<type> var##_holder(var, CoTaskMemFree);
-
-static DXVA2CreateVideoServicePtr g_DXVA2CreateVideoService;
-static bool LoadDXVA()
-{
-  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_DXVA2CreateVideoService = (DXVA2CreateVideoServicePtr)GetProcAddress(g_handle, "DXVA2CreateVideoService");
-  if (g_DXVA2CreateVideoService == NULL)
-    return false;
-  return true;
-}
-
-CProcessor::CProcessor()
-{
-  m_service = NULL;
-  m_process = NULL;
-  m_time    = 0;
-  g_Windowing.Register(this);
-
-  m_surfaces = NULL;
-  m_context = NULL;
-  m_index = 0;
-  m_progressive = true;
-}
-
-CProcessor::~CProcessor()
-{
-  g_Windowing.Unregister(this);
-  UnInit();
-}
-
-void CProcessor::UnInit()
-{
-  CSingleLock lock(m_section);
-  Close();
-  SAFE_RELEASE(m_service);
-}
-
-void CProcessor::Close()
-{
-  CSingleLock lock(m_section);
-  SAFE_RELEASE(m_process);
-  for(unsigned i = 0; i < m_sample.size(); i++)
-  {
-    SAFE_RELEASE(m_sample[i].context);
-    SAFE_RELEASE(m_sample[i].sample.SrcSurface);
-  }
-  m_sample.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 CProcessor::UpdateSize(const DXVA2_VideoDesc& dsc)
-{
-  // TODO: print the D3FORMAT text version in log
-  CLog::Log(LOGDEBUG, "DXVA - checking samples array size using %d render target", dsc.Format);
-
-  GUID* deint_guid_list = NULL;
-  unsigned guid_count = 0;
-  if (FAILED(m_service->GetVideoProcessorDeviceGuids(&dsc, &guid_count, &deint_guid_list)))
-    return false;
-
-  SCOPE(GUID, deint_guid_list);
-  
-  for (unsigned i = 0; i < guid_count; i++)
-  {
-    DXVA2_VideoProcessorCaps caps;
-    CHECK(m_service->GetVideoProcessorCaps(deint_guid_list[i], &dsc, D3DFMT_X8R8G8B8, &caps));
-    if (caps.NumBackwardRefSamples + caps.NumForwardRefSamples > m_size)
-    {
-      m_size = caps.NumBackwardRefSamples + caps.NumForwardRefSamples;
-      CLog::Log(LOGDEBUG, "DXVA - updated maximum samples count to %d", m_size);
-    }
-    m_max_back_refs = std::max(caps.NumBackwardRefSamples, m_max_back_refs);
-    m_max_fwd_refs = std::max(caps.NumForwardRefSamples, m_max_fwd_refs);
-  }
-
-  return true;
-}
-
-bool CProcessor::PreInit()
-{
-  if (!LoadDXVA())
-    return false;
-
-  UnInit();
-
-  CSingleLock lock(m_section);
-
-  if (FAILED(g_DXVA2CreateVideoService(g_Windowing.Get3DDevice(), IID_IDirectXVideoProcessorService, (void**)&m_service)))
-    return false;
-
-  m_size = 0;
-
-  // We try to find the maximum count of reference frames using a standard resolution and all known render target formats
-  DXVA2_VideoDesc dsc = {};
-  dsc.SampleWidth = 640;
-  dsc.SampleHeight = 480;
-  dsc.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedOddFirst;
-
-  m_max_back_refs = 0;
-  m_max_fwd_refs = 0;
-
-  for (unsigned i = 0; render_targets[i] != D3DFMT_UNKNOWN; i++)
-  {
-    dsc.Format = render_targets[i];
-    if (!UpdateSize(dsc))
-      CLog::Log(LOGDEBUG, "DXVA - render target not supported by processor");
-  }
-
-  m_size = m_max_back_refs + 1 + m_max_fwd_refs + 2;  // refs + 1 display + 2 safety frames
-
-  return true;
-}
-
-bool CProcessor::Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format)
-{
-  Close();
-
-  CSingleLock lock(m_section);
-
-  if (!m_service)
-    return false;
-
-  DXVA2_VideoDesc dsc;
-  memset(&dsc, 0, sizeof(DXVA2_VideoDesc));
-
-  dsc.SampleWidth = width;
-  dsc.SampleHeight = height;
-  dsc.SampleFormat.VideoLighting = DXVA2_VideoLighting_dim;
-
-  switch (CONF_FLAGS_CHROMA_MASK(flags))
-  {
-    case CONF_FLAGS_CHROMA_LEFT:
-      dsc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_Horizontally_Cosited
-                                              | DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes;
-      break;
-    case CONF_FLAGS_CHROMA_CENTER:
-      dsc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes;
-      break;
-    case CONF_FLAGS_CHROMA_TOPLEFT:
-      dsc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_Horizontally_Cosited
-                                              | DXVA2_VideoChromaSubsampling_Vertically_Cosited;
-      break;
-    default:
-      dsc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_Unknown;
-  }
-
-  if (flags & CONF_FLAGS_YUV_FULLRANGE)
-    dsc.SampleFormat.NominalRange = DXVA2_NominalRange_0_255;
-  else
-    dsc.SampleFormat.NominalRange = DXVA2_NominalRange_16_235;
-
-  switch (CONF_FLAGS_YUVCOEF_MASK(flags))
-  {
-    case CONF_FLAGS_YUVCOEF_240M:
-      dsc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_SMPTE240M;
-      break;
-    case CONF_FLAGS_YUVCOEF_BT601:
-      dsc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT601;
-      break;
-    case CONF_FLAGS_YUVCOEF_BT709:
-      dsc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT709;
-      break;
-    default:
-      dsc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_Unknown;
-  }
-
-  switch (CONF_FLAGS_COLPRI_MASK(flags))
-  {
-    case CONF_FLAGS_COLPRI_BT709:
-      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT709;
-      break;
-    case CONF_FLAGS_COLPRI_BT470M:
-      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT470_2_SysM;
-      break;
-    case CONF_FLAGS_COLPRI_BT470BG:
-      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT470_2_SysBG;
-      break;
-    case CONF_FLAGS_COLPRI_170M:
-      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_SMPTE170M;
-      break;
-    case CONF_FLAGS_COLPRI_240M:
-      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_SMPTE240M;
-      break;
-    default:
-      dsc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_Unknown;
-  }
-
-  switch (CONF_FLAGS_TRC_MASK(flags))
-  {
-    case CONF_FLAGS_TRC_BT709:
-      dsc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_709;
-      break;
-    case CONF_FLAGS_TRC_GAMMA22:
-      dsc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_22;
-      break;
-    case CONF_FLAGS_TRC_GAMMA28:
-      dsc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_28;
-      break;
-    default:
-      dsc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_Unknown;
-  }
-
-  m_desc = dsc;
-
-  if (format == RENDER_FMT_DXVA)
-    m_desc.Format = (D3DFORMAT)extended_format;
-  else
-  {
-    // Only NV12 software colorspace conversion is implemented for now
-    m_desc.Format = (D3DFORMAT)MAKEFOURCC('N','V','1','2');
-    if (!CreateSurfaces())
-      return false;
-  }
-
-  // frame flags are not available to do the complete calculation of the deinterlacing mode, as done in Render()
-  // It's OK, as it doesn't make any difference for all hardware except the few GPUs on the quirk list.
-  // And for those GPUs, the correct values will be calculated with the first Render() and the correct processor
-  // will replace the one allocated here, before the user sees anything.
-  // It's a bit inefficient, that's all.
-  m_deinterlace_mode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
-  m_interlace_method = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);;
-
-  EvaluateQuirkNoDeintProcForProg();
-
-  if (g_advancedSettings.m_DXVANoDeintProcForProgressive || m_quirk_nodeintprocforprog)
-    CLog::Log(LOGNOTICE, "DXVA: Auto deinterlacing mode workaround activated. Deinterlacing processor will be used only for interlaced frames.");
-
-  if (!OpenProcessor())
-    return false;
-
-  m_time = 0;
-
-  return true;
-}
-
-void CProcessor::EvaluateQuirkNoDeintProcForProg()
-{
-  D3DADAPTER_IDENTIFIER9 AIdentifier = g_Windowing.GetAIdentifier();
-
-  for (unsigned idx = 0; NoDeintProcForProgDevices[idx].VendorID != 0; idx++)
-  {
-    if(NoDeintProcForProgDevices[idx].VendorID == AIdentifier.VendorId
-    && NoDeintProcForProgDevices[idx].DeviceID == AIdentifier.DeviceId)
-    {
-      m_quirk_nodeintprocforprog = true;
-      return;
-    }
-  }
-  m_quirk_nodeintprocforprog = false;
-}
-
-bool CProcessor::SelectProcessor()
-{
-  // The CProcessor can be run after dxva or software decoding, possibly after software deinterlacing.
-
-  // Deinterlace mode off: force progressive
-  // Deinterlace mode auto or force, with a dxva deinterlacing method: create an deinterlacing capable processor. The frame flags will tell it to deinterlace or not.
-  m_progressive = m_deinterlace_mode == VS_DEINTERLACEMODE_OFF
-                  || (   m_interlace_method != VS_INTERLACEMETHOD_DXVA_BOB
-                      && m_interlace_method != VS_INTERLACEMETHOD_DXVA_BEST);
-
-  if (m_progressive)
-    m_desc.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
-  else
-    m_desc.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst;
-
-  GUID*    guid_list;
-  unsigned guid_count;
-  CHECK(m_service->GetVideoProcessorDeviceGuids(&m_desc, &guid_count, &guid_list));
-  SCOPE(GUID, guid_list);
-
-  if(guid_count == 0)
-  {
-    CLog::Log(LOGDEBUG, "DXVA - unable to find any processors");
-    return false;
-  }
-
-  for(unsigned i = 0; i < guid_count; i++)
-  {
-    const GUID* g = &guid_list[i];
-    const dxva2_device_t* device = dxva2_find_device(g);
-
-    if (device)
-    {
-      CLog::Log(LOGDEBUG, "DXVA - processor found %s", device->name);
-    }
-    else
-    {
-      CHECK(m_service->GetVideoProcessorCaps(*g, &m_desc, D3DFMT_X8R8G8B8, &m_caps));
-      const dxva2_deinterlacetech_t* tech = dxva2_find_deinterlacetech(m_caps.DeinterlaceTechnology);
-      if (tech != NULL)
-        CLog::Log(LOGDEBUG, "DXVA - unknown processor %s found, deinterlace technology %s", GUIDToString(*g).c_str(), tech->name);
-      else
-        CLog::Log(LOGDEBUG, "DXVA - unknown processor %s found, unknown technology", GUIDToString(*g).c_str());
-    }
-  }
-
-  if (m_progressive)
-    m_device = DXVA2_VideoProcProgressiveDevice;
-  else if(m_interlace_method == VS_INTERLACEMETHOD_DXVA_BEST)
-    m_device = guid_list[0];
-  else
-    m_device = DXVA2_VideoProcBobDevice;
-
-  return true;
-}
-
-bool CProcessor::OpenProcessor()
-{
-  if (!SelectProcessor())
-    return false;
-
-  SAFE_RELEASE(m_process);
-
-  const dxva2_device_t* device = dxva2_find_device(&m_device);
-  if (device)
-    CLog::Log(LOGDEBUG, "DXVA - processor selected %s", device->name);
-  else
-    CLog::Log(LOGDEBUG, "DXVA - processor selected %s", GUIDToString(m_device).c_str());
-
-  D3DFORMAT rtFormat = D3DFMT_X8R8G8B8;
-  CHECK(m_service->GetVideoProcessorCaps(m_device, &m_desc, rtFormat, &m_caps))
-
-  /* HACK for Intel Egde Device. 
-   * won't work if backward refs is equals value from the capabilities *
-   * Possible reasons are:                                             *
-   * 1) The device capabilities are incorrectly reported               *
-   * 2) The device is broken                                           */
-  if (IsEqualGUID(m_device, DXVA2_VideoProcIntelEdgeDevice))
-    m_caps.NumBackwardRefSamples = 0;
-
-  if (m_caps.DeviceCaps & DXVA2_VPDev_SoftwareDevice)
-    CLog::Log(LOGDEBUG, "DXVA - processor is software device");
-
-  if (m_caps.DeviceCaps & DXVA2_VPDev_EmulatedDXVA1)
-    CLog::Log(LOGDEBUG, "DXVA - processor is emulated dxva1");
-
-  CLog::Log(LOGDEBUG, "DXVA - processor requires %d past frames and %d future frames", m_caps.NumBackwardRefSamples, m_caps.NumForwardRefSamples);
-
-  if (m_caps.NumBackwardRefSamples + m_caps.NumForwardRefSamples + 3 > m_size)
-  {
-    CLog::Log(LOGERROR, "DXVA - used an incorrect number of reference frames creating processor");
-    return false;
-  }
-
-  CHECK(m_service->CreateVideoProcessor(m_device, &m_desc, rtFormat, 0, &m_process));
-
-  CHECK(m_service->GetProcAmpRange(m_device, &m_desc, rtFormat, DXVA2_ProcAmp_Brightness, &m_brightness));
-  CHECK(m_service->GetProcAmpRange(m_device, &m_desc, rtFormat, DXVA2_ProcAmp_Contrast  , &m_contrast));
-  CHECK(m_service->GetProcAmpRange(m_device, &m_desc, rtFormat, DXVA2_ProcAmp_Hue       , &m_hue));
-  CHECK(m_service->GetProcAmpRange(m_device, &m_desc, rtFormat, DXVA2_ProcAmp_Saturation, &m_saturation));
-
-  return true;
-}
-
-bool CProcessor::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_desc.SampleWidth + 15) & ~15,
-                                (m_desc.SampleHeight + 15) & ~15,
-                                m_desc.Format,
-                                D3DPOOL_DEFAULT,
-                                &m_surfaces[idx],
-                                NULL));
-
-  m_context = new CSurfaceContext();
-
-  return true;
-}
-
-REFERENCE_TIME CProcessor::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:
-    {
-      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
-      for (unsigned y = 0; y < picture->iHeight/2; y++)
-      {
-        uint8_t *s_u = picture->data[1] + (y * picture->iLineSize[1]);
-        uint8_t *s_v = picture->data[2] + (y * picture->iLineSize[2]);
-        uint8_t *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, "DXVA - colorspace not supported by processor, skipping frame");
-      return 0;
-    }
-  }
-
-  if (!surface || !context)
-    return 0;
-
-  m_time += 2;
-
-  surface->AddRef();
-  context->Acquire();
-
-  SVideoSample vs = {};
-  vs.sample.Start          = m_time;
-  vs.sample.End            = 0; 
-  vs.sample.SampleFormat   = m_desc.SampleFormat;
-
-  if (picture->iFlags & DVP_FLAG_INTERLACED)
-  {
-    if (picture->iFlags & DVP_FLAG_TOP_FIELD_FIRST)
-      vs.sample.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst;
-    else
-      vs.sample.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedOddFirst;
-  }
-  else
-  {
-    vs.sample.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
-  }
-
-  vs.sample.PlanarAlpha    = DXVA2_Fixed32OpaqueAlpha();
-  vs.sample.SampleData     = 0;
-  vs.sample.SrcSurface     = surface;
-
-
-  vs.context = context;
-
-  if(!m_sample.empty())
-    m_sample.back().sample.End = vs.sample.Start;
-
-  m_sample.push_back(vs);
-  if (m_sample.size() > m_size)
-  {
-    SAFE_RELEASE(m_sample.front().context);
-    SAFE_RELEASE(m_sample.front().sample.SrcSurface);
-    m_sample.pop_front();
-  }
-
-  return m_time;
-}
-
-static DXVA2_Fixed32 ConvertRange(const DXVA2_ValueRange& range, int value, int min, int max, int def)
-{
-  if(value > def)
-    return DXVA2FloatToFixed( DXVA2FixedToFloat(range.DefaultValue)
-                            + (DXVA2FixedToFloat(range.MaxValue) - DXVA2FixedToFloat(range.DefaultValue))
-                            * (value - def) / (max - def) );
-  else if(value < def)
-    return DXVA2FloatToFixed( DXVA2FixedToFloat(range.DefaultValue)
-                            + (DXVA2FixedToFloat(range.MinValue) - DXVA2FixedToFloat(range.DefaultValue)) 
-                            * (value - def) / (min - def) );
-  else
-    return range.DefaultValue;
-}
-
-bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFERENCE_TIME time, DWORD flags)
-{
-  CSingleLock lock(m_section);
-
-  // With auto deinterlacing, the Ion Gen. 1 drops some frames with deinterlacing processor + progressive flags for progressive material.
-  // For that GPU (or when specified by an advanced setting), use the progressive processor.
-  // This is at the expense of the switch speed when video interlacing flags change and a deinterlacing processor is actually required.
-  EDEINTERLACEMODE mode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
-  if (g_advancedSettings.m_DXVANoDeintProcForProgressive || m_quirk_nodeintprocforprog)
-    mode = (flags & RENDER_FLAG_FIELD0 || flags & RENDER_FLAG_FIELD1) ? VS_DEINTERLACEMODE_FORCE : VS_DEINTERLACEMODE_OFF;
-  EINTERLACEMETHOD method = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);
-  if(m_interlace_method != method
-  || m_deinterlace_mode != mode
-  || !m_process)
-  {
-    m_deinterlace_mode = mode;
-    m_interlace_method = method;
-
-    if (!OpenProcessor())
-      return false;
-  }
-  
-  // MinTime and MaxTime are the first and last samples to keep. Delete the rest.
-  REFERENCE_TIME MinTime = time - m_max_back_refs*2;
-  REFERENCE_TIME MaxTime = time + m_max_fwd_refs*2;
-
-  SSamples::iterator it = m_sample.begin();
-  while (it != m_sample.end())
-  {
-    if (it->sample.Start < MinTime)
-    {
-      SAFE_RELEASE(it->context);
-      SAFE_RELEASE(it->sample.SrcSurface);
-      it = m_sample.erase(it);
-    }
-    else
-      ++it;
-  }
-
-  if(m_sample.empty())
-    return false;
-
-  // MinTime and MaxTime are now the first and last samples to feed the processor.
-  MinTime = time - m_caps.NumBackwardRefSamples*2;
-  MaxTime = time + m_caps.NumForwardRefSamples*2;
-
-  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 };
-
-
-  // How to prepare the samples array for VideoProcessBlt
-  // - always provide current picture + the number of forward and backward references required by the current processor.
-  // - provide the surfaces in the array in increasing temporal order
-  // - at the start of playback, there may not be enough samples available. Use SampleFormat.SampleFormat = DXVA2_SampleUnknown for the missing samples.
-
-  int count = 1 + m_caps.NumBackwardRefSamples + m_caps.NumForwardRefSamples;
-  int valid = 0;
-  auto_aptr<DXVA2_VideoSample> samp(new DXVA2_VideoSample[count]);
-
-  for (int i = 0; i < count; i++)
-    samp[i].SampleFormat.SampleFormat = DXVA2_SampleUnknown;
-
-  for(it = m_sample.begin(); it != m_sample.end() && valid < count; ++it)
-  {
-    if (it->sample.Start >= MinTime && it->sample.Start <= MaxTime)
-    {
-      DXVA2_VideoSample& vs = samp[(it->sample.Start - MinTime) / 2];
-      vs = it->sample;
-      vs.SrcRect = sourceRECT;
-      vs.DstRect = dstRECT;
-      if(vs.End == 0)
-        vs.End = vs.Start + 2;
-
-      // Override the sample format when the processor doesn't need to deinterlace or when deinterlacing is forced and flags are missing.
-      if (m_progressive)
-        vs.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
-      else if (m_deinterlace_mode == VS_DEINTERLACEMODE_FORCE && vs.SampleFormat.SampleFormat == DXVA2_SampleProgressiveFrame)
-        vs.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst;
-
-      valid++;
-    }
-  }
-  
-  // MS' guidelines above don't work. The blit fails when the processor is given DXVA2_SampleUnknown samples (with ATI at least).
-  // The ATI driver works with a reduced number of samples though, support that for now.
-  // Problem is an ambiguity if there are future refs requested by the processor. There are no such implementations at the moment.
-  int offset = 0;
-  if(valid < count)
-  {
-    CLog::Log(LOGWARNING, __FUNCTION__" - did not find all required samples, adjusting the sample array.");
-
-    for (int i = 0; i < count; i++)
-    {
-      if (samp[i].SampleFormat.SampleFormat == DXVA2_SampleUnknown)
-        offset = i+1;
-    }
-    count -= offset;
-    if (count == 0)
-    {
-      CLog::Log(LOGWARNING, __FUNCTION__" - no usable samples.");
-      return false;
-    }
-  }
-
-  DXVA2_VideoProcessBltParams blt = {};
-  blt.TargetFrame = time;
-  if (flags & RENDER_FLAG_FIELD1)
-    blt.TargetFrame += 1;
-  blt.TargetRect  = dstRECT;
-  blt.ConstrictionSize.cx = 0;
-  blt.ConstrictionSize.cy = 0;
-
-  blt.DestFormat.VideoTransferFunction = DXVA2_VideoTransFunc_sRGB;
-  blt.DestFormat.SampleFormat          = DXVA2_SampleProgressiveFrame;
-  if(g_Windowing.UseLimitedColor())
-    blt.DestFormat.NominalRange          = DXVA2_NominalRange_16_235;
-  else
-    blt.DestFormat.NominalRange          = DXVA2_NominalRange_0_255;
-  blt.Alpha = DXVA2_Fixed32OpaqueAlpha();
-
-  blt.ProcAmpValues.Brightness = ConvertRange( m_brightness, CMediaSettings::Get().GetCurrentVideoSettings().m_Brightness
-                                             , 0, 100, 50);
-  blt.ProcAmpValues.Contrast   = ConvertRange( m_contrast, CMediaSettings::Get().GetCurrentVideoSettings().m_Contrast
-                                             , 0, 100, 50);
-  blt.ProcAmpValues.Hue        = m_hue.DefaultValue;
-  blt.ProcAmpValues.Saturation = m_saturation.DefaultValue;
-
-  blt.BackgroundColor.Y     = 0x1000;
-  blt.BackgroundColor.Cb    = 0x8000;
-  blt.BackgroundColor.Cr    = 0x8000;
-  blt.BackgroundColor.Alpha = 0xffff;
-
-  /* HACK to kickstart certain DXVA drivers (poulsbo) which oddly  *
-   * won't render anything until someting else have been rendered. */
-  g_Windowing.Get3DDevice()->SetFVF( D3DFVF_XYZ );
-  float verts[2][3]= {};
-  g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 1, verts, 3*sizeof(float));
-
-  CHECK(m_process->VideoProcessBlt(target, &blt, &samp[offset], count, NULL));
-  return true;
-}
 
 #endif
index 2dcb142..fa24556 100644 (file)
 
 namespace DXVA {
 
+#define CHECK(a) \
+do { \
+  HRESULT res = a; \
+  if(FAILED(res)) \
+  { \
+    CLog::Log(LOGERROR, "DXVA - failed executing "#a" at line %d with error %x", __LINE__, res); \
+    return false; \
+  } \
+} while(0);
+
 class CSurfaceContext
   : public IDVDResourceCounted<CSurfaceContext>
 {
@@ -143,68 +153,4 @@ protected:
   CEvent                       m_event;
 };
 
-class CProcessor
-  : public ID3DResource
-{
-public:
-  CProcessor();
- ~CProcessor();
-
-  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(); }
-  virtual void OnLostDevice()    { CSingleLock lock(m_section); Close(); }
-  virtual void OnResetDevice()   { CSingleLock lock(m_section); Close(); }
-
-protected:
-  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;
-  GUID                           m_device;
-
-  DXVA2_VideoProcessorCaps m_caps;
-  DXVA2_VideoDesc  m_desc;
-
-  DXVA2_ValueRange m_brightness;
-  DXVA2_ValueRange m_contrast;
-  DXVA2_ValueRange m_hue;
-  DXVA2_ValueRange m_saturation;
-  REFERENCE_TIME   m_time;
-  unsigned         m_size;
-  unsigned         m_max_back_refs;
-  unsigned         m_max_fwd_refs;
-  EDEINTERLACEMODE m_deinterlace_mode;
-  EINTERLACEMETHOD m_interlace_method;
-  bool             m_progressive; // true for progressive source or to force ignoring interlacing flags.
-  unsigned         m_index;
-
-  struct SVideoSample
-  {
-    DXVA2_VideoSample sample;
-    CSurfaceContext* context;
-  };
-
-  typedef std::deque<SVideoSample> SSamples;
-  SSamples          m_sample;
-
-  CCriticalSection  m_section;
-
-  LPDIRECT3DSURFACE9* m_surfaces;
-  CSurfaceContext* m_context;
-
-  bool             m_quirk_nodeintprocforprog;
-};
-
 };
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVAHD.cpp
deleted file mode 100644 (file)
index 3a90d6a..0000000
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- *      Copyright (C) 2005-2013 Team XBMC
- *      http://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"
-#include "utils/Log.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;
-
-  HRESULT cvres = g_DXVAHDCreateVideoService( (IDirect3DDevice9Ex*)g_Windowing.Get3DDevice()
-                                              , &desc
-                                              , DXVAHD_DEVICE_USAGE_OPTIMAL_QUALITY
-                                              , NULL
-                                              , &m_pDXVAHD );
-
-  if(FAILED(cvres))
-  {
-    if(cvres == E_NOINTERFACE)
-      CLog::Log(LOGNOTICE, __FUNCTION__" - The Direct3d device doesn't support DXVA-HD.");
-    else
-      CLog::Log(LOGERROR, __FUNCTION__" - failed to create DXVAHD device %x", cvres);
-
-    return false;
-  }
-
-  CHECK(m_pDXVAHD->GetVideoProcessorDeviceCaps( &m_VPDevCaps ));
-
-  if (m_VPDevCaps.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_VPDevCaps.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_VPDevCaps.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_VPDevCaps.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_VPDevCaps.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
-    0,                                          // RGB_Range: 0=Full, 1=Limited
-    m_flags & CONF_FLAGS_YUVCOEF_BT709 ? 1 : 0, // YCbCr_Matrix: 0=BT.601, 1=BT.709
-    m_flags & CONF_FLAGS_YUV_FULLRANGE ? 1 : 0  // 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_VPDevCaps.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);
-
-  // 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-1, T-2, T-3 }
-        stream_data.ppPastSurfaces[(frame - it->index)/2 - 1] = 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;
-  }
-
-  // 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);
-  }
-
-  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
deleted file mode 100644 (file)
index 811841f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *      Copyright (C) 2005-2013 Team XBMC
- *      http://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 "libavcodec/avcodec.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_VPDevCaps;
-  DXVAHD_VPCAPS            m_VPCaps;
-  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;
-};
-
-};