[Swfdec] Integrating Swfdec and GStreamer
in7y118 at public.uni-hamburg.de
in7y118 at public.uni-hamburg.de
Thu Mar 22 02:44:48 PDT 2007
Hi,
I've recently been looking at integrating Swfdec and GStreamer. There
are some issues I'd like advice on. In order of importance for me:
1) Using GStreamer codecs
Swfdec currently has a simple API for decoding data that looks like
GstBuffer *decode_next_buffer (Decoder *dec, GstBuffer *input); [1]
Which is used to decode video (VP6 and Sorensen Squeeze/H263 to RGBA)
and audio (MP3, Nellymoser to 44kHz raw audio). The decoding API can't
include demuxers (like FLV), since those demuxers trigger script
events [2], and I need to ensure they do happen and happen in the
right order. And it can't pass the data on to the API. Video is
rendered just like every other object, and as such can be rotated,
scaled, affected by a clipping region or place below other object.
Audio can be modified by scripts or the file (volume, panning). [3]
My idea to implement this has been to spawn a pipeline like: appsrc !
right/caps,go=here ! decodebin ! right/caps,go=here ! appsink
But as you can see above, the current Swfdec API decodes only one
buffer at a time and then wants all available output. Since the
available output is not necessary one buffer (it is for video), but
may be 0-n (in the mp3 case), how do I make sure I got all available
output before returning from the decode function?
Or even better: Does someone of you have a better idea on how to
implement the Swfdec codec API to make it more suited for APIs like
GStreamer's?
2) Using GStreamer as audio output
The current audio API in Swfdec is modelled after how the official
player works and I've had the best results regarding start/stop
latency in ALSA with this approach. When a new audio stream [4]
becomes available [5], a new ALSA pcm is openened, and when the stream
gets removed by the player, I close the pcm. This way (as opposed to
mixing the audio myself), the open/close operations avoid the sound
card's buffer and happen way faster.
So I've been thinking about opening a new pipeline with appsrc !
autoaudiosink for every new stream and run it for as long as the
stream plays. Since you can easily find Flash files which have 5 of
those streams playing, I've been wondering if this might cause issues
for the varying sound backends. I know it works on Linux/ALSA with
dmix and it'll probably work on $SOUND_SERVER_OF_CHOICE, but what
about Solaris or BSD? Any opinions on this?
3) Writing a Swfdec plugin for GStreamer
People have asked me why I removed the GStreamer plugin from Swfdec.
This is motivated by Swfdec now supporting Actionscript and what the
Actionscript stuff can do to one's Flash files. This whole new can of
worms would make lots of Flash files complicated to get right,
especially in the autoplugger. Since I don't have the time to hack two
output frontends and the GStreamer one was problematic, I removed the
plugin. Btw, I think these problems would apply to other formats
interesting for GStreamer, too, like for example SMIL. In no
particular order:
- Flash files can load (multiple) files (at once). Currently there's
no good way to request data from elsewhere. I've been told there is an
event to request a different URI that is used by some demuxers, but
that requires the current file to be complete and does not support
more than one file.
- If Flash wants to open new files, it needs the URL of the input for
local URL resolving and for security management. Last I looked the URL
was not part of the (meta)data in the stream.
- Rendering a Flash movie requires a lot of drawing operations. Swfdec
uses cairo for this. The only available solution for cairo in
GStreamer is to use image buffers. Rendering to images is pretty much
the slowest rendering method cairo offers.
- A lot of Flash files take 100% CPU and require frame dropping to get
smooth audio playback and OK video. Back when I dropped the plugin,
the QoS framework did not exist. I haven't looked if the GStreamer QoS
would be up to the task now.
- Modern Flash relies a lot on user input. Particular in 0.8 there was
a lot of buffering taking place inside pipelines, which made user
input feel very unresponsive. I have no idea how much that is still
the case in 0.10.
- The audio issues pointed out in 2) might be interesting, too, in
particular when thinking about autoplugging.
Nonetheless I am very interested in a working GStreamer plugin for
Swfdec. And I bet a lot of other people are, too. While designing the
Swfdec API [6], I kept in mind that people want to use Swfdec inside
GStreamer, so I hope there are no obstacles in implementing a
GStreamer plugin. If there are, I'm of course open to change the API,
since it's by no means frozen.
So if anyone is looking for an interesting project to do, this might
be it. I'll gladly help everyone trying to make this happen, but I
certainly do not have enough time to do it myself, since making Swfdec
correctly decode SWF files takes up 150% of my time already.
Cheers,
Benjamin
[1]
http://gitweb.freedesktop.org/?p=swfdec.git;a=blob;f=libswfdec/swfdec_codec.h
[2] http://brajeshwar.com/reference/as2/NetStream.html
[3] http://brajeshwar.com/reference/as2/Sound.html
[4] http://swfdec.freedesktop.org/documentation/swfdec/SwfdecAudio.html
[5]
http://swfdec.freedesktop.org/documentation/swfdec/SwfdecPlayer.html#SwfdecPlayer-audio-added
[6] http://swfdec.freedesktop.org/documentation/swfdec/
More information about the Swfdec
mailing list