}
static void
-gst_rtp_h263_depay_init (GstRtpH263Depay * rtph263depay,
- GstRtpH263DepayClass * klass)
+gst_rtp_h263_depay_init (GstRtpH263Depay * rtph263depay)
{
rtph263depay->adapter = gst_adapter_new ();
guint SBIT, EBIT;
gboolean F, P, M;
gboolean I;
+ GstRTPBuffer rtp = { NULL };
rtph263depay = GST_RTP_H263_DEPAY (depayload);
rtph263depay->start = FALSE;
}
- payload_len = gst_rtp_buffer_get_payload_len (buf);
- payload = gst_rtp_buffer_get_payload (buf);
+ gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
- M = gst_rtp_buffer_get_marker (buf);
+ payload_len = gst_rtp_buffer_get_payload_len (&rtp);
+ payload = gst_rtp_buffer_get_payload (&rtp);
+
+ M = gst_rtp_buffer_get_marker (&rtp);
/* Let's see what mode we are using */
F = (payload[0] & 0x80) == 0x80;
GstBuffer *tmp;
/* Take the entire buffer */
- tmp = gst_rtp_buffer_get_payload_subbuffer (buf, header_len, payload_len);
+ tmp = gst_rtp_buffer_get_payload_subbuffer (&rtp, header_len, payload_len);
gst_adapter_push (rtph263depay->adapter, tmp);
} else {
GstBuffer *tmp;
/* Take the entire buffer except for the last byte */
- tmp = gst_rtp_buffer_get_payload_subbuffer (buf, header_len,
+ tmp = gst_rtp_buffer_get_payload_subbuffer (&rtp, header_len,
payload_len - 1);
gst_adapter_push (rtph263depay->adapter, tmp);
GstBuffer *buf = gst_buffer_new_and_alloc (1);
GST_DEBUG ("Pushing leftover in adapter");
- GST_BUFFER_DATA (buf)[0] = rtph263depay->leftover;
+ gst_buffer_fill (buf, 0, &rtph263depay->leftover, 1);
gst_adapter_push (rtph263depay->adapter, buf);
}
GST_DEBUG ("Pushing out a buffer of %d bytes", avail);
- timestamp = gst_rtp_buffer_get_timestamp (buf);
+ timestamp = gst_rtp_buffer_get_timestamp (&rtp);
gst_base_rtp_depayload_push_ts (depayload, timestamp, outbuf);
rtph263depay->offset = 0;
rtph263depay->leftover = 0;
rtph263depay->start = TRUE;
}
}
+ gst_rtp_buffer_unmap (&rtp);
return NULL;
}
guint ind);
static void gst_rtp_h263_pay_package_destroy (GstRtpH263PayPackage * pack);
-GST_BOILERPLATE (GstRtpH263Pay, gst_rtp_h263_pay, GstBaseRTPPayload,
- GST_TYPE_BASE_RTP_PAYLOAD)
-
- static void gst_rtp_h263_pay_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_h263_pay_src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_h263_pay_sink_template));
-
- gst_element_class_set_details_simple (element_class,
- "RTP H263 packet payloader", "Codec/Payloader/Network/RTP",
- "Payload-encodes H263 video in RTP packets (RFC 2190)",
- "Neil Stratford <neils@vipadia.com>"
- "Dejan Sakelsak <dejan.sakelsak@marand.si>");
-}
+#define gst_rtp_h263_pay_parent_class parent_class
+G_DEFINE_TYPE (GstRtpH263Pay, gst_rtp_h263_pay, GST_TYPE_BASE_RTP_PAYLOAD);
static void
gst_rtp_h263_pay_class_init (GstRtpH263PayClass * klass)
{
GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
gobject_class->finalize = gst_rtp_h263_pay_finalize;
"Disable packetization modes B and C", DEFAULT_MODE_A,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rtp_h263_pay_src_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rtp_h263_pay_sink_template));
+
+ gst_element_class_set_details_simple (gstelement_class,
+ "RTP H263 packet payloader", "Codec/Payloader/Network/RTP",
+ "Payload-encodes H263 video in RTP packets (RFC 2190)",
+ "Neil Stratford <neils@vipadia.com>"
+ "Dejan Sakelsak <dejan.sakelsak@marand.si>");
+
GST_DEBUG_CATEGORY_INIT (rtph263pay_debug, "rtph263pay", 0,
"H263 RTP Payloader");
}
static void
-gst_rtp_h263_pay_init (GstRtpH263Pay * rtph263pay, GstRtpH263PayClass * klass)
+gst_rtp_h263_pay_init (GstRtpH263Pay * rtph263pay)
{
rtph263pay->adapter = gst_adapter_new ();
guint8 *header;
guint8 *payload;
GstFlowReturn ret;
+ GstRTPBuffer rtp = { NULL };
- header = gst_rtp_buffer_get_payload (package->outbuf);
+ gst_rtp_buffer_map (package->outbuf, GST_MAP_WRITE, &rtp);
+
+ header = gst_rtp_buffer_get_payload (&rtp);
payload = header + package->mode;
switch (package->mode) {
*/
GST_BUFFER_TIMESTAMP (package->outbuf) = rtph263pay->first_ts;
- gst_rtp_buffer_set_marker (package->outbuf, package->marker);
+ gst_rtp_buffer_set_marker (&rtp, package->marker);
if (package->marker)
GST_DEBUG ("Marker set!");
+ gst_rtp_buffer_unmap (&rtp);
+
ret =
gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263pay),
package->outbuf);
/* Get a pointer to all the data for the frame */
rtph263pay->data =
- (guint8 *) gst_adapter_peek (rtph263pay->adapter,
+ (guint8 *) gst_adapter_map (rtph263pay->adapter,
rtph263pay->available_data);
/* Picture header */
end:
gst_rtp_h263_pay_context_destroy (context,
context->piclayer->ptype_srcformat);
- gst_adapter_flush (rtph263pay->adapter, rtph263pay->available_data);
+ gst_adapter_unmap (rtph263pay->adapter, rtph263pay->available_data);
return ret;
}
{
GstRtpH263PDepay *rtph263pdepay;
GstBuffer *outbuf;
+ gint payload_len;
+ guint8 *payload;
+ gboolean P, V, M;
+ guint header_len;
+ guint8 PLEN, PEBIT;
+ GstRTPBuffer rtp = { NULL };
rtph263pdepay = GST_RTP_H263P_DEPAY (depayload);
rtph263pdepay->wait_start = TRUE;
}
- {
- gint payload_len;
- guint8 *payload;
- gboolean P, V, M;
- guint header_len;
- guint8 PLEN, PEBIT;
-
- payload_len = gst_rtp_buffer_get_payload_len (buf);
- payload = gst_rtp_buffer_get_payload (buf);
-
- header_len = 2;
-
- if (payload_len < header_len)
- goto too_small;
-
- M = gst_rtp_buffer_get_marker (buf);
-
- /* 0 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RR |P|V| PLEN |PEBIT|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- P = (payload[0] & 0x04) == 0x04;
- V = (payload[0] & 0x02) == 0x02;
- PLEN = ((payload[0] & 0x1) << 5) | (payload[1] >> 3);
- PEBIT = payload[1] & 0x7;
-
- GST_LOG_OBJECT (depayload, "P %d, V %d, PLEN %d, PEBIT %d", P, V, PLEN,
- PEBIT);
-
- if (V) {
- header_len++;
- }
- if (PLEN) {
- header_len += PLEN;
- }
+ gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
- if ((!P && payload_len < header_len) || (P && payload_len < header_len - 2))
- goto too_small;
+ payload_len = gst_rtp_buffer_get_payload_len (&rtp);
+ header_len = 2;
- if (P) {
- /* FIXME, have to make the packet writable hear. Better to reset these
- * bytes when we copy the packet below */
- rtph263pdepay->wait_start = FALSE;
- header_len -= 2;
- payload[header_len] = 0;
- payload[header_len + 1] = 0;
- }
+ if (payload_len < header_len)
+ goto too_small;
- if (rtph263pdepay->wait_start)
- goto waiting_start;
+ payload = gst_rtp_buffer_get_payload (&rtp);
- if (payload_len < header_len)
- goto too_small;
+ M = gst_rtp_buffer_get_marker (&rtp);
- /* FIXME do not ignore the VRC header (See RFC 2429 section 4.2) */
- /* FIXME actually use the RTP picture header when it is lost in the network */
- /* for now strip off header */
- payload += header_len;
- payload_len -= header_len;
+ /* 0 1
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | RR |P|V| PLEN |PEBIT|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ P = (payload[0] & 0x04) == 0x04;
+ V = (payload[0] & 0x02) == 0x02;
+ PLEN = ((payload[0] & 0x1) << 5) | (payload[1] >> 3);
+ PEBIT = payload[1] & 0x7;
- if (M) {
- /* frame is completed: append to previous, push it out */
- guint len, padlen;
- guint avail;
+ GST_LOG_OBJECT (depayload, "P %d, V %d, PLEN %d, PEBIT %d", P, V, PLEN,
+ PEBIT);
- GST_LOG_OBJECT (depayload, "Frame complete");
+ if (V) {
+ header_len++;
+ }
+ if (PLEN) {
+ header_len += PLEN;
+ }
- avail = gst_adapter_available (rtph263pdepay->adapter);
+ if ((!P && payload_len < header_len) || (P && payload_len < header_len - 2))
+ goto too_small;
- len = avail + payload_len;
- padlen = (len % 4) + 4;
- outbuf = gst_buffer_new_and_alloc (len + padlen);
- memset (GST_BUFFER_DATA (outbuf) + len, 0, padlen);
- GST_BUFFER_SIZE (outbuf) = len;
+ if (P) {
+ /* FIXME, have to make the packet writable hear. Better to reset these
+ * bytes when we copy the packet below */
+ rtph263pdepay->wait_start = FALSE;
+ header_len -= 2;
+ payload[header_len] = 0;
+ payload[header_len + 1] = 0;
+ }
- /* prepend previous data */
- if (avail > 0) {
- gst_adapter_copy (rtph263pdepay->adapter, GST_BUFFER_DATA (outbuf), 0,
- avail);
- gst_adapter_flush (rtph263pdepay->adapter, avail);
- }
- memcpy (GST_BUFFER_DATA (outbuf) + avail, payload, payload_len);
+ if (rtph263pdepay->wait_start)
+ goto waiting_start;
- return outbuf;
+ if (payload_len < header_len)
+ goto too_small;
- } else {
- /* frame not completed: store in adapter */
- outbuf = gst_buffer_new_and_alloc (payload_len);
+ /* FIXME do not ignore the VRC header (See RFC 2429 section 4.2) */
+ /* FIXME actually use the RTP picture header when it is lost in the network */
+ /* for now strip off header */
+ payload += header_len;
+ payload_len -= header_len;
- GST_LOG_OBJECT (depayload, "Frame incomplete, storing %d", payload_len);
+ if (M) {
+ /* frame is completed: append to previous, push it out */
+ guint len, padlen;
+ guint avail;
+ guint8 *data;
- memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
+ GST_LOG_OBJECT (depayload, "Frame complete");
- gst_adapter_push (rtph263pdepay->adapter, outbuf);
+ avail = gst_adapter_available (rtph263pdepay->adapter);
+ len = avail + payload_len;
+ padlen = (len % 4) + 4;
+
+ outbuf = gst_buffer_new_and_alloc (len + padlen);
+
+ data = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
+ memset (data + len, 0, padlen);
+
+ /* prepend previous data */
+ if (avail > 0) {
+ gst_adapter_copy (rtph263pdepay->adapter, data, 0, avail);
+ gst_adapter_flush (rtph263pdepay->adapter, avail);
}
+ memcpy (data + avail, payload, payload_len);
+ gst_buffer_unmap (outbuf, data, len);
+ gst_rtp_buffer_unmap (&rtp);
+
+ return outbuf;
+
+ } else {
+ /* frame not completed: store in adapter */
+ outbuf = gst_buffer_new_and_alloc (payload_len);
+
+ GST_LOG_OBJECT (depayload, "Frame incomplete, storing %d", payload_len);
+ gst_buffer_fill (outbuf, 0, payload, payload_len);
+
+ gst_adapter_push (rtph263pdepay->adapter, outbuf);
+ gst_rtp_buffer_unmap (&rtp);
}
return NULL;
{
GST_ELEMENT_WARNING (rtph263pdepay, STREAM, DECODE,
("Packet payload was too small"), (NULL));
+ gst_rtp_buffer_unmap (&rtp);
return NULL;
}
waiting_start:
{
GST_DEBUG_OBJECT (rtph263pdepay, "waiting for picture start");
+ gst_rtp_buffer_unmap (&rtp);
return NULL;
}
}
static GstFlowReturn gst_rtp_h263p_pay_handle_buffer (GstBaseRTPPayload *
payload, GstBuffer * buffer);
-GST_BOILERPLATE (GstRtpH263PPay, gst_rtp_h263p_pay, GstBaseRTPPayload,
- GST_TYPE_BASE_RTP_PAYLOAD);
-
-static void
-gst_rtp_h263p_pay_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_h263p_pay_src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_h263p_pay_sink_template));
-
- gst_element_class_set_details_simple (element_class, "RTP H263 payloader",
- "Codec/Payloader/Network/RTP",
- "Payload-encodes H263/+/++ video in RTP packets (RFC 4629)",
- "Wim Taymans <wim.taymans@gmail.com>");
-}
+#define gst_rtp_h263p_pay_parent_class parent_class
+G_DEFINE_TYPE (GstRtpH263PPay, gst_rtp_h263p_pay, GST_TYPE_BASE_RTP_PAYLOAD);
static void
gst_rtp_h263p_pay_class_init (GstRtpH263PPayClass * klass)
{
GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
gobject_class->finalize = gst_rtp_h263p_pay_finalize;
DEFAULT_FRAGMENTATION_MODE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rtp_h263p_pay_src_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rtp_h263p_pay_sink_template));
+
+ gst_element_class_set_details_simple (gstelement_class, "RTP H263 payloader",
+ "Codec/Payloader/Network/RTP",
+ "Payload-encodes H263/+/++ video in RTP packets (RFC 4629)",
+ "Wim Taymans <wim.taymans@gmail.com>");
+
GST_DEBUG_CATEGORY_INIT (rtph263ppay_debug, "rtph263ppay",
0, "rtph263ppay (RFC 4629)");
}
static void
-gst_rtp_h263p_pay_init (GstRtpH263PPay * rtph263ppay,
- GstRtpH263PPayClass * klass)
+gst_rtp_h263p_pay_init (GstRtpH263PPay * rtph263ppay)
{
rtph263ppay->adapter = gst_adapter_new ();
gint header_len;
guint next_gop = 0;
gboolean found_gob = FALSE;
+ GstRTPBuffer rtp = { NULL };
if (rtph263ppay->fragmentation_mode == GST_FRAGMENTATION_MODE_SYNC) {
/* start after 1st gop possible */
guint parsed_len = 3;
const guint8 *parse_data = NULL;
- parse_data = gst_adapter_peek (rtph263ppay->adapter, avail);
+ parse_data = gst_adapter_map (rtph263ppay->adapter, avail);
/* Check if we have a gob or eos , eossbs */
/* FIXME EOS and EOSSBS packets should never contain any gobs and vice-versa */
}
parsed_len++;
}
+ gst_adapter_unmap (rtph263ppay->adapter, 0);
}
/* for picture start frames (non-fragmented), we need to remove the first
payload_len = header_len + towrite;
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
+
+ gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
/* last fragment gets the marker bit set */
- gst_rtp_buffer_set_marker (outbuf, avail > towrite ? 0 : 1);
+ gst_rtp_buffer_set_marker (&rtp, avail > towrite ? 0 : 1);
- payload = gst_rtp_buffer_get_payload (outbuf);
+ payload = gst_rtp_buffer_get_payload (&rtp);
gst_adapter_copy (rtph263ppay->adapter, &payload[header_len], 0, towrite);
GST_BUFFER_TIMESTAMP (outbuf) = rtph263ppay->first_timestamp;
GST_BUFFER_DURATION (outbuf) = rtph263ppay->first_duration;
+ gst_rtp_buffer_unmap (&rtp);
gst_adapter_flush (rtph263ppay->adapter, towrite);
/* "max-rcmd-nalu-size = (string) ANY " */
);
-GST_BOILERPLATE (GstRtpH264Depay, gst_rtp_h264_depay, GstBaseRTPDepayload,
+#define gst_rtp_h264_depay_parent_class parent_class
+G_DEFINE_TYPE (GstRtpH264Depay, gst_rtp_h264_depay,
GST_TYPE_BASE_RTP_DEPAYLOAD);
static void gst_rtp_h264_depay_finalize (GObject * object);
GstCaps * caps);
static void
-gst_rtp_h264_depay_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_h264_depay_src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_h264_depay_sink_template));
-
- gst_element_class_set_details_simple (element_class, "RTP H264 depayloader",
- "Codec/Depayloader/Network/RTP",
- "Extracts H264 video from RTP packets (RFC 3984)",
- "Wim Taymans <wim.taymans@gmail.com>");
-}
-
-static void
gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass)
{
GObjectClass *gobject_class;
"Merge NALU into AU (picture) (deprecated; use caps)",
DEFAULT_ACCESS_UNIT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rtp_h264_depay_src_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rtp_h264_depay_sink_template));
+
+ gst_element_class_set_details_simple (gstelement_class,
+ "RTP H264 depayloader", "Codec/Depayloader/Network/RTP",
+ "Extracts H264 video from RTP packets (RFC 3984)",
+ "Wim Taymans <wim.taymans@gmail.com>");
gstelement_class->change_state = gst_rtp_h264_depay_change_state;
gstbasertpdepayload_class->process = gst_rtp_h264_depay_process;
}
static void
-gst_rtp_h264_depay_init (GstRtpH264Depay * rtph264depay,
- GstRtpH264DepayClass * klass)
+gst_rtp_h264_depay_init (GstRtpH264Depay * rtph264depay)
{
rtph264depay->adapter = gst_adapter_new ();
rtph264depay->picture_adapter = gst_adapter_new ();
GstRtpH264Depay *rtph264depay;
const gchar *ps, *profile;
GstBuffer *codec_data;
- guint8 *b64;
+ guint8 *ptr, *data;
gboolean res;
rtph264depay = GST_RTP_H264_DEPAY (depayload);
}
/* we seriously overshoot the length, but it's fine. */
codec_data = gst_buffer_new_and_alloc (len);
- b64 = GST_BUFFER_DATA (codec_data);
+
+ data = gst_buffer_map (codec_data, NULL, NULL, GST_MAP_WRITE);
+ ptr = data;
total = 0;
for (i = 0; params[i]; i++) {
guint save = 0;
gint state = 0;
GST_DEBUG_OBJECT (depayload, "decoding param %d (%s)", i, params[i]);
- memcpy (b64, sync_bytes, sizeof (sync_bytes));
- b64 += sizeof (sync_bytes);
+ memcpy (ptr, sync_bytes, sizeof (sync_bytes));
+ ptr += sizeof (sync_bytes);
len =
- g_base64_decode_step (params[i], strlen (params[i]), b64, &state,
+ g_base64_decode_step (params[i], strlen (params[i]), ptr, &state,
&save);
GST_DEBUG_OBJECT (depayload, "decoded %d bytes", len);
total += len + sizeof (sync_bytes);
- b64 += len;
+ ptr += len;
}
- GST_BUFFER_SIZE (codec_data) = total;
+ gst_buffer_unmap (codec_data, data, total);
g_strfreev (params);
/* keep the codec_data, we need to send it as the first buffer. We cannot
guint8 **sps, **pps;
guint len, num_sps, num_pps;
gint i;
- guint8 *data;
if (ps == NULL)
goto incomplete_caps;
}
codec_data = gst_buffer_new_and_alloc (len);
- data = GST_BUFFER_DATA (codec_data);
+
+ data = ptr = gst_buffer_map (codec_data, NULL, NULL, GST_MAP_WRITE);
/* 8 bits version == 1 */
- *data++ = 1;
+ *ptr++ = 1;
if (profile) {
guint32 profile_id;
/* hex: AVCProfileIndication:8 | profile_compat:8 | AVCLevelIndication:8 */
sscanf (profile, "%6x", &profile_id);
- *data++ = (profile_id >> 16) & 0xff;
- *data++ = (profile_id >> 8) & 0xff;
- *data++ = profile_id & 0xff;
+ *ptr++ = (profile_id >> 16) & 0xff;
+ *ptr++ = (profile_id >> 8) & 0xff;
+ *ptr++ = profile_id & 0xff;
} else {
/* extract from SPS */
- *data++ = sps[0][3];
- *data++ = sps[0][4];
- *data++ = sps[0][5];
+ *ptr++ = sps[0][3];
+ *ptr++ = sps[0][4];
+ *ptr++ = sps[0][5];
}
/* 6 bits reserved | 2 bits lengthSizeMinusOn */
- *data++ = 0xff;
+ *ptr++ = 0xff;
/* 3 bits reserved | 5 bits numOfSequenceParameterSets */
- *data++ = 0xe0 | (num_sps & 0x1f);
+ *ptr++ = 0xe0 | (num_sps & 0x1f);
/* copy all SPS */
for (i = 0; sps[i]; i++) {
len = ((sps[i][0] << 8) | sps[i][1]) + 2;
GST_DEBUG_OBJECT (depayload, "copy SPS %d of length %d", i, len);
- memcpy (data, sps[i], len);
+ memcpy (ptr, sps[i], len);
g_free (sps[i]);
- data += len;
+ ptr += len;
}
g_free (sps);
/* 8 bits numOfPictureParameterSets */
- *data++ = num_pps;
+ *ptr++ = num_pps;
/* copy all PPS */
for (i = 0; pps[i]; i++) {
len = ((pps[i][0] << 8) | pps[i][1]) + 2;
GST_DEBUG_OBJECT (depayload, "copy PPS %d of length %d", i, len);
- memcpy (data, pps[i], len);
+ memcpy (ptr, pps[i], len);
g_free (pps[i]);
- data += len;
+ ptr += len;
}
g_free (pps);
- GST_BUFFER_SIZE (codec_data) = data - GST_BUFFER_DATA (codec_data);
+ gst_buffer_unmap (codec_data, data, ptr - data);
gst_caps_set_simple (srccaps,
"codec_data", GST_TYPE_BUFFER, codec_data, NULL);
{
GstBaseRTPDepayload *depayload = GST_BASE_RTP_DEPAYLOAD (rtph264depay);
gint nal_type;
- guint size;
+ gsize size;
guint8 *data;
GstBuffer *outbuf = NULL;
GstClockTime out_timestamp;
gboolean keyframe, out_keyframe;
- size = GST_BUFFER_SIZE (nal);
+ data = gst_buffer_map (nal, &size, NULL, GST_MAP_READ);
if (G_UNLIKELY (size < 5))
goto short_nal;
- data = GST_BUFFER_DATA (nal);
-
nal_type = data[4] & 0x1f;
GST_DEBUG_OBJECT (rtph264depay, "handle NAL type %d", nal_type);
GST_DEBUG_OBJECT (depayload, "using NAL as output");
outbuf = nal;
}
+ gst_buffer_unmap (nal, data, size);
if (outbuf) {
/* prepend codec_data */
rtph264depay->codec_data = NULL;
out_keyframe = TRUE;
}
- outbuf = gst_buffer_make_metadata_writable (outbuf);
+ outbuf = gst_buffer_make_writable (outbuf);
GST_BUFFER_TIMESTAMP (outbuf) = out_timestamp;
else
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
-
gst_base_rtp_depayload_push (depayload, outbuf);
}
short_nal:
{
GST_WARNING_OBJECT (depayload, "dropping short NAL");
+ gst_buffer_unmap (nal, data, size);
gst_buffer_unref (nal);
return FALSE;
}
GstRtpH264Depay *rtph264depay;
GstBuffer *outbuf;
guint8 nal_unit_type;
+ GstRTPBuffer rtp = { NULL };
rtph264depay = GST_RTP_H264_DEPAY (depayload);
timestamp = GST_BUFFER_TIMESTAMP (buf);
- payload_len = gst_rtp_buffer_get_payload_len (buf);
- payload = gst_rtp_buffer_get_payload (buf);
+ gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
+
+ payload_len = gst_rtp_buffer_get_payload_len (&rtp);
+ payload = gst_rtp_buffer_get_payload (&rtp);
GST_DEBUG_OBJECT (rtph264depay, "receiving %d bytes", payload_len);
outsize = nalu_size + sizeof (sync_bytes);
outbuf = gst_buffer_new_and_alloc (outsize);
- outdata = GST_BUFFER_DATA (outbuf);
+
+ outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
if (rtph264depay->byte_stream) {
memcpy (outdata, sync_bytes, sizeof (sync_bytes));
} else {
payload += 2;
payload_len -= 2;
- outdata += sizeof (sync_bytes);
- memcpy (outdata, payload, nalu_size);
+ memcpy (outdata + sizeof (sync_bytes), payload, nalu_size);
+ gst_buffer_unmap (outbuf, outdata, outsize);
gst_adapter_push (rtph264depay->adapter, outbuf);
nalu_size = payload_len;
outsize = nalu_size + sizeof (sync_bytes);
outbuf = gst_buffer_new_and_alloc (outsize);
- outdata = GST_BUFFER_DATA (outbuf);
- outdata += sizeof (sync_bytes);
- memcpy (outdata, payload, nalu_size);
- outdata[0] = nal_header;
+
+ outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
+ memcpy (outdata + sizeof (sync_bytes), payload, nalu_size);
+ outdata[sizeof (sync_bytes)] = nal_header;
+ gst_buffer_unmap (outbuf, outdata, outsize);
GST_DEBUG_OBJECT (rtph264depay, "queueing %d bytes", outsize);
outsize = payload_len;
outbuf = gst_buffer_new_and_alloc (outsize);
- outdata = GST_BUFFER_DATA (outbuf);
+
+ outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
memcpy (outdata, payload, outsize);
+ gst_buffer_unmap (outbuf, outdata, outsize);
GST_DEBUG_OBJECT (rtph264depay, "queueing %d bytes", outsize);
outsize = gst_adapter_available (rtph264depay->adapter);
outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
- outdata = GST_BUFFER_DATA (outbuf);
+ outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
if (rtph264depay->byte_stream) {
memcpy (outdata, sync_bytes, sizeof (sync_bytes));
} else {
outdata[1] = (outsize >> 16);
outdata[2] = (outsize >> 8);
outdata[3] = (outsize);
+ outsize += 4;
}
+ gst_buffer_unmap (outbuf, outdata, outsize);
+
gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp);
}
break;
nalu_size = payload_len;
outsize = nalu_size + sizeof (sync_bytes);
outbuf = gst_buffer_new_and_alloc (outsize);
- outdata = GST_BUFFER_DATA (outbuf);
+
+ outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
if (rtph264depay->byte_stream) {
memcpy (outdata, sync_bytes, sizeof (sync_bytes));
} else {
outdata[2] = nalu_size >> 8;
outdata[3] = nalu_size & 0xff;
}
- outdata += sizeof (sync_bytes);
- memcpy (outdata, payload, nalu_size);
+ memcpy (outdata + sizeof (sync_bytes), payload, nalu_size);
+ gst_buffer_unmap (outbuf, outdata, outsize);
gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp);
break;
}
}
+ gst_rtp_buffer_unmap (&rtp);
}
return NULL;
{
GST_ELEMENT_WARNING (rtph264depay, STREAM, DECODE,
(NULL), ("Undefined packet type"));
+ gst_rtp_buffer_unmap (&rtp);
return NULL;
}
waiting_start:
{
GST_DEBUG_OBJECT (rtph264depay, "waiting for start");
+ gst_rtp_buffer_unmap (&rtp);
return NULL;
}
not_implemented:
{
GST_ELEMENT_ERROR (rtph264depay, STREAM, FORMAT,
(NULL), ("NAL unit type %d not supported yet", nal_unit_type));
+ gst_rtp_buffer_unmap (&rtp);
return NULL;
}
}
GstCaps * caps);
static GstFlowReturn gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * pad,
GstBuffer * buffer);
-static gboolean gst_rtp_h264_pay_handle_event (GstPad * pad, GstEvent * event);
+static gboolean gst_rtp_h264_pay_handle_event (GstBaseRTPPayload * payload,
+ GstEvent * event);
static GstStateChangeReturn gst_basertppayload_change_state (GstElement *
element, GstStateChange transition);
-GST_BOILERPLATE (GstRtpH264Pay, gst_rtp_h264_pay, GstBaseRTPPayload,
- GST_TYPE_BASE_RTP_PAYLOAD);
-
-static void
-gst_rtp_h264_pay_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_h264_pay_src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_h264_pay_sink_template));
-
- gst_element_class_set_details_simple (element_class, "RTP H264 payloader",
- "Codec/Payloader/Network/RTP",
- "Payload-encode H264 video into RTP packets (RFC 3984)",
- "Laurent Glayal <spglegle@yahoo.fr>");
-}
+#define gst_rtp_h264_pay_parent_class parent_class
+G_DEFINE_TYPE (GstRtpH264Pay, gst_rtp_h264_pay, GST_TYPE_BASE_RTP_PAYLOAD);
static void
gst_rtp_h264_pay_class_init (GstRtpH264PayClass * klass)
gobject_class->finalize = gst_rtp_h264_pay_finalize;
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rtp_h264_pay_src_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_rtp_h264_pay_sink_template));
+
+ gst_element_class_set_details_simple (gstelement_class, "RTP H264 payloader",
+ "Codec/Payloader/Network/RTP",
+ "Payload-encode H264 video into RTP packets (RFC 3984)",
+ "Laurent Glayal <spglegle@yahoo.fr>");
+
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_basertppayload_change_state);
}
static void
-gst_rtp_h264_pay_init (GstRtpH264Pay * rtph264pay, GstRtpH264PayClass * klass)
+gst_rtp_h264_pay_init (GstRtpH264Pay * rtph264pay)
{
rtph264pay->queue = g_array_new (FALSE, FALSE, sizeof (guint));
rtph264pay->profile = 0;
GString *sprops;
guint count;
gboolean res;
+ guint8 *data;
+ gsize size;
sprops = g_string_new ("");
count = 0;
for (walk = payloader->sps; walk; walk = g_list_next (walk)) {
GstBuffer *sps_buf = GST_BUFFER_CAST (walk->data);
- set =
- g_base64_encode (GST_BUFFER_DATA (sps_buf), GST_BUFFER_SIZE (sps_buf));
+ data = gst_buffer_map (sps_buf, &size, NULL, GST_MAP_READ);
+ set = g_base64_encode (data, size);
+ gst_buffer_unmap (sps_buf, data, size);
+
g_string_append_printf (sprops, "%s%s", count ? "," : "", set);
g_free (set);
count++;
for (walk = payloader->pps; walk; walk = g_list_next (walk)) {
GstBuffer *pps_buf = GST_BUFFER_CAST (walk->data);
- set =
- g_base64_encode (GST_BUFFER_DATA (pps_buf), GST_BUFFER_SIZE (pps_buf));
+ data = gst_buffer_map (pps_buf, &size, NULL, GST_MAP_READ);
+ set = g_base64_encode (data, size);
+ gst_buffer_unmap (pps_buf, data, size);
+
g_string_append_printf (sprops, "%s%s", count ? "," : "", set);
g_free (set);
count++;
GstRtpH264Pay *rtph264pay;
GstStructure *str;
const GValue *value;
- guint8 *data;
- guint size;
+ guint8 *data, *bdata;
+ gsize size, bsize;
+ GstBuffer *buffer;
rtph264pay = GST_RTP_H264_PAY (basepayload);
/* packetized AVC video has a codec_data */
if ((value = gst_structure_get_value (str, "codec_data"))) {
- GstBuffer *buffer;
guint num_sps, num_pps;
gint i, nal_size;
rtph264pay->packetized = TRUE;
buffer = gst_value_get_buffer (value);
- data = GST_BUFFER_DATA (buffer);
- size = GST_BUFFER_SIZE (buffer);
+
+ bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READ);
+ data = bdata;
+ size = bsize;
/* parse the avcC data */
if (size < 7)
/* make a buffer out of it and add to SPS list */
sps_buf = gst_buffer_new_and_alloc (nal_size);
- memcpy (GST_BUFFER_DATA (sps_buf), data, nal_size);
+ gst_buffer_fill (sps_buf, 0, data, nal_size);
rtph264pay->sps = g_list_append (rtph264pay->sps, sps_buf);
data += nal_size;
/* make a buffer out of it and add to PPS list */
pps_buf = gst_buffer_new_and_alloc (nal_size);
- memcpy (GST_BUFFER_DATA (pps_buf), data, nal_size);
+ gst_buffer_fill (pps_buf, 0, data, nal_size);
rtph264pay->pps = g_list_append (rtph264pay->pps, pps_buf);
data += nal_size;
}
/* and update the caps with the collected data */
if (!gst_rtp_h264_pay_set_sps_pps (basepayload))
- return FALSE;
+ goto set_sps_pps_failed;
} else {
GST_DEBUG_OBJECT (rtph264pay, "have bytestream h264");
rtph264pay->packetized = FALSE;
avcc_too_small:
{
GST_ERROR_OBJECT (rtph264pay, "avcC size %u < 7", size);
- return FALSE;
+ goto error;
}
wrong_version:
{
GST_ERROR_OBJECT (rtph264pay, "wrong avcC version");
- return FALSE;
+ goto error;
}
avcc_error:
{
GST_ERROR_OBJECT (rtph264pay, "avcC too small ");
+ goto error;
+ }
+set_sps_pps_failed:
+ {
+ GST_ERROR_OBJECT (rtph264pay, "failed to set sps/pps");
+ goto error;
+ }
+error:
+ {
+ gst_buffer_unmap (buffer, bdata, bsize);
return FALSE;
}
}
guint8 *nalp;
guint save = 0;
gint state = 0;
+ guint8 nal_type;
nal_len = strlen (params[i]);
buf = gst_buffer_new_and_alloc (nal_len);
- nalp = GST_BUFFER_DATA (buf);
+ nalp = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
nal_len = g_base64_decode_step (params[i], nal_len, nalp, &state, &save);
- GST_BUFFER_SIZE (buf) = nal_len;
+ nal_type = nalp[0];
+ gst_buffer_unmap (buf, nalp, nal_len);
if (!nal_len) {
gst_buffer_unref (buf);
}
/* append to the right list */
- if ((nalp[0] & 0x1f) == 7) {
+ if ((nal_type & 0x1f) == 7) {
GST_DEBUG_OBJECT (rtph264pay, "adding param %d as SPS %d", i, num_sps);
rtph264pay->sps = g_list_append (rtph264pay->sps, buf);
num_sps++;
if (payloader->sps != NULL) {
sps_buf = GST_BUFFER_CAST (payloader->sps->data);
- if ((GST_BUFFER_SIZE (sps_buf) != sps_len)
- || memcmp (GST_BUFFER_DATA (sps_buf), sps, sps_len)) {
+ if (gst_buffer_memcmp (sps_buf, 0, sps, sps_len)) {
/* something changed, update */
payloader->profile = (sps[1] << 16) + (sps[2] << 8) + sps[3];
GST_DEBUG ("Profile level IDC = %06x", payloader->profile);
if (updated) {
sps_buf = gst_buffer_new_and_alloc (sps_len);
- memcpy (GST_BUFFER_DATA (sps_buf), sps, sps_len);
+ gst_buffer_fill (sps_buf, 0, sps, sps_len);
if (payloader->sps) {
/* replace old buffer */
if (payloader->pps != NULL) {
pps_buf = GST_BUFFER_CAST (payloader->pps->data);
- if ((GST_BUFFER_SIZE (pps_buf) != pps_len)
- || memcmp (GST_BUFFER_DATA (pps_buf), pps, pps_len)) {
+ if (gst_buffer_memcmp (pps_buf, 0, pps, pps_len)) {
/* something changed, update */
updated = TRUE;
}
if (updated) {
pps_buf = gst_buffer_new_and_alloc (pps_len);
- memcpy (GST_BUFFER_DATA (pps_buf), pps, pps_len);
+ gst_buffer_fill (pps_buf, 0, pps, pps_len);
if (payloader->pps) {
/* replace old buffer */
{
GstFlowReturn ret = GST_FLOW_OK;
GList *walk;
+ guint8 *data;
+ gsize size;
for (walk = rtph264pay->sps; walk; walk = g_list_next (walk)) {
GstBuffer *sps_buf = GST_BUFFER_CAST (walk->data);
GST_DEBUG_OBJECT (rtph264pay, "inserting SPS in the stream");
/* resend SPS */
+ data = gst_buffer_map (sps_buf, &size, NULL, GST_MAP_READ);
ret = gst_rtp_h264_pay_payload_nal (basepayload,
- GST_BUFFER_DATA (sps_buf), GST_BUFFER_SIZE (sps_buf), timestamp,
- sps_buf);
+ data, size, timestamp, sps_buf);
+ gst_buffer_unmap (sps_buf, data, size);
/* Not critical here; but throw a warning */
if (ret != GST_FLOW_OK)
GST_WARNING ("Problem pushing SPS");
GST_DEBUG_OBJECT (rtph264pay, "inserting PPS in the stream");
/* resend PPS */
+ data = gst_buffer_map (pps_buf, &size, NULL, GST_MAP_READ);
ret = gst_rtp_h264_pay_payload_nal (basepayload,
- GST_BUFFER_DATA (pps_buf), GST_BUFFER_SIZE (pps_buf), timestamp,
- pps_buf);
+ data, size, timestamp, pps_buf);
+ gst_buffer_unmap (pps_buf, data, size);
/* Not critical here; but throw a warning */
if (ret != GST_FLOW_OK)
GST_WARNING ("Problem pushing PPS");
}
static gboolean
-gst_rtp_h264_pay_handle_event (GstPad * pad, GstEvent * event)
+gst_rtp_h264_pay_handle_event (GstBaseRTPPayload * payload, GstEvent * event)
{
+ gboolean res;
const GstStructure *s;
- GstRtpH264Pay *rtph264pay = GST_RTP_H264_PAY (GST_PAD_PARENT (pad));
+ GstRtpH264Pay *rtph264pay = GST_RTP_H264_PAY (payload);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_STOP:
break;
}
- return FALSE;
+ res =
+ GST_BASE_RTP_PAYLOAD_CLASS (parent_class)->handle_event (payload, event);
+
+ return res;
}
static GstStateChangeReturn