Aleksoid1978 / VideoRenderer

Внешний видео-рендерер
GNU General Public License v3.0
983 stars 108 forks source link

Green video with Direct3D11 #149

Closed Alhaitham closed 2 months ago

Alhaitham commented 2 months ago

Continued from here https://github.com/clsid2/mpc-hc/issues/2737#issuecomment-2054204275

Sample video

https://files.catbox.moe/faq3h5.avi Or https://mega.nz/file/hVpSDSRT#J2dKoOJCM-xrzTUGkI8Jw1wlALJQWr2sLpyPmSULi2E

With Direct3D11:

Clipboard_04-13-2024_03

Without Direct3D11:

Clipboard_04-13-2024_04

clsid2 commented 2 months ago

Does it work properly if you uncheck YUY2 in the video processor section of MPCVR settings?

Alhaitham commented 2 months ago

Unfortunately not

Aleksoid1978 commented 2 months ago

I can't reproduce - for all is good on D3D11, with VP or Shaders. Checked in MPC-BE and MPC-HC. изображение

Aleksoid1978 commented 2 months ago

And - i don't have old Intel HD Graphics for check/debug.

Aleksoid1978 commented 2 months ago

Old graphic - use Direct3D9.

Alhaitham commented 2 months ago

If there is a way to provide you with debug info, will gladly provide it

If not then you can close it as it is not really a major issue because it only happens with capture videos

clsid2 commented 2 months ago

I am able to reproduce the green issue on a laptop with same Intel GPU. Happens even if VP is fully disabled so shaders are used.

Debug output shows: Feature LEGACY: NO Feature Shader usage: NOT supported

So it does not support shaders when using VP. Perhaps always check for this capability and if unavailable disable the D3D11 option?

Edit: And with VP disabled it shows this: CMpcVideoRenderer::CalcImageSize() buffer size changed from 640x480 to 1280x480 That is wrong? InitializeTexVP() started with input surface; YUY2, 640x480 GetShaderConvertColor() started for YUY2 640x480

With DX9 there is no CalcImageSize() in the log. GetShaderConvertColor() started for YUY2 320x480 Why suddenly use 320? Or is that correct since it is dealing with chroma?

v0lt commented 2 months ago

Intel UHD 750 (i5-11500) has no problems with this video. I remember there were no problems on the old Intel HD 4000 (i5-3570k) either.

Please take a screenshot of the first GPU-Z tab for your graphics adapter.

clsid2 commented 2 months ago

See my post above. There is difference in behavior between DX9 and DX11 when using Shaders. Wrong size used somehow.

v0lt commented 2 months ago

So it does not support shaders when using VP. Perhaps always check for this capability and if unavailable disable the D3D11 option?

In D3D11 mode, D3D_FEATURE_LEVEL_10_0 or later is supported. This is usually enough for MPC VR to work.

Edit: And with VP disabled it shows this: CMpcVideoRenderer::CalcImageSize() buffer size changed from 640x480 to 1280x480 That is wrong?

It depends on what texture format is used.

clsid2 commented 2 months ago

GPU-Z shows DX12 (11_1). So that shouldn't be the issue.

Why does size depend in texture format? That logging line is mediatype related.

Aleksoid1978 commented 2 months ago

Why does size depend in texture format?

For fast copy GPU -> CPU. When destination pitch = source pitch - we have 1 call of memcpy(), see as example https://github.com/Aleksoid1978/VideoRenderer/blob/master/Source/Helper.cpp#L367-L381

Aleksoid1978 commented 2 months ago

Looks like D3D11 supported in driver is buggy.

clsid2 commented 2 months ago

Do you get this log line on your working system? Here it only shows on Intel system. CMpcVideoRenderer::CalcImageSize() buffer size changed from 640x480 to 1280x480

I added log for m_pInputPin->GetConnected()->QueryAccept(&mtNew) failure, and that indeed fails.

clsid2 commented 2 months ago
            if (S_OK == m_pInputPin->GetConnected()->QueryAccept(&mtNew)) {
                DLog(L"CMpcVideoRenderer::SetMediaType() : upstream filter accepted new media type. QueryAccept return S_OK");
                inputPin->SetNewMediaType(mtNew);
            } else {
                DLog(L"CMpcVideoRenderer::SetMediaType() : upstream filter rejected new media type.");
                return VFW_E_UNSUPPORTED_VIDEO;
            }

With this change it will reject connection. Graph builder will insert AVI Decompressor (YUY2) filter, and playback works ok. AVI Decompressor outputs RGB32 to renderer.

clsid2 commented 2 months ago

Now another funny issue. As a test I set AVI Decompressor as a blocked external filter. Now it loads LAV Video Decoder instead to process the YUY2 video between splitter and renderer.

Now buffer size is first changed to 1280x480, and then SetMediaType() gets called again (I think by LAV) with exact same mediatype and that was just renegotiated with upstream filter. This is causing another buffer change to 2560x480. And original bug is back. That second buffer change seems wrong. SetMediaType() needs to check if mediatype differs from the currently set one? I tested a small hack to prevent the second change, but it is still buggy. So possible that YUY2 is simply buggy with DX11 on this GPU.

00000065    2.94851160  [2752] mpcvideorenderer64.ax(tid 28e8)   606855 : Direct3D11 initialization successfully!   
00000066    2.94966364  [2752] mpcvideorenderer64.ax(tid 28e8)   606855 : CDX11VideoProcessor::Init()   
00000067    2.95014262  [2752] mpcvideorenderer64.ax(tid 28e8)   606855 : CDX11VideoProcessor::InitSwapChain() - window     
00000068    2.95021129  [2752] mpcvideorenderer64.ax(tid 28e8)   606855 : CDX11VideoProcessor::InitSwapChain() : Invalid window size 0x0, use 8x8   
00000069    2.95072556  [2752] mpcvideorenderer64.ax(tid 28e8)   606855 : CVideoRendererInputPin::ReceiveConnection()   
00000070    2.95088124  [2752] mpcvideorenderer64.ax(tid 28e8)   606855 : CMpcVideoRenderer::SetMediaType() 
00000071    2.95088124  [2752] MajorType : Video    
00000072    2.95088124  [2752] SubType   : YUY2 
00000073    2.95088124  [2752] FormatType: VideoInfo2   
00000074    2.95088124  [2752] BimapSize : 640 x 480    
00000075    2.95088124  [2752] SourceRect: (0, 0, 640, 480) 
00000076    2.95088124  [2752] SizeImage : 614400 bytes     
00000077    2.95180845  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CMpcVideoRenderer::CalcImageSize() buffer size changed from 640x480 to 1280x480   
00000078    2.95189404  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CMpcVideoRenderer::SetMediaType() : upstream filter accepted new media type. QueryAccept return S_OK  
00000079    2.95197511  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CVideoRendererInputPin::SetNewMediaType()     
00000080    2.95200515  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CDX11VideoProcessor::InitMediaType()  
00000081    2.95208812  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CDX11VideoProcessor::ReleaseVP()  
00000082    2.95457292  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CDX11VideoProcessor::InitializeTexVP() started with input surface: YUY2, 640 x 480    
00000083    2.95463181  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : GetShaderConvertColor() started for YUY2 640x480 extfmt:0x288d2000 chroma:1   
00000084    2.95490766  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : ConvertColorShader: frame consists of 1 planes    
00000085    2.95500326  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : ConvertColorShader: chroma location - YUV 4:2:2   
00000086    2.96224713  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CDX11VideoProcessor::InitializeTexVP() completed successfully     
00000087    2.96274209  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CVideoRendererInputPin::GetAllocator()    
00000088    2.96284151  [2752] mpcvideorenderer64.ax(tid 28e8)   606871 : CCustomAllocator::SetNewMediaType()   
00000089    3.74077439  [2752] mpcvideorenderer64.ax(tid 3364)   607605 : CDX11VideoProcessor::ClearPostScaleShaders().     
00000090    3.77005196  [2752] mpcvideorenderer64.ax(tid 3364)   607688 : CMpcVideoRenderer::Pause()    
00000091    3.77066755  [2752] mpcvideorenderer64.ax(tid 2dd0)   607689 : CMpcVideoRenderer::NewSegment()   
00000092    3.77468038  [2752] mpcvideorenderer64.ax(tid 24d4)   607691 : CCustomAllocator::GetBuffer() : Set new media type for MediaSample    
00000093    3.77468038  [2752] MajorType : Video    
00000094    3.77468038  [2752] SubType   : YUY2 
00000095    3.77468038  [2752] FormatType: VideoInfo2   
00000096    3.77468038  [2752] BimapSize : 1280 x 480   
00000097    3.77468038  [2752] SourceRect: (0, 0, 640, 480) 
00000098    3.77468038  [2752] SizeImage : 1228800 bytes    
00000099    3.77609324  [2752] mpcvideorenderer64.ax(tid 24d4)   607694 : CMpcVideoRenderer::SetMediaType() 
00000100    3.77609324  [2752] MajorType : Video    
00000101    3.77609324  [2752] SubType   : YUY2 
00000102    3.77609324  [2752] FormatType: VideoInfo2   
00000103    3.77609324  [2752] BimapSize : 1280 x 480   
00000104    3.77609324  [2752] SourceRect: (0, 0, 640, 480) 
00000105    3.77609324  [2752] SizeImage : 1228800 bytes    
00000106    3.78042793  [2752] mpcvideorenderer64.ax(tid 24d4)   607699 : CMpcVideoRenderer::CalcImageSize() buffer size changed from 1280x480 to 2560x480  
00000107    3.78051710  [2752] mpcvideorenderer64.ax(tid 24d4)   607699 : CMpcVideoRenderer::SetMediaType() : upstream filter accepted new media type. QueryAccept return S_OK  
00000108    3.78064251  [2752] mpcvideorenderer64.ax(tid 24d4)   607699 : CVideoRendererInputPin::SetNewMediaType()     
00000109    3.78079247  [2752] mpcvideorenderer64.ax(tid 24d4)   607699 : CCustomAllocator::SetNewMediaType()   
00000110    3.78089070  [2752] mpcvideorenderer64.ax(tid 24d4)   607699 : CDX11VideoProcessor::InitMediaType()  
00000111    3.78107595  [2752] mpcvideorenderer64.ax(tid 24d4)   607700 : CDX11VideoProcessor::ReleaseVP()  
00000112    3.78526711  [2752] mpcvideorenderer64.ax(tid 24d4)   607701 : CDX11VideoProcessor::InitializeTexVP() started with input surface: YUY2, 640 x 480    
00000113    3.78570318  [2752] mpcvideorenderer64.ax(tid 24d4)   607701 : GetShaderConvertColor() started for YUY2 640x480 extfmt:0x288d2000 chroma:1   
00000114    3.78588486  [2752] mpcvideorenderer64.ax(tid 24d4)   607704 : ConvertColorShader: frame consists of 1 planes    
00000115    3.78964520  [2752] mpcvideorenderer64.ax(tid 24d4)   607704 : ConvertColorShader: chroma location - YUV 4:2:2   
00000116    4.13335371  [2752] mpcvideorenderer64.ax(tid 24d4)   607719 : CDX11VideoProcessor::InitializeTexVP() completed successfully     
00000117    4.13351774  [2752] mpcvideorenderer64.ax(tid 9f4)   607722 : CMpcVideoRenderer::Run()   
00000118    4.13882399  [2752] mpcvideorenderer64.ax(tid 24d4)   608057 : CCustomAllocator::GetBuffer() : Set new media type for MediaSample    
00000119    4.13882399  [2752] MajorType : Video    
00000120    4.13882399  [2752] SubType   : YUY2 
00000121    4.13882399  [2752] FormatType: VideoInfo2   
00000122    4.13882399  [2752] BimapSize : 2560 x 480   
00000123    4.13882399  [2752] SourceRect: (0, 0, 640, 480) 
00000124    4.13882399  [2752] SizeImage : 2457600 bytes 
Aleksoid1978 commented 2 months ago

It's very strange, for 640 alignment size is 1280, but for 1280 - alignment size is 2560. Check in debugger CDX11VideoProcessor::GetAlignmentSize() - there a D3D11 texture of the specified size is created and RowPitch is taken.

Aleksoid1978 commented 2 months ago

m_pInputPin->GetConnected()->QueryAccept(&mtNew)

If m_pInputPin->GetConnected()->QueryAccept(&mtNew) does not work, it’s okay, it means the higher-level filter did not accept the new media type and we will continue to work with the current one, there is no need to add anything here.

Aleksoid1978 commented 2 months ago

Let's do it this way - the issue is closed, the developers don't have such old Intel. Therefore, we stop writing here - if someone can find the reason, fix it, etc. - either a patch or a pull request. The end :)

v0lt commented 2 months ago

If there is a way to provide you with debug info, will gladly provide it

https://github.com/Aleksoid1978/VideoRenderer/releases There you can find the Debug version. Use DebugView to view the debug log.

Alhaitham commented 2 months ago

mpc-hc64_capture_2024-04-13_14-33-40.LOG