resindvd: Switch to using a hard-coded mpeg2dec, and change pad blocking a bit.
authorJan Schmidt <thaytan@noraisin.net>
Mon, 30 Mar 2009 00:07:49 +0000 (01:07 +0100)
committerJan Schmidt <thaytan@noraisin.net>
Thu, 2 Apr 2009 13:49:24 +0000 (14:49 +0100)
Change the pad blocking behaviour during startup, and use a hard-coded mpeg2dec (for the moment), in order to make things work with playbin2.

ext/resindvd/resindvdbin.c
ext/resindvd/resindvdbin.h

index c17f31a..310fac7 100644 (file)
@@ -38,6 +38,7 @@ GST_DEBUG_CATEGORY_EXTERN (resindvd_debug);
 #define GST_CAT_DEFAULT resindvd_debug
 
 #define USE_VIDEOQ 0
+#define USE_HARDCODED_VIDEODEC 1
 #define USE_HARDCODED_AUDIODEC 1
 
 #define DVDBIN_LOCK(d) g_mutex_lock((d)->dvd_lock)
@@ -88,8 +89,10 @@ GST_BOILERPLATE_FULL (RsnDvdBin, rsn_dvdbin, GstBin,
 
 static void demux_pad_added (GstElement * element, GstPad * pad,
     RsnDvdBin * dvdbin);
+#if !USE_HARDCODED_VIDEODEC
 static void viddec_pad_added (GstElement * element, GstPad * pad,
     gboolean last, RsnDvdBin * dvdbin);
+#endif
 static void rsn_dvdbin_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void rsn_dvdbin_get_property (GObject * object, guint prop_id,
@@ -372,18 +375,37 @@ create_elements (RsnDvdBin * dvdbin)
       "max-size-time", (7 * GST_SECOND / 10), "max-size-bytes", 0,
       "max-size-buffers", 0, NULL);
 
+#if USE_HARDCODED_VIDEODEC
+  if (!try_create_piece (dvdbin, DVD_ELEM_VIDDEC, "mpeg2dec", 0, "viddec",
+          "video decoder"))
+    return FALSE;
+
+#else
   /* Decodebin will throw a missing element message to find an MPEG decoder */
-  if (!try_create_piece (dvdbin, DVD_ELEM_VIDDEC, "decodebin", 0, "viddec",
+  if (!try_create_piece (dvdbin, DVD_ELEM_VIDDEC, "decodebin2", 0, "viddec",
           "video decoder"))
     return FALSE;
 
   g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_VIDDEC]),
       "new-decoded-pad", G_CALLBACK (viddec_pad_added), dvdbin);
+#endif
 
   if (!try_create_piece (dvdbin, DVD_ELEM_PARSET, NULL, RSN_TYPE_RSNPARSETTER,
           "rsnparsetter", "Aspect ratio adjustment"))
     return FALSE;
 
+#if USE_HARDCODED_VIDEODEC
+  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_VIDDEC], "src");
+  sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "sink");
+  if (src == NULL || sink == NULL)
+    goto failed_viddec_connect;
+  if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
+    goto failed_viddec_connect;
+  gst_object_unref (src);
+  gst_object_unref (sink);
+  src = sink = NULL;
+#endif
+
 #if USE_VIDEOQ
   /* Add a small amount of queueing after the video decoder. */
   if (!try_create_piece (dvdbin, DVD_ELEM_VIDQ, "queue", 0, "vid_q",
@@ -414,12 +436,38 @@ create_elements (RsnDvdBin * dvdbin)
     goto failed_video_ghost;
   gst_object_unref (src);
   src = NULL;
+  gst_pad_set_active (dvdbin->video_pad, TRUE);
+  gst_pad_set_blocked_async (dvdbin->video_pad, TRUE,
+      (GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
+
+#if USE_HARDCODED_VIDEODEC
+  gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->video_pad);
+  dvdbin->video_added = TRUE;
+#endif
 
   if (!try_create_piece (dvdbin, DVD_ELEM_SPU_SELECT, NULL,
           RSN_TYPE_STREAM_SELECTOR, "subpselect", "Subpicture stream selector"))
     return FALSE;
 
+  /* Add a single standalone queue to hold a single buffer of SPU data */
+  if (!try_create_piece (dvdbin, DVD_ELEM_SPUQ, "queue", 0, "spu_q",
+          "subpicture decoder buffer"))
+    return FALSE;
+  g_object_set (dvdbin->pieces[DVD_ELEM_SPUQ],
+      "max-size-time", G_GUINT64_CONSTANT (0), "max-size-bytes", 0,
+      "max-size-buffers", 1, NULL);
+
   src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPU_SELECT], "src");
+  sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPUQ], "sink");
+  if (src == NULL || sink == NULL)
+    goto failed_spuq_connect;
+  if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
+    goto failed_spuq_connect;
+  gst_object_unref (src);
+  gst_object_unref (sink);
+  src = sink = NULL;
+
+  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPUQ], "src");
   if (src == NULL)
     goto failed_spu_ghost;
   dvdbin->subpicture_pad = gst_ghost_pad_new ("subpicture", src);
@@ -484,12 +532,23 @@ create_elements (RsnDvdBin * dvdbin)
   gst_object_unref (src);
   src = NULL;
 
+  if (dvdbin->video_added && dvdbin->audio_added && dvdbin->subpicture_added) {
+    GST_DEBUG_OBJECT (dvdbin, "Firing no more pads");
+    gst_element_no_more_pads (GST_ELEMENT (dvdbin));
+  }
+
   return TRUE;
 
 failed_connect:
   GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
       ("Could not connect DVD source and demuxer elements"));
   goto error_out;
+#if USE_HARDCODED_VIDEODEC
+failed_viddec_connect:
+  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
+      ("Could not connect DVD video decoder and aspect ratio adjuster"));
+  goto error_out;
+#endif
 #if USE_VIDEOQ
 failed_vidq_connect:
   GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
@@ -500,6 +559,10 @@ failed_video_ghost:
   GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
       ("Could not ghost SPU output pad"));
   goto error_out;
+failed_spuq_connect:
+  GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
+      ("Could not connect DVD subpicture selector and buffer elements"));
+  goto error_out;
 failed_spu_ghost:
   GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL),
       ("Could not ghost SPU output pad"));
@@ -679,22 +742,48 @@ static void
 dvdbin_pad_blocked_cb (GstPad * pad, gboolean blocked, RsnDvdBin * dvdbin)
 {
   gboolean changed = FALSE;
+  gboolean added = FALSE;
   if (!blocked)
     return;
 
   if (pad == dvdbin->subpicture_pad) {
-    if (!dvdbin->subpicture_added) {
+    GST_DEBUG_OBJECT (dvdbin, "Pad block -> subpicture pad");
+    GST_OBJECT_LOCK (dvdbin);
+    added = dvdbin->subpicture_added;
+    dvdbin->subpicture_added = TRUE;
+    GST_OBJECT_UNLOCK (dvdbin);
+
+    if (!added) {
       gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->subpicture_pad);
-      dvdbin->subpicture_added = TRUE;
       changed = TRUE;
     }
 
     gst_pad_set_blocked_async (pad, FALSE,
         (GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
   } else if (pad == dvdbin->audio_pad) {
-    if (!dvdbin->audio_added) {
+    GST_DEBUG_OBJECT (dvdbin, "Pad block -> audio pad");
+    GST_OBJECT_LOCK (dvdbin);
+    added = dvdbin->audio_added;
+    dvdbin->audio_added = TRUE;
+    GST_OBJECT_UNLOCK (dvdbin);
+
+    if (!added) {
       gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->audio_pad);
-      dvdbin->audio_added = TRUE;
+      changed = TRUE;
+    }
+
+    gst_pad_set_blocked_async (pad, FALSE,
+        (GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin);
+  } else if (pad == dvdbin->video_pad) {
+    GST_DEBUG_OBJECT (dvdbin, "Pad block -> video pad");
+
+    GST_OBJECT_LOCK (dvdbin);
+    added = dvdbin->video_added;
+    dvdbin->video_added = TRUE;
+    GST_OBJECT_UNLOCK (dvdbin);
+
+    if (!added) {
+      gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->video_pad);
       changed = TRUE;
     }
 
@@ -704,10 +793,12 @@ dvdbin_pad_blocked_cb (GstPad * pad, gboolean blocked, RsnDvdBin * dvdbin)
 
   if (changed &&
       dvdbin->video_added && dvdbin->audio_added && dvdbin->subpicture_added) {
+    GST_DEBUG_OBJECT (dvdbin, "Firing no more pads from pad-blocked cb");
     gst_element_no_more_pads (GST_ELEMENT (dvdbin));
   }
 }
 
+#if !USE_HARDCODED_VIDEODEC
 static void
 viddec_pad_added (GstElement * element, GstPad * pad, gboolean last,
     RsnDvdBin * dvdbin)
@@ -720,17 +811,8 @@ viddec_pad_added (GstElement * element, GstPad * pad, gboolean last,
   gst_pad_link (pad, q_pad);
 
   gst_object_unref (q_pad);
-
-  if (!dvdbin->video_added) {
-    gst_pad_set_active (dvdbin->video_pad, TRUE);
-    gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->video_pad);
-    dvdbin->video_added = TRUE;
-
-    if (dvdbin->video_added && dvdbin->audio_added && dvdbin->subpicture_added) {
-      gst_element_no_more_pads (GST_ELEMENT (dvdbin));
-    }
-  }
 }
+#endif
 
 static void
 rsn_dvdbin_set_property (GObject * object, guint prop_id,
index 5f8d167..5a063f4 100644 (file)
@@ -42,7 +42,7 @@ typedef struct _RsnDvdBinClass RsnDvdBinClass;
 #define DVD_ELEM_SOURCE         0
 #define DVD_ELEM_DEMUX          1
 #define DVD_ELEM_MQUEUE         2
-#define DVD_ELEM_SPU            3
+#define DVD_ELEM_SPUQ           3
 #define DVD_ELEM_VIDDEC         4
 #define DVD_ELEM_PARSET         5
 #define DVD_ELEM_AUDDEC         6