rtpmp4apay: Create buffer lists and don't copy payload memory

This commit is contained in:
Sebastian Dröge 2015-07-03 10:51:57 +02:00
parent 5ae672fd22
commit 002bba37f7

View file

@ -342,6 +342,8 @@ config_failed:
} }
} }
#define RTP_HEADER_LEN 12
/* we expect buffers as exactly one complete AU /* we expect buffers as exactly one complete AU
*/ */
static GstFlowReturn static GstFlowReturn
@ -350,11 +352,10 @@ gst_rtp_mp4a_pay_handle_buffer (GstRTPBasePayload * basepayload,
{ {
GstRtpMP4APay *rtpmp4apay; GstRtpMP4APay *rtpmp4apay;
GstFlowReturn ret; GstFlowReturn ret;
GstBuffer *outbuf; GstBufferList *list;
guint count, mtu; guint mtu;
GstMapInfo map; guint offset;
gsize size; gsize size;
guint8 *data;
gboolean fragmented; gboolean fragmented;
GstClockTime timestamp; GstClockTime timestamp;
@ -362,83 +363,90 @@ gst_rtp_mp4a_pay_handle_buffer (GstRTPBasePayload * basepayload,
rtpmp4apay = GST_RTP_MP4A_PAY (basepayload); rtpmp4apay = GST_RTP_MP4A_PAY (basepayload);
gst_buffer_map (buffer, &map, GST_MAP_READ); offset = 0;
size = map.size; size = gst_buffer_get_size (buffer);
data = map.data;
timestamp = GST_BUFFER_PTS (buffer); timestamp = GST_BUFFER_PTS (buffer);
fragmented = FALSE; fragmented = FALSE;
mtu = GST_RTP_BASE_PAYLOAD_MTU (rtpmp4apay); mtu = GST_RTP_BASE_PAYLOAD_MTU (rtpmp4apay);
list = gst_buffer_list_new_sized (size / (mtu - RTP_HEADER_LEN) + 1);
while (size > 0) { while (size > 0) {
guint towrite; guint towrite;
guint8 *payload; GstBuffer *outbuf;
guint payload_len; guint payload_len;
guint packet_len; guint packet_len;
guint header_len;
GstBuffer *paybuf;
GstRTPBuffer rtp = { NULL }; GstRTPBuffer rtp = { NULL };
/* this will be the total lenght of the packet */ header_len = 0;
packet_len = gst_rtp_buffer_calc_packet_len (size, 0, 0);
if (!fragmented) { if (!fragmented) {
guint count;
/* first packet calculate space for the packet including the header */ /* first packet calculate space for the packet including the header */
count = size; count = size;
while (count >= 0xff) { while (count >= 0xff) {
packet_len++; header_len++;
count -= 0xff; count -= 0xff;
} }
packet_len++; header_len++;
} }
/* fill one MTU or all available bytes */ packet_len = gst_rtp_buffer_calc_packet_len (header_len + size, 0, 0);
towrite = MIN (packet_len, mtu); towrite = MIN (packet_len, mtu);
/* this is the payload length */
payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0); payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0);
payload_len -= header_len;
GST_DEBUG_OBJECT (rtpmp4apay, GST_DEBUG_OBJECT (rtpmp4apay,
"avail %" G_GSIZE_FORMAT ", towrite %d, packet_len %d, payload_len %d", "avail %" G_GSIZE_FORMAT
size, towrite, packet_len, payload_len); ", header_len %d, packet_len %d, payload_len %d", size, header_len,
packet_len, payload_len);
/* create buffer to hold the payload. */ /* create buffer to hold the payload. */
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0); outbuf = gst_rtp_buffer_new_allocate (header_len, 0, 0);
/* copy payload */ /* copy payload */
gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp); gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
payload = gst_rtp_buffer_get_payload (&rtp);
if (!fragmented) { if (!fragmented) {
guint8 *payload = gst_rtp_buffer_get_payload (&rtp);
guint count;
/* first packet write the header */ /* first packet write the header */
count = size; count = size;
while (count >= 0xff) { while (count >= 0xff) {
*payload++ = 0xff; *payload++ = 0xff;
payload_len--;
count -= 0xff; count -= 0xff;
} }
*payload++ = count; *payload++ = count;
payload_len--;
} }
/* copy data to payload */
memcpy (payload, data, payload_len);
data += payload_len;
size -= payload_len;
/* marker only if the packet is complete */ /* marker only if the packet is complete */
gst_rtp_buffer_set_marker (&rtp, size == 0); gst_rtp_buffer_set_marker (&rtp, size == payload_len);
gst_rtp_buffer_unmap (&rtp); gst_rtp_buffer_unmap (&rtp);
/* create a new buf to hold the payload */
paybuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL,
offset, payload_len);
/* join memory parts */
outbuf = gst_buffer_append (outbuf, paybuf);
gst_buffer_list_add (list, outbuf);
offset += payload_len;
size -= payload_len;
/* copy incomming timestamp (if any) to outgoing buffers */ /* copy incomming timestamp (if any) to outgoing buffers */
GST_BUFFER_PTS (outbuf) = timestamp; GST_BUFFER_PTS (outbuf) = timestamp;
ret = gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (rtpmp4apay), outbuf);
fragmented = TRUE; fragmented = TRUE;
} }
gst_buffer_unmap (buffer, &map); ret =
gst_rtp_base_payload_push_list (GST_RTP_BASE_PAYLOAD (rtpmp4apay), list);
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
return ret; return ret;