From 53583f1b60b912a04d34c4b3896a1c77ff1ecf3b Mon Sep 17 00:00:00 2001 From: Istvan Stikrad Date: Thu, 28 Jul 2011 11:13:42 +0200 Subject: [PATCH] DXVA rendering for software decoded material - thanks isidrogar --- xbmc/cores/VideoRenderers/RenderFlags.h | 20 ++ xbmc/cores/VideoRenderers/RenderManager.cpp | 8 +- xbmc/cores/VideoRenderers/WinRenderer.cpp | 54 ++++- xbmc/cores/VideoRenderers/WinRenderer.h | 4 +- .../dvdplayer/DVDCodecs/Video/DVDVideoCodec.h | 3 + .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 4 + .../DVDCodecs/Video/DVDVideoCodecLibMpeg2.cpp | 3 + xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp | 214 +++++++++++++++++- xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h | 10 +- xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 51 +++++ xbmc/cores/dvdplayer/DVDPlayerVideo.h | 3 + xbmc/settings/GUISettings.cpp | 2 + xbmc/settings/GUISettings.h | 1 + 13 files changed, 358 insertions(+), 19 deletions(-) diff --git a/xbmc/cores/VideoRenderers/RenderFlags.h b/xbmc/cores/VideoRenderers/RenderFlags.h index 38394e0099801..c97e891f34667 100644 --- a/xbmc/cores/VideoRenderers/RenderFlags.h +++ b/xbmc/cores/VideoRenderers/RenderFlags.h @@ -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 diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp index 4dd6b0fd10c7a..c18c1a879f006 100644 --- a/xbmc/cores/VideoRenderers/RenderManager.cpp +++ b/xbmc/cores/VideoRenderers/RenderManager.cpp @@ -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); diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp index 1277d609ace26..3844d1ab50949 100644 --- a/xbmc/cores/VideoRenderers/WinRenderer.cpp +++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp @@ -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; diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h index 02715718e6999..0f8e69647dcfd 100644 --- a/xbmc/cores/VideoRenderers/WinRenderer.h +++ b/xbmc/cores/VideoRenderers/WinRenderer.h @@ -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; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h index f31a10d2d0691..25ebcd73596d9 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h @@ -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 diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp index da2d14f18bbcf..128ced73e9556 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -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; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecLibMpeg2.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecLibMpeg2.cpp index 42552dcd777a0..6e0aec965bc3a 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecLibMpeg2.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecLibMpeg2.cpp @@ -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; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp index bf375c1e2bb34..b9fee8715dbee 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp @@ -641,10 +641,7 @@ bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture CSingleLock lock(m_section); picture->format = DVDVideoPicture::FMT_DXVA; picture->proc = m_processor; - if(picture->iFlags & DVP_FLAG_DROPPED) - picture->proc_id = 0; - else - picture->proc_id = m_processor->Add((IDirect3DSurface9*)frame->data[3]); + picture->data[3]= frame->data[3]; return true; } @@ -884,6 +881,9 @@ CProcessor::CProcessor() m_process = NULL; m_time = 0; g_Windowing.Register(this); + + m_surfaces = NULL; + m_index = 0; } CProcessor::~CProcessor() @@ -902,10 +902,122 @@ void CProcessor::Close() m_sample.clear(); for (vector::iterator it = m_heldsurfaces.begin(); it != m_heldsurfaces.end(); it++) SAFE_RELEASE(*it); + + if (m_surfaces) + { + for (unsigned i = 0; i < m_surfaces_count; i++) SAFE_RELEASE(m_surfaces[i]); + free(m_surfaces); + m_surfaces = NULL; + } +} + +bool CProcessor::Open(UINT width, UINT height, unsigned int flags) +{ + // Only NV12 software colorspace conversion is implemented for now + if (Open(width, height, flags, (D3DFORMAT)MAKEFOURCC('N','V','1','2'))) + return true; + + // Future... + //if (Open(width, height, flags, (D3DFORMAT)MAKEFOURCC('Y','U','Y','2'))) + // return true; + + //if (Open(width, height, flags, (D3DFORMAT)MAKEFOURCC('U','Y','V','Y'))) + // return true; + + return false; +} + +bool CProcessor::Open(UINT width, UINT height, unsigned int flags, D3DFORMAT format) +{ + DXVA2_VideoDesc dsc; + memset(&dsc, 0, sizeof(DXVA2_VideoDesc)); + + dsc.Format = format; + dsc.SampleWidth = width; + dsc.SampleHeight = height; + dsc.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame; + 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; + } + + return Open(dsc); } bool CProcessor::Open(const DXVA2_VideoDesc& dsc) { + Close(); + if(!LoadDXVA()) return false; @@ -972,6 +1084,25 @@ void CProcessor::HoldSurface(IDirect3DSurface9* surface) m_heldsurfaces.push_back(surface); } +bool CProcessor::CreateSurfaces() +{ + CSingleLock lock(m_section); + + m_surfaces_count = m_size; + m_surfaces = (LPDIRECT3DSURFACE9*)calloc(m_surfaces_count, sizeof(LPDIRECT3DSURFACE9)); + CHECK(m_service->CreateSurface((m_desc.SampleWidth + 15) & ~15, + (m_desc.SampleHeight + 15) & ~15, + m_surfaces_count - 1, + m_desc.Format, + D3DPOOL_DEFAULT, + 0, + DXVA2_VideoSoftwareRenderTarget, + m_surfaces, + NULL)); + + return true; +} + REFERENCE_TIME CProcessor::Add(IDirect3DSurface9* source) { CSingleLock lock(m_section); @@ -1004,6 +1135,81 @@ REFERENCE_TIME CProcessor::Add(IDirect3DSurface9* source) return m_time; } +bool CProcessor::ProcessPicture(DVDVideoPicture* picture) +{ + CSingleLock lock(m_section); + + IDirect3DSurface9* surface = NULL; + + switch (picture->format) + { + case DVDVideoPicture::FMT_DXVA: + { + surface = (IDirect3DSurface9*)picture->data[3]; + break; + } + + case DVDVideoPicture::FMT_YUV420P: + { + surface = m_surfaces[m_index]; + m_index = (m_index + 1) % m_size; + + D3DLOCKED_RECT rectangle; + CHECK(surface->LockRect(&rectangle, NULL, 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; + CHECK(surface->GetDesc(&desc)); + + // 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++; + } + } + + CHECK(surface->UnlockRect()); + + picture->proc = this; + picture->format = DVDVideoPicture::FMT_DXVA; + break; + } + + default: + { + CLog::Log(LOGWARNING, "DXVA - colorspace not supported by processor, skipping frame"); + return false; + } + } + + if (!surface) + return false; + + if (picture->iFlags & DVP_FLAG_DROPPED) + picture->proc_id = 0; + else + picture->proc_id = Add(surface); + + return true; +} + static DXVA2_Fixed32 ConvertRange(const DXVA2_ValueRange& range, int value, int min, int max, int def) { if(value > def) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h index c61817c1e5ec6..b829df2cbb8fb 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h @@ -106,10 +106,13 @@ class CProcessor CProcessor(); ~CProcessor(); + bool Open(UINT width, UINT height, unsigned int flags); bool Open(const DXVA2_VideoDesc& dsc); + bool CreateSurfaces(); void Close(); void HoldSurface(IDirect3DSurface9* surface); REFERENCE_TIME Add(IDirect3DSurface9* source); + bool ProcessPicture(DVDVideoPicture* picture); bool Render(const RECT& dst, IDirect3DSurface9* target, const REFERENCE_TIME time); int Size() { return m_size; } @@ -118,6 +121,9 @@ class CProcessor virtual void OnLostDevice() { CSingleLock lock(m_section); Close(); } virtual void OnResetDevice() { CSingleLock lock(m_section); Close(); } +protected: + bool Open(UINT width, UINT height, unsigned int flags, D3DFORMAT format); + IDirectXVideoProcessorService* m_service; IDirectXVideoProcessor* m_process; GUID m_device; @@ -132,13 +138,15 @@ class CProcessor REFERENCE_TIME m_time; unsigned m_size; + unsigned m_index; typedef std::deque SSamples; SSamples m_sample; CCriticalSection m_section; -protected: std::vector m_heldsurfaces; + LPDIRECT3DSURFACE9* m_surfaces; + unsigned m_surfaces_count; }; }; diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp index 566bfe22aa49d..c1309ab54a71c 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp @@ -913,6 +913,9 @@ int CDVDPlayerVideo::OutputPicture(DVDVideoPicture* pPicture, double pts) || m_output.framerate != m_fFrameRate || m_output.color_format != (unsigned int)pPicture->format || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified + || ( m_output.chroma_position != pPicture->chroma_position && pPicture->chroma_position != 0 ) + || ( m_output.color_primaries != pPicture->color_primaries && pPicture->color_primaries != 0 ) + || ( m_output.color_transfer != pPicture->color_transfer && pPicture->color_transfer != 0 ) || m_output.color_range != pPicture->color_range) { CLog::Log(LOGNOTICE, " fps: %f, pwidth: %i, pheight: %i, dwidth: %i, dheight: %i", @@ -944,6 +947,51 @@ int CDVDPlayerVideo::OutputPicture(DVDVideoPicture* pPicture, double pts) break; } + switch(pPicture->chroma_position) + { + case 1: + flags |= CONF_FLAGS_CHROMA_LEFT; + break; + case 2: + flags |= CONF_FLAGS_CHROMA_CENTER; + break; + case 3: + flags |= CONF_FLAGS_CHROMA_TOPLEFT; + break; + } + + switch(pPicture->color_primaries) + { + case 1: + flags |= CONF_FLAGS_COLPRI_BT709; + break; + case 4: + flags |= CONF_FLAGS_COLPRI_BT470M; + break; + case 5: + flags |= CONF_FLAGS_COLPRI_BT470BG; + break; + case 6: + flags |= CONF_FLAGS_COLPRI_170M; + break; + case 7: + flags |= CONF_FLAGS_COLPRI_240M; + break; + } + + switch(pPicture->color_transfer) + { + case 1: + flags |= CONF_FLAGS_TRC_BT709; + break; + case 4: + flags |= CONF_FLAGS_TRC_GAMMA22; + break; + case 5: + flags |= CONF_FLAGS_TRC_GAMMA28; + break; + } + CStdString formatstr; switch(pPicture->format) @@ -1005,6 +1053,9 @@ int CDVDPlayerVideo::OutputPicture(DVDVideoPicture* pPicture, double pts) m_output.framerate = m_fFrameRate; m_output.color_format = pPicture->format; m_output.color_matrix = pPicture->color_matrix; + m_output.chroma_position = pPicture->chroma_position; + m_output.color_primaries = pPicture->color_primaries; + m_output.color_transfer = pPicture->color_transfer; m_output.color_range = pPicture->color_range; } diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h index 33e04345080bd..d35febb98eec8 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h @@ -152,6 +152,9 @@ class CDVDPlayerVideo : public CThread unsigned int color_format; unsigned int color_matrix : 4; unsigned int color_range : 1; + unsigned int chroma_position; + unsigned int color_primaries; + unsigned int color_transfer; double framerate; bool inited; } m_output; //holds currently configured output diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp index 7d471a4319f51..6d95944da4aeb 100644 --- a/xbmc/settings/GUISettings.cpp +++ b/xbmc/settings/GUISettings.cpp @@ -570,6 +570,8 @@ void CGUISettings::Initialize() renderers.insert(make_pair(13416, RENDER_METHOD_AUTO)); #ifdef HAS_DX + if (g_sysinfo.IsVistaOrHigher()) + renderers.insert(make_pair(16319, RENDER_METHOD_DXVA)); renderers.insert(make_pair(13431, RENDER_METHOD_D3D_PS)); renderers.insert(make_pair(13419, RENDER_METHOD_SOFTWARE)); #endif diff --git a/xbmc/settings/GUISettings.h b/xbmc/settings/GUISettings.h index 18bb95a3d2b20..65b5801c9e5c3 100644 --- a/xbmc/settings/GUISettings.h +++ b/xbmc/settings/GUISettings.h @@ -35,6 +35,7 @@ class TiXmlElement; #define RENDER_METHOD_GLSL 2 #define RENDER_METHOD_SOFTWARE 3 #define RENDER_METHOD_D3D_PS 4 +#define RENDER_METHOD_DXVA 5 #define RENDER_OVERLAYS 99 // to retain compatibility // Scaling options.