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 26th December 2019, 09:23   #1  |  Link
bruno321
Registered User
 
Join Date: Oct 2018
Posts: 133
How to produce variable framerate output from a hybrid source?

I'm loading a .d2v file into avisynth using MPEG2Source. It's at 25fps. Some sections are progressive, and some are purely interlaced. I'd like to manually discriminate them, and run QTGMC() in the ones of the second type, finishing with something with variable framerate. I looked around in this forum but only found really old information, so I'd like to know what's the best and most up-to-date method for doing this kind of thing.

In case it matters, I use the latest Avisynth+, together with avspmod and megui.

Thanks in advance.
bruno321 is offline   Reply With Quote
Old 26th December 2019, 10:11   #2  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,026
I would avoid to create VFR material. It may just cause playback issues or problems for future editing, depending on the device.
Do you want to keep it as mpeg2 or is changing to AVC or HEVC an option?
If you want progressive output I would deinterlace (or bob deinterlace) everything using QTGMC and encode with x264 (AVC) as progressive.
Or encode everything as interlaced using x264 (MBAFF).
I doubt whether a more sophisticated method would really show a benefit.
It's not an answer to your question though …….

Last edited by Sharc; 26th December 2019 at 10:33.
Sharc is offline   Reply With Quote
Old 26th December 2019, 10:41   #3  |  Link
bruno321
Registered User
 
Join Date: Oct 2018
Posts: 133
I want to encode it with x264.

But I wouldn't want to have 1 out of 2 frames being duplicates in the progressive parts (which would happen if I QTMGC them)... it bloats the file unnecessarily, and wouldn't it make it judder as well?
bruno321 is offline   Reply With Quote
Old 26th December 2019, 11:33   #4  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,087
Quote:
Originally Posted by bruno321 View Post
I want to encode it with x264.

But I wouldn't want to have 1 out of 2 frames being duplicates in the progressive parts (which would happen if I QTMGC them)... it bloats the file unnecessarily, and wouldn't it make it judder as well?
Side note:

With an high enough reframe, x264 motion compensation will work really well in compressing identical frames and it won't stutter more than it does when you watched it on air: for instance if you live in a PAL region and you get a mixed progressive flagged as interlaced and truly interlaced stream, they will both be blindly bobbed to 50p by your TV.


Encoding VFR:

If you wanna try to encode in VFR, though, you can try to write your Avisynth Script, bob-deinterlace everything to 50p and then open the .avs file as input in ffmpeg with something like:

FFmpeg.exe -i "AVS_Script.avs" -vsync 2

Followed by the libx264 parameters.
Vsync 2 will drop frames when necessary and will be perfect for your needs. I also suggest you to use mkv as a container for your VFR stream as it handles VFR nicely.

This is the description of the vsync parameter:

Quote:
-vsync parameter
Video sync method.

0, passthrough

Each frame is passed with its timestamp from the demuxer to the muxer.

1, cfr

Frames will be duplicated and dropped to achieve exactly the requested constant frame rate.

2, vfr

Frames are passed through with their timestamp or dropped so as to prevent 2 frames from having the same timestamp.
drop

As passthrough but destroys all timestamps, making the muxer generate fresh timestamps based on frame-rate.

-1, auto

Chooses between 1 and 2 depending on muxer capabilities. This is the default method.

Please note that players don't have to be VFR aware by H.264 specifications and may not be able to reproduce a file. I tested some VFR files on TV sets and I can tell you that not all of them are compatible. Just encode a minute or so as test wit trim() and check whether your TV plays the file or not and eventually choose what to do.

Cheers,
Frank.
FranceBB is offline   Reply With Quote
Old 26th December 2019, 11:48   #5  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,026
Quote:
Originally Posted by bruno321 View Post
I want to encode it with x264.

But I wouldn't want to have 1 out of 2 frames being duplicates in the progressive parts (which would happen if I QTMGC them)... it bloats the file unnecessarily, and wouldn't it make it judder as well?
No bloating to be expected as x264 is very efficient in encoding duplicated frames. Almost nil overhead. Actually, the file might even become significantly smaller (for same crf) due to the cleaning/denoising effect of QTGMC. Just run a test and be surprised
As I wrote I would expect much more problems with a variable frame rate (VFR) attempt and avoid it unless you have a very specific reason for it.
Sharc is offline   Reply With Quote
Old 26th December 2019, 15:51   #6  |  Link
Overdrive80
Anime addict
 
Overdrive80's Avatar
 
Join Date: Feb 2009
Location: Spain
Posts: 673
http://avisynth.nl/index.php/VFR

Quote:
This is a 2-pass mode. Add this to your script:

TFM(mode=1,output="tfm.txt")
TDecimate(mode=4,output="stats.txt")
Open this and play through it in VirtualDub. Then close it, comment those lines out (or start a second script) and add:

TFM(mode=1)
TDecimate(mode=5,hybrid=2,dupthresh=1.0,input="stats.txt",tfmin="tfm.txt",mkvout="timecodes.txt")
Load and encode.
It is automate mode, if you want manual mode then:

1. Setting sections, you should noted parts.

Code:
YourLoader(".\VideoFile1.d2v", info=3)

ColorMatrix(hints=true, threads=0,interlaced=true)
2. With noted sections [f.e.: material FILM (0-38811), material NTSC (38812,0)], deinterlacing:

Code:
YourLoader(".\VideoFile1.d2v", info=3)

ColorMatrix(hints=true, threads=0,interlaced=true)

part1=trim(0,38811).tfm().tdecimate()
part2_in=trim(38812,41089) 


part2=part2_in.QTGMC( Preset="very Slow", EdiMode="EEDI2",fpsdivisor=2).assumefps(part1.framerate)

part1++part2
3. Generate timecodes:

Code:
YourLoader(".\VideoFile1.d2v", info=3)

ColorMatrix(hints=true, threads=0,interlaced=true)

part1=trim(0,38811).tfm().tdecimate()
part2_in=trim(38812,41089) 

part2=part2_in.QTGMC( Preset="very Slow", EdiMode="EEDI2",fpsdivisor=2).assumefps(part1.framerate)

part1++part2

WriteFile(last, "timecodesv1.txt" ,""" "# assume 29.970029" """, append=false)

WriteFile(last, "timecodesv1.txt" ,""" "0," """, "part1.framecount", """ "," """, "part1.framerate")

WriteFile(last, "timecodesv1.txt" , "part1.framecount+1", """ "," """ , "part1.framecount+part2.framecount-1",\
		 """ "," """, "part2_in.framerate")

return last
4. Muxing on mkv.

Manual mode is generic example, you must modify according to your needs.
__________________
Intel i7-6700K + Noctua NH-D15 + Z170A XPower G. Titanium + Kingston HyperX Savage DDR4 2x8GB + Radeon RX580 8GB DDR5 + ADATA SX8200 Pro 1 TB + Antec EDG750 80 Plus Gold Mod + Corsair 780T Graphite

Last edited by Overdrive80; 26th December 2019 at 15:55.
Overdrive80 is offline   Reply With Quote
Old 26th December 2019, 22:19   #7  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 4,924
For PAL I don't think there's a way to automate the process (the TIVTC plugin can do it for NTSC as long as you only de-interlace to 29.970fps). I'll confess though, I don't fully understand how the method FranceBB suggested earlier works.

If there's only a small number of progressive sections I'd probably just run QTGMC on the whole thing, and sometimes even for the progressive sections I use QTGMC().SelectEven() or something similar to clean them up a bit, even when the output will be VFR, but my process is something like this, which can be fairly time consuming.

Create the initial script and open it with MeGUI's AVS Cutter. Use it's preview to find the interlaced and progressive sections and specify the start and end frames for each, then save the "cuts" as MeGUI calls them. From there you add the required de-interlacing to each section and the end result will be something like this.

For this example QTGMC() is used on it's own to de-interlace the interlaced sections. I've followed the progressive sections with AssumeFPS(50), as Avisynth requires a constant frame rate. Temporarily adding GreyScale() sometimes makes the next step a little easier.

film=Last
__t0 = film.trim(0, 25849).QTGMC()
__t1 = film.trim(25850, 52749).AssumeFPS(50).GreyScale()
__t2 = film.trim(52750, 58007).QTGMC()
__t3 = film.trim(58008, 66063).AssumeFPS(50).GreyScale()
__t4 = film.trim(66064, 67577).QTGMC()
__t5 = film.trim(67578, 70921).AssumeFPS(50).GreyScale()
__t6 = film.trim(70922, 73651).QTGMC()
__t0 ++ __t1 ++ __t2 ++ __t3 ++ __t4 ++ __t5 ++ __t6
# crop and/or resize or whatever else here as required.

When that's done you need to go through the process again to find the frame numbers for the timecodes file. They'll change, as for example, the first section now has twice the number of frames so it'll be frames 0 to 51699. I generally find the new frame numbers by opening the scrpt again with the AVS cutter and adding a second lot of trims. If stepping through the script is slow, you can temporarily replace QTGMC with Yadif(Mode=1).
Because the "film" sections are greyscale it makes it harder to mistake an interlaced section for progressive etc and end up with a mess. I'm roughly calculating frame numbers here, so they mightn't be exact, but the second lot of trims added to the script would look like this:

film=Last
__t0 = film.trim(0, 51699)
__t1 = film.trim(51700, 78598)
__t2 = film.trim(78599, 89112)
__t3 = film.trim(89113, 97167)
__t4 = film.trim(97168, 100193)
__t5 = film.trim(100194, 103536)
__t6 = film.trim(103537, 108994)
__t0 ++ __t1 ++ __t2 ++ __t3 ++ __t4 ++ __t5 ++ __t6

Next step is to create a timecodes file using the frame numbers from just the progressive (25fps) sections. It's a text file.

# timecode format v1
Assume 50
51700, 78598, 25
89113, 97167, 25
100194, 103536, 25

Or you can do it the other way around:

# timecode format v1
Assume 25
0, 51699, 50
78599, 89112, 50
97167, 100193, 50
103537, 108994, 50

Once you've created the timecodes file you can delete the second lot of trims from the script, remove GreyScale() from the progressive sections and supply x264 with the timecodes for VFR encoding by adding the following to the custom command line section in MeGUI's x264 encoder configuration (obviously with the appropriate file path and file name).

--tcfile-in "D:\Timecodes.txt"

If the encoder is writing directly to MKV there's no need to add the timecodes file again when muxing the audio etc with the encoded video. If the encoder is writing a raw h264 stream, I'm not sure.

It can be a lot of work when there's many interlaced and progressive sections, but that's how I do it when I'm really keen.

Last edited by hello_hello; 27th December 2019 at 01:19.
hello_hello is offline   Reply With Quote
Old 28th December 2019, 07:07   #8  |  Link
bruno321
Registered User
 
Join Date: Oct 2018
Posts: 133
Thank you all for the suggestions. I have some testing to do
bruno321 is offline   Reply With Quote
Old 31st December 2019, 02:50   #9  |  Link
kuchikirukia
Registered User
 
Join Date: Oct 2014
Posts: 478
The only time I had to deal with a hybrid progressive/interlaced source I went and doubled the progressive frames so the entire thing was 60fps. There should be a thread started by me where I was asking for help.

Here it is:
https://forum.doom9.org/showthread.php?t=173966

Code:
DeInt=QTGMC(preset="Very Slow")
A=ConditionalFilter(last,DeInt.SelectEven,last,"IsCombedTIVTC","=","true") 
B=ConditionalFilter(last,DeInt.SelectOdd,last,"IsCombedTIVTC","=","true")
Interleave(A,B)
kuchikirukia is offline   Reply With Quote
Old 9th November 2020, 14:14   #10  |  Link
bruno321
Registered User
 
Join Date: Oct 2018
Posts: 133
I now have another kind of hybrid source. 29.97fps, some sections need tfm().tdecimate(), other sections need QTGMC(), so this would be a hybrid of some parts in 23.976fps and some parts in 59.94fps. Is there some way to achieve this automatically? And if not, what's the best manual way to do it?

EDIT: a better forum search led me to https://forum.doom9.org/showthread.php?p=1713315 or https://forum.doom9.org/showthread.php?t=173147, will dig into that.....

EDIT, some time later: Damn, is it really that hard?

Last edited by bruno321; 9th November 2020 at 15:25.
bruno321 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 11:51.


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