Video Encoding on a Quad Core – mp4, h264, meGUI, Linux, ffmpeg – Part 2

Posted on August 19th, 2007 in Audio,Software Development by andrija

If you want to encode video on Linux, you’re in for a world of pain. Let’s compare encoding a video file to crossing a river. Expect to have to generally learn how to build a bridge to cross to the other side – and then build it. As opposed to – at the very worst – following the instructions on how to build a bridge if using Windows, or more likely just walk right across it, as someone else probably built it and left it there already. In Linux, someone probably built the bridge before you too, but they either built it right for their specifications or they teared it down so for anyone coming afterwards it’s as it was never built in the first place.

In other words, expect to have to compile stuff yourself, apply patches and spend many hours if not days experimenting rather than being productive.

The attraction is that you hopefully can use 64-bit operating system and applications and utilize the full power of the processor, including multithreading. In practice though, things are not what they seem.

There is only one program that will actually encode a video to H.264: it’s called X264. That’s not a problem – it’s the best of its kind, comparing favourably to commercial software, and is what Windows programs use too. The problem is that if you have a multicore cpu, it will likely not utilize it nowhere near its full potential. For dual core machines differences are not drastic and is probably the reason why it slipped under the radar, but for a quad core it is very important to apply this patch. Read here why – if you have patience. I am uncertain whether this problem affects Windows – but the author mentioned that his problems occur in Linux only, so it could be an issue with how the X.264 author coded threading for Linux. Windows users score another one.

That’s not all though. There are more patches that affect the video quality. In the video I encoded there were noticeable blocking artifacts in the dark background, making the scene look ugly and last generation (macroblocks were endemic on mpeg1 and mpeg2, especially if the bitrate was low). Unfortunately there is no easy solution other than increasing the bitrate too high for my taste (say to 3000kb/s for this particular sequence – I’d prefer 2000kb/s or even less). There is however a fairly well accepted solution – adaptive quantization which can be added with this AQ quality patch. This patch adds adaptive quntization options to the command: –aq-strength and –aq-sensitivity . Alas, not even this one is without problems and needs a patching of its own. However, while this patch works if you’re using X.264 directly, it is useless if the front end doesn’t support it, that being ffmpeg or mencode. Unfortunately that makes this patch only a step above useless, unless you’re willing to complicate your life yet even more. Here’s how you would go about doing that.  I will provide an example as well, later on.
However, all of these are (probably) already compiled into Windows programs, thanks to their agile development teams and large communities. This is the trouble with Linux. With Windows someone else is going to do it for you. With Linux, it’s all up to you. It used to be the case that the tradeoff was worth it – you would gain a lot of flexibility and power by moving to Linux and learning how to do things yourself. This is not the case any more – if you use meGUI or some other tool, you’ll have no less flexibility yet much more convenience – and perhaps even speed and quality.

It is rare to use X.264 directly. That’s because it’s an encoder, not a mixer and not a general purpose tool. It expects its data to be in raw YUV format and it will output it unwrapped (as in, not in a container). It does not deal with any kind of audio (obviously), nor it knows anything about mp4 container which is where you want the output to end up packaged into. Therefore you will be using either ffmpeg or mencoder. Those aren’t front ends but kind of a swiss knife tools that can (de)multiplex video and audio from and to various containers, use filters to resize and pre- or postprocess, deinterlace, pulldown or pullup and so on.

Unfortunately neither of these tools is the “one size fits all”. That isn’t a problem either as diversity is good. The real problem is: each of those damn tools uses its own syntax to define parameters that will be used with X.264! Yes, you read it right: even though all they do is pass those parameters to underlying X.264, each of them has its own way of defining it. Not only that, but for many parameters it is not obvious which parameter in one tool corresponds to the one in other tool! Tell me that there is a good reason that an option called “bime” in mencoder needs to be called “bidir_refine 1” in ffmpeg! Especially since neither project is using its own implementation of the standard – they both will translate and pass the same thing to X.264. Unbelievable! It’s a stunning display of worst that open source can deviate into – an anarchy, a number of groups that each goes its separate way, oblivious – or worse – to others doing the same thing. Whatever the reason, the end result is even more suffering on top of pain already inflicted with this complicated subject matter.

Anyway, the fact that you had to compile x.264 unfortunately means that you’ll have to recompile mencoder and ffmpeg too. No thanks to seemingly hard linked dependencies. It’s not enough to just disable the system-supplied X.264 and install your own; the tools that depend on it will stubbornly want the other version. Whatever happened to dynamic libraries? Oh, who knows, in the end you’ll have to compile stuff yourself anyway and it’s probably for the best since it’s likely whoever compiled the os-supplied versions disabled a bunch of features that you’ll need.

More to come, but I post this anyway to make sure I don’t forget or lose these commands.

Here is a command for two pass encoding which creates a PSP playable file. You can use it if you have say an anime fansub in an avi file. Adjust the frame rate if necessary. It will produce a big file, possible a little bigger than the one you started with! The quality will be excellent but it will be overkill – H.264 is more efficient than even XviD so it makes no sense to use higher bitrate than you began with, especially since you’re probably resizing the picture down!

ffmpeg -i $1 -y -r 23.98 -s 480×272 -vcodec libx264 -acodec libfaac -f mp4 -b 1000k -maxrate 4000k -coder ac -flags loop -flags2 +wpred+mixed_refs+brdo -level 21 -subq 6 -refs 2 -bf 3 -bidir_refine 1 -ac 2 -ab 160k -trellis 1 -threads 0 -pass 1 -partitions +partp8x8+partb8x8+parti4x4+partp4x4-parti8x8 $1.mp4

ffmpeg -i $1 -y -r 23.98 -s 480×272 -vcodec libx264 -acodec libfaac -f mp4 -b 1000k -maxrate 4000k -coder ac -flags loop -flags2 +wpred+mixed_refs+brdo -level 21 -subq 6 -refs 2 -bf 3 -bidir_refine 1 -ac 2 -ab 160k -trellis 1 -threads 0 -pass 2 -partitions +partp8x8+partb8x8+parti4x4+partp4x4-parti8x8 $1.mp4

And here is the command that can do that in one pass and will produce much smaller file. Change crf to higher value to compress more, or lower value to compress less. Value of 20 is typical.

ffmpeg -i “$1” -y -r 23.98 -s 480×272 -vcodec libx264 -acodec libfaac -f mp4 -maxrate 4000k -coder ac -flags loop -flags2 +wpred+mixed_refs+brdo -level 21 -subq 6 -refs 2 -bf 3 -bidir_refine 1 -ac 2 -ab 128k -trellis 1 -threads 0 -crf 22 -partitions +partp8x8+partb8x8+parti4x4+partp4x4-parti8x8 -t “$1” “$1”.mp4

There a few things to remember regarding PSP encoding: you can use up to 3 B frames, up to 2 reference frames and you cannot use B Pyramid. You must not use adaptive spatial transform 8×8 matrix (a High profile feature) nor I 8×8 partition. You also need to specify frame rate (in the example above it’s 23.98) because your video will not play if it’s longer than few minutes. You also need to take care to set the level appropriately (I believe you can use level 3.0 if you want to use higher 720×480 resolution though I can’t see a good reason to do so, other than perhaps ability to use the same file on PS3). And be sure to use one of newer firmwares (3.30 or higher) as some features weren’t supported in earlier versions.

On the other hand, to encode a ripped DVD file with two-pass for PS3 use the command below. This page provides details about the video acquisition (ripping, deinterlacing etc). In the case below, I had an anamorphic 1:2.35 movie shot in 24fps and provided at circa 60Hz with 3:2 pulldown. This is probably going to be most common case if you watch a lot of mainstream movies. If you do have special needs and say need to deal with deinterlacing, read here. Anyhow, adjust the crop parameters as per this guide and adjust map parameters to use the audio stream that you want (e.g. english 5.1 DTS). Use mplayer to find out what is what.
ffmpeg -map 0:0 -map 0:1 -i input.mpg -y -croptop 62 -cropbottom 66 -cropleft 0 -cropright 0 -padtop 62 -padbottom 66 -vcodec libx264 -acodec libfaac -title “Random DVD” -f mp4 -coder ac -b 2000k -bufsize 10000k -maxrate 25000k -g 300 -level 41 -ac 2 -ab 172k -flags2 dct8x8+bpyramid+brdo+wpred+mixed_refs -refs 5 -bf 3 -me umh -subq 6 -trellis 0 -directpred auto -flags +loop -deblockalpha -2 -deblockbeta -1 -partitions +partp8x8+partb8x8+parti4x4+parti8x8 -threads auto -pass 1 output.mp4

ffmpeg -i input.mpg -y -map 0:0 -map 0:1 -y -croptop 62 -cropbottom 66 -cropleft 0 -cropright 0 -padtop 62 -padbottom 66 -vcodec libx264 -acodec libfaac -title “Random DVD” -f mp4 -coder ac -b 2000k -bufsize 10000k -maxrate 25000k -g 300 -level 41 -ac 2 -ab 172k -flags2 dct8x8+bpyramid+brdo+wpred+mixed_refs -refs 5 -bf 3 -me umh -subq 6 -trellis 0 -directpred auto -flags +loop -deblockalpha -2 -deblockbeta -1 -partitions +partp8x8+partb8x8+parti4x4+parti8x8 -threads auto -pass 2 output.mp4

The example below might not be as good as it can be – you could end up with some macroblocking in dark areas. As mentioned before, you might want to use adaptive quantization to deal with that, unfortunately that means using X264 directly.  The script below will do that.

rm tmp.fifo.y4m
mkfifo tmp.fifo.y4m
ffmpeg -y -i input.mpg -croptop 62 -cropbottom 66 -cropleft 0 -cropright 0 -map 0:0 -f yuv4mpegpipe -t 50 -an tmp.fifo.y4m & x264 -o output.mp4 –fps 59.94 –threads auto –progress –ref 5 –bframes 3 –b-pyramid –level 4.1 –sar 1:1 –b-rdo –mixed-refs –8x8dct –partitions all –direct auto –weightb –trellis 0 –aq-strength 0.8 –aq-sensitivity 17 –crf 20 tmp.fifo.y4m 720×352

The script will only deal with video – you will need to extract audio track separately (using mencode or ffmpeg) and then multiplex them together using mp4box.  Painful, to say the least.

Things to remember about PS3: make sure to set the level to 4.1 or 4.2. A lot of tweaking can be done above, I’ll get on that later.

Video Encoding on a Quad Core – mp4, h264, meGUI, Linux, ffmpeg – Part 1

Posted on August 18th, 2007 in Audio,Software Development by andrija

On July 22, 2007 Intel executed massive price cuts on their entire processor line. I decided that enough is enough and finally bought myself one of those new processors. The best value for connoisseur right now is quad core chip – the Q6600. I even managed to get the new-as-of-July-16th G0 revision, but that’s a story for another day. The story for this post is about what can be done with such a power. Of course, I buy new hardware just because but there is one reason which does make sense – and that is video encoding.

Now comes the punchline – I am not a big fan of movies. That might be a shocking revelation to some of my friends. After all, my shelves are overflowing with 300 odd DVDs of all sorts and genres. Let’s not dwell upon this though as it’s yet another story for another time (why don’t I post these in my blog? Another story). The real question here is why would one want to encode video at all? If one owns original DVDs, one has no need for Divx, mpeg4 or whatnot, right? So why compress your content if you’re don’t have to?

Because you might want to watch your content on the go. Say, on an iPod or PSP or some lesser know (though probably more powerful) portable video device. Personally, I only need that when I’m traveling which is luckily only once or twice a year at most.

The other reason to do some video encoding is if you need to deal with a device that can’t play the content in its original format, such as PS3. This case may occur on a more regular basis and it might also require real-time (on demand) transcoding. It depends on what you’re trying to do. You might want to keep all of your content in one place, such as PS3’s hard drive. If your content is diverse or numerous, that may not be practical. In that case you might want to be able to stream your content from whatever storage server you have to your PS3.
As a media hub, a general purpose PC can’t be beaten. It can play just about anything and it can always be upgraded with software or hardware to do stuff it couldn’t do previously. There’s nothing more flexible than a general purpose computer. But a computer may not be the best ergonomic choice – a standalone player with its customized remote is almost always easier to use and faster to operate. Unfortunately, exactly because it’s customized, the standalone player is not going to be able to handle everything. That’s why it’d be good to have a PC that can transcode in real time, on demand into any format you need. A quad core surely can do it, can’t it?

Now you’re talking: this is the real reason for all this experimentation. I don’t really care whether PS3 can play an odd anime fansub Divx file I may have – whenever content I want is available to buy, I buy and since I demand the utmost quality possible I use BluRay or DVD or HD-DVD for my video fix anyway. I will just use the HTPC for the odd file and live with some inconvenience. It’s about the challenge and the “call of technology” – I want to feel the power of this processor and will invent a reason to stretch its legs, if necessary. And I want to learn how things work – that’s what drives me in life.

So with all that out of the way, let’s talk about the real thing – how to encode videos for PSP (or PS3). At their best, these things are using mpeg4. Using that container, with H.264 video codec and AAC audio codec you can achieve highest practical levels of compression at this time.
There’s the easy way and there’s the hard way. In part 1 I will talk about the easy way. The real fun stuff is in part 2, but that’s also where most of the frustration is as well. If you don’t need the aggravation, just take the easy way .

You run Windows – XP or Vista (maybe even 2000). You don’t know your codec from your container, let alone what’s DCT or a wavelet. You do know roughly what you need though – as in what file format you require. Lucky for you, you’re in majority.

Simply, download PS3 Video 9 and/or PSP Video 9. You are using official firmware for PSP, right? If don’t think it matters but I have never tried hacked firmwares and since we are now able to watch videos in full resolution, my only reason to ever try one doesn’t exist any longer. So, select convert, select current conversion and then click on “Convert Video”. Select your file, then select values for target device (PSP or PS3) and target format you want in the now-enabled combo boxes. Resolution of PSP screen is 480×272 so this is what you should select (for firmware 3.30+ of course, why would you run anything lower anyway?). Now click start… and that’s it. If you need to encode more videos at once – of course you do, this is for traveling, remember? – then simply repeat the procedure for other files which will queue them for processing. When it’s done, copy your files to PSP or PS3 – the program will even assist you with that – and you’re done.

There are some limitations. The obvious one is that I’m assuming you’re converting an existing video. That works well with downloaded content. But what if you want to encode something from a DVD? Then you’ll need to extract DVD to your hard drive first. That can be a simple process but it can also be pretty messy one in itself due to multiple video and audio streams present, various ads and extra features, various copy protection issues and so on. Luckily, this is nothing new and I’m sure there are plenty of guides on the web and plenty of software that will help you with this step. I wouldn’t be surprised if there was a single program that would let you rip a DVD to a PSP or PS3 compatible file. I haven’t had a need to do this yet but I have tried for education’s sake to create a PSP/PS3 playable video from a DVD. This is from memory as it was done a while ago. I will summarize it below.

You can use a freeware program called DVD Shrink to extract your DVD to a single (or multiple) .VOB files. I heard some newer DVDs don’t work with DVD Shrink – supposedly you can use DVD Fab Decrypter. None of this is new or noteworthy, I’m just reporting what you can find with some Google search. But the trick to success which could make you hitting your head against the wall for days at end is this: make sure that .VOB file you rip to has only one audio stream. Otherwise your video and your audio will end up out of sync when encoded with PSP Video 9 (and probably most other software as it’s just the visual front end). As long as you end up with one video and one audio stream, you should end up with a good, useful encoding. Just be aware, in most countries it’s fine if you’re copying a DVD you own for you to watch on the go but this is considered a criminal activity – notably US. Yep, arranging a DVD you own to a different format to watch on the plane while away from home is a crime that depending on circumstances may be a “worse” offence than going to a bank armed with a gun to withdraw someone else’s money.

The other limitation is parameters of encoding. That is, you may end up encoding stuff at much higher (or lower) bitrates and quality settings than the content warrants. This especially applies if you’re re-encoding something (say a fansubbed episode of anime). You do have a fair bit of leeway here though as you can customize provided profiles to suit your needs. Of course, that means you’ll need to learn some things about H.264 codec. I will deal with that in part 2.

There is another way which I’ll still classify as “easy”. There is a very powerful application for Windows called meGUI which is a glorious front end/scripting program running on top of several famous raw processing engines. This application is very flexible and will give you close to a full control over encoding process but in a fairly user-friendly way considering the alternatives. There is no need for me to go over its usage as help – as in detailed guides with hand-holding – is provided within it. Given the example above, it would take the ripped movie (providing instructions as to how to rip them), guide you through interactive determination of its size, aspect ratio and frame rate (e.g. in order to cut off black bars present in most DVD video because encoding them would be a waste), guide you through separately encoding audio and video – providing you with the opportunity to select one of many preset profiles that will likely suit your every need as well as be compatible with your desired device, be it PSP or an iPod. It will also let you tweak each and every encoding option if you know what you’re doing, as well as let you create (AVI)Scripts which would let you script various pre-processors, scalers, filters, deinterlacers and whatnot. So whether you needs are complicated but common – in which case you’ll have to perform many steps but you’ll have guides to lead you every step of the way – or you know what you’re doing but don’t want to waste productivity on doing everything manually – you stand a good chance of getting best or close to best results possible with the least amount of aggravation, using meGUI.

There are more limitations. Software you are using may not be using all the power of your hardware. It will not take the advantage of 64-bit instructions and it’s Windows only. If you want to do things the simple way in Linux, you should get VMWare player (which is free) and install Windows and run it as a virtual machine. You will lose some performance – and unless you buy the higher versions you won’t be able to use advantage of your multi-core processor either. You also have no control over how the programs you use were compiled – they may be quite suboptimal and not take advantage of advanced instruction sets or even multiple cores. Ironically, likely due to their popularity and huge number of users, in practice it looks like the situation is actually better than if you were to do everything yourself! For example, applications are already patched to deal with bugs or performance improvements afforded by new hardware, which is something the “official” source code may not incorporate and might not do so for a long time!. I discuss that in part 2.

In summary, between PSP (PS3) Video 9 and meGUI, most users will be able to do all they need to, whether they want a (close to) one click solution or they know what they’re doing. The best thing is, most of these programs work given normal usage patterns and if they don’t, a lot of people will complain and then someone will fix it.