Tag Archives: mythtv

Converting DVDs for viewing on a tablet, while inlining captions

Previously, I  described how to convert HDTV videos for my EEE Pad Transformer.  Now, I’ll go over something a bit more difficult.

My wife and I have some DVDs of Bollywood films that we enjoy watching.  Aaja Nachle, Om Shanti Om, 3 Idiots, Billu, among others.  These films are mostly in Hindi, but there are English subtitles available.  As we don’t understand Hindi, we watch the movies with the subtitles.  The Android media viewer that comes with the tablet doesn’t have a way to select subtitles from an alternate video stream.

Now, I wanted to make files of these movies that I could watch on the Android tablet.  As noted in the previous article, the resulting files have to be H.264 Baseline profile, and under 2GB in size.

Here’s how I did this.  Note that this procedure required no less than 70 GB of free disk space to hold a large intermediate file, as I wanted to avoid artefacts introduced by running through multiple codecs, so I used a lossless intermediate state.

First of all, I used the MythTV option to rip a perfect copy of the DVD.  That gave me a file, say 3IDIOTS.vob.

Next, I used mencoder to inline the captions directly into the video stream:

mencoder -ovc lavc -lavcopts vcodec=ljpeg:aspect=16/9 \
    -vobsubid 0 -oac lavc -lavcopts acodec=flac \
    -o 3idiots 3IDIOTS.vob

The output file, 3idiots, was, as noted, huge.  It consisted of a lossless jpeg video stream, with the subtitle 0 track overlaid on the video stream itself.

Next, the file had to be converted to H.264 Baseline.  In this case, I decided, rather than setting a qmax, that I would set a bitrate.  That way I could be certain ahead of time what the final size of the file would be, though at the cost of increased trancoding time.  To get a fixed bitrate, it is necessary to run ffmpeg in two passes, once to collect statistics, and the second time to generate the file itself.  Here’s how this is run:

ffmpeg -pass 1 -i 3idiots -vcodec libx264 -vpre fast \
    -vpre baseline -b 1400 -acodec libfaac -ab 64k \
    -ac 2 -ar 44100 -threads 3 \
    -deinterlace -y junkfile.mp4
ffmpeg -pass 2 -i 3idiots -vcodec libx264 -vpre fast \
    -vpre baseline -b 1400k -acodec libfaac -ab 64k \
    -ac 2 -ar 44100 -threads 3 \
    -deinterlace 3idiots.mp4 

The “junkfile.mp4” file can be deleted.  The H.264 file, 3idiots.mp4, came in at 1.8 GB, and was of quite acceptable quality to view on the tablet.

Converting HDTV videos for viewing on a tablet

I have an Android-based tablet computer, the EEE Pad Transformer.  My MythTV computer can record digital over-the-air broadcasts in high definition now that I have put an HDHomerun on my network.  So, it would be nice to be able to transfer some HDTV programs to the Android computer to watch them there while traveling.  The HDTV shows are 1080i, encoded as mpeg2 video, at a bitrate of close to 16000 kbits/sec.

So, what are our constraints?  The Android computer is not powerful enough to play videos without hardware assist, and that hardware assist is only available when viewing H.264 videos encoded with the baseline profile.  It doesn’t work on main profile H.264 videos.  Also, the Micro-SD card that I plug into the tablet must be formatted as VFAT, it isn’t recognized when I reformat it to any more modern Linux filesystems, so our files are going to have to be under 2GB in size.  Also, the Android screen is only 1280×800, so there’s no point copying a 2560×1080 file there, the machine will have to reduce the resolution, we might as well do it before we copy it to the card.

So, a 1 hour show, recorded on the MythTV box, is about 8 GB and in the wrong format.  We convert it in two steps.  First, cut out any commercials and transcode it at high quality.  For network broadcast television that chops off about 25% of the file size, and you probably didn’t want to watch the commercials while sitting on the train/airplane anyway.

Next, it has to be transcoded to H.264 Basline.  This can be done with ffmpeg:

ffmpeg -i PROGRAM.mpg -vcodec libx264 -vpre fast \
-vpre baseline -s hd720 -qmax 30 -acodec libfaac \
-ab 128k -ac 2 -threads 4 -ar 44100 -deinterlace \
PROGRAM.mp4

This takes the HDTV .mpg file from mythtv, “PROGRAM.mpg”, and converts it.  We use the libx264 video codec, fast settings, baseline profile, formatted for a high definition 720 line screen.  “qmax” sets a limit on quality loss, I usually use a value between 25 and 30.  We use the FAAC audio codec at 128kbits/sec, deinterlace the result, and write it to “PROGRAM.mp4”.

The resulting file, about 45 minutes of air time, is about 600 MB in size.

Breaking packages on the MythTV box

As I mentioned earlier, I have a MythTV computer, installed from packages, but I’ve broken some of the packages. Here are some of the issues that I had with the packages, and how I solved them.

Two of the package manager drawbacks I’ve mentioned previously appear here: the one-size-fits-all approach to software packaging, and the failure to receive timely updates.

The MythTV box is on old hardware. Because it has hardware assistance for both MPEG encoding and decoding, I didn’t need a new computer with a fast CPU. The fact that this is old hardware, with a 7-year old BIOS, may be why I had problems, but I found it easier to break the packages than to try to solve the problems under the constraints of the package system.

First, the MythTV box controls an infra-red LED attached to its serial port, allowing it to change the channels on a digital cable box. This requires the use of the LIRC package, and the lirc_serial kernel module. Well, at the time I set this up, the lirc_serial module was having problems with the SMP kernel. The system would generate an oops quite regularly when it wanted to change channels. Looking at the oops logs, I could see that there were problems specifically with SMP. My MythTV box has only one CPU, so I didn’t need an SMP kernel, but because some users will have SMP computers, the KnoppMyth distribution ships with an SMP kernel. I tried to find a non-SMP kernel for the system, without success. So, the easiest way to fix the problem was just to download a recent kernel source tree from kernel.org, copy the configuration file from the Knoppix kernel, and reconfigure it as non-SMP. The spontaneous reboots stopped occurring. The package manager still believes that it knows what kernel is running on the computer, but that isn’t what is really installed.

When I installed the MythTV box, the software was still a bit immature, and a stability fix in the form of version 0.20 came out several months later. I waited a few weeks with no update to the distribution, and no word of when an update might become available. Eventually, I grew impatient and downloaded the source code of 0.20 myself, recompiled it on the MythTV box, and installed it over top of the existing programs.

There was one other impact of the one-size-fits-all approach that caused difficulties with the MythTV box. I was regularly recording a television show between 6:00AM and 6:30AM. A few minutes before the end of the show, the recording would have problems. The audio would break up, and the video would jump. It appeared that the program was losing frames of data, either because it was losing interrupts, or because it couldn’t get the data to the disk quickly enough. Because it happened at about the same time every day, I expected it was probably a cron job. I got a root shell on the box, and asked for the list of all root-owned cron jobs with the command “crontab -l”. This reported that there were no root-owned cron jobs. I mistrusted this result, and did more investigation. As I mentioned in the first post, distribution packagers often break up a configuration file into a set of separate files. They did that with cron jobs, which means that the command-line tool that ought to tell you all about root-owned cron jobs didn’t report the full set of such processes. A bit of digging around in /etc showed that the slocate database update was being run at that time. This process scans the entire disk, making a list of the files on it. While probably useful in a general context, this is an unnecessary operation on an appliance box that isn’t changing, particularly when it results in so much bus traffic that the primary function of the box is degraded. My solution was to change the /etc/crontab file (which is, itself, not viewed by “crontab -l”) so that a cron job would be skipped if there were any users (reported by the ‘fuser’ command) of either of the two video input devices, /dev/video0 and /dev/video1.