View Full Version : InterFrame 2.8.2 - Framedoubling/60FPS/HFR conversion script
Pages :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[
20]
StainlessS
8th November 2016, 16:17
I will fix it in my pfmod branch in the next release.
Oooh, lovely :)
I'm doing a little bit of work on DoubleRate deinterlace/Interpolation and need the overlap thing. It caught me a bit by surprise that when dealing with
hybrid source (with possibility of single interlaced frame in progressive sequence), that single non-combed status of progressive frame is not enough
to deal with it properly, a third combed status is required. 0)=Interlaced, 1)=Progressive current+progressive next, 2)=Progressive current & Interlaced Next.
If not taken into account, then Interpolated frames will use Progressive current + Interlaced next as sources. Perhaps this was obvious to you lot, but
was not to me. To fix it, I'm using Progressive current + deinterlaced first field of next for interpolation. I guess that QTGMC already copes with this.
DanilaZabiaka
9th March 2020, 21:47
My version based on new libraries :)
https://forum.doom9.org/showthread.php?p=1903412#post1903412
markfilipak
17th February 2021, 07:17
Hi Y'all,
I've successfully transcoded 24/1.001fps samples to 60/1.001fps (and also to 120/1.001fps) via the Windows cmd scripts below.
But when I use the same script to transcode SubJunk's 24/1.001fps sample (http://www.spirton.com/uploads/InterFrame/20110618-Sample-Original.mkv), the transcode comes out unexpectedly and I wonder why.
This transcodes to 60/1.001fps as expected:
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=60000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=60000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-60fps.mkv
This transcodes to 60fps instead of to 60/1.001fps:
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=120000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=120000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -filter_complex "tinterlace=mode=drop_odd" -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-120fps-to-60fps.mkv
Of course, the problem could be with 'tinterlace=mode=drop_odd', so I tried it without 'tinterlace':
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=120000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=120000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-120fps.mkv
but it transcodes to 120fps instead of to 120/1.001fps. Anyone know why? I just can't see it.
poisondeathray
17th February 2021, 08:30
Hi Y'all,
I've successfully transcoded 24/1.001fps samples to 60/1.001fps (and also to 120/1.001fps) via the Windows cmd scripts below.
But when I use the same script to transcode SubJunk's 24/1.001fps sample (http://www.spirton.com/uploads/InterFrame/20110618-Sample-Original.mkv), the transcode comes out unexpectedly and I wonder why.
This transcodes to 60/1.001fps as expected:
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=60000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=60000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-60fps.mkv
This transcodes to 60fps instead of to 60/1.001fps:
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=120000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=120000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -filter_complex "tinterlace=mode=drop_odd" -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-120fps-to-60fps.mkv
Of course, the problem could be with 'tinterlace=mode=drop_odd', so I tried it without 'tinterlace':
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=120000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=120000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-120fps.mkv
but it transcodes to 120fps instead of to 120/1.001fps. Anyone know why? I just can't see it.
It has nothing to do with interframe
When debugging scripts, strip everything down , eliminate variables, and check each step, each output node. Same with ffmpeg. Start with something simple like blankclip(). Label the framenumbers.
vapoursynth and the input pipe into ffmpeg are fine; it's the output in ffmpeg that is the problem - even with NUL - the output is rounded. There might be some switch or command to prevent this, not sure
vspipe --y4m 1.vpy - | ffmpeg -f yuv4mpegpipe -i - -an -f null NUL
Input #0, yuv4mpegpipe, from 'pipe:':
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p(progressive), 640x48
0, 119.88 fps, 120 tbr, 119.88 tbn, 119.88 tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> wrapped_avframe (native))
Output #0, null, to 'NUL':
Metadata:
encoder : Lavf58.67.100
Stream #0:0: Video: wrapped_avframe, yuv420p(progressive), 640x480, q=2-31, 20
0 kb/s, 120 fps, 120 tbn
Another option is to perform the operations vapoursynth or avisynth
tinterlace=mode=drop_odd is the same thing as selecteven() in avisynth, or clip = clip[::2] in vapoursynth
2.vpy
import vapoursynth as vs
core = vs.get_core()
clip = core.std.BlankClip(format=vs.YUV420P8, length=240, color=[16, 128, 128])
clip = core.text.FrameNum(clip)
clip = core.std.AssumeFPS(clip, fpsnum=120000, fpsden=1001)
clip = clip[::2]
clip.set_output()
vspipe --y4m 2.vpy - | ffmpeg -f yuv4mpegpipe -i - -an -f null NUL
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p(progressive), 640x48
0, 59.94 fps, 59.94 tbr, 59.94 tbn, 59.94 tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> wrapped_avframe (native))
Output #0, null, to 'NUL':
Metadata:
encoder : Lavf58.67.100
Stream #0:0: Video: wrapped_avframe, yuv420p(progressive), 640x480, q=2-31, 20
0 kb/s, 59.94 fps, 59.94 tbn
actual encode
vspipe --y4m 2.vpy - | ffmpeg -f yuv4mpegpipe -i - -c:v libx264 -preset:v fast -crf 20 -an 2.mp4
ffmpeg -i 2.mp4
Duration: 00:00:02.00, start: 0.000000, bitrate: 48 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x480, 39
kb/s, 59.94 fps, 59.94 tbr, 60k tbn, 119.88 tbc (default)
Looks ok, frames are correct when examined
Also, I would avoid mkv if you want more accurate timestamps. mkv uses a timebase of 1/1000s so there is rounding and some jitter
markfilipak
17th February 2021, 09:30
It has nothing to do with interframe
I agree wholeheartedly. Why? Because it worked for SubJunk. I assume SubJunk didn't pipe to ffmpeg.
I love doom9. You guys are the best. You, and ... well, I'm not going to name names because I fear I would leave someone out. You all are Heroes of the Revolution. :thanks:
You've given me a lot to examine. Do you think the difference is because ffmpeg works via PTSs instead of frame numbers? I've been getting that feeling but ffmpeg docs hardly even mention "PTS". Certainly the filter docs don't mention what they do regarding either reading or writing PTSs.
It's funny you should mention "tinterlace=mode=drop_odd is the same thing as selecteven() in avisynth" because my first ffmpeg drop_odd approach was to use 'select=eq(mod(n\,2)\,0)' but PTSs don't get updated (as seen in MPV) and the results are unpredictable.
You're obviously well informed. I've been struggling with ffmpeg for half a year but, tell me: Do you think I should abandon ffmpeg?
markfilipak
17th February 2021, 09:40
Also, I would avoid mkv if you want more accurate timestamps. mkv uses a timebase of 1/1000s so there is rounding and some jitter
What do you prefer?
Edit: I think MPEG streams use 1/90000s. What transports also use 1/90000s? All my sources will be DVD & BD movies.
poisondeathray
17th February 2021, 15:34
Do you think the difference is because ffmpeg works via PTSs instead of frame numbers? I've been getting that feeling but ffmpeg docs hardly even mention "PTS". Certainly the filter docs don't mention what they do regarding either reading or writing PTSs.
That's a difference, but not the full explanation here. That rounding observation needs to be investigated farther, it's unexpected
It's avisynth that is CFR only, frame only. vapoursynth is actually both
It's funny you should mention "tinterlace=mode=drop_odd is the same thing as selecteven() in avisynth" because my first ffmpeg drop_odd approach was to use 'select=eq(mod(n\,2)\,0)' but PTSs don't get updated (as seen in MPV) and the results are unpredictable.
For frame manipulations like that, they are automatically adjusted in avisynth and mostly in vapoursynth too.
Do you think I should abandon ffmpeg?
No.
They are just tools, pros/cons to each of them. Often there are multiple ways to get something done, but certain operations are often better/faster in one or the other.
Also, I would avoid mkv if you want more accurate timestamps. mkv uses a timebase of 1/1000s so there is rounding and some jitter
What do you prefer?
For general use MP4, because it's more compatible with devices, web, NLE's - basically all scenarios
richardpl
17th February 2021, 15:55
Hi Y'all,
I've successfully transcoded 24/1.001fps samples to 60/1.001fps (and also to 120/1.001fps) via the Windows cmd scripts below.
But when I use the same script to transcode SubJunk's 24/1.001fps sample (http://www.spirton.com/uploads/InterFrame/20110618-Sample-Original.mkv), the transcode comes out unexpectedly and I wonder why.
This transcodes to 60/1.001fps as expected:
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=60000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=60000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-60fps.mkv
This transcodes to 60fps instead of to 60/1.001fps:
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=120000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=120000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -filter_complex "tinterlace=mode=drop_odd" -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-120fps-to-60fps.mkv
Of course, the problem could be with 'tinterlace=mode=drop_odd', so I tried it without 'tinterlace':
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source='20130218-Sample-Original.mkv')>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=120000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video = core.std.AssumeFPS(video, fpsnum=120000, fpsden=1001)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
vspipe --y4m Mark's.vpy - | ffmpeg -thread_queue_size 2048 -i pipe: -i 20130218-Sample-Original.mkv -map 0:v -map 1:a -codec:v libx265 -x265-params "crf=16:qcomp=0.6" -codec:a copy -codec:s copy 20130218-Sample-InterFrame-120fps.mkv
but it transcodes to 120fps instead of to 120/1.001fps. Anyone know why? I just can't see it.
You clearly cant read filter documentation. Drop odd mode of tinterlace filter drops odd fields.
While for some reason unknown to universe you expect it will make video into smaller fps.
First you invent problem that does not actually exist. Then you claim tool have issue.
And the only issue from start is you.
poisondeathray
17th February 2021, 16:25
You clearly cant read filter documentation. Drop odd mode of tinterlace filter drops odd fields.
While for some reason unknown to universe you expect it will make video into smaller fps.
You must not be awake yet, Paul
https://ffmpeg.org/ffmpeg-filters.html#tinterlace
‘drop_odd, 2’
Only output even frames, odd frames are dropped, generating a frame with unchanged height at half frame rate.
Drops odd frames, which implies keeps even frames
It also says "half frame rate" , which implies a lower fps
Also, in video world, non ffmpeg, frames are very different than fields.
What do you make of the rounding issue without any filters, without any containers ?
markfilipak
17th February 2021, 19:54
What do you [Paul Mahol] make of the rounding issue without any filters, without any containers ?
How can MKV affect PTS? PTS (and DTS) are part of the elemental stream, not part of the container. The following is my parse from an MPEG2 movie ('--' is a byte, '----' is a nibble, '[####.#]' is hex offset '.' bit offset). Look:
Ref: stnsoft.com/DVD/pes-hdr.html | ... PES_HEADER_EXTENSION__________________
PTS (presentation time stamp) | ... 31 00 01 5B C9 -- -- -- -- -- -- -- --
[0017] [0000] ????? | 0011 ---- ---- ---- ---- ---- ---- ---- ---- ----
[0017.4] [0000.4] PTS | ---- 000- 0000 0000 0000 000- 0101 1011 1100 100- ... = 11748; PTS = (11748)/(90000) seconds = 00:00:00.130533333
[0017.7] [0000.7] (marker bit) | ---- ---1 ---- ---- ---- ---- ---- ---- ---- ----
[0019.7] [0002.7] (marker bit) | ---- ---- ---- ---- ---- ---1 ---- ---- ---- ----
[001B.7] [0004.7] (marker bit) | ---- ---- ---- ---- ---- ---- ---- ---- ---- ---1
DTS (decoding time stamp) | ... -- -- -- -- -- 11 00 01 09 AD -- -- --
[001C] [0005] ????? | 0001 ---- ---- ---- ---- ---- ---- ---- ---- ----
[001C.4] [0005.4] DTS | ---- 000- 0000 0000 0000 000- 0000 1001 1010 110- ... = 1238; DTS = (1238)/(90000) seconds = 00:00:00.013755555
[001C.7] [0005.7] (marker bit) | ---- ---1 ---- ---- ---- ---- ---- ---- ---- ----
[001E.7] [0007.7] (marker bit) | ---- ---- ---- ---- ---- ---1 ---- ---- ---- ----
[0020.7] [0009.7] (marker bit) | ---- ---- ---- ---- ---- ---- ---- ---- ---- ---1
Am I misinterpreting things?
poisondeathray
17th February 2021, 20:49
How can MKV affect PTS? PTS (and DTS) are part of the elemental stream, not part of the container.
Am I misinterpreting things?
2 separate issues are being referred to
1) One is your original 120000/1001 vs. 120.0 fps issue . The input in my little test is clearly 119.88fps
Stream #0:0, 11, 1001/120000: Video: rawvideo (I420 / 0x30323449), yuv420p(progressive), 640x480, 119.88 fps, 120 tbr, 119.88 tbn, 119.88 tbc
But the output is rounded to 120fps -this is a null stream, no container
Stream #0:0, 0, 1/120: Video: wrapped_avframe, yuv420p(progressive), 640x480, q=2-31, 200 kb/s, 120 fps, 120 tbn
exerpt from -report
[graph 0 input from stream 0:0 @ 0000000afe895840] Setting 'frame_rate' to value '120/1'
Why is ffmpeg setting frame rate to 120/1 ? Over to Paul...
2) Second is the general issue of MKV container default 1/1000s timebase resulting in rounded timestamps. It's fine for playback. Not ok for other workflows with intermediates - potential for propogating errors
eg.
The same 24000/1001 video is encoded using MP4 container vs. MKV container
The resulting timestamps look like this
MKV
0
42
83
125
167
.
.
.
MP4
0
41.7083333333333
83.4166666666667
125.125
166.833333333333
.
.
.
Why is MP4 more precise? - Because of the MP4 timebase scale
Read this for the math
https://www.nmm-hd.org/newbbs/viewtopic.php?t=219&start=290#p10428
markfilipak
17th February 2021, 21:17
2) Second is the general issue of MKV container default 1/1000s timebase resulting in rounded timestamps. It's fine for playback. Not ok for other workflows with intermediates - potential for propogating errors
I confess that I don't know MKV, but what about this: http://forum.doom9.org/showthread.php?p=1936167?
Read this for the math
https://www.nmm-hd.org/newbbs/viewtopic.php?t=219&start=290#p10428
To me, that looks like lipstick on a pig.
If, in addition to the PES's 'PES_HEADER_EXTENSION', the MKV container also stores PTS (but truncated to milliseconds), then MKV is seriously flawed. But I find it hard to believe that MKV (or any container TS) does that. I can't say it doesn't because, as I said, I don't know MKV formatting, but I can say that it would be really strange.
Edit: I would say, stick with the PTSs as stored in the PES and ignore what MKV has in the TS (if, indeed, it does that).
markfilipak
17th February 2021, 23:39
vspipe --y4m 1.vpy - | ffmpeg -f yuv4mpegpipe -i - -an -f null NUL
Would you post '1.vpy' so I can replicate your findings?
poisondeathray
18th February 2021, 00:09
what about this: http://forum.doom9.org/showthread.php?p=1936167?
Not sure. How does it cover VFR situations ? e.g. smartphones video, webcams, etc.. Currently they are handled by external timestamps ("container") , not in the ES.
Would you post '1.vpy' so I can replicate your findings?
It's the same thing as 2.vpy without selecteven, or you can comment it out
import vapoursynth as vs
core = vs.get_core()
clip = core.std.BlankClip(format=vs.YUV420P8, length=240, color=[16, 128, 128])
clip = core.text.FrameNum(clip)
clip = core.std.AssumeFPS(clip, fpsnum=120000, fpsden=1001)
clip.set_output()
poisondeathray
18th February 2021, 00:40
For the 120fps vs. 120000/1001 - you can encode 1.vpy with other tools like x264cli, x265cli, it results in the proper 120000/1001 output. You can check the encoded framerate and timestamps with other tools, they all agree, even ffprobe/ffmpeg says the x264cli output is 119.88fps not 120fps
The ffmpeg " Setting 'frame_rate' to value '120/1' " I think is not intended behaviour
markfilipak
18th February 2021, 03:52
Regarding an MPEG2 PES,Not sure. How does it cover VFR situations ? e.g. smartphones video, webcams, etc.. Currently they are handled by external timestamps ("container") , not in the ES.
Hmmm... I checked a bunch of BDs & DVDs. Some extras and previews are VFR. A few DVD features are VFR if they start with a studio splash at 30fps -- assumed: That it was a "Home Video" splash jammed on for DVD but that wasn't seen in theaters.
The change is, of course, perfectly okay if the fps change happens at a keyframe. In fact, it can happen solely at keyframes.
Currently, I transcode for the main part of the feature or extra, not the opener or splash. I don't care about them. Often, I cut them out.
What I infer from what you write is that ffmpeg (and other tools) don't allow for VFR coming out of the decoder. Am I correct? If so, that's too bad and aught to be fixed. Putting framerate in the transport stream is a poor choice from an architectural point of view. Oh, well.
I understand what you mean now when you say that MKV is a bad choice. And I agree. I picked it solely because it's popular, everthing seems to play it, Handbrake & MKVToolNix, and people said to avoid MP4.
markfilipak
18th February 2021, 04:05
The ffmpeg " Setting 'frame_rate' to value '120/1' " I think is not intended behaviour
I'm no longer surprised by what passes for "intended behavior". I submitted the following
tinterlace broken - SAR & DAR wrong
ffmpeg -report -i source.mkv -vf "tinterlace=mode=merge" -c:a copy -c:s copy -dn tinterlace.mkv
I made source.mkv from a VOB:
ffmpeg -ss 1.00 -to 2.00 -i g:\VIDEO_TS\VTS_06_1.VOB -vf separatefields -c:a copy -c:s copy -dn source.mkv
That's why source.mkv is MPEG-4 AVC & 720x240 @ 60/1.001 FPS:
Stream #0:0: Video: h264 (High), yuv420p(tv, smpte170m, progressive), 720x240 [SAR 8:9 DAR 8:3], 59.94 fps, 59.94 tbr, 1k tbn, 119.88 tbc (default)
Therefore, tinterlace.mkv should be 720x480 @ 30/1.001 FPS [SAR 8:9 DAR 4:3] but it's not. tinterlace.mkv is:
Stream #0:0: Video: h264 (High), yuv420p(tv, smpte170m, top coded first (swapped)), 720x480 [SAR 16:9 DAR 8:3], 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc (default)
Though I've never done it before, I think I can force SAR & DAR, but tinterlace really needs to be fixed.
Thanks,
Mark.
and Paul said it was intended.
He is diddling SAR based, not on differential resampling of source pixels at a different sample aspect, but on what makes other things work -- at least, that's what I think (sort of offsetting penalties in various use-cases).
poisondeathray
18th February 2021, 04:41
I understand what you mean now when you say that MKV is a bad choice. And I agree. I picked it solely because it's popular, everthing seems to play it, Handbrake & MKVToolNix, and people said to avoid MP4.
I never said "bad choice" ; I said
I would avoid mkv if you want more accurate timestamps. mkv uses a timebase of 1/1000s so there is rounding and some jitter
It's perfectly fine for final playback purposes. Don't overlook the other advantages that MKV has over other containers in stream support, A/V format support, sub support, attachments, ordered chapters. There are pros/cons to everything.
markfilipak
18th February 2021, 08:06
I never said "bad choice" ...
Oops! Indeed, you did not. Kindly excuse me. I'm still attempting to determine the properties of the various TS containers. It's not an easy task as there's much contradictory info/opinions.
markfilipak
19th February 2021, 05:16
[MKV is] perfectly fine for final playback purposes. Don't overlook the other advantages that MKV has over other containers in stream support, A/V format support, sub support, attachments, ordered chapters. There are pros/cons to everything.
You are so far down the road I'm trudging... May I ask: What if I transcode to MP4 and then remux to MKV? Would that be the best of both worlds? Would that be the best solution in my quest for perfection?
poisondeathray
19th February 2021, 15:36
You are so far down the road I'm trudging... May I ask: What if I transcode to MP4 and then remux to MKV? Would that be the best of both worlds? Would that be the best solution in my quest for perfection?
Remux with mkvmerge or similar? - No difference in terms of timestamps, the end result will be the same without the MP4 step
markfilipak
19th February 2021, 23:46
Remux with mkvmerge or similar? - No difference in terms of timestamps, the end result will be the same without the MP4 step
Oh! I get it (I think). The problem isn't just that MKV has a 1 kHz timebase. It's that the ffmpeg filter pipeline also uses a 1 kHz TB. So, using a PES that has a 90 kHz TB wouldn't make any difference -- the resolution just isn't there.
Is that what you demonstated by writing to NULL? Do I have that right?
Oh, dear. I guess 1 kHz TB is baked into the decoder, right? If so, then there is no 'better' tool, or is there? Do all transcoding apps use the same decoders?
poisondeathray
20th February 2021, 01:03
Oh! I get it (I think). The problem isn't just that MKV has a 1 kHz timebase. It's that the ffmpeg filter pipeline also uses a 1 kHz TB. So, using a PES that has a 90 kHz TB wouldn't make any difference -- the resolution just isn't there.
Is that what you demonstated by writing to NULL? Do I have that right?
Oh, dear. I guess 1 kHz TB is baked into the decoder, right? If so, then there is no 'better' tool, or is there? Do all transcoding apps use the same decoders?
What you start with doesn't matter in this MKV tbn regard ("tbn" what ffmpeg labels the container timebase), as soon as you put it into MKV, you use the 1K tbn. It doesn't matter what you use to parse the MKV . It does not matter if you non-ffmpeg/libavcodec tools either
You would expect (or I expected from prior tests years past) there to be no difference with using MP4 step - and I retested it again today, then read the timestamps in the output MKV file, and it confirms no difference. Those little rounding differences are not a problem for regular end playback situations. You have to be superhuman to perceive some difference. But it can be an issue for intermediates and some types of workflows
NUL is partly to help avoid all the other variables. It's part of the "basic scientific method (TM)". Eliminate all the other confounding variables like filters, containers, audio etc.. eg. Maybe adding of subtitles screws up timing; Maybe muxing audio screws something else up, etc... Strip it down to the smallest elements that can reproduce the issue. The issue was the 120000/1001 to 120 fps change. So that's what you test. Don't go testing other stuff or adding extraneous things unless you find out it's contributing to the problem. For debugging nobody want to wait for libx265 to complete. Nobody wants to download a big file to test, unless it's actually part of the problem. If you can simplify everything, each test run observation goes faster. If you can reproduce with blankclip or something like testsrc2 in ffmpeg, all the better. Do some of the legwork - so if there is a real bug - the developer does not have to spend extra time working things out
markfilipak
26th February 2021, 03:57
Because of excellent help here -- thank you ChaosKing & lansing & poisondeathray -- I succeeded piping vspipe to ffmpeg.
Now, I need to go in the opposite direction. I did a ton of reading and head scratching, then I guessed (and failed twice).
What's wrong?
Failure #1
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source=-)>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=60000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
ffmpeg -i INPUT.MKV -vf "...works.skipping..." -f rawvideo - | vspipe --y4m Mark's.vpy OUTPUT.MKV
...
Output #0, rawvideo, to 'pipe:':
Metadata:
encoder : Lavf58.65.101
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p(tv, smpte170m, progressive), 240x236 [SAR 32:27 DAR 640:531], q=2-31, 16296 kb/s, 23.98 fps, 23.98 tbn (default)
Metadata:
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
BPS-eng : 642744
DURATION-eng : 00:00:05.739000000
NUMBER_OF_FRAMES-eng: 172
NUMBER_OF_BYTES-eng: 461089
_STATISTICS_WRITING_APP-eng: mkvmerge v51.0.0 ('I Wish') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-12-21 04:14:21
DURATION : 00:00:05.739000000
encoder : Lavc58.119.100 rawvideo
Script evaluation failed:
Python exception: invalid syntax (Mark's.vpy, line 2)
Traceback (most recent call last):
File "src\cython\vapoursynth.pyx", line 2241, in vapoursynth.vpy_evaluateScript
File "Mark's.vpy", line 2
video = core.ffms2.Source(source=-)
^
SyntaxError: invalid syntax
av_interleaved_write_frame(): Broken pipe
Error writing trailer of pipe:: Broken pipetime=00:00:00.04 bitrate=16296.2kbits/s speed=0.453x
frame= 1 fps=0.3 q=-0.0 Lsize= 83kB time=00:00:00.04 bitrate=16296.2kbits/s speed=0.0121x
video:83kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
Conversion failed!
Failure #2
ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source=-)>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=60000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video.output(OUTPUT.MKV)>>Mark's.vpy
ffmpeg -i INPUT.MKV -vf "...works.skipping..." -f rawvideo - | vspipe --y4m Mark's.vpy
...
Output #0, rawvideo, to 'pipe:':
Metadata:
encoder : Lavf58.65.101
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p(tv, smpte170m, progressive), 240x236 [SAR 32:27 DAR 640:531], q=2-31, 16296 kb/s, 23.98 fps, 23.98 tbn (default)
Metadata:
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
BPS-eng : 642744
DURATION-eng : 00:00:05.739000000
NUMBER_OF_FRAMES-eng: 172
NUMBER_OF_BYTES-eng: 461089
_STATISTICS_WRITING_APP-eng: mkvmerge v51.0.0 ('I Wish') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-12-21 04:14:21
DURATION : 00:00:05.739000000
encoder : Lavc58.119.100 rawvideo
av_interleaved_write_frame(): Invalid argument
Error writing trailer of pipe:: Invalid argument00:00:00.04 bitrate=16296.2kbits/s speed= 0.4x
frame= 1 fps=0.0 q=-0.0 Lsize= 83kB time=00:00:00.04 bitrate=16296.2kbits/s speed=0.18x
video:83kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
Conversion failed!
poisondeathray
26th February 2021, 04:40
Failure #1
[CODE]ECHO from vapoursynth import core>Mark's.vpy
ECHO video = core.ffms2.Source(source=-)>>Mark's.vpy
ECHO import havsfunc as havsfunc>>Mark's.vpy
ECHO video = havsfunc.InterFrame(video, Preset="medium", Tuning="smooth", InputType="2D", NewNum=60000, NewDen=1001, GPU=True)>>Mark's.vpy
ECHO video.set_output()>>Mark's.vpy
ffmpeg -i INPUT.MKV -vf "...works.skipping..." -f rawvideo - | vspipe --y4m Mark's.vpy OUTPUT.MKV
ffmpeg raw pipe to vpy can be done with vsrawsource
https://github.com/HolyWu/vsrawsource/releases/
But vapoursynth usually is not used to write an output file directly without other libraries, typically you'd pipe to something else to write the final file (such has ffmpeg or similar)
It would look like this
ffmpeg -i "input.mkv" -vf..... -f rawvideo - | vspipe --y4m script.vpy - | ffmpeg -f yuv4mpegpipe -i - ..... "output.mkv"
Where the source filter in the vpy would look something like this. A rawvideo pipe require you to enter dimensions, pixel format, and framerate. yuv4mpegpipe does not. Since you're sending rawvideo from ffmpeg into the vpy script, you have to enter those parameters
video = core.raws.Source("-", width=1920, height=1080, src_fmt="YUV420P8", fpsnum=24000, fpsden=1001)
It would usually make more sense to do the filtering in vapoursynth since you're already using it for interframe, then to ffmpeg to write the final file . Piping back and forth adds overhead (slower, more memory consumption). A simplified workflow, fewer steps is generally preferred, unless there are some ffmpeg operations that you cannot emulate in vapoursynth
And if your desired output is in MKV container , it's still going to have a timebase of 1/1000s
markfilipak
26th February 2021, 06:12
ffmpeg raw pipe to vpy can be done with vsrawsource ...
Thanks for the push. Maybe I can get the rest of the way out of the ditch on my own. I'll try. I'm doing a lot of processing because the source was telecined, then a frame dropped back to 24fps, then a frame repeated back to 30fps... not by me, but I assume by a video engineer who did not have the intermediates -- originals had probably been discarded -- and the engineer needed to integrate the result in with a mix of other telecined material and NTSC video and 30fps progressive. It's a mess, but I can get the original 24fps with just a single frame that's field repeated at 60fps. Whew! I'll need to review the VS functions to see whether there's coverage of all the gymnastics I'm doing in ffmpeg. I doubt I'll be able to do it as, in the ffmpeg filter chain, I have to do a lot of intermediate 'setpts's and 'fps's to get the whole process to work out without mixing up the frame order.
And if your desired output is in MKV container , it's still going to have a timebase of 1/1000s
I would prefer to avoid 1kHz TB until the very end, and a suggestion how I can do that would be very welcome, but I suspect that the ffmpeg filter chain also uses 1kHz TB. I've not been successful getting an answer to the question of decoder/pipeline TB from the ffmpeg devs, and I don't know how to ascertain that answer on my own: I don't read 'C', and I don't know how to probe the filter pipeline.
I've noticed that, with all the processing I do (the gymnastics), the ffmpeg TB winds up being '23.98 tbn' in the stage just prior to interpolating to 60fps. :(
poisondeathray
26th February 2021, 06:49
I'm doing a lot of processing because the source was telecined, then a frame dropped back to 24fps, then a frame repeated back to 30fps... not by me, but I assume by a video engineer who did not have the intermediates -- originals had probably been discarded -- and the engineer needed to integrate the result in with a mix of other telecined material and NTSC video and 30fps progressive. It's a mess, but I can get the original 24fps with just a single frame that's field repeated at 60fps. Whew! I'll need to review the VS functions to see whether there's coverage of all the gymnastics I'm doing in ffmpeg. I doubt I'll be able to do it as, in the ffmpeg filter chain, I have to do a lot of intermediate 'setpts's and 'fps's to get the whole process to work out without mixing up the frame order.
It suspect it would be easier to do in vapoursynth or avisynth without all the pts gymnastics.
I would prefer to avoid 1kHz TB until the very end, and a suggestion how I can do that would be very welcome, but I suspect that the ffmpeg filter chain also uses 1kHz TB. I've not been successful getting an answer to the question of decoder/pipeline TB from the ffmpeg devs, and I don't know how to ascertain that answer on my own: I don't read 'C', and I don't know how to probe the filter pipeline.
I've noticed that, with all the processing I do (the gymnastics), the ffmpeg TB winds up being '23.98 tbn' in the stage just prior to interpolating to 60fps. :(
"-i INPUT.mkv"
When you start with MKV, you start with that 1/1000s timebase. If you're doing other operations that require precise timing instead of rounded timestamps....don't start with MKV. In ffmpeg, a vob from DVD-video , or .m2ts from BD has a tbn of 1/90000s. You can check/verify the timestamps after each step, each filter, by inserting a -vf showinfo . You can set null output and use -report -loglevel quiet
markfilipak
26th February 2021, 07:12
When you start with MKV, you start with that 1/1000s timebase. If you're doing other operations that require precise timing instead of rounded timestamps....don't start with MKV.
Oooooohhhh! I see. I get it now. FFmpeg is using what it's given, eh?
Well, I've been using MKV sources just for development. My eventual sources will all be VOBs and M2TSs.
BTW, ChaosKing included vsrawsource in his distro (which I jumped on), so I can use it 'out of the box' so to speak. :)
You guys have saved my life. I would have committed 'sewercide' by now if it wasn't for y'all.
flossy_cake
26th March 2024, 16:21
Is this bit correct in InterFrame2.avsi?
# Create SuperString
Preset == "Fastest" ? Eval("""
SuperString = "{pel:2,"
""") : Preset == "Fast" || Preset == "Faster" ? Eval("""
SuperString = "{pel:1,"
""") : Eval("""
SuperString = "{"
""")
Because...
"pel:" The accuracy of the motion estimation. Value can only be 1, 2 or 4. 1 means a precision to the pixel, 2 means a precision to half a pixel, 4 - to quarter pixel (not recommended to use).
It sounds like 4 is highest quality, 1 is lowest. I'm assuming by "quarter pixel" they mean subpixel precision?
By the way to anyone reading this who might be wondering how to get InterFrame working in 64-bit Avisynth+ without requiring SVPManager to be running just use the v4.2.0.142 dlls from the link above. InterFrame is basically just presets for SVPFlow - not that this diminishes its usefulness.
Then you can go something like...
InterFrame(GPU=true, tuning="film", preset="medium", Cores=8).Prefetch(8)
I'm not sure if I'm doing the multithreading correctly though, only tested with 576p files so far. My CPU and GPU barely breaking a sweat though - would like to crank up the quality more to see if artefacts can be mitigated further.
edit: okay increasing cores & prefetch to 8 makes 1080p possible now but still quite CPU heavy - I thought this was going to be mostly done on the GPU. Oh well it's still very cool, makes 576p25 streaming service Top Gear episodes look more like broadcast version.
DTL
26th March 2024, 20:06
"It sounds like 4 is highest quality, 1 is lowest. I'm assuming by "quarter pixel" they mean subpixel precision?"
Yes. Also performance greatly depends on pel value so fastest is pel=1 and slowest is pel=4 (quater size of MV length in the inter-samples virtual distance).
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.