Thread Tools
Posts: 21 | Thanked: 62 times | Joined on Nov 2014
Status (2015/01/04) :
HLS playback working with gstreamer, but not with OMP/MP/MAFW yet (read thread).

Original post :
Over the past few days I tried to have some kind of HLS playback on the n900 and here is what I gathered thus far.

TL;DR: I have an incomplete HLS playback solution, but it's not pretty

For the context, HTTP Live Streaming (HLS) is a media streaming "protocol" over HTTP, drafted by Apple, available at least on iOS-powered devices and OS X to some extent (actually it's the only "official" way to stream audio/video content to iPad/iPhones), and some Android versions.
It's being used by a lot of broadcasters/channels to provide their content to customers, which is why it might be interesting to get (some kind of) support for it on N900.

HLS basically consists of a playlist (.m3u8) of MPEG-TS chunks (usually containing h.264 video and aac or mp3 audio).
It can use a "master" (variants) playlist to present different synchronized streams of the same content to the consumer, which will be able to choose one and change across those during playback based on a few parameters; mainly the stream bitrate vs available bandwidth (this is called adaptative bitrate streaming).
It also specifies a few encryption mechanisms but let's focus on the simple part first :-)

To play an HLS stream one would need to :
- fetch a master .m3u8 playlist
- fetch the variant playlists
- implement some playback logic (to choose/change the selected variant)
- fetch chunks
- feed the MPEG-TS chunks to the actual playback pipeline (namely an MPEG-TS demux, h.264/aac/mp3 decoders, and audio/video sinks)

MPEG-TS playback
As per stock fremantle/n900 cannot play MPEG-TS/H.264 streams because of an inconsistency between our gstreamer mpegtsdemux and the h.264 decoders, be it dspvdec, omx_h264, or ff_h264. Basically they need encoded frames to be sent separately and in one piece, which mpegtsdemux doesnt do. omx_h264 will refuse the stream while dspvdec is more lenient and will decode the partial frames with a lot of green artefacts.
The bugreport mentions inserting an updated h264parse filter (which retrieves information from the h.264 bitstream and cuts it in proper encoded frames), but then we'd need to patch playbin2 (or some other gstreamer component) or use a custom pipeline to play MPEG-TS streams.

Another trick is to use gstreamer/ffmpeg demux (ffdemux_mpegts in our case) :
gst-launch-0.10  -v filesrc location=moo.ts ! ffdemux_mpegts name=demux demux. ! queue ! decodebin2 ! autovideosink demux. ! queue ! decodebin2 ! autoaudiosink
Please note I'm am using libgstdsp dspvdec (the "HD" version from freemangordon) instead of omx_h264 (see for details).
To make MPEG-TS/H.264 work "out of the box" with playbin2, and with MAFW-based players (stock Media Player, OMP) we need to force gstreamer into using ffdemux_mpegts instead of mpegtsdemux.
Since libgstffmpeg plugin has a hardcoded rank of None (0) I had to patch and rebuild gstreamer0.10-ffmpeg to set its rank to Marginal (64). Then I removed /usr/lib/gstreamer-0.10/ (I could also patch gstreamer0.10-plugins-bad-extra to change libgstmpegdemux rank).
Now we can play MPEG-TS streams (keep in mind that we're still limited by N900 dsp regarding H.264 decoding) with Media Player. Since you won't be able to open it from the file browser (I guess we need to fiddle with file associations and/or mimetypes) you'll need to use dbus, as explained at :
dbus-send --print-reply /com/nokia/mediaplayer string:"file:///absolute/path/to/foobar.ts"
Note that you can also play TS files served over http (and even TS *streamed* over http).
While for VOD/event HLS streams we could just fetch the chunks and concat those into a single TS file, this wont do for real live streams.

Native playlist handling
As a nice side effect of Media Player playlist handling, you can now try to open an HLS stream (.m3u8) using the dbus command ( for instance). You should get a clean picture/sound with a short playback interruption every 10 seconds (the chunk size).

HLS playback solutions
One alternative to a proper HLS playback solution is backporting gstreamer hlsdemux from gst-plugins-bad. Copying gst/hls/ (tag maemo6/0.10.22-0maemo9) allows us to build with an hls "demux" embryo, but it's still awfully broken and needs a lot of work. Others gstreamer elements (souphttpsrc for instance) might require an update, and/or we could get an even more recent version of hlsdemux from latest gst-plugins-bad (but then we'd have to port it back to gstreamer-0.10).
While it's probably The Proper Way (along with making playbin2 automatically construct a full hls playback pipeline), it looks like we'd need quite a lot of patching/coding (and we're talking gstreamer code ).

Another solution is hls-player , a python/gstreamer-based HLS fetcher/player which can play live HLS streams.
It is quite buggy and not maintained anymore, I couldnt get it to play master m3u8 (variants), and it's quite unstable (it looks like the fetcher logic/heuristic is messed up).
I then thought of livestreamer but it needs python >= 2.6 with a pile of python deps.

VLC streamout
Eventually I tried retrieving the HLS stream with VLC and stream/remux it back to Media Player as MPEG-TS over HTTP (please note we only remux it, we won't do any transcoding here).
It looks like our old (1.1.0) vlc didnt have a proper HLS support either at the time it was released and it seems it respawns part of the the remux/streamout pipeline, leading to broken playback.
Trying with a recent VLC on my laptop I was able to successfully remux/send an HLS stream to my N900 and play it with Media Player.
I ended up building a 2.2.0-git VLC with some of its contribs (and a few patches here and there).

Now to play an HLS stream I can fetch/stream it with VLC using :
/opt/vlc/bin/vlc -I dummy -vvv --sout '#standard{access=http,mux=ts,dst=}'
and play with Media Player.

Playback is quite stable. No a/v desync, and it played the same channel/variant for an hour over usbnet before I stopped it. Playback over wireless is less stable, but I think my wireless network is at fault here.

As said previously H.264 decoding is still limited by the DSP and you might find some streams that are simply too complex for the N900 to play properly (baseline/SD and main/low-res streams are fine, but dont expect to play SD main profile streams, let alone high profile). This makes playing master m3u8 (variants) tricky since VLC will try and fetch the variant with the higher bitrate it can get (taking available bandwidth into consideration).
We might also run into resolution change issues when changing variant (like the XMPP/Jingle videocall issue N900 once had with Gtalk users), but I still need to check that.

I tried playing an AES-encrypted HLS stream but unfortunately the AES key was only available using HTTPS and it looks like I still have a gnutls-related error with my quick&dirty VLC build.

We now have a working HLS playback proof-of-concept.
I can make the binaries I built available if anyone is interested, but I'm not sure the gst-plugins-bad/gst-ffmpeg patches should go to extras-devel as-is (even though it probably wont break anything since mpeg-ts doesn't work properly as it is now in the repositories).

Ideally we'd need to write a proper gstreamer hls source/demux (or port the current one to 0.10) and make it play nicely with playbin2 and Media Player (since Media Player will try to handle the .m3u8 as a regular playlist).
We could also (re)write an HLS fetcher logic (like hls-player) and embed it in a dedicated application with a gstreamer pipeline (or a QMediaPlayer like in CuteTube).
Or have a stripped-down vlc-based (or whatever) application to stream it back to (Open) Media Player.

All I know is it still needs quite a bit of work

Last edited by bencoh; 2015-01-03 at 23:17.

The Following 8 Users Say Thank You to bencoh For This Useful Post:
nokiabot's Avatar
Posts: 1,973 | Thanked: 1,822 times | Joined on Mar 2013 @ india
Carving for this since ages as i can watch live tv on symbians but not on n900 f*** also many video portals use this even youtube.
the next thing i never got to do on maemo is playback of downloading videos .
btw didnt knew its an apple thing
Posts: 21 | Thanked: 62 times | Joined on Nov 2014
Okay, some update on this.
Now I can play a live HLS stream with gstreamer/playbin2 (using hlsdemux).
I had to backport (mostly copy) a few things from more recent versions of gstreamer-plugins* to have it work :
- add hlsdemux in gst-plugins-bad
- add hls typefinds in gst-plugins-base
- add the QUERY_URI command to httpsoupsrc in gst-plugins-good

I also had to change gstmpegtsdemux rank to NONE and gstffmpeg rank to MARGINAL (as explained in my first post).
hlsdemux needed a tiny bit of adaptation to make it cooperate nicely with decodebin2 (gstreamer automagic decoding bin).

You can try it with the packages attached below. To install it, keep trace of the already installed gstreamer-* packages using
dpkg -l |grep gstreamer
and just "dpkg -i" the downloaded packages.
To revert back, "apt-get install --reinstall reinstall" (edit: for some unknown reason that does not seem to work ...) the packages (or remove for the packages that were not there in the first place).

To play a stream :
gst-launch playbin2 uri=
Note that gst-launch doesnt handle input focus properly with matchbox (Maemo window manager) so if you want to use it fullscreen you'll have to play with wmctrl :
wmctrl -b toggle,fullscreen -r gst-launch
For some reason dspvdec (the DSP video decoder in gstdsp) fails when changing variants inside a stream (from a low res to a higher res) with the following message :
handle_hdcodec_error: unsupported stream or invalid i/p params
So we won't be able to play variants (master) playlists for now, and you'll have to manually select the right version of your stream. Considering you won't be able to play the HD (or high profile) version of most streams you'd probably need to do this anyway.
I tested it with the HD codecs installed, so please tell me if result differs with stock codecs.

I could not get (Open)MediaPlayer to pass the HLS .m3u8 URI directly to gstreamer without parsing it as a playlist first, so HLS playback does not work with (Open)MediaPlayer for now.
I don't know whether the problem lies in (Open)MediaPlayer or MAFW yet.

Playback is much more stable than when using VLC to remux it (especially over wireless or when playing too complex h264 streams).

- fix the MP/OMP/MAFW(?) issue
- fix dspvdec (erm ...) and/or find a proper way to select a specific stream variant. This could be using a special HLS application, or via a MAFW/OMP plugin (since we cannot fix MediaPlayer, I'd rather write a MAFW plugin, if possible).

Edit : I forgot to attach the packages
gstreamer-ffmpeg is too big to be attached with this message, so here it is :
For some reason I could not use "apt-get install --reinstall" to reinstall the original packages back, I get
"Reinstallation of gstreamer0.10-plugins-bad is not possible, it cannot be downloaded"
(same for the other packages, except for gstreamer-ffmpeg which comes from extras). I dont know if I have some issue with my apt settings, or if this is an issue with how nokia repositories are handled, but I have a mirror copy of from which I downloaded it back, so I know it's supposed to be there.

Last edited by bencoh; 2015-01-03 at 23:54.

The Following User Says Thank You to bencoh For This Useful Post:

Thread Tools

Forum Jump

All times are GMT. The time now is 08:05.