static GstStateChangeReturn gst_play_sink_convert_bin_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret; GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN_CAST (element); switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: GST_PLAY_SINK_CONVERT_BIN_LOCK (self); unblock_proxypad (self); GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_PLAY_SINK_CONVERT_BIN_LOCK (self); gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED); gst_play_sink_convert_bin_set_targets (self, TRUE); self->raw = FALSE; GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (ret == GST_STATE_CHANGE_FAILURE) return ret; switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: GST_PLAY_SINK_CONVERT_BIN_LOCK (self); gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED); gst_play_sink_convert_bin_set_targets (self, TRUE); self->raw = FALSE; GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_PLAY_SINK_CONVERT_BIN_LOCK (self); unblock_proxypad (self); GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); break; default: break; } return ret; }
static GstPadProbeReturn pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { GstPlaySinkConvertBin *self = user_data; GstPad *peer; GstCaps *caps; gboolean raw; if (GST_IS_EVENT (info->data) && !GST_EVENT_IS_SERIALIZED (info->data)) { GST_DEBUG_OBJECT (self, "Letting non-serialized event %s pass", GST_EVENT_TYPE_NAME (info->data)); return GST_PAD_PROBE_PASS; } GST_PLAY_SINK_CONVERT_BIN_LOCK (self); GST_DEBUG_OBJECT (self, "Pad blocked"); /* There must be a peer at this point */ peer = gst_pad_get_peer (self->sinkpad); caps = gst_pad_get_current_caps (peer); if (!caps) caps = gst_pad_query_caps (peer, NULL); gst_object_unref (peer); raw = is_raw_caps (caps, self->audio); GST_DEBUG_OBJECT (self, "Caps %" GST_PTR_FORMAT " are raw: %d", caps, raw); gst_caps_unref (caps); if (raw == self->raw) goto unblock; self->raw = raw; gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL); gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL); if (raw) { GST_DEBUG_OBJECT (self, "Switching to raw conversion pipeline"); if (self->conversion_elements) g_list_foreach (self->conversion_elements, (GFunc) gst_play_sink_convert_bin_on_element_added, self); } else { GST_DEBUG_OBJECT (self, "Switch to passthrough pipeline"); gst_play_sink_convert_bin_on_element_added (self->identity, self); } gst_play_sink_convert_bin_set_targets (self, !raw); unblock: self->sink_proxypad_block_id = 0; GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); return GST_PAD_PROBE_REMOVE; }