Permalink
Browse files

DXVA rendering for software decoded material - thanks isidrogar

  • Loading branch information...
1 parent 30a9070 commit 53583f1b60b912a04d34c4b3896a1c77ff1ecf3b @a11599 a11599 committed Jul 28, 2011
@@ -45,6 +45,26 @@
#define CONF_FLAGS_YUV_FULLRANGE 0x08
#define CONF_FLAGS_FULLSCREEN 0x10
+/* defines color primaries */
+#define CONF_FLAGS_COLPRI_MASK(a) ((a) & 0xe0)
+#define CONF_FLAGS_COLPRI_BT709 0x20
+#define CONF_FLAGS_COLPRI_BT470M 0x40
+#define CONF_FLAGS_COLPRI_BT470BG 0x60
+#define CONF_FLAGS_COLPRI_170M 0x80
+#define CONF_FLAGS_COLPRI_240M 0xa0
+
+/* defines chroma subsampling sample location */
+#define CONF_FLAGS_CHROMA_MASK(a) ((a) & 0x0300)
+#define CONF_FLAGS_CHROMA_LEFT 0x0100
+#define CONF_FLAGS_CHROMA_CENTER 0x0200
+#define CONF_FLAGS_CHROMA_TOPLEFT 0x0300
+
+/* defines color transfer function */
+#define CONF_FLAGS_TRC_MASK(a) ((a) & 0x0c00)
+#define CONF_FLAGS_TRC_BT709 0x0400
+#define CONF_FLAGS_TRC_GAMMA22 0x0800
+#define CONF_FLAGS_TRC_GAMMA28 0x0c00
+
#define CONF_FLAGS_FORMAT_MASK(a) ((a) & 0xff000)
#define CONF_FLAGS_FORMAT_YV12 0x01000
#define CONF_FLAGS_FORMAT_NV12 0x02000
@@ -694,6 +694,10 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic)
if (!m_pRenderer)
return -1;
+#ifdef HAS_DX
+ m_pRenderer->AddProcessor(&pic);
+#endif
+
YV12Image image;
int index = m_pRenderer->GetImage(&image);
@@ -713,10 +717,6 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic)
{
CDVDCodecUtils::CopyYUV422PackedPicture(&image, &pic);
}
-#ifdef HAS_DX
- else if(pic.format == DVDVideoPicture::FMT_DXVA)
- m_pRenderer->AddProcessor(pic.proc, pic.proc_id);
-#endif
#ifdef HAVE_LIBVDPAU
else if(pic.format == DVDVideoPicture::FMT_VDPAU)
m_pRenderer->AddProcessor(pic.vdpau);
@@ -80,6 +80,7 @@ CWinRenderer::CWinRenderer()
m_sw_scale_ctx = NULL;
m_dllSwScale = NULL;
+ m_processor = NULL;
}
CWinRenderer::~CWinRenderer()
@@ -139,6 +140,25 @@ void CWinRenderer::SelectRenderMethod()
switch(requestedMethod)
{
+ case RENDER_METHOD_DXVA:
+ if (CONF_FLAGS_FORMAT_MASK(m_flags) == CONF_FLAGS_FORMAT_YV12)
+ {
+ if (m_processor == NULL)
+ m_processor = new DXVA::CProcessor();
+
+ if (m_processor->Open(m_sourceWidth, m_sourceHeight, m_flags)
+ && m_processor->CreateSurfaces())
+ {
+ m_renderMethod = RENDER_DXVA;
+ break;
+ }
+ else
+ {
+ m_processor->Close();
+ SAFE_RELEASE(m_processor);
+ }
+ }
+ // Drop through to pixel shader
case RENDER_METHOD_AUTO:
case RENDER_METHOD_D3D_PS:
// Try the pixel shaders support
@@ -235,15 +255,25 @@ int CWinRenderer::NextYV12Texture()
return -1;
}
-void CWinRenderer::AddProcessor(DXVA::CProcessor* processor, int64_t id)
+void CWinRenderer::AddProcessor(DVDVideoPicture* picture)
{
- int source = NextYV12Texture();
- if(source < 0)
- return;
- DXVABuffer *buf = (DXVABuffer*)m_VideoBuffers[source];
- SAFE_RELEASE(buf->proc);
- buf->proc = processor->Acquire();
- buf->id = id;
+ if (m_renderMethod == RENDER_DXVA)
+ {
+ int source = NextYV12Texture();
+ if(source < 0)
+ return;
+
+ DXVA::CProcessor* processor = m_processor;
+ if (CONF_FLAGS_FORMAT_MASK(m_flags) == CONF_FLAGS_FORMAT_DXVA)
+ processor = picture->proc;
+
+ processor->ProcessPicture(picture);
+
+ DXVABuffer *buf = (DXVABuffer*)m_VideoBuffers[source];
+ SAFE_RELEASE(buf->proc);
+ buf->proc = processor->Acquire();
+ buf->id = picture->proc_id;
+ }
}
int CWinRenderer::GetImage(YV12Image *image, int source, bool readonly)
@@ -351,6 +381,12 @@ void CWinRenderer::UnInit()
{
CSingleLock lock(g_graphicsContext);
+ if (m_processor)
+ {
+ m_processor->Close();
+ SAFE_RELEASE(m_processor);
+ }
+
if (m_SWTarget.Get())
m_SWTarget.Release();
@@ -589,7 +625,7 @@ void CWinRenderer::CropSource(RECT& src, RECT& dst, const D3DSURFACE_DESC& desc)
void CWinRenderer::Render(DWORD flags)
{
- if(CONF_FLAGS_FORMAT_MASK(m_flags) == CONF_FLAGS_FORMAT_DXVA)
+ if (m_renderMethod == RENDER_DXVA)
{
CWinRenderer::RenderProcessor(flags);
return;
@@ -80,6 +80,7 @@ class DllAvCodec;
class DllSwScale;
namespace DXVA { class CProcessor; }
+struct DVDVideoPicture;
struct DRAWRECT
{
@@ -196,7 +197,7 @@ class CWinRenderer : public CBaseRenderer
virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags);
virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
virtual void ReleaseImage(int source, bool preserve = false);
- virtual void AddProcessor(DXVA::CProcessor* processor, int64_t id);
+ virtual void AddProcessor(DVDVideoPicture* picture);
virtual void FlipPage(int source);
virtual unsigned int PreInit();
virtual void UnInit();
@@ -241,6 +242,7 @@ class CWinRenderer : public CBaseRenderer
bool m_bConfigured;
SVideoBuffer *m_VideoBuffers[NUM_BUFFERS];
RenderMethod m_renderMethod;
+ DXVA::CProcessor* m_processor;
// software scale libraries (fallback if required pixel shaders version is not available)
DllAvUtil *m_dllAvUtil;
@@ -85,6 +85,9 @@ struct DVDVideoPicture
unsigned int iFrameType : 4; // see defines above // 1->I, 2->P, 3->B, 0->Undef
unsigned int color_matrix : 4;
unsigned int color_range : 1; // 1 indicate if we have a full range of color
+ unsigned int chroma_position;
+ unsigned int color_primaries;
+ unsigned int color_transfer;
int iGroupId;
int8_t* qscale_table; // Quantization parameters, primarily used by filters
@@ -602,6 +602,10 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
if(m_pCodecContext->pix_fmt == PIX_FMT_YUVJ420P)
pDvdVideoPicture->color_range = 1;
+ pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location;
+ pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries;
+ pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc;
+
pDvdVideoPicture->qscale_table = m_pFrame->qscale_table;
pDvdVideoPicture->qscale_stride = m_pFrame->qstride;
@@ -428,6 +428,9 @@ int CDVDVideoCodecLibMpeg2::Decode(BYTE* pData, int iSize, double dts, double pt
// make sure we send the color coeficients with the image
pBuffer->color_matrix = m_pInfo->sequence->matrix_coefficients;
pBuffer->color_range = 0; // mpeg2 always have th 16->235/229 color range
+ pBuffer->chroma_position = 1; // mpeg2 chroma positioning always left
+ pBuffer->color_primaries = m_pInfo->sequence->colour_primaries;
+ pBuffer->color_transfer = m_pInfo->sequence->transfer_characteristics;
TagUnion u;
u.tag.l = m_pInfo->display_picture->tag;
Oops, something went wrong.

0 comments on commit 53583f1

Please sign in to comment.