HD Video Playback in Linux

It seems that any developer I ask tells me that it’s currently not possible to play back 1080p H.264 video in Linux. In this post, I respond loud and clear to anyone who has said that: They Are Wrong. But there has to be a catch, right? Of course there is; there’s always a catch. Yes, I can play back some 1080p H.264 video flawlessly in Linux. Yes, I have watched entire movies in this fashion. Yes, there are some clips that I just can’t play back with my setup. Read on for the details of said setup, how I do it, and what the limitations are.

Definitions & Limitations

First, I should provide some definitions and/or limitations; in order to make any claims we first need to lay down some commonly accepted premises. I’m not going to argue that the following definitions are universally correct or even that they represent any general consensus; this is just how I define the following terms and what these definitions mean — subjectively — to me.

1080p

This one is going to be controversial. Technically speaking, a video is defined as within the 1080p standard if (a) its picture is progressive (non-interlaced) and (b) the picture is made up of 1,080 rows of pixels. What is implied but not specifically stated in this definition is that the aspect ratio of a 1080p picture is 16:9, yielding a resolution of 1920×1080. However, since many movies are filmed in wider aspect ratios, commercial 1080p media is often letterboxed in order to avoid cropping. As such, for my purposes, I define 1080p to be any picture with 1,920 columns of pixels.

H.264

The H.264 codec is an ugly multi-headed beast. The specification for this particular video codec provides many different profiles which all require different amounts of processing power to encode or decode. There are all sorts of available ‘options’ within the standard and many of them probably require a supercomputer just to decode (in 1080p) in realtime. For the purposes of this discussion, I’ll say that we’re dealing with the baseline or main H.264 profiles, using a reasonable amount of b-frames and reference frames — say, one to three — at a reasonable bitrate of about 10mbit (average) for 1080p films, using CABAC. Most of my test clips were encoded using the wonderful x264 open-source H.264 encoder.

Hardware

When I set out to build a Home Theater PC (HTPC), I wanted to keep 1080p H.264 playback in mind, and knowing that this problem is computationally difficult, I bought fairly high-end hardware with budget somewhat in mind. I won’t argue for or against my hardware, since that’s a whole different debate better suited to people more so inclined. I will say that my hardware works me.

Processor AMD Athlon 64 X2 6000+
Motherboard Gigabyte GA-MA69G-S3H
RAM Wintec AMPX 1GB (2 x 512MB) PC2 6400
Video BFG Tech 3D Fuzion GeForce 6200LE
Display Mitsubishi LT-46131 (1920×1080 46″ LCD)

Processor

AMD Athlon 64 X2 6000+

Whilst not getting into the AMD vs. Intel debate, I will say this: I feel that going with AMD is more cost-effective. At time of purchase, the chip I bought had just had a huge price drop and as such became quite attractive. Once I got the components together and verified that everything worked, I overclocked this bad-boy from its stock 3.0Ghz (200Mhz x 15) to 3.15Ghz (210Mhz x 15) just to squeeze a bit (5% to be precise) out of it. Whilst I could get it to run at 3.3Ghz, it wasn’t stable and I wasn’t willing to bump the voltages up too much on the stock cooling I have. Currently this processor runs at around 35°C idle and around 65°C under load.

Motherboard

Gigabyte GA-MA69G-S3H

This is where I spent a lot of time researching. I wanted a motherboard that had as many integrated components as possible. Most motherboards these days have integrated sound but not all have integrated sound with optical out, which was an absolute necessity for me. I was also looking for a motherboard with integrated video. I found this one with the added bonus of having integrated HDMI. I couldn’t get the sound pass-through over HDMI working under Linux, but since I have an optical connection to the receiver anyways I’m not too fettered about it.

RAM

Quite simply, just whatever cheap dual-channel 800Mhz RAM compatible with my motherboard I happened to find on newegg.com.

Video

BFG Tech 3D Fuzion GeForce 6200LE

As I found out just after putting all of the hardware together, ATI’s drivers for Linux do not support XVideo (hardware accelerated video scaling, color-space conversions, and display), rendering the integrated video card on the motherboard less useful. I decided to buy the cheapest PCI-Express NVIDIA card I could find, making sure that it was fully supported with the latest NVIDIA Linux drivers. More on this in the software section below.

Display

Mitsubishi LT-46131

Most new HDTVs now have some sort of direct-from-computer input — mine has a DVI port right on the back. Some HDTVs, however, do some overscanning and other image processing on the signal received, even for digital signals. Depending on the source, this can be good or bad, but in general when attaching a computer to a display you want a 1:1 (no overscan) pixel mapping. Fortunately my display supports this via its DVI port.

Software

There was no doubt in my mind that I’d be running Linux, so hardware acceleration of H.264 playback was immediately a no-go: the driver support just isn’t there yet. It turns out that I’m pretty much stuck with ffmpeg’s H.264 decoder for playback (I won’t get into the controversial CoreAVC-on-Linux fiasco here other than to say I’m not about to go hacking up mplayer code to get CoreAVC on Linux under 64bit). But there’s more to playback than just decoding the input video stream; once the stream is decoded, there is an often necessary colorspace conversion to do, there may or may not be some scaling involved, and of course you have to get the decoded image to the display somehow, which can take significant amounts of compute time.

Decoding

The ffmpeg H.264 decoder is really great with one major caveat: it’s not multithreaded. This means that no matter how many cores you have, H.264 decoding will use exactly one. I hear there’s some work being done on parallelizing said decoder, but as of yet I’ve heard of no working prototypes let alone a release. Knowing this is mostly why I wanted such a high clock speed for my main processor, regardless of how many cores it has — for sure I would have bought a cheaper, slower dual-core processor had the ffmpeg H.264 decoder been capable of taking advantage of two cores simultaneously.

That having been said, there are some decoding options that you can pass to ffmpeg’s H.264 decoder via mplayer that will improve performance at the cost of quality. Specifically, there’s the ability so skip all of the in-loop filters (deblocking, mainly), which should yield a performance increase of ranging from zero to three hundred precent or more depending on the source material and encoding options. Simply invoke mplayer with the option -lavdopts fast=1:skiploopfilter=all — you can read more about these in your mplayer manpage. If your processor just isn’t capable of handling H.264 videos you’re trying to play, a good first pass is to try disabling in-loop filters. If your processor still can’t handle it, it’s time for you to upgrade — there’s pretty much nothing else you can do.

Displaying

Once a video stream has been decoded, it is typically sent to a display for viewing. Often this involves colorspace conversions and/or scaling. In my case, with 1080p playback, there is typically no scaling necessary as my display is exactly as large (at least in the limiting dimension) as the image being displayed. In the case of 720p on a 1080p display, however, some upscaling needs to be done. Some upscaling and colorspace conversion computations can be done in hardware on your graphics card if your graphics drivers are capable and set up for it. One such technology under Linux is XVideo, or XV for short.

XV can handle colorspace conversions and upscaling natively in graphics hardware so that your CPU doesn’t have to burn cycles doing so. In the absence of XV, I have found mplayer’s X11 output driver to be the best on my setup. Even though the X11 processing seemingly went on in the X11 server (according to top), which of course does not run on the same core as mplayer so as to maximize performance, I found that using the X11 display driver cause a significant decrease in video playback performance — enough to drop a few frames in some test clips. Since the ATI drivers for the integrated graphics chipset on my motherboard do not provide XV capabilities at time of writing (note that this is a specific case for my video chipset, the X1250 — most other ATI chipsets boast XV support in the proprietary ATI drivers), I bought a cheap NVIDIA card that I knew would work with XV. Once I had XV working, I was able to play back clips that had previously stuttered due to dropped frames.

It is my preference, however, to not upscale videos using XV, as generally I find the results to be much better when using a decent software upscaler. This is especially visible when viewing, for example, NTSC television captures on a 1080p display. There are a number of software upscale implementations bundled with mplayer, and for most people the default will suffice. If this is a bit too CPU-intensive, though, I find that the fast bilinear algorithm does a fairly good job and is a little bit less CPU intensive than the default bicubic algorithm. To select this, simply invoke mplayer with the -zoom -sws 0 arguments. Of course, the quality of the upscale will depend on the source and the algorithm of choice, so as with anything else, try a few of the different options and go with what you prefer.

A Note On Sound

I run an optical line between my HTPC and my sound receiver and use it for both PCM and surround (Dolby or DTS) sound. While this article is, as the title suggests, about video, I feel compelled here to mention that decoding surround sound in software does take a nontrivial amount of CPU time. You’ll be much better off — for a number of reasons, compute time inclusive — sending the audio stream to a hardware decoder (read: sound receiver) for playback there. Sometimes the little bit of difference that decoding sound can make is what you’ll need to avoid a few dropped frames here and there.

27 Responses to “HD Video Playback in Linux”


  1. 1 Steve Dibb

    That is an awesome writeup on the state of HDTV playback, thanks for that. :)

  2. 2 Steve Dibb

    I forgot to ask .. which TV do you have?

  3. 3 Hasan

    I’m glad you liked the post!

    As stated in the article, I have a Mitsubishi LT-46131 HDTV.

  4. 4 mike

    Thanks for the write-up. I’ve been looking at doing something exactly like you did.

    My question…. what is the full mplayer command you use to playback video? I saw…

    -lavdopts fast=1:skiploopfilter=all -zoom -sws 0

    but was wondering if there were other options you use.

    thanks again for the writeup!

  5. 5 Hasan

    My mplayer.conf file, which you might think of as providing defaults for command-line invocation of mplayer, has the following entries:


    # Use XVideo by default.
    vo = xv

    # Use 2 threads. Not all codecs can take advantage of this.
    lavdopts = threads=2

    # Use AC3/DTS passthrough over S/PDIF by default.
    afm = hwac3

    # Start in fullscreen by default.
    fs = yes

    # Always enable software scaling.
    zoom = yes

    # Set the WM hints to keep the mplayer window on top of others.
    ontop = yes

    # Fix for buggy audio drivers/codecs.
    autosync = 30

    # Drop video frames as necessary to keep audio sync.
    framedrop = yes

    # Use a 100MB cache; very large but helps with slow media such as NFS over a crowded network
    cache = 102400

    # Fill 20% of the cache before starting playback.
    cache-min = 20

    # Fill 20% of the cache before starting playback again when seeking.
    cache-seek-min = 20

    If the code comments provided in-line above are not sufficient, feel free to ask questions here!

  6. 6 Steph Legere

    Your blog is boring, and you don’t update enough. I DEMAND MORE.

  7. 7 Bart

    Great writeup! I only wish I found it sooner. :) So I guess this basically means there’s still no proper support for H.264 under Linux. Heck, we don’t even have proper H.264 1080p support under Windows without CoreAVC! What a shame.

  8. 8 Hasan

    Bart-

    Really it’s a matter of perspective, and how you define ‘proper’. My setup as described above is more than powerful enough for any Blu-Ray or HD-DVD H.264 source I’ve found. Similar setups with ffdshow on Windows work as well.

    Not to mention that CoreAVC has its decoding bugs and glitches… But I won’t go down that road just yet, I promise.

  9. 9 myself

    nice work! a bit pricy for me but very nice article

  10. 10 Bart

    I wouldn’t mind you going down that road at all! We need more info on this subject. What I mean with “proper” is fullblown 1920×1080p H.264 decoding without the need for mplayer parameters that increase performance at the expense of quality. Correct me if I’m wrong: But I believe there’s currently no processor on the market that is able to perform such a task (on Linux) realtime without sweating too much. Maybe the PS3?

    I’m thinking of upgrading my HTPC since it’s currently unable to handle H.264. But I can’t seem to find any system that I feel comfortable with unless I switch to Windows with CoreAVC or perhaps go with a PureVideo solution. But I prefer to stick to Linux. :)
    Another option could be to buy a PS3 and turn that into a mediacenter for HD material. The only problem with that is that it makes a bit too much noise for my liking. But perhaps that’ll be acceptable for now until we have some new developments.

    Interestingly though, the minimum specs for the XBMC Linux port aren’t very high. Looks like there is a lot of improvement space on the software side of things. Multithreading would probably help a lot. Hardware acceleration would help a lot too. Perhaps one day my current mediacenter (P4 2.8Ghz celeron with a GeForce 7600) could even have sufficient power.

    So that’s why I’m getting the impression that we’re a bit stuck with Linux right now.

  11. 11 LuckyChuckkie

    Does your add-on video card (3D Fuzion 6200 LE) support multi-display? I’m looking at one for my kids computer that will drive (at the same time, in cloning mode) a DVI-monitor, and a S-Video television.

  12. 12 Bart

    A friend of mine has a Mac mini 2.0GHz Intel Core 2 Duo with 1 GB memory. He runs Windows XP on it with CoreAVC. For testing we found BBC’s “Planet Earth” 1080p rips which are floating around on the internet here and there. In the beginning of the first episode there’s a beautiful shot of thousands and thousands of birds flying over land. This completely choked the Mac mini which resulted into the movie stuttering! Both cores were running at peak performance and simply couldn’t cope with it. And this with the world’s fastest H.264 software decoder!

    I there any processor out there which single core performance outperforms a 2.0GHz Intel Core 2 Duo running both cores??

    Btw. That “Planet Earth” scene is an excellent benchmark scene since it involves thousands of small moving dots. If anyone has a system which can pull that off without too much trouble I’d be happy to learn about it. :)

  13. 13 BruceATmacau

    I got the similar setup on my HTPC. However, I got the ASUS P2-M2A690G barebone, which only has a PCI and a PCIe 1x slots. I could not put in another decent video card. Hence, I went different route. I used coreavc with mplayer and it did manage to play 1080p material with x11 smoothly.

    http://code.google.com/p/coreavc-for-linux/

    Another good news is that the new ati driver for linux 7.12 does support xvideo for X1250. However, the picture quality is not as good as using X11 (too bright) and there is a flicking diagonal line when playing in full screen. Besides the two problems, I am very satisfied with the new ati driver. ( I heard that people had problem getting the new driver to display 1680×1050.)

    BTW, I also tried the xorg radeonhd driver. The latest git version worked with my HDMI output but still no 3D nor XV support yet.

  14. 14 Hasan

    Bart-

    I gave those 1080p H.264 encodes of BBC’s Planet Earth out with pretty poor results, I must admit. My performance sank down to less than 1fps without any optimizations, and down to around 2-3fps with a still-in-development patch for (somewhat) parallelized decoding of H.264 via ffmpeg/mplayer. The scenes with a large number of small moving objects really kill the frame rate, but otherwise it’s really quite watchable.

    Alas, there is still more work to be done, but at least we have a head start on it! I still hold, however, that most 1080p movies play back just fine.

    -Hasan

  15. 15 David

    Hey friend,

    Thanks for the great update on Linux capabilities. I myself am interested in high quality stereo playback and I am currently looking into digital out capabilities in linux using another Gigabyte board. Hopefully it works out!

    –David

  16. 16 Bart

    Hasan-

    Sucks, huh?… :)… really makes me wonder what kind of system I’m going to buy for my next mediacenter hardware-wise…. If anyone has some advice it would be greatly appreciated… :)

  17. 17 bubu

    xv is bad quality. use opengl! with sw yuv-rgb conversion.


    ac=hwdts,hwac3,a52,libmad,mp3lib
    lavdopts=threads=2 #dual core decoding...
    mc = 0.00001 # for lagless playing
    autosync = 130 # for lagless playing
    spp = 6
    sws = 9
    ssf = ls=100
    display = :0
    #mcdeint=0:1:10
    #fps=30
    #vf = pp=al/ac/fd

    #denoise
    #vf = hqdn3d=4:3:6,scale

    #extra sahrpening
    vf = smartblur=3:-0.4:-1,scale

    #extra sahrpening deinterlace
    #vf = smartblur=3:-0.4:-1,yadif,scale

    #denoise sharpen
    #vf = smartblur=3:-0.4:-1,hqdn3d=4:3:6,scale

    #denoise sharpen deblock
    #vf = pp=ac/lb/al,smartblur=3:-0.4:-1,hqdn3d=4:3:6,scale

    hardframedrop =1
    rtc =1

    #vo=gl:yuv=6 #:lscale=1 #:cscale=1 //hw yuv-conversion
    vo=gl:yuv=0 # swscaler yuv-rgb conversion

    dr=1

    vsync =1

    ao=alsa # To specify default audio driver (see -ao help for
    # list)

    fs=yes # Enlarges movie window to your desktop's size.
    # Used by drivers: all
    zoom=yes

  18. 18 Octavian

    Hi Bruce,

    Are you sure that ATI driver 7.12 supports XVideo for X1250? I had a system with 7.12 but still did not get any XV extension. Did you use by mistake OpenGL for playing videos? The flicking diagonal line looks like an OpenGL playback.

    Best regards,
    Octavian

  19. 19 npcomplete

    Actually, ffmpeg still has some optimizations to do besides multithreading. On a single core P4, CoreAVC still performs 30-40% faster than ffmpeg.

  20. 20 acmelabs

    Hi,
    I’m using a patched VDR (1.5.14, http://www.cadsoft.de/vdr) to watch HDTV(h264; 1920×1088

  21. 21 gnarly

    Excellent summary and comments

    I’d like to point out libavcodec (used in mplayer) is getting much better at HDTV H.264 with recent optimisations checked in the last month. Build an up to date mplayer from SVN and try it on a 3GHz Core2.

    I can play BBC HD (H.264) on mplayer using an E8400 stock frequency, and have the option of deinterlacing (”-vf yadif”) too. I only need the “-lavdopts skiploopfilter=all” speedup when deinterlacing. My display is set to the correct resolution 1440×1080 to avoid any scaling.

    With a working software player for HD H.264, Linux suddenly becomes a viable HTPC platform and there is no dependence on special h/w optimisations which are likely to be a way off.

    I hope the performance of open source software like mplayer will continue to improve and start to make real use of threading etc. Thanks to all the people that are contributing to this effort.

  22. 22 Lithium17

    Thanx for the article. As a Linux greenhorn (OSX user), I found it extremely useful.

    I’m actually running Hardy-32bit on my lil sister’s old Acer laptop (AMD Turion 2.2ghz) using Wubi at the moment. A few minor issues, but I got MPlayer to play most of my videos…audio seems to stutter after long hours of playback (some say it’s a PulseAudio issue) but other than that, no problems so far. 576p/720p h.264 runs great….not tried any 1080p yet.

    Will be building a Linux HTPC soon.

    Cheerz!

  23. 23 Joao Barbosa

    Great article!

    I would like to know your thoughts about the performance of a linux box with two vga outputs configured as an extended screen playing 20-30 HD videos at the same time.

  24. 24 balitwilight

    Thanks for the great article. I have a Dell XPS-420 and a Mitsubishi LT46231 46″ monitor running on Ubuntu Hardy. I have a problem with mplayer (even with your configuration). When I run mplayer, my HDTV flashes and seems to take about 2 seconds to change its mode before playing the video perfectly. The same sluggish “mode change” effect happens when I quit the video. The “mode change” effect is an annoying mystery: because before during and after video play my HDTV shows 1080p in the upper left corner. I have tried -noaspect, etc on mplayer to no effect. Any suggestions? Could you please post your xorg.conf file for the LT46131.

    - Thanks

  25. 25 Johannes Jensen

    Great article!

    We just bought a 40″ Samsung LE40A656 HDTV and are pondering whether it’s possible to view 1080p HD videos using our current HTPC: An Ahtlon 64 3200+ @ 2.2GHz with 1GiB RAM and an old GeForce 6800 GPU. What do you think? Is it at all possible?

    We thought that we maybe, just maybe, could upgrade just the GPU to one that could do H.264 decoding in hardware. But that’s apparently not possible with the Linux drivers :-/ Do you have any experience with hardware accelerated H.264 decoding on Windows? How much difference in CPU usage would this setup have compared to software decoding?

    I’ll try tomorrow and post my results!

  26. 26 Martijn Bastiaan

    Very nice!

    It’s a shame we don’t have hardware acceleration on Linux.. oh well, let’s hope for ffmpeg to support multiple cores or AMD, to provide HA soon..

  27. 27 Octavian Petre

    Hi Johannes,

    It should be possible to use an Ahtlon 64 3200+ for HD playback.

    I remember seeing an fullHD content with an Ahtlon 64 2800+ at 1.8GHz (if I remember correctly) although the CPU was almost 100% utilized.

Leave a Reply