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; }
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; }
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; }
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; }
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); }
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; }
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; } }
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; } }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; } }
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); }
/* 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); }
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; }
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; } }
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; }
/* 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; }
/* 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; }
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 (); }