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. |
28th May 2012, 15:54 | #1 | Link |
Registered User
Join Date: Feb 2002
Posts: 303
|
VFRtoCFR
Hi all! From my testing, it seems FFMS2 and Dss2 were slightly inaccurate when converting variable frame rate to constant frame rate videos in MKV. So I decided to write my own plugin. It still requires something like FFMS2 to retrieve all the frames without dups/drops and to grab the timecodes (though mkvextract could also do this). I hope this will be useful to someone.
Code:
VFRtoCFR Converts a variable frame rate (VFR) video to a constant frame rate (CFR) video with the help of Matroska Version 2 Timecodes. Usage: VFRtoCFR(clip c, string times="times.txt", int numfps=30000, int denfps=1001, bool dropped=false) Where: c The clip to convert from VFR to CFR times The path to Matroska timecodes (v2) numfps The numerator of the CFR denfps The denominator of the CFR dropped If true, it will throws an error if there are frames dropped in the conversion. Good to figure out if the CFR is set too low. Changelog: 2012/07/30: -Rewrote the whole algorithm to be a lot smarter 2012/05/28: - Initial release Edit: I'm not sure I posted this in the right forum. If not could some mod move it to the correct place? Edit 2: Clarified that the inaccuracies of FFMS2 and Dss2 is only slight. Last edited by Aktan; 30th July 2012 at 20:07. Reason: Updated release |
29th May 2012, 01:35 | #3 | Link |
Registered User
Join Date: Feb 2002
Posts: 303
|
FFMS2 is only slightly inaccurate in that it is off by half a frame, but depending on the current framerate, the delay may be huge. Take the following example:
Code:
frame number timecode (in ms) 0 0 1 1000 2 2000 3 3000 As to why not a bug report, well I didn't want to wait for it to be fixed, but I can write one if you want. I also had fun programming this, so might as well. Another thing was I couldn't tell if the framerate I choose in FFMS2 dropped frames or not. Last edited by Aktan; 29th May 2012 at 02:12. |
29th May 2012, 12:11 | #4 | Link | |
Registered User
Join Date: Mar 2012
Posts: 10
|
Quote:
Covers the specific issue mentioned here; that FFMS treats the timecode as a sort of 'centerpoint' in a frame, instead of the beginning of the frame. Aktan: Guess you didn't like my TimecodeFPS plugin? |
|
29th May 2012, 15:00 | #7 | Link |
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
I'd argue that it's not "off", it's just a different way of converting. For each frame in the output, FFMS2 uses the source frame that starts closest to the target timestamp. You want it to use the first frame that has a timestamp that is greater than or equal to the requested timestamp instead. In my opinion that's a feature request, since I don't see the current implementation as buggy. It might not do what you want, but it's not strictly wrong either.
For many cases, the FFMS2 implementation will almost always pick frames that are much less "off" time-wise than the one you suggest will. The issue, I guess, is that while the strictly equal-or-greater algorithm may pick frames that are at worst "off" by (almost) one output frame duration, the closest-source-timestamp algorithm will at worst pick frames that are 0.5 input frame durations "off". If the maximum input frame duration * 0.5 is smaller than the output frame duration, closest-source-timestamp will always choose better. I use "off" within quotation marks above because the term is arguable. I guess since you chose the algorithm you did and because of your slideshow example that you consider any frame that is displayed before its source timestamp says it should be displayed to be off, while a frame that is displayed later than its source timestamp might not necessarily be considered "off" to you. I'm not sure if that's the best way to approach framerate conversions in general, though. It works better for your example, sure, but as stated above it has problems with other funny inputs (more specifically, if the output frame duration is longer than the maximum input frame duration, i.e. you're dropping frames). Last edited by TheFluff; 29th May 2012 at 15:02. |
29th May 2012, 16:37 | #9 | Link |
Registered User
Join Date: Feb 2002
Posts: 303
|
I still think that choosing a frame under the timestamp is still incorrect as the original playback would not have the chosen frame shown at that time. Take for example a source area of 30000/1001 FPS. Lets say the timestamps of frames in ms were:
Code:
... 29963 29997 30030 30063 30097 ... I think I can see how this is of opinion which is why, TheFluff, since you consider this a feature request, instead of a bug, it was a good thing I wrote my own then, right? Last edited by Aktan; 29th May 2012 at 16:43. |
29th May 2012, 19:26 | #12 | Link |
Registered User
Join Date: Feb 2002
Posts: 303
|
Wow, I must have had a brainfart when writing the post with dropping frames. Take the example again with frames timestamp in ms:
Code:
... 29963 29997 30030 30063 30097 ... Code:
... 968 1001 ... In general, what VFRtoCFR does is this: Given a CFR frame timestamp: 1. Find the first VFR frame with a timestamp greater than the CFR fame. 2. Take the previous VFR frame as the output for that CFR frame. |
29th May 2012, 19:55 | #13 | Link |
Registered User
Join Date: Feb 2002
Posts: 303
|
I have another proposed solution that I may implement in VFRtoCFR instead:
Given a CFR frame: If the frame time fits completely inside a VFR frame time, choose that VFR frame. Example: A CFR frame has a timestamp playback from 1 ms to 2 ms which fits completely inside a VFR frame that has a timestamp playback from 0 ms to 1000 ms Else if there is a VFR frame time that takes most of the CFR frame time, choose that VFR frame. Example: A CFR has a timestamp playback from 1000 ms to 2000 ms with 3 VFR frames to choose from. The 3 VFR frames have the following timestamps: 1. 999 ms to 1010 ms 2. 1010 ms to 1900 ms 3. 1900 ms to 2001 ms VFR frame choice 2 is taken. Else if there are multiple largest VFR frame that takes most of the CFR frame time, take your pick, but be consistent. Example: A CFR has a timestamp playback from 1000 ms to 2000 ms with 2 VFR frames to choose from. The 2 VFR frames have the following timestamps: 1. 999 ms to 1500 ms 2. 1500 ms to 2001 ms Either VFR frame should be fine, but maybe there are other factors as to why one is chosen over the other (like to avoid dropping or dupping frames). I think this solution would fixed the problems I originally had with FFMS2 and the drop frame problems TheFluff mentioned. Last edited by Aktan; 29th May 2012 at 19:58. |
29th May 2012, 20:44 | #14 | Link |
Registered User
Join Date: Mar 2009
Location: Germany
Posts: 5,769
|
Have you considered how the VFR frames have been achieved?
It may be that a frame was taken just before/after a certain TC during recording (BTW, what recorder other than screen caps do record in VFR?), and thus, due to 2 approximations, be substantially displaced from its place.
__________________
Born in the USB (not USA) |
29th May 2012, 21:38 | #15 | Link |
Registered User
Join Date: Feb 2002
Posts: 303
|
I have not thought of that, but I do create VFR MP4s and MKVs regularly. I make encodes of console emulator games being played back via an input files a lot, and those may have a ton of real duplicate frames. I capture and then I run it through something like DeDup, or lately, ExactDedup to create a timecode file and remove duplicate frames. It is because I know what the original CFR source looks like that I noticed the problems I deem incorrect with Dss2 and FFMS2. I should probably read what the MKV timecodes stand for, but I believe it does mean the start time of a frame, in which case, in your example, the program generating the timecodes are doing it wrong and nothing I can do to fix it.
|
29th May 2012, 21:47 | #16 | Link | |
Registered User
Join Date: Dec 2002
Posts: 5,565
|
Quote:
Ghitulescu's objection is irrelevant to the problem at hand, since we have no way of knowing when a frame "really" should've been displayed. |
|
30th May 2012, 07:42 | #17 | Link |
Registered User
Join Date: Mar 2009
Location: Germany
Posts: 5,769
|
It was not an objection, just a thought. AFAIK screen capturing programs (it includes here PC games played on a PC) lay the TC at the beginning of a frame change, while console games should yield CFR videos (they must be compatible with CFR display devices (eg TVs), if my definition of console games coincides with that of the OP , so a capturing SW that provides VFR videos from CFR ones is wrongly set, used or designed).
__________________
Born in the USB (not USA) |
30th May 2012, 13:28 | #19 | Link |
Registered User
Join Date: Mar 2009
Location: Germany
Posts: 5,769
|
I would consider logic to move all the visual information of the current VFR frame into the current CBR one, if the VFR-TC did not get over half of the CBR-framerate, or the next VFR frame if over. In case a VFR frame is shorter than a CBR one, it should be maintained nevertheless. But I assume this case is rather rare, VFR appeared to save space due to longer frame durations, not shorter.
__________________
Born in the USB (not USA) |
30th May 2012, 13:51 | #20 | Link |
Registered User
Join Date: Feb 2002
Posts: 303
|
In your example graphic, wouldn't my proposed solution above fit it perfectly?
If the CFR frame fits in the VFR frame, take that VFR frame. CFR frames 0 and 1 fits in VFR frame 0. CFR frames 4 and 5 fit in VFR frame 3. Else if there are multiple VFR frames to choose from, take the largest. CFR frame 2 can choose from VFR frame 0 and 1, but since VFR frame 0 takes most of the time in the CFR frame, VFR frame 0 is chosen. Similarly, CFR frame 3 can choose from VFR frames 1 and 2, but since VFR frame 1 takes most of the time in the CFR frame, VFR frame 1 is chosen. |
Thread Tools | Search this Thread |
Display Modes | |
|
|