summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2017-06-03 00:58:05 +0100
committerTim-Philipp Müller <tim@centricular.com>2017-11-23 09:35:59 +0100
commitf3e4df72a1aa674565ca6e383181a6c1d4ec4fbd (patch)
tree9755f0bded23722b07ab9e81ec1ad9e8b3a6de93
parentb6f13ce4e928d023620406fdaae91ff2ea32962f (diff)
rtph264depay: assemble AUs into downstream-allocated memory
When merging NALs into AUs, use downstream-provided allocator to allocate memory and copy NALs directly into that memory when assembling them.
-rw-r--r--gst/rtp/gstrtph264depay.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/gst/rtp/gstrtph264depay.c b/gst/rtp/gstrtph264depay.c
index c05f88a26..6a9a97be2 100644
--- a/gst/rtp/gstrtph264depay.c
+++ b/gst/rtp/gstrtph264depay.c
@@ -775,16 +775,70 @@ incomplete_caps:
}
static GstBuffer *
+gst_rtp_h264_depay_allocate_output_buffer (GstRtpH264Depay * depay, gsize size)
+{
+ GstBuffer *buffer = NULL;
+
+ g_return_val_if_fail (size > 0, NULL);
+
+ GST_LOG_OBJECT (depay, "want output buffer of %u bytes", (guint) size);
+
+ buffer = gst_buffer_new_allocate (depay->allocator, size, &depay->params);
+ if (buffer == NULL) {
+ GST_INFO_OBJECT (depay, "couldn't allocate output buffer");
+ buffer = gst_buffer_new_allocate (NULL, size, NULL);
+ }
+
+ return buffer;
+}
+
+static GstBuffer *
gst_rtp_h264_complete_au (GstRtpH264Depay * rtph264depay,
GstClockTime * out_timestamp, gboolean * out_keyframe)
{
- guint outsize;
+ GstBufferList *list;
+ GstMapInfo outmap;
GstBuffer *outbuf;
+ guint outsize, offset = 0;
+ gint b, n_bufs, m, n_mem;
/* we had a picture in the adapter and we completed it */
GST_DEBUG_OBJECT (rtph264depay, "taking completed AU");
outsize = gst_adapter_available (rtph264depay->picture_adapter);
- outbuf = gst_adapter_take_buffer (rtph264depay->picture_adapter, outsize);
+
+ outbuf = gst_rtp_h264_depay_allocate_output_buffer (rtph264depay, outsize);
+
+ if (outbuf == NULL)
+ return NULL;
+
+ if (!gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE))
+ return NULL;
+
+ list = gst_adapter_take_buffer_list (rtph264depay->picture_adapter, outsize);
+
+ n_bufs = gst_buffer_list_length (list);
+ for (b = 0; b < n_bufs; ++b) {
+ GstBuffer *buf = gst_buffer_list_get (list, b);
+
+ n_mem = gst_buffer_n_memory (buf);
+ for (m = 0; m < n_mem; ++m) {
+ GstMemory *mem = gst_buffer_peek_memory (buf, m);
+ gsize mem_size = gst_memory_get_sizes (mem, NULL, NULL);
+ GstMapInfo mem_map;
+
+ if (gst_memory_map (mem, &mem_map, GST_MAP_READ)) {
+ memcpy (outmap.data + offset, mem_map.data, mem_size);
+ gst_memory_unmap (mem, &mem_map);
+ } else {
+ memset (outmap.data + offset, 0, mem_size);
+ }
+ offset += mem_size;
+ }
+
+ gst_rtp_copy_video_meta (rtph264depay, outbuf, buf);
+ }
+ gst_buffer_list_unref (list);
+ gst_buffer_unmap (outbuf, &outmap);
*out_timestamp = rtph264depay->last_ts;
*out_keyframe = rtph264depay->last_keyframe;