60% speed gain using a single ffmpeg command

When upscaling 720x576 using Artemis 2x on my Mac Studio (M1 Max 24 Core GPU) and Mac mini M4 Pro (16 Core GPU), I get around 60% speed gain using my custom command over the standard ffmpeg command used by TVAI (and the TVAI command is with Max Memory set to 10%).

My technique is to stack multiple SD segments together to form a much higher source resolution prior to upscaling, then crop and join the separate the segments afterwards back to a single stream. Some time ago I created a set of scripts to do this but since then I’ve learnt a bit more about ffmpeg. Hence this is now condensed into a single command.

The command below is an example using an MKV from a PAL DVD (720x576). I get ~ 26 FPS on my Mac Studio, compared to ~16 in TVAI; ~ 29 FPS on the Mac mini Pro compared to ~ 18. So plenty fast enough to watch the video in realtime using VLC while it’s processing. There are just 2 variables to set: the frame count for each segment “fc” - 10 seems about right but I don’t know what’s optimal for the TVAI upscaling filter; and the frame rate “fr” which is 25 in this case, accounting for the de-interlacing which I’ve also added.

I invite and encourage the Topaz developers to incorporate this technique somehow in TVAI, or in their custom version of ffmpeg. Even if they don’t, other users might like to use it. After experimenting I found that a stack of 5 segments is optimal. Also by experimenting, I found the optimal Max Memory is ~ 75% for both my Mac Studio and Mac mini Pro.

fc=10 ; fr=25 ; ffmpeg -i ~/desktop/“s1e06 eye of the needle.mkv” -r $fr -filter_complex " \
bwdif=mode=0:parity=-1:deint=0,split=5[1][2][3][4][5]; \
[1]select='lt(mod(n,$fc*5),$fc)', \
setpts=N/($fr*TB)[S1]; \
[2]select='between(mod(n,$fc*5),$fc,$fc*2-1)', \
setpts=N/($fr*TB)[S2]; \
[3]select='between(mod(n,$fc*5),$fc*2,$fc*3-1)', \
setpts=N/($fr*TB)[S3]; \
[4]select='between(mod(n,$fc*5),$fc*3,$fc*4-1)', \
setpts=N/($fr*TB)[S4]; \
[5]select='between(mod(n,$fc*5),$fc*4,$fc*5-1)', \
setpts=N/($fr*TB)[S5]; \
[S1][S2][S3][S4][S5]hstack=inputs=5, \
tvai_up=model=alq-13:scale=0:w=7200:h=1152:blend=0.5:device=0:vram=0.75:instances=1, \
split=5[CS1][CS2][CS3][CS4][CS5]; \
[CS1]crop=iw/5:ih:0:0, \
setpts=(N+floor(N/$fc)*4*$fc)/($fr*TB)[C1]; \
[CS2]crop=iw/5:ih:iw/5:0, \
setpts=($fc+N+floor(N/$fc)*4*$fc)/($fr*TB)[C2]; \
[CS3]crop=iw/5:ih:2*iw/5:0, \
setpts=($fc*2+N+floor(N/$fc)*4*$fc)/($fr*TB)[C3]; \
[CS4]crop=iw/5:ih:3*iw/5:0, \
setpts=($fc*3+N+floor(N/$fc)*4*$fc)/($fr*TB)[C4]; \
[CS5]crop=iw/5:ih:4*iw/5:0, \
setpts=($fc*4+N+floor(N/$fc)*4*$fc)/($fr*TB)[C5]; \
[C1][C2][C3][C4][C5]interleave=nb_inputs=5" \
-c:v prores_videotoolbox -profile:v proxy -pix_fmt p210le -allow_sw 1 \
-movflags frag_keyframe+empty_moov+delay_moov+use_metadata_tags+write_colr ~/desktop/upscaled.mkv

Andy

EDITED to correct the TVAI_UP width from 1440 to 7200

I’m looking through it, and you tried to explain it, but I’m not understanding how this is working.
Are you stacking frames from this
{BA039498-66CC-4450-A229-3BC0A3DFD1C0}
to this?
image

But that can’t be it, since the upscale resolution is scale=0:w=1440:h=1152 and stacking 5 doesn’t fit in a grid.

Does that mean you’re splitting it up in lines like this
image
And upscaling them then joining them back?

Sorry for the confusion. Just to confirm the “stacking” is 5 segments in a row horizontally. However, although it still works as intended with the width set to 1440 in TVAI_UP, it turns out to be just by chance, because the width should indeed be 7200 (720 x 5 and x 2 for the upscale). I’ll now edit that accordingly. Thanks very much for noticing and pointing that out. I think that because the upscaling only works in factors of 2, I’m guessing it used the double height to determine a x2 upscale. My mistake must have been from a copy and paste of a previous ffmpeg command generated by TVAI.

Thanks.

Andy

Thank you. I understand now.
Yeah you can put scale=2 and I think you can leave the height and width out. In my scripts I have them set to 0.

1 Like