[Swfdec-commits] 8 commits - doc/swfdec-sections.txt swfdec-gtk/Makefile.am swfdec-gtk/swfdec_gtk_player.c swfdec-gtk/swfdec_gtk_player.h swfdec/swfdec_codec_audio.c swfdec/swfdec_codec_audio.h swfdec/swfdec_codec_ffmpeg.c swfdec/swfdec_codec_gst.c swfdec/swfdec_codec_mad.c swfdec/swfdec_codec_video.c swfdec/swfdec_codec_video.h swfdec/swfdec_internal.h swfdec/swfdec_player.c swfdec/swfdec_system_as.c swfdec/swfdec_video_movie.c test/swfdec_test_plugin.c

Benjamin Otte company at kemper.freedesktop.org
Fri Feb 8 13:42:35 PST 2008


 doc/swfdec-sections.txt        |    8 +-
 swfdec-gtk/Makefile.am         |    4 -
 swfdec-gtk/swfdec_gtk_player.c |  141 ++++++++++++++++++++++++++++++++++++++++-
 swfdec-gtk/swfdec_gtk_player.h |    6 +
 swfdec/swfdec_codec_audio.c    |   82 +++++++++++++----------
 swfdec/swfdec_codec_audio.h    |    3 
 swfdec/swfdec_codec_ffmpeg.c   |   14 ++++
 swfdec/swfdec_codec_gst.c      |   30 +++-----
 swfdec/swfdec_codec_mad.c      |    6 +
 swfdec/swfdec_codec_video.c    |   79 +++++++++++++---------
 swfdec/swfdec_codec_video.h    |    1 
 swfdec/swfdec_internal.h       |   20 +++--
 swfdec/swfdec_player.c         |    4 -
 swfdec/swfdec_system_as.c      |   13 +--
 swfdec/swfdec_video_movie.c    |    2 
 test/swfdec_test_plugin.c      |   17 ++--
 16 files changed, 311 insertions(+), 119 deletions(-)

New commits:
commit 703660b0e7d2e4be1fbf60385ea92554346f5984
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 8 22:42:14 2008 +0100

    make System.settings.hasMP3 querying work with _prepare

diff --git a/swfdec/swfdec_codec_audio.c b/swfdec/swfdec_codec_audio.c
index dfe0944..27bf03f 100644
--- a/swfdec/swfdec_codec_audio.c
+++ b/swfdec/swfdec_codec_audio.c
@@ -146,8 +146,8 @@ static const struct {
 #endif
 };
 
-char *
-swfdec_audio_decoder_prepare (guint codec, SwfdecAudioFormat format)
+gboolean
+swfdec_audio_decoder_prepare (guint codec, SwfdecAudioFormat format, char **missing)
 {
   char *detail = NULL, *s = NULL;
   guint i;
@@ -156,7 +156,9 @@ swfdec_audio_decoder_prepare (guint codec, SwfdecAudioFormat format)
     if (audio_codecs[i].prepare (codec, format, &s)) {
       g_free (detail);
       g_free (s);
-      return NULL;
+      if (missing)
+	*missing = NULL;
+      return TRUE;
     }
     if (s) {
       if (detail == NULL)
@@ -166,7 +168,9 @@ swfdec_audio_decoder_prepare (guint codec, SwfdecAudioFormat format)
       s = NULL;
     }
   }
-  return detail;
+  if (missing)
+    *missing = detail;
+  return FALSE;
 }
 
 /**
diff --git a/swfdec/swfdec_codec_audio.h b/swfdec/swfdec_codec_audio.h
index 6ea72f0..d3fb74d 100644
--- a/swfdec/swfdec_codec_audio.h
+++ b/swfdec/swfdec_codec_audio.h
@@ -44,8 +44,9 @@ struct _SwfdecAudioDecoder {
   void		  	(* free)	(SwfdecAudioDecoder *	decoder);
 };
 
-char *			swfdec_audio_decoder_prepare	(guint			codec,
-							 SwfdecAudioFormat	format);
+gboolean		swfdec_audio_decoder_prepare	(guint			codec,
+							 SwfdecAudioFormat	format,
+							 char **		missing);
 SwfdecAudioDecoder *   	swfdec_audio_decoder_new      	(guint			codec,
 							 SwfdecAudioFormat	format);
 void			swfdec_audio_decoder_free      	(SwfdecAudioDecoder *	decoder);
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index d5aa494..e73567c 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -2241,7 +2241,7 @@ swfdec_player_use_audio_codec (SwfdecPlayer *player, guint codec,
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
 
-  detail = swfdec_audio_decoder_prepare (codec, format);
+  swfdec_audio_decoder_prepare (codec, format, &detail);
   if (detail == NULL)
     return;
 
diff --git a/swfdec/swfdec_system_as.c b/swfdec/swfdec_system_as.c
index 0ba3f9e..1e29f50 100644
--- a/swfdec/swfdec_system_as.c
+++ b/swfdec/swfdec_system_as.c
@@ -107,15 +107,10 @@ swfdec_system_has_embedded_video (SwfdecPlayer *player, SwfdecAsValue *ret)
 static void
 swfdec_system_has_mp3 (SwfdecPlayer *player, SwfdecAsValue *ret)
 {
-  SwfdecAudioDecoder *dec = swfdec_audio_decoder_new (SWFDEC_AUDIO_CODEC_MP3, 
-      swfdec_audio_format_new (44100, 2, TRUE));
-
-  if (dec) {
-    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, TRUE);
-    swfdec_audio_decoder_free (dec);
-  } else {
-    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, FALSE);
-  }
+  gboolean result = swfdec_audio_decoder_prepare (SWFDEC_AUDIO_CODEC_MP3, 
+      swfdec_audio_format_new (44100, 2, TRUE), NULL);
+
+  SWFDEC_AS_VALUE_SET_BOOLEAN (ret, result);
 }
 
 static void
commit 921b0d5391ff2860140ac0c8ba87fe572b75ad60
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 8 22:41:04 2008 +0100

    fix advance to always advance until all actions are done
    
    fixes breakage of setinterval tests

diff --git a/test/swfdec_test_plugin.c b/test/swfdec_test_plugin.c
index 24719fb..39d56de 100644
--- a/test/swfdec_test_plugin.c
+++ b/test/swfdec_test_plugin.c
@@ -29,16 +29,15 @@
 static void
 swfdec_test_plugin_swfdec_advance (SwfdecTestPlugin *plugin, unsigned int msecs)
 {
-  if (msecs == 0) {
+  while (plugin->data && msecs > 0) {
+    long next_event = swfdec_player_get_next_event (plugin->data);
+    if (next_event < 0)
+      break;
+    next_event = MIN (next_event, (long) msecs);
+    msecs -= swfdec_player_advance (plugin->data, next_event);
+  }
+  while (plugin->data && swfdec_player_get_next_event (plugin->data) == 0) {
     swfdec_player_advance (plugin->data, 0);
-  } else {
-    while (msecs > 0 && plugin->data) {
-      long next_event = swfdec_player_get_next_event (plugin->data);
-      if (next_event < 0)
-	break;
-      next_event = MIN (next_event, (long) msecs);
-      msecs -= swfdec_player_advance (plugin->data, next_event);
-    }
   }
 }
 
commit 662d4dbc0f5e4e69a61dff01922da68fa2ae0e0f
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 8 22:29:46 2008 +0100

    make video codec detection work the same way as audio

diff --git a/swfdec/swfdec_codec_ffmpeg.c b/swfdec/swfdec_codec_ffmpeg.c
index 601f9d6..8bfc889 100644
--- a/swfdec/swfdec_codec_ffmpeg.c
+++ b/swfdec/swfdec_codec_ffmpeg.c
@@ -287,6 +287,14 @@ swfdec_video_decoder_ffmpeg_free (SwfdecVideoDecoder *dec)
   g_free (codec);
 }
 
+gboolean
+swfdec_video_decoder_ffmpeg_prepare (guint codec, char **detail)
+{
+  return codec == SWFDEC_VIDEO_CODEC_H263 ||
+    codec == SWFDEC_VIDEO_CODEC_SCREEN ||
+    codec == SWFDEC_VIDEO_CODEC_VP6;
+}
+
 SwfdecVideoDecoder *
 swfdec_video_decoder_ffmpeg_new (guint type)
 {
diff --git a/swfdec/swfdec_codec_gst.c b/swfdec/swfdec_codec_gst.c
index 679bf7e..6b27a67 100644
--- a/swfdec/swfdec_codec_gst.c
+++ b/swfdec/swfdec_codec_gst.c
@@ -658,32 +658,27 @@ swfdec_audio_decoder_gst_prepare (guint codec, SwfdecAudioFormat format, char **
   return FALSE;
 }
 
-char *
-swfdec_video_decoder_gst_missing (guint	codec)
+gboolean
+swfdec_video_decoder_gst_prepare (guint codec, char **detail)
 {
   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;
+    return FALSE;
 
   /* If we can already handle it, woohoo! */
   factory = swfdec_gst_get_element_factory (caps);
   if (factory != NULL) {
     gst_object_unref (factory);
-    return NULL;
+    return TRUE;
   }
 
   /* need to install plugins... */
-  ret = gst_missing_decoder_installer_detail_new (caps);
+  *detail = gst_missing_decoder_installer_detail_new (caps);
   gst_caps_unref (caps);
-  return ret;
+  return FALSE;
 }
 
diff --git a/swfdec/swfdec_codec_video.c b/swfdec/swfdec_codec_video.c
index dcd03ce..0b04285 100644
--- a/swfdec/swfdec_codec_video.c
+++ b/swfdec/swfdec_codec_video.c
@@ -27,6 +27,12 @@
 #include "swfdec_debug.h"
 #include "swfdec_internal.h"
 
+static gboolean
+swfdec_video_decoder_builtin_prepare (guint codec, char **detail)
+{
+  return codec == SWFDEC_VIDEO_CODEC_SCREEN;
+}
+
 static SwfdecVideoDecoder *
 swfdec_video_decoder_builtin_new (guint codec)
 {
@@ -39,20 +45,47 @@ swfdec_video_decoder_builtin_new (guint codec)
   return ret;
 }
 
-struct {
+static const struct {
   const char *		name;
   SwfdecVideoDecoder *	(* func) (guint);
+  gboolean		(* prepare) (guint, char **);
 } video_codecs[] = {
-  { "builtin",	swfdec_video_decoder_builtin_new },
+    { "builtin",	swfdec_video_decoder_builtin_new,	swfdec_video_decoder_builtin_prepare }
 #ifdef HAVE_GST
-  { "gst",	swfdec_video_decoder_gst_new },
+  , { "gst",		swfdec_video_decoder_gst_new,		swfdec_video_decoder_gst_prepare }
 #endif
 #ifdef HAVE_FFMPEG
-  { "ffmpeg",	swfdec_video_decoder_ffmpeg_new },
+  , { "ffmpeg",		swfdec_video_decoder_ffmpeg_new,	swfdec_video_decoder_ffmpeg_prepare }
 #endif
-  { NULL, }
 };
 
+char *
+swfdec_video_decoder_prepare (guint codec)
+{
+  char *detail = NULL, *s = NULL;
+  guint i;
+  
+  /* the builtin codec is implemented as a wrapper around VP6 */
+  if (codec == SWFDEC_VIDEO_CODEC_VP6_ALPHA)
+    codec = SWFDEC_VIDEO_CODEC_VP6;
+
+  for (i = 0; i < G_N_ELEMENTS (video_codecs); i++) {
+    if (video_codecs[i].prepare (codec, &s)) {
+      g_free (detail);
+      g_free (s);
+      return NULL;
+    }
+    if (s) {
+      if (detail == NULL)
+	detail = s;
+      else
+	g_free (s);
+      s = NULL;
+    }
+  }
+  return detail;
+}
+
 /**
  * swfdec_video_decoder_new:
  * @codec: #SwfdecVideoCodec to create the #SwfdecVideoDecoder for
@@ -65,35 +98,13 @@ struct {
 SwfdecVideoDecoder *
 swfdec_video_decoder_new (guint codec)
 {
-  SwfdecVideoDecoder *ret;
-  const char *list;
-
-  list = g_getenv ("SWFDEC_CODEC_VIDEO");
-  if (list == NULL)
-    list = g_getenv ("SWFDEC_CODEC");
-  if (list == NULL) {
-    guint i;
-    ret = NULL;
-    for (i = 0; video_codecs[i].name != NULL; i++) {
-      ret = video_codecs[i].func (codec);
-      if (ret)
-	break;
-    }
-  } else {
-    char **split = g_strsplit (list, ",", -1);
-    guint i, j;
-    ret = NULL;
-    SWFDEC_LOG ("codecs limited to \"%s\"", list);
-    for (i = 0; split[i] != NULL && ret == NULL; i++) {
-      for (j = 0; video_codecs[j].name != NULL; j++) {
-	if (g_ascii_strcasecmp (video_codecs[j].name, split[i]) != 0)
-	  continue;
-	ret = video_codecs[j].func (codec);
-	if (ret)
-	  break;
-      }
-    }
-    g_strfreev (split);
+  SwfdecVideoDecoder *ret = NULL;
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (video_codecs); i++) {
+    ret = video_codecs[i].func (codec);
+    if (ret)
+      break;
   }
 
   if (ret != NULL) {
diff --git a/swfdec/swfdec_codec_video.h b/swfdec/swfdec_codec_video.h
index c58fd03..eb6e3ab 100644
--- a/swfdec/swfdec_codec_video.h
+++ b/swfdec/swfdec_codec_video.h
@@ -64,6 +64,7 @@ struct _SwfdecVideoDecoder {
 
 SwfdecVideoFormat     	swfdec_video_codec_get_format	(guint			codec);
 
+char *			swfdec_video_decoder_prepare	(guint			codec);
 SwfdecVideoDecoder *	swfdec_video_decoder_new      	(guint			codec);
 void			swfdec_video_decoder_free	(SwfdecVideoDecoder *   decoder);
 
diff --git a/swfdec/swfdec_internal.h b/swfdec/swfdec_internal.h
index e1adddf..30a7404 100644
--- a/swfdec/swfdec_internal.h
+++ b/swfdec/swfdec_internal.h
@@ -61,12 +61,13 @@ SwfdecVideoDecoder *	swfdec_video_decoder_screen_new		(guint			format);
 SwfdecVideoDecoder *	swfdec_video_decoder_vp6_alpha_new    	(guint			format);
 #ifdef HAVE_FFMPEG
 SwfdecVideoDecoder *	swfdec_video_decoder_ffmpeg_new		(guint			format);
+gboolean		swfdec_video_decoder_ffmpeg_prepare	(guint			codec,
+								 char **		detail);
 #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
+gboolean		swfdec_video_decoder_gst_prepare	(guint			codec,
+								 char **		detail);
 #endif
 
 /* AS engine setup code */
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index c762bb7..d5aa494 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -2262,7 +2262,7 @@ swfdec_player_use_video_codec (SwfdecPlayer *player, guint codec)
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
 
-  detail = swfdec_video_decoder_gst_missing (codec);
+  detail = swfdec_video_decoder_prepare (codec);
   if (detail == NULL)
     return;
 
commit d099d2b2b4114bb5edf101f58a8eae69207fd024
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 8 21:03:10 2008 +0100

    don't crash if no input is set

diff --git a/swfdec/swfdec_video_movie.c b/swfdec/swfdec_video_movie.c
index b77379a..087797d 100644
--- a/swfdec/swfdec_video_movie.c
+++ b/swfdec/swfdec_video_movie.c
@@ -109,7 +109,7 @@ swfdec_video_movie_set_ratio (SwfdecMovie *movie)
 {
   SwfdecVideoMovie *video = SWFDEC_VIDEO_MOVIE (movie);
 
-  if (video->input->set_ratio) {
+  if (video->input && video->input->set_ratio) {
     video->needs_update = TRUE;
     swfdec_movie_invalidate_last (movie);
   }
commit 5a102efdf026b22755f3fc161cf7d7807369272e
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 8 20:32:27 2008 +0100

    rework plugin checking to take into account different backends
    
    also remove the SWFDEC_CODEC env var hack. If anyone still needs it, feel free
    to readd it.

diff --git a/swfdec/swfdec_codec_audio.c b/swfdec/swfdec_codec_audio.c
index 2d121af..dfe0944 100644
--- a/swfdec/swfdec_codec_audio.c
+++ b/swfdec/swfdec_codec_audio.c
@@ -121,23 +121,54 @@ swfdec_audio_decoder_builtin_new (guint codec, SwfdecAudioFormat format)
   return ret;
 }
 
-struct {
+static gboolean
+swfdec_audio_decoder_builtin_prepare (guint codec, SwfdecAudioFormat format, char **detail)
+{
+  return codec == SWFDEC_AUDIO_CODEC_UNCOMPRESSED ||
+    codec == SWFDEC_AUDIO_CODEC_UNDEFINED ||
+    codec == SWFDEC_AUDIO_CODEC_ADPCM;
+}
+
+static const struct {
   const char *		name;
   SwfdecAudioDecoder *	(* func) (guint, SwfdecAudioFormat);
+  gboolean		(* prepare) (guint, SwfdecAudioFormat, char **);
 } audio_codecs[] = {
-  { "builtin",	swfdec_audio_decoder_builtin_new },
+  { "builtin",	swfdec_audio_decoder_builtin_new, swfdec_audio_decoder_builtin_prepare },
 #ifdef HAVE_GST
-  { "gst",	swfdec_audio_decoder_gst_new },
+  { "gst",	swfdec_audio_decoder_gst_new, swfdec_audio_decoder_gst_prepare },
 #endif
 #ifdef HAVE_MAD
-  { "mad",	swfdec_audio_decoder_mad_new },
+  { "mad",	swfdec_audio_decoder_mad_new, swfdec_audio_decoder_mad_prepare },
 #endif
 #ifdef HAVE_FFMPEG
-  { "ffmpeg",	swfdec_audio_decoder_ffmpeg_new },
+  { "ffmpeg",	swfdec_audio_decoder_ffmpeg_new, swfdec_audio_decoder_ffmpeg_prepare }
 #endif
-  { NULL, }
 };
 
+char *
+swfdec_audio_decoder_prepare (guint codec, SwfdecAudioFormat format)
+{
+  char *detail = NULL, *s = NULL;
+  guint i;
+  
+  for (i = 0; i < G_N_ELEMENTS (audio_codecs); i++) {
+    if (audio_codecs[i].prepare (codec, format, &s)) {
+      g_free (detail);
+      g_free (s);
+      return NULL;
+    }
+    if (s) {
+      if (detail == NULL)
+	detail = s;
+      else
+	g_free (s);
+      s = NULL;
+    }
+  }
+  return detail;
+}
+
 /**
  * swfdec_audio_decoder_new:
  * @format: #SwfdecAudioCodec to decode
@@ -150,37 +181,16 @@ struct {
 SwfdecAudioDecoder *
 swfdec_audio_decoder_new (guint codec, SwfdecAudioFormat format)
 {
-  SwfdecAudioDecoder *ret;
-  const char *list;
+  SwfdecAudioDecoder *ret = NULL;
+  guint i;
 
   g_return_val_if_fail (SWFDEC_IS_AUDIO_FORMAT (format), NULL);
 
-  list = g_getenv ("SWFDEC_CODEC_AUDIO");
-  if (list == NULL)
-    list = g_getenv ("SWFDEC_CODEC");
-  if (list == NULL) {
-    guint i;
-    ret = NULL;
-    for (i = 0; audio_codecs[i].name != NULL; i++) {
-      ret = audio_codecs[i].func (codec, format);
-      if (ret)
-	break;
-    }
-  } else {
-    char **split = g_strsplit (list, ",", -1);
-    guint i, j;
-    ret = NULL;
-    SWFDEC_LOG ("codecs limited to \"%s\"", list);
-    for (i = 0; split[i] != NULL && ret == NULL; i++) {
-      for (j = 0; audio_codecs[j].name != NULL; j++) {
-	if (g_ascii_strcasecmp (audio_codecs[j].name, split[i]) != 0)
-	  continue;
-	ret = audio_codecs[j].func (codec, format);
-	if (ret)
-	  break;
-      }
-    }
-    g_strfreev (split);
+  g_print ("new decoder for format %u\n", codec);
+  for (i = 0; i < G_N_ELEMENTS (audio_codecs); i++) {
+    ret = audio_codecs[i].func (codec, format);
+    if (ret)
+      break;
   }
 
   if (ret) {
diff --git a/swfdec/swfdec_codec_audio.h b/swfdec/swfdec_codec_audio.h
index 6f9e4f9..6ea72f0 100644
--- a/swfdec/swfdec_codec_audio.h
+++ b/swfdec/swfdec_codec_audio.h
@@ -44,6 +44,8 @@ struct _SwfdecAudioDecoder {
   void		  	(* free)	(SwfdecAudioDecoder *	decoder);
 };
 
+char *			swfdec_audio_decoder_prepare	(guint			codec,
+							 SwfdecAudioFormat	format);
 SwfdecAudioDecoder *   	swfdec_audio_decoder_new      	(guint			codec,
 							 SwfdecAudioFormat	format);
 void			swfdec_audio_decoder_free      	(SwfdecAudioDecoder *	decoder);
diff --git a/swfdec/swfdec_codec_ffmpeg.c b/swfdec/swfdec_codec_ffmpeg.c
index fef007b..601f9d6 100644
--- a/swfdec/swfdec_codec_ffmpeg.c
+++ b/swfdec/swfdec_codec_ffmpeg.c
@@ -169,6 +169,12 @@ swfdec_audio_decoder_ffmpeg_free (SwfdecAudioDecoder *dec)
   g_slice_free (SwfdecAudioDecoderFFMpeg, ffmpeg);
 }
 
+gboolean
+swfdec_audio_decoder_ffmpeg_prepare (guint type, SwfdecAudioFormat format, char **details)
+{
+  return type == SWFDEC_AUDIO_CODEC_MP3 || type == SWFDEC_AUDIO_CODEC_ADPCM;
+}
+
 SwfdecAudioDecoder *
 swfdec_audio_decoder_ffmpeg_new (guint type, SwfdecAudioFormat format)
 {
diff --git a/swfdec/swfdec_codec_gst.c b/swfdec/swfdec_codec_gst.c
index ade7277..679bf7e 100644
--- a/swfdec/swfdec_codec_gst.c
+++ b/swfdec/swfdec_codec_gst.c
@@ -634,29 +634,28 @@ swfdec_video_decoder_gst_new (guint codec)
 
 /*** MISSING PLUGIN SUPPORT ***/
   
-char *
-swfdec_audio_decoder_gst_missing (guint codec, SwfdecAudioFormat format)
+gboolean
+swfdec_audio_decoder_gst_prepare (guint codec, SwfdecAudioFormat format, char **detail)
 {
   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;
+    return FALSE;
 
   /* If we can already handle it, woohoo! */
   factory = swfdec_gst_get_element_factory (caps);
   if (factory != NULL) {
     gst_object_unref (factory);
-    return NULL;
+    return TRUE;
   }
 
   /* need to install plugins... */
-  ret = gst_missing_decoder_installer_detail_new (caps);
+  *detail = gst_missing_decoder_installer_detail_new (caps);
   gst_caps_unref (caps);
-  return ret;
+  return FALSE;
 }
 
 char *
diff --git a/swfdec/swfdec_codec_mad.c b/swfdec/swfdec_codec_mad.c
index 03241d5..3b508b8 100644
--- a/swfdec/swfdec_codec_mad.c
+++ b/swfdec/swfdec_codec_mad.c
@@ -208,6 +208,12 @@ swfdec_audio_decoder_mad_pull (SwfdecAudioDecoder *dec)
   return swfdec_buffer_queue_pull_buffer (((MadData *) dec)->queue);
 }
 
+gboolean
+swfdec_audio_decoder_mad_prepare (guint type, SwfdecAudioFormat format, char **details)
+{
+  return type == SWFDEC_AUDIO_CODEC_MP3;
+}
+
 SwfdecAudioDecoder *
 swfdec_audio_decoder_mad_new (guint type, SwfdecAudioFormat format)
 {
diff --git a/swfdec/swfdec_internal.h b/swfdec/swfdec_internal.h
index 479397a..e1adddf 100644
--- a/swfdec/swfdec_internal.h
+++ b/swfdec/swfdec_internal.h
@@ -36,18 +36,23 @@ SwfdecAudioDecoder *	swfdec_audio_decoder_adpcm_new		(guint			type,
 #ifdef HAVE_MAD
 SwfdecAudioDecoder *	swfdec_audio_decoder_mad_new		(guint		type, 
 								 SwfdecAudioFormat	format);
+gboolean		swfdec_audio_decoder_mad_prepare	(guint			codec,
+								 SwfdecAudioFormat	format,
+								 char **		detail);
 #endif
 #ifdef HAVE_FFMPEG
 SwfdecAudioDecoder *	swfdec_audio_decoder_ffmpeg_new		(guint			type, 
 								 SwfdecAudioFormat	format);
+gboolean		swfdec_audio_decoder_ffmpeg_prepare	(guint			codec,
+								 SwfdecAudioFormat	format,
+								 char **		detail);
 #endif
 #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
+gboolean		swfdec_audio_decoder_gst_prepare	(guint			codec,
+								 SwfdecAudioFormat	format,
+								 char **		detail);
 #endif
 
 /* video codecs */
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index ba499f8..c762bb7 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -2241,7 +2241,7 @@ swfdec_player_use_audio_codec (SwfdecPlayer *player, guint codec,
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
 
-  detail = swfdec_audio_decoder_gst_missing (codec, format);
+  detail = swfdec_audio_decoder_prepare (codec, format);
   if (detail == NULL)
     return;
 
commit ae5786db99c4d1dd44c8a7e90a7cf7f2817ead62
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 8 20:29:20 2008 +0100

    we need to update the registry after a successfull installation

diff --git a/swfdec-gtk/swfdec_gtk_player.c b/swfdec-gtk/swfdec_gtk_player.c
index cca5fd4..2c4f41b 100644
--- a/swfdec-gtk/swfdec_gtk_player.c
+++ b/swfdec-gtk/swfdec_gtk_player.c
@@ -86,6 +86,7 @@ swfdec_gtk_player_missing_plugins_done (GstInstallPluginsReturn result, gpointer
   SwfdecGtkPlayer *player = data;
   SwfdecGtkPlayerPrivate *priv = player->priv;
 
+  gst_update_registry ();
   if (priv->needs_resume)
     swfdec_gtk_player_set_playing (player, TRUE);
 }
commit dd7a80e02aa9d1cebd0730a477adebdf1ed7da45
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 8 14:04:11 2008 +0100

    update docs

diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index 53fbb61..efc27d5 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -198,8 +198,9 @@ SwfdecBuffer
 SwfdecBufferQueue
 SwfdecBufferFreeFunc
 swfdec_buffer_new
-swfdec_buffer_new_and_alloc
-swfdec_buffer_new_and_alloc0
+swfdec_buffer_new0
+swfdec_buffer_new_full
+swfdec_buffer_new_static
 swfdec_buffer_new_for_data
 swfdec_buffer_new_subbuffer
 swfdec_buffer_new_from_file
@@ -217,6 +218,7 @@ swfdec_buffer_queue_pull
 swfdec_buffer_queue_pull_buffer
 swfdec_buffer_queue_peek
 swfdec_buffer_queue_peek_buffer
+swfdec_buffer_queue_flush
 <SUBSECTION Standard>
 SWFDEC_TYPE_BUFFER
 swfdec_buffer_get_type
@@ -265,6 +267,8 @@ swfdec_gtk_player_get_speed
 swfdec_gtk_player_set_speed
 swfdec_gtk_player_get_audio_enabled
 swfdec_gtk_player_set_audio_enabled
+swfdec_gtk_player_get_missing_plugins_window
+swfdec_gtk_player_set_missing_plugins_window
 <SUBSECTION Standard>
 SwfdecGtkPlayerPrivate
 SwfdecGtkPlayerClass
commit 58b8d3168328da4f1c7ad12f82201ed6915ba8aa
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 8 14:02:04 2008 +0100

    add API for automatic codec install

diff --git a/swfdec-gtk/Makefile.am b/swfdec-gtk/Makefile.am
index 2fdd027..dfe7527 100644
--- a/swfdec-gtk/Makefile.am
+++ b/swfdec-gtk/Makefile.am
@@ -23,12 +23,12 @@ noinst_HEADERS = \
 
 libswfdec_gtk_ at SWFDEC_MAJORMINOR@_la_CFLAGS = \
 	-I$(top_srcdir) $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) \
-	$(AUDIO_CFLAGS) \
+	$(AUDIO_CFLAGS) $(GST_CFLAGS) \
 	-DG_LOG_DOMAIN=\"Swfdec-Gtk\"
 libswfdec_gtk_ at SWFDEC_MAJORMINOR@_la_LDFLAGS = \
 	-version-info $(SWFDEC_LIBVERSION) \
 	-export-symbols-regex '^(swfdec_.*)' \
-	$(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) 
+	$(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) $(GST_LIBS)
 libswfdec_ at SWFDEC_MAJORMINOR@includedir = $(includedir)/swfdec- at SWFDEC_MAJORMINOR@/swfdec-gtk
 libswfdec_ at SWFDEC_MAJORMINOR@include_HEADERS = \
 	swfdec-gtk.h \
diff --git a/swfdec-gtk/swfdec_gtk_player.c b/swfdec-gtk/swfdec_gtk_player.c
index 42fc01b..cca5fd4 100644
--- a/swfdec-gtk/swfdec_gtk_player.c
+++ b/swfdec-gtk/swfdec_gtk_player.c
@@ -21,6 +21,15 @@
 #include "config.h"
 #endif
 
+#ifdef HAVE_GST
+#include <gst/pbutils/pbutils.h>
+#endif
+
+#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
 #include "swfdec-gtk/swfdec_gtk_loader.h"
 #include "swfdec-gtk/swfdec_gtk_player.h"
 #include "swfdec-gtk/swfdec_gtk_socket.h"
@@ -33,13 +42,19 @@ struct _SwfdecGtkPlayerPrivate
   SwfdecPlayback *	playback;	/* audio playback object */
   gboolean		audio_enabled;	/* TRUE if audio should be played */
   double		speed;		/* desired playback speed */
+
+  /* missing plugins */
+  GdkWindow *		missing_plugins_window; /* window used for displaying missing plugins info */
+  GstInstallPluginsContext *missing_plugins_context; /* context used during install */
+  gboolean		needs_resume;	/* restart playback after plugin install is done? */
 };
 
 enum {
   PROP_0,
   PROP_PLAYING,
   PROP_AUDIO,
-  PROP_SPEED
+  PROP_SPEED,
+  PROP_MISSING_PLUGINS_WINDOW
 };
 
 /*** gtk-doc ***/
@@ -63,6 +78,52 @@ enum {
  * The structure for the Swfdec Gtk player contains no public fields.
  */
 
+/*** MISSING PLUGINS ***/
+
+static void
+swfdec_gtk_player_missing_plugins_done (GstInstallPluginsReturn result, gpointer data)
+{
+  SwfdecGtkPlayer *player = data;
+  SwfdecGtkPlayerPrivate *priv = player->priv;
+
+  if (priv->needs_resume)
+    swfdec_gtk_player_set_playing (player, TRUE);
+}
+
+static void
+swfdec_gtk_player_missing_plugins (SwfdecPlayer *player, const char **details)
+{
+  SwfdecGtkPlayerPrivate *priv = SWFDEC_GTK_PLAYER (player)->priv;
+
+  /* That should only happen if users don't listen and then we don't listen either */
+  if (priv->missing_plugins_context)
+    return;
+  /* no automatic install desired */
+  if (priv->missing_plugins_window == NULL)
+    return;
+
+#ifdef HAVE_GST
+  {
+    GstInstallPluginsReturn result;
+    priv->missing_plugins_context = gst_install_plugins_context_new ();
+#ifdef GDK_WINDOWING_X11
+    gst_install_plugins_context_set_xid (priv->missing_plugins_context,
+	GDK_DRAWABLE_XID (priv->missing_plugins_window));
+#endif
+    result = gst_install_plugins_async ((char **) details, priv->missing_plugins_context,
+	swfdec_gtk_player_missing_plugins_done, player);
+    if (result == GST_INSTALL_PLUGINS_STARTED_OK) {
+      if (swfdec_gtk_player_get_playing (SWFDEC_GTK_PLAYER (player))) {
+	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (player), FALSE);
+	priv->needs_resume = TRUE;
+      }
+    } else {
+      /* FIXME: error handling */
+    }
+  }
+#endif
+}
+
 /*** SWFDEC_GTK_PLAYER ***/
 
 G_DEFINE_TYPE (SwfdecGtkPlayer, swfdec_gtk_player, SWFDEC_TYPE_PLAYER)
@@ -83,6 +144,9 @@ swfdec_gtk_player_get_property (GObject *object, guint param_id, GValue *value,
     case PROP_SPEED:
       g_value_set_double (value, priv->speed);
       break;
+    case PROP_MISSING_PLUGINS_WINDOW:
+      g_value_set_object (value, G_OBJECT (priv->missing_plugins_window));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -105,6 +169,10 @@ swfdec_gtk_player_set_property (GObject *object, guint param_id, const GValue *v
     case PROP_SPEED:
       swfdec_gtk_player_set_speed (player, g_value_get_double (value));
       break;
+    case PROP_MISSING_PLUGINS_WINDOW:
+      swfdec_gtk_player_set_missing_plugins_window (player,
+	  GDK_WINDOW (g_value_get_object (value)));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -126,6 +194,7 @@ static void
 swfdec_gtk_player_class_init (SwfdecGtkPlayerClass * g_class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+  SwfdecPlayerClass *player_class = SWFDEC_PLAYER_CLASS (g_class);
 
   g_type_class_add_private (g_class, sizeof (SwfdecGtkPlayerPrivate));
 
@@ -142,6 +211,12 @@ swfdec_gtk_player_class_init (SwfdecGtkPlayerClass * g_class)
   g_object_class_install_property (object_class, PROP_SPEED,
       g_param_spec_double ("speed", "speed", "desired playback speed",
 	  G_MINDOUBLE, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_MISSING_PLUGINS_WINDOW,
+      g_param_spec_object ("missing-plugins-window", "missing plugins window", 
+	  "window on which to do autmatic missing plugins installation",
+	  GDK_TYPE_WINDOW, G_PARAM_READWRITE));
+
+  player_class->missing_plugins = swfdec_gtk_player_missing_plugins;
 }
 
 static void
@@ -221,7 +296,10 @@ swfdec_gtk_player_set_playing (SwfdecGtkPlayer *player, gboolean playing)
     g_source_destroy (priv->source);
     g_source_unref (priv->source);
     priv->source = NULL;
+  } else {
+    return;
   }
+  priv->needs_resume = FALSE;
   swfdec_gtk_player_update_audio (player);
   g_object_notify (G_OBJECT (player), "playing");
 }
@@ -316,3 +394,63 @@ swfdec_gtk_player_get_speed (SwfdecGtkPlayer *player)
 
   return player->priv->speed;
 }
+
+/**
+ * swfdec_gtk_player_set_missing_plugins_window:
+ * @player: a #SwfdecGtkPlayer
+ * @window: the window to use for popping up codec install dialogs or %NULL
+ *
+ * Sets a given #GdkWindow to be used as the reference window when popping up
+ * automatic codec install dialogs. Automatic codec install happens when Swfdec
+ * cannot find a GStreamer plugin to play back a given media file. The player
+ * will automaticcaly pause when this happens to allow the plugin install to 
+ * finish and will resume playback after the codec install has completed.
+ * You can use %NULL to disable this feature. It is disable by default.
+ * Note that this function takes a #GdkWindow, not a #GtkWindow, as its 
+ * argument. This makes it slightly more inconvenient to use, as you need to 
+ * call gtk_widget_show() on your #GtkWindow before having access to its 
+ * #GdkWindow, but it allows automatic plugin installatio even when your 
+ * application does not have a window. You can use gdk_get_default_root_window()
+ * to obtain a default window in that case.
+ * For details about automatic codec install, see the GStreamer documentation,
+ * in particular the function gst_install_plugins_async(). If Swfdec was 
+ * compiled without GStreamer support, this function will have no effect.
+ **/
+void
+swfdec_gtk_player_set_missing_plugins_window (SwfdecGtkPlayer *player,
+    GdkWindow *window)
+{
+  SwfdecGtkPlayerPrivate *priv;
+
+  g_return_if_fail (SWFDEC_IS_GTK_PLAYER (player));
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  priv = player->priv;
+  if (priv->missing_plugins_window)
+    g_object_unref (priv->missing_plugins_window);
+
+  priv->missing_plugins_window = window;
+
+  if (window)
+    g_object_ref (window);
+  g_object_notify (G_OBJECT (player), "missing-plugins-window");
+}
+
+/**
+ * swfdec_gtk_player_get_missing_plugins_window:
+ * @player: a #SwfdecPlayer
+ *
+ * Gets the window used for automatic codec install. See 
+ * swfdec_gtk_player_set_missing_plugins_window() for details.
+ *
+ * Returns: the #GdkWindow used as parent for showing missing plugin dialogs or
+ *          %NULL if automatic codec install is disabled.
+ **/
+GdkWindow *
+swfdec_gtk_player_get_missing_plugins_window (SwfdecGtkPlayer *player)
+{
+  g_return_val_if_fail (SWFDEC_IS_GTK_PLAYER (player), NULL);
+
+  return player->priv->missing_plugins_window;
+}
+
diff --git a/swfdec-gtk/swfdec_gtk_player.h b/swfdec-gtk/swfdec_gtk_player.h
index 4abef90..ea342b0 100644
--- a/swfdec-gtk/swfdec_gtk_player.h
+++ b/swfdec-gtk/swfdec_gtk_player.h
@@ -21,6 +21,7 @@
 #define _SWFDEC_GTK_PLAYER_H_
 
 #include <swfdec/swfdec.h>
+#include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
@@ -62,6 +63,11 @@ gboolean	swfdec_gtk_player_get_audio_enabled
 void		swfdec_gtk_player_set_speed	(SwfdecGtkPlayer *	player,
 						 double			speed);
 double		swfdec_gtk_player_get_speed 	(SwfdecGtkPlayer *	player);
+void		swfdec_gtk_player_set_missing_plugins_window
+						(SwfdecGtkPlayer *	player,
+						 GdkWindow *		window);
+GdkWindow *	swfdec_gtk_player_get_missing_plugins_window
+						(SwfdecGtkPlayer *	player);
 
 
 


More information about the Swfdec-commits mailing list