I'm digitizing a number of VHS tapes into lossless video files using FFmpeg. How can I optimize my FFmpeg command further in order to come closer to the requested specs below, with the best possible quality?
Target (ideal) lossless specs
- File format: MKV/AVI/MOV/MXF
- Video Codecs: FFV1/JPG2000 lossless/HuffYUV/Dirac/H.264 lossless
- Chroma: 4:2:2
- Pixel size: Rec. 601
- Aspect ratio: 4:3
- Resolution: 720x576
- 25 fps
- Audio: 48Khz/24-bit PCM 48Khz/16
(OS is Ubuntu Studio, CPU has 8 cores)
sudo \ nice --20 \ ffmpeg \ -hide_banner \ -v verbose \ -report \ -err_detect +crccheck+bitstream+buffer+compliant+aggressive \ -fflags +igndts \ -f video4linux2 -thread_queue_size 1024 -i "/dev/video4" \ -f alsa -thread_queue_size 1024 -channel_layout stereo -ac 2 -i "hw:1" \ -vcodec ffv1 -level 3 -threads 8 -coder 1 -context 1 -g 1 -slices 30 -slicecrc 1 \ -acodec copy \ -aspect 4:3 \ -colorspace bt470bg \ -t 00:00:00 \ "NAME_HERE.mkv"
FFmpeg Input streams from capture device:
Input #0, video4linux2,v4l2, from '/dev/video4': Duration: N/A, start: 3909.466392, bitrate: 165888 kb/s Stream #0:0: Video: rawvideo, 1 reference frame (YUY2 / 0x32595559), yuyv422, 720x576, 165888 kb/s, 25 fps, 25 tbr, 1000k tbn Guessed Channel Layout for Input Stream #1.0 : stereo Input #1, alsa, from 'hw:1': Duration: N/A, start: 1673622488.857382, bitrate: 1536 kb/s Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s Stream mapping: Stream #0:0 -> #0:0 (rawvideo (native) -> ffv1 (native)) Stream #1:0 -> #0:1 (copy)
FFprobe streams for sample output video file:
ffprobe -hide_banner sample.mkv Input #0, matroska,webm, from 'sample.mkv': Metadata: ENCODER : Lavf59.27.100 Duration: 00:00:10.02, start: 0.000000, bitrate: 59168 kb/s Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), yuv422p(tv, bt470bg/unknown/unknown, progressive), 720x576, SAR 16:15 DAR 4:3, 25 fps, 25 tbr, 1k tbn Metadata: ENCODER : Lavc59.37.100 ffv1 DURATION : 00:00:10.000000000 Stream #0:1: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s Metadata: DURATION : 00:00:10.016000000
Current command rationalizations
sudo nice --20 ensures that the ffmpeg process is maximally prioritized by the CPU. (Afterwards, I use chown to change ownership of the video file from root.)
err_detect is there to catch any and all errors. Should something come up I restart the digitisation session. Dunno if any of the flags are entirely redundant with one another and/or performance-impacting.
As I understand it, because ffv1 is an "intra-frame" codec and not an inter-frame one, DTS errors should be safe to ignore trough fflags +igndts. (It's fairly common that they pop up during a session and it seems unnecessary to restart because of them.)
Without the excessive thread_queue_size 1024, ffmpeg has a tendency to warn about "Thread message queue blocking"
ffv1 seems to be the most powerful lossless video codec available, and the parameters seems to be the most powerful possible: https://trac.ffmpeg.org/wiki/Encode/FFV1
Input audio is close enough to the target specs (and AFAIK can't be improved anyway) so they're just copied as-is.