/**
 * gst_buffer_list_insert:
 * @list: a #GstBufferList
 * @idx: the index
 * @buffer: (transfer full): a #GstBuffer
 *
 * Insert @buffer at @idx in @list. Other buffers are moved to make room for
 * this new buffer.
 *
 * A -1 value for @idx will append the buffer at the end.
 */
void
gst_buffer_list_insert (GstBufferList * list, gint idx, GstBuffer * buffer)
{
  guint want_alloc;

  g_return_if_fail (GST_IS_BUFFER_LIST (list));
  g_return_if_fail (buffer != NULL);
  g_return_if_fail (gst_buffer_list_is_writable (list));

  if (idx == -1 && list->n_buffers < list->n_allocated) {
    list->buffers[list->n_buffers++] = buffer;
    return;
  }

  if (idx == -1 || idx > list->n_buffers)
    idx = list->n_buffers;

  want_alloc = list->n_buffers + 1;

  if (want_alloc > list->n_allocated) {
    want_alloc = MAX (GST_ROUND_UP_16 (want_alloc), list->n_allocated * 2);

    if (GST_BUFFER_LIST_IS_USING_DYNAMIC_ARRAY (list)) {
      list->buffers = g_renew (GstBuffer *, list->buffers, want_alloc);
    } else {
/**
 * gst_buffer_list_length:
 * @list: a #GstBufferList
 *
 * Returns the number of buffers in @list.
 *
 * Returns: the number of buffers in the buffer list
 */
guint
gst_buffer_list_length (GstBufferList * list)
{
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), 0);

  return list->n_buffers;
}
/**
 * gst_buffer_list_get:
 * @list: a #GstBufferList
 * @idx: the index
 *
 * Get the buffer at @idx.
 *
 * Returns: (transfer none) (nullable): the buffer at @idx in @group
 *     or %NULL when there is no buffer. The buffer remains valid as
 *     long as @list is valid and buffer is not removed from the list.
 */
GstBuffer *
gst_buffer_list_get (GstBufferList * list, guint idx)
{
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), NULL);
  g_return_val_if_fail (idx < list->n_buffers, NULL);

  return list->buffers[idx];
}
Beispiel #4
0
/**
 * gst_proxy_pad_chain_list_default:
 * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
 * @parent: the parent of @pad or NULL
 * @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
 *     if not.
 *
 * Invoke the default chain list function of the proxy pad.
 *
 * Returns: a #GstFlowReturn from the pad.
 */
GstFlowReturn
gst_proxy_pad_chain_list_default (GstPad * pad, GstObject * parent,
    GstBufferList * list)
{
  GstFlowReturn res;
  GstPad *internal;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);

  internal = GST_PROXY_PAD_INTERNAL (pad);
  res = gst_pad_push_list (internal, list);

  return res;
}
/**
 * gst_buffer_list_foreach:
 * @list: a #GstBufferList
 * @func: (scope call): a #GstBufferListFunc to call
 * @user_data: (closure): user data passed to @func
 *
 * Call @func with @data for each buffer in @list.
 *
 * @func can modify the passed buffer pointer or its contents. The return value
 * of @func define if this function returns or if the remaining buffers in
 * the list should be skipped.
 *
 * Returns: %TRUE when @func returned %TRUE for each buffer in @list or when
 * @list is empty.
 */
gboolean
gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
    gpointer user_data)
{
  guint i, len;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
  g_return_val_if_fail (func != NULL, FALSE);

  len = list->n_buffers;
  for (i = 0; i < len;) {
    GstBuffer *buf, *buf_ret;

    buf = buf_ret = list->buffers[i];
    ret = func (&buf_ret, i, user_data);

    /* Check if the function changed the buffer */
    if (buf != buf_ret) {
      if (buf_ret == NULL) {
        gst_buffer_list_remove_range_internal (list, i, 1, FALSE);
        --len;
      } else {
        list->buffers[i] = buf_ret;
      }
    }

    if (!ret)
      break;

    /* If the buffer was not removed by func go to the next buffer */
    if (buf_ret != NULL)
      i++;
  }
  return ret;
}
Beispiel #6
0
/**
 * gst_rtp_buffer_list_validate:
 * @list: the buffer list to validate
 *
 * Check if all RTP packets in the @list are valid using validate_data().
 * Use this function to validate an list before using the other functions in
 * this module.
 *
 * Returns: TRUE if @list consists only of valid RTP packets.
 *
 * Since: 0.10.24
 */
gboolean
gst_rtp_buffer_list_validate (GstBufferList * list)
{
  guint16 prev_seqnum = 0;
  GstBufferListIterator *it;
  guint i = 0;

  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);

  it = gst_buffer_list_iterate (list);
  g_return_val_if_fail (it != NULL, FALSE);

  /* iterate through all the RTP packets in the list */
  while (gst_buffer_list_iterator_next_group (it)) {
    GstBuffer *rtpbuf;
    GstBuffer *paybuf;
    guint8 *packet_header;
    guint8 *packet_payload;
    guint payload_size;
    guint packet_size;

    /* each group should consists of 2 buffers: one containing the RTP header
     * and the other one the payload, FIXME, relax the requirement of only one
     * payload buffer. */
    if (gst_buffer_list_iterator_n_buffers (it) != 2)
      goto invalid_list;

    /* get the RTP header */
    rtpbuf = gst_buffer_list_iterator_next (it);
    packet_header = GST_BUFFER_DATA (rtpbuf);
    if (packet_header == NULL)
      goto invalid_list;

    /* get the payload */
    paybuf = gst_buffer_list_iterator_next (it);
    packet_payload = GST_BUFFER_DATA (paybuf);
    if (packet_payload == NULL) {
      goto invalid_list;
    }
    payload_size = GST_BUFFER_SIZE (paybuf);
    if (payload_size == 0) {
      goto invalid_list;
    }

    /* the size of the RTP packet within the current group */
    packet_size = GST_BUFFER_SIZE (rtpbuf) + payload_size;

    /* check the sequence number */
    if (G_UNLIKELY (i == 0)) {
      prev_seqnum = g_ntohs (GST_RTP_HEADER_SEQ (packet_header));
      i++;
    } else {
      if (++prev_seqnum != g_ntohs (GST_RTP_HEADER_SEQ (packet_header)))
        goto invalid_list;
    }

    /* validate packet */
    if (!validate_data (packet_header, packet_size, packet_payload,
            payload_size)) {
      goto invalid_list;
    }
  }

  gst_buffer_list_iterator_free (it);

  return TRUE;

  /* ERRORS */
invalid_list:
  {
    gst_buffer_list_iterator_free (it);
    return FALSE;
  }
}