AVCHD on Linux

Introduction

In July 2009, I acquired my first HD camcorder, the AVCHD-compatible Canon VIXIA HF S100. However, given the fact that I am no longer a user of Microsoft Windows, this puts me in a more challenging position (or so I thought) when it comes to editing high-definition video.

I have three requirements: First, I'd like to be able to author DVDs of the video I capture. Second, I'd like to have the video in a viewable format on my computer which is cross-platform and will provide good quality with minimal size. Since I cannot play back MTS files directly, I'd like to join these files and transcode them to a resolution comparable to that found on DVD. Finally, at some point I would like to author Blu-ray discs of my home movies using Linux. Although I do not have a Blu-ray player currently, I want to at least be thinking about the problem and how I would go about building the correct file system. The processes required to complete these tasks are discussed below.

About AVCHD

The AVCHD format is just one of many HD formats and was designed for tapeless consumer camcorders. More information is available at Wikipedia's AVCHD article. To be brief, the AVCHD format that is used by the Canon HF S100 consists of the MTS/M2TS container format encapsulating the H.264 video codec and the AC-3 audio codec. H.264 support on Linux has existed for a few years now and so has AC-3. The big question was whether the MTS container could be de-multiplexed and re-multiplexed using open tools. And, from what I can gather, MTS and M2TS are the same format, so re-muxing from MTS to M2TS is a futile exercise.

M2TS and FFmpeg

After doing some initial reading, I found that several efforts were underway to support the AVCHD format in Linux. The first tutorial I came across consisted of converting the MTS files into AVIs through a couple of command-line scripts that someone was kind enough to author and give to the community. After playing around with the M2TS scripts, I found that they required too many steps and didn't fit with my previous video transcoding workflow. I thought that there had to be a better way.

I have been playing around with FFmpeg for some time and am very familiar with its command-line options. I was curious if it supported AVCHD and tried to transcode a couple of clips with the version that came with Ubuntu 8.10. However, I found that although it could partially decode the format, the frame rate was incorrect and produced other artifacts.

After reading through the FFmpeg mailing lists, I found that AVCHD support has progressed substantially since this release. I decided to grab the latest version from the SVN repository and give it a try in my Ubuntu virtual machine.

You may at this point be wondering why I just don't upgrade to the latest Ubuntu (9.04 as of this writing). It turns out there is a problem with X11 (which I believe is Compiz-related) in the newer versions of Ubuntu that conflict with Parallels Desktop 3.0 (which I run on the Mac). Thus, I am stuck with 8.10 at the moment.

After compiling the latest version of FFmpeg, I found that AVCHD just works on Linux. I mentioned previously that one of my goals was to be able to put the AVCHD clips onto a DVD to play back on a standard television. Before the structure of the DVD may be created, the MTS files need to be converted into NTSC-compatible VOB files (MPEG-2 video with AC-3 audio). Below is a Perl script I wrote to take MTS files in the current directory and transcode them to DVD-compatible MPEG files.

#!/usr/bin/perl
# transcode_mts-mpg.pl
use File::Basename;
@files = glob "*.MTS";

foreach(@files)
{
print "$_\n";
`ffmpeg -i $_ -deinterlace -target ntsc-dvd -pass 1 $_.mpg`;
`rm $_.mpg`;
`ffmpeg -i $_ -deinterlace -target ntsc-dvd -pass 2 $_.mpg`;
}

DVD-compatible video may be encoded automatically with FFmpeg's -target flag. However, if you shoot your video in an interlaced format (1920x1080i) and not in progressive segmented frame (PSF) mode (1920x1080p30), a deinterlacing step is necessary. This process completes a two-pass encode.

DVDAuthor

Linux users have access to a very powerful DVD authoring tool called DVDAuthor. A good tutorial can get you started and the documentation is also very helpful for advanced uses, particularly with authoring your own custom menus. These resources are highly recommended for further reading and are beyond the scope of this article.

Once each scene clip is properly encoded as a VOB or MPEG-2 transport stream file, the DVDAuthor XML file is written to generate the DVD file structure. This file also acts as an excellent documentation aid and makes creating an edited version of the DVD in the future simple and easy. It contains paths to the files that will be on the DVD, menu information, and advanced commands allowed by the DVD standard. A simple DVDAuthor XML file is shown below.

<!-- dvdstructure.xml -->
<dvdauthor dest="dvd">
<vmgm />
<titleset>
<titles>
<pgc>
<vob file="00001.MTS.mpg" chapters="0" />
<vob file="00002.MTS.mpg" />
<vob file="00003.MTS.mpg" />
<vob file="00004.MTS.mpg" chapters="0" />
</pgc>
</titles>
</titleset>
</dvdauthor>

Here, two chapters are created for a single title, and the first three clips are grouped together as a single chapter. This file is passed into DVDAuthor issuing the following command:

dvdauthor -x dvdstructure.xml

Building the DVDAuthor XML file can be tedious when you have a hundred or more scene clips on a single DVD. The small Perl script below will list every scene in the current working directory and will output the DVDAuthor XML structure to standard output.

#!/usr/bin/perl
# list_clips.pl
use File::Basename;
@files = glob "*.mpg";

foreach(@files)
{
print "<vob file=\"$_\" chapters=\"0\" />\n";
}

Next, an ISO image must be created for writing to a standard DVD-R.

mkisofs -V "My DVD" -dvd-video -o mydvd.iso dvd/

Finally, burn the ISO with your favorite burning utility and you have just put your AVCHD video clips on a standard, NTSC-compatible DVD! It should also be noted that FFmpeg does not have the best built-in deinterlacer and can result in some strobing artifacts. Thus, if you have experience with mencoder, you may wish to create your VOB files using the Yadif deinterlacer (more on Yadif later).

Creating MP4s

Next, I want to be able to transcode the AVCHD video to a web-compatible format for play back in VLC or QuickTime. I have been transcoding my home video to MPEG-4 video with AAC audio in the past, but have recently been using the superior H.264 video codec along with the MP4 container format.

One utility I highly recommend for transcoding video to this target format is Handbrake. As of version 0.9.3, Handbrake can handle many input formats, including AVCHD's MTS files.

However, Handbrake cannot re-multiplex scene clips, which means that only individual MTS files may be encoded. Thus, unless you have shot your video as a single MTS file, using Handbrake directly will not produce the results you desire.

eac3to and tsMuxeR

In order to join all MTS files as a single MTS file, the container of each MTS file must first be de-multiplexed and the individual streams must be joined. A few utilities exist for this task, but none open source that I could find. Two freeware utilities, eac3to and tsMuxeR can join multiple TS and MTS files. However, when joining multiple streams together, it is possible for video and audio to become out of sync. In the case of AVCHD, this can be a few milliseconds to tens of milliseconds of overlap between each file in the AC-3 stream. Thus, when joining a dozen or so files together, a noticeable sync problem arises in the audio stream if these overlaps are not properly handled.

tsMuxeR (as of 1.10.6) cannot properly deal with this audio overlap problem and merely concatenates all files together. Thus, it is not recommended to use this program to join multiple MTS files together. Thankfully, however, eac3to can be used to properly keep audio/video in sync through many joins. I noted in its standard output, it specifies the audio overlap between each clip in milliseconds. The format for joining multiple streams together is as follows:

eac3to.exe -demux 00000.MTS+00001.MTS+00002.MTS

This command outputs the two stream files that will then have to be multiplexed into a single MTS/M2TS. This is where tsMuxeR comes in.

tsMuxeR has a Linux version which includes a GUI that is written in Nokia's Qt toolkit. Unfortunately, eac3to is not available natively in Linux. In order to de-multiplex the video, I had to run it via Wine, which worked quite well. The eac3to utility includes some advanced features that can make calls to commercial utilities on Windows, but also builds in some open source tools which are sufficient for this process.

It should also be noted that these programs are freeware and are not open source. I was hesitant to use these tools at first because I was unsure whether I could trust the authors of these programs. As it is, I am running them both in a sandboxed virtual machine but have not seen them exhibit malicious behavior. It appears as though the people responsible for these utilities have very genuine intentions and their features and documentation in various forums are numerous. Please use these utilities at your own risk.

Handbrake

As was mentioned previously, Handbrake can now accept many input formats, including MTS files. Now that the files have been properly re-muxed, they can be transcoded to a web-friendly format. I have found that the default settings of Handbrake are quite good. However, I generally make minor tweaks via the Advanced tab (of the H.264 video codec) to include the no-fast-pskip flag, which helps prevent blocking on solid objects such a blue skies. I also resize the 1920x1080 stream to 720x400 with a bitrate of 2000 kbps. One other important feature of Handbrake is its use of the Yadif deinterlacing algorithm. Everything described above can be achieved using a vanilla FFmpeg build except for Yadif. Although slower than many other deinterlacers, it produces much smoother video, making it absolutely necessary for interlaced source material.

Making Blu-ray Discs

The tsMuxeR utility is capable of outputting the file structure of the Blu-ray disc. Even though I do not currently own a Blu-ray burner or player, I hope to use this utility in the future to create single discs of my home movies. I hope to update this article as soon as this happens, as well as my own experience in burning Blu-ray-compatible ISO images under Linux. For me, this is a question yet unanswered.

Conclusion

I have spent a significant portion of my spare time this past month figuring out the best strategy for transcoding HD video on Linux. I hope that you found this article worthwhile and hopefully it saves you some frustration during your next AVCHD video project.