Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 5th January 2021, 05:52   #1  |  Link
bruno321
Registered User
 
Join Date: Oct 2018
Posts: 133
Decimating a variable framerate file

I have a VFR progressive mkv which has dupe frames in the form of 1-out-of-5. I loaded the file normally into with LWLibavVideoSource, did Tdecimate(0,1,5), this produces a new file, which I need to make VFR as well to keep the synch with the audio. I extracted the timestamps file from the original with mkvextract. However, I can't merely mux this file with the new video as now the frame numbers don't match.

How do I go about this? Is there perhaps a way to "decimate the timecodes file"?

EDIT: I should add that my script for the file is long, involving lots of trimming... So I'm wishing for a solution that wouldn't need to have me adjust all those lines manually. Let me be clear: I was loading the file with LWLibAvVideoSource, which avspmod reports as 30.303fps, then I have some trimming and editing there.

P.S. ideally, if this could somehow be converted to a CFR file, all the better. Am now looking into VFRtoCFR...

EDIT2: Looks like loading the file with ffvideosource + its timecodes option, then using VFRtoCFR, then my script would be fine since the frame numbers are luckily unchanged. I'm encoding it, hopefully everything will be all right. The question about whether it's possible to decimate the timecodes file still stands, though it may just be academic if I actually managed to solve this...

Last edited by bruno321; 5th January 2021 at 06:51.
bruno321 is offline   Reply With Quote
Old 5th January 2021, 08:45   #2  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,823
Isn't sing VFRtoCFR pretty much the same as converting to a constant frame rate with ffms2 or LSmash. ie

LWLibavVideoSource("some.mkv", FPSNum=30000, FPSDen=1001)
Or
FFVideoSource("some.mkv", FPSNum=30000, FPSDen=1001)

They both add or drop frames as required to produce a constant frame rate, as VFRtoCFR does, so I'm not sure how the frame numbers wouldn't change, whichever way you do it.
hello_hello is offline   Reply With Quote
Old 5th January 2021, 09:19   #3  |  Link
bruno321
Registered User
 
Join Date: Oct 2018
Posts: 133
I don't really know what VFRtoCFR does. In the manual http://avisynth.nl/index.php/VFRtoCFR the example given reads:

Code:
FFVideoSource("myclip.mp4", timecodes="timecodes.txt")
VFRtoCFR(times="timecodes.txt", numfps=24000, denfps=1001)
In my case, already the first line loads the file with a reasonable framerate (30.000fps), and adding the second one doesn't do anything immediately noticeable in avspmod.

A subsidiary question is: would loading the clip like FFVideoSource("myclip.mkv", FPSNum=30000,fpsden=1000) be the same? In avspmod both seem to have the same behavior. By looking at https://forum.doom9.org/showthread.php?t=165045 it seems the author of VFRtoCFR was addressing some problems that this usage of ffvideosource was giving.


I guess I don't really understand how the "timecodes" option or the framerate forcing option for ffvideosource really work.

Last edited by bruno321; 5th January 2021 at 09:23.
bruno321 is offline   Reply With Quote
Old 5th January 2021, 09:54   #4  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 3,997
Quote:
Originally Posted by bruno321 View Post
.... ideally, if this could somehow be converted to a CFR file, all the better. Am now looking into VFRtoCFR...
You may also want to have a look here:
https://github.com/nu774/mp4fpsmod
Sharc is offline   Reply With Quote
Old 5th January 2021, 11:05   #5  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,823
Quote:
Originally Posted by bruno321 View Post
I don't really know what VFRtoCFR does. In the manual http://avisynth.nl/index.php/VFRtoCFR the example given reads:

Code:
FFVideoSource("myclip.mp4", timecodes="timecodes.txt")
VFRtoCFR(times="timecodes.txt", numfps=24000, denfps=1001)
In my case, already the first line loads the file with a reasonable framerate (30.000fps), and adding the second one doesn't do anything immediately noticeable in avspmod.

A subsidiary question is: would loading the clip like FFVideoSource("myclip.mkv", FPSNum=30000,fpsden=1000) be the same? In avspmod both seem to have the same behavior. By looking at https://forum.doom9.org/showthread.php?t=165045 it seems the author of VFRtoCFR was addressing some problems that this usage of ffvideosource was giving.


I guess I don't really understand how the "timecodes" option or the framerate forcing option for ffvideosource really work.
I don't know what Avspmod tells you, so below is a function for displaying the relevant info (frame rate, frame count and duration). It's nothing you can't discover using Avisynth's Info(), but it's maybe more user friendly for just that specific info.

For a VFR source, FFMS2 or Lsmash both decode at the average frame rate without frame rate conversion. When you specify a frame rate for frame rate conversion, they add or drop frames as required. Where the original frame rate is lower than the specified frame rate, frames will be added. Where it's greater, they'll be dropped. VFRtoCFR converts to a constant frame rate the same way, but I think it can make different choices regarding which frames to duplicate or drop (whether it duplicates the previous frame or the next frame etc).

So when converting VFR to CFR, the total frame count will almost always change, but the duration should remain the same (give or take a few milliseconds).
Because the total frame count changes, it's likely the original frame numbers won't be in their original positions, time-wise. Hopefully that makes sense.

If need be, add VideoInfo() to the script and see what happens to the frame count with and without VFR to CFR conversion.
You can also use this function to see where a particular frame number is located, time-wise, before and after frame rate conversion. It requires GRunT.

If you're using VFRtoCFR you could do something like this for before and after frame numbers:

Frame(y=50)
VFRtoCFR()
Position()

Edit: Updated the function.

Code:
# VideoInfo displays the frame rate, total frame count and duration of a clip.

function VideoInfo(clip V, float "Size", val "Color", float "X", float "Y")   {

VWidth = width(V)
VHeight = height(V)
Size = default(Size, 1.0) * min(VWidth * 0.045, VHeight * 0.0452)
Color = default(Color, $FFFFE0)
X = default(X, VWidth * 0.5)
Y = default(Y, (VHeight * 0.5) - (Size * 1.1))

FNum = FrameRateNumerator(V)
FDen = FrameRateDenominator(V)
FRate = string(float(FNum) / float(FDen), "Frame Rate\n%.4f fps") + \
string(FNum, "  (%.0f/") + string(FDen, "%.0f)\n")
FC = FrameCount(V)
FCount = string(FC, "Frame Count  %.0f")
Duration = float(FC) * float(FDen) / float(FNum)
Decimal = Duration - floor(Duration)
RoundDown = (round(Decimal * 1000.0) == 1000)
Down = floor(Decimal * 1000.0)
Either = round(Decimal * 1000.0)
HH = string(floor(Duration / 3600), "\nDuration  %02.0f")
MM = string(floor(Duration / 60) % 60, ":%02.0f")
SS = string(floor(Duration) % 60, ":%02.0f")
MS = string(RoundDown ? Down : Either, ".%03.0f")

SubText = FRate + FCount + HH + MM + SS + MS

return V.subtitle(SubText, x=X, y=Y, size=Size, align=2, text_color=Color, lsp=20)   }

Last edited by hello_hello; 6th January 2021 at 05:41.
hello_hello is offline   Reply With Quote
Old 5th January 2021, 13:06   #6  |  Link
bruno321
Registered User
 
Join Date: Oct 2018
Posts: 133
Trying to wrap my head around all the above, but something more is confusing me:

1- If I load the file with lwlibavvideosource("file.mkv"), then avspmod reports 30.303fps and 181080 frames.

2- If I load the file with ffvideosource("file.mkv"), then avspmod reports 30.000fps and same number of frames, but a given frame doesn't show in the same timecode as with 1-.

3- lwlibavvideosource("file.mkv",fpsnum=30000,fpsden=1000) gives the same as 2-.

I suspect that what's happening is that ffvideosource detects that it's a VFR file and automatically reads the timecodes file muxed in it, but lwlibavvideosource doesn't?

FWIW mediainfo reports:

Code:
Frame rate mode                          : VFR
Frame rate mode                          : Variable
Frame rate                               : 30.000
Frame rate                               : 30.000 FPS
Frame count                              : 181080

Last edited by bruno321; 5th January 2021 at 13:16.
bruno321 is offline   Reply With Quote
Old 6th January 2021, 05:35   #7  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,823
I'm always suspicious when MediaInfo reports two frame rates, because I think it means the video stream and the container have different frame rates written to them, at least for CFR video.

Maybe try extracting the video stream and the video timecodes with gMKVExtractGUI and remuxing the video stream with MKVToolNix while adding the timecodes file to see what happens when you index the new MKV, although that's just a shot in the dark.

None of what follows will be likely to help you. It's just me playing around.

I'm not sure how either ffms2 or lsmash calculate the average frame rate. I extracted the timecodes from a VFR MKV, and also used ffms2 to write them, and both timecode files showed the last timecode as 1358899, although when extracting with gMKVExtractGUI, the last timecode was repeated for an extra frame, which I don't understand...

1358816
1358857
1358899
1358899

But that aside, both ffms2 and lsmash decoded the video with 33201 frames. My logic for working out the average frame rate would be to ignore the duration of the last frame, as it could be anything, and base the calculation on 33200 frames. So...
33200 / 1358.899 = 24.431543

ffms2 decoded at 24.431957 fps, and for lsmash (the old version I use on XP) it was 24.431568.
If you base the calculations on the duration for each, they both appear to outputting the correct frame rate, but lsmash put the last frame right on the last timecode, whereas for some reason ffms2 didn't. I'm not sure why they work the way they do. I just found it interesting (or maybe odd).

Info()
VideoInfo()
Position(y=350)

ffms2


lsmash

Last edited by hello_hello; 6th January 2021 at 05:44.
hello_hello is offline   Reply With Quote
Old 6th January 2021, 06:19   #8  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,823
By the way, while I was playing around I found a section of the video where each successive frame is unique (it's easy to tell as there's strobing). The video was encoded as VFR from the DVD with the help of the TIVTC plugin, so the section in question should be either 23.976fps or 29.97fps.

When I converted to a 30000/1001 CFR with the old version of lsmash, many of the unique frames were dropped and replaced with copies of neighbouring frames. The same thing happened using this version of VFRToCFR.

When I converted the frame rate with either ffms2 or this version of VFRToCFR, I'm pretty sure no unique frames went missing.

Last edited by hello_hello; 6th January 2021 at 06:24.
hello_hello is offline   Reply With Quote
Reply

Tags
vfr

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 21:34.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.