h264/README.md

2.1 KiB

H264 transcoder with RPi4 hardware acceleration

This is a shell script to transcode video files to h.264. It handles audio and subtitles gracefully.

It uses the Raspberry Pi's hardware acceleration (h264_v4l2m2m codec) to encode the h.264 files.

I don't know if the ffmpeg code is immature, or if I just don't understand ffmpeg, but this codec demands some special treatment, which this shell script provides.

h264_v4l2m2m Special Treatment

Here are the h264_v4l2m2m quirks I've identified (February 2023):

  • The codec will not write into a .mkv container, but it will write into a .mp4 or .nut container.
  • The codec does not play well with subrip subtitles, making it look like you don't have enough capture buffers. You will never have enough capture buffers: you have to stop trying to copy over subtitles.
  • -crf value, if set, is ignored: you must use -b:v.

The solution this script uses is to transcode video and audio into an intermediate .nut file. Then it combines the .nut file, and any subtitles from the original file, into a new .mkv file. Since the "copy" video codec is used in the second step, everything works properly.

Doing things in two steps adds a little bit of time, but in my experience, the hardware transcoder is so much faster, the second step time isn't a problem. I see ffmpeg reporting running at speed=84x and higher on the second step.

Thanks

Thank you to Will Usher, who figured out how to get the codec working at all. Without Will's helpful blog post I would still be fighting with ffmpeg trying to make it use hardware acceleration. Will also wrote the FBED batch transcoder, very similar to this. You might try it out if you don't like this script.

I created this simpler shell script mainly to avoid Python package dependencies: FBED needed an ffmpeg library that I had to patch before it would run. I wound up having to fiddle with ffmpeg so much dealing with the codec quirks, that working in Bourne shell made things much simpler as I chased down the subtitle problems.