static gboolean create_elements (RsnDvdBin * dvdbin) { GstPad *src = NULL; GstPad *sink = NULL; if (!try_create_piece (dvdbin, DVD_ELEM_SOURCE, NULL, RESIN_TYPE_DVDSRC, "dvdsrc", "DVD source")) { return FALSE; } /* FIXME: Locking */ if (dvdbin->device) { g_object_set (G_OBJECT (dvdbin->pieces[DVD_ELEM_SOURCE]), "device", dvdbin->device, NULL); } if (!try_create_piece (dvdbin, DVD_ELEM_DEMUX, NULL, GST_TYPE_FLUPS_DEMUX, "dvddemux", "DVD demuxer")) return FALSE; if (gst_element_link (dvdbin->pieces[DVD_ELEM_SOURCE], dvdbin->pieces[DVD_ELEM_DEMUX]) == FALSE) goto failed_connect; /* Listen for new pads from the demuxer */ g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_DEMUX]), "pad-added", G_CALLBACK (demux_pad_added), dvdbin); if (!try_create_piece (dvdbin, DVD_ELEM_MQUEUE, "multiqueue", 0, "mq", "multiqueue")) return FALSE; g_object_set (dvdbin->pieces[DVD_ELEM_MQUEUE], "max-size-time", (7 * GST_SECOND / 10), "max-size-bytes", 0, "max-size-buffers", 0, NULL); /* Decodebin will throw a missing element message to find an MPEG decoder */ if (!try_create_piece (dvdbin, DVD_ELEM_VIDDEC, "decodebin", 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); if (!try_create_piece (dvdbin, DVD_ELEM_PARSET, NULL, RSN_TYPE_RSNPARSETTER, "rsnparsetter", "Aspect ratio adjustment")) return FALSE; #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", "video decoder buffer")) return FALSE; g_object_set (dvdbin->pieces[DVD_ELEM_VIDQ], "max-size-time", G_GUINT64_CONSTANT (0), "max-size-bytes", 0, "max-size-buffers", 3, NULL); src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "src"); sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_VIDQ], "sink"); if (src == NULL || sink == NULL) goto failed_vidq_connect; if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink))) goto failed_vidq_connect; gst_object_unref (src); gst_object_unref (sink); src = sink = NULL; src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_VIDQ], "src"); #else src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "src"); #endif if (src == NULL) goto failed_video_ghost; dvdbin->video_pad = gst_ghost_pad_new ("video", src); if (dvdbin->video_pad == NULL) goto failed_video_ghost; gst_object_unref (src); src = NULL; if (!try_create_piece (dvdbin, DVD_ELEM_SPU_SELECT, NULL, RSN_TYPE_STREAM_SELECTOR, "subpselect", "Subpicture stream selector")) return FALSE; src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_SPU_SELECT], "src"); if (src == NULL) goto failed_spu_ghost; dvdbin->subpicture_pad = gst_ghost_pad_new ("subpicture", src); if (dvdbin->subpicture_pad == NULL) goto failed_spu_ghost; gst_pad_set_active (dvdbin->subpicture_pad, TRUE); gst_pad_set_blocked_async (dvdbin->subpicture_pad, TRUE, (GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin); gst_object_unref (src); src = NULL; if (!try_create_piece (dvdbin, DVD_ELEM_AUD_SELECT, NULL, RSN_TYPE_STREAM_SELECTOR, "audioselect", "Audio stream selector")) return FALSE; /* rsnaudiomunge goes after the audio decoding to regulate the stream */ if (!try_create_piece (dvdbin, DVD_ELEM_AUD_MUNGE, NULL, RSN_TYPE_AUDIOMUNGE, "audiomunge", "Audio output filter")) return FALSE; #if DECODEBIN_AUDIO /* Decodebin will throw a missing element message to find a suitable * decoder */ if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, "decodebin", 0, "auddec", "audio decoder")) return FALSE; g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_AUDDEC]), "new-decoded-pad", G_CALLBACK (auddec_pad_added), dvdbin); #else if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, "a52dec", 0, "auddec", "audio decoder")) return FALSE; src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "src"); sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "sink"); if (src == NULL || sink == NULL) goto failed_aud_connect; if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink))) goto failed_aud_connect; gst_object_unref (sink); gst_object_unref (src); src = sink = NULL; #endif src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_SELECT], "src"); sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "sink"); if (src == NULL || sink == NULL) goto failed_aud_connect; if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink))) goto failed_aud_connect; gst_object_unref (sink); gst_object_unref (src); src = sink = NULL; /* ghost audio munge output pad onto bin */ src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src"); if (src == NULL) goto failed_aud_ghost; dvdbin->audio_pad = gst_ghost_pad_new ("audio", src); if (dvdbin->audio_pad == NULL) goto failed_aud_ghost; gst_pad_set_active (dvdbin->audio_pad, TRUE); gst_pad_set_blocked_async (dvdbin->audio_pad, TRUE, (GstPadBlockCallback) dvdbin_pad_blocked_cb, dvdbin); gst_object_unref (src); src = NULL; return TRUE; failed_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD source and demuxer elements")); goto error_out; #if USE_VIDEOQ failed_vidq_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD aspect ratio adjuster and video buffer elements")); goto error_out; #endif failed_video_ghost: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not ghost SPU output pad")); goto error_out; failed_spu_ghost: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not ghost SPU output pad")); goto error_out; failed_aud_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD audio decoder")); goto error_out; failed_aud_ghost: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not ghost audio output pad")); goto error_out; error_out: if (src != NULL) gst_object_unref (src); if (sink != NULL) gst_object_unref (sink); return FALSE; }
static gboolean create_elements (RsnDvdBin * dvdbin) { GstPadTemplate *src_templ = NULL; GstPad *src = NULL; GstPad *sink = NULL; RsnDvdBinPadBlockCtx *bctx = NULL; if (!try_create_piece (dvdbin, DVD_ELEM_SOURCE, NULL, RESIN_TYPE_DVDSRC, "dvdsrc", "DVD source")) { return FALSE; } /* FIXME: Locking */ if (dvdbin->device) { g_object_set (G_OBJECT (dvdbin->pieces[DVD_ELEM_SOURCE]), "device", dvdbin->device, NULL); } if (!try_create_piece (dvdbin, DVD_ELEM_DEMUX, NULL, GST_TYPE_FLUPS_DEMUX, "dvddemux", "DVD demuxer")) return FALSE; if (gst_element_link (dvdbin->pieces[DVD_ELEM_SOURCE], dvdbin->pieces[DVD_ELEM_DEMUX]) == FALSE) goto failed_connect; /* Listen for new pads from the demuxer */ g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_DEMUX]), "pad-added", G_CALLBACK (demux_pad_added), dvdbin); g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_DEMUX]), "no-more-pads", G_CALLBACK (demux_no_more_pads), dvdbin); if (!try_create_piece (dvdbin, DVD_ELEM_MQUEUE, "multiqueue", 0, "mq", "multiqueue")) return FALSE; g_object_set (dvdbin->pieces[DVD_ELEM_MQUEUE], "max-size-time", (7 * GST_SECOND / 10), "max-size-bytes", 0, "max-size-buffers", 0, NULL); /* Decodebin will throw a missing element message to find an MPEG decoder */ if (!try_create_piece (dvdbin, DVD_ELEM_VIDDEC, NULL, RSN_TYPE_VIDEODEC, "viddec", "video decoder")) return FALSE; if (!try_create_piece (dvdbin, DVD_ELEM_PARSET, NULL, RSN_TYPE_RSNPARSETTER, "rsnparsetter", "Aspect ratio adjustment")) return FALSE; 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; src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "src"); if (src == NULL) goto failed_video_ghost; src_templ = gst_static_pad_template_get (&video_src_template); dvdbin->video_pad = gst_ghost_pad_new_from_template ("video", src, src_templ); gst_object_unref (src_templ); if (dvdbin->video_pad == NULL) goto failed_video_ghost; gst_pad_set_active (dvdbin->video_pad, TRUE); bctx = g_slice_new (RsnDvdBinPadBlockCtx); bctx->dvdbin = gst_object_ref (dvdbin); bctx->pad = gst_object_ref (dvdbin->video_pad); gst_pad_set_blocked_async_full (src, TRUE, (GstPadBlockCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify) _pad_block_destroy_notify); gst_object_unref (src); src = NULL; 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; src_templ = gst_static_pad_template_get (&subpicture_src_template); dvdbin->subpicture_pad = gst_ghost_pad_new_from_template ("subpicture", src, src_templ); gst_object_unref (src_templ); if (dvdbin->subpicture_pad == NULL) goto failed_spu_ghost; gst_pad_set_active (dvdbin->subpicture_pad, TRUE); bctx = g_slice_new (RsnDvdBinPadBlockCtx); bctx->dvdbin = gst_object_ref (dvdbin); bctx->pad = gst_object_ref (dvdbin->subpicture_pad); gst_pad_set_blocked_async_full (src, TRUE, (GstPadBlockCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify) _pad_block_destroy_notify); gst_object_unref (src); src = NULL; if (!try_create_piece (dvdbin, DVD_ELEM_AUD_SELECT, NULL, RSN_TYPE_STREAM_SELECTOR, "audioselect", "Audio stream selector")) return FALSE; if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, NULL, RSN_TYPE_AUDIODEC, "auddec", "audio decoder")) return FALSE; /* rsnaudiomunge goes after the audio decoding to regulate the stream */ if (!try_create_piece (dvdbin, DVD_ELEM_AUD_MUNGE, NULL, RSN_TYPE_AUDIOMUNGE, "audiomunge", "Audio output filter")) return FALSE; src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "src"); sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "sink"); if (src == NULL || sink == NULL) goto failed_aud_connect; if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink))) goto failed_aud_connect; gst_object_unref (sink); gst_object_unref (src); src = sink = NULL; src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_SELECT], "src"); sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "sink"); if (src == NULL || sink == NULL) goto failed_aud_connect; if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink))) goto failed_aud_connect; gst_object_unref (sink); gst_object_unref (src); src = sink = NULL; /* ghost audio munge output pad onto bin */ src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src"); if (src == NULL) goto failed_aud_ghost; src_templ = gst_static_pad_template_get (&audio_src_template); dvdbin->audio_pad = gst_ghost_pad_new_from_template ("audio", src, src_templ); gst_object_unref (src_templ); if (dvdbin->audio_pad == NULL) goto failed_aud_ghost; gst_pad_set_active (dvdbin->audio_pad, TRUE); bctx = g_slice_new (RsnDvdBinPadBlockCtx); bctx->dvdbin = gst_object_ref (dvdbin); bctx->pad = gst_object_ref (dvdbin->audio_pad); gst_pad_set_blocked_async_full (src, TRUE, (GstPadBlockCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify) _pad_block_destroy_notify); gst_object_unref (src); src = NULL; if (dvdbin->video_added && (dvdbin->audio_added || dvdbin->audio_broken) && 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; failed_viddec_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD video decoder and aspect ratio adjuster")); goto error_out; failed_video_ghost: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not ghost video 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")); goto error_out; failed_aud_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD audio decoder")); goto error_out; failed_aud_ghost: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not ghost audio output pad")); goto error_out; error_out: if (src != NULL) gst_object_unref (src); if (sink != NULL) gst_object_unref (sink); return FALSE; }
static gboolean create_elements (RsnDvdBin * dvdbin) { GstPadTemplate *src_templ = NULL; GstPad *src = NULL; GstPad *sink = NULL; RsnDvdBinPadBlockCtx *bctx = NULL; if (!try_create_piece (dvdbin, DVD_ELEM_SOURCE, NULL, RESIN_TYPE_DVDSRC, "dvdsrc", "DVD source")) { return FALSE; } /* FIXME: Locking */ if (dvdbin->device) { g_object_set (G_OBJECT (dvdbin->pieces[DVD_ELEM_SOURCE]), "device", dvdbin->device, NULL); } /* FIXME: Import and use local copy of mpeg PS demuxer */ if (!try_create_piece (dvdbin, DVD_ELEM_DEMUX, NULL, GST_TYPE_FLUPS_DEMUX, "dvddemux", "DVD demuxer")) return FALSE; if (gst_element_link (dvdbin->pieces[DVD_ELEM_SOURCE], dvdbin->pieces[DVD_ELEM_DEMUX]) == FALSE) goto failed_connect; /* Listen for new pads from the demuxer */ g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_DEMUX]), "pad-added", G_CALLBACK (demux_pad_added), dvdbin); g_signal_connect (G_OBJECT (dvdbin->pieces[DVD_ELEM_DEMUX]), "no-more-pads", G_CALLBACK (demux_no_more_pads), dvdbin); if (!try_create_piece (dvdbin, DVD_ELEM_MQUEUE, "multiqueue", 0, "rsnmq", "multiqueue")) return FALSE; g_object_set (dvdbin->pieces[DVD_ELEM_MQUEUE], "max-size-time", (7 * GST_SECOND / 10), "max-size-bytes", 0, "max-size-buffers", 0, NULL); if (!try_create_piece (dvdbin, DVD_ELEM_VIDPARSE, "mpegvideoparse", 0, "rsnvidparse", "video parser")) return FALSE; /* Decodebin will throw a missing element message to find an MPEG decoder */ if (!try_create_piece (dvdbin, DVD_ELEM_VIDDEC, NULL, RSN_TYPE_VIDEODEC, "rsnviddec", "video decoder")) return FALSE; /* FIXME: Replace identity */ if (!try_create_piece (dvdbin, DVD_ELEM_PARSET, NULL, RSN_TYPE_RSNPARSETTER, "rsnparsetter", "Aspect ratio adjustment")) return FALSE; if (!try_link_pieces (dvdbin->pieces[DVD_ELEM_VIDPARSE], "src", dvdbin->pieces[DVD_ELEM_VIDDEC], "sink")) goto failed_vidparse_connect; 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; src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_PARSET], "src"); if (src == NULL) goto failed_video_ghost; src_templ = gst_static_pad_template_get (&video_src_template); dvdbin->video_pad = gst_ghost_pad_new_from_template ("video", src, src_templ); gst_object_unref (src_templ); if (dvdbin->video_pad == NULL) goto failed_video_ghost; gst_pad_set_active (dvdbin->video_pad, TRUE); bctx = g_slice_new (RsnDvdBinPadBlockCtx); bctx->dvdbin = gst_object_ref (dvdbin); bctx->pad = gst_object_ref (dvdbin->video_pad); bctx->pad_block_id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, (GstPadProbeCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify) _pad_block_destroy_notify); gst_object_unref (src); src = NULL; #if DEBUG_TIMING gst_pad_add_probe (dvdbin->video_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_EVENT_FLUSH, (GstPadProbeCallback) dvdbin_dump_timing_info, NULL, NULL); #endif /* FIXME: Merge stream-selection logic to core and switch back */ if (!try_create_piece (dvdbin, DVD_ELEM_SPU_SELECT, NULL, RSN_TYPE_INPUT_SELECTOR, "subpselect", "Subpicture stream selector")) return FALSE; g_object_set (G_OBJECT (dvdbin->pieces[DVD_ELEM_SPU_SELECT]), "sync-streams", FALSE, NULL); /* 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; /* Allow a lot more while pre-rolling */ g_object_set (dvdbin->pieces[DVD_ELEM_SPUQ], "max-size-time", G_GUINT64_CONSTANT (0), "max-size-bytes", 0, "max-size-buffers", 100, 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; src_templ = gst_static_pad_template_get (&subpicture_src_template); dvdbin->subpicture_pad = gst_ghost_pad_new_from_template ("subpicture", src, src_templ); gst_object_unref (src_templ); if (dvdbin->subpicture_pad == NULL) goto failed_spu_ghost; gst_pad_set_active (dvdbin->subpicture_pad, TRUE); bctx = g_slice_new (RsnDvdBinPadBlockCtx); bctx->dvdbin = gst_object_ref (dvdbin); bctx->pad = gst_object_ref (dvdbin->subpicture_pad); bctx->pad_block_id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, (GstPadProbeCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify) _pad_block_destroy_notify); gst_object_unref (src); src = NULL; if (!try_create_piece (dvdbin, DVD_ELEM_AUD_SELECT, NULL, RSN_TYPE_INPUT_SELECTOR, "audioselect", "Audio stream selector")) return FALSE; g_object_set (G_OBJECT (dvdbin->pieces[DVD_ELEM_AUD_SELECT]), "sync-streams", FALSE, NULL); if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, NULL, RSN_TYPE_AUDIODEC, "auddec", "audio decoder")) return FALSE; src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_SELECT], "src"); sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "sink"); if (src == NULL || sink == NULL) goto failed_aud_connect; if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink))) goto failed_aud_connect; gst_object_unref (sink); gst_object_unref (src); src = sink = NULL; /* ghost audio munge output pad onto bin */ src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "src"); if (src == NULL) goto failed_aud_ghost; src_templ = gst_static_pad_template_get (&audio_src_template); dvdbin->audio_pad = gst_ghost_pad_new_from_template ("audio", src, src_templ); gst_object_unref (src_templ); if (dvdbin->audio_pad == NULL) goto failed_aud_ghost; gst_pad_set_active (dvdbin->audio_pad, TRUE); bctx = g_slice_new (RsnDvdBinPadBlockCtx); bctx->dvdbin = gst_object_ref (dvdbin); bctx->pad = gst_object_ref (dvdbin->audio_pad); bctx->pad_block_id = gst_pad_add_probe (src, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, (GstPadProbeCallback) dvdbin_pad_blocked_cb, bctx, (GDestroyNotify) _pad_block_destroy_notify); gst_object_unref (src); src = NULL; if (dvdbin->video_added && (dvdbin->audio_added || dvdbin->audio_broken) && dvdbin->subpicture_added) { rsn_dvdbin_no_more_pads (dvdbin); } return TRUE; failed_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD source and demuxer elements")); goto error_out; failed_vidparse_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD video parser and video decoder")); goto error_out; failed_viddec_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD video decoder and aspect ratio adjuster")); goto error_out; failed_video_ghost: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not ghost video 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")); goto error_out; failed_aud_connect: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not connect DVD audio decoder")); goto error_out; failed_aud_ghost: GST_ELEMENT_ERROR (dvdbin, CORE, FAILED, (NULL), ("Could not ghost audio output pad")); goto error_out; error_out: if (src != NULL) gst_object_unref (src); if (sink != NULL) gst_object_unref (sink); return FALSE; }