playbin2: properly reconfigure upon subsequent no-more-pads

... such as during switch in chained ogg.
This commit is contained in:
Mark Nauwelaerts 2012-05-08 15:42:02 +02:00 committed by Sebastian Dröge
parent 1c70c5b85e
commit e623bea6fa
3 changed files with 78 additions and 1 deletions

View file

@ -2715,6 +2715,9 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
* the sink. */ * the sink. */
changed = FALSE; changed = FALSE;
sinkpad = NULL; sinkpad = NULL;
/* store the selector for the pad */
g_object_set_data (G_OBJECT (pad), "playbin2.select", select);
} }
GST_SOURCE_GROUP_UNLOCK (group); GST_SOURCE_GROUP_UNLOCK (group);
@ -2787,6 +2790,15 @@ pad_removed_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
"pad %s:%s removed from group %p", GST_DEBUG_PAD_NAME (pad), group); "pad %s:%s removed from group %p", GST_DEBUG_PAD_NAME (pad), group);
GST_SOURCE_GROUP_LOCK (group); GST_SOURCE_GROUP_LOCK (group);
if ((select = g_object_get_data (G_OBJECT (pad), "playbin2.select"))) {
g_assert (select->selector == NULL);
g_assert (select->srcpad == pad);
gst_object_unref (pad);
select->srcpad = NULL;
goto exit;
}
/* get the selector sinkpad */ /* get the selector sinkpad */
if (!(peer = g_object_get_data (G_OBJECT (pad), "playbin.sinkpad"))) if (!(peer = g_object_get_data (G_OBJECT (pad), "playbin.sinkpad")))
goto not_linked; goto not_linked;
@ -2804,6 +2816,16 @@ pad_removed_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
/* remove the pad from the array */ /* remove the pad from the array */
g_ptr_array_remove (select->channels, peer); g_ptr_array_remove (select->channels, peer);
GST_DEBUG_OBJECT (playbin, "pad %p removed from array", peer); GST_DEBUG_OBJECT (playbin, "pad %p removed from array", peer);
if (!select->channels->len && select->selector) {
GST_DEBUG_OBJECT (playbin, "all selector sinkpads removed");
GST_DEBUG_OBJECT (playbin, "removing selector %p", select->selector);
gst_object_unref (select->srcpad);
select->srcpad = NULL;
gst_element_set_state (select->selector, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (playbin), select->selector);
select->selector = NULL;
}
} }
/* unlink the pad now (can fail, the pad is unlinked before it's removed) */ /* unlink the pad now (can fail, the pad is unlinked before it's removed) */
@ -2823,6 +2845,7 @@ pad_removed_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
gst_object_unref (peer); gst_object_unref (peer);
gst_object_unref (selector); gst_object_unref (selector);
exit:
GST_SOURCE_GROUP_UNLOCK (group); GST_SOURCE_GROUP_UNLOCK (group);
return; return;
@ -2877,7 +2900,17 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group)
GST_DEBUG_OBJECT (playbin, "requesting new sink pad %d", select->type); GST_DEBUG_OBJECT (playbin, "requesting new sink pad %d", select->type);
select->sinkpad = select->sinkpad =
gst_play_sink_request_pad (playbin->playsink, select->type); gst_play_sink_request_pad (playbin->playsink, select->type);
} else if (select->srcpad && select->sinkpad) {
GST_DEBUG_OBJECT (playbin, "refreshing new sink pad %d", select->type);
gst_play_sink_refresh_pad (playbin->playsink, select->sinkpad,
select->type);
} else if (select->sinkpad && select->srcpad == NULL) {
GST_DEBUG_OBJECT (playbin, "releasing sink pad %d", select->type);
gst_play_sink_release_pad (playbin->playsink, select->sinkpad);
select->sinkpad = NULL;
}
if (select->sinkpad && select->srcpad &&
!gst_pad_is_linked (select->srcpad)) {
res = gst_pad_link (select->srcpad, select->sinkpad); res = gst_pad_link (select->srcpad, select->sinkpad);
GST_DEBUG_OBJECT (playbin, "linked type %s, result: %d", GST_DEBUG_OBJECT (playbin, "linked type %s, result: %d",
select->media_list[0], res); select->media_list[0], res);

View file

@ -3507,6 +3507,48 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink)
} }
} }
void
gst_play_sink_refresh_pad (GstPlaySink * playsink, GstPad * pad,
GstPlaySinkType type)
{
GST_DEBUG_OBJECT (playsink, "refresh pad %" GST_PTR_FORMAT, pad);
GST_PLAY_SINK_LOCK (playsink);
if (pad == playsink->video_pad) {
if (type != GST_PLAY_SINK_TYPE_VIDEO_RAW &&
type != GST_PLAY_SINK_TYPE_VIDEO)
goto wrong_type;
} else if (pad == playsink->audio_pad) {
if (type != GST_PLAY_SINK_TYPE_AUDIO_RAW &&
type != GST_PLAY_SINK_TYPE_AUDIO)
goto wrong_type;
} else if (pad == playsink->text_pad) {
if (type != GST_PLAY_SINK_TYPE_TEXT)
goto wrong_type;
}
if (type != GST_PLAY_SINK_TYPE_FLUSHING) {
GstPad *blockpad =
GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (pad)));
gst_pad_set_blocked_async (blockpad, TRUE, sinkpad_blocked_cb, playsink);
PENDING_FLAG_SET (playsink, type);
gst_object_unref (blockpad);
}
GST_PLAY_SINK_UNLOCK (playsink);
return;
/* ERRORS */
wrong_type:
{
GST_WARNING_OBJECT (playsink, "wrong type %d for pad %" GST_PTR_FORMAT,
pad);
GST_PLAY_SINK_UNLOCK (playsink);
return;
}
}
/** /**
* gst_play_sink_request_pad * gst_play_sink_request_pad
* @playsink: a #GstPlaySink * @playsink: a #GstPlaySink
@ -3631,6 +3673,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
return res; return res;
} }
static GstPad * static GstPad *
gst_play_sink_request_new_pad (GstElement * element, GstPadTemplate * templ, gst_play_sink_request_new_pad (GstElement * element, GstPadTemplate * templ,
const gchar * name, const GstCaps * caps) const gchar * name, const GstCaps * caps)

View file

@ -70,6 +70,7 @@ GType gst_play_sink_get_type (void);
GstPad * gst_play_sink_request_pad (GstPlaySink *playsink, GstPlaySinkType type); GstPad * gst_play_sink_request_pad (GstPlaySink *playsink, GstPlaySinkType type);
void gst_play_sink_release_pad (GstPlaySink *playsink, GstPad *pad); void gst_play_sink_release_pad (GstPlaySink *playsink, GstPad *pad);
void gst_play_sink_refresh_pad (GstPlaySink *playsink, GstPad *pad, GstPlaySinkType type);
void gst_play_sink_set_sink (GstPlaySink * playsink, GstPlaySinkType type, GstElement * sink); void gst_play_sink_set_sink (GstPlaySink * playsink, GstPlaySinkType type, GstElement * sink);
GstElement * gst_play_sink_get_sink (GstPlaySink * playsink, GstPlaySinkType type); GstElement * gst_play_sink_get_sink (GstPlaySink * playsink, GstPlaySinkType type);