I’m pleased to finally be able to announce that my CrystalHD support patches have been accepted into FFmpeg and MPlayer – if you grab the latest source from each of the projects, you’ll be good to go. As before, you’ll need the latest driver and userspace library from Jarod Wilson’s git tree. The driver that’s included in the Linux kernel’s staging directory, and the library on Broadcom’s website are both too old.
In terms of features, the merged code doesn’t differ a great deal from my original announcement – there’s now support for interlaced VC1 and MPEG4 Part 2, but interlaced H.264 remains problematic. I’ve got patches in my github tree that get very close to full support, but there’s still a corner case which can cause one type of file to play back incorrectly.
I have to say, I’ve learnt far more about interlaced encoding than I ever wanted to know, working on this project. I think it’s safe to say that I’ve spent at least 70% of my time working on it, and it’s still not perfect. With progressive content, it’s simple – you have a compressed frame going in one end, and an uncompressed one coming out the other end – there’s really no ambiguity (modulo the hardware’s odd treatment of packed b-frames where it will output the packed frame twice and you have to skip one of them).
But with interlaced content, on this hardware, you have to deal with multiple variations of input and output packing; check out wikipedia if you want a quick introduction to interlacing. When compressed video is packed into a container (like AVI or matroska), it is typically split up into packets, and those packets will correspond to compressed frames or fields, and this where the fun begins. With progressive content, a packet is obviously one frame, but with interlaced content, it could be one field or two fields – sometimes the container or video format will enforce that it is one or the other, and sometimes both are valid. On the output side, the hardware, in its infinite wisdom, will sometimes output individual fields or a full frame of two fields, without much rhyme or reason. And naturally, with h.264, all four combinations are possible. That’s bad enough; to add insult to injury, the flags that the hardware is supposed to set to identify the fields/frames is bogus – meaning that it’s simply not possible to distinguish three out of the four cases until it’s too late. With a little help from FFmpeg, I was able to identify one of those three formats, but for the last two, I had to use a method that relies on peeking ahead at the next frame/field – which is great when it works, but sometimes the hardware hasn’t decoded the next frame/field sufficiently to answer the question, and then I just have to guess.
It should come as no surprise that all the other projects that support CrystalHD have punted on interlaced support 🙂
As for the future, I still need to get the improved interlaced support merged, and then I have to start looking at how to support the older 70012 hardware. This chip is very sensitive to the rate that frames are submitted to, and retrieved from, it; the code today will work enough that you should see frames most of the time, but the hardware will do odd things and drop frames or stall, so the experience isn’t good at all. I can at least take comfort from the fact that Broadcom’s gstreamer plugin and XBMC have both got it working.
Onward and upward, etc!
{ 19 } Comments