Exemplo n.º 1
0
EXPORT_C
#endif
void
gst_rtp_buffer_list_set_ssrc (GstBufferList * list, guint32 ssrc)
{
  gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc_header, &ssrc);
}
Exemplo n.º 2
0
/**
 * gst_rtp_buffer_list_set_payload_type:
 * @list: the buffer list
 * @payload_type: the new type
 *
 * Set the payload type of each RTP packet in @list to @payload_type.
 *
 * Since: 0.10.24
 */
void
gst_rtp_buffer_list_set_payload_type (GstBufferList * list, guint8 payload_type)
{
  g_return_if_fail (payload_type < 0x80);

  gst_buffer_list_foreach (list, (GstBufferListFunc) set_pt_header,
      &payload_type);
}
Exemplo n.º 3
0
EXPORT_C
#endif

void
gst_rtp_buffer_list_set_timestamp (GstBufferList * list, guint32 timestamp)
{
  gst_buffer_list_foreach (list, (GstBufferListFunc) set_timestamp_header,
      &timestamp);
}
Exemplo n.º 4
0
EXPORT_C
#endif

guint16
gst_rtp_buffer_list_set_seq (GstBufferList * list, guint16 seq)
{
  gst_buffer_list_foreach (list, (GstBufferListFunc) set_seq_header, &seq);
  return seq;
}
Exemplo n.º 5
0
/* Our assumption for now is that the buffers in a buffer list should always
 * end up in the same file. If someone wants different behaviour, they'll just
 * have to add a property for that. */
static GstFlowReturn
gst_multi_file_sink_render_list (GstBaseSink * sink, GstBufferList * list)
{
  GstBuffer *buf;
  guint size = 0;

  gst_buffer_list_foreach (list, buffer_list_calc_size, &size);
  GST_LOG_OBJECT (sink, "total size of buffer list %p: %u", list, size);

  /* copy all buffers in the list into one single buffer, so we can use
   * the normal render function (FIXME: optimise to avoid the memcpy) */
  buf = gst_buffer_new ();
  gst_buffer_list_foreach (list, buffer_list_copy_data, buf);
  g_assert (gst_buffer_get_size (buf) == size);

  gst_multi_file_sink_render (sink, buf);
  gst_buffer_unref (buf);

  return GST_FLOW_OK;
}
Exemplo n.º 6
0
static void
do_push_buffer_list_pre (GstStatsTracer * self, guint64 ts, GstPad * this_pad,
    GstBufferList * list)
{
  GstPadStats *this_pad_stats = get_pad_stats (self, this_pad);
  GstPad *that_pad = GST_PAD_PEER (this_pad);
  GstPadStats *that_pad_stats = get_pad_stats (self, that_pad);
  DoPushBufferListArgs args = { self, this_pad, this_pad_stats, that_pad,
    that_pad_stats, ts
  };

  gst_buffer_list_foreach (list, do_push_buffer_list_item, &args);
}
Exemplo n.º 7
0
static GstPadProbeReturn
process_buffer_probe_cb (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER) {
    GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);

    process_buffer (buffer, user_data);
  } else if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER_LIST) {
    GstBufferList *list = GST_PAD_PROBE_INFO_BUFFER_LIST (info);

    gst_buffer_list_foreach (list, process_buffer_list_cb, user_data);
  }

  return GST_PAD_PROBE_OK;
}
Exemplo n.º 8
0
static GstFlowReturn
gst_rtp_mux_chain_list (GstPad * pad, GstObject * parent,
    GstBufferList * bufferlist)
{
  GstRTPMux *rtp_mux;
  GstFlowReturn ret;
  GstRTPMuxPadPrivate *padpriv;
  struct BufferListData bd;

  rtp_mux = GST_RTP_MUX (parent);

  GST_OBJECT_LOCK (rtp_mux);

  padpriv = gst_pad_get_element_private (pad);
  if (!padpriv) {
    GST_OBJECT_UNLOCK (rtp_mux);
    ret = GST_FLOW_NOT_LINKED;
    gst_buffer_list_unref (bufferlist);
    goto out;
  }

  bd.rtp_mux = rtp_mux;
  bd.padpriv = padpriv;
  bd.drop = FALSE;

  bufferlist = gst_buffer_list_make_writable (bufferlist);
  gst_buffer_list_foreach (bufferlist, process_list_item, &bd);

  GST_OBJECT_UNLOCK (rtp_mux);

  if (bd.drop) {
    gst_buffer_list_unref (bufferlist);
    ret = GST_FLOW_OK;
  } else {
    ret = gst_pad_push_list (rtp_mux->srcpad, bufferlist);
  }

out:

  return ret;
}
Exemplo n.º 9
0
static GstFlowReturn
gst_rtp_base_depayload_prepare_push (GstRTPBaseDepayload * filter,
    gboolean is_list, gpointer obj)
{
  if (is_list) {
    GstBufferList **blist = obj;
    gst_buffer_list_foreach (*blist, (GstBufferListFunc) set_headers, filter);
  } else {
    GstBuffer **buf = obj;
    set_headers (buf, 0, filter);
  }

  /* if this is the first buffer send a NEWSEGMENT */
  if (G_UNLIKELY (filter->priv->segment_event)) {
    gst_pad_push_event (filter->srcpad, filter->priv->segment_event);
    filter->priv->segment_event = NULL;
    GST_DEBUG_OBJECT (filter, "Pushed newsegment event on this first buffer");
  }

  return GST_FLOW_OK;
}
Exemplo n.º 10
0
static GstPadProbeReturn
kms_av_muxer_injector_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer self)
{
  GstElement *elem;
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;

  if (info->type & GST_PAD_PROBE_TYPE_BLOCK) {
    return GST_PAD_PROBE_PASS;
  }

  elem = gst_pad_get_parent_element (pad);

  g_return_val_if_fail (elem != NULL, GST_PAD_PROBE_OK);

  if (info->type & GST_PAD_PROBE_TYPE_BUFFER_LIST) {
    GstBufferList *list = GST_PAD_PROBE_INFO_BUFFER_LIST (info);
    BufferListItData itData;

    itData.self = self;
    itData.elem = elem;

    if (G_UNLIKELY (!gst_buffer_list_foreach (list,
                kms_av_muxer_injector_probe_it, &itData))) {
      ret = GST_PAD_PROBE_DROP;
    }
  } else if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
    GstBuffer **buffer = (GstBuffer **) & info->data;

    if (G_UNLIKELY (!kms_av_muxer_injector (self, elem, buffer))) {
      ret = GST_PAD_PROBE_DROP;
    }
  }

  g_object_unref (elem);

  return ret;
}
Exemplo n.º 11
0
static GstFlowReturn
sink_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list)
{
  GstDtlsDec *self = GST_DTLS_DEC (parent);
  GstFlowReturn ret = GST_FLOW_OK;
  GstPad *other_pad;

  list = gst_buffer_list_make_writable (list);
  gst_buffer_list_foreach (list, process_buffer_from_list, self);

  if (gst_buffer_list_length (list) == 0) {
    GST_DEBUG_OBJECT (self, "Not produced any buffers");
    gst_buffer_list_unref (list);

    return GST_FLOW_OK;
  }

  g_mutex_lock (&self->src_mutex);
  other_pad = self->src;
  if (other_pad)
    gst_object_ref (other_pad);
  g_mutex_unlock (&self->src_mutex);

  if (other_pad) {
    GST_LOG_OBJECT (self, "decoded buffer list with length %u, pushing",
        gst_buffer_list_length (list));
    ret = gst_pad_push_list (other_pad, list);
    gst_object_unref (other_pad);
  } else {
    GST_LOG_OBJECT (self, "dropped buffer list with length %d, not linked",
        gst_buffer_list_length (list));
    gst_buffer_list_unref (list);
  }

  return ret;
}
Exemplo n.º 12
0
/* Updates the SSRC, payload type, seqnum and timestamp of the RTP buffer
 * before the buffer is pushed. */
static GstFlowReturn
gst_rtp_base_payload_prepare_push (GstRTPBasePayload * payload,
    gpointer obj, gboolean is_list)
{
  GstRTPBasePayloadPrivate *priv;
  HeaderData data;

  if (payload->clock_rate == 0)
    goto no_rate;

  priv = payload->priv;

  /* update first, so that the property is set to the last
   * seqnum pushed */
  payload->seqnum = priv->next_seqnum;

  /* fill in the fields we want to set on all headers */
  data.payload = payload;
  data.seqnum = payload->seqnum;
  data.ssrc = payload->current_ssrc;
  data.pt = payload->pt;

  /* find the first buffer with a timestamp */
  if (is_list) {
    data.dts = -1;
    data.pts = -1;
    data.offset = GST_BUFFER_OFFSET_NONE;
    gst_buffer_list_foreach (GST_BUFFER_LIST_CAST (obj), find_timestamp, &data);
  } else {
    data.dts = GST_BUFFER_DTS (GST_BUFFER_CAST (obj));
    data.pts = GST_BUFFER_PTS (GST_BUFFER_CAST (obj));
    data.offset = GST_BUFFER_OFFSET (GST_BUFFER_CAST (obj));
  }

  /* convert to RTP time */
  if (priv->perfect_rtptime && data.offset != GST_BUFFER_OFFSET_NONE &&
      priv->base_offset != GST_BUFFER_OFFSET_NONE) {
    /* if we have an offset, use that for making an RTP timestamp */
    data.rtptime = payload->ts_base + priv->base_rtime +
        data.offset - priv->base_offset;
    GST_LOG_OBJECT (payload,
        "Using offset %" G_GUINT64_FORMAT " for RTP timestamp", data.offset);
  } else if (GST_CLOCK_TIME_IS_VALID (data.pts)) {
    gint64 rtime;

    /* no offset, use the gstreamer pts */
    rtime = gst_segment_to_running_time (&payload->segment, GST_FORMAT_TIME,
        data.pts);

    if (rtime == -1) {
      GST_LOG_OBJECT (payload, "Clipped pts, using base RTP timestamp");
      rtime = 0;
    } else {
      GST_LOG_OBJECT (payload,
          "Using running_time %" GST_TIME_FORMAT " for RTP timestamp",
          GST_TIME_ARGS (rtime));
      rtime =
          gst_util_uint64_scale_int (rtime, payload->clock_rate, GST_SECOND);
      priv->base_offset = data.offset;
      priv->base_rtime = rtime;
    }
    /* add running_time in clock-rate units to the base timestamp */
    data.rtptime = payload->ts_base + rtime;
  } else {
    GST_LOG_OBJECT (payload,
        "Using previous RTP timestamp %" G_GUINT32_FORMAT, payload->timestamp);
    /* no timestamp to convert, take previous timestamp */
    data.rtptime = payload->timestamp;
  }

  /* set ssrc, payload type, seq number, caps and rtptime */
  if (is_list) {
    gst_buffer_list_foreach (GST_BUFFER_LIST_CAST (obj), set_headers, &data);
  } else {
    GstBuffer *buf = GST_BUFFER_CAST (obj);
    set_headers (&buf, 0, &data);
  }

  priv->next_seqnum = data.seqnum;
  payload->timestamp = data.rtptime;

  GST_LOG_OBJECT (payload, "Preparing to push packet with size %"
      G_GSIZE_FORMAT ", seq=%d, rtptime=%u, pts %" GST_TIME_FORMAT,
      (is_list) ? -1 : gst_buffer_get_size (GST_BUFFER (obj)),
      payload->seqnum, data.rtptime, GST_TIME_ARGS (data.pts));

  if (g_atomic_int_compare_and_exchange (&payload->
          priv->notified_first_timestamp, 1, 0)) {
    g_object_notify (G_OBJECT (payload), "timestamp");
    g_object_notify (G_OBJECT (payload), "seqnum");
  }

  return GST_FLOW_OK;

  /* ERRORS */
no_rate:
  {
    GST_ELEMENT_ERROR (payload, STREAM, NOT_IMPLEMENTED, (NULL),
        ("subclass did not specify clock-rate"));
    return GST_FLOW_ERROR;
  }
}
static GstFlowReturn
gst_rtp_mux_chain_list (GstPad * pad, GstObject * parent,
    GstBufferList * bufferlist)
{
  GstRTPMux *rtp_mux;
  GstFlowReturn ret;
  GstRTPMuxPadPrivate *padpriv;
  gboolean changed = FALSE;
  struct BufferListData bd;

  rtp_mux = GST_RTP_MUX (parent);

  if (gst_pad_check_reconfigure (rtp_mux->srcpad)) {
    GstCaps *current_caps = gst_pad_get_current_caps (pad);

    if (!gst_rtp_mux_setcaps (pad, rtp_mux, current_caps)) {
      ret = GST_FLOW_NOT_NEGOTIATED;
      gst_buffer_list_unref (bufferlist);
      goto out;
    }
    gst_caps_unref (current_caps);
  }

  GST_OBJECT_LOCK (rtp_mux);

  padpriv = gst_pad_get_element_private (pad);
  if (!padpriv) {
    GST_OBJECT_UNLOCK (rtp_mux);
    ret = GST_FLOW_NOT_LINKED;
    gst_buffer_list_unref (bufferlist);
    goto out;
  }

  bd.rtp_mux = rtp_mux;
  bd.padpriv = padpriv;
  bd.drop = FALSE;

  bufferlist = gst_buffer_list_make_writable (bufferlist);
  gst_buffer_list_foreach (bufferlist, process_list_item, &bd);

  if (!bd.drop && pad != rtp_mux->last_pad) {
    changed = TRUE;
    g_clear_object (&rtp_mux->last_pad);
    rtp_mux->last_pad = g_object_ref (pad);
  }

  GST_OBJECT_UNLOCK (rtp_mux);

  if (changed)
    gst_pad_sticky_events_foreach (pad, resend_events, rtp_mux);

  if (bd.drop) {
    gst_buffer_list_unref (bufferlist);
    ret = GST_FLOW_OK;
  } else {
    ret = gst_pad_push_list (rtp_mux->srcpad, bufferlist);
  }

out:

  return ret;
}