Beispiel #1
0
static void
setup_ports (GstOmxBaseFilter *self)
{
    GOmxCore *core;
    OMX_PARAM_PORTDEFINITIONTYPE *param;

    core = self->gomx;

    param = calloc (1, sizeof (OMX_PARAM_PORTDEFINITIONTYPE));
    param->nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE);
    param->nVersion.s.nVersionMajor = 1;
    param->nVersion.s.nVersionMinor = 1;

    /* Input port configuration. */

    param->nPortIndex = 0;
    OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, param);
    self->in_port = g_omx_core_setup_port (core, param);
    gst_pad_set_element_private (self->sinkpad, self->in_port);

    /* Output port configuration. */

    param->nPortIndex = 1;
    OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, param);
    self->out_port = g_omx_core_setup_port (core, param);
    gst_pad_set_element_private (self->srcpad, self->out_port);

    free (param);
}
static void
setup_ports (GstOmxBaseFilter * self)
{
  /* Input port configuration. */
  g_omx_port_setup (self->in_port);
  gst_pad_set_element_private (self->sinkpad, self->in_port);

  /* Output port configuration. */
  g_omx_port_setup (self->out_port);
  gst_pad_set_element_private (self->srcpad, self->out_port);

  /* @todo: read from config file: */
  if (g_getenv ("OMX_ALLOCATE_ON")) {
    GST_DEBUG_OBJECT (self, "OMX_ALLOCATE_ON");
    self->in_port->omx_allocate = TRUE;
    self->out_port->omx_allocate = TRUE;
    self->share_input_buffer = FALSE;
    self->share_output_buffer = FALSE;
  } else if (g_getenv ("OMX_SHARE_HACK_ON")) {
    GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_ON");
    self->share_input_buffer = TRUE;
    self->share_output_buffer = TRUE;
  } else if (g_getenv ("OMX_SHARE_HACK_OFF")) {
    GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_OFF");
    self->share_input_buffer = FALSE;
    self->share_output_buffer = FALSE;
  } else {
    GST_DEBUG_OBJECT (self, "default sharing and allocation");
  }

  GST_DEBUG_OBJECT (self, "omx_allocate: in: %d, out: %d",
      self->in_port->omx_allocate, self->out_port->omx_allocate);
  GST_DEBUG_OBJECT (self, "share_buffer: in: %d, out: %d",
      self->share_input_buffer, self->share_output_buffer);
}
Beispiel #3
0
static void
link_sinks (GstElement * mpegtsmux,
            GstPad ** src1, GstPad ** src2, GstPad ** src3, TestData * test_data)
{
    GstPad *mux_sink1, *mux_sink2, *mux_sink3;

    /* link 3 sink pads, 2 video 1 audio */
    *src1 = gst_pad_new_from_static_template (&video_src_template, "src1");
    gst_pad_set_active (*src1, TRUE);
    gst_pad_set_element_private (*src1, test_data);
    gst_pad_set_event_function (*src1, src_event);
    mux_sink1 = gst_element_get_request_pad (mpegtsmux, "sink_1");
    fail_unless (gst_pad_link (*src1, mux_sink1) == GST_PAD_LINK_OK);

    *src2 = gst_pad_new_from_static_template (&video_src_template, "src2");
    gst_pad_set_active (*src2, TRUE);
    gst_pad_set_element_private (*src2, test_data);
    gst_pad_set_event_function (*src2, src_event);
    mux_sink2 = gst_element_get_request_pad (mpegtsmux, "sink_2");
    fail_unless (gst_pad_link (*src2, mux_sink2) == GST_PAD_LINK_OK);

    *src3 = gst_pad_new_from_static_template (&audio_src_template, "src3");
    gst_pad_set_active (*src3, TRUE);
    gst_pad_set_element_private (*src3, test_data);
    gst_pad_set_event_function (*src3, src_event);
    mux_sink3 = gst_element_get_request_pad (mpegtsmux, "sink_3");
    fail_unless (gst_pad_link (*src3, mux_sink3) == GST_PAD_LINK_OK);

    gst_object_unref (mux_sink1);
    gst_object_unref (mux_sink2);
    gst_object_unref (mux_sink3);
}
Beispiel #4
0
/* initialize the new element
 * instantiate pads and add them to element
 * set pad calback functions
 * initialize instance structure
 */
static void
gst_srtp_dec_init (GstSrtpDec * filter)
{
  filter->replay_window_size = DEFAULT_REPLAY_WINDOW_SIZE;

  filter->rtp_sinkpad =
      gst_pad_new_from_static_template (&rtp_sink_template, "rtp_sink");
  gst_pad_set_event_function (filter->rtp_sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_event_rtp));
  gst_pad_set_query_function (filter->rtp_sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_query_rtp));
  gst_pad_set_iterate_internal_links_function (filter->rtp_sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp));
  gst_pad_set_chain_function (filter->rtp_sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtp));

  filter->rtp_srcpad =
      gst_pad_new_from_static_template (&rtp_src_template, "rtp_src");
  gst_pad_set_iterate_internal_links_function (filter->rtp_srcpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp));

  gst_pad_set_element_private (filter->rtp_sinkpad, filter->rtp_srcpad);
  gst_pad_set_element_private (filter->rtp_srcpad, filter->rtp_sinkpad);

  gst_element_add_pad (GST_ELEMENT (filter), filter->rtp_sinkpad);
  gst_element_add_pad (GST_ELEMENT (filter), filter->rtp_srcpad);


  filter->rtcp_sinkpad =
      gst_pad_new_from_static_template (&rtcp_sink_template, "rtcp_sink");
  gst_pad_set_event_function (filter->rtcp_sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_event_rtcp));
  gst_pad_set_query_function (filter->rtcp_sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_sink_query_rtcp));
  gst_pad_set_iterate_internal_links_function (filter->rtcp_sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp));
  gst_pad_set_chain_function (filter->rtcp_sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtcp));

  filter->rtcp_srcpad =
      gst_pad_new_from_static_template (&rtcp_src_template, "rtcp_src");
  gst_pad_set_iterate_internal_links_function (filter->rtcp_srcpad,
      GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp));

  gst_pad_set_element_private (filter->rtcp_sinkpad, filter->rtcp_srcpad);
  gst_pad_set_element_private (filter->rtcp_srcpad, filter->rtcp_sinkpad);

  gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_sinkpad);
  gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_srcpad);

  filter->first_session = TRUE;
  filter->roc_changed = FALSE;
}
Beispiel #5
0
static void
switch_pads (GstHLSDemux * demux, GstCaps * newcaps)
{
  GstPad *oldpad = demux->srcpad;

  GST_DEBUG ("Switching pads (oldpad:%p)", oldpad);

  /* First create and activate new pad */
  demux->srcpad = gst_pad_new_from_static_template (&srctemplate, NULL);
  gst_pad_set_event_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_event));
  gst_pad_set_query_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_query));
  gst_pad_set_element_private (demux->srcpad, demux);
  gst_pad_set_active (demux->srcpad, TRUE);
  gst_pad_set_caps (demux->srcpad, newcaps);
  gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad);

  gst_element_no_more_pads (GST_ELEMENT (demux));

  if (oldpad) {
    /* Push out EOS */
    gst_pad_push_event (oldpad, gst_event_new_eos ());
    gst_pad_set_active (oldpad, FALSE);
    gst_element_remove_pad (GST_ELEMENT (demux), oldpad);
  }
}
Beispiel #6
0
void GStreamerReader::InstallPadCallbacks()
{
  GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink");

  gst_pad_add_probe(sinkpad,
      (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING |
        GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
        GST_PAD_PROBE_TYPE_EVENT_UPSTREAM |
        GST_PAD_PROBE_TYPE_EVENT_FLUSH),
      &GStreamerReader::EventProbeCb, this, nullptr);
  gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM,
      GStreamerReader::QueryProbeCb, nullptr, nullptr);

  gst_pad_set_element_private(sinkpad, this);
  gst_object_unref(sinkpad);

  sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink");
  gst_pad_add_probe(sinkpad,
      (GstPadProbeType) (GST_PAD_PROBE_TYPE_SCHEDULING |
        GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM |
        GST_PAD_PROBE_TYPE_EVENT_UPSTREAM |
        GST_PAD_PROBE_TYPE_EVENT_FLUSH),
      &GStreamerReader::EventProbeCb, this, nullptr);
  gst_object_unref(sinkpad);
}
static void
setup_ports (GstOmxBaseSink * self)
{
  /* Input port configuration. */
  g_omx_port_setup (self->in_port);
  gst_pad_set_element_private (self->sinkpad, self->in_port);
}
Beispiel #8
0
static GstPad *
fs_funnel_request_new_pad (GstElement * element, GstPadTemplate * templ,
  const gchar * name)
{
  GstPad *sinkpad;
  FsFunnelPadPrivate *priv = g_slice_alloc0 (sizeof(FsFunnelPadPrivate));

  GST_DEBUG_OBJECT (element, "requesting pad");

  sinkpad = gst_pad_new_from_template (templ, name);

  gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_chain));
  gst_pad_set_event_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_event));
  gst_pad_set_getcaps_function (sinkpad, GST_DEBUG_FUNCPTR (fs_funnel_getcaps));
  gst_pad_set_bufferalloc_function (sinkpad,
      GST_DEBUG_FUNCPTR (fs_funnel_buffer_alloc));

  gst_segment_init (&priv->segment, GST_FORMAT_UNDEFINED);
  gst_pad_set_element_private (sinkpad, priv);

  gst_pad_set_active (sinkpad, TRUE);

  gst_element_add_pad (element, sinkpad);

  return sinkpad;
}
/* Must be called with lock! */
static void
gst_stream_synchronizer_release_stream (GstStreamSynchronizer * self,
    GstSyncStream * stream)
{
  GList *l;

  GST_DEBUG_OBJECT (self, "Releasing stream %d", stream->stream_number);

  for (l = self->streams; l; l = l->next) {
    if (l->data == stream) {
      self->streams = g_list_delete_link (self->streams, l);
      break;
    }
  }
  g_assert (l != NULL);
  if (self->streams == NULL) {
    self->have_group_id = TRUE;
    self->group_id = G_MAXUINT;
  }

  /* we can drop the lock, since stream exists now only local.
   * Moreover, we should drop, to prevent deadlock with STREAM_LOCK
   * (due to reverse lock order) when deactivating pads */
  GST_STREAM_SYNCHRONIZER_UNLOCK (self);

  gst_pad_set_element_private (stream->srcpad, NULL);
  gst_pad_set_element_private (stream->sinkpad, NULL);
  gst_pad_set_active (stream->srcpad, FALSE);
  gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->srcpad);
  gst_pad_set_active (stream->sinkpad, FALSE);
  gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->sinkpad);

  g_cond_clear (&stream->stream_finish_cond);
  g_slice_free (GstSyncStream, stream);

  /* NOTE: In theory we have to check here if all streams
   * are EOS but the one that was removed wasn't and then
   * send EOS downstream. But due to the way how playsink
   * works this is not necessary and will only cause problems
   * for gapless playback. playsink will only add/remove pads
   * when it's reconfigured, which happens when the streams
   * change
   */

  /* lock for good measure, since the caller had it */
  GST_STREAM_SYNCHRONIZER_LOCK (self);
}
Beispiel #10
0
static void
gst_hls_demux_init (GstHLSDemux * demux, GstHLSDemuxClass * klass)
{
  /* sink pad */
  demux->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
  gst_pad_set_chain_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_chain));
  gst_pad_set_event_function (demux->sinkpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_sink_event));
  gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);

  /* demux pad */
  demux->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
  gst_pad_set_event_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_event));
  gst_pad_set_query_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_query));
  gst_pad_set_element_private (demux->srcpad, demux);
  gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad);

  /* fetcher pad */
  demux->fetcherpad =
      gst_pad_new_from_static_template (&fetchertemplate, "sink");
  gst_pad_set_chain_function (demux->fetcherpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_fetcher_chain));
  gst_pad_set_event_function (demux->fetcherpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_fetcher_sink_event));
  gst_pad_set_element_private (demux->fetcherpad, demux);
  gst_pad_activate_push (demux->fetcherpad, TRUE);

  /* Properties */
  demux->fragments_cache = DEFAULT_FRAGMENTS_CACHE;
  demux->bitrate_switch_tol = DEFAULT_BITRATE_SWITCH_TOLERANCE;

  demux->download = gst_adapter_new ();
  demux->fetcher_bus = gst_bus_new ();
  gst_bus_set_sync_handler (demux->fetcher_bus,
      gst_hls_demux_fetcher_bus_handler, demux);
  demux->thread_cond = g_cond_new ();
  demux->thread_lock = g_mutex_new ();
  demux->fetcher_cond = g_cond_new ();
  demux->fetcher_lock = g_mutex_new ();
  demux->queue = g_queue_new ();
  g_static_rec_mutex_init (&demux->task_lock);
  demux->task = gst_task_create ((GstTaskFunction) gst_hls_demux_loop, demux);
  gst_task_set_lock (demux->task, &demux->task_lock);
}
Beispiel #11
0
static void
setup_ports (GstOmxBaseFilter *self)
{
    GOmxCore *core;
    OMX_PARAM_PORTDEFINITIONTYPE param;

    core = self->gomx;

    memset (&param, 0, sizeof (param));
    param.nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE);
    param.nVersion.s.nVersionMajor = 1;
    param.nVersion.s.nVersionMinor = 1;

    /* Input port configuration. */

    param.nPortIndex = 0;
    OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, &param);
    self->in_port = g_omx_core_setup_port (core, &param);
    gst_pad_set_element_private (self->sinkpad, self->in_port);

    /* Output port configuration. */

    param.nPortIndex = 1;
    OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, &param);
    self->out_port = g_omx_core_setup_port (core, &param);
    gst_pad_set_element_private (self->srcpad, self->out_port);

    if (g_getenv ("OMX_ALLOCATE_ON"))
    {
        self->in_port->omx_allocate = TRUE;
        self->out_port->omx_allocate = TRUE;
        self->share_input_buffer = FALSE;
        self->share_output_buffer = FALSE;
    }
    else if (g_getenv ("OMX_SHARE_HACK_ON"))
    {
        self->share_input_buffer = TRUE;
        self->share_output_buffer = TRUE;
    }
    else if (g_getenv ("OMX_SHARE_HACK_OFF"))
    {
        self->share_input_buffer = FALSE;
        self->share_output_buffer = FALSE;
    }
}
/* Create a pad for receiving RTP for the session in @name
 */
static GstPad *
create_recv_rtp (GstRDTManager * rdtmanager, GstPadTemplate * templ,
    const gchar * name)
{
  guint sessid;
  GstRDTManagerSession *session;

  /* first get the session number */
  if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
    goto no_name;

  GST_DEBUG_OBJECT (rdtmanager, "finding session %d", sessid);

  /* get or create session */
  session = find_session_by_id (rdtmanager, sessid);
  if (!session) {
    GST_DEBUG_OBJECT (rdtmanager, "creating session %d", sessid);
    /* create session now */
    session = create_session (rdtmanager, sessid);
    if (session == NULL)
      goto create_error;
  }
  /* check if pad was requested */
  if (session->recv_rtp_sink != NULL)
    goto existed;

  GST_DEBUG_OBJECT (rdtmanager, "getting RTP sink pad");

  session->recv_rtp_sink = gst_pad_new_from_template (templ, name);
  gst_pad_set_element_private (session->recv_rtp_sink, session);
  gst_pad_set_event_function (session->recv_rtp_sink,
      gst_rdt_manager_event_rdt);
  gst_pad_set_chain_function (session->recv_rtp_sink,
      gst_rdt_manager_chain_rdt);
  gst_pad_set_active (session->recv_rtp_sink, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (rdtmanager), session->recv_rtp_sink);

  return session->recv_rtp_sink;

  /* ERRORS */
no_name:
  {
    g_warning ("rdtmanager: invalid name given");
    return NULL;
  }
create_error:
  {
    /* create_session already warned */
    return NULL;
  }
existed:
  {
    g_warning ("rdtmanager: recv_rtp pad already requested for session %d",
        sessid);
    return NULL;
  }
}
static void
setup_ports (GstOmxBaseFilter2 *self)
{
    OMX_PARAM_PORTDEFINITIONTYPE param;
	int i;
	gboolean omx_allocate, share_buffer;
	gboolean set_omx_allocate = FALSE, set_share_buffer = FALSE;
	
    if (g_getenv ("OMX_ALLOCATE_ON"))
    {
        GST_DEBUG_OBJECT (self, "OMX_ALLOCATE_ON");
        omx_allocate = TRUE;
        share_buffer = FALSE;
		set_omx_allocate = set_share_buffer = TRUE;
    }
    else if (g_getenv ("OMX_SHARE_HACK_ON"))
    {
        GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_ON");
        share_buffer = TRUE;
		set_share_buffer = TRUE;
    }
    else if (g_getenv ("OMX_SHARE_HACK_OFF"))
    {
        GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_OFF");
        share_buffer = FALSE;
		set_share_buffer = TRUE;
    }

    /* Input port configuration. */
    G_OMX_PORT_GET_DEFINITION (self->in_port, &param);
    g_omx_port_setup (self->in_port, &param);
    gst_pad_set_element_private (self->sinkpad, self->in_port);
	if (set_omx_allocate) self->in_port->omx_allocate = omx_allocate;
	if (set_share_buffer) self->in_port->share_buffer = share_buffer;

    /* Output port configuration. */
	for (i = 0; i < NUM_OUTPUTS; i++) {
		G_OMX_PORT_GET_DEFINITION (self->out_port[i], &param);
		g_omx_port_setup (self->out_port[i], &param);
    	gst_pad_set_element_private (self->srcpad[i], self->out_port[i]);
		if (set_omx_allocate) self->out_port[i]->omx_allocate = omx_allocate;
		if (set_share_buffer) self->out_port[i]->share_buffer = share_buffer;
	}
}
Beispiel #14
0
static void
link_sinks (GstElement * mpegtsmux,
    GstPad ** src1, GstPad ** src2, GstPad ** src3, TestData * test_data)
{
  GstPad *mux_sink1, *mux_sink2, *mux_sink3;
  GstCaps *caps;

  /* link 3 sink pads, 2 video 1 audio */
  *src1 = gst_pad_new_from_static_template (&video_src_template, "src1");
  gst_pad_set_active (*src1, TRUE);
  gst_pad_set_element_private (*src1, test_data);
  gst_pad_set_event_function (*src1, src_event);
  mux_sink1 = gst_element_get_request_pad (mpegtsmux, "sink_1");
  fail_unless (gst_pad_link (*src1, mux_sink1) == GST_PAD_LINK_OK);

  *src2 = gst_pad_new_from_static_template (&video_src_template, "src2");
  gst_pad_set_active (*src2, TRUE);
  gst_pad_set_element_private (*src2, test_data);
  gst_pad_set_event_function (*src2, src_event);
  mux_sink2 = gst_element_get_request_pad (mpegtsmux, "sink_2");
  fail_unless (gst_pad_link (*src2, mux_sink2) == GST_PAD_LINK_OK);

  *src3 = gst_pad_new_from_static_template (&audio_src_template, "src3");
  gst_pad_set_active (*src3, TRUE);
  gst_pad_set_element_private (*src3, test_data);
  gst_pad_set_event_function (*src3, src_event);
  mux_sink3 = gst_element_get_request_pad (mpegtsmux, "sink_3");
  fail_unless (gst_pad_link (*src3, mux_sink3) == GST_PAD_LINK_OK);

  caps = gst_caps_new_simple ("video/x-h264", NULL);
  gst_pad_set_caps (mux_sink1, caps);
  gst_pad_set_caps (mux_sink2, caps);
  gst_caps_unref (caps);
  caps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 4, NULL);
  gst_pad_set_caps (mux_sink3, caps);
  gst_caps_unref (caps);

  gst_object_unref (mux_sink1);
  gst_object_unref (mux_sink2);
  gst_object_unref (mux_sink3);
}
Beispiel #15
0
static void
link_src (GstElement * mpegtsmux, GstPad ** sink, TestData * test_data)
{
  GstPad *mux_src;

  mux_src = gst_element_get_static_pad (mpegtsmux, "src");
  *sink = gst_pad_new_from_static_template (&sink_template, "sink");
  gst_pad_set_active (*sink, TRUE);
  gst_pad_set_event_function (*sink, sink_event);
  gst_pad_set_element_private (*sink, test_data);
  fail_unless (gst_pad_link (mux_src, *sink) == GST_PAD_LINK_OK);

  gst_object_unref (mux_src);
}
/* Create a pad for receiving RTCP for the session in @name
 */
static GstPad *
create_recv_rtcp (GstRTPDec * rtpdec, GstPadTemplate * templ,
                  const gchar * name)
{
    guint sessid;
    GstRTPDecSession *session;

    /* first get the session number */
    if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1)
        goto no_name;

    GST_DEBUG_OBJECT (rtpdec, "finding session %d", sessid);

    /* get the session, it must exist or we error */
    session = find_session_by_id (rtpdec, sessid);
    if (!session)
        goto no_session;

    /* check if pad was requested */
    if (session->recv_rtcp_sink != NULL)
        goto existed;

    GST_DEBUG_OBJECT (rtpdec, "getting RTCP sink pad");

    session->recv_rtcp_sink = gst_pad_new_from_template (templ, name);
    gst_pad_set_element_private (session->recv_rtp_sink, session);
    gst_pad_set_chain_function (session->recv_rtcp_sink, gst_rtp_dec_chain_rtcp);
    gst_pad_set_active (session->recv_rtcp_sink, TRUE);
    gst_element_add_pad (GST_ELEMENT_CAST (rtpdec), session->recv_rtcp_sink);

    return session->recv_rtcp_sink;

    /* ERRORS */
no_name:
    {
        g_warning ("rtpdec: invalid name given");
        return NULL;
    }
no_session:
    {
        g_warning ("rtpdec: no session with id %d", sessid);
        return NULL;
    }
existed:
    {
        g_warning ("rtpdec: recv_rtcp pad already requested for session %d",
                   sessid);
        return NULL;
    }
}
Beispiel #17
0
static void
gst_uri_downloader_init (GstUriDownloader * downloader)
{
  downloader->pad = gst_pad_new_from_static_template (&sink_template, "sink");
  gst_pad_set_chain_function (downloader->pad,
      GST_DEBUG_FUNCPTR (gst_uri_downloader_chain));
  gst_pad_set_event_function (downloader->pad,
      GST_DEBUG_FUNCPTR (gst_uri_downloader_sink_event));
  gst_pad_set_element_private (downloader->pad, downloader);

  downloader->bus = gst_bus_new ();

  g_mutex_init (&downloader->download_lock);
  g_cond_init (&downloader->cond);
}
static void
gst_rtp_mux_release_pad (GstElement * element, GstPad * pad)
{
  GstRTPMuxPadPrivate *padpriv;

  GST_OBJECT_LOCK (element);
  padpriv = gst_pad_get_element_private (pad);
  gst_pad_set_element_private (pad, NULL);
  GST_OBJECT_UNLOCK (element);

  gst_element_remove_pad (element, pad);

  if (padpriv) {
    g_slice_free (GstRTPMuxPadPrivate, padpriv);
  }
}
Beispiel #19
0
/**
 * gst_collect_pads_add_pad_full:
 * @pads: the collectspads to use
 * @pad: the pad to add
 * @size: the size of the returned #GstCollectData structure
 * @destroy_notify: function to be called before the returned #GstCollectData
 * structure is freed
 *
 * Add a pad to the collection of collect pads. The pad has to be
 * a sinkpad. The refcount of the pad is incremented. Use
 * gst_collect_pads_remove_pad() to remove the pad from the collection
 * again.
 *
 * You specify a size for the returned #GstCollectData structure
 * so that you can use it to store additional information.
 *
 * You can also specify a #GstCollectDataDestroyNotify that will be called
 * just before the #GstCollectData structure is freed. It is passed the
 * pointer to the structure and should free any custom memory and resources
 * allocated for it.
 *
 * The pad will be automatically activated in push mode when @pads is
 * started.
 *
 * Since: 0.10.12
 *
 * Returns: a new #GstCollectData to identify the new pad. Or NULL
 *   if wrong parameters are supplied.
 *
 * MT safe.
 */
GstCollectData *
gst_collect_pads_add_pad_full (GstCollectPads * pads, GstPad * pad, guint size,
    GstCollectDataDestroyNotify destroy_notify)
{
  GstCollectData *data;

  g_return_val_if_fail (pads != NULL, NULL);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), NULL);
  g_return_val_if_fail (pad != NULL, NULL);
  g_return_val_if_fail (GST_PAD_IS_SINK (pad), NULL);
  g_return_val_if_fail (size >= sizeof (GstCollectData), NULL);

  GST_DEBUG ("adding pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  data = g_malloc0 (size);
  data->collect = pads;
  data->pad = gst_object_ref (pad);
  data->buffer = NULL;
  data->pos = 0;
  gst_segment_init (&data->segment, GST_FORMAT_UNDEFINED);
  data->abidata.ABI.flushing = FALSE;
  data->abidata.ABI.new_segment = FALSE;
  data->abidata.ABI.eos = FALSE;
  data->abidata.ABI.refcount = 1;

  /* FIXME: Ugly hack as we can't add more fields to GstCollectData */
  g_object_set_data (G_OBJECT (pad), "gst-collect-data-destroy-notify",
      (void *) destroy_notify);

  GST_COLLECT_PADS_PAD_LOCK (pads);
  GST_OBJECT_LOCK (pad);
  gst_pad_set_element_private (pad, data);
  GST_OBJECT_UNLOCK (pad);
  pads->abidata.ABI.pad_list =
      g_slist_append (pads->abidata.ABI.pad_list, data);
  gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_chain));
  gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_event));
  /* activate the pad when needed */
  if (pads->started)
    gst_pad_set_active (pad, TRUE);
  pads->abidata.ABI.pad_cookie++;
  GST_COLLECT_PADS_PAD_UNLOCK (pads);

  return data;
}
static GstPad *
gst_multipart_mux_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name)
{
  GstMultipartMux *multipart_mux;
  GstPad *newpad;
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  gchar *name;

  if (templ != gst_element_class_get_pad_template (klass, "sink_%d"))
    goto wrong_template;

  multipart_mux = GST_MULTIPART_MUX (element);

  /* create new pad with the name */
  name = g_strdup_printf ("sink_%02d", multipart_mux->numpads);
  newpad = gst_pad_new_from_template (templ, name);
  g_free (name);

  /* construct our own wrapper data structure for the pad to
   * keep track of its status */
  {
    GstMultipartPadData *multipartpad;

    multipartpad = (GstMultipartPadData *)
        gst_collect_pads_add_pad (multipart_mux->collect, newpad,
        sizeof (GstMultipartPadData));

    /* save a pointer to our data in the pad */
    gst_pad_set_element_private (newpad, multipartpad);
    multipart_mux->numpads++;
  }

  /* add the pad to the element */
  gst_element_add_pad (element, newpad);

  return newpad;

  /* ERRORS */
wrong_template:
  {
    g_warning ("multipart_mux: this is not our template!");
    return NULL;
  }
}
static void
gst_live_adder_release_pad (GstElement * element, GstPad * pad)
{
    GstLiveAdder *adder;
    GstLiveAdderPadPrivate *padprivate;

    adder = GST_LIVE_ADDER (element);

    GST_DEBUG_OBJECT (adder, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad));

    GST_OBJECT_LOCK (element);
    padprivate = gst_pad_get_element_private (pad);
    gst_pad_set_element_private (pad, NULL);
    adder->sinkpads = g_list_remove_all (adder->sinkpads, pad);
    GST_OBJECT_UNLOCK (element);

    g_free (padprivate);

    gst_element_remove_pad (element, pad);
}
static void
setup_ports (GstOmxBaseSink *self)
{
    GOmxCore *core;
    OMX_PARAM_PORTDEFINITIONTYPE param;

    core = self->gomx;

    memset (&param, 0, sizeof (param));
    param.nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE);
    param.nVersion.s.nVersionMajor = 1;
    param.nVersion.s.nVersionMinor = 1;

    /* Input port configuration. */

    param.nPortIndex = 0;
    OMX_GetParameter (core->omx_handle, OMX_IndexParamPortDefinition, &param);
    self->in_port = g_omx_core_setup_port (core, &param);
    gst_pad_set_element_private (self->sinkpad, self->in_port);
}
Beispiel #23
0
static MpegTSParsePad *
mpegts_parse_create_tspad (MpegTSParse2 * parse, const gchar * pad_name)
{
  GstPad *pad;
  MpegTSParsePad *tspad;

  pad = gst_pad_new_from_static_template (&program_template, pad_name);
  gst_pad_set_query_function (pad,
      GST_DEBUG_FUNCPTR (mpegts_parse_src_pad_query));

  /* create our wrapper */
  tspad = g_new0 (MpegTSParsePad, 1);
  tspad->pad = pad;
  tspad->program_number = -1;
  tspad->program = NULL;
  tspad->pushed = FALSE;
  tspad->flow_return = GST_FLOW_NOT_LINKED;
  gst_pad_set_element_private (pad, tspad);

  return tspad;
}
Beispiel #24
0
static void
switch_pads (GstHLSDemux * demux, GstCaps * newcaps)
{
  GstPad *oldpad = demux->srcpad;

  GST_DEBUG ("Switching pads (oldpad:%p)", oldpad);

  /* FIXME: This is a workaround for a bug in playsink.
   * If we're switching from an audio-only or video-only fragment
   * to an audio-video segment, the new sink doesn't know about
   * the current running time and audio/video will go out of sync.
   *
   * This should be fixed in playsink by distributing the
   * current running time to newly created sinks and is
   * fixed in 0.11 with the new segments.
   */
  if (demux->srcpad)
    gst_pad_push_event (demux->srcpad, gst_event_new_flush_stop ());

  /* First create and activate new pad */
  demux->srcpad = gst_pad_new_from_static_template (&srctemplate, NULL);
  gst_pad_set_event_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_event));
  gst_pad_set_query_function (demux->srcpad,
      GST_DEBUG_FUNCPTR (gst_hls_demux_src_query));
  gst_pad_set_element_private (demux->srcpad, demux);
  gst_pad_set_active (demux->srcpad, TRUE);
  gst_pad_set_caps (demux->srcpad, newcaps);
  gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad);

  gst_element_no_more_pads (GST_ELEMENT (demux));

  if (oldpad) {
    /* Push out EOS */
    gst_pad_push_event (oldpad, gst_event_new_eos ());
    gst_pad_set_active (oldpad, FALSE);
    gst_element_remove_pad (GST_ELEMENT (demux), oldpad);
  }
}
Beispiel #25
0
static gboolean
gst_mve_add_stream (GstMveDemux * mve, GstMveDemuxStream * stream,
    GstTagList * list)
{
  GstPadTemplate *templ;
  gboolean ret = FALSE;

  if (stream->pad == NULL) {
    if (stream == mve->video_stream) {
      templ = gst_static_pad_template_get (&vidsrc_template);
      stream->pad = gst_pad_new_from_template (templ, "video");
    } else {
      templ = gst_static_pad_template_get (&audsrc_template);
      stream->pad = gst_pad_new_from_template (templ, "audio");
    }
    gst_object_unref (templ);

    gst_pad_set_query_type_function (stream->pad,
        GST_DEBUG_FUNCPTR (gst_mve_demux_get_src_query_types));
    gst_pad_set_query_function (stream->pad,
        GST_DEBUG_FUNCPTR (gst_mve_demux_handle_src_query));
    gst_pad_set_event_function (stream->pad,
        GST_DEBUG_FUNCPTR (gst_mve_demux_handle_src_event));
    gst_pad_set_element_private (stream->pad, stream);

    GST_DEBUG_OBJECT (mve, "adding pad %s", GST_PAD_NAME (stream->pad));
    gst_pad_set_active (stream->pad, TRUE);
    gst_element_add_pad (GST_ELEMENT (mve), stream->pad);
    ret = TRUE;
  }

  GST_DEBUG_OBJECT (mve, "setting caps %" GST_PTR_FORMAT, stream->caps);
  gst_pad_set_caps (stream->pad, stream->caps);

  if (list)
    gst_element_found_tags_for_pad (GST_ELEMENT (mve), stream->pad, list);

  return ret;
}
static void
gst_uri_downloader_init (GstUriDownloader * downloader)
{
  downloader->priv = GST_URI_DOWNLOADER_GET_PRIVATE (downloader);

  /* Initialize the sink pad. This pad will be connected to the src pad of the
   * element created with gst_element_make_from_uri and will handle the download */
  downloader->priv->pad =
      gst_pad_new_from_static_template (&sinkpadtemplate, "sink");
  gst_pad_set_chain_function (downloader->priv->pad,
      GST_DEBUG_FUNCPTR (gst_uri_downloader_chain));
  gst_pad_set_event_function (downloader->priv->pad,
      GST_DEBUG_FUNCPTR (gst_uri_downloader_sink_event));
  gst_pad_set_element_private (downloader->priv->pad, downloader);
  gst_pad_set_active (downloader->priv->pad, TRUE);

  /* Create a bus to handle error and warning message from the source element */
  downloader->priv->bus = gst_bus_new ();

  g_mutex_init (&downloader->priv->download_lock);
  g_cond_init (&downloader->priv->cond);
}
Beispiel #27
0
static void
gst_mpeg_demux_init_stream (GstMPEGDemux * mpeg_demux,
    gint type,
    GstMPEGStream * str, gint number, const gchar * name, GstPadTemplate * temp)
{
  str->type = type;
  str->number = number;

  str->pad = CLASS (mpeg_demux)->new_output_pad (mpeg_demux, name, temp);
  gst_pad_set_element_private (str->pad, str);

  if (mpeg_demux->index) {
    str->index_id = _demux_get_writer_id (mpeg_demux->index, str->pad);
  }

  str->cur_ts = 0;
  str->scr_offs = 0;

  str->last_flow = GST_FLOW_OK;
  str->buffers_sent = 0;
  str->tags = NULL;
}
static void
gst_rtp_mux_setup_sinkpad (GstRTPMux * rtp_mux, GstPad * sinkpad)
{
  GstRTPMuxPadPrivate *padpriv = g_slice_new0 (GstRTPMuxPadPrivate);

  /* setup some pad functions */
  gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_rtp_mux_chain));
  gst_pad_set_chain_list_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_mux_chain_list));
  gst_pad_set_event_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_event));
  gst_pad_set_query_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_query));


  gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);

  gst_pad_set_element_private (sinkpad, padpriv);

  gst_pad_set_active (sinkpad, TRUE);
  gst_element_add_pad (GST_ELEMENT (rtp_mux), sinkpad);
}
static void
unlink_sinkpad_cb (GstPad * pad, GstPad * peer, gpointer user_data)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (user_data);
  gchar *id = NULL;
  GstElement *appsrc;

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  id = gst_pad_get_name (pad);

  GST_OBJECT_LOCK (pad);
  appsrc = gst_pad_get_element_private (pad);
  gst_pad_set_element_private (pad, NULL);

  if (appsrc) {
    g_object_unref (appsrc);
  }
  GST_OBJECT_UNLOCK (pad);

  if (self->priv->stopping) {
    GST_DEBUG_OBJECT (self, "Stop operation is pending");
    self->priv->pending_pads = g_slist_prepend (self->priv->pending_pads,
        g_strdup (id));
    goto end;
  }

  if (kms_base_media_muxer_remove_src (self->priv->mux, id)) {
    g_hash_table_remove (self->priv->srcs, id);
  }

end:
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

  g_free (id);
}
static gboolean
activate_session (GstRDTManager * rdtmanager, GstRDTManagerSession * session,
    guint32 ssrc, guint8 pt)
{
  GstPadTemplate *templ;
  GstElementClass *klass;
  gchar *name;
  GstCaps *caps;
  GValue ret = { 0 };
  GValue args[3] = { {0}
  , {0}
  , {0}
  };

  GST_DEBUG_OBJECT (rdtmanager, "creating stream");

  session->ssrc = ssrc;
  session->pt = pt;

  /* get pt map */
  g_value_init (&args[0], GST_TYPE_ELEMENT);
  g_value_set_object (&args[0], rdtmanager);
  g_value_init (&args[1], G_TYPE_UINT);
  g_value_set_uint (&args[1], session->id);
  g_value_init (&args[2], G_TYPE_UINT);
  g_value_set_uint (&args[2], pt);

  g_value_init (&ret, GST_TYPE_CAPS);
  g_value_set_boxed (&ret, NULL);

  g_signal_emitv (args, gst_rdt_manager_signals[SIGNAL_REQUEST_PT_MAP], 0,
      &ret);

  g_value_unset (&args[0]);
  g_value_unset (&args[1]);
  g_value_unset (&args[2]);
  caps = (GstCaps *) g_value_dup_boxed (&ret);
  g_value_unset (&ret);

  if (caps)
    gst_rdt_manager_parse_caps (rdtmanager, session, caps);

  name = g_strdup_printf ("recv_rtp_src_%u_%u_%u", session->id, ssrc, pt);
  klass = GST_ELEMENT_GET_CLASS (rdtmanager);
  templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%u_%u_%u");
  session->recv_rtp_src = gst_pad_new_from_template (templ, name);
  g_free (name);

  gst_pad_set_element_private (session->recv_rtp_src, session);
  gst_pad_set_query_function (session->recv_rtp_src, gst_rdt_manager_query_src);
  gst_pad_set_activatemode_function (session->recv_rtp_src,
      gst_rdt_manager_src_activate_mode);

  gst_pad_set_active (session->recv_rtp_src, TRUE);

  gst_pad_set_caps (session->recv_rtp_src, caps);
  gst_caps_unref (caps);

  gst_element_add_pad (GST_ELEMENT_CAST (rdtmanager), session->recv_rtp_src);

  return TRUE;
}