A few years ago, I had to work on UPnP A/V protocol for work. This is a service from the UPnP specifications that is used by many so-called audio/video players/servers (mostly set-top-boxes) to provide an easy way to share and stream multimedia content. Having worked on it, I’ve decided to write a small UPnP A/V media server, with embedded constraints in mind and there came uShare (pronounce you-share). Surprisingly uShare quickly became one of the most used UPnP A/V Media Server on UNIX. It is indeed now part of Ubuntu distribution, and included in many micro-distributions such as OpenWRT or FreeNAS, which are used on some routers or NAS.
The UPnP A/V protocol never was really well defined (broadcast messages, making massive usage of SOAP requests over HTTP to send info under XML form) but it could have been worse. That probably also was industry engineers way of thinking when they designed DLNA specifications. UPnP A/V relies on UPnP protocol to exchanged session information. It also requires up to 3 services to dialog between a client/player and a server: the Content Directory Service (CDS) which exports your shares, a Connection Manager Service (CMS) which handles connections between both end-points, and an optional AV Transport Service (AVTS) which only god knows the use of. Finally, all that it does, is the server providing an HTTP URL to the client to know where to stream from … yeah, this seems to be over-complicated just to do a so simple thing, but so is life.
But, so far, it was working not that bad and uShare became more and more famous and used. Ironically, although being uShare‘s author, I didn’t myself had any use on this protocol, having no UPnP A/V compatible device. This doesn’t help much with testing, that’s for sure😉 But then came Microsoft Xbox 360. As usual with MS, they did their lot of crap and decided to add an extra UPnP service, just to became not compatible with the norm they’ve created themselves (UPnP was designed by Microsoft in early 2000’s). Let’s call this new service Microsoft Registrar (MSR). In fact, it has been designed so that only Windows Media Connect (WMC) can be used as a server to XboX 360. As a result, uShare had to mimics WMC to server XboX 360. Also, they’ve decided not to have a regular implementation of CDS, which, again, is just one more thing used to drive me crazy. The fact that I have no interest in XboX 360, nor access to any of those beast (and I still don’t have) wasn’t the best way to have it supported. Though, thanks to the help of many testers over the years, I managed to make it work. And it seems to be used massively around the world, mostly with XboX. I still don’t understand why, but I even had to reply to some interview about my plans with uShare and XboX 360 support. This was extremely funny
But let’s come back to DLNA. DLNA stands for Digital Living Network Alliance. It’s a consortium of industrials that are focusing on the embedded and set-top-box market and that wanted to define a protocol to share media content among various devices (NAS, Televisions, A/V Players and so on …). They decided to use UPnP A/V protocol but, judging it way too versatile, it was better to harden it quite a bit so that it just sounds more professional. In simple words, DLNA can be defined as “UPnP A/V with restrictions“. Using plain UPnP A/V, a server can share any kind of file (being binary, audio file, video file, text file like subtitle, or even a Word or PowerPoint presentation, whatever …). All it does after all, is sharing a file through HTTP with its associated MIME type, just like any HTTP server (Apache …) would do. It was then up to the client/player to determine whether or not it can handle the stream. This was quite too simple for DLNA folks. They have decided that only a numerous number of files are worth being shared. As a result, they’ve decided to restrict the protocol so that only some specific file extensions, but also containers and audio/video codecs combination can be used. This just sounds like a very good idea. Even a 16-year-old drunk cheerleader could have understood it was pure crap !!
You’ll find below the only supported stream characteristics:
- Image Codecs: JPEG, PNG
- Audio Codecs: AC3, AMR, ATRAC3, LPCM, MP3, MPEG4, WMA
- Video Codecs: MPEG 1, MPEG 2, MPEG 4 Part 2 (a.k.a DivX), MPEG 4 Part 10 (a.k.a H.264), WMV9.
- Containers: MPEG PS/TS, MP4, ASF for video files …
As you can see, many media formats are purely and simply dropped because no one use them in industry, that’s quite simple to understand. As you may have seen, no free audio codec is supported (Ogg/Vorbis, FLAC …), nor is WMV10 (a.k.a VC-1), which tends to replace WMV9 more and more but, more interestingly, neither AVI nor Matroska (MKV) containers are supported. This just means that 99% of video files are not DLNA compliant and thus, can’t be streamed as it. This is simply brilliant ! But if it just ended up here, the protocol could have been just “bad”. Let’s see the tricky part. Supposing you have a multimedia file that fulfill these constraints (let’s say you’ve downloaded some HDTV trailer on Apple.com, which is H.264 video based, with AAC audio, encapsulated within a MOV/MP4 container). That’s looks like a supported media. Unfortunately it isn’t Yeah, I forget to tell you about DLNA profiles. DLNA specifications defines quite a lot of A/V profiles (something like 250-300 I’d say) and a file, to be compliant with DLNA, has to comply with one of these profiles. As said, it depends on audio/video codec and container but also on resolution, bitrates and stuff like that. If we use the previous example, the file could have match because both A/V codecs and container are valid. Though, when resolution exceeds 720×576, MP4 container is judged inadequate and thus, only content within MPEG TS container can be streamed. This is the worse one could have imagined.
The very good thing with this broken design is that nearly 99% of video files are not DLNA compliant (it’s a bit easier with audio files, MP3 and AAC being OK for example). How to stream your file then ? This is quite simple in theory: you have to make them compliant with the protocol, that’s all😉 How to do that then ? Well, for each file, the DLNA server has to first demux it, in order to retrieve its A/V and container information, so that it knows whether or not it complies with an existing profile. If it does not and you still want it to be streamed, than the server has to either remux it (best case ever) if it’s enough, or remux and re-encode it on the fly (worst case ever) to a valid profile so that player can read it. Of course, doing so on-the-fly consumes a lot of CPU power, which is, by definition, not available, making it impossible to do on embedded devices, which were the target of DLNA inventors. Also, each file, once demuxed, has to be given a DLNA profile id. The good thing is that, supposing the file _IS_ DLNA compliant and could be decoded by the player but the server has announced it with a faulty ID, then you won’t be able to have it played.
As we’ve seen, DLNA is truly broken by design. Though, it is industry standards and more and more devices will be DLNA compliant only and won’t support UPnP A/V any longer. The first one to do so was Sony Playstation 3 console (yeah, they manage to do worse than Microsoft …). Luckily for me, I’ve been granted a PS3 to make uShare work with it. I’ve also been sponsored by Consumer Embedded Linux Forum (CELF) which provided me the DLNA specifications for free (otherwise, the stupidity explained before still costs $5000 …) which helped me design the first and unique C implementation of DLNA specifications for Linux through libdlna. libdlna implements all DLNA profile discovery and now allows you to build a fully compliant DLNA (or UPnP A/V) Media Server with a few lines of code. Next goal will be to provide Media Player capabilities too and also to support the on-the-fly remuxing/re-encoding thing for server, which is requested by users for quite too long time. Also, development version of uShare now completely relies on libdlna and is no more than a command-line frontend to it.
At present time, I have no date for next libdlna and uShare release. Many things still need to be fixed in both, especially now that they are tightly binded. All of uShare UPnP CDS/CMS code now has moved to libdlna and Xbox 360 support is broken one more time. If someone want to sponsor me one, you know where to find me. That’s all for today, more libdlna/uShare news to come within next weeks if I manage to find the time and motivation for it😉