diff options
author | Anton Fedchin <afedchin@users.noreply.github.com> | 2016-04-25 14:55:14 +0400 |
---|---|---|
committer | Anton Fedchin <afedchin@users.noreply.github.com> | 2016-04-25 14:55:14 +0400 |
commit | 738434cb9e9068c4afd1ab4a9096c6a6f1f1744e (patch) | |
tree | 4acc87855b405000a8c7b6b7885dd1900eaa7629 | |
parent | 4b3b39d2dbdb2b0d8e2f1a3b1fbbec5de9aaeca3 (diff) | |
parent | 774f262141f26bfaeca8eb5bf41519977532274c (diff) |
Merge pull request #9678 from afedchin/win32_fixes
[Win32] a set of fixes for windows.
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp | 2 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h | 73 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp | 161 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h | 92 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp | 9 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h | 21 | ||||
-rw-r--r-- | xbmc/rendering/dx/RenderSystemDX.cpp | 4 | ||||
-rw-r--r-- | xbmc/windowing/windows/WinSystemWin32.cpp | 42 | ||||
-rw-r--r-- | xbmc/windowing/windows/WinSystemWin32.h | 1 | ||||
-rw-r--r-- | xbmc/windowing/windows/WinSystemWin32DX.cpp | 15 |
10 files changed, 224 insertions, 196 deletions
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp index 2b959135f3..f8730c5abf 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp @@ -671,7 +671,7 @@ bool CSurfaceContext::HasRefs() } //----------------------------------------------------------------------------- -// DXVA RednerPictures +// DXVA RenderPictures //----------------------------------------------------------------------------- CRenderPicture::CRenderPicture(CSurfaceContext *context) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h index 5cf14ae6e6..ab756f74c1 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h @@ -72,6 +72,7 @@ public: CRenderPicture(CSurfaceContext *context); ~CRenderPicture(); ID3D11View* view; + protected: CSurfaceContext *surface_context; }; @@ -87,6 +88,7 @@ public: bool CreateDecoder(D3D11_VIDEO_DECODER_DESC *format, const D3D11_VIDEO_DECODER_CONFIG *config, ID3D11VideoDecoder **decoder, ID3D11VideoContext **context); void Release(CDecoder *decoder); ID3D11VideoContext* GetVideoContext() { return m_vcontext; } + private: CDXVAContext(); void Close(); @@ -94,8 +96,10 @@ private: void DestroyContext(); void QueryCaps(); bool IsValidDecoder(CDecoder *decoder); + static CDXVAContext *m_context; static CCriticalSection m_section; + ID3D11VideoContext* m_vcontext; ID3D11VideoDevice* m_service; int m_refCount; @@ -112,23 +116,26 @@ class CDecoder public: CDecoder(); ~CDecoder(); - virtual bool Open (AVCodecContext* avctx, AVCodecContext* mainctx, const enum AVPixelFormat, unsigned int surfaces); - virtual int Decode (AVCodecContext* avctx, AVFrame* frame); - virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture); - virtual int Check (AVCodecContext* avctx); - virtual void Close(); - virtual const std::string Name() { return "d3d11va"; } - virtual unsigned GetAllowedReferences(); - virtual long Release(); - bool OpenDecoder(); - int GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags); - void RelBuffer(uint8_t *data); + // IHardwareDecoder overrides + bool Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum AVPixelFormat, unsigned int surfaces) override; + int Decode(AVCodecContext* avctx, AVFrame* frame) override; + bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture) override; + int Check(AVCodecContext* avctx) override; + const std::string Name() override { return "d3d11va"; } + unsigned GetAllowedReferences() override; - static bool Supports(enum AVPixelFormat fmt); + // IDVDResourceCounted overrides + long Release() override; + bool OpenDecoder(); + int GetBuffer(AVCodecContext *avctx, AVFrame *pic, int flags); + void RelBuffer(uint8_t *data); + void Close(); void CloseDXVADecoder(); + static bool Supports(enum AVPixelFormat fmt); + protected: enum EDeviceState { DXVA_OPEN @@ -136,28 +143,26 @@ protected: , DXVA_LOST } m_state; - virtual void OnCreateDevice() {} - virtual void OnDestroyDevice() { CSingleLock lock(m_section); m_state = DXVA_LOST; m_event.Reset(); } - virtual void OnLostDevice() { CSingleLock lock(m_section); m_state = DXVA_LOST; m_event.Reset(); } - virtual void OnResetDevice() { CSingleLock lock(m_section); m_state = DXVA_RESET; m_event.Set(); } - - ID3D11VideoDecoder* m_decoder; - ID3D11VideoContext* m_vcontext; - HANDLE m_device; - D3D11_VIDEO_DECODER_DESC m_format; - int m_refs; - CRenderPicture *m_presentPicture; - - struct AVD3D11VAContext* m_context; - - CSurfaceContext* m_surface_context; - CDXVAContext* m_dxva_context; - AVCodecContext* m_avctx; - - unsigned int m_shared; - unsigned int m_surface_alignment; - CCriticalSection m_section; - CEvent m_event; + // ID3DResource overrides + void OnCreateDevice() override {} + void OnDestroyDevice() override { CSingleLock lock(m_section); m_state = DXVA_LOST; m_event.Reset(); } + void OnLostDevice() override { CSingleLock lock(m_section); m_state = DXVA_LOST; m_event.Reset(); } + void OnResetDevice() override { CSingleLock lock(m_section); m_state = DXVA_RESET; m_event.Set(); } + + int m_refs; + HANDLE m_device; + ID3D11VideoDecoder *m_decoder; + ID3D11VideoContext *m_vcontext; + D3D11_VIDEO_DECODER_DESC m_format; + CRenderPicture *m_presentPicture; + struct AVD3D11VAContext *m_context; + CSurfaceContext *m_surface_context; + CDXVAContext *m_dxva_context; + AVCodecContext *m_avctx; + unsigned int m_shared; + unsigned int m_surface_alignment; + CCriticalSection m_section; + CEvent m_event; }; }; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp index c893765cc9..42f0616ad4 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp @@ -54,6 +54,7 @@ CProcessorHD::CProcessorHD() m_pVideoContext = nullptr; m_pEnumerator = nullptr; m_pVideoProcessor = nullptr; + m_eViewType = PROCESSOR_VIEW_TYPE_UNKNOWN; g_Windowing.Register(this); m_context = nullptr; @@ -81,6 +82,7 @@ void CProcessorHD::Close() SAFE_RELEASE(m_pEnumerator); SAFE_RELEASE(m_pVideoProcessor); SAFE_RELEASE(m_context); + m_eViewType = PROCESSOR_VIEW_TYPE_UNKNOWN; } bool CProcessorHD::UpdateSize(const DXVA2_VideoDesc& dsc) @@ -122,18 +124,11 @@ bool CProcessorHD::PreInit() void CProcessorHD::ApplySupportedFormats(std::vector<ERenderFormat> *formats) { - // do not check for NV12 it supported by default - UINT flags; - if (SUCCEEDED(m_pEnumerator->CheckVideoProcessorFormat(DXGI_FORMAT_P010, &flags)) - && (flags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)) - { + if (IsFormatSupported(DXGI_FORMAT_P010, D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)) formats->push_back(RENDER_FMT_YUV420P10); - } - if (SUCCEEDED(m_pEnumerator->CheckVideoProcessorFormat(DXGI_FORMAT_P016, &flags)) - && (flags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)) - { + + if (IsFormatSupported(DXGI_FORMAT_P016, D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)) formats->push_back(RENDER_FMT_YUV420P16); - } } bool CProcessorHD::InitProcessor() @@ -170,9 +165,6 @@ bool CProcessorHD::InitProcessor() CLog::Log(LOGDEBUG, "%s - Video processor has %d max input streams.", __FUNCTION__, m_vcaps.MaxInputStreams); CLog::Log(LOGDEBUG, "%s - Video processor has %d max stream states.", __FUNCTION__, m_vcaps.MaxStreamStates); - if (0 != (m_vcaps.FeatureCaps & D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_STEREO)) - m_bStereoEnabled = true; - if (0 != (m_vcaps.FeatureCaps & D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_LEGACY)) CLog::Log(LOGWARNING, "%s - The video driver does not support full video processing capabilities.", __FUNCTION__); @@ -238,6 +230,19 @@ bool CProcessorHD::InitProcessor() return true; } +bool DXVA::CProcessorHD::IsFormatSupported(DXGI_FORMAT format, D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT support) +{ + UINT uiFlags; + if (S_OK != m_pEnumerator->CheckVideoProcessorFormat(format, &uiFlags)) + { + if (uiFlags & support) + return true; + } + + CLog::Log(LOGERROR, "%s - Unsupported format %d for %d.", __FUNCTION__, format, support); + return false; +} + bool CProcessorHD::ConfigureProcessor(unsigned int format, unsigned int extended_format) { if (g_advancedSettings.m_DXVANoDeintProcForProgressive) @@ -245,30 +250,17 @@ bool CProcessorHD::ConfigureProcessor(unsigned int format, unsigned int extended CLog::Log(LOGNOTICE, "%s - Auto deinterlacing mode workaround activated. Deinterlacing processor will be used only for interlaced frames.", __FUNCTION__); } - UINT uiFlags; // check default output format DXGI_FORMAT_B8G8R8A8_UNORM (as render target) - if (S_OK != m_pEnumerator->CheckVideoProcessorFormat(DXGI_FORMAT_B8G8R8A8_UNORM, &uiFlags) - || 0 == (uiFlags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT)) - { - CLog::Log(LOGERROR, "%s - Unsupported output format.", __FUNCTION__); + if (!IsFormatSupported(DXGI_FORMAT_B8G8R8A8_UNORM, D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT)) return false; - } if (format == RENDER_FMT_DXVA) { m_textureFormat = (DXGI_FORMAT)extended_format; - - // this was checked by decoder, but check again. - if (S_OK != m_pEnumerator->CheckVideoProcessorFormat(m_textureFormat, &uiFlags) - || 0 == (uiFlags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)) - { - CLog::Log(LOGERROR, "%s - Unsupported input format.", __FUNCTION__); - return false; - } + m_eViewType = PROCESSOR_VIEW_TYPE_DECODER; } else { - // Only NV12 software colorspace conversion is implemented for now m_textureFormat = DXGI_FORMAT_NV12; // default if (format == RENDER_FMT_YUV420P) @@ -278,16 +270,14 @@ bool CProcessorHD::ConfigureProcessor(unsigned int format, unsigned int extended if (format == RENDER_FMT_YUV420P16) m_textureFormat = DXGI_FORMAT_P016; - if (S_OK != m_pEnumerator->CheckVideoProcessorFormat(m_textureFormat, &uiFlags) - || 0 == (uiFlags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)) - { - CLog::Log(LOGERROR, "%s - Unsupported input format.", __FUNCTION__); - return false; - } - - if (!CreateSurfaces()) - return false; + m_eViewType = PROCESSOR_VIEW_TYPE_PROCESSOR; } + + if (!IsFormatSupported(m_textureFormat, D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT)) + return false; + if (m_eViewType == PROCESSOR_VIEW_TYPE_PROCESSOR && !CreateSurfaces()) + return false; + return true; } @@ -365,25 +355,6 @@ bool CProcessorHD::OpenProcessor() color.YCbCr = { 0.0625f, 0.5f, 0.5f, 1.0f }; // black color m_pVideoContext->VideoProcessorSetOutputBackgroundColor(m_pVideoProcessor, TRUE, &color); - // the following code is unneeded, keep it for reference only - /*if (0 != (m_vcaps.FeatureCaps & D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_ALPHA_FILL)) - { - CLog::Log(LOGDEBUG, "%s - Processor supports alfa fill feature.", __FUNCTION__); - //m_pVideoContext->VideoProcessorSetStreamAlpha(m_pVideoProcessor, DEFAULT_STREAM_INDEX, true, 1.0f); - //m_pVideoContext->VideoProcessorSetOutputAlphaFillMode(m_pVideoProcessor, D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_BACKGROUND, DEFAULT_STREAM_INDEX); - } - else - CLog::Log(LOGDEBUG, "%s - Processor doesn't support alfa fill feature.", __FUNCTION__); - - // Output rate (repeat frames) - if (0 != (m_rateCaps.ProcessorCaps & D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION)) - { - CLog::Log(LOGDEBUG, "%s - Processor supports frame rate conversion feature.", __FUNCTION__); - //m_pVideoContext->VideoProcessorSetStreamOutputRate(m_pVideoProcessor, DEFAULT_STREAM_INDEX, D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_NORMAL, TRUE, NULL); - } - else - CLog::Log(LOGDEBUG, "%s - Processor doesn't support frame rate conversion feature.", __FUNCTION__);*/ - return true; } @@ -405,7 +376,7 @@ bool CProcessorHD::CreateSurfaces() for (idx = 0; idx < m_size; idx++) { ID3D11Texture2D* pTexture = nullptr; - hr = pD3DDevice->CreateTexture2D(&texDesc, NULL, &pTexture); + hr = pD3DDevice->CreateTexture2D(&texDesc, nullptr, &pTexture); if (FAILED(hr)) break; @@ -457,21 +428,16 @@ CRenderPicture *CProcessorHD::Convert(DVDVideoPicture &picture) return nullptr; } - ID3D11VideoProcessorInputView* view = reinterpret_cast<ID3D11VideoProcessorInputView*>(pView); - ID3D11Resource* pResource = nullptr; - view->GetResource(&pResource); - - D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC vpivd; - view->GetDesc(&vpivd); - UINT subresource = D3D11CalcSubresource(0, vpivd.Texture2D.ArraySlice, 1); + pView->GetResource(&pResource); D3D11_MAPPED_SUBRESOURCE rectangle; ID3D11DeviceContext* pContext = g_Windowing.GetImmediateContext(); - if (FAILED(pContext->Map(pResource, subresource, D3D11_MAP_WRITE_DISCARD, 0, &rectangle))) + + if (FAILED(pContext->Map(pResource, 0, D3D11_MAP_WRITE_DISCARD, 0, &rectangle))) { CLog::Log(LOGERROR, "%s - could not lock rect", __FUNCTION__); - m_context->ClearReference(view); + m_context->ClearReference(pView); return nullptr; } @@ -489,13 +455,14 @@ CRenderPicture *CProcessorHD::Convert(DVDVideoPicture &picture) convert_yuv420_p01x(picture.data, picture.iLineSize, picture.iHeight, picture.iWidth, dst, dstStride , picture.format == RENDER_FMT_YUV420P10 ? 10 : 16); } - pContext->Unmap(pResource, subresource); + pContext->Unmap(pResource, 0); SAFE_RELEASE(pResource); - m_context->ClearReference(view); - m_context->MarkRender(view); + m_context->ClearReference(pView); + m_context->MarkRender(pView); + CRenderPicture *pic = new CRenderPicture(m_context); - pic->view = view; + pic->view = pView; return pic; } @@ -525,39 +492,37 @@ bool CProcessorHD::ApplyFilter(D3D11_VIDEO_PROCESSOR_FILTER filter, int value, i ID3D11VideoProcessorInputView* CProcessorHD::GetInputView(ID3D11View* view) { ID3D11VideoProcessorInputView* inputView = nullptr; - if (m_context) // we have own context so the view will be processor input view + if (m_eViewType == PROCESSOR_VIEW_TYPE_PROCESSOR) { inputView = reinterpret_cast<ID3D11VideoProcessorInputView*>(view); - inputView->AddRef(); // it will be released in Render method - - return inputView; + inputView->AddRef(); // it will be released later } - - // the view came from decoder - ID3D11VideoDecoderOutputView* decoderView = reinterpret_cast<ID3D11VideoDecoderOutputView*>(view); - if (!decoderView) + else if (m_eViewType == PROCESSOR_VIEW_TYPE_DECODER) { - CLog::Log(LOGERROR, __FUNCTION__" - cannot get view."); - return nullptr; - } + // the view cames from decoder + ID3D11VideoDecoderOutputView* decoderView = reinterpret_cast<ID3D11VideoDecoderOutputView*>(view); + if (!decoderView) + { + CLog::Log(LOGERROR, "%s - cannot get view.", __FUNCTION__); + return nullptr; + } - ID3D11Resource* resource = nullptr; - D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC vdovd; - decoderView->GetDesc(&vdovd); - decoderView->GetResource(&resource); + ID3D11Resource* resource = nullptr; + D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC vdovd; + decoderView->GetDesc(&vdovd); + decoderView->GetResource(&resource); - D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC vpivd = { 0 }; - vpivd.FourCC = 0; // if zero, the driver uses the DXGI format; must be 0 on level 9.x - vpivd.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; - vpivd.Texture2D.ArraySlice = vdovd.Texture2D.ArraySlice; - vpivd.Texture2D.MipSlice = 0; + D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC vpivd = { { 0 } }; + vpivd.FourCC = 0; + vpivd.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; + vpivd.Texture2D.ArraySlice = vdovd.Texture2D.ArraySlice; + vpivd.Texture2D.MipSlice = 0; - if (FAILED(m_pVideoDevice->CreateVideoProcessorInputView(resource, m_pEnumerator, &vpivd, &inputView))) - { - CLog::Log(LOGERROR, __FUNCTION__" - cannot create processor view."); - } - resource->Release(); + if (FAILED(m_pVideoDevice->CreateVideoProcessorInputView(resource, m_pEnumerator, &vpivd, &inputView))) + CLog::Log(LOGERROR, "%s - cannot create processor view.", __FUNCTION__); + resource->Release(); + } return inputView; } @@ -722,14 +687,14 @@ bool CProcessorHD::Render(CRect src, CRect dst, ID3D11Resource* target, ID3D11Vi SAFE_RELEASE(pOutputView); SAFE_RELEASE(stream_data.pInputSurface); - for (unsigned i = 0; i < stream_data.PastFrames; ++i) + for (size_t i = 0; i < stream_data.PastFrames; ++i) SAFE_RELEASE(stream_data.ppPastSurfaces[i]); - for (unsigned i = 0; i < stream_data.FutureFrames; ++i) + for (size_t i = 0; i < stream_data.FutureFrames; ++i) SAFE_RELEASE(stream_data.ppFutureSurfaces[i]); delete[] stream_data.ppPastSurfaces; - delete [] stream_data.ppFutureSurfaces; + delete[] stream_data.ppFutureSurfaces; return !FAILED(hr); } diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h index 52d07e1dd8..daec224ed5 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h @@ -37,69 +37,77 @@ const D3D11_VIDEO_PROCESSOR_FILTER PROCAMP_FILTERS[] = D3D11_VIDEO_PROCESSOR_FILTER_SATURATION }; +enum PROCESSOR_VIEW_TYPE +{ + PROCESSOR_VIEW_TYPE_UNKNOWN = 0, + PROCESSOR_VIEW_TYPE_DECODER = 1, + PROCESSOR_VIEW_TYPE_PROCESSOR = 2 +}; + const DWORD NUM_FILTERS = ARRAYSIZE(PROCAMP_FILTERS); -class CProcessorHD : ID3DResource - //: public CProcessor +class CProcessorHD : public ID3DResource { 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 CRenderPicture *Convert(DVDVideoPicture &picture); - virtual bool Render(CRect src, CRect dst, ID3D11Resource* target, ID3D11View **views, DWORD flags, UINT frameIdx, UINT rotation); - virtual unsigned Size() { if (m_pVideoProcessor) return m_size; return 0; } - virtual unsigned PastRefs() { return m_max_back_refs; } - virtual void ApplySupportedFormats(std::vector<ERenderFormat> * formats); + bool PreInit(); + void UnInit(); + bool Open(UINT width, UINT height, unsigned int flags, unsigned int format, unsigned int extended_format); + void Close(); + CRenderPicture *Convert(DVDVideoPicture &picture); + bool Render(CRect src, CRect dst, ID3D11Resource* target, ID3D11View **views, DWORD flags, UINT frameIdx, UINT rotation); + uint8_t Size() { if (m_pVideoProcessor) return m_size; return 0; } + uint8_t PastRefs() { return m_max_back_refs; } + void ApplySupportedFormats(std::vector<ERenderFormat> * formats); - 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(); } + // ID3DResource overrides + void OnCreateDevice() override {} + void OnDestroyDevice() override { CSingleLock lock(m_section); UnInit(); } + void OnLostDevice() override { CSingleLock lock(m_section); UnInit(); } + void OnResetDevice() override { CSingleLock lock(m_section); Close(); } protected: - virtual bool UpdateSize(const DXVA2_VideoDesc& dsc); - virtual bool ReInit(); - virtual bool InitProcessor(); - virtual bool ConfigureProcessor(unsigned int format, unsigned int extended_format); - virtual bool OpenProcessor(); - virtual bool CreateSurfaces(); - virtual bool ApplyFilter(D3D11_VIDEO_PROCESSOR_FILTER filter, int value, int min, int max, int def); + bool UpdateSize(const DXVA2_VideoDesc& dsc); + bool ReInit(); + bool InitProcessor(); + bool ConfigureProcessor(unsigned int format, unsigned int extended_format); + bool OpenProcessor(); + bool CreateSurfaces(); + bool ApplyFilter(D3D11_VIDEO_PROCESSOR_FILTER filter, int value, int min, int max, int def); ID3D11VideoProcessorInputView* GetInputView(ID3D11View* view); + bool IsFormatSupported(DXGI_FORMAT format, D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT support); - unsigned int m_width; - unsigned int m_height; - unsigned int m_flags; - unsigned int m_renderFormat; - unsigned m_size; - unsigned m_max_back_refs; - unsigned m_max_fwd_refs; + uint32_t m_width; + uint32_t m_height; + uint32_t m_flags; + uint32_t m_renderFormat; + uint8_t m_size; + uint8_t m_max_back_refs; + uint8_t m_max_fwd_refs; struct ProcAmpInfo { - bool bSupported; + bool bSupported; D3D11_VIDEO_PROCESSOR_FILTER_RANGE Range; }; - ProcAmpInfo m_Filters[NUM_FILTERS]; + ProcAmpInfo m_Filters[NUM_FILTERS]; // dx 11 - DXGI_FORMAT m_textureFormat; - ID3D11VideoDevice* m_pVideoDevice; - ID3D11VideoContext* m_pVideoContext; - ID3D11VideoProcessorEnumerator* m_pEnumerator; - D3D11_VIDEO_PROCESSOR_CAPS m_vcaps; - ID3D11VideoProcessor* m_pVideoProcessor; - bool m_bStereoEnabled = false; - CSurfaceContext* m_context; - CCriticalSection m_section; + DXGI_FORMAT m_textureFormat; + ID3D11VideoDevice *m_pVideoDevice; + ID3D11VideoContext *m_pVideoContext; + ID3D11VideoProcessorEnumerator *m_pEnumerator; + D3D11_VIDEO_PROCESSOR_CAPS m_vcaps; + ID3D11VideoProcessor *m_pVideoProcessor; + CSurfaceContext *m_context; + CCriticalSection m_section; - unsigned int m_procIndex; + uint32_t m_procIndex; D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS m_rateCaps; - D3D11_TEXTURE2D_DESC m_texDesc; + D3D11_TEXTURE2D_DESC m_texDesc; + PROCESSOR_VIEW_TYPE m_eViewType; }; }; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp index 0e69b95a28..d221c8aaaa 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp @@ -1234,6 +1234,12 @@ void YUVBuffer::StartRender() if (!m_locked) return; + if (m_bPending) + { + PerformCopy(); + m_bPending = false; + } + m_locked = false; for (unsigned i = 0; i < m_activeplanes; i++) @@ -1251,6 +1257,7 @@ void YUVBuffer::StartDecode() return; m_locked = true; + m_bPending = false; for(unsigned i = 0; i < m_activeplanes; i++) { @@ -1371,7 +1378,7 @@ bool YUVBuffer::CopyFromDXVA(ID3D11VideoDecoderOutputView* pView) resource, D3D11CalcSubresource(0, vpivd.Texture2D.ArraySlice, 1), nullptr); - PerformCopy(); + m_bPending = true; } SAFE_RELEASE(resource); diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h index 21c84b61b6..d4f3984d77 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h @@ -102,19 +102,27 @@ struct SVideoPlane struct YUVBuffer : SVideoBuffer { - YUVBuffer() : m_width(0), m_height(0), m_format(RENDER_FMT_NONE), m_activeplanes(0), m_locked(false), m_staging(nullptr) + YUVBuffer() : m_width(0), m_height(0) + , m_format(RENDER_FMT_NONE) + , m_activeplanes(0) + , m_locked(false) + , m_staging(nullptr) + , m_bPending(false) { memset(&m_sDesc, 0, sizeof(CD3D11_TEXTURE2D_DESC)); } ~YUVBuffer(); bool Create(ERenderFormat format, unsigned int width, unsigned int height, bool dynamic); - virtual void Release(); - virtual void StartDecode(); - virtual void StartRender(); - virtual void Clear(); unsigned int GetActivePlanes() { return m_activeplanes; } - virtual bool IsReadyToRender(); bool CopyFromPicture(DVDVideoPicture &picture); + + // SVideoBuffer overrides + void Release() override; + void StartDecode() override; + void StartRender() override; + void Clear() override; + bool IsReadyToRender() override; + SVideoPlane planes[MAX_PLANES]; private: @@ -129,6 +137,7 @@ private: D3D11_MAP m_mapType; ID3D11Texture2D* m_staging; CD3D11_TEXTURE2D_DESC m_sDesc; + bool m_bPending; }; struct DXVABuffer : SVideoBuffer diff --git a/xbmc/rendering/dx/RenderSystemDX.cpp b/xbmc/rendering/dx/RenderSystemDX.cpp index 12db8c3dde..e22c364c3d 100644 --- a/xbmc/rendering/dx/RenderSystemDX.cpp +++ b/xbmc/rendering/dx/RenderSystemDX.cpp @@ -840,7 +840,7 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources() DXGI_SWAP_CHAIN_DESC1 scDesc1 = { 0 }; scDesc1.Width = m_nBackBufferWidth; scDesc1.Height = m_nBackBufferHeight; - scDesc1.BufferCount = 2 + 3 * bHWStereoEnabled; + scDesc1.BufferCount = 3 * (1 + bHWStereoEnabled); scDesc1.Format = DXGI_FORMAT_B8G8R8A8_UNORM; scDesc1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scDesc1.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; @@ -891,7 +891,7 @@ bool CRenderSystemDX::CreateWindowSizeDependentResources() else { // DirectX 11.0 systems - scDesc.BufferCount = 2; // Use double buffering to minimize latency. + scDesc.BufferCount = 3; scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scDesc.OutputWindow = m_hFocusWnd; scDesc.Windowed = m_useWindowedDX; diff --git a/xbmc/windowing/windows/WinSystemWin32.cpp b/xbmc/windowing/windows/WinSystemWin32.cpp index 8934fb79c4..405cb49c5c 100644 --- a/xbmc/windowing/windows/WinSystemWin32.cpp +++ b/xbmc/windowing/windows/WinSystemWin32.cpp @@ -843,4 +843,46 @@ void CWinSystemWin32::ResolutionChanged() OnDisplayBack(); } +void CWinSystemWin32::SetForegroundWindowInternal(HWND hWnd) +{ + if (!IsWindow(hWnd)) return; + + // if the window isn't focused, bring it to front or SetFullScreen will fail + BYTE keyState[256] = { 0 }; + // to unlock SetForegroundWindow we need to imitate Alt pressing + if (GetKeyboardState((LPBYTE)&keyState) && !(keyState[VK_MENU] & 0x80)) + keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0); + + BOOL res = SetForegroundWindow(hWnd); + + if (GetKeyboardState((LPBYTE)&keyState) && !(keyState[VK_MENU] & 0x80)) + keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); + + if (!res) + { + //relation time of SetForegroundWindow lock + DWORD lockTimeOut = 0; + HWND hCurrWnd = GetForegroundWindow(); + DWORD dwThisTID = GetCurrentThreadId(), + dwCurrTID = GetWindowThreadProcessId(hCurrWnd, 0); + + // we need to bypass some limitations from Microsoft + if (dwThisTID != dwCurrTID) + { + AttachThreadInput(dwThisTID, dwCurrTID, TRUE); + SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &lockTimeOut, 0); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); + AllowSetForegroundWindow(ASFW_ANY); + } + + SetForegroundWindow(hWnd); + + if (dwThisTID != dwCurrTID) + { + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (PVOID)lockTimeOut, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE); + AttachThreadInput(dwThisTID, dwCurrTID, FALSE); + } + } +} + #endif diff --git a/xbmc/windowing/windows/WinSystemWin32.h b/xbmc/windowing/windows/WinSystemWin32.h index 91c609ca0e..59e78f4e03 100644 --- a/xbmc/windowing/windows/WinSystemWin32.h +++ b/xbmc/windowing/windows/WinSystemWin32.h @@ -186,6 +186,7 @@ protected: void OnDisplayReset(); void OnDisplayBack(); void ResolutionChanged(); + void SetForegroundWindowInternal(HWND hWnd); HWND m_hWnd; std::vector<HWND> m_hBlankWindows; diff --git a/xbmc/windowing/windows/WinSystemWin32DX.cpp b/xbmc/windowing/windows/WinSystemWin32DX.cpp index 9950cdb249..0a4d18c6d8 100644 --- a/xbmc/windowing/windows/WinSystemWin32DX.cpp +++ b/xbmc/windowing/windows/WinSystemWin32DX.cpp @@ -50,6 +50,8 @@ void CWinSystemWin32DX::PresentRender(bool rendered) m_delayDispReset = false; CWinSystemWin32::OnDisplayReset(); } + if (!rendered) + Sleep(40); } bool CWinSystemWin32DX::UseWindowedDX(bool fullScreen) @@ -118,18 +120,7 @@ bool CWinSystemWin32DX::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, boo CRenderSystemDX::SetFullScreenInternal(); if (!m_useWindowedDX) - { - // if the window isn't focused, bring it to front or SetFullScreen will fail - BYTE keyState[256] = { 0 }; - // to unlock SetForegroundWindow we need to imitate Alt pressing - if (GetKeyboardState((LPBYTE)&keyState) && !(keyState[VK_MENU] & 0x80)) - keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0); - - BringWindowToTop(m_hWnd); - - if (GetKeyboardState((LPBYTE)&keyState) && !(keyState[VK_MENU] & 0x80)) - keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); - } + SetForegroundWindowInternal(m_hWnd); // most 3D content has 23.976fps, so switch for this mode if (g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_HARDWAREBASED) |