static gboolean gst_play_sink_convert_bin_sink_setcaps (GstPlaySinkConvertBin * self, GstCaps * caps) { GstStructure *s; const gchar *name; gboolean reconfigure = FALSE; gboolean raw; GST_DEBUG_OBJECT (self, "setcaps"); GST_PLAY_SINK_CONVERT_BIN_LOCK (self); s = gst_caps_get_structure (caps, 0); name = gst_structure_get_name (s); if (self->audio) { raw = g_str_equal (name, "audio/x-raw"); } else { raw = g_str_equal (name, "video/x-raw"); } GST_DEBUG_OBJECT (self, "raw %d, self->raw %d, blocked %d", raw, self->raw, gst_pad_is_blocked (self->sink_proxypad)); if (raw) { if (!gst_pad_is_blocked (self->sink_proxypad)) { GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (self->sinkpad)); if (!self->raw || (target && !gst_pad_query_accept_caps (target, caps))) { if (!self->raw) GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw"); else GST_DEBUG_OBJECT (self, "Changing caps in an incompatible way"); reconfigure = TRUE; block_proxypad (self); } if (target) gst_object_unref (target); } } else { if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) { GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw"); reconfigure = TRUE; block_proxypad (self); } } /* Otherwise the setcaps below fails */ if (reconfigure) { gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL); gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL); } GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); GST_DEBUG_OBJECT (self, "Setting sink caps %" GST_PTR_FORMAT, caps); return TRUE; }
static GstStateChangeReturn gst_play_sink_video_convert_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret; GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (element); switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self); if (gst_pad_is_blocked (self->sink_proxypad)) gst_pad_set_blocked_async_full (self->sink_proxypad, FALSE, (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), (GDestroyNotify) gst_object_unref); GST_PLAY_SINK_VIDEO_CONVERT_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_VIDEO_CONVERT_LOCK (self); gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED); if (self->conv) { gst_element_set_state (self->conv, GST_STATE_NULL); gst_bin_remove (GST_BIN_CAST (self), self->conv); self->conv = NULL; } if (self->scale) { gst_element_set_state (self->scale, GST_STATE_NULL); gst_bin_remove (GST_BIN_CAST (self), self->scale); self->scale = NULL; } gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), self->sink_proxypad); self->raw = FALSE; GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self); break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self); if (!gst_pad_is_blocked (self->sink_proxypad)) gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE, (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), (GDestroyNotify) gst_object_unref); GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self); default: break; } return ret; }
static gboolean gst_play_sink_video_convert_sink_setcaps (GstPad * pad, GstCaps * caps) { GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT (gst_pad_get_parent (pad)); gboolean ret; GstStructure *s; const gchar *name; gboolean reconfigure = FALSE; GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self); s = gst_caps_get_structure (caps, 0); name = gst_structure_get_name (s); if (g_str_has_prefix (name, "video/x-raw-")) { if (!self->raw && !gst_pad_is_blocked (self->sink_proxypad)) { GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw"); reconfigure = TRUE; gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE, (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), (GDestroyNotify) gst_object_unref); } } else { if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) { GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw"); reconfigure = TRUE; gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE, (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), (GDestroyNotify) gst_object_unref); } } /* Otherwise the setcaps below fails */ if (reconfigure) { gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL); gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL); } GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self); ret = gst_ghost_pad_setcaps_default (pad, caps); GST_DEBUG_OBJECT (self, "Setting sink caps %" GST_PTR_FORMAT ": %d", caps, ret); gst_object_unref (self); return ret; }
void _bp_replaygain_pipeline_rebuild (BansheePlayer* player) { GstPad* srcPad; g_return_if_fail (IS_BANSHEE_PLAYER (player)); g_return_if_fail (GST_IS_ELEMENT (player->before_rgvolume)); srcPad = gst_element_get_static_pad (player->before_rgvolume, "src"); if (gst_pad_is_active (srcPad) && !gst_pad_is_blocked (srcPad)) { player->rg_pad_block_id = gst_pad_add_probe (srcPad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, &pad_block_cb, player, NULL); } else if (!player->rg_pad_block_id) { pad_block_cb (srcPad, NULL, player); } }
void QGstreamerPlayerSession::finishVideoOutputChange() { if (!m_pendingVideoSink) return; #ifdef DEBUG_PLAYBIN qDebug() << "finishVideoOutputChange" << m_pendingVideoSink; #endif GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src"); if (!gst_pad_is_blocked(srcPad)) { //pad is not blocked, it's possible to swap outputs only in the null state qWarning() << "Pad is not blocked yet, could not switch video sink"; GstState identityElementState = GST_STATE_NULL; gst_element_get_state(m_videoIdentity, &identityElementState, NULL, GST_CLOCK_TIME_NONE); if (identityElementState != GST_STATE_NULL) { gst_object_unref(GST_OBJECT(srcPad)); return; //can't change vo yet, received async call from the previous change } } if (m_pendingVideoSink == m_videoSink) { //video output was change back to the current one, //no need to torment the pipeline, just unblock the pad if (gst_pad_is_blocked(srcPad)) gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0); m_pendingVideoSink = 0; gst_object_unref(GST_OBJECT(srcPad)); return; } gst_element_set_state(m_videoSink, GST_STATE_NULL); gst_element_unlink(m_videoIdentity, m_videoSink); gst_bin_remove(GST_BIN(m_videoOutputBin), m_videoSink); m_videoSink = m_pendingVideoSink; m_pendingVideoSink = 0; gst_bin_add(GST_BIN(m_videoOutputBin), m_videoSink); if (!gst_element_link(m_videoIdentity, m_videoSink)) qWarning() << "Linking video output element failed"; GstState state; switch (m_pendingState) { case QMediaPlayer::StoppedState: state = GST_STATE_NULL; break; case QMediaPlayer::PausedState: state = GST_STATE_PAUSED; break; case QMediaPlayer::PlayingState: state = GST_STATE_PLAYING; break; } gst_element_set_state(m_videoSink, state); //don't have to wait here, it will unblock eventually if (gst_pad_is_blocked(srcPad)) gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0); gst_object_unref(GST_OBJECT(srcPad)); #ifdef DEBUG_VO_BIN_DUMP dumpNum++; _gst_debug_bin_to_dot_file(GST_BIN(m_playbin), GstDebugGraphDetails(/*GST_DEBUG_GRAPH_SHOW_ALL */ GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES), QString("playbin_%1_finish").arg(dumpNum).toAscii().constData()); #endif }
bool Pad::isBlocked() const { return gst_pad_is_blocked(object<GstPad>()); }