vapoursynth / bestsource

A super great audio/video source and FFmpeg wrapper
MIT License
67 stars 15 forks source link

Field order and Framebased set incorrectly #47

Closed flossy83 closed 5 months ago

flossy83 commented 5 months ago

As reported here there appears to be an issue with BSVideoSource setting the Avisynth clip properties:

  1. Field order of the clip (result of clip.GetParity)
  2. Whether the clip is field based (result of clip.isFieldBased)

To be clear these are in relation to clip properties not frame properties.

Thanks

myrsloik commented 5 months ago

I've changed #2 because that one is obvious. However let me point out that other source filters don't have a static value for GetParity (I mean what's the point of taking frame number as an argument if it has to be static?).

For example this code here definitely isn't constant: https://github.com/HomeOfAviSynthPlusEvolution/L-SMASH-Works/blob/master/AviSynth/lwlibav_source.cpp#L249

What you consider clip level GetParity() simply expands to GetParity(0). That value should be reliable.

I know there are bad clips with field order reversals out there so it can definitely change. Get me a sample of the problem clip and maybe I can figure out why it displeases you.

flossy83 commented 5 months ago

Ok thanks, in that case I can workaround it with:

if (GetParity(0)){ AssumeTFF() }
else { AssumeBFF() }

As long as you are aware that without the above workaround it may create problems downstream compared to the other source filters - here's an example showing how it affects Bob()

file = https://drive.google.com/uc?export=download&id=1xz_WEX36iv8tpC18zR8e8-etGwtqfuVb

top_left = BSVideoSource(file, rff=true)
\ .Text("BSVideoSource\n_____________", align=5, lsp=0, size=30).Bob().info().Prefetch(1)

top_right = LWLibavVideoSource(file, repeat=true)
\ .Text("LWLibavVideoSource\n__________________", align=5, lsp=0, size=30).Bob().info().Prefetch(1)

bottom_left = FFVideoSource(file, rffmode=1)
\ .Text("FFVideoSource\n_____________", align=5, lsp=0, size=30).Bob().info().Prefetch(1)

bottom_right = DGSource(file, fieldop=0)
\.Text("DGSource\n________", align=5, lsp=0, size=30).Bob().info().Prefetch(1)
# latest version of DGSource accepts file as 1st arg and will auto-index to .dgi

StackVertical(
\ StackHorizontal(top_left, top_right),
\ StackHorizontal(bottom_left, bottom_right))

The bobbed output is different with BS due to Bob obeying Avisynth internal field order which BS is setting differently per frame

debug avs_snapshot_00 04 938

Rendered to x264 @ 60fps with ffmpeg.exe: https://drive.google.com/uc?export=download&id=14ohEANdh2S1czhuEnvbmgx01K8zJfI2N

Other filters like BWDIF and TIVTC look at the Avisynth internal field order when making decisions about what field to weave/match with so those can potentially be affected too (iirc they preference the frame prop over the Avisynth internal order). NNEDI3 currently only uses parity of frame 0 - I was already working around this by getting the parity of the frame half way through the clip to avoid any field order corruption in frame 0 which can occur due to file splicing with eg. ffmpeg.exe or .ts files from my PVR.

myrsloik commented 5 months ago

Definitely different output but bobbing telecined material is in itself the definition of insanity. So closing this.