Handbrake encoding, and a rare Quicktime crash
I compiled the latest Handbrake source code a few weeks ago and started testing it out on both my Mac and PC. I’ve got a collection of video that I’d like to have in H.264 format, and I want the files to work on the iPod Touch, iPhone, stream to the Xbox 360, and maintain enough quality to look good on a 40″ television.
Some time scanning the Development Forum yielded a profile which looks on track to become the latest ‘Apple Universal’ profile in the next stable release. The CLI string for the profile is as follows, and I was able to easily get it working on both the Mac and PC:
-e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,auto -R 48,Auto -6 dpl2,auto -f mp4 -X 720 -P -m -x level=30:cabac=0:ref=2:mixed-refs=1:me=umh:no-fast-pskip=1
The preset creates files which are fully compatible with my devices, and although the file size is a little larger than normal, it offers very good quality. The main problem with creating a ‘Universal’ profile seems to be that the portable devices can’t handle the latest candy, which allows the same quality a much smaller file size. Oh well.
An Odd Problem
All of my video worked fine with this profile, with the exception of 3 files. These files would open fine in VLC (Mac/PC, 0.9.9a), Media Player Classic (PC, 188.8.131.52), Windows Media Player (PC, 11), iTunes (Mac, 8.1.1) and Quicktime (PC, 7.6). When opened in Quicktime (Mac, 7.6), they would crash the player every single time. This irked me.
My efforts to fix the problem started with re-encoding from the source using several different compression settings, and this yielded no results. I started looking closely at the source and encoded video with several tools and players, and compared working video with crash-happy video. The only difference I could see was the audio tracks. In all my working video, the audio track was labeled ‘English’; In my crash happy files, the audio track was labeled ‘Unknown’.
I decided to try forcing the language to English at encode time using Handbrake’s CLI options. This allowed me to change the label for the language, but didn’t do anything to help the problem. Next, I tried remuxing the files using MP4Creator and its GUI front end MP4Muxer; That helped just as little.
I now suspected one or more audio tracks were being tagged with improper language codes, so I read up on the Quicktime Container spec. Each mp4 file contains a moov/trak/mdia/mdhd atom for each video and audio track, along with 2 bytes of language data for each atom. Using MP4Muxer, I opened the working and non-working files to compare the atoms. For all working mp4 files, the atoms for the audio tracks was
0x15c7. For my crash-happy mp4 files, atoms were
0x55c4. I figured that changing this value would fix things, but I wasn’t entirely sure it was possible with MP4Muxer. I was also curious as to what these values actually meant.
According to the container specification, the language code’s 2 byte value contains a 3 digit language code. The code follows the ISO 639 language codes, and to save space it splits the 16 bytes into three 5 bit blocks; Each block represents a letter of the country code, using the ASCII value of the letter minus
0x60. The short of it is, 1=a, 2=b, and so on. If you take the
0x55c4 value from my probe, you get
10101 01110 00100 in binary. Broken into groups of 5 bits and converted to letters, and you get
00100=4=d, or ‘und’ as our 3 digit code. This is the special code for undetermined, and apparently the cause of my problems. Applying the same process to the
0x15c7, we get ‘eng’ as our language code, for English.
I found another muxer called MP4Box, which supports language codes. Running this simple command took seconds, and rewrote the language code for all my crash-happy files:
mp4box -lang en VideoFile.m4v
Presto, the files no longer crash Quicktime (Mac, 7.6)! I later discovered a tool from Apple called Dumpster that allows both browsing and editing the container data. I tried fixing the language codes for the audio tracks of a file using this tool, and it worked equally well.
I’m not entirely sure who’s at fault here. Is the creator of the source video at fault for not tagging the audio tracks with a language? Is Handbrake at fault for not forcing English as a default when an undefined audio track is found? Or is Quicktime (Mac, 7.6) at fault for crashing trying to open a file with an undefined audio track? I’m inclined to call Quicktime (Mac, 7.6) out on this one here, as every other program I tried had zero problems.