resindvd: Switch to using a hard-coded mpeg2dec, and change pad blocking a bit.

Change the pad blocking behaviour during startup, and use a hard-coded mpeg2dec (for the moment), in order to make things work with playbin2.
This commit is contained in:
Jan Schmidt 2009-03-30 01:07:49 +01:00
parent 1c6529e93e
commit 97a1f14fc0
2 changed files with 98 additions and 16 deletions

View 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,

View 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