예제 #1
0
static GstPadProbeReturn
drop_theora_config (GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
{
  GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
  guint8 *payload;
  guint32 header;
  guchar TDT;

  gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer);

  payload = gst_rtp_buffer_get_payload (&rtpbuffer);

  header = GST_READ_UINT32_BE (payload);
  /*
   *  0                   1                   2                   3
   *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                     Ident                     | F |TDT|# pkts.|
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   *
   * F: Fragment type (0=none, 1=start, 2=cont, 3=end)
   * TDT: Theora data type (0=theora, 1=config, 2=comment, 3=reserved)
   * pkts: number of packets.
   */
  TDT = (header & 0x30) >> 4;

  gst_rtp_buffer_unmap (&rtpbuffer);

  if (TDT == 1)
    return GST_PAD_PROBE_DROP;
  else
    return GST_PAD_PROBE_OK;
}
예제 #2
0
static GstBuffer *
gst_rtp_ilbc_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
{
  GstBuffer *outbuf;
  gboolean marker;
  GstRTPBuffer rtp = { NULL };

  gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);

  marker = gst_rtp_buffer_get_marker (&rtp);

  GST_DEBUG ("process : got %" G_GSIZE_FORMAT " bytes, mark %d ts %u seqn %d",
      gst_buffer_get_size (buf), marker,
      gst_rtp_buffer_get_timestamp (&rtp), gst_rtp_buffer_get_seq (&rtp));

  outbuf = gst_rtp_buffer_get_payload_buffer (&rtp);

  gst_rtp_buffer_unmap (&rtp);

  if (marker && outbuf) {
    /* mark start of talkspurt with DISCONT */
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
  }

  return outbuf;
}
/**
 * gst_rtp_base_audio_payload_push:
 * @baseaudiopayload: a #GstRTPBasePayload
 * @data: data to set as payload
 * @payload_len: length of payload
 * @timestamp: a #GstClockTime
 *
 * Create an RTP buffer and store @payload_len bytes of @data as the
 * payload. Set the timestamp on the new buffer to @timestamp before pushing
 * the buffer downstream.
 *
 * Returns: a #GstFlowReturn
 */
GstFlowReturn
gst_rtp_base_audio_payload_push (GstRTPBaseAudioPayload * baseaudiopayload,
    const guint8 * data, guint payload_len, GstClockTime timestamp)
{
  GstRTPBasePayload *basepayload;
  GstBuffer *outbuf;
  guint8 *payload;
  GstFlowReturn ret;
  GstRTPBuffer rtp = { NULL };

  basepayload = GST_RTP_BASE_PAYLOAD (baseaudiopayload);

  GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT,
      payload_len, GST_TIME_ARGS (timestamp));

  /* create buffer to hold the payload */
  outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);

  /* copy payload */
  gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
  payload = gst_rtp_buffer_get_payload (&rtp);
  memcpy (payload, data, payload_len);
  gst_rtp_buffer_unmap (&rtp);

  /* set metadata */
  gst_rtp_base_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len,
      timestamp);

  ret = gst_rtp_base_payload_push (basepayload, outbuf);

  return ret;
}
예제 #4
0
static GstFlowReturn
gst_rtp_celt_pay_flush_queued (GstRtpCELTPay * rtpceltpay)
{
  GstFlowReturn ret;
  GstBuffer *buf, *outbuf;
  guint8 *payload, *spayload;
  guint payload_len;
  GstClockTime duration;
  GstRTPBuffer rtp = { NULL, };

  payload_len = rtpceltpay->bytes + rtpceltpay->sbytes;
  duration = rtpceltpay->qduration;

  GST_DEBUG_OBJECT (rtpceltpay, "flushing out %u, duration %" GST_TIME_FORMAT,
      payload_len, GST_TIME_ARGS (rtpceltpay->qduration));

  /* get a big enough packet for the sizes + payloads */
  outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);

  GST_BUFFER_DURATION (outbuf) = duration;

  gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);

  /* point to the payload for size headers and data */
  spayload = gst_rtp_buffer_get_payload (&rtp);
  payload = spayload + rtpceltpay->sbytes;

  while ((buf = g_queue_pop_head (rtpceltpay->queue))) {
    guint size;

    /* copy first timestamp to output */
    if (GST_BUFFER_PTS (outbuf) == -1)
      GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (buf);

    /* write the size to the header */
    size = gst_buffer_get_size (buf);
    while (size > 0xff) {
      *spayload++ = 0xff;
      size -= 0xff;
    }
    *spayload++ = size;

    /* copy payload */
    size = gst_buffer_get_size (buf);
    gst_buffer_extract (buf, 0, payload, size);
    payload += size;

    gst_buffer_unref (buf);
  }
  gst_rtp_buffer_unmap (&rtp);

  /* we consumed it all */
  rtpceltpay->bytes = 0;
  rtpceltpay->sbytes = 0;
  rtpceltpay->qduration = 0;

  ret = gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (rtpceltpay), outbuf);

  return ret;
}
static GstBuffer *
generate_test_buffer (GstClockTime gst_ts,
    gboolean marker_bit, guint seq_num, guint32 rtp_ts, guint ssrc)
{
  GstBuffer *buf;
  guint8 *payload;
  guint i;
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;

  buf = gst_rtp_buffer_new_allocate (payload_size, 0, 0);
  GST_BUFFER_DTS (buf) = gst_ts;
  GST_BUFFER_PTS (buf) = gst_ts;

  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
  gst_rtp_buffer_set_payload_type (&rtp, payload_type);
  gst_rtp_buffer_set_marker (&rtp, marker_bit);
  gst_rtp_buffer_set_seq (&rtp, seq_num);
  gst_rtp_buffer_set_timestamp (&rtp, rtp_ts);
  gst_rtp_buffer_set_ssrc (&rtp, ssrc);

  payload = gst_rtp_buffer_get_payload (&rtp);
  for (i = 0; i < payload_size; i++)
    payload[i] = 0xff;

  gst_rtp_buffer_unmap (&rtp);

  return buf;
}
예제 #6
0
static GstBuffer *
generate_test_buffer_full (GstClockTime dts,
    guint seq_num, guint32 rtp_ts, guint ssrc)
{
  GstBuffer *buf;
  guint8 *payload;
  guint i;
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;

  buf = gst_rtp_buffer_new_allocate (TEST_BUF_SIZE, 0, 0);
  GST_BUFFER_DTS (buf) = dts;

  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
  gst_rtp_buffer_set_payload_type (&rtp, TEST_BUF_PT);
  gst_rtp_buffer_set_seq (&rtp, seq_num);
  gst_rtp_buffer_set_timestamp (&rtp, rtp_ts);
  gst_rtp_buffer_set_ssrc (&rtp, ssrc);

  payload = gst_rtp_buffer_get_payload (&rtp);
  for (i = 0; i < TEST_BUF_SIZE; i++)
    payload[i] = 0xff;

  gst_rtp_buffer_unmap (&rtp);

  return buf;
}
예제 #7
0
static void
check_rtp_buffer (GstClockTime ts, GstClockTime duration, gboolean start,
    gboolean end, guint rtpts, guint ssrc, guint volume, guint number,
    guint rtpduration)
{
  GstBuffer *buffer;
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
  gchar *payload;

  g_mutex_lock (&check_mutex);
  while (buffers == NULL)
    g_cond_wait (&check_cond, &check_mutex);
  g_mutex_unlock (&check_mutex);
  fail_unless (buffers != NULL);

  buffer = buffers->data;
  buffers = g_list_delete_link (buffers, buffers);

  fail_unless (GST_BUFFER_PTS (buffer) == ts);
  fail_unless (GST_BUFFER_DURATION (buffer) == duration);

  fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtpbuffer));
  fail_unless (gst_rtp_buffer_get_marker (&rtpbuffer) == start);
  fail_unless (gst_rtp_buffer_get_timestamp (&rtpbuffer) == rtpts);
  payload = gst_rtp_buffer_get_payload (&rtpbuffer);

  fail_unless (payload[0] == number);
  fail_unless ((payload[1] & 0x7F) == volume);
  fail_unless (! !(payload[1] & 0x80) == end);
  fail_unless (GST_READ_UINT16_BE (payload + 2) == rtpduration);

  gst_rtp_buffer_unmap (&rtpbuffer);
  gst_buffer_unref (buffer);
}
예제 #8
0
static gboolean
process_list_item (GstBuffer ** buffer, guint idx, gpointer user_data)
{
  struct BufferListData *bd = user_data;
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;

  *buffer = gst_buffer_make_writable (*buffer);

  gst_rtp_buffer_map (*buffer, GST_MAP_READWRITE, &rtpbuffer);

  bd->drop = !process_buffer_locked (bd->rtp_mux, bd->padpriv, &rtpbuffer);

  gst_rtp_buffer_unmap (&rtpbuffer);

  if (bd->drop)
    return FALSE;

  if (GST_BUFFER_DURATION_IS_VALID (*buffer) &&
      GST_BUFFER_PTS_IS_VALID (*buffer))
    bd->rtp_mux->last_stop = GST_BUFFER_PTS (*buffer) +
        GST_BUFFER_DURATION (*buffer);
  else
    bd->rtp_mux->last_stop = GST_CLOCK_TIME_NONE;

  return TRUE;
}
예제 #9
0
static GstFlowReturn
gst_rtp_ssrc_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
    GstFlowReturn ret;
    GstRtpSsrcDemux *demux;
    guint32 ssrc;
    GstRTPBuffer rtp = { NULL };
    GstPad *srcpad;
    GstRtpSsrcDemuxPad *dpad;

    demux = GST_RTP_SSRC_DEMUX (parent);

    if (!gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp))
        goto invalid_payload;

    ssrc = gst_rtp_buffer_get_ssrc (&rtp);
    gst_rtp_buffer_unmap (&rtp);

    GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc);

    srcpad = find_or_create_demux_pad_for_ssrc (demux, ssrc, RTP_PAD);
    if (srcpad == NULL)
        goto create_failed;

    /* push to srcpad */
    ret = gst_pad_push (srcpad, buf);

    if (ret != GST_FLOW_OK) {
        /* check if the ssrc still there, may have been removed */
        GST_PAD_LOCK (demux);
        dpad = find_demux_pad_for_ssrc (demux, ssrc);
        if (dpad == NULL || dpad->rtp_pad != srcpad) {
            /* SSRC was removed during the push ... ignore the error */
            ret = GST_FLOW_OK;
        }
        GST_PAD_UNLOCK (demux);
    }

    gst_object_unref (srcpad);

    return ret;

    /* ERRORS */
invalid_payload:
    {
        /* this is fatal and should be filtered earlier */
        GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
                           ("Dropping invalid RTP payload"));
        gst_buffer_unref (buf);
        return GST_FLOW_ERROR;
    }
create_failed:
    {
        GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
                           ("Could not create new pad"));
        gst_buffer_unref (buf);
        return GST_FLOW_ERROR;
    }
}
예제 #10
0
static GstBuffer *
gst_rtp_g722_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
{
  GstRtpG722Depay *rtpg722depay;
  GstBuffer *outbuf;
  gint payload_len;
  gboolean marker;
  GstRTPBuffer rtp = { NULL };

  rtpg722depay = GST_RTP_G722_DEPAY (depayload);

  gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);

  payload_len = gst_rtp_buffer_get_payload_len (&rtp);

  if (payload_len <= 0)
    goto empty_packet;

  GST_DEBUG_OBJECT (rtpg722depay, "got payload of %d bytes", payload_len);

  outbuf = gst_rtp_buffer_get_payload_buffer (&rtp);
  marker = gst_rtp_buffer_get_marker (&rtp);
  gst_rtp_buffer_unmap (&rtp);

  if (marker && outbuf) {
    /* mark talk spurt with RESYNC */
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_RESYNC);
  }

  if (outbuf) {
    gst_rtp_drop_meta (GST_ELEMENT_CAST (rtpg722depay), outbuf,
        g_quark_from_static_string (GST_META_TAG_AUDIO_STR));
  }

  return outbuf;

  /* ERRORS */
empty_packet:
  {
    GST_ELEMENT_WARNING (rtpg722depay, STREAM, DECODE,
        ("Empty Payload."), (NULL));
    gst_rtp_buffer_unmap (&rtp);
    return NULL;
  }
}
예제 #11
0
static GstFlowReturn
gst_rtp_sbc_pay_flush_buffers (GstRtpSBCPay * sbcpay)
{
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
  guint available;
  guint max_payload;
  GstBuffer *outbuf;
  guint8 *payload_data;
  guint frame_count;
  guint payload_length;
  struct rtp_payload *payload;

  if (sbcpay->frame_length == 0) {
    GST_ERROR_OBJECT (sbcpay, "Frame length is 0");
    return GST_FLOW_ERROR;
  }

  available = gst_adapter_available (sbcpay->adapter);

  max_payload =
      gst_rtp_buffer_calc_payload_len (GST_RTP_BASE_PAYLOAD_MTU (sbcpay) -
      RTP_SBC_PAYLOAD_HEADER_SIZE, 0, 0);

  max_payload = MIN (max_payload, available);
  frame_count = max_payload / sbcpay->frame_length;
  payload_length = frame_count * sbcpay->frame_length;
  if (payload_length == 0)      /* Nothing to send */
    return GST_FLOW_OK;

  outbuf = gst_rtp_buffer_new_allocate (payload_length +
      RTP_SBC_PAYLOAD_HEADER_SIZE, 0, 0);

  /* get payload */
  gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);

  gst_rtp_buffer_set_payload_type (&rtp, GST_RTP_BASE_PAYLOAD_PT (sbcpay));

  /* write header and copy data into payload */
  payload_data = gst_rtp_buffer_get_payload (&rtp);
  payload = (struct rtp_payload *) payload_data;
  memset (payload, 0, sizeof (struct rtp_payload));
  payload->frame_count = frame_count;

  gst_adapter_copy (sbcpay->adapter, payload_data +
      RTP_SBC_PAYLOAD_HEADER_SIZE, 0, payload_length);

  gst_rtp_buffer_unmap (&rtp);

  gst_adapter_flush (sbcpay->adapter, payload_length);

  /* FIXME: what about duration? */
  GST_BUFFER_PTS (outbuf) = sbcpay->timestamp;
  GST_DEBUG_OBJECT (sbcpay, "Pushing %d bytes", payload_length);

  return gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (sbcpay), outbuf);
}
예제 #12
0
static GstBuffer *
gst_rtp_dtmf_src_create_next_rtp_packet (GstRTPDTMFSrc * dtmfsrc)
{
  GstBuffer *buf;
  GstRTPDTMFPayload *payload;
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;

  buf = gst_rtp_buffer_new_allocate (sizeof (GstRTPDTMFPayload), 0, 0);

  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtpbuffer);

  gst_rtp_dtmf_prepare_rtp_headers (dtmfsrc, &rtpbuffer);

  /* timestamp and duration of GstBuffer */
  /* Redundant buffer have no duration ... */
  if (dtmfsrc->redundancy_count > 1)
    GST_BUFFER_DURATION (buf) = 0;
  else
    GST_BUFFER_DURATION (buf) = dtmfsrc->ptime * GST_MSECOND;
  GST_BUFFER_PTS (buf) = dtmfsrc->timestamp;

  payload = (GstRTPDTMFPayload *) gst_rtp_buffer_get_payload (&rtpbuffer);

  /* copy payload and convert to network-byte order */
  memmove (payload, dtmfsrc->payload, sizeof (GstRTPDTMFPayload));

  payload->duration = g_htons (payload->duration);

  if (dtmfsrc->redundancy_count <= 1 && dtmfsrc->last_packet) {
    GstClockTime inter_digit_interval = MIN_INTER_DIGIT_INTERVAL;

    if (inter_digit_interval % dtmfsrc->ptime != 0)
      inter_digit_interval += dtmfsrc->ptime -
          (MIN_INTER_DIGIT_INTERVAL % dtmfsrc->ptime);

    GST_BUFFER_DURATION (buf) += inter_digit_interval * GST_MSECOND;
  }

  GST_LOG_OBJECT (dtmfsrc, "Creating new buffer with event %u duration "
      " gst: %" GST_TIME_FORMAT " at %" GST_TIME_FORMAT "(rtp ts:%u dur:%u)",
      dtmfsrc->payload->event, GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), dtmfsrc->rtp_timestamp,
      dtmfsrc->payload->duration);

  /* duration of DTMF payloadfor the NEXT packet */
  /* not updated for redundant packets */
  if (dtmfsrc->redundancy_count <= 1)
    dtmfsrc->payload->duration += dtmfsrc->ptime * dtmfsrc->clock_rate / 1000;

  if (GST_CLOCK_TIME_IS_VALID (dtmfsrc->timestamp))
    dtmfsrc->timestamp += GST_BUFFER_DURATION (buf);

  gst_rtp_buffer_unmap (&rtpbuffer);

  return buf;
}
예제 #13
0
static guint32
_rtp_buffer_get_ssrc (GstBuffer * buf)
{
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
  guint32 ret;
  g_assert (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
  ret = gst_rtp_buffer_get_ssrc (&rtp);
  gst_rtp_buffer_unmap (&rtp);
  return ret;
}
예제 #14
0
static GstBuffer *
create_rtp_buffer_with_timestamp (guint32 ssrc, guint8 payload_type,
    guint16 seqnum, guint32 timestamp)
{
  GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;
  GstBuffer *buf = create_rtp_buffer (ssrc, payload_type, seqnum);
  gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtpbuf);
  gst_rtp_buffer_set_timestamp (&rtpbuf, timestamp);
  gst_rtp_buffer_unmap (&rtpbuf);
  return buf;
}
예제 #15
0
static GstPadProbeReturn
rtpsession_sinkpad_probe2 (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;

  if (info->type == (GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH)) {
    GstBuffer *buffer = GST_BUFFER (info->data);
    GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
    guint payload_type = 0;

    static gint i = 0;

    /* retrieve current ssrc for retransmission stream only */
    gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp);
    payload_type = gst_rtp_buffer_get_payload_type (&rtp);
    if (payload_type == 99) {
      if (i < 3)
        rtx_ssrc_before = gst_rtp_buffer_get_ssrc (&rtp);
      else
        rtx_ssrc_after = gst_rtp_buffer_get_ssrc (&rtp);
    } else {
      /* ask to retransmit every packet */
      GstEvent *event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
          gst_structure_new ("GstRTPRetransmissionRequest",
              "seqnum", G_TYPE_UINT, gst_rtp_buffer_get_seq (&rtp),
              "ssrc", G_TYPE_UINT, gst_rtp_buffer_get_ssrc (&rtp),
              NULL));
      gst_pad_push_event (pad, event);

      if (i < 3)
        ssrc_before = gst_rtp_buffer_get_ssrc (&rtp);
      else
        ssrc_after = gst_rtp_buffer_get_ssrc (&rtp);
    }
    gst_rtp_buffer_unmap (&rtp);

    /* feint a collision on recv_rtcp_sink pad of gstrtpsession
     * (note that after being marked as collied the rtpsession ignores
     * all non bye packets)
     */
    if (i == 2) {
      GstBuffer *rtcp_buffer = create_rtcp_app (rtx_ssrc_before, 0);

      /* push collied packet on recv_rtcp_sink */
      gst_pad_push (srcpad, rtcp_buffer);
    }

    ++i;
  }

  return ret;
}
예제 #16
0
static GstBuffer *
gst_rtp_opus_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
{
  GstBuffer *outbuf;
  GstRTPBuffer rtpbuf = { NULL, };

  gst_rtp_buffer_map (buf, GST_MAP_READ, &rtpbuf);
  outbuf = gst_rtp_buffer_get_payload_buffer (&rtpbuf);
  gst_rtp_buffer_unmap (&rtpbuf);

  return outbuf;
}
예제 #17
0
static gboolean
buffer_is_rtcp (GstBuffer * buffer)
{
  GstRTPBuffer rtp_buffer = { NULL };

  if (!gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp_buffer)) {
    return TRUE;
  }

  gst_rtp_buffer_unmap (&rtp_buffer);
  return FALSE;
}
예제 #18
0
static void
basic_check_cb (GstPad * pad, int i)
{
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
  fail_unless (buffers && g_list_length (buffers) == 1);

  gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
  fail_unless_equals_int (66, gst_rtp_buffer_get_ssrc (&rtpbuffer));
  fail_unless_equals_int64 (200 - 57 + 1000 + i,
      gst_rtp_buffer_get_timestamp (&rtpbuffer));
  fail_unless_equals_int (100 + 1 + i, gst_rtp_buffer_get_seq (&rtpbuffer));
  gst_rtp_buffer_unmap (&rtpbuffer);
}
예제 #19
0
static gboolean
handle_buffer (GstRtpOnvifParse * self, GstBuffer * buf)
{
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
  guint8 *data;
  guint16 bits;
  guint wordlen;
  guint8 flags;
  /*
     guint64 timestamp;
     guint8 cseq;
   */

  if (!gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp)) {
    GST_ELEMENT_ERROR (self, STREAM, FAILED,
        ("Failed to map RTP buffer"), (NULL));
    return FALSE;
  }

  /* Check if the ONVIF RTP extension is present in the packet */
  if (!gst_rtp_buffer_get_extension_data (&rtp, &bits, (gpointer) & data,
          &wordlen))
    goto out;

  if (bits != EXTENSION_ID || wordlen != EXTENSION_SIZE)
    goto out;

  /* timestamp = GST_READ_UINT64_BE (data);  TODO */
  flags = GST_READ_UINT8 (data + 8);
  /* cseq = GST_READ_UINT8 (data + 9);  TODO */

  /* C */
  if (flags & (1 << 7))
    GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
  else
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);

  /* E */
  /* if (flags & (1 << 6));  TODO */

  /* D */
  if (flags & (1 << 5))
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
  else
    GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);

out:
  gst_rtp_buffer_unmap (&rtp);
  return TRUE;
}
static GstBuffer *
gst_rtp_g729_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
{
  GstRtpG729Depay *rtpg729depay;
  GstBuffer *outbuf = NULL;
  gint payload_len;
  gboolean marker;
  GstRTPBuffer rtp = { NULL };

  rtpg729depay = GST_RTP_G729_DEPAY (depayload);

  gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);

  payload_len = gst_rtp_buffer_get_payload_len (&rtp);

  /* At least 2 bytes (CNG from G729 Annex B) */
  if (payload_len < 2) {
    GST_ELEMENT_WARNING (rtpg729depay, STREAM, DECODE,
        (NULL), ("G729 RTP payload too small (%d)", payload_len));
    goto bad_packet;
  }

  GST_LOG_OBJECT (rtpg729depay, "payload len %d", payload_len);

  if ((payload_len % 10) == 2) {
    GST_LOG_OBJECT (rtpg729depay, "G729 payload contains CNG frame");
  }

  outbuf = gst_rtp_buffer_get_payload_buffer (&rtp);
  marker = gst_rtp_buffer_get_marker (&rtp);

  gst_rtp_buffer_unmap (&rtp);

  if (marker) {
    /* marker bit starts talkspurt */
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_RESYNC);
  }

  GST_LOG_OBJECT (depayload, "pushing buffer of size %" G_GSIZE_FORMAT,
      gst_buffer_get_size (outbuf));

  return outbuf;

  /* ERRORS */
bad_packet:
  {
    /* no fatal error */
    return NULL;
  }
}
예제 #21
0
static void
compare_rtp_packets (GstBuffer * a, GstBuffer * b)
{
  GstRTPBuffer rtp_a = GST_RTP_BUFFER_INIT;
  GstRTPBuffer rtp_b = GST_RTP_BUFFER_INIT;

  gst_rtp_buffer_map (a, GST_MAP_READ, &rtp_a);
  gst_rtp_buffer_map (b, GST_MAP_READ, &rtp_b);

  fail_unless_equals_int (gst_rtp_buffer_get_header_len (&rtp_a),
      gst_rtp_buffer_get_header_len (&rtp_b));
  fail_unless_equals_int (gst_rtp_buffer_get_version (&rtp_a),
      gst_rtp_buffer_get_version (&rtp_b));
  fail_unless_equals_int (gst_rtp_buffer_get_ssrc (&rtp_a),
      gst_rtp_buffer_get_ssrc (&rtp_b));
  fail_unless_equals_int (gst_rtp_buffer_get_seq (&rtp_a),
      gst_rtp_buffer_get_seq (&rtp_b));
  fail_unless_equals_int (gst_rtp_buffer_get_csrc_count (&rtp_a),
      gst_rtp_buffer_get_csrc_count (&rtp_b));
  fail_unless_equals_int (gst_rtp_buffer_get_marker (&rtp_a),
      gst_rtp_buffer_get_marker (&rtp_b));
  fail_unless_equals_int (gst_rtp_buffer_get_payload_type (&rtp_a),
      gst_rtp_buffer_get_payload_type (&rtp_b));
  fail_unless_equals_int (gst_rtp_buffer_get_timestamp (&rtp_a),
      gst_rtp_buffer_get_timestamp (&rtp_b));
  fail_unless_equals_int (gst_rtp_buffer_get_extension (&rtp_a),
      gst_rtp_buffer_get_extension (&rtp_b));

  fail_unless_equals_int (gst_rtp_buffer_get_payload_len (&rtp_a),
      gst_rtp_buffer_get_payload_len (&rtp_b));
  fail_unless_equals_int (memcmp (gst_rtp_buffer_get_payload (&rtp_a),
          gst_rtp_buffer_get_payload (&rtp_b),
          gst_rtp_buffer_get_payload_len (&rtp_a)), 0);

  gst_rtp_buffer_unmap (&rtp_a);
  gst_rtp_buffer_unmap (&rtp_b);
}
예제 #22
0
/* Return a stream structure for a given buffer
 */
static GstSrtpDecSsrcStream *
validate_buffer (GstSrtpDec * filter, GstBuffer * buf, guint32 * ssrc,
    gboolean * is_rtcp)
{
  GstSrtpDecSsrcStream *stream = NULL;
  GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;

  if (gst_rtp_buffer_map (buf,
          GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtpbuf)) {
    if (gst_rtp_buffer_get_payload_type (&rtpbuf) < 64
        || gst_rtp_buffer_get_payload_type (&rtpbuf) > 80) {
      *ssrc = gst_rtp_buffer_get_ssrc (&rtpbuf);

      gst_rtp_buffer_unmap (&rtpbuf);
      *is_rtcp = FALSE;
      goto have_ssrc;
    }
    gst_rtp_buffer_unmap (&rtpbuf);
  }

  if (rtcp_buffer_get_ssrc (buf, ssrc)) {
    *is_rtcp = TRUE;
  } else {
    GST_WARNING_OBJECT (filter, "No SSRC found in buffer");
    return NULL;
  }

have_ssrc:

  stream = find_stream_by_ssrc (filter, *ssrc);

  if (stream)
    return stream;

  return request_key_with_signal (filter, *ssrc, SIGNAL_REQUEST_KEY);
}
예제 #23
0
static void
lock_check_cb (GstPad * pad, int i)
{
  GstBuffer *inbuf;

  if (i % 2) {
    fail_unless (buffers == NULL);
  } else {
    GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;

    fail_unless (buffers && g_list_length (buffers) == 1);
    gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
    fail_unless_equals_int (66, gst_rtp_buffer_get_ssrc (&rtpbuffer));
    fail_unless_equals_int64 (200 - 57 + 1000 + i,
        gst_rtp_buffer_get_timestamp (&rtpbuffer));
    fail_unless_equals_int (100 + 1 + i, gst_rtp_buffer_get_seq (&rtpbuffer));
    gst_rtp_buffer_unmap (&rtpbuffer);

    inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
    GST_BUFFER_PTS (inbuf) = i * 1000 + 500;
    GST_BUFFER_DURATION (inbuf) = 1000;
    gst_rtp_buffer_map (inbuf, GST_MAP_WRITE, &rtpbuffer);
    gst_rtp_buffer_set_version (&rtpbuffer, 2);
    gst_rtp_buffer_set_payload_type (&rtpbuffer, 98);
    gst_rtp_buffer_set_ssrc (&rtpbuffer, 44);
    gst_rtp_buffer_set_timestamp (&rtpbuffer, 200 + i);
    gst_rtp_buffer_set_seq (&rtpbuffer, 2000 + i);
    gst_rtp_buffer_unmap (&rtpbuffer);
    fail_unless (gst_pad_push (pad, inbuf) == GST_FLOW_OK);


    g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
    g_list_free (buffers);
    buffers = NULL;
  }
}
static GstFlowReturn gst_scream_queue_sink_chain(GstPad *pad, GstObject *parent, GstBuffer *buffer)
{
    GstScreamQueue *self = GST_SCREAM_QUEUE(parent);
    GstRTPBuffer rtp_buffer = GST_RTP_BUFFER_INIT;
    GstFlowReturn flow_ret = GST_FLOW_OK;
    GstScreamDataQueueRtpItem *rtp_item;

    if (GST_PAD_IS_FLUSHING(pad)) {
        flow_ret = GST_FLOW_FLUSHING;
        goto end;
    }

    if (!gst_rtp_buffer_map(buffer, GST_MAP_READ, &rtp_buffer)) {
        flow_ret = GST_FLOW_ERROR;
        goto end;
    }

    rtp_item = g_slice_new(GstScreamDataQueueRtpItem);
    ((GstDataQueueItem *)rtp_item)->object = GST_MINI_OBJECT(buffer);
    ((GstDataQueueItem *)rtp_item)->size = gst_buffer_get_size(buffer);
    ((GstDataQueueItem *)rtp_item)->visible = TRUE;
    ((GstDataQueueItem *)rtp_item)->duration = GST_BUFFER_DURATION(buffer);
    ((GstDataQueueItem *)rtp_item)->destroy = (GDestroyNotify) gst_scream_data_queue_rtp_item_free;

    ((GstScreamDataQueueItem *)rtp_item)->type = GST_SCREAM_DATA_QUEUE_ITEM_TYPE_RTP;
    ((GstScreamDataQueueItem *)rtp_item)->rtp_ssrc = gst_rtp_buffer_get_ssrc(&rtp_buffer);
    rtp_item->rtp_pt = gst_rtp_buffer_get_payload_type(&rtp_buffer);
    rtp_item->gst_ts = GST_BUFFER_PTS(buffer);
    rtp_item->rtp_seq = gst_rtp_buffer_get_seq(&rtp_buffer);
    rtp_item->rtp_ts = gst_rtp_buffer_get_timestamp(&rtp_buffer);
    rtp_item->rtp_marker = gst_rtp_buffer_get_marker(&rtp_buffer);
    rtp_item->rtp_payload_size = gst_rtp_buffer_get_payload_len(&rtp_buffer);
    rtp_item->enqueued_time = get_gst_time_us(self);
    gst_rtp_buffer_unmap(&rtp_buffer);

    if (self->pass_through) {
        rtp_item->adapted = FALSE;
        GST_LOG_OBJECT(self, "passing through: pt = %u, seq: %u, pass: %u", rtp_item->rtp_pt, rtp_item->rtp_seq, self->pass_through);
        gst_data_queue_push(self->approved_packets, (GstDataQueueItem *)rtp_item);
        goto end;
    }

    GST_LOG_OBJECT(self, "queuing: pt = %u, seq: %u, pass: %u", rtp_item->rtp_pt, rtp_item->rtp_seq, self->pass_through);
    g_async_queue_push(self->incoming_packets, (gpointer)rtp_item);

end:
    return flow_ret;
}
static GstBuffer *
gst_rtp_opus_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
{
    GstBuffer *outbuf;
    GstRTPBuffer rtpbuf = { NULL, };

    gst_rtp_buffer_map (buf, GST_MAP_READ, &rtpbuf);
    outbuf = gst_rtp_buffer_get_payload_buffer (&rtpbuf);
    gst_rtp_buffer_unmap (&rtpbuf);

    outbuf = gst_buffer_make_writable (outbuf);
    /* Filter away all metas that are not sensible to copy */
    gst_buffer_foreach_meta (outbuf, foreach_metadata, depayload);

    return outbuf;
}
예제 #26
0
static GstFlowReturn
gst_rtp_ssrc_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn ret;
  GstRtpSsrcDemux *demux;
  guint32 ssrc;
  GstRTPBuffer rtp = { NULL };
  GstPad *srcpad;

  demux = GST_RTP_SSRC_DEMUX (parent);

  if (!gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp))
    goto invalid_payload;

  ssrc = gst_rtp_buffer_get_ssrc (&rtp);
  gst_rtp_buffer_unmap (&rtp);

  GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc);

  srcpad = find_or_create_demux_pad_for_ssrc (demux, ssrc, RTP_PAD);
  if (srcpad == NULL)
    goto create_failed;

  /* push to srcpad */
  ret = gst_pad_push (srcpad, buf);

  gst_object_unref (srcpad);

  return ret;

  /* ERRORS */
invalid_payload:
  {
    /* this is fatal and should be filtered earlier */
    GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
        ("Dropping invalid RTP payload"));
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
create_failed:
  {
    GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
        ("Could not create new pad"));
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
}
예제 #27
0
static GstBuffer *
create_rtp_buffer (guint32 ssrc, guint8 payload_type, guint16 seqnum)
{
  GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;
  guint payload_size = 29;
  guint64 timestamp = gst_util_uint64_scale_int (seqnum, 90000, 30);
  GstBuffer *buf = gst_rtp_buffer_new_allocate (payload_size, 0, 0);

  gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtpbuf);
  gst_rtp_buffer_set_ssrc (&rtpbuf, ssrc);
  gst_rtp_buffer_set_payload_type (&rtpbuf, payload_type);
  gst_rtp_buffer_set_seq (&rtpbuf, seqnum);
  gst_rtp_buffer_set_timestamp (&rtpbuf, (guint32) timestamp);
  memset (gst_rtp_buffer_get_payload (&rtpbuf), 0x29, payload_size);
  gst_rtp_buffer_unmap (&rtpbuf);
  return buf;
}
예제 #28
0
/* Create a RTP buffer without the extension */
static GstBuffer *
create_rtp_buffer (GstClockTime timestamp, gboolean clean_point)
{
  GstBuffer *buffer_in;
  GstRTPBuffer rtpbuffer_in = GST_RTP_BUFFER_INIT;

  buffer_in = gst_rtp_buffer_new_allocate (0, 0, 0);
  GST_BUFFER_PTS (buffer_in) = timestamp;

  if (!clean_point)
    GST_BUFFER_FLAG_SET (buffer_in, GST_BUFFER_FLAG_DELTA_UNIT);

  fail_unless (gst_rtp_buffer_map (buffer_in, GST_MAP_READ, &rtpbuffer_in));
  fail_if (gst_rtp_buffer_get_extension (&rtpbuffer_in));
  gst_rtp_buffer_unmap (&rtpbuffer_in);

  return buffer_in;
}
예제 #29
0
/* Create a copy of @buffer_in having the RTP extension */
static GstBuffer *
create_extension_buffer (GstBuffer * buffer_in, gboolean clean_point,
    gboolean end_contiguous, gboolean discont, guint64 ntp_offset, guint8 cseq)
{
  GstBuffer *buffer_out;
  GstRTPBuffer rtpbuffer_out = GST_RTP_BUFFER_INIT;
  guint8 *data;
  guint8 flags = 0;

  buffer_out = gst_buffer_copy (buffer_in);

  fail_unless (gst_rtp_buffer_map (buffer_out, GST_MAP_READWRITE,
          &rtpbuffer_out));

  /* extension */
  fail_unless (gst_rtp_buffer_set_extension_data (&rtpbuffer_out, 0xABAC, 3));
  fail_unless (gst_rtp_buffer_get_extension (&rtpbuffer_out));
  fail_unless (gst_rtp_buffer_get_extension_data (&rtpbuffer_out, NULL,
          (gpointer) & data, NULL));

  /* NTP timestamp */
  GST_WRITE_UINT64_BE (data, convert_to_ntp (GST_BUFFER_PTS (buffer_in) +
          ntp_offset));

  /* C E D mbz */
  if (clean_point)
    flags |= (1 << 7);
  if (end_contiguous)
    flags |= (1 << 6);
  if (discont)
    flags |= (1 << 5);

  GST_WRITE_UINT8 (data + 8, flags);

  /* CSeq */
  GST_WRITE_UINT8 (data + 9, cseq);

  memset (data + 10, 0, 4);

  gst_rtp_buffer_unmap (&rtpbuffer_out);

  return buffer_out;
}
예제 #30
0
static void
do_ntp_time (GstClockTime buffer_time, gint segment_start, gint segment_base)
{
  GstSegment segment;
  GstBuffer *buffer;
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
  guint8 *data;
  guint64 expected_ntp_time;
  guint64 timestamp;

  /* create a segment that controls the behavior
   * by changing segment.start and segment.base we affect the stream time and
   * running time respectively */
  gst_segment_init (&segment, GST_FORMAT_TIME);
  segment.start = segment_start;
  segment.base = segment_base;
  gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment));

  expected_ntp_time = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME,
      buffer_time);
    expected_ntp_time += NTP_OFFSET;
  expected_ntp_time = gst_util_uint64_scale (expected_ntp_time,
      (G_GINT64_CONSTANT (1) << 32), GST_SECOND);

  buffer = create_rtp_buffer (buffer_time, FALSE);
  fail_unless_equals_int (gst_pad_push (mysrcpad, buffer), GST_FLOW_OK);
  fail_unless_equals_int (g_list_length (buffers), 1);

  buffer = g_list_last (buffers)->data;

  /* get the extension header */
  fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READWRITE, &rtpbuffer));
  fail_unless (gst_rtp_buffer_get_extension_data (&rtpbuffer, NULL,
          (gpointer) & data, NULL));

  /* ...and read the NTP timestamp and verify that it's the expected one */
  timestamp = GST_READ_UINT64_BE (data);
  fail_unless_equals_uint64 (timestamp, expected_ntp_time);

  gst_rtp_buffer_unmap (&rtpbuffer);
  gst_check_drop_buffers ();
}