View Full Version : Help needed with VFR Framerate Conversion?
aegisofrime
28th September 2015, 11:11
Hi all. I have been stumped at trying to re-encode a certain MP4 file.
Here's the MediaInfo for it:
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main@L4
Format settings, CABAC : Yes
Format settings, ReFrames : 1 frame
Format settings, GOP : M=1, N=60
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 2h 10mn
Bit rate : 5 779 Kbps
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Variable
Frame rate : 29.102 fps
Original frame rate : 29.970 fps
Minimum frame rate : 9.990 fps
Maximum frame rate : 30.000 fps
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.096
Stream size : 5.25 GiB (97%)
Language : English
Encoded date : UTC 2015-08-19 01:48:20
Tagged date : UTC 2015-08-19 01:48:20
I would like to apply Interframe (a frame double) and encode it in 59.94FPS. If I do this, regardless of the source filter the audio is always out of sync with the video.
So I Googled and the Avisynth Wiki suggested using mp4fpsmod to extract the timecode and mux it with the resulting file.
So, I went ahead and used MKVMerge to mux the MP4, along with the timecode, and the resultant mkv file plays in sync.
However, if I were to do my 60fps encoding, MKVMerge throws up an error when I try to mux the timecode file with the resulting 60fps mkv, complaining that the amount of frames in the timecode is lesser than the file.
What would be the proper way to handle this? I hope that I'm making sense here, I know it's a complex issue. Thanks in advance :D
tl;dr Trying to convert VFR file to 60fps-ish. Result has video/audio sync problems.
Edit: I have tried using DirectShowSource in conjunction with convertfps=true and this does not work as well.
Overdrive80
28th September 2015, 11:21
Invoke video with:
LSMASHVideoSource("xxxx.mp4").assumefps(30000,1001.0)
#Now interframe
aegisofrime
30th September 2015, 14:43
Invoke video with:
LSMASHVideoSource("xxxx.mp4").assumefps(30000,1001.0)
#Now interframe
Thanks Overdrive. I have given your suggestion a go and unfortunately the result is still out of sync. I noticed that the length for the audio track as read by L-Smash is 02:09:58; the video length is 02:06:14. Without the AssumeFPS part the length is 02:10:00.
Is there anything else I can try? :(
sneaker_ger
30th September 2015, 15:12
a=LSMASHAudioSource("xxxx.mp4", av_sync=true)
v=LSMASHVideoSource("xxxx.mp4", fpsnum=30000, fpsden=1001)
AudioDub(v, a)
If it is still out of sync add DelayAudio() (http://avisynth.nl/index.php/DelayAudio) and try different values until it's in sync. Then after that add all the interframe stuff you want to use.
Motenai Yoda
30th September 2015, 15:14
You have to open it with
DirectShowSource("F:\Hybrid\vfr.mkv", fps=29.97, convertfps=true)
#interframe
(in case dds2("F:\Hybrid\vfr.mkv", fps=29.97) will work too)
or extract the timecode from mp4 and use some tool to convert the vfr script or avi to a cfr one like tc2cfr
otherwise use normal lsmash/ffmpeg/dss2 source filter, interframe it and use the extracted timecode when encoding or muxing, but I don't know if there is a tool to easely edit timecodecs for a different framerate.
aegisofrime
30th September 2015, 15:51
a=LSMASHAudioSource("xxxx.mp4", av_sync=true)
v=LSMASHVideoSource("xxxx.mp4", fpsnum=30000, fpsden=1001)
AudioDub(v, a)
If it is still out of sync add DelayAudio() (http://avisynth.nl/index.php/DelayAudio) and try different values until it's in sync. Then after that add all the interframe stuff you want to use.
Interesting about the av_sync flag, I was scouring the L-Smash docs but missed it. Will give this a go!
You have to open it with
DirectShowSource("F:\Hybrid\vfr.mkv", fps=29.97, convertfps=true)
#interframe
(in case dds2("F:\Hybrid\vfr.mkv", fps=29.97) will work too)
or extract the timecode from mp4 and use some tool to convert the vfr script or avi to a cfr one like tc2cfr
otherwise use normal lsmash/ffmpeg/dss2 source filter, interframe it and use the extracted timecode when encoding or muxing, but I don't know if there is a tool to easely edit timecodecs for a different framerate.
Yeah, I have the timecode extracted by mp4fpsmod which if I muxed back would actually enable the resultant MKV to be played in sync (If I just muxed the mp4 to mkv it would be out of sync). However I too have no idea how to change the timecode for a different framerate.
Thanks guys will give your suggestions a go as soon as my current encode finishes. ;)
sneaker_ger
30th September 2015, 15:55
Demuxing vfr timecodes and remuxing them later is trivial if you don't touch frame count/timings (sharpening, resizing, denoising etc.), doing things like interframe is a completely different beast.
Music Fan
30th September 2015, 20:38
Another possibility that may work : open your video in Virtual Dub with the ffmpeg plugin, convert in lossless (Lagarith for example), open this video (that should have a 29.97 CFR and be played in sync) with Avisynth and use Interframe.
Virtual Dub with the ffmpeg plugin was the only method that worked with a VFR h264 video I had to convert in CFR.
https://fr.osdn.jp/projects/sfnet_virtualdubffmpeginputplugin/
In Virtual Dub, go in File, open video file, files of type, choose FFMpeg supported files, select your video and open it.
The problem being that a 2h10mn 1080p video in Lagarith will be huge.
colours
1st October 2015, 05:40
Motenai Yoda's post is, thus far, the only reply in this thread that actually makes sense. If you want to stick to AviSynth processing, you should convert to CFR first (because there's no concept of VFR within AviSynth) and then do motion interpolation. (Note: "convert", not just "assume as CFR".) Using one of those duplicate frame removing thingamajigs will probably improve results further.
This is not a perfect solution, but it's certainly an easy one. If you want the frame timings to be handled 100% properly, one way to do this is to write a script to parse the extracted timecodes, calculate the interpolation position for every frame, then dump this out in the form of an AviSynth script.
Alternatively, you could run InterFrame as usual, and modify the timecodes so that you insert a new timecode between every two old timecodes by averaging them, then mux the result with these new timecodes. This is probably a bit easier than the above suggestion.
Music Fan
1st October 2015, 08:25
Motenai Yoda's post is, thus far, the only reply in this thread that actually makes sense
To you.
Mine makes sense too and works (maybe not with all videos but no solution works every time), the problem being the size of the intermediate file. But it's easy to do, no need for timecode extraction and remux.
foxyshadis
1st October 2015, 10:31
Every suggestion I've seen so far will lead to broken interpolation, by duplicating or dropping frames and confusing the hell out of Interframe. How about this: Use DSS to import a Graphedit .grf instead, one in which you start with your mp4 source and connect SVP. Let the VFR be taken care of in a VFR domain instead of importing it into avisynth.
If Interframe is ever ported to VapourSynth, it would just work, since VS natively supports VFR. But it's not available yet.
AzraelNewtype
1st October 2015, 11:20
Every suggestion I've seen so far will lead to broken interpolation, by duplicating or dropping frames and confusing the hell out of Interframe. How about this: Use DSS to import a Graphedit .grf instead, one in which you start with your mp4 source and connect SVP. Let the VFR be taken care of in a VFR domain instead of importing it into avisynth.
If Interframe is ever ported to VapourSynth, it would just work, since VS natively supports VFR. But it's not available yet.
colours' final suggestion of running interframe as normal and then just making a new timecodes file for it would actually work just fine. If it's mainly one framerate with a couple oddball segments, a v2->v1 converter and just doubling the rates would be pretty easy. If it's messier you can just read every timecode line, divide it by two, and insert that twice into a new file. Maybe alternate rounding up and down for safety. It's easy to script, though lol please don't do it by hand. Vapoursynth would surely make it trivial, but it's not necessary.
Music Fan
1st October 2015, 12:56
Every suggestion I've seen so far will lead to broken interpolation, by duplicating or dropping frames and confusing the hell out of Interframe.
The principle of VFR is that some frames are duplicated when the video is played. Thus anyway, when it's converted to CFR correctly (which means it stays in sync), the video will contain duplicated frames, but the result is supposed to be the same than if the video had been encoded directly in CFR mode. The only difference is that the duplicated frames are hard coded and not created in real time by the player (same principle than soft pulldown and hard pulldown).
I don't understand why Interframe would be more confused if there is a VFR step before, it's not supposed to know it if CFR is created before the Interframe step (whatever the VFR to CFR conversion is made with Avisynth in the same script than the Interframe process or with Virtual Dub and an intermediate avi).
vivan
1st October 2015, 13:25
The principle of VFR is that some frames are duplicated when the video is played.Imagine playing back video that has 24 and 30 fps parts on 120 hz display. Normally it will not have stutter, but if you convert it to 30 fps first then it will.
Should you convert it 120 instead? Maybe even using so-called "null frames"? Oh, wait, we've been there before.
I don't understand why Interframe would be more confused if there is a VFR step before, it's not supposed to know it if CFR is created before the Interframe step (whatever the VFR to CFR conversion is made with Avisynth in the same script than the Interframe process or with Virtual Dub and an intermediate avi).It won't be confused. It just won't interpolate.
Avisynth can't handle VFR, and thus can't Interframe. Whatever method you use to convert it to CFR will have same result - it just won't interpolate between dublicated frames at best (and with blended frames it will be even more sad).
Imagine having 10 fps video that was converted to 30 and then interpolated to 60.
How about this: Use DSS to import a Graphedit .grf instead, one in which you start with your mp4 source and connect SVP.I don't know if it can handle it now, but 3 years ago it handled VFR by looking at fps ffdshow reported. It took 10+ seconds just to switch from one constant framerate to another... Also it will require processing everything in realtime, or am I misunderstanding something?
If video is switching between different constant framerates it should be possible to splice those parts and use Interframe on each part separately... With v1 timecodes it shouldn't be hard.
Music Fan
1st October 2015, 13:49
Imagine playing back video that has 24 and 30 fps parts on 120 hz display. Normally it will not have stutter, but if you convert it to 30 fps first then it will.
Ok, but you are talking about a special case where two framerates are mixed together, but most of VFR videos have only one original framerate and the VFR encoding is only used to discard the duplicated frames and lower the bitrate.
It won't be confused. It just won't interpolate.
Imagine having 10 fps video that was converted to 30 and then interpolated to 60.
I understand. In this case, if it doesn't work with hard coded duplicated frames, it won't work better with a VFR video.
Motenai Yoda
1st October 2015, 14:12
You are all rights, (even if I don't know how interframe can handle vfr streams), but at 90% the source of the mp4 was a 30p one.
aegisofrime
1st October 2015, 14:13
Wow, thanks for the very enlightening discussion so far guys! There's so much that I don't know. The point about using Vapoursynth is interesting. Wasn't there a way to use Avisynth plugins in Vapoursynth?
Unfortunately I haven't gotten a chance to try your suggestions yet; QTGMC'ing a Blu-Ray is no joke!
If it's mainly one framerate with a couple oddball segments, a v2->v1 converter and just doubling the rates would be pretty easy. If it's messier you can just read every timecode line, divide it by two, and insert that twice into a new file. Maybe alternate rounding up and down for safety
This actually sounds interesting because I know that the timecode I extracted works, if I give MKVMerge the MP4 and timecode file the result plays in sync. To clarify, is this what you are saying?
# Example for 10 consecutive frames at 25fps:
0
40.0
80.0
120
160
200
240
280
320
360
# Example for 10 consecutive frames at 50fps:
0
20
40.0
60.0
80.0
100.0
120
140
160
180
200
220
240
260
280
300
320
340
360
If so I can probably whip up a quick program to do the job.
Once again, I appreciate everyone's input in this! It would probably help others who have to deal with VFR content as well!
Music Fan
1st October 2015, 14:17
I don't know how interframe can handle vfr streams
I also wonder how it does handle CFR videos with some short parts without any movement (as it happens sometimes in movies when the camera don't move and film fixed objects).
colours
1st October 2015, 15:58
If Interframe is ever ported to VapourSynth, it would just work, since VS natively supports VFR. But it's not available yet.
That's the exact reason I didn't suggest VapourSynth here. The problem of writing a shim to handle VFR correctly is as hard as writing a script to output a script with pre-calculated interpolation fractions (as in the time parameter of MFlow/MFlowInter).
foxyshadis
2nd October 2015, 11:16
I understand. In this case, if it doesn't work with hard coded duplicated frames, it won't work better with a VFR video.
The problem is that they're not hard coded, but flattening to a 30fps constant frame rate in DSS creates hard coded duplicates where they didn't exist before. That's why I said frame rate conversion should occur where VFR can run free. Interframe is an amazing script, but it just slapping timecodes on its output isn't sufficient when the input is already garbage.
If SVP really can't switch on real-time framerate -- apparently it's still tied too close to MVTools -- then I guess there are no good easy solutions. VS would require some heavy lifting, not just translating but changing the script. Like vivan says, for best quality you're stuck for now with chopping the video up with v1 timecodes and separately Interframing each.
Motenai Yoda
3rd October 2015, 02:39
Well in aegisofrime's case it is a 30p video tdecimated to vfr with 5 frames gops/cycle coz the M-in-N decimation, so that vfr is garbage too.
converting to 30fps, if you're lucky it returns original frames, but usually it'll duplicate another frame.
It's better starting from source
- apply something that generates true vfr like dedup, interframe, save as 60fps
- interpolate the timecode or convert it to v1 and double all frame numbers.
IIRC Interframe/SVP symply interpolate between 2 frames, I don't think it take into account movements speed
but I don't think it will work sensibly better, as you know almost all animation stuff are made with low framerate animations (usually 12 or less) with asynchrony between single animations (ie an arm can move in 0-2-4-6-8 while a leg in 0-3-6 and the background in 1-3-5-7, so it will no decimate any frame, edit- other the ones for ivtc).
TCmullet
26th September 2016, 06:03
As I read this thread, I remain confused. Even after noting who said what. I simply want to get a VFR (variable frame rate) video in an FLV to be CFR at the opening point (top) of my Avisynth script. The two methods debated so far (that are within my realm of feasibility) are:
1. video = LWLibavVideoSource(mainfile,fpsnum=30000,fpsden=1001,cache=false)
2. video = DirectShowSource(mainfile,fps=29.97,convertfps=true,audio=true)
Some say #2 (DSS) is the only way, yet others say never use DSS. Maybe in the months since the past post, some have come to more definitive positions or changed. Could you all please re-chime in and express your thoughts? I've just gotten a whole slew (dozens) of long FLVs that are VFR and I need to get into Avisynth successfully (that is, with perfect audio sync), and without a lot of tedious experimentation. Some are VFR with 29.97 as the max but many are 59.94. None of them show the min and max framerates in MediaInfo, eve tho Mediainfo says it's Variable.
In every case where I had problems (this was last winter and spring), I could always play the file fine in VLC. This makes me wonder if it might be possible to get VLC to frameserve INTO Avisynth. If anyone knows, please telll, as using the smarts of VLC's internals for perfect playback (perfect audio sync) would solve this problem easily and reliably.
Music Fan
26th September 2016, 09:13
There is also the method I described (open your video directly in Virtual Dub with the ffmpeg plugin, without avisynth) ;
http://forum.doom9.org/showthread.php?p=1741010#post1741010
Or try ffvideosource in avisynth.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.