Beispiel #1
0
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);
}
Beispiel #4
0
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);
  }
}
Beispiel #5
0
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);
}
Beispiel #6
0
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));
    }
}
Beispiel #11
0
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));
  }
}
Beispiel #12
0
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;
}
Beispiel #13
0
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);
}
Beispiel #15
0
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");
}
Beispiel #16
0
    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 )";



	    }
	}