I just submitted a patch to enable deinterlacing on Windows with DXVA accelerated decoding. NOTE: VC-1 deinterlacing is not possible due to lack of interlaced VC-1 support in ffmpeg. It supports standard DXVA2 bob and advanced (HQ) deinterlace video processors. To keep the GUI lean, only four new options are added to deinterlace options with DXVA decoding: "Bob", "Best available" and their bottom field first counterparts marked with "(inverted)". If the best deinterlacer offered by the card is bob, bob will be used for "Best available" option as well.
Bob should work everywhere because it is required by DXVA specification. The "Best available" option evaluates all available DXVA processor devices available for the video format and looks for the processor offered with the "best" deinterlacing algorithm by the video driver. HQ deinterlacer preference is:
- Vector adaptive (Ati)
- Motion adaptive (Ati)
- Adaptive (Ati)
- Spatial-temporal (nVidia)
- Edge directed (?) (Intel)
If the hardware does not report a known processor GUID which is better than standard Bob, processors will be ranked according to the reported deinterlacing technology and the number of reference samples required (the higher the better).
Automatic selection of deinterlace method based on stream properties is supported. Automatic deinterlacing uses internally the "Best available" option, but this can be constrained to bob using advancedsettings.xml if the video hardware is not capable of doing advanced deinterlacing above a certain resolution/framerate (see below).
As of v5, it is not possible to switch hardware deinterlace processors without reinitializing the entire decoder chain (quick switch) so switching between deinterlace methods should be very smooth now. If quick switch fails for some reason, the old codec reset method will be used. Quick switch can also be forced disabled in advancedsettings.xml if you are experiencing any troubles with it.
The following advancedsettings are supported (here with default values). Neither of them is mandatory, the patch works without advancedsettings straight out of the box.
<enablequickswitch>: Set to false to force disable quick switch and to revert old (pre-v5) behavior.
<automaxhq*>: Set these to force Bob deinterlace for automatic deinterlace method if your hardware has problems with HQ deinterlacing above certain resolutions/framerates. Bob will be used if the source material is greater either horizontally or vertically than the width and height specified AND the decoded framerate (ie. after deinterlacing) exceeds the maximum specified.
Example 1: Force Bob above 720i:
Example 2: HQ works fine for 1080i50, but struggles with 1080i60:
Example 2: Force Bob for all resolutions above 50 fps:
How does it work?
There are four new deinterlace methods: VS_INTERLACEMETHOD_DXVA_BOB, VS_INTERLACEMETHOD_DXVA_BOB_INVERTED, VS_INTERLACEMETHOD_DXVA_HQ and VS_INTERLACEMETHOD_DXVA_HQ_INVERTED. CWinRenderer::Supports() now reports true for the four new DXVA deinterlace methods as well as VS_INTERLACEMETHOD_AUTO if DXVA hardware decoding is used.
CProcessor::Render() evaluates whether the selected deinterlace method has changed or if the stream interlace format changed and deinterlace method is set to automatic. In these cases, CProcessor::SelectProcessor() is called to perform quick switch of processors. This method has also got a new parameter which is 1 if the source is interlaced and the bottom field has to be rendered and 0 in all other cases. Per DXVA2 specification the deinterlaced material has 2x frame rate as the original source. This parameter is used to display the "extra" frames. CWinRenderer::RenderProcessor() has been updated to provide the extra parameter.
CProcessor::Open() has been refactored and most of the init code has been moved to CProcessor::FindProcessors() and CProcessor::SelectProcessor().
CProcessor::FindProcessors() performs a lookup on supported hardware video processors and will store GUIDs of progressive, bob and high quality deinterlace processors. This runs only once when the processor is open. The largest number of references required by processors will be stored in m_size variable so the required reference samples are available for all processors during a mid-stream change.
CProcessor::SelectProcessor() is responsible to select and initialize the DXVA video processor depending on deinterlace method. If deinterlace method is set to automatic, the processor is selected based on the stream's interlaced type. When quick switch is disabled, m_size will be set to the amount of required reference samples of the selected processor. This decreases the number of textures allocated for progressive and bob-deinterlaced material for Ati (also maybe for others as well).
CProcessor::SetStreamSampleFormat() is used to tell the processor the stream format (DXVA2_Sample* enums). This method is called by CWinRenderer::AddProcessor(). CWinRenderer::AddProcessor() has now an additional parameter which contains the iFlags member of the CDVDVideoPicture struct to find out the stream's interlace format. CDVDVideoPlayer::ProcessOverlays() provides this information.
CProcessor::GetStreamSampleFormat() is used to query the current stream interlaced format. CProcessor::IsInitied() returns false if the processor was unable to perform quick switch and the processor failed to initialize.
CDecoder::Check() will call CProcessor::IsInited(). If it returns false then quick switch failed and a codec reset has to be performed. CProcessor::GetStreamSampleFormat() is then called and the result is stored so the decoder will be initialized with the proper SampleFormat (for automatic deinterlace method) when the codec is reinitialized.
CDecoder::OpenTarget() has been updated to prefer NV12 output, because usually it supports better quality hardware deinterlacers.
CXBMCRenderManager::Present() has been updated to call PresentBob() when any of the DXVA deinterlace options are selected, or deinterlace is automatic and source is interlaced. You can see in player statistics, that framerate is doubled with DXVA deinterlace options.