Well, I've spent a long time trying to figure out an effective way of archiving content. Here's the scenario: you've got a DVR, you've got Netflix, you've got home videos, how do you store it all? I've decided that an MPEG-4 is the way to go over Windows Media. The reason is simple, in the IPTV world, MPEG-4 and UDP streaming dominates. For the home I can argue it makes sense as well.
First, MPEG-4 compression is good. It'll eventually be as good if not better than WMV9 Advanced Profile and VC-1. Second, if you have any device that's not based on Micro$oft, most likely it will be able to play some kind of MPEG-4 variant. Examples: Quicktime and DivX are MPEG-4. Third, MPEG-4 encoders and players can be found for free (especially the open source ones).
Anyway, let me get right to it. I use H.264 for the following purposes:
- Backing up my DVDs
- Recording television shows
Conventions
- # - means execute the command as the root user
- $ - means execute the command as a normal user
When I back up a DVD, I only store the main movie title. Remember DVDs can have many titles and chapters. I don't really want all the out-takes, deleted scenes, etc. If I do, then I buy the DVD ;-). So, step 1 is to "rip" the VOB file from the DVD. This means we take all of the chapters associated with the main movie title, decrypt them, and store them in a single VOB file on disk. There are several tools to do this (including one I wrote myself based on MythDVD). The most readily available one is vobcopy.
Prerequisites
The following tools are required:
# yum install vobcopyNote: transcode brings ffmpeg with it, which is what we use for the transcoding. You may have to add freshrpms to your YUM repository configuration. Also potentially ATrpms. You should be able to Google and figure out how to add those. If not, email me and I'll post directions.
# yum install transcode
Make sure you have x264 installed:
# yum install x264Big fat note: I had to recompile ffmpeg because the one that comes from freshrpms didn't have H.264 support built in.
Ripping & Transcoding
Now, using vobcopy, rip the main movie title. I am currently using Fedora Core 5 with the following vobcopy command:
$ vobcopy -lThat's an "ell" argument meaning large file support. This tells vobcopy to create a single, large output VOB file. You should be able to tell where the resultant VOB file gets created. So for the sake of an example, I'm working on transcoding "The Girl Next Door" while I write this, so I'll use it for illustrative purposes. Here is the resultant VOB file that got created:
$ ls -l GIRL*Pretty big file eh? You can see how easy it is to chew up your entire hard disk storing DVDs in MPEG-2 Program Stream format (VOB).
-rw-r--r-- 1 mythtv mythtv 4.2G Apr 23 14:56 GIRL_NEXT_DOOR_UNRATED_1691.vob
Let's using a transcode tool and get familiar with what we are working with:
$ tcprobe -i GIRL_NEXT_DOOR_UNRATED_1691.vobSo, we've got one video track, and 4 audio tracks. That's how DVDs have the ability to play in English, French, Spanish, with Director's commentary, etc. We don't need all that; we only want the English track. Fortunately, the first audio track for DVDs in North America is the English one, so when we transcode, things tend to work out by default. But, if you want to save a different audio track instead of the first one, I recommend using tcdemux to remux the VOB file with only the specific audio track you need. I will do this for illustrative purposes by creating a new VOB file with only the English audio track.
[tcprobe] MPEG program stream (PS)
[tcprobe] summary for GIRL_NEXT_DOOR_UNRATED_1691.vob, (*) = not default, 0 = not detected
import frame size: -g 720x480 [720x576] (*)
aspect ratio: 16:9 (*)
frame rate: -f 29.970 [25.000] frc=4 (*)
PTS=0.1977, frame_time=33 ms, bitrate=9800 kbps
audio track: -a 0 [0] -e 48000,16,2 [48000,16,2] -n 0x2000 [0x2000]
PTS=0.1977, bitrate=448 kbps
-D 0 --av_fine_ms 0 (frames & ms) [0] [0]
audio track: -a 1 [0] -e 48000,16,2 [48000,16,2] -n 0x2000 [0x2000]
PTS=0.1977, bitrate=192 kbps
-D 0 --av_fine_ms 0 (frames & ms) [0] [0]
audio track: -a 2 [0] -e 48000,16,2 [48000,16,2] -n 0x2000 [0x2000]
PTS=0.1977, bitrate=192 kbps
-D 0 --av_fine_ms 0 (frames & ms) [0] [0]
audio track: -a 3 [0] -e 48000,16,2 [48000,16,2] -n 0x2000 [0x2000]
PTS=0.1977, bitrate=192 kbps
-D 0 --av_fine_ms 0 (frames & ms) [0] [0]
$ tcdemux -i GIRL_NEXT_DOOR_UNRATED_1691.vob -A 0xe0,0x80 > GIRL_EN.vobNotice how we saved about 500MB simply by stripping out the non-English audio tracks? Anyway, now if we tcprobe GIRL_EN.vob, you can see the simplified format:
0=0xe0 1=0x80 2=0x0 3=0x0 4=0x0
$ ls -lh GIRL*.vob
-rw-rw-r-- 1 mythtv mythtv 3.7G Apr 23 15:19 GIRL_EN.vob
-rw-r--r-- 1 mythtv mythtv 4.2G Apr 23 14:56 GIRL_NEXT_DOOR_UNRATED_1691.vob
$ tcprobe -i GIRL_EN.vobIn my mind anyway, this makes things a lot easier to work with. Oh, and I should mention, there is NO LOSS in running tcdemux to create GIRL_EN.vob. Remember a VOB file is a container format and we simply removed some of the contents, but we didn't actually do any video or audio conversion whatsoever.
[tcprobe] MPEG program stream (PS)
[tcprobe] summary for GIRL_EN.vob, (*) = not default, 0 = not detected
import frame size: -g 720x480 [720x576] (*)
aspect ratio: 16:9 (*)
frame rate: -f 29.970 [25.000] frc=4 (*)
PTS=0.1977, frame_time=33 ms, bitrate=9800 kbps
audio track: -a 0 [0] -e 48000,16,2 [48000,16,2] -n 0x2000 [0x2000]
PTS=0.1977, bitrate=448 kbps
-D 0 --av_fine_ms 0 (frames & ms) [0] [0]
Anyway, I think it's time to starting creating our H.264 content. With the toolset currently available, and the state of players on Linux and on Windows, it's my opinion that the AVI container format, H.264 video codec, and MP3 audio codec is the way to go. Now I should also mention that personally I'm trying to figure out a MPEG-2 Transport Stream format, H.264 video codec, and AC3 audio codec. The reason being that I want to be able to stream this content to an H.264 capable Set Top Box (STB) such as the Amino A124. So, I'll show how to create both formats here, but I have to point out that I can't figure out how to smoothly play the MPEG-2 TS format on XP or on Linux. Perhaps the TS output of ffmpeg isn't as good as it could be?
Format: AVI / Video Codec: H.264 / Audio Codec: MP3
Fortunately for us, ffmpeg rules, and this can all be done in one step. The only really important thing to decide on it the quality. I've come up with the following guidelines:
- Near-lossless: video bitrate: 5872kbps, audio bitrate: 128kbps (total 6Mbps)
- Excellent: video bitrate: 3872kbps, audio bitrate: 128kbps (total 4Mbps)
- Good: video bitrate: 2872kbps, audio bitrate: 128kbps (total 3Mbps)
- Fair: video bitrate: 1872kbps, audio bitrate: 128kbps (total 2Mbps)
- Poor: video bitrate: 1372kbps, audio bitrate: 128 kbps (total 1.5Mbps)
Anyway, let's make this happen. But not so fast, let's create a sample file that will encode pretty quick to give us a general idea of what the output will look like:
$ ffmpeg -i GIRL_EN.vob -f avi -b 2872 -vcodec h264 -g 300 -bf 2 -acodec mp3 -ab 128 -t 60 GIRL_EN-Good-sample.aviThis command can take a really long time. If you are transcoding at 2-4 frames per second, it won't finish for 8-12 times the length of the movie. Here's where CPU power really comes in handy. Let me explain a bit about what's going on in the above command:
- -i GIRL_EN.vob: should be obvious, specify the input file
- -f avi: force the output format to be AVI
- -b 2872: attempt to maintain a video bitrate of 2872 kbps
- -vcodec h264: use the H.264 video encoder (a la x264)
- -g 300: use a GOP size of 300
- -bf 2: use 2 b-frames (I have to understand this one more)
- -acodec mp3: use the MP3 audio encoder (a la lame)
- -ab 128: use an audio bitrate of 128 kbps
- -t 60: create a sample that's 60 seconds long
- GIRL_EN-Good-sample.avi: should be obvious, the output file
$ ffmpeg -i GIRL_EN.vob -f avi -b 2872 -vcodec h264 -g 300 -bf 2 -acodec mp3 -ab 128 -pass 1 /dev/nullThe differences between these commands and the previous one that generated the sample are:
$ ffmpeg -i GIRL_EN.vob -f avi -b 2872 -vcodec h264 -g 300 -bf 2 -acodec mp3 -ab 128 -pass 2 GIRL_EN-Good.avi
- -t
was removed because we wan't to transcode the entire movie now - -pass 1 /dev/null: for pass 1 don't bother saving the output, write it to the null device
- -pass 2 GIRL_EN-Good.avi: for pass 2, save the output
Anyway, once the above command completes, you should have an AVI file of your movie.
Format: MPEG-2 Transport Stream / Video Codec: H.264 / Audio Codec: AC3
We can use the same quality guidelines as defined in the previous section. Let's create the sample:
$ ffmpeg -i GIRL_EN.vob -f mpegts -b 2872 -vcodec h264 -g 300 -bf 2 -acodec copy -t 60 GIRL_EN-Good-sample.tsThe noteworthy differences here are:
- -f mpegts: create an output MPEG-2 Transport Stream
- -acodec copy: copy the source audio track as-is to the output file. For a DVD, this basically means we preserve the original Dolby 5.1, AC3 format
- .ts: use a .ts file extension denoting this file is a transport stream
Conclusion
The future is definitely H.264. There is so much momentum behind it right now, I just don't see VC-1 catching up. Especially in Europe and South America where H.264 is spreading like wild fire.
I should have probably put this closer to the top, but I've create a Perl program to simply the transcoding step. Vob2h264.pl does the work of creating the sample, and doing the 2-pass encoding. The only thing you need to tell vob2h264.pl is the bitrate, and output format.
http://mandalore.dyndns.biz/svn/public/mythtools/helpers/vob2h264.pl
Please let me know if you have any questions, comments, or suggestions.