Yet another developer blog.
Emotion backend: generic
Posted on 27-09-2011 in profusion efl vlc emotionEmotion is the EFL library that handles audio and video playback. It had only two backends: gstreamer and xine. But recently, Zodiac Aerospace asked ProFUSION to integrate a VLC backend that was being developed originally by Hugo Camboulive. After analyzing his current work, we figured out that it could be used to integrate not only VLC, but other players. The end result of this work is a generic backend and a brand new vlc plugin for it.
This generic backend executes a separated player (its plugin) in another process. It receives the bytes to be drawn on the Emotion object through a shared memory, and communicates/controls the player through a pipe. The pipe file descriptors to be used are sent to the player through command line arguments, leaving the standard input/output free to be used if necessary.
The player must receive and send commands defined on a common file called
Emotion_Generic_Plugin.h, which can be included for easier implementation.
However, there’s no need for the player to link against Emotion.
How does it work?
When the module is initialized for an emotion object, it starts another process that runs the specified player. The player command line is specified using:
emotion_object_module_option_set(object, "player", <command_to_player>);
A player using libvlc is being provided now, and the generic module internally checks if the command given was “vlc”, in which case it will use this provided emotion-vlc player.
When a file is set to this object, Emotion sends the file name to the player, and expects an answer that will tell that the player already decoded a bit of the file, and the video size is already set on the module, so it can allocate a shared memory with correct size.
The module then allocates the memory, sends a message to the player and expects an answer. After this last answer, the “open_done” signal is sent and the module knows that it is ready for playing. Commands issued before the module being ready are now applied (and play is resumed if necessary).
During this setup stage, info about the file set will be stored in the module, so commands like meta data get, length get and so will be available to sync calls like emotion_object_play_length_get().
The playback phase occurs by VLC writing the decoded video data on a shared memory buffer, which will be used by Emotion to display the decoded frame. A triple buffering mechanism is used to avoid tearing, and also ensures that no blocking happens on Emotion when the player is writing the pixels on the buffer.
If the player dies for any reason, a “decode_stop” signal is sent, allowing the program to call play again, and in that case it will be restarted. The playback should start from the same point it was before the player crashed (if the player supports seek on the current media format).
This last point is the main advantage of the generic backend, allowing the program to recover from a player crash. Similar plugins can be implemented using gstreamer and xine, isolating the decode from the program UI using a separated process.
If you have any questions about this backend, please feel free to ask =).