diff options
-rw-r--r-- | ext/resindvd/resindvdbin.c | 112 | ||||
-rw-r--r-- | ext/resindvd/resindvdbin.h | 2 |
2 files changed, 98 insertions, 16 deletions
diff --git a/ext/resindvd/resindvdbin.c b/ext/resindvd/resindvdbin.c index c17f31af..310fac7f 100644 --- a/ext/resindvd/resindvdbin.c +++ b/ext/resindvd/resindvdbin.c @@ -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, diff --git a/ext/resindvd/resindvdbin.h b/ext/resindvd/resindvdbin.h index 5f8d1673..5a063f4f 100644 --- a/ext/resindvd/resindvdbin.h +++ b/ext/resindvd/resindvdbin.h @@ -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 |