omx: Add infrastructure to enable special hacks for broken OpenMAX implementations
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 19 Jul 2011 08:33:15 +0000 (10:33 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 19 Jul 2011 08:33:15 +0000 (10:33 +0200)
omx/gstomx.c
omx/gstomx.conf
omx/gstomx.h
omx/gstomxvideodec.c
omx/gstomxvideodec.h

index 898fdd4..d4d9961 100644 (file)
@@ -314,7 +314,7 @@ static OMX_CALLBACKTYPE callbacks =
 
 GstOMXComponent *
 gst_omx_component_new (GstObject * parent, const gchar * core_name,
-    const gchar * component_name, const gchar * component_role)
+    const gchar * component_name, const gchar * component_role, guint64 hacks)
 {
   OMX_ERRORTYPE err;
   GstOMXCore *core;
@@ -342,6 +342,7 @@ gst_omx_component_new (GstObject * parent, const gchar * core_name,
       "Successfully got component handle %p (%s) from core '%s'", comp->handle,
       component_name, core_name);
   comp->parent = gst_object_ref (parent);
+  comp->hacks = hacks;
 
   comp->ports = g_ptr_array_new ();
   comp->n_in_ports = 0;
@@ -1616,6 +1617,29 @@ gst_omx_error_to_string (OMX_ERRORTYPE err)
   }
 }
 
+guint64
+gst_omx_parse_hacks (gchar ** hacks)
+{
+  guint64 hacks_flags = 0;
+
+  if (!hacks)
+    return 0;
+
+  while (*hacks) {
+    if (g_str_equal (*hacks,
+            "event-port-settings-changed-ndata-parameter-swap"))
+      hacks_flags |=
+          GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_NDATA_PARAMETER_SWAP;
+    else if (g_str_equal (*hacks, "event-port-settings-changed-port-0-to-1"))
+      hacks_flags |= GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_PORT_0_TO_1;
+    else
+      GST_WARNING ("Unknown hack: %s", *hacks);
+    hacks++;
+  }
+
+  return hacks_flags;
+}
+
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
index 88f779b..e5c22e3 100644 (file)
@@ -5,6 +5,7 @@ component-name=OMX.st.video_decoder.mpeg4
 rank=256
 in-port-index=0
 out-port-index=1
+hacks=event-port-settings-changed-ndata-parameter-swap;event-port-settings-changed-port-0-to-1
 
 [omxh264dec]
 type-name=GstOMXH264Dec
@@ -13,4 +14,5 @@ component-name=OMX.st.video_decoder.avc
 rank=256
 in-port-index=0
 out-port-index=1
+hacks=event-port-settings-changed-ndata-parameter-swap;event-port-settings-changed-port-0-to-1
 
index c6a9c29..e0d46e5 100644 (file)
 
 G_BEGIN_DECLS
 
+/* Different hacks that are required to work around
+ * bugs in different OpenMAX implementations
+ */
+/* In the EventSettingsChanged callback use nData2 instead of nData1 for
+ * the port index. Happens with Bellagio.
+ */
+#define GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_NDATA_PARAMETER_SWAP G_GUINT64_CONSTANT (0x0000000000000001)
+/* In the EventSettingsChanged callback assume that port index 0 really
+ * means port index 1. Happens with the Bellagio ffmpegdist video decoder.
+ */
+#define GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_PORT_0_TO_1 G_GUINT64_CONSTANT          (0x0000000000000002)
+
 typedef struct _GstOMXCore GstOMXCore;
 typedef struct _GstOMXPort GstOMXPort;
 typedef enum _GstOMXPortDirection GstOMXPortDirection;
@@ -108,6 +120,8 @@ struct _GstOMXComponent {
   OMX_HANDLETYPE handle;
   GstOMXCore *core;
 
+  guint64 hacks; /* Flags, GST_OMX_HACK_* */
+
   GPtrArray *ports; /* Contains GstOMXPort* */
   gint n_in_ports, n_out_ports;
 
@@ -150,12 +164,13 @@ extern GQuark     gst_omx_element_name_quark;
 GKeyFile *        gst_omx_get_configuration (void);
 
 const gchar *     gst_omx_error_to_string (OMX_ERRORTYPE err);
+guint64           gst_omx_parse_hacks (gchar ** hacks);
 
 GstOMXCore *      gst_omx_core_acquire (const gchar * filename);
 void              gst_omx_core_release (GstOMXCore * core);
 
 
-GstOMXComponent * gst_omx_component_new  (GstObject *parent, const gchar * core_name, const gchar * component_name, const gchar *component_role);
+GstOMXComponent * gst_omx_component_new  (GstObject *parent, const gchar * core_name, const gchar * component_name, const gchar *component_role, guint64 hacks);
 void              gst_omx_component_free (GstOMXComponent * comp);
 
 OMX_ERRORTYPE     gst_omx_component_set_state (GstOMXComponent * comp, OMX_STATETYPE state);
index efe6215..64ea70d 100644 (file)
@@ -87,6 +87,7 @@ gst_omx_video_dec_base_init (gpointer g_class)
   gchar *template_caps;
   GstPadTemplate *templ;
   GstCaps *caps;
+  gchar **hacks;
 
   element_name =
       g_type_get_qdata (G_TYPE_FROM_CLASS (g_class),
@@ -191,6 +192,21 @@ gst_omx_video_dec_base_init (gpointer g_class)
   g_free (template_caps);
   gst_element_class_add_pad_template (element_class, templ);
   gst_object_unref (templ);
+
+  if ((hacks =
+          g_key_file_get_string_list (config, element_name, "hacks", NULL,
+              NULL))) {
+#ifndef GST_DISABLE_GST_DEBUG
+    gchar **walk = hacks;
+
+    while (*walk) {
+      GST_DEBUG ("Using hack: %s", *walk);
+      walk++;
+    }
+#endif
+
+    videodec_class->hacks = gst_omx_parse_hacks (hacks);
+  }
 }
 
 static void
@@ -232,7 +248,7 @@ gst_omx_video_dec_open (GstOMXVideoDec * self)
 
   self->component =
       gst_omx_component_new (GST_OBJECT_CAST (self), klass->core_name,
-      klass->component_name, klass->component_role);
+      klass->component_name, klass->component_role, klass->hacks);
   self->started = FALSE;
 
   if (!self->component)
index af20602..e4b6c8f 100644 (file)
@@ -73,6 +73,8 @@ struct _GstOMXVideoDecClass
   
   guint32 in_port_index, out_port_index;
 
+  guint64 hacks;
+
   gboolean (*is_format_change) (GstOMXVideoDec * self, GstOMXPort * port, GstVideoState * state);
   gboolean (*set_format)       (GstOMXVideoDec * self, GstOMXPort * port, GstVideoState * state);
 };