vf_d3d11vpp: fix deinterlacing#17413
Conversation
|
/cc @softworkz Frankly, I didn't go deep into the issues, I just made it so it pases the required amount of reference frames, which mostly resolves the broken deinterlacing. We can work on other fixes if we have good examples when it is not working. |
Hi, thanks a lot for looking into this. It took me a moment to refresh memory, but from a glance it makes sense. But: what this does is to change from one hard-code mode to a different fixed mode and it can be made better with a few simple changes:
This would make the mode param effective (for the first time) and retrain existing behavior, which might be useful for example when a driver/GPU has a problematic/undesired impl. of ADAPTIVE or MOTION_COMPENSATION, then one can still switch back to Bob. sw |
27bc7b0 to
e4ffc4b
Compare
I don't want to remove those, as they doesn't do any harm. IVTC cadence is still detected correctly, we just don't support custom rates to drop duplicated frames. My GPU doesn't support custom rates, so not sure how else we can support that. Without proper feedback from driver, not sure how we could even do manually frame selection. Anyway, it works as best as it can now. Maybe someone will step in and improve that.
It is not really possible to select any mode, unless they were to be exposed as separate video processors. But they are not, at least on my hardware. In which cases we just give the driver frames and it selects "best" strategy. I've added a "force" bob mode, where we don't pass reference frames, this can be used for debugging if anything else, but frankly adding ref frames gives way better results. |
No. You select the mode by the way how you are using it. You switch to blend by setting output rate=input rate (without reference frames) and you select Bob by specifying a double output rate and by not providing reference frames. That's pretty clear. With this PR, you have hardcoded adaptive/mocomp. Which means that the mode parameter is totally useless - it doesn't have any effect. But at the same time, you don't want to remove values (or the mode param entirely)? These two things don't go together. It is confusing everybody, and often enough it has been upsetting me when using software with such "anomalies" which only a handful of people know about and the rest of the world either remains confused/frustrated/whatever, except those who find it out the hard way - and are even more frustrated, then. |
No, it's not possible to select the mode. You can infer whether BOB or BLEND will be used, but the driver can do whatever it wants. It can use BOB even when passing frames. However, the code currently assumes that without frames BOB will always be used, which is implied by docs. It also depends on the hardware. On my Intel system, BLEND (not yet included in the PR) works correctly, but on an AMD system it outputs only one field without blending the other one. (need to test more though, maybe it's fancy and have blending threshold, but I doubt that)
As I said, my hardware doesn't support custom rates, so I won't implement full 60i to 24p conversion. It's actually quite clear how to make it work, but if no vendor supports it, it's completely pointless to implement. IVTC itself works correctly, just with repeated progressive frames.
I didn't hardcode anything. It might have an effect if the driver exposed separate processors or rate converters. In practice, no one implements that, but the point here is that every mode works fine. Hardware implementations can detect the telecine cadence and correctly reconstruct frames, just without the frame-dropping part, so there is duplication. As I said, there is no way to force the mode except by changing the rate itself. I implemented this locally for half-rate, because why not, but not for any custom rate... I would like to see it in action first before committing the code. While playing with this, I found the root cause of some weirdness in behavior in some scenarios. Now everything works exactly as documentation describes. I will commit later remaining changes. I'm kind of surprised that no one before complained about this deinterlacing quality. Sorry it took me so long to get into this topic and thanks for bringing this up. |
That's what I mean: We can force it to do BOB by specify the double output rate and by not supplying reference frames. Then, we can (more or less) safely assume that it will use Adaptive or Mocomp if (1) it supports that and (2) we provide the required reference frames. So, what I'm proposing is simply to:
Doesn't that make sense?
That observation matches the D3D11 processor caps that I'm seeing on my system. I can easily compare because here I have 3 GPUs: Intel integrated, Nvidia RTX and Radeon - all working in parallel (try that on Linux 🤣). Also notable: AMD has separate processors for Interlaced and progressive sources while Intel and Nvidia have a single (combined) one. Intel and AMD want 1 past and 1 future frame and Nvidia wants 2 past and 1 future frame.
I think you are mixing up two things: Framerate ConversionThis is operating on progressive frames and meant to be an upcoming feature where intermediate frames are calculated based on motion interpolation (even for conversion to lower rates, interpolation is needed for smooth motion). => No vendor is supporting this yet (that's what you are referring to) Inverse TelecineThis is working on interlaced fields and it is not about "repeated progressive frames" but it is about removing the "right" fields/frames which have been inserted by telecine conversions (film => TV). => All three vendors are supporting this via their D3D11 processors They are even indicating the exact patterns which they are supporting for that:
This page has a pseudo-code snippet illustrating IVTC from 60i -> 24p (the lower half of the snippet). Of course, I'm not saying you should do this. Obviously this makes only sense when you have a display connected which is running at 24Hz and you want to restore the original "cinematic experience".
I'm very surprised as well, especially since MPV users are typically very picky and critical regarding playback quality. Even more, I'm very glad and thankful that you found the time for taking a look a this. 👍 |
|
In comment #17413 (comment):
|
Sorry, my bad, must have overlooked it. |
|
Regarding the rate conversions, Nvidia driver is just wrong. It says it supports IVTC but then it specifies custom rate conversions (which it indicates not to support:
From the docs, it's very clear:
There is D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS which has a member ITelecineCaps and corresponds to: D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS This capability is indicated by D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_INVERSE_TELECINE and it has a member CustomRateCount which can be used to call GetVideoProcessorCustomRate() This capability is indicated by D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION Nvidia indicates D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_INVERSE_TELECINE and not D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION, even though it returns values for custom rate conversions. Intel and AMD are reporting their IVTC capabilities correctly - with values from the enum D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS , so they are surely able to do this. |
I noticed this too :) |
This was a typo. Although this changes the user option name, this filter, especially this option, is so niche that I fix it without a deprecation period.
|
Some of our users have been asking whether we can implement rate doubling with motion interpolation. One has a very adventurous setup going through vaporsynth and some specialized software (name of which I don't remember), but I said we won't go crazy about it now as it's just a matter of time that GPU vendors will offer it in a way where it can easily be enabled with just a few changes - and that capability (D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION) is at least how MS thinks it should be made available. So let's hope that GPU vendors won't be cooking their own soup - like so often... |
e4ffc4b to
0cf51ac
Compare
|
Updated PR with all changes. Should resolve all issues now.
Like, they already do. See #17148 it's available through AMF only. While it could easily be exposed in d3d11vpp too, especially it's trivial 2x converter. NVIDIA at least support some FRC in d3d11. Might actually look into supporting that at some point. Though I'm not a big fun of rate converters and interpolation to be honest.
AMD is also wrong, because for progressive rate converter, they say FRC is supported, but no custom rates are exposed, so it's not possible to configure any rate, except maybe half rate, but that doesn't work for progressive. |
Awesome!
ITelecineCaps is part of the D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS.
Reversing a 3:2 pulldown from 60i gives you 24p So, why do you think that "custom rates" would be needed for this? Custom is custom (= non-standard) and the D3D11_VIDEO_PROCESSOR_ITELECINE_CAPS_* values are the standard one when dealing with fields.
Nice!
By theory, they might set this capability as supported without specifying custom rates, in case they would support arbitrary rate conversions . the docs are not clear in this regard - unlikely the case though... |
Reversing 3:2 pulldown without rate conversion. You can think about this like when using software ffmpeg filters. fieldmatch filter can match fileds and do the progressive frames reconstruction. While on top of that you have to use decimate filter to drop duplicated frames.
This is pretty clear if you read the docs, the example at the bottom has two cases for performing Inverse Telecine (IVTC) on 3:2 pull-down, 30 frames (60 fields) per second interlaced content. First is From API point of view it would not be possible to support without custom rate and more reference frames, because we actually need to drive the processing at the output rate. NORMAL_RATE means that we drive processing at field rate repeating the same frame twice, HALF_RATE means that we drive at frame rate sending both fields once. This API makes sense. For IVTC we would need to send the same input frame 4 times, and give more reference frame, none of which is exposed by the caps reported by the driver. Therefore it's not supported. Also I understand why it's not supported in practice. Because while normal rate processing can internally do the detection of the cadence and reconstruct frames as it wishes. Rate conversion would need preexisting knowledge for us to know how to configure the filter. Which we don't have because the biggest telecine thing is to detect the cadence in the first place and it can be mixed telecine / interlaced content. Normal rate processing just works, custom rate would be pain to support and likely not used by anyone. EDIT: Well it would be easy to support with output_rate option, manually set by user... |
|
Updated to output half-rate in ivtc mode, as this is likely more expected. Added also example in docs with |
I was under the assumption that an indication for 3:2 IVTC would imply support for the corresponding rate conversion. After more reading, I see that this might be wrong. Have you ever tried to specify D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_CUSTOM and 4/5 as custom rate?
Nice! And yes, that fits better. |
Yes, I have. It fails with invalid parameter error on VideoProcessorBlt. I tried also I initially was under impression that it should be supported, but it really needs custom rate to be exposed. I wonder if it ever was supported on some hardware and got cut down over the years. |
c212cd4 to
3f95e1f
Compare
I bet it was - at least at some point. It's untypical for MS to expose APIs like this which have never been tested or implemented at least by one vendor (which they are typically collaborating with). For DXVAHD, there's even a private stream data struct for IVTC state information: DXVAHD_STREAM_STATE_PRIVATE_IVTC_DATA where they're explicitly describing the scenario:
Perhaps they sensed that it's too rarely used (who switches a desktop to 24Hz for watching a video?). |
|
LGTM - as far as I can tell. Just typos. |
Ah, that would be perfect. This was exactly the thing I would want when implementing IVTC. Else without proper feedback it's just manual guessing the parameters of the video stream, that can be mixed content.
Right, most likely it was used at some places. Actually I wonder why it's not exposed on current hardware. If they (AMD and Intel) already detect the cadence, it would be just detecting which frame to drop, some buffering of frames. Not like there is much silicon needed if any for that.
Yeah, maybe. There was at some point a push for Windows Media Center interface too, where all those things like IVTC would make sense. But I guess watching TV on PC died, or even never really existed. |
a82f3f2 to
043ec5a
Compare
There's a chance that it's working. The replacement for private stream_state data is ID3D11VideoContext::VideoProcessorSetStreamExtension / VideoProcessorGetStreamExtension. This also takes a GUID, so maybe(!) it's available by using the same GUID and the same structure...
Yeah, it's cheap to do...
That was before all those APIs appeared. WMC was DirectShow based and there didn't even exist any 24 Hz displays at that time.
Life after death (little side project): https://www.youtube.com/watch?v=Ykfq9ILPsyM |
|
I think you can remove the word "mostly" from the OP now 😉 |
Not working. Maybe in another universe :) |
cd0f108 to
335b81f
Compare
There were multiple issues in API usage, not setting correct OutputIndex, lying about frame field parity to make it work without OutputIndex. Not passing reference frames which forced BOB mode always. Fix all issues and allow forcing BLEND/BOB mode by not passing frames. Blend mode also sets half rate output. Half rate could be separate option too, but there is not much gain from it except for debugging really. Fixes: mpv-player#15197
The optimal way would be to use custom rate based on telecine cadence, but it's not supported by any driver in practice. So instead, allow driver to field match and output with duplicated frames, which can be removed using decimate filter. Note that in practice all GPU vendors uses single video processor for all deinterlacing, so IVTC will be done even if mode is not explicitly selected. At least the field matching part, because correct rate output is not supported. The main difference is that when selecting more we output at video frame rate, not field rate.
335b81f to
00e7bf4
Compare










This fixes deinterlacing issues in #15197