void fs_rtp_sub_stream_verify_codec_locked (FsRtpSubStream *substream) { GST_LOG ("Starting codec verification process for substream with" " SSRC:%x pt:%d", substream->ssrc, substream->pt); fs_rtp_sub_stream_add_probe_locked (substream); gst_pad_set_blocked_async (substream->priv->rtpbin_pad, TRUE, _rtpbin_pad_blocked_callback, substream); }
static void _bp_vis_pipeline_set_blocked (BansheePlayer *player, gboolean blocked) { GstPad *queue_sink; if (player->vis_resampler == NULL) return; queue_sink = gst_element_get_static_pad (player->vis_resampler, "src"); gst_pad_set_blocked_async (queue_sink, blocked, _bp_vis_pipeline_block_callback, (gpointer) player); gst_object_unref (GST_OBJECT (queue_sink)); }
static void really_remove_filter (GstPad *pad, gboolean blocked, RBGstPipelineOp *op) { GstPad *mypad; GstPad *prevpad, *nextpad; GstElement *bin; /* get the containing bin and remove it */ bin = GST_ELEMENT (gst_element_get_parent (op->element)); if (bin == NULL) { return; } rb_debug ("removing filter %p", op->element); _rb_player_gst_filter_emit_filter_pre_remove (RB_PLAYER_GST_FILTER (op->player), op->element); /* probably check return? */ gst_element_set_state (bin, GST_STATE_NULL); /* unlink our sink */ mypad = gst_element_get_static_pad (bin, "sink"); prevpad = gst_pad_get_peer (mypad); gst_pad_unlink (prevpad, mypad); gst_object_unref (mypad); /* unlink our src */ mypad = gst_element_get_static_pad (bin, "src"); nextpad = gst_pad_get_peer (mypad); gst_pad_unlink (mypad, nextpad); gst_object_unref (mypad); /* link previous and next pads */ gst_pad_link (prevpad, nextpad); gst_object_unref (prevpad); gst_object_unref (nextpad); gst_bin_remove (GST_BIN (op->fixture), bin); gst_object_unref (bin); /* if we're supposed to be playing, unblock the sink */ if (blocked) { rb_debug ("unblocking pad after removing filter"); gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback)pipeline_op_done, NULL); } free_pipeline_op (op); }
static void fs_rtp_sub_stream_try_stop (FsRtpSubStream *substream) { FS_RTP_SUB_STREAM_LOCK (substream); if (!substream->priv->stopped || substream->priv->modifying) { FS_RTP_SUB_STREAM_UNLOCK (substream); return; } FS_RTP_SUB_STREAM_UNLOCK (substream); if (substream->priv->rtpbin_unlinked_sig) { g_signal_handler_disconnect (substream->priv->rtpbin_pad, substream->priv->rtpbin_unlinked_sig); substream->priv->rtpbin_unlinked_sig = 0; } gst_pad_set_blocked_async (substream->priv->rtpbin_pad, FALSE, do_nothing_blocked_callback, NULL); if (substream->priv->output_ghostpad) gst_pad_set_active (substream->priv->output_ghostpad, FALSE); if (substream->priv->output_valve) { gst_element_set_locked_state (substream->priv->output_valve, TRUE); gst_element_set_state (substream->priv->output_valve, GST_STATE_NULL); } if (substream->priv->codecbin) { gst_element_set_locked_state (substream->priv->codecbin, TRUE); gst_element_set_state (substream->priv->codecbin, GST_STATE_NULL); } if (substream->priv->capsfilter) { gst_element_set_locked_state (substream->priv->capsfilter, TRUE); gst_element_set_state (substream->priv->capsfilter, GST_STATE_NULL); } if (substream->priv->input_valve) { gst_element_set_locked_state (substream->priv->input_valve, TRUE); gst_element_set_state (substream->priv->input_valve, GST_STATE_NULL); } }
static void pad_block (GstPad * pad, gboolean blocked, gpointer user_data) { GstPad *ghost; GstBin *bin; if (!blocked) return; bin = GST_BIN (user_data); ghost = gst_ghost_pad_new ("src", pad); gst_pad_set_active (ghost, TRUE); gst_element_add_pad (GST_ELEMENT (bin), ghost); gst_pad_set_blocked_async (pad, FALSE, pad_block, NULL); }
void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) { QGstreamerVideoRendererInterface* renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput); if (m_renderer == renderer) return; #ifdef DEBUG_VO_BIN_DUMP dumpNum++; _gst_debug_bin_to_dot_file(GST_BIN(m_videoOutputBin), 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("video_output_change_%1_set").arg(dumpNum).toAscii().constData()); #endif m_renderer = renderer; GstElement *videoSink = m_renderer ? m_renderer->videoSink() : m_nullVideoSink; if (m_state == QMediaPlayer::StoppedState) { m_pendingVideoSink = 0; gst_element_unlink(m_videoScale, m_videoSink); gst_bin_remove(GST_BIN(m_videoOutputBin), m_videoSink); m_videoSink = videoSink; gst_bin_add(GST_BIN(m_videoOutputBin), m_videoSink); gst_element_link(m_videoScale, m_videoSink); } else { if (m_pendingVideoSink) { m_pendingVideoSink = videoSink; return; } m_pendingVideoSink = videoSink; //block pads, async to avoid locking in paused state GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src"); gst_pad_set_blocked_async(srcPad, true, &block_pad_cb, this); gst_object_unref(GST_OBJECT(srcPad)); } }
void fs_rtp_sub_stream_stop (FsRtpSubStream *substream) { substream->priv->stopped = TRUE; g_static_rw_lock_writer_lock (&substream->priv->stopped_lock); substream->priv->stopped = TRUE; g_static_rw_lock_writer_unlock (&substream->priv->stopped_lock); if (substream->priv->rtpbin_unlinked_sig) { g_signal_handler_disconnect (substream->priv->rtpbin_pad, substream->priv->rtpbin_unlinked_sig); substream->priv->rtpbin_unlinked_sig = 0; } gst_pad_set_blocked_async (substream->priv->rtpbin_pad, FALSE, do_nothing_blocked_callback, NULL); if (substream->priv->output_ghostpad) gst_pad_set_active (substream->priv->output_ghostpad, FALSE); if (substream->priv->output_valve) { gst_element_set_locked_state (substream->priv->output_valve, TRUE); gst_element_set_state (substream->priv->output_valve, GST_STATE_NULL); } if (substream->priv->codecbin) { gst_element_set_locked_state (substream->priv->codecbin, TRUE); gst_element_set_state (substream->priv->codecbin, GST_STATE_NULL); } if (substream->priv->capsfilter) { gst_element_set_locked_state (substream->priv->capsfilter, TRUE); gst_element_set_state (substream->priv->capsfilter, GST_STATE_NULL); } if (substream->priv->input_valve) { gst_element_set_locked_state (substream->priv->input_valve, TRUE); gst_element_set_state (substream->priv->input_valve, GST_STATE_NULL); } }
static gboolean pipeline_op (GObject *player, GstElement *fixture, GstElement *element, gboolean use_pad_block, GstPadBlockCallback callback) { RBGstPipelineOp *op; GstPad *fixture_pad; GstPad *block_pad; op = new_pipeline_op (player, fixture, element); /* seems like we should be able to just block the src pad connected * to the fixture's sink pad.. */ fixture_pad = gst_element_get_static_pad (fixture, "sink"); block_pad = gst_pad_get_peer (fixture_pad); gst_object_unref (fixture_pad); if (use_pad_block) { char *whatpad; whatpad = gst_object_get_path_string (GST_OBJECT (block_pad)); rb_debug ("blocking pad %s to perform an operation", whatpad); g_free (whatpad); gst_pad_set_blocked_async (block_pad, TRUE, callback, op); } else { rb_debug ("not using pad blocking, calling op directly"); (*callback) (block_pad, FALSE, op); } gst_object_unref (block_pad); return TRUE; }
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 }
void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) { if (m_videoOutput != videoOutput) { if (m_videoOutput) { disconnect(m_videoOutput, SIGNAL(sinkChanged()), this, SLOT(updateVideoRenderer())); disconnect(m_videoOutput, SIGNAL(readyChanged(bool)), this, SLOT(updateVideoRenderer())); } if (videoOutput) { connect(videoOutput, SIGNAL(sinkChanged()), this, SLOT(updateVideoRenderer())); connect(videoOutput, SIGNAL(readyChanged(bool)), this, SLOT(updateVideoRenderer())); } m_videoOutput = videoOutput; } QGstreamerVideoRendererInterface* renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput); m_renderer = renderer; #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_set").arg(dumpNum).toAscii().constData()); #endif GstElement *videoSink = m_renderer ? m_renderer->videoSink() : m_nullVideoSink; if (!videoSink) videoSink = m_nullVideoSink; #ifdef DEBUG_PLAYBIN qDebug() << "Set video output:" << videoOutput; qDebug() << "Current sink:" << (m_videoSink ? GST_ELEMENT_NAME(m_videoSink) : "") << m_videoSink << "pending:" << (m_pendingVideoSink ? GST_ELEMENT_NAME(m_pendingVideoSink) : "") << m_pendingVideoSink << "new sink:" << (videoSink ? GST_ELEMENT_NAME(videoSink) : "") << videoSink; #endif if (m_pendingVideoSink == videoSink || (m_pendingVideoSink == 0 && m_videoSink == videoSink)) { #ifdef DEBUG_PLAYBIN qDebug() << "Video sink has not changed, skip video output reconfiguration"; #endif return; } #ifdef DEBUG_PLAYBIN qDebug() << "Reconfigure video output"; #endif if (m_state == QMediaPlayer::StoppedState) { #ifdef DEBUG_PLAYBIN qDebug() << "The pipeline has not started yet, pending state:" << m_pendingState; #endif //the pipeline has not started yet m_pendingVideoSink = 0; gst_element_set_state(m_videoSink, GST_STATE_NULL); gst_element_set_state(m_playbin, GST_STATE_NULL); gst_element_unlink(m_videoIdentity, m_videoSink); gst_bin_remove(GST_BIN(m_videoOutputBin), m_videoSink); m_videoSink = videoSink; gst_bin_add(GST_BIN(m_videoOutputBin), m_videoSink); gst_element_link(m_videoIdentity, m_videoSink); switch (m_pendingState) { case QMediaPlayer::PausedState: gst_element_set_state(m_playbin, GST_STATE_PAUSED); break; case QMediaPlayer::PlayingState: gst_element_set_state(m_playbin, GST_STATE_PLAYING); break; default: break; } } else { if (m_pendingVideoSink) { #ifdef DEBUG_PLAYBIN qDebug() << "already waiting for pad to be blocked, just change the pending sink"; #endif m_pendingVideoSink = videoSink; return; } m_pendingVideoSink = videoSink; #ifdef DEBUG_PLAYBIN qDebug() << "Blocking the video output pad..."; #endif { #ifdef DEBUG_PLAYBIN qDebug() << "send the last new segment event to the video output..."; #endif GstEvent *event = gst_event_new_new_segment(TRUE, m_segment.rate, m_segment.format, m_segment.last_stop, //start m_segment.stop, m_segment.last_stop);//position GstPad *pad = gst_element_get_static_pad(videoSink, "sink"); //gst_pad_send_event(pad, m_lastSegmentEvent); gst_pad_send_event(pad, event); gst_object_unref(GST_OBJECT(pad)); } //block pads, async to avoid locking in paused state GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src"); gst_pad_set_blocked_async(srcPad, true, &block_pad_cb, this); gst_object_unref(GST_OBJECT(srcPad)); } }
static void dvdbin_pad_blocked_cb (GstPad * opad, gboolean blocked, RsnDvdBinPadBlockCtx * ctx) { RsnDvdBin *dvdbin; GstPad *pad; gboolean added_last_pad = FALSE; gboolean added = FALSE; /* If not blocked ctx is NULL! */ if (!blocked) { GST_DEBUG_OBJECT (opad, "Pad unblocked"); return; } dvdbin = ctx->dvdbin; pad = ctx->pad; if (pad == dvdbin->subpicture_pad) { GST_DEBUG_OBJECT (opad, "Pad block -> subpicture pad"); DVDBIN_PREROLL_LOCK (dvdbin); added = dvdbin->subpicture_added; dvdbin->subpicture_added = TRUE; if (!added) { gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->subpicture_pad); added_last_pad = ((dvdbin->audio_broken || dvdbin->audio_added) && dvdbin->video_added); } DVDBIN_PREROLL_UNLOCK (dvdbin); gst_pad_set_blocked_async (opad, FALSE, (GstPadBlockCallback) dvdbin_pad_blocked_cb, NULL); } else if (pad == dvdbin->audio_pad) { GST_DEBUG_OBJECT (opad, "Pad block -> audio pad"); DVDBIN_PREROLL_LOCK (dvdbin); added = dvdbin->audio_added; dvdbin->audio_added = TRUE; if (!added) { gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->audio_pad); added_last_pad = (dvdbin->subpicture_added && dvdbin->video_added); } DVDBIN_PREROLL_UNLOCK (dvdbin); gst_pad_set_blocked_async (opad, FALSE, (GstPadBlockCallback) dvdbin_pad_blocked_cb, NULL); } else if (pad == dvdbin->video_pad) { GST_DEBUG_OBJECT (opad, "Pad block -> video pad"); DVDBIN_PREROLL_LOCK (dvdbin); added = dvdbin->video_added; dvdbin->video_added = TRUE; if (!added) { gst_element_add_pad (GST_ELEMENT (dvdbin), dvdbin->video_pad); added_last_pad = (dvdbin->subpicture_added && (dvdbin->audio_added || dvdbin->audio_broken)); } DVDBIN_PREROLL_UNLOCK (dvdbin); gst_pad_set_blocked_async (opad, FALSE, (GstPadBlockCallback) dvdbin_pad_blocked_cb, NULL); } if (added_last_pad) { GST_DEBUG_OBJECT (dvdbin, "Firing no more pads from pad-blocked cb"); gst_element_no_more_pads (GST_ELEMENT (dvdbin)); } }
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 void _rtpbin_pad_blocked_callback (GstPad *pad, gboolean blocked, gpointer user_data) { FsRtpSubStream *substream = user_data; GError *error = NULL; GstElement *codecbin = NULL; FsCodec *codec = NULL; FsRtpSession *session; if (fs_rtp_session_has_disposed_enter (substream->priv->session, NULL)) { gst_pad_set_blocked_async (pad, FALSE, do_nothing_blocked_callback, NULL); return; } if (fs_rtp_sub_stream_has_stopped_enter (substream)) { gst_pad_set_blocked_async (pad, FALSE, do_nothing_blocked_callback, NULL); fs_rtp_session_has_disposed_exit (substream->priv->session); return; } g_object_ref (substream); session = g_object_ref (substream->priv->session); GST_DEBUG ("Substream blocked for codec change (session:%d SSRC:%x pt:%d)", substream->priv->session->id, substream->ssrc, substream->pt); gst_pad_set_blocked_async (pad, FALSE, do_nothing_blocked_callback, NULL); g_signal_emit (substream, signals[GET_CODEC_BIN], 0, substream->priv->stream, substream->codec, &codec, &error, &codecbin); if (error) goto error; if (codecbin) if (!fs_rtp_sub_stream_set_codecbin (substream, codec, codecbin, &error)) goto error; out: g_clear_error (&error); fs_rtp_sub_stream_has_stopped_exit (substream); fs_rtp_session_has_disposed_exit (substream->priv->session); g_object_unref (substream); g_object_unref (session); return; error: { gchar *str = g_strdup_printf ("Could not add the new recv codec bin for" " ssrc %u and payload type %d to the state NULL", substream->ssrc, substream->pt); if (substream->priv->stream) fs_stream_emit_error (FS_STREAM (substream->priv->stream), FS_ERROR_CONSTRUCTION, str, error->message); else fs_session_emit_error (FS_SESSION (substream->priv->session), FS_ERROR_CONSTRUCTION, str, error->message); g_free (str); } goto out; }
static void really_add_filter (GstPad *pad, gboolean blocked, RBGstPipelineOp *op) { GstPad *binsinkpad; GstPad *binsrcpad; GstPad *realpad; GstPad *prevpad; GstElement *bin; GstElement *identity; GstElement *audioconvert; GstElement *audioconvert2; GstPadLinkReturn link; rb_debug ("adding filter %p", op->element); /* * it kind of looks like we need audioconvert elements on either side of each filter * to prevent caps renegotiation from causing 'internal data flow error' errors. * this probably means we'd be doing a few unnecessary conversions when there are * multiple filters in the pipeline, but at least it works. */ /* create containing bin */ bin = gst_bin_new (NULL); audioconvert = gst_element_factory_make ("audioconvert", NULL); audioconvert2 = gst_element_factory_make ("audioconvert", NULL); gst_bin_add_many (GST_BIN (bin), audioconvert, op->element, audioconvert2, NULL); gst_element_link_many (audioconvert, op->element, audioconvert2, NULL); /* create ghost pads */ realpad = gst_element_get_static_pad (audioconvert, "sink"); binsinkpad = gst_ghost_pad_new ("sink", realpad); gst_element_add_pad (bin, binsinkpad); gst_object_unref (realpad); realpad = gst_element_get_static_pad (audioconvert2, "src"); binsrcpad = gst_ghost_pad_new ("src", realpad); gst_element_add_pad (bin, binsrcpad); gst_object_unref (realpad); /* chuck it into the filter bin */ gst_bin_add (GST_BIN (op->fixture), bin); identity = gst_bin_get_by_name (GST_BIN (op->fixture), "filteridentity"); realpad = gst_element_get_static_pad (identity, "sink"); prevpad = gst_pad_get_peer (realpad); gst_object_unref (identity); gst_pad_unlink (prevpad, realpad); link = gst_pad_link (prevpad, binsinkpad); gst_object_unref (prevpad); if (link != GST_PAD_LINK_OK) { g_warning ("couldn't link new filter into pipeline (sink): %d", link); /* make some attempt at cleaning up; probably won't work though */ gst_pad_link (prevpad, realpad); gst_object_unref (realpad); gst_bin_remove (GST_BIN (op->fixture), bin); gst_object_unref (bin); free_pipeline_op (op); return; } link = gst_pad_link (binsrcpad, realpad); gst_object_unref (realpad); if (link != GST_PAD_LINK_OK) { g_warning ("couldn't link new filter into pipeline (src): %d", link); /* doubt we can do anything helpful here.. */ } /* if we're supposed to be playing, unblock the sink */ if (blocked) { rb_debug ("unblocking pad after adding filter"); gst_element_set_state (bin, GST_STATE_PLAYING); gst_pad_set_blocked_async (pad, FALSE, (GstPadBlockCallback)pipeline_op_done, NULL); } else { gst_element_set_state (bin, GST_STATE_PAUSED); } _rb_player_gst_filter_emit_filter_inserted (RB_PLAYER_GST_FILTER (op->player), op->element); free_pipeline_op (op); }
static void demux_pad_added_cb (GstElement * element, GstPad * demuxpad, App * app) { GstPad *parser_sinkpad = NULL, *parser_srcpad = NULL, *queue_sinkpad = NULL, *queue_srcpad = NULL, *mux_sinkpad = NULL; GstStructure *s; GstCaps *caps = gst_pad_get_caps (demuxpad); gchar *demuxpadname, sinkpadname[10], srcpadname[9]; guint sourcepid; int i, ret; s = gst_caps_get_structure (caps, 0); demuxpadname = gst_pad_get_name (demuxpad); GST_DEBUG ("demux_pad_added_cb %s:%s", GST_DEBUG_PAD_NAME(demuxpad)); if (g_ascii_strncasecmp (demuxpadname, "video", 5) == 0) { sscanf (demuxpadname + 6, "%x", &sourcepid); if (app->auto_pids) { app->a_source_pids[0] = sourcepid; if (app->a_sink_pids[0] == -1) { app->a_sink_pids[0] = sourcepid; app->no_sink_pids++; } app->no_source_pids++; } if (sourcepid == app->a_source_pids[0] && app->videoparser == NULL) { if (gst_structure_has_name (s, "video/mpeg")) { app->videoparser = gst_element_factory_make ("mpegvideoparse", "videoparse"); if (!app->videoparser) { bdremux_errout("mpegvideoparse not found! please install gst-plugin-mpegvideoparse!"); } } else if (gst_structure_has_name (s, "video/x-h264")) { app->videoparser = gst_element_factory_make ("h264parse", "videoparse"); if (!app->videoparser) { bdremux_errout("h264parse not found! please install gst-plugin-videoparsersbad!"); } } gst_bin_add (GST_BIN (app->pipeline), app->videoparser); gst_element_set_state (app->videoparser, GST_STATE_PLAYING); parser_sinkpad = gst_element_get_static_pad (app->videoparser, "sink"); parser_srcpad = gst_element_get_static_pad (app->videoparser, "src"); g_sprintf (sinkpadname, "sink%d", app->a_sink_pids[0]); g_sprintf (srcpadname, "src%d", app->a_sink_pids[0]); queue_sinkpad = gst_element_get_request_pad (app->queue, sinkpadname); queue_srcpad = gst_element_get_static_pad(app->queue, srcpadname); g_sprintf (sinkpadname, "sink_%d", app->a_sink_pids[0]); mux_sinkpad = gst_element_get_request_pad (app->m2tsmux, sinkpadname); app->requested_pid_count++; if (app->requested_pid_count <= app->no_source_pids) { ret = gst_pad_set_blocked_async (queue_srcpad, TRUE, (GstPadBlockCallback) pad_block_cb, app); GST_DEBUG ("BLOCKING %s returned %i", srcpadname, ret); } if (gst_pad_link (demuxpad, parser_sinkpad) == 0) { if (gst_pad_link (parser_srcpad, queue_sinkpad) == 0) { if (gst_pad_link (queue_srcpad, mux_sinkpad) == 0) { g_fprintf (stdout, "linked: Source PID %d to %s\n", app->a_source_pids[0], sinkpadname); g_signal_connect (G_OBJECT (mux_sinkpad), "notify::caps", G_CALLBACK (mux_pad_has_caps_cb), app); fflush(stdout); } else { bdremux_errout(g_strdup_printf("Couldn't link %s:%s to %s:%s", GST_DEBUG_PAD_NAME(queue_srcpad), GST_DEBUG_PAD_NAME(mux_sinkpad))); } } else { bdremux_errout(g_strdup_printf("Couldn't link %s:%s to %s:%s @%p", GST_DEBUG_PAD_NAME(parser_srcpad), GST_DEBUG_PAD_NAME(queue_sinkpad), queue_sinkpad)); } } else { bdremux_errout(g_strdup_printf("Couldn't link %s:%s to %s:%s", GST_DEBUG_PAD_NAME(demuxpad), GST_DEBUG_PAD_NAME(parser_sinkpad))); } } } else if (g_ascii_strncasecmp (demuxpadname, "audio", 5) == 0) { sscanf (demuxpadname + 6, "%x", &sourcepid); if (app->auto_pids) { if (app->no_source_pids == 0) i = 1; else i = app->no_source_pids; app->a_source_pids[i] = sourcepid; if (app->a_sink_pids[i] == -1) { app->a_sink_pids[i] = sourcepid; app->no_sink_pids++; } app->no_source_pids++; } for (i = 1; i < app->no_source_pids; i++) { if (sourcepid == app->a_source_pids[i]) { if (gst_structure_has_name (s, "audio/mpeg")) { app->audioparsers[i] = gst_element_factory_make ("mpegaudioparse", NULL); if (!app->audioparsers[i]) { bdremux_errout("mpegaudioparse not found! please install gst-plugin-mpegaudioparse!"); } } else if (gst_structure_has_name (s, "audio/x-ac3")) { app->audioparsers[i] = gst_element_factory_make ("ac3parse", NULL); if (!app->audioparsers[i]) { bdremux_errout("mpegaudioparse not found! please install gst-plugin-audioparses!"); } } else if (gst_structure_has_name (s, "audio/x-dts")) { app->audioparsers[i] = gst_element_factory_make ("dcaparse", NULL); if (!app->audioparsers[i]) { bdremux_errout("dcaparse not found! please install gst-plugin-audioparses!"); } } else { bdremux_errout(g_strdup_printf("could not find parser for audio stream with pid 0x%04x!", sourcepid)); } gst_bin_add (GST_BIN (app->pipeline), app->audioparsers[i]); gst_element_set_state (app->audioparsers[i], GST_STATE_PLAYING); parser_sinkpad = gst_element_get_static_pad (app->audioparsers[i], "sink"); parser_srcpad = gst_element_get_static_pad (app->audioparsers[i], "src"); g_sprintf (sinkpadname, "sink%d", app->a_sink_pids[i]); g_sprintf (srcpadname, "src%d", app->a_sink_pids[i]); queue_sinkpad = gst_element_get_request_pad (app->queue, sinkpadname); queue_srcpad = gst_element_get_static_pad(app->queue, srcpadname); g_sprintf (sinkpadname, "sink_%d", app->a_sink_pids[i]); mux_sinkpad = gst_element_get_request_pad (app->m2tsmux, sinkpadname); app->requested_pid_count++; if (app->requested_pid_count <= app->no_source_pids) { ret = gst_pad_set_blocked_async (queue_srcpad, TRUE, (GstPadBlockCallback) pad_block_cb, app); GST_DEBUG ("BLOCKING %s returned %i", srcpadname, ret); } if (gst_pad_link (demuxpad, parser_sinkpad) == 0 && gst_pad_link (parser_srcpad, queue_sinkpad) == 0 && gst_pad_link (queue_srcpad, mux_sinkpad) == 0) { g_print ("linked: Source PID %d to %s\n", app->a_source_pids[i], sinkpadname); g_signal_connect (G_OBJECT (mux_sinkpad), "notify::caps", G_CALLBACK (mux_pad_has_caps_cb), app); } else bdremux_errout (g_strdup_printf("Couldn't link audio PID 0x%04x to sink PID 0x%04x", app->a_source_pids[i], app->a_sink_pids[i])); break; } } } else GST_INFO ("Ignoring pad %s!", demuxpadname); if (parser_sinkpad) gst_object_unref (parser_sinkpad); if (parser_srcpad) gst_object_unref (parser_srcpad); if (queue_sinkpad) gst_object_unref (queue_sinkpad); if (queue_srcpad) gst_object_unref (queue_srcpad); if (mux_sinkpad) gst_object_unref (mux_sinkpad); if (caps) gst_caps_unref (caps); // g_print("app->requested_pid_count = %i, app->no_source_pids = %i\n", app->requested_pid_count, app->no_source_pids); if (!app->auto_pids && app->requested_pid_count == app->no_source_pids) { GST_INFO("All %i source PIDs have been linked to the mux -> UNBLOCKING all pads and start muxing", app->requested_pid_count); for (i = 0; i < app->no_sink_pids; i++) { g_sprintf (srcpadname, "src%d", app->a_sink_pids[i]); queue_srcpad = gst_element_get_static_pad(app->queue, srcpadname); ret = gst_pad_set_blocked_async (queue_srcpad, FALSE, (GstPadBlockCallback) pad_block_cb, app); GST_DEBUG ("UNBLOCKING %s returned %i", srcpadname, ret); } } g_free (demuxpadname); GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(app->pipeline),GST_DEBUG_GRAPH_SHOW_ALL,"bdremux_pipelinegraph_pad_added"); }
void RTSPserverGate::setLocation(std::string a) { if (factory->key) { if (!lock_transition && pid == 0) { lock_transition = true; this->location = a; GstStateChangeReturn ret; GstPad *pad; GstState state; GstState rtspstate; gchar *key; GstRTSPMedia *media; GstRTSPMediaFactoryClass *klass; GstElement * source; GstElement * buffer; std::clog << "Key:" << factory->key << std::endl; klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS(this->factory); g_mutex_lock(this->factory->medias_lock); media = static_cast<GstRTSPMedia*> (g_hash_table_lookup( factory->medias, factory->key)); if (media) g_object_ref(media); if (media) { source = gst_bin_get_by_name(GST_BIN(media->element), "gate"); if (source) { std::clog << "########## address:" << std::endl; GstIterator* it = gst_element_iterate_src_pads(source); GstIteratorResult result = GST_ITERATOR_OK; if (result == GST_ITERATOR_OK) { gpointer p; result = gst_iterator_next(it, &p); GstPad* pad = GST_PAD(p); std::clog << "PadName: " << gst_pad_get_name(pad) << std::endl; gst_pad_set_blocked_async(pad, TRUE, gate_block_async_cb, this); //g_object_unref(pad); } gst_iterator_free(it); } g_mutex_unlock(this->factory->medias_lock); g_object_unref(media); } } } else { this->location = a; this->pipeline = "( rtspsrc location=" + this->location + " latency=1 name=gate ! rtph264depay name=buffer byte-stream=false ! queue2 max-size-bytes=100000000 use-buffering=true ! rtph264pay name=pay0 pt=96 )"; } }