ext/ffmpeg/: Don't use GINT_TO_POINTER and GPOINTER_TO_INT with GTypes, this can...
authorTim-Philipp Müller <tim@centricular.net>
Fri, 16 Feb 2007 11:48:15 +0000 (11:48 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Fri, 16 Feb 2007 11:48:15 +0000 (11:48 +0000)
Original commit message from CVS:
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_base_init),
(gst_ffmpegdec_register):
* ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_base_init),
(gst_ffmpegdemux_register):
* ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_base_init),
(gst_ffmpegenc_register):
* ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_base_init),
(gst_ffmpegmux_register):
Don't use GINT_TO_POINTER and GPOINTER_TO_INT with GTypes, this
can break horribly if sizeof(GType) happens to be bigger than
sizeof(int), because GPOINTER_TO_INT might then chop off some bits
of our GType (the reason this seems to works nevertheless is the
put-current-type-also-as-value-0-into-the-hash-table-as-fallback
hack used in the current code).
In any case, instead of just fixing this, let's not use a hash table
with GTypes here at all. g_type_{set|get}_qdata() seems to do the
job just as well.

ChangeLog
ext/ffmpeg/gstffmpegdec.c
ext/ffmpeg/gstffmpegdemux.c
ext/ffmpeg/gstffmpegenc.c
ext/ffmpeg/gstffmpegmux.c

index c20453b..27f9f2c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2007-02-16  Tim-Philipp Müller  <tim at centricular dot net>
+
+       * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_base_init),
+       (gst_ffmpegdec_register):
+       * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_base_init),
+       (gst_ffmpegdemux_register):
+       * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_base_init),
+       (gst_ffmpegenc_register):
+       * ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_base_init),
+       (gst_ffmpegmux_register):
+         Don't use GINT_TO_POINTER and GPOINTER_TO_INT with GTypes, this
+         can break horribly if sizeof(GType) happens to be bigger than
+         sizeof(int), because GPOINTER_TO_INT might then chop off some bits
+         of our GType (the reason this seems to works nevertheless is the
+         put-current-type-also-as-value-0-into-the-hash-table-as-fallback
+         hack used in the current code).
+         In any case, instead of just fixing this, let's not use a hash table
+         with GTypes here at all. g_type_{set|get}_qdata() seems to do the
+         job just as well.
+
 2007-02-14  Edward Hervey  <edward@fluendo.com>
 
        * ext/ffmpeg/gstffmpegcfg.c: (gst_ffmpeg_flags_get_type):
index 160c81e..a6b6dec 100644 (file)
@@ -126,9 +126,7 @@ enum
   ARG_SKIPFRAME
 };
 
-static GHashTable *global_plugins;
-
-/* A number of functon prototypes are given so we can refer to them later. */
+/* A number of function prototypes are given so we can refer to them later. */
 static void gst_ffmpegdec_base_init (GstFFMpegDecClass * klass);
 static void gst_ffmpegdec_class_init (GstFFMpegDecClass * klass);
 static void gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec);
@@ -157,6 +155,8 @@ static int gst_ffmpegdec_get_buffer (AVCodecContext * context,
 static void gst_ffmpegdec_release_buffer (AVCodecContext * context,
     AVFrame * picture);
 
+#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("ffdec-params")
+
 static GstElementClass *parent_class = NULL;
 
 #define GST_FFMPEGDEC_TYPE_LOWRES (gst_ffmpegdec_lowres_get_type())
@@ -205,17 +205,15 @@ gst_ffmpegdec_skipframe_get_type (void)
 static void
 gst_ffmpegdec_base_init (GstFFMpegDecClass * klass)
 {
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstFFMpegDecClassParams *params;
   GstElementDetails details;
   GstPadTemplate *sinktempl, *srctempl;
 
-  params = g_hash_table_lookup (global_plugins,
-      GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
-  if (!params)
-    params = g_hash_table_lookup (global_plugins, GINT_TO_POINTER (0));
-  g_assert (params);
+  params =
+      (GstFFMpegDecClassParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
+      GST_FFDEC_PARAMS_QDATA);
+  g_assert (params != NULL);
 
   /* construct the element details struct */
   details.longname = g_strdup_printf ("FFMPEG %s decoder",
@@ -2109,8 +2107,6 @@ gst_ffmpegdec_register (GstPlugin * plugin)
 
   in_plugin = first_avcodec;
 
-  global_plugins = g_hash_table_new (NULL, NULL);
-
   while (in_plugin) {
     GstFFMpegDecClassParams *params;
     GstCaps *srccaps = NULL, *sinkcaps = NULL;
@@ -2158,11 +2154,10 @@ gst_ffmpegdec_register (GstPlugin * plugin)
     params->in_plugin = in_plugin;
     params->srccaps = gst_caps_ref (srccaps);
     params->sinkcaps = gst_caps_ref (sinkcaps);
-    g_hash_table_insert (global_plugins,
-        GINT_TO_POINTER (0), (gpointer) params);
 
     /* create the gtype now */
     type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
+    g_type_set_qdata (type, GST_FFDEC_PARAMS_QDATA, (gpointer) params);
 
     /* (Ronald) MPEG-4 gets a higher priority because it has been well-
      * tested and by far outperforms divxdec/xviddec - so we prefer it.
@@ -2201,9 +2196,6 @@ gst_ffmpegdec_register (GstPlugin * plugin)
 
     g_free (type_name);
 
-    g_hash_table_insert (global_plugins,
-        GINT_TO_POINTER (type), (gpointer) params);
-
   next:
     if (sinkcaps)
       gst_caps_unref (sinkcaps);
@@ -2211,7 +2203,6 @@ gst_ffmpegdec_register (GstPlugin * plugin)
       gst_caps_unref (srccaps);
     in_plugin = in_plugin->next;
   }
-  g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));
 
   return TRUE;
 }
index 2fc78fd..fd18b9c 100644 (file)
@@ -33,7 +33,6 @@
 #include <ffmpeg/avformat.h>
 #include <ffmpeg/avi.h>
 #endif
-
 #include <gst/gst.h>
 
 #include "gstffmpeg.h"
@@ -102,9 +101,7 @@ struct _GstFFMpegDemuxClass
   GstPadTemplate *audiosrctempl;
 };
 
-static GHashTable *global_plugins;
-
-/* A number of functon prototypes are given so we can refer to them later. */
+/* A number of function prototypes are given so we can refer to them later. */
 static void gst_ffmpegdemux_class_init (GstFFMpegDemuxClass * klass);
 static void gst_ffmpegdemux_base_init (GstFFMpegDemuxClass * klass);
 static void gst_ffmpegdemux_init (GstFFMpegDemux * demux);
@@ -127,6 +124,8 @@ gst_ffmpegdemux_send_event (GstElement * element, GstEvent * event);
 static GstStateChangeReturn
 gst_ffmpegdemux_change_state (GstElement * element, GstStateChange transition);
 
+#define GST_FFDEMUX_PARAMS_QDATA g_quark_from_static_string("ffdemux-params")
+
 static GstElementClass *parent_class = NULL;
 
 static const gchar *
@@ -167,17 +166,15 @@ gst_ffmpegdemux_averror (gint av_errno)
 static void
 gst_ffmpegdemux_base_init (GstFFMpegDemuxClass * klass)
 {
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstFFMpegDemuxClassParams *params;
   GstElementDetails details;
   GstPadTemplate *sinktempl, *audiosrctempl, *videosrctempl;
 
-  params = g_hash_table_lookup (global_plugins,
-      GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
-  if (!params)
-    params = g_hash_table_lookup (global_plugins, GINT_TO_POINTER (0));
-  g_assert (params);
+  params =
+      (GstFFMpegDemuxClassParams *)
+      g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), GST_FFDEMUX_PARAMS_QDATA);
+  g_assert (params != NULL);
 
   /* construct the element details struct */
   details.longname = g_strdup_printf ("FFMPEG %s demuxer",
@@ -512,6 +509,7 @@ gst_ffmpegdemux_perform_seek (GstFFMpegDemux * demux, GstEvent * event)
   /* and prepare to continue streaming */
   if (flush) {
     gint n;
+
     /* send flush stop, peer will accept data and events again. We
      * are not yet providing data as we still have the STREAM_LOCK. */
     gst_ffmpegdemux_push_event (demux, gst_event_new_flush_stop ());
@@ -1234,7 +1232,7 @@ gst_ffmpegdemux_loop (GstPad * pad)
 
   /* if a pad is in e.g. WRONG_STATE, we want to pause to unlock the STREAM_LOCK */
   if ((ret != GST_FLOW_OK)
-       && ((ret = gst_ffmpegdemux_aggregated_flow (demux)) != GST_FLOW_OK)) {
+      && ((ret = gst_ffmpegdemux_aggregated_flow (demux)) != GST_FLOW_OK)) {
     GST_WARNING_OBJECT (demux, "stream_movi flow: %s / %s",
         gst_flow_get_name (stream->last_flow), gst_flow_get_name (ret));
     goto pause;
@@ -1433,8 +1431,6 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
 
   in_plugin = first_iformat;
 
-  global_plugins = g_hash_table_new (NULL, NULL);
-
   while (in_plugin) {
     gchar *type_name, *typefind_name;
     gchar *p, *name = NULL;
@@ -1506,9 +1502,9 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
         !strcmp (in_plugin->name, "ea") ||
         !strcmp (in_plugin->name, "daud") ||
         !strcmp (in_plugin->name, "avs") ||
-        !strcmp (in_plugin->name, "aiff") || 
-       !strcmp (in_plugin->name, "4xm") || 
-       !strcmp(in_plugin->name, "yuv4mpegpipe"))
+        !strcmp (in_plugin->name, "aiff") ||
+        !strcmp (in_plugin->name, "4xm") ||
+        !strcmp (in_plugin->name, "yuv4mpegpipe"))
       rank = GST_RANK_MARGINAL;
     else
       rank = GST_RANK_NONE;
@@ -1551,14 +1547,9 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
     params->videosrccaps = videosrccaps;
     params->audiosrccaps = audiosrccaps;
 
-    g_hash_table_insert (global_plugins,
-        GINT_TO_POINTER (0), (gpointer) params);
-
     /* create the type now */
     type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
-
-    g_hash_table_insert (global_plugins,
-        GINT_TO_POINTER (type), (gpointer) params);
+    g_type_set_qdata (type, GST_FFDEMUX_PARAMS_QDATA, (gpointer) params);
 
     if (in_plugin->extensions)
       extensions = g_strsplit (in_plugin->extensions, " ", 0);
@@ -1585,7 +1576,6 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
     g_free (name);
     in_plugin = in_plugin->next;
   }
-  g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));
 
   return TRUE;
 }
index 58563a5..6e6d6f5 100644 (file)
@@ -89,9 +89,7 @@ gst_ffmpegenc_me_method_get_type (void)
   return ffmpegenc_me_method_type;
 }
 
-static GHashTable *enc_global_plugins;
-
-/* A number of functon prototypes are given so we can refer to them later. */
+/* A number of function prototypes are given so we can refer to them later. */
 static void gst_ffmpegenc_class_init (GstFFMpegEncClass * klass);
 static void gst_ffmpegenc_base_init (GstFFMpegEncClass * klass);
 static void gst_ffmpegenc_init (GstFFMpegEnc * ffmpegenc);
@@ -113,6 +111,8 @@ static void gst_ffmpegenc_get_property (GObject * object,
 static GstStateChangeReturn gst_ffmpegenc_change_state (GstElement * element,
     GstStateChange transition);
 
+#define GST_FFENC_PARAMS_QDATA g_quark_from_static_string("ffenc-params")
+
 static GstElementClass *parent_class = NULL;
 
 /*static guint gst_ffmpegenc_signals[LAST_SIGNAL] = { 0 }; */
@@ -120,19 +120,15 @@ static GstElementClass *parent_class = NULL;
 static void
 gst_ffmpegenc_base_init (GstFFMpegEncClass * klass)
 {
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstFFMpegEncClassParams *params;
   GstElementDetails details;
   GstPadTemplate *srctempl, *sinktempl;
 
-  params = g_hash_table_lookup (enc_global_plugins,
-      GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
-  /* HACK: if we don't have a GType yet, our params are stored at position 0 */
-  if (!params) {
-    params = g_hash_table_lookup (enc_global_plugins, GINT_TO_POINTER (0));
-  }
-  g_assert (params);
+  params =
+      (GstFFMpegEncClassParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
+      GST_FFENC_PARAMS_QDATA);
+  g_assert (params != NULL);
 
   /* construct the element details struct */
   details.longname = g_strdup_printf ("FFMPEG %s encoder",
@@ -928,8 +924,6 @@ gst_ffmpegenc_register (GstPlugin * plugin)
 
   in_plugin = first_avcodec;
 
-  enc_global_plugins = g_hash_table_new (NULL, NULL);
-
   /* build global ffmpeg param/property info */
   gst_ffmpeg_cfg_init ();
 
@@ -983,11 +977,10 @@ gst_ffmpegenc_register (GstPlugin * plugin)
     params->srccaps = gst_caps_ref (srccaps);
     params->sinkcaps = gst_caps_ref (sinkcaps);
 
-    g_hash_table_insert (enc_global_plugins,
-        GINT_TO_POINTER (0), (gpointer) params);
-
     /* create the glib type now */
     type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
+    g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) params);
+
     if (!gst_element_register (plugin, type_name, GST_RANK_NONE, type)) {
       g_free (type_name);
       return FALSE;
@@ -995,9 +988,6 @@ gst_ffmpegenc_register (GstPlugin * plugin)
 
     g_free (type_name);
 
-    g_hash_table_insert (enc_global_plugins,
-        GINT_TO_POINTER (type), (gpointer) params);
-
   next:
     if (sinkcaps)
       gst_caps_unref (sinkcaps);
@@ -1005,7 +995,6 @@ gst_ffmpegenc_register (GstPlugin * plugin)
       gst_caps_unref (srccaps);
     in_plugin = in_plugin->next;
   }
-  g_hash_table_remove (enc_global_plugins, GINT_TO_POINTER (0));
 
   return TRUE;
 }
index 7f6ea26..94de5a8 100644 (file)
@@ -102,9 +102,7 @@ enum
   /* FILL ME */
 };
 
-static GHashTable *global_plugins;
-
-/* A number of functon prototypes are given so we can refer to them later. */
+/* A number of function prototypes are given so we can refer to them later. */
 static void gst_ffmpegmux_class_init (GstFFMpegMuxClass * klass);
 static void gst_ffmpegmux_base_init (gpointer g_class);
 static void gst_ffmpegmux_init (GstFFMpegMux * ffmpegmux,
@@ -122,6 +120,8 @@ static gboolean gst_ffmpegmux_sink_event (GstPad * pad, GstEvent * event);
 static GstStateChangeReturn gst_ffmpegmux_change_state (GstElement * element,
     GstStateChange transition);
 
+#define GST_FFMUX_PARAMS_QDATA g_quark_from_static_string("ffmux-params")
+
 static GstElementClass *parent_class = NULL;
 
 /*static guint gst_ffmpegmux_signals[LAST_SIGNAL] = { 0 }; */
@@ -129,18 +129,16 @@ static GstElementClass *parent_class = NULL;
 static void
 gst_ffmpegmux_base_init (gpointer g_class)
 {
-  GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
   GstFFMpegMuxClass *klass = (GstFFMpegMuxClass *) g_class;
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
   GstElementDetails details;
   GstFFMpegMuxClassParams *params;
   GstPadTemplate *videosinktempl, *audiosinktempl, *srctempl;
 
-  params = g_hash_table_lookup (global_plugins,
-      GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
-  if (!params)
-    params = g_hash_table_lookup (global_plugins, GINT_TO_POINTER (0));
-  g_assert (params);
+  params =
+      (GstFFMpegMuxClassParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
+      GST_FFMUX_PARAMS_QDATA);
+  g_assert (params != NULL);
 
   /* construct the element details struct */
   details.longname = g_strdup_printf ("FFMPEG %s Muxer",
@@ -675,8 +673,6 @@ gst_ffmpegmux_register (GstPlugin * plugin)
 
   in_plugin = first_oformat;
 
-  global_plugins = g_hash_table_new (NULL, NULL);
-
   while (in_plugin) {
     gchar *type_name;
     gchar *p;
@@ -732,12 +728,11 @@ gst_ffmpegmux_register (GstPlugin * plugin)
     params->videosinkcaps = videosinkcaps;
     params->audiosinkcaps = audiosinkcaps;
 
-    g_hash_table_insert (global_plugins,
-        GINT_TO_POINTER (0), (gpointer) params);
-
     /* create the type now */
     type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
+    g_type_set_qdata (type, GST_FFMUX_PARAMS_QDATA, (gpointer) params);
     g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, &tag_setter_info);
+
     if (!gst_element_register (plugin, type_name, GST_RANK_NONE, type)) {
       g_free (type_name);
       gst_caps_unref (srccaps);
@@ -750,13 +745,9 @@ gst_ffmpegmux_register (GstPlugin * plugin)
 
     g_free (type_name);
 
-    g_hash_table_insert (global_plugins,
-        GINT_TO_POINTER (type), (gpointer) params);
-
   next:
     in_plugin = in_plugin->next;
   }
-  g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));
 
   return TRUE;
 }