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. |
5th January 2021, 05:52 | #1 | Link |
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. |
5th January 2021, 08:45 | #2 | Link |
Registered User
Join Date: Mar 2011
Posts: 4,829
|
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. |
5th January 2021, 09:19 | #3 | Link |
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) 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. |
5th January 2021, 09:54 | #4 | Link | |
Registered User
Join Date: May 2006
Posts: 3,997
|
Quote:
https://github.com/nu774/mp4fpsmod |
|
5th January 2021, 11:05 | #5 | Link | |
Registered User
Join Date: Mar 2011
Posts: 4,829
|
Quote:
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. |
|
5th January 2021, 13:06 | #6 | Link |
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. |
6th January 2021, 05:35 | #7 | Link |
Registered User
Join Date: Mar 2011
Posts: 4,829
|
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. |
6th January 2021, 06:19 | #8 | Link |
Registered User
Join Date: Mar 2011
Posts: 4,829
|
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. |
Tags |
vfr |
|
|