After talking about Grilo at GUADEC-ES, I’ll be talking next thursday about MAFWGriloSource in a lightning talk during GUADEC. Both events are sponsored by Igalia.
Moving to the next page in MafwGriloSource
Thank Aldon Hynes, who sent me an email with some comments about MafwGriloSource behavior in the N900, I could fix a bug and implement a feature. The bug was a limitation when browsing, as you could only see the first 64 results. It was caused by a problem with indexes when returning the results, as I alwayes sent 0. When fixing this, the interface was requesting more and adding them to the treeview. Then we had all results in the treeview.
Then the problem I saw was that loading so many items in treeview was not slow, but a never ending story, as it took a long time to stop because we were asking for more pages until we reached the end, which took a long time.
I thought of a way of providing my own pagination and the first step was reverting the fix for the index bug to avoid the interface requesting more pages itself, which is a bit hacky, but it was the only way when the interface is not open. The next step was implementing a way of showing a new container row with a “More results…” label to be able to transparently carry on browsing.
Other dirty thing is that I need to override the count and skip parameters because now we have to pay attention to the pagination info and having only 64 results would be a pain in the ass. Do you imaging browsing the thousands and thousands of Jamendo artists in chunks of 64? I thought that 1024 was a much more reasonable number. Anyway a g_message is printed when the given count is overridden.
I talked to Juan about the possibility of implementing that in Grilo itself as it could be a nice of way of providing automatic pagination, but we agreed that it was better to implement the prototype at MafwGriloSource and then, if it was good enough and the model was suitable for Grilo, we could move it there.
How could I implement this? The easiest way was changing the way the MAFW object ids are build from the GrlMedia object. What we had so far, was source_uuid::media_object_id
. First I thought of having a special uuid indicating that there was pagination but this would not work as MAFW really needs to parse a valid source uuid (this is, corresponding to an existing source), to send the requests to the appropriate one, so I had to discard this option.
Then, if I could not touch the source uuid, the next and only choice was the media object id. As the MAFW media object id is created directly from the GrlMedia id, it is an opaque string for us, so the best solution was adding the pagination information (the next element index in the list to request) and then catenating the media object id with a semicolon as separation. Result: source_uuid::next_element_index:current_container_media_object_id
. For this, I needed to change the functions to serialize and deserialize the object id.
Once I had the pagination info, the only thing left should be changing the callback to return the data to check if there were results left and adding the row that you will see if you, for example, browse Jamendo artists.
Here you have the result:
If you find anything weird, drop me a line.
I have to thank Igalia for letting use work time to finish this.
GUADEC-ES
GUADEC
MAFW went Grilo
As I explained in another post, some colleagues at Igalia were creating the Grilo framework to gather multimedia content and ease the creation of that kind of applications. The origins of Grilo are in MAFW, which is the multimedia application framework used in Maemo 5 (Fremantle) to power the official media player, and that we had created in collaboration with Nokia and other companies, but we wanted to go beyond its limitations and Grilo is the result.
We thought that we could mix both things and power MAFW with Grilo, by creating a MAFW source so that contents provided by Grilo could be accessed through MAFW and therefore, through the official Fremantle media player. I began to code that and I already got something pretty stable. You can find it at Gitorious.
For grilo and grilo-plugins, I created fremantle branches from the last stable release at that moment. Some plugins became useless because of two main reasons: they had already the counterpart in MAFW (such as UPnP or bookmarks) or they couldn’t be mapped correctly to MAFW, such as Apple trailers (which needed a user-agent to work) or Vimeo, which does not support browse, so I removed them from grilo-plugins fremantle branch release.
Other important thing I had to do was porting some plugins from GVFS back to GnomeVFS because GVFS http backend was not working propertly and it made the plugins hang.
It is a pity that I couldn’t rebase against the last grilo release, because of GData. The fremantle release is not working properly with Grilo, so I preferred to have the last stable release working.
I received some feedback from the Maemo community. They were requesting a couple of things, but none of them is feasible or has a proper solution. First is remembering the position at least for Filesystem. Problem is that who sends the position to be stored is the interface and it only does it for the mafw-tracker-source, so it is something we cannot do if they don’t send that positions to us.
Other interesting feature is the search and that’s a problem. MAFW does not support search (one of MAFW limitations we corrected in Grilo), though it could be easily wrapped as a special browse. The biggest problem is the interface, which we don’t have access to. As the interface does not have any search button and has no possibility to have it, it makes the thing almost impossible. There could be the solution of adding a search container and it that was opened, we could allow selection the search string by tapping on rows with letters, but you’d need to tap and pan many times to perform the search, which makes it annoying and of course, very ugly.
Summing up, no search and no remembering the last position because the interface does not support those things. What I am trying to do now is getting MAFWGriloSource listed in the App Manager. Lucky that I know two fellow Igalians, who hacked on it 🙂 .
Lightning talk for GUADEC submitted
My submission for this year’s GUADEC:
This is a _lightning talk_ about how the evolution from MAFW (Multimedia Aplication FrameWork used in Fremantle official media player) to Grilo (new multimedia framework for application aiming to provide easy access to many sources of media) and how they can work together to provide a better user experience and access to more media in the Maemo 5 platform (Fremantle)
Unbricking my SheevaPlug
More or less one month ago, my SheevaPlug went bananas and didn’t turn on again. After talking to a colleague at Igalia who googled a bit, we found out that it could be a problem with the power supply unit. The issue seems to be known and it happens when you keep an external harddisk taking power directly from the USB port for a long time. It seems that power is not enough and you get a burnt power supply unit.
What I did was opening the Sheeva and taking the power supply unit to electronics specialized shop in my city and they told me that they didn’t have so small power supply unit, but that I could use an external one. He explained me what I should do.
I needed a couple of pieces not to cut the new power supply unit cables and a soldering iron (with some solder, of course). Then I could cut the connector of the broken power supply unit as you can see in the picture:
Next step was soldering the red cables to the inner pole of the adapter and the black ones to the outter pole (if I am not mistaken, you can recognize in the picture that the outter is negative and inner is positive). As I was bad doing this manual works at school and I still am, we (my wife and me, yes the pole soldered by her was in a better shape than mine) had to insulate them with a bit of insulating tape. You can see this in the picture.
The rest was just putting the external power supply connector thru the hole left by the old one and keep the cables where the old one was. I connected it to the motherboard, closed it and voilà !
Now I have the again the Sheeva with the external hard disk, but I provide external supply with something similar to this not to have the same problem again, but I wonder if just using a more powerful power supply unit would remove the problem of having the harddisk with external an external one.
mafw goes Grilo
As you may know, some colleagues at Igalia are developing a framework to gather, browse and query multimedia sources called Grilo. Of course it is no replacement for GStreamer as it is at a much higher level and we are focusing in gathering, browsing and querying so far.
We were an important part of the main developers of MAFW, so in this case we are trying to learn from the mistakes and try to create a more useful and easy to use framework.
One of my first steps, as a test, will be creating a MAFW pluging for Grilo, so that we can have all sources managed by Grilo running on the Fremantle official media player (as soon as bug 9361 gets fixed) with the consequence of having integrated important and interesting features as Youtube, podcasts, Jamendo, Shoutcast and so on.
mafw-gst-renderer and volume management
In the beginning we are just having a volume in MAFW that we were just setting to the GStreamer. This was a bit complicated to maintain because you always have to be careful of resetting volume to the pipeline when you create a new one and even after some state changes, meaning GST_STATE_READY
for example, what I consider a GStreamer limitation, BTW. Anyway, we kept that with a conditional compilation because running Pulse was hell inside Scratchbox, at least for me.
Maemo 5 does not have global volume (to be changed by a user) and uses Pulseaudio, as I just advanced. It defines several volume roles so we can say that volume is context sensitive, meaning that call volume is not the same as multimedia volume, for example. As Maemo can have more than one media player it was not a clever idea to define our volume and use it with GStreamer pipeline and if you also take into account that you need to have the same volume as the status menu volume bar, mission turns much more complicated. The idea was then to use Pulse directly through ext-stream-restore2
API (which I think is not merged upstream yet). One of the side effect advantages is that we do not need to store the volume between executions because Pulse does.
Pulse API has the ability of several kind of loops, say, a threaded mainloop and a GLib mainloop. For simplicity and as it was enough, we used GLib mainloop API.
Other issue was merging requests implementation. We implemented this by sending only a maximum of 5 changes per second, it is once every 200ms in order not to flood Pulse with changes.
One of the things I did not like too much was the hacks to reconnect to pulse if they failed. In those cases we were just crashing, but people did not like it, so we had to implement reconnection (IMHO Pulse should never crash either). The issue was failures during reconnection, which made us to write a hack to try reconnection after one second, until we get it. This solved the problems but it is a workaround, not a solution (which should be Pulse not crashing or reconnecting always fine).
You can take a look at the code at mafw-gst-renderer-worker-volume.c
and mafw-gst-renderer-worker-volume.h
.
Seekability and DLNA in MAFW
Seekability when streaming contents involves almost all layers of a multimedia player and it is not a trivial issue. First, your interface needs to have a seekbar or something to do that. Of course, the media you are streaming has to seekable, meaning container and codecs used. And we cannot forget the transport either, this is, HTTP, local access and so on.
Thank Gods, GStreamer does a wonderful job making easier everything related to transport, decoding, containers, etc. But in the case of UPnP–DLNA, there is a extension saying if the media you are playing is seekable or not.
We did not have support for that in MAFW and we needed it, I added the request for the metadata key MAFW_METADATA_KEY_IS_SEEKABLE
when requesting data to play media, so now we have duration, uri and seekability. Our approach had to be consevative (otherwise, GStreamer seekability would have been enough), and then if MAFW source provides the metadata key and media is not seekable, se just say it is not seekable. Otherwise, we rely on GStreamer, that has the final responsibility (which is logical, if it cannot seek, seeking is impossible). Of course, seekability depends on duration, meaning, if there is no duration, we cannot seek as we would not know the seeking limits.
About how to implement that in the sources, the only one needing it was mafw-upnp-source. In the other ones we just want to rely on GStreamer, but for UPnP, if we want to honor DLNA specification, we had to do that. Specification is fun itself and of course, adding that every vendor/provider implements what it wants makes it more difficult. A proof is that a friend of mine bought a TV claiming to be DLNA certified and it only works with the crappy server provided by the vendor, closed of course, and with a lot of missing features, like subtitles support, IIRC (yes Zeenix, I told him to use Rygel and Philippe, it was before you joining Igalia :-p). Now with new gupnp
this was reworked, but when I wrote it, we had to check the DLNA_OP
fields to know if it was seekable or not and it was a pain in the ass to decide what the default was depending on the missing options and so on.
Fortunately, it is working fine now, I think.