markfilipak
6th October 2021, 22:42
Transcoding a mix of TV and telecined video is the hardest task. It is the last piece in my task list. I present the issues, my nomenclature, some ffmpeg, and some issues.
I would appreciate your thoughts and some clues to overcoming the issues.
"fps" means "frames per second", "sps" means "scans per second", "pps" means "pictures per second".
29.9fps[59.9sps] (read: "29.9 fps of 59.9 sps") is interlaced scans (e.g. NTSC).
29.9fps[2-3[24pps]] (read: "29.9 fps of 2-3 pull-down of 24 pps") is hard telecined (2-3 pull-down) cinema.
29.9fps[3-2[24pps]] (read: "29.9 fps of 3-2 pull-down of 24 pps") is hard telecined (3-2 pull-down) cinema.
29.9fps[3-3-2-2[24pps]] (read: "29.9 fps of 3-3-2-2 pull-down of 24 pps") is hard telecined (3-3-2-2 pull-down) cinema.
29.9fps[2-2-3-3[24pps]] (read: "29.9 fps of 2-2-3-3 pull-down of 24 pps") is hard telecined (2-2-3-3 pull-down) cinema.
'c' denotes combed frame, '-' denotes uncombed frame, time flows left to right.
c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c ...Scans: 29.9fps[59.9sps].
- - c c - - - c c - - - c c - - - c c - - - c c - - - c c - - - c c - - ...Hard Telecine: 29.9fps[2-3[24pps]].
- - - c - - - - c - - - - c - - - - c - - - - c - - - - c - - - - c - - ...Hard Telecine: 29.9fps[2-2-3-3[24pps]].
- c c - - - c c - - - c c - - - c c - - - c c - - - c c - - - c c - - - ...Hard Telecine: 29.9fps[3-2[24pps]].
- c - - - - c - - - - c - - - - c - - - - c - - - - c - - - - c - - - - ...Hard Telecine: 29.9fps[3-3-2-2[24pps]].
- - - - - c c - - - - - c c - - - - - - - - - - - c c - - - - - - - c c ...Hard Telecine: Wacky pull-down (seen in a few videos, e.g. "PASSION FISH");
\____________\___(2 combed frames alternate with 5 / 7.. uncombed frames) -- always odd, always 2 combed frames, seemingly random intervals.
c c c c c c c c c c c c c c c c c c c - - c c - - - c c - - - c c - - - ...Mixed Scans+Hard Telecine: e.g. 29.9fps[[59.9sps]+2-3[24pps]].
\
A well cut, 'Hard Telecine' segment always begins with an uncombed frame.
A poorly cut, 'Hard Telecine' segment may suffer 1 or 2 combed frames coinciding with scene change.
For 29.9fps[59.9sps] segments:
SET UNWEAVE=settb=expr=1001/30000,setpts=expr=N,separatefields,split[1][2]
SET FIELD1=[1]select=eq(mod(n\,2)\,0),minterpolate=fps=120000/1001:mi_mode=mci:scd=fdiff,settb=expr=1/120,setpts=expr=N,split[3][4]
SET FIELD2=[2]select=eq(mod(n\,2)\,1),minterpolate=fps=120000/1001:mi_mode=mci:scd=fdiff,settb=expr=1/120,setpts=expr=N[5]
SET BOB=[3]select=lt(n\,2)[6]
SET AFTERBOB=[5]select=gt(n\,1)[7]
SET MERGE=[6][7]tinterlace=mode=merge[8]
SET NEWFIELD2=%FIELD2%,%BOB%,%AFTERBOB%,%MERGE%
SET WEAVE=[4][8]weave[v]
-filter_complex "%UNWEAVE%,%FIELD1%,%NEWFIELD2%,%WEAVE%"
The 2 fields are separated and independently 4x MV converted to 120fps.
As the 1st field stream passes through unaltered, duplicates of its 1st 2 frames are split off.
The 2nd field stream is delayed by 2 frames and merged with the 2 split off frames from field 1. That process, 1, bobs the 1st 2 frames, and 2, shifts field 2's frames to temporally align them with field 1, thereby making progressive frames out of scan fields with zero cosmetic filtering!
The 2 streams are then woven.
For 29.9fps[2-3[24pps]] segments:
-filter_complex "settb=expr=1001/30000,setpts=expr=N,detelecine,minterpolate=fps=120000/1001:mi_mode=mci:scd=fdiff,settb=expr=1/120,setpts=expr=N[v]"
The result is 5x MV interpolation of the detelecined source.
To pull this off, I need a flag, 'combed', so that, after I combine filter graph sections, I know when to switch between them. Cu Selur suggested I try 'tdm.IsCombed' (https://github.com/HomeOfVapourSynthEvolution/VapourSynth-TDeintMod) but I think it scans an entire clip and can't flag segments.
And I'd also like to replace 'minterpolate' with pipes to/from VapourSynth's superior MV interpolation: Super(), Analyse(), SmoothFps(), but I don't know whether a pipe in the middle of a filter graph is possible -- I suspect not -- or alternatively, whether ffmpeg can support 2 filter graphs with to/from pipes between them -- I've never tried 2 'filter_complex's in one ffmpeg command).
I would appreciate your thoughts and some clues to overcoming the issues.
"fps" means "frames per second", "sps" means "scans per second", "pps" means "pictures per second".
29.9fps[59.9sps] (read: "29.9 fps of 59.9 sps") is interlaced scans (e.g. NTSC).
29.9fps[2-3[24pps]] (read: "29.9 fps of 2-3 pull-down of 24 pps") is hard telecined (2-3 pull-down) cinema.
29.9fps[3-2[24pps]] (read: "29.9 fps of 3-2 pull-down of 24 pps") is hard telecined (3-2 pull-down) cinema.
29.9fps[3-3-2-2[24pps]] (read: "29.9 fps of 3-3-2-2 pull-down of 24 pps") is hard telecined (3-3-2-2 pull-down) cinema.
29.9fps[2-2-3-3[24pps]] (read: "29.9 fps of 2-2-3-3 pull-down of 24 pps") is hard telecined (2-2-3-3 pull-down) cinema.
'c' denotes combed frame, '-' denotes uncombed frame, time flows left to right.
c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c ...Scans: 29.9fps[59.9sps].
- - c c - - - c c - - - c c - - - c c - - - c c - - - c c - - - c c - - ...Hard Telecine: 29.9fps[2-3[24pps]].
- - - c - - - - c - - - - c - - - - c - - - - c - - - - c - - - - c - - ...Hard Telecine: 29.9fps[2-2-3-3[24pps]].
- c c - - - c c - - - c c - - - c c - - - c c - - - c c - - - c c - - - ...Hard Telecine: 29.9fps[3-2[24pps]].
- c - - - - c - - - - c - - - - c - - - - c - - - - c - - - - c - - - - ...Hard Telecine: 29.9fps[3-3-2-2[24pps]].
- - - - - c c - - - - - c c - - - - - - - - - - - c c - - - - - - - c c ...Hard Telecine: Wacky pull-down (seen in a few videos, e.g. "PASSION FISH");
\____________\___(2 combed frames alternate with 5 / 7.. uncombed frames) -- always odd, always 2 combed frames, seemingly random intervals.
c c c c c c c c c c c c c c c c c c c - - c c - - - c c - - - c c - - - ...Mixed Scans+Hard Telecine: e.g. 29.9fps[[59.9sps]+2-3[24pps]].
\
A well cut, 'Hard Telecine' segment always begins with an uncombed frame.
A poorly cut, 'Hard Telecine' segment may suffer 1 or 2 combed frames coinciding with scene change.
For 29.9fps[59.9sps] segments:
SET UNWEAVE=settb=expr=1001/30000,setpts=expr=N,separatefields,split[1][2]
SET FIELD1=[1]select=eq(mod(n\,2)\,0),minterpolate=fps=120000/1001:mi_mode=mci:scd=fdiff,settb=expr=1/120,setpts=expr=N,split[3][4]
SET FIELD2=[2]select=eq(mod(n\,2)\,1),minterpolate=fps=120000/1001:mi_mode=mci:scd=fdiff,settb=expr=1/120,setpts=expr=N[5]
SET BOB=[3]select=lt(n\,2)[6]
SET AFTERBOB=[5]select=gt(n\,1)[7]
SET MERGE=[6][7]tinterlace=mode=merge[8]
SET NEWFIELD2=%FIELD2%,%BOB%,%AFTERBOB%,%MERGE%
SET WEAVE=[4][8]weave[v]
-filter_complex "%UNWEAVE%,%FIELD1%,%NEWFIELD2%,%WEAVE%"
The 2 fields are separated and independently 4x MV converted to 120fps.
As the 1st field stream passes through unaltered, duplicates of its 1st 2 frames are split off.
The 2nd field stream is delayed by 2 frames and merged with the 2 split off frames from field 1. That process, 1, bobs the 1st 2 frames, and 2, shifts field 2's frames to temporally align them with field 1, thereby making progressive frames out of scan fields with zero cosmetic filtering!
The 2 streams are then woven.
For 29.9fps[2-3[24pps]] segments:
-filter_complex "settb=expr=1001/30000,setpts=expr=N,detelecine,minterpolate=fps=120000/1001:mi_mode=mci:scd=fdiff,settb=expr=1/120,setpts=expr=N[v]"
The result is 5x MV interpolation of the detelecined source.
To pull this off, I need a flag, 'combed', so that, after I combine filter graph sections, I know when to switch between them. Cu Selur suggested I try 'tdm.IsCombed' (https://github.com/HomeOfVapourSynthEvolution/VapourSynth-TDeintMod) but I think it scans an entire clip and can't flag segments.
And I'd also like to replace 'minterpolate' with pipes to/from VapourSynth's superior MV interpolation: Super(), Analyse(), SmoothFps(), but I don't know whether a pipe in the middle of a filter graph is possible -- I suspect not -- or alternatively, whether ffmpeg can support 2 filter graphs with to/from pipes between them -- I've never tried 2 'filter_complex's in one ffmpeg command).