Skip to content

video transcoding notes

Published: at 04:45 PM

meta

These are some notes gathered on my exploration of transcoding videos for more reliable playback. This doesn’t cover the downloading of the video files; just post-processing them into different formats for playback, primarily on an Apple TV 4k (2019).

Hardware used:

overview

The main take-aways are:

Donmelton’s other_video_transcode tool

Use this script to generate an ffmpeg command that can be executed on another system, if needed.

https://github.com/donmelton/other_video_transcoding

This is basically an easier-to-understand wrapper for ffmpeg. Install ruby, then install this with ruby gems. It’s helpful to read the script to get a better understanding of all the options and how they map to ffmpeg params.

It requires ffmpeg and the mkvtoolnix-cli packages.

Example with libx265 (software/CPU transcode):

other-transcode \
  --target 12000 \  # there are defaults for each resolution, but imo they're too low
  --x265 \  # change this to VAAPI for gpu hw transcode
  --hevc \  # no point in not doing HEVC 
  --mp4 \   # imo it's widely enough compatible.
  great for appleTV
  --add-audio all \  # without this, the default will strip out all the extraneous audio
  --add-subtitle eng \
  </path/to/file.mkv> \
  -n # "dry run" (just prints the ffmpeg commmand)mi

Example with iGPU (hardware accelerated transcode):

other-transcode \
  --vaapi \  # this is a reliable api for linux + intel w/ iGPU (QuickSync)
  --target 12000 \  # VAAPI doesn't have an easy equivalent of CRF ; this should be tweaked per title
  --hevc \
  --add-audio all \
  --add-subtitle eng \
  </path/to/file.mkv>  # note: omitted --mp4 here because of subtitle incompatability

[Feb 19, 2022] - there is currently a bug in intel-media-driver that results in corrputed video output when using VAAPI (intel iGPU hw accelerated transcode).

[Feb 20, 2022] - went down the rabbit hole of manually building libva, intel-media-driver (and all intermediate dependencies, yikes!) and ffmpeg with this patch.

example ffmpeg command that is generated:

ffmpeg -loglevel error -stats -vaapi_device /dev/dri/renderD128 \
  -i /media/movies/Honeyland\ \(2019\)/Honeyland\ \(2019\)\ Remux-1080p.mkv \
  -map 0:0 -filter:v yadif,format\=nv12,hwupload -c:v hevc_vaapi -b:v 9000k \
  -color_primaries:v bt709 -color_trc:v bt709 -colorspace:v bt709 \
  -metadata:s:v title\= -disposition:v default -map 0:1 -c:​a:0 ac3 \
  -metadata:s:​a:0 title\= -disposition:​a:0 default -map 0:2 -c:​a:1 aac \
  -metadata:s:​a:1 title\= -disposition:​a:1 0 -sn \
  -metadata:g title\= -default_mode passthrough \
  Honeyland\ \(2019\)\ Remux-1080p.mkv

general ffmpeg param structure:

ffmpeg -i <input file> \
	-stats \
	-<extra params> \
	<output_file_name>

(likely rare), but remux + transcode BR disk .iso rip:

https://unixsheikh.com/tutorials/remuxing-iso-dvd-or-bluray-using-cat-and-ffmpeg-on-linux.html

essentially, the process is 1) mount the iso, find the correct m2ts file, combine them if necessary, then ffmpeg to package it up into .mkv and transcode if desired. Here’s an example of processing Apollo 11 blu-ray full disk:

  ffmpeg -i br/BDMV/STREAM/00006.m2ts -stats -map 0:0 -pix_fmt yuv420p10le -c:v libx265 -x265-params profile=main10:crf=20 -tag:v hvc1 -map 0:​a 'Apollo 11 (2019) Remux-2160p.mp4’

using CRF for 4k main10:

nohup ffmpeg -loglevel error -stats -i ../Jojo\ Rabbit\ \(2019\)\ Remux-2160p.mkv \
  -map 0:0 \
  -c:v libx265 -pix_fmt:v yuv420p10le -crf 17 -preset slower \
  -color_primaries:v bt2020 -color_trc:v smpte2084 -colorspace:v bt2020nc \
  -metadata:s:v title\= -disposition:v default \
  -map 0:1 -c:​a:0 ac3 -metadata:s:​a:0 title\= -disposition:​a:0 default \
  -sn -metadata:g title\= -default_mode passthrough \
  Jojo\ Rabbit\ \(2019\)\ Remux-2160p.mkv &

{{< lead >}} Quality checking the transcoded output is essential. {{< /lead >}}

further reading

https://codecalamity.com/encoding-settings-for-hdr-4k-videos-using-10-bit-x265/ - tl;dr CRF 20 preset slow

Apple TV 4k hevc - Use the -tag:v hvc1 parameter in your FFmpeg command make your HEVC file work on Apple devices.

https://codecalamity.com/stop-re-encoding-videos/

https://slhck.info/video/2017/02/24/crf-guide.html

https://netflixtechblog.com/per-title-encode-optimization-7e99442b62a2 - very interesting. Big takeaways are:

  1. every netflix title is considered to have its own optimal bitrate + quality level for each resolution
  2. Lower resolution + higher precision can result in greater quality than higher res + lower precision, but mostly at the low side of the quality curve.
  3. netflix stores multiple encodes per resolution, per title. Storage tradeoff gives bandwidth + user experience wins

Using VAAPI’s hardware accelerated video encoding on Linux with Intel’s hardware on FFmpeg and libav

still TODO / open questions