[Swfdec-commits] 8 commits - configure.ac swfdec/swfdec_codec_gst.c swfdec/swfdec_flv_decoder.c swfdec/swfdec_internal.h swfdec/swfdec_player.c swfdec/swfdec_player.h swfdec/swfdec_player_internal.h swfdec/swfdec_sound.c swfdec/swfdec_video.c test/sound test/swfdec_test_plugin.c tools/crashfinder.c
Benjamin Otte
company at kemper.freedesktop.org
Fri Feb 8 01:23:13 PST 2008
configure.ac | 3
swfdec/swfdec_codec_gst.c | 150 ++++++++++++++++++++++++++++++++--------
swfdec/swfdec_flv_decoder.c | 12 ++-
swfdec/swfdec_internal.h | 7 +
swfdec/swfdec_player.c | 133 +++++++++++++++++++++++++++++------
swfdec/swfdec_player.h | 4 -
swfdec/swfdec_player_internal.h | 7 +
swfdec/swfdec_sound.c | 5 +
swfdec/swfdec_video.c | 2
test/sound/Makefile.am | 6 -
test/swfdec_test_plugin.c | 3
tools/crashfinder.c | 4 -
12 files changed, 267 insertions(+), 69 deletions(-)
New commits:
commit 0d69659987848bcd2e22f200a866b98dd1044521
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Feb 8 10:18:10 2008 +0100
add how swfdec_player_advance() works
It used to tigger all the timeouts that were necessary to advance the specified
msecs. Now it just advances to the first event. This was necessary to allow
easy abort on events like missing plugins.
Ilike that it has surprisingly little impact on the code we have already
written, because that one advances by swfdec_player_get_next_event()'s return
value, which is exactly what this change enforces. I guess the only app not
doing this will be the thumbnailer, and I haven't looked at it yet.
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 03e3cbd..ba499f8 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -243,7 +243,12 @@ swfdec_player_get_next_event_time (SwfdecPlayer *player)
SwfdecPlayerPrivate *priv = player->priv;
if (priv->timeouts) {
- return ((SwfdecTimeout *) priv->timeouts->data)->timestamp - priv->time;
+ SwfdecTick next = ((SwfdecTimeout *) priv->timeouts->data)->timestamp;
+ /* This can happen because advancing only uses millisecond granularity */
+ if (next < priv->time)
+ return 0;
+ else
+ return next - priv->time;
} else {
return G_MAXUINT64;
}
@@ -1443,36 +1448,26 @@ swfdec_player_do_advance (SwfdecPlayer *player, gulong msecs, guint audio_sample
SwfdecPlayerPrivate *priv = player->priv;
SwfdecTimeout *timeout;
SwfdecTick target_time;
- guint frames_now;
if (!swfdec_player_lock (player))
return;
+ g_assert (priv->timeouts != NULL);
+
target_time = priv->time + SWFDEC_MSECS_TO_TICKS (msecs);
SWFDEC_DEBUG ("advancing %lu msecs (%u audio frames)", msecs, audio_samples);
- for (timeout = priv->timeouts ? priv->timeouts->data : NULL;
- timeout && timeout->timestamp <= target_time;
- timeout = priv->timeouts ? priv->timeouts->data : NULL) {
+ timeout = priv->timeouts->data;
+ swfdec_player_advance_audio (player, audio_samples);
+ if (timeout->timestamp <= target_time) {
priv->timeouts = g_list_remove (priv->timeouts, timeout);
- frames_now = SWFDEC_TICKS_TO_SAMPLES (timeout->timestamp) -
- SWFDEC_TICKS_TO_SAMPLES (priv->time);
priv->time = timeout->timestamp;
- swfdec_player_advance_audio (player, frames_now);
- audio_samples -= frames_now;
- SWFDEC_LOG ("activating timeout %p now (timeout is %"G_GUINT64_FORMAT", target time is %"G_GUINT64_FORMAT,
- timeout, timeout->timestamp, target_time);
+ SWFDEC_LOG ("activating timeout %p now (timeout is %"G_GUINT64_FORMAT,
+ timeout, timeout->timestamp);
timeout->callback (timeout);
swfdec_player_perform_actions (player);
}
- if (target_time > priv->time) {
- frames_now = SWFDEC_TICKS_TO_SAMPLES (target_time) -
- SWFDEC_TICKS_TO_SAMPLES (priv->time);
- priv->time = target_time;
- swfdec_player_advance_audio (player, frames_now);
- audio_samples -= frames_now;
- }
- g_assert (audio_samples == 0);
+ priv->time = target_time;
g_object_notify (G_OBJECT (player), "next-event");
swfdec_player_unlock (player);
@@ -2548,23 +2543,36 @@ swfdec_player_render (SwfdecPlayer *player, cairo_t *cr,
/**
* swfdec_player_advance:
* @player: the #SwfdecPlayer to advance
- * @msecs: number of milliseconds to advance
+ * @msecs: number of milliseconds to advance at maximum
*
- * Advances @player by @msecs. You should make sure to call this function as
- * often as the SwfdecPlayer::next-event property indicates.
+ * Advances @player by @msecs or at most one event, whatever happens first in
+ * the player's timeline. You should make sure to call this function as often
+ * as swfdec_player_get_next_event() indicates or your player will not appear
+ * smooth.
+ *
+ * Returns: actual number of milliseconds advanced.
**/
-void
+gulong
swfdec_player_advance (SwfdecPlayer *player, gulong msecs)
{
SwfdecPlayerPrivate *priv;
guint frames;
+ glong max;
- g_return_if_fail (SWFDEC_IS_PLAYER (player));
+ g_return_val_if_fail (SWFDEC_IS_PLAYER (player), 0);
+ /* find the max time to advance */
+ max = swfdec_player_get_next_event (player);
+ if (max < 0)
+ msecs = 0;
+ else
+ msecs = MIN ((gulong) max, msecs);
priv = player->priv;
frames = SWFDEC_TICKS_TO_SAMPLES (priv->time + SWFDEC_MSECS_TO_TICKS (msecs))
- SWFDEC_TICKS_TO_SAMPLES (priv->time);
g_signal_emit (player, signals[ADVANCE], 0, msecs, frames);
+
+ return msecs;
}
/**
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index 881de79..a77addf 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -149,7 +149,7 @@ void swfdec_player_render (SwfdecPlayer * player,
double y,
double width,
double height);
-void swfdec_player_advance (SwfdecPlayer * player,
+gulong swfdec_player_advance (SwfdecPlayer * player,
gulong msecs);
gboolean swfdec_player_mouse_move (SwfdecPlayer * player,
double x,
diff --git a/test/swfdec_test_plugin.c b/test/swfdec_test_plugin.c
index 62768a7..24719fb 100644
--- a/test/swfdec_test_plugin.c
+++ b/test/swfdec_test_plugin.c
@@ -37,8 +37,7 @@ swfdec_test_plugin_swfdec_advance (SwfdecTestPlugin *plugin, unsigned int msecs)
if (next_event < 0)
break;
next_event = MIN (next_event, (long) msecs);
- swfdec_player_advance (plugin->data, next_event);
- msecs -= next_event;
+ msecs -= swfdec_player_advance (plugin->data, next_event);
}
}
}
diff --git a/tools/crashfinder.c b/tools/crashfinder.c
index 7c3898a..4d8f36d 100644
--- a/tools/crashfinder.c
+++ b/tools/crashfinder.c
@@ -119,11 +119,9 @@ main (int argc, char **argv)
advance = swfdec_player_get_next_event (player);
if (advance == -1)
break;
- swfdec_player_advance (player, advance);
+ played += swfdec_player_advance (player, advance);
swfdec_player_render (player, cr, 0, 0, 0, 0);
-
- played += advance;
}
if (elapsed >= max_per_file ||
commit cd24919277a7c5af723145972c85d88318306dbb
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Feb 8 09:47:13 2008 +0100
fix various bugs
- SEGV when factory was NULL
- need to keep a reference to the element factory
- SwfdecPlayerClass now has a vfunc for missing plugins
- run gst_init() from swfdec_init()
diff --git a/swfdec/swfdec_codec_gst.c b/swfdec/swfdec_codec_gst.c
index 8736a55..ade7277 100644
--- a/swfdec/swfdec_codec_gst.c
+++ b/swfdec/swfdec_codec_gst.c
@@ -173,6 +173,7 @@ swfdec_gst_get_element_factory (GstCaps *caps)
list = g_list_sort (list, swfdec_gst_compare_features);
ret = list->data;
+ gst_object_ref (ret);
gst_plugin_feature_list_free (list);
return ret;
}
@@ -259,7 +260,10 @@ swfdec_gst_decoder_init (SwfdecGstDecoder *dec, const char *name, GstCaps *srcca
dec->decoder = gst_element_factory_make (name, "decoder");
} else {
GstElementFactory *factory = swfdec_gst_get_element_factory (srccaps);
- dec->decoder = gst_element_factory_create (factory, "decoder");
+ if (factory) {
+ dec->decoder = gst_element_factory_create (factory, "decoder");
+ gst_object_unref (factory);
+ }
}
if (dec->decoder == NULL) {
SWFDEC_ERROR ("failed to create decoder");
@@ -445,10 +449,6 @@ swfdec_audio_decoder_gst_new (guint type, SwfdecAudioFormat format)
SwfdecGstAudio *player;
GstCaps *srccaps, *sinkcaps;
- if (!gst_init_check (NULL, NULL, NULL))
- return NULL;
- gst_pb_utils_init ();
-
srccaps = swfdec_audio_decoder_get_caps (type, format);
if (srccaps == NULL)
return NULL;
@@ -611,10 +611,6 @@ swfdec_video_decoder_gst_new (guint codec)
SwfdecGstVideo *player;
GstCaps *srccaps, *sinkcaps;
- if (!gst_init_check (NULL, NULL, NULL))
- return NULL;
- gst_pb_utils_init ();
-
srccaps = swfdec_video_decoder_get_caps (codec);
if (srccaps == NULL)
return NULL;
@@ -652,8 +648,10 @@ swfdec_audio_decoder_gst_missing (guint codec, SwfdecAudioFormat format)
/* If we can already handle it, woohoo! */
factory = swfdec_gst_get_element_factory (caps);
- if (factory != NULL)
+ if (factory != NULL) {
+ gst_object_unref (factory);
return NULL;
+ }
/* need to install plugins... */
ret = gst_missing_decoder_installer_detail_new (caps);
@@ -679,8 +677,10 @@ swfdec_video_decoder_gst_missing (guint codec)
/* If we can already handle it, woohoo! */
factory = swfdec_gst_get_element_factory (caps);
- if (factory != NULL)
+ if (factory != NULL) {
+ gst_object_unref (factory);
return NULL;
+ }
/* need to install plugins... */
ret = gst_missing_decoder_installer_detail_new (caps);
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 6b2de97..03e3cbd 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -22,6 +22,8 @@
#endif
#include <errno.h>
+#include <gst/gst.h>
+#include <gst/pbutils/pbutils.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
@@ -1844,7 +1846,8 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
*
*/
signals[MISSING_PLUGINS] = g_signal_new ("missing-plugins", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwfdecPlayerClass, missing_plugins),
+ NULL, NULL, g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE, 1, G_TYPE_STRV);
context_class->mark = swfdec_player_mark;
@@ -2329,6 +2332,10 @@ swfdec_init (void)
g_thread_init (NULL);
g_type_init ();
oil_init ();
+#ifdef HAVE_GST
+ gst_init (NULL, NULL);
+ gst_pb_utils_init ();
+#endif
s = g_getenv ("SWFDEC_DEBUG");
if (s && s[0]) {
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index 5c32f59..881de79 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -89,6 +89,8 @@ struct _SwfdecPlayerClass
double x,
double y,
int button);
+ void (* missing_plugins) (SwfdecPlayer * player,
+ const char ** details);
};
void swfdec_init (void);
commit d699d72e33affe548dad3c309a6ef0eeeb77a46c
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Feb 8 09:45:32 2008 +0100
advertise video and audio codec
diff --git a/swfdec/swfdec_flv_decoder.c b/swfdec/swfdec_flv_decoder.c
index 52f14e2..9652e90 100644
--- a/swfdec/swfdec_flv_decoder.c
+++ b/swfdec/swfdec_flv_decoder.c
@@ -25,6 +25,7 @@
#include "swfdec_audio_internal.h"
#include "swfdec_bits.h"
#include "swfdec_debug.h"
+#include "swfdec_player_internal.h"
enum {
SWFDEC_STATE_HEADER, /* need to parse header */
@@ -252,6 +253,7 @@ swfdec_flv_decoder_parse_video_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
}
if (flv->video->len == 0) {
g_array_append_val (flv->video, tag);
+ swfdec_player_use_video_codec (SWFDEC_DECODER (flv)->player, tag.format);
} else if (g_array_index (flv->video, SwfdecFlvVideoTag,
flv->video->len - 1).timestamp < tag.timestamp) {
g_array_append_val (flv->video, tag);
@@ -266,7 +268,7 @@ swfdec_flv_decoder_parse_video_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
return SWFDEC_STATUS_IMAGE;
}
-static void
+static SwfdecStatus
swfdec_flv_decoder_parse_audio_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, guint timestamp)
{
SwfdecFlvAudioTag tag;
@@ -274,7 +276,7 @@ swfdec_flv_decoder_parse_audio_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
if (flv->audio == NULL) {
SWFDEC_INFO ("audio tags even though header didn't decalre them. Initializing...");
flv->audio = g_array_new (FALSE, FALSE, sizeof (SwfdecFlvAudioTag));
- return;
+ return SWFDEC_STATUS_OK;
}
tag.timestamp = timestamp;
@@ -285,10 +287,11 @@ swfdec_flv_decoder_parse_audio_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
SWFDEC_LOG (" format: %s", swfdec_audio_format_to_string (tag.original_format));
if (tag.buffer == NULL) {
SWFDEC_WARNING ("no buffer, ignoring");
- return;
+ return SWFDEC_STATUS_OK;
}
if (flv->audio->len == 0) {
g_array_append_val (flv->audio, tag);
+ swfdec_player_use_audio_codec (SWFDEC_DECODER (flv)->player, tag.format, tag.original_format);
} else if (g_array_index (flv->audio, SwfdecFlvAudioTag,
flv->audio->len - 1).timestamp < tag.timestamp) {
g_array_append_val (flv->audio, tag);
@@ -300,6 +303,7 @@ swfdec_flv_decoder_parse_audio_tag (SwfdecFlvDecoder *flv, SwfdecBits *bits, gui
idx = swfdec_flv_decoder_find_audio (flv, tag.timestamp);
g_array_insert_val (flv->audio, idx, tag);
}
+ return SWFDEC_STATUS_OK;
}
static void
@@ -364,7 +368,7 @@ swfdec_flv_decoder_parse_tag (SwfdecFlvDecoder *flv)
SWFDEC_LOG (" timestamp %u", timestamp);
switch (type) {
case 8:
- swfdec_flv_decoder_parse_audio_tag (flv, &bits, timestamp);
+ ret = swfdec_flv_decoder_parse_audio_tag (flv, &bits, timestamp);
break;
case 9:
ret = swfdec_flv_decoder_parse_video_tag (flv, &bits, timestamp);
commit 6c8e47fbf2dae7cdc4b711cc1b9947ffe9332f76
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Feb 8 09:39:43 2008 +0100
advertise the audio codec
diff --git a/swfdec/swfdec_sound.c b/swfdec/swfdec_sound.c
index cb1e97c..96fc1fd 100644
--- a/swfdec/swfdec_sound.c
+++ b/swfdec/swfdec_sound.c
@@ -29,6 +29,7 @@
#include "swfdec_buffer.h"
#include "swfdec_button.h"
#include "swfdec_debug.h"
+#include "swfdec_player_internal.h"
#include "swfdec_sprite.h"
#include "swfdec_swf_decoder.h"
@@ -160,6 +161,8 @@ tag_func_define_sound (SwfdecSwfDecoder * s, guint tag)
}
sound->n_samples *= swfdec_audio_format_get_granularity (sound->format);
+ swfdec_player_use_audio_codec (SWFDEC_DECODER (s)->player, sound->codec, sound->format);
+
return SWFDEC_STATUS_OK;
}
@@ -286,6 +289,8 @@ tag_func_sound_stream_head (SwfdecSwfDecoder * s, guint tag)
sound->codec = SWFDEC_AUDIO_CODEC_UNDEFINED;
}
+ swfdec_player_use_audio_codec (SWFDEC_DECODER (s)->player, sound->codec, sound->format);
+
return SWFDEC_STATUS_OK;
}
commit 407168c83abbf725e4e7160f6191b9683383b5ad
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Feb 8 09:39:23 2008 +0100
advertise usage of the video codec
diff --git a/swfdec/swfdec_video.c b/swfdec/swfdec_video.c
index 7ff8d8f..215c6dd 100644
--- a/swfdec/swfdec_video.c
+++ b/swfdec/swfdec_video.c
@@ -26,6 +26,7 @@
#include "swfdec_video.h"
#include "swfdec_debug.h"
#include "swfdec_font.h"
+#include "swfdec_player_internal.h"
#include "swfdec_swf_decoder.h"
#include "swfdec_video_movie.h"
@@ -239,6 +240,7 @@ tag_func_define_video (SwfdecSwfDecoder *s, guint tag)
SWFDEC_LOG (" deblocking: %d", deblocking);
SWFDEC_LOG (" smoothing: %d", smoothing);
SWFDEC_LOG (" format: %d", (int) video->format);
+ swfdec_player_use_video_codec (SWFDEC_DECODER (s)->player, video->format);
return SWFDEC_STATUS_OK;
}
commit 0fd15057d2daa3ead3042104c933d715a7179a56
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Feb 8 09:37:41 2008 +0100
update GStreamer requirements for missing plugin stuff
Yes, it requires GStreamer 0.10.17 now (actually 0.10.15 is fine, but would
bloat configure.ac). It's a bit unfortunate, just like libsoup-2.4, but should
be solved with the next round of distros. Hardy, unstable and rawhide pretty
likely have packages for this. Hardy does, and it's easy to just grab them for
Gutsy.
diff --git a/configure.ac b/configure.ac
index cac18b7..d5222cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -250,7 +250,8 @@ AC_ARG_ENABLE(gstreamer,
if test "$enable_gstreamer" = "yes"; then
GST_REQUIRED=0.10.11
- PKG_CHECK_MODULES(GST, gstreamer-0.10 >= $GST_REQUIRED, HAVE_GST=yes, HAVE_GST=no)
+ GST_PB_REQUIRED=0.10.15
+ PKG_CHECK_MODULES(GST, gstreamer-0.10 >= $GST_REQUIRED gstreamer-pbutils-0.10 >= $GST_PB_REQUIRED, HAVE_GST=yes, HAVE_GST=no)
if test "x$HAVE_GST" = xyes; then
AC_DEFINE(HAVE_GST, 1, [Define if GStreamer is enabled])
else
commit 55475e671b34180d2bfada1badab2967edfbe985
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Feb 7 21:46:06 2008 +0100
implement functions for notifying of missing functions
THey're not used yet though
diff --git a/swfdec/swfdec_codec_gst.c b/swfdec/swfdec_codec_gst.c
index ebcd75f..8736a55 100644
--- a/swfdec/swfdec_codec_gst.c
+++ b/swfdec/swfdec_codec_gst.c
@@ -22,12 +22,62 @@
#endif
#include <string.h>
#include <gst/gst.h>
+#include <gst/pbutils/pbutils.h>
#include "swfdec_codec_audio.h"
#include "swfdec_codec_video.h"
#include "swfdec_debug.h"
#include "swfdec_internal.h"
+/*** CAPS MATCHING ***/
+
+static GstCaps *
+swfdec_audio_decoder_get_caps (guint codec, SwfdecAudioFormat format)
+{
+ GstCaps *caps;
+ char *s;
+
+ switch (codec) {
+ case SWFDEC_AUDIO_CODEC_MP3:
+ s = g_strdup ("audio/mpeg, mpegversion=(int)1, layer=(int)3");
+ break;
+ case SWFDEC_AUDIO_CODEC_NELLYMOSER_8KHZ:
+ s = g_strdup ("audio/x-nellymoser, rate=8000, channels=1");
+ break;
+ case SWFDEC_AUDIO_CODEC_NELLYMOSER:
+ s = g_strdup_printf ("audio/x-nellymoser, rate=%d, channels=%d",
+ swfdec_audio_format_get_rate (format),
+ swfdec_audio_format_get_channels (format));
+ break;
+ default:
+ return NULL;
+ }
+
+ caps = gst_caps_from_string (s);
+ g_assert (caps);
+ g_free (s);
+ return caps;
+}
+
+static GstCaps *
+swfdec_video_decoder_get_caps (guint codec)
+{
+ GstCaps *caps;
+
+ switch (codec) {
+ case SWFDEC_VIDEO_CODEC_H263:
+ caps = gst_caps_from_string ("video/x-flash-video");
+ break;
+ case SWFDEC_VIDEO_CODEC_VP6:
+ caps = gst_caps_from_string ("video/x-vp6-flash");
+ break;
+ default:
+ return NULL;
+ }
+ g_assert (caps);
+ return caps;
+}
+
/*** BUFFER ***/
/* NB: references argument more than once */
@@ -110,10 +160,10 @@ swfdec_gst_compare_features (gconstpointer a_, gconstpointer b_)
return strcmp (gst_plugin_feature_get_name (a), gst_plugin_feature_get_name (b));
}
-static GstElement *
-swfdec_gst_get_element (GstCaps *caps)
+static GstElementFactory *
+swfdec_gst_get_element_factory (GstCaps *caps)
{
- GstElement *element;
+ GstElementFactory *ret;
GList *list;
list = gst_registry_feature_filter (gst_registry_get_default (),
@@ -122,9 +172,9 @@ swfdec_gst_get_element (GstCaps *caps)
return NULL;
list = g_list_sort (list, swfdec_gst_compare_features);
- element = gst_element_factory_create (list->data, "decoder");
+ ret = list->data;
gst_plugin_feature_list_free (list);
- return element;
+ return ret;
}
/*** PADS ***/
@@ -208,7 +258,8 @@ swfdec_gst_decoder_init (SwfdecGstDecoder *dec, const char *name, GstCaps *srcca
if (name) {
dec->decoder = gst_element_factory_make (name, "decoder");
} else {
- dec->decoder = swfdec_gst_get_element (srccaps);
+ GstElementFactory *factory = swfdec_gst_get_element_factory (srccaps);
+ dec->decoder = gst_element_factory_create (factory, "decoder");
}
if (dec->decoder == NULL) {
SWFDEC_ERROR ("failed to create decoder");
@@ -396,15 +447,11 @@ swfdec_audio_decoder_gst_new (guint type, SwfdecAudioFormat format)
if (!gst_init_check (NULL, NULL, NULL))
return NULL;
+ gst_pb_utils_init ();
- switch (type) {
- case SWFDEC_AUDIO_CODEC_MP3:
- srccaps = gst_caps_from_string ("audio/mpeg, mpegversion=(int)1, layer=(int)3");
- break;
- default:
- return NULL;
- }
- g_assert (srccaps);
+ srccaps = swfdec_audio_decoder_get_caps (type, format);
+ if (srccaps == NULL)
+ return NULL;
player = g_slice_new0 (SwfdecGstAudio);
player->decoder.format = SWFDEC_AUDIO_FORMAT_INVALID;
@@ -566,18 +613,11 @@ swfdec_video_decoder_gst_new (guint codec)
if (!gst_init_check (NULL, NULL, NULL))
return NULL;
+ gst_pb_utils_init ();
- switch (codec) {
- case SWFDEC_VIDEO_CODEC_H263:
- srccaps = gst_caps_from_string ("video/x-flash-video");
- break;
- case SWFDEC_VIDEO_CODEC_VP6:
- srccaps = gst_caps_from_string ("video/x-vp6-flash");
- break;
- default:
- return NULL;
- }
- g_assert (srccaps);
+ srccaps = swfdec_video_decoder_get_caps (codec);
+ if (srccaps == NULL)
+ return NULL;
sinkcaps = swfdec_video_decoder_get_sink_caps (codec);
player = g_slice_new0 (SwfdecGstVideo);
@@ -596,3 +636,55 @@ swfdec_video_decoder_gst_new (guint codec)
return &player->decoder;
}
+/*** MISSING PLUGIN SUPPORT ***/
+
+char *
+swfdec_audio_decoder_gst_missing (guint codec, SwfdecAudioFormat format)
+{
+ GstElementFactory *factory;
+ GstCaps *caps;
+ char *ret;
+
+ /* Check if we can handle the format at all. If not, no plugin will help us. */
+ caps = swfdec_audio_decoder_get_caps (codec, format);
+ if (caps == NULL)
+ return NULL;
+
+ /* If we can already handle it, woohoo! */
+ factory = swfdec_gst_get_element_factory (caps);
+ if (factory != NULL)
+ return NULL;
+
+ /* need to install plugins... */
+ ret = gst_missing_decoder_installer_detail_new (caps);
+ gst_caps_unref (caps);
+ return ret;
+}
+
+char *
+swfdec_video_decoder_gst_missing (guint codec)
+{
+ GstElementFactory *factory;
+ GstCaps *caps;
+ char *ret;
+
+ /* This is necessary because the VP6 alpha decoder uses 2 VP6 decoders */
+ if (codec == SWFDEC_VIDEO_CODEC_VP6_ALPHA)
+ codec = SWFDEC_VIDEO_CODEC_VP6;
+
+ /* Check if we can handle the format at all. If not, no plugin will help us. */
+ caps = swfdec_video_decoder_get_caps (codec);
+ if (caps == NULL)
+ return NULL;
+
+ /* If we can already handle it, woohoo! */
+ factory = swfdec_gst_get_element_factory (caps);
+ if (factory != NULL)
+ return NULL;
+
+ /* need to install plugins... */
+ ret = gst_missing_decoder_installer_detail_new (caps);
+ gst_caps_unref (caps);
+ return ret;
+}
+
diff --git a/swfdec/swfdec_internal.h b/swfdec/swfdec_internal.h
index 41d8664..479397a 100644
--- a/swfdec/swfdec_internal.h
+++ b/swfdec/swfdec_internal.h
@@ -44,6 +44,10 @@ SwfdecAudioDecoder * swfdec_audio_decoder_ffmpeg_new (guint type,
#ifdef HAVE_GST
SwfdecAudioDecoder * swfdec_audio_decoder_gst_new (guint type,
SwfdecAudioFormat format);
+char * swfdec_audio_decoder_gst_missing (guint codec,
+ SwfdecAudioFormat format);
+#else
+#define swfdec_audio_decoder_gst_missing(codec) NULL
#endif
/* video codecs */
@@ -55,6 +59,9 @@ SwfdecVideoDecoder * swfdec_video_decoder_ffmpeg_new (guint format);
#endif
#ifdef HAVE_GST
SwfdecVideoDecoder * swfdec_video_decoder_gst_new (guint format);
+char * swfdec_video_decoder_gst_missing (guint codec);
+#else
+#define swfdec_video_decoder_gst_missing(codec) NULL
#endif
/* AS engine setup code */
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index e0c59ac..6b2de97 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -36,6 +36,7 @@
#include "swfdec_debug.h"
#include "swfdec_enums.h"
#include "swfdec_event.h"
+#include "swfdec_internal.h"
#include "swfdec_loader_internal.h"
#include "swfdec_marshal.h"
#include "swfdec_movie.h"
@@ -597,6 +598,7 @@ enum {
AUDIO_REMOVED,
LAUNCH,
FSCOMMAND,
+ MISSING_PLUGINS,
LAST_SIGNAL
};
@@ -1268,6 +1270,22 @@ swfdec_player_emit_signals (SwfdecPlayer *player)
g_signal_emit (player, signals[AUDIO_ADDED], 0, audio);
audio->added = TRUE;
}
+
+ /* emit missing-plugin signal for newly discovered plugins */
+ if (priv->missing_plugins) {
+ GSList *swalk;
+ guint i = 0;
+ char **details = g_new (char *, g_slist_length (priv->missing_plugins) + 1);
+
+ for (swalk = priv->missing_plugins; swalk; swalk = swalk->next) {
+ details[i++] = swalk->data;
+ }
+ details[i] = NULL;
+ g_slist_free (priv->missing_plugins);
+ priv->missing_plugins = NULL;
+ g_signal_emit (player, signals[MISSING_PLUGINS], 0, details);
+ g_strfreev (details);
+ }
}
static gboolean
@@ -1819,6 +1837,15 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
G_SIGNAL_RUN_LAST, 0, NULL, NULL, swfdec_marshal_VOID__ENUM_STRING_STRING_BOXED,
G_TYPE_NONE, 4, SWFDEC_TYPE_LOADER_REQUEST, G_TYPE_STRING, G_TYPE_STRING,
SWFDEC_TYPE_BUFFER);
+ /**
+ * SwfdecPlayer::missing-plugins:
+ * @player: the #SwfdecPlayer missing plugins
+ * @details: the details strigs for all missing plugins
+ *
+ */
+ signals[MISSING_PLUGINS] = g_signal_new ("missing-plugins", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1, G_TYPE_STRV);
context_class->mark = swfdec_player_mark;
context_class->get_time = swfdec_player_get_time;
@@ -2207,6 +2234,49 @@ swfdec_player_load (SwfdecPlayer *player, const char *url,
return loader;
}
+void
+swfdec_player_use_audio_codec (SwfdecPlayer *player, guint codec,
+ SwfdecAudioFormat format)
+{
+ SwfdecPlayerPrivate *priv;
+ char *detail;
+
+ g_return_if_fail (SWFDEC_IS_PLAYER (player));
+
+ detail = swfdec_audio_decoder_gst_missing (codec, format);
+ if (detail == NULL)
+ return;
+
+ priv = player->priv;
+ if (g_slist_find_custom (priv->missing_plugins, detail, (GCompareFunc) strcmp)) {
+ g_free (detail);
+ return;
+ }
+
+ priv->missing_plugins = g_slist_prepend (priv->missing_plugins, detail);
+}
+
+void
+swfdec_player_use_video_codec (SwfdecPlayer *player, guint codec)
+{
+ SwfdecPlayerPrivate *priv;
+ char *detail;
+
+ g_return_if_fail (SWFDEC_IS_PLAYER (player));
+
+ detail = swfdec_video_decoder_gst_missing (codec);
+ if (detail == NULL)
+ return;
+
+ priv = player->priv;
+ if (g_slist_find_custom (priv->missing_plugins, detail, (GCompareFunc) strcmp)) {
+ g_free (detail);
+ return;
+ }
+
+ priv->missing_plugins = g_slist_prepend (priv->missing_plugins, detail);
+}
+
/** PUBLIC API ***/
/**
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index e371391..71569be 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -22,6 +22,7 @@
#include <swfdec/swfdec_player.h>
#include <swfdec/swfdec_audio.h>
+#include <swfdec/swfdec_audio_internal.h>
#include <swfdec/swfdec_event.h>
#include <swfdec/swfdec_function_list.h>
#include <swfdec/swfdec_loader.h>
@@ -123,6 +124,7 @@ struct _SwfdecPlayerPrivate
/* audio */
GList * audio; /* list of playing SwfdecAudio */
+ GSList * missing_plugins; /* list of GStreamer detail strings for missing plugins */
/* events and advancing */
SwfdecTick time; /* current time */
@@ -243,6 +245,11 @@ void swfdec_player_global_to_stage (SwfdecPlayer * player,
double * y);
void swfdec_player_update_scale (SwfdecPlayer * player);
+void swfdec_player_use_audio_codec (SwfdecPlayer * player,
+ guint codec,
+ SwfdecAudioFormat format);
+void swfdec_player_use_video_codec (SwfdecPlayer * player,
+ guint codec);
/* in swfdec_policy_file.c */
gboolean swfdec_player_allow_now (SwfdecPlayer * player,
const SwfdecURL * url);
commit 7576b2417f17b885204e0345045638736c00d0bb
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Feb 7 16:20:36 2008 +0100
don't list nonexisting files
diff --git a/test/sound/Makefile.am b/test/sound/Makefile.am
index 96e859a..73a6643 100644
--- a/test/sound/Makefile.am
+++ b/test/sound/Makefile.am
@@ -36,10 +36,6 @@ EXTRA_DIST = \
adpcm-5-2.swf.1.0.raw \
crash-0.5.3-no-samples.c \
crash-0.5.3-no-samples.swf \
- crash-0.5.3-no-samples.swf.1.0.raw \
- crash-0.5.3-no-samples.swf.3.0.raw \
- crash-0.5.3-no-samples.swf.5.0.raw \
- crash-0.5.3-no-samples.swf.7.0.raw \
- crash-0.5.3-no-samples.swf.9.0.raw
+ crash-0.5.3-no-samples.swf.1.0.raw
CLEANFILES = tmp
More information about the Swfdec-commits
mailing list