diff options
author | Tim-Philipp Müller <tim@centricular.com> | 2017-06-03 00:58:05 +0100 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2017-11-23 09:35:59 +0100 |
commit | f3e4df72a1aa674565ca6e383181a6c1d4ec4fbd (patch) | |
tree | 9755f0bded23722b07ab9e81ec1ad9e8b3a6de93 | |
parent | b6f13ce4e928d023620406fdaae91ff2ea32962f (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.c | 58 |
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; |