Reduce mem copying and code clean-up
authorHarinarayan Bhatta <harinarayan@ti.com>
Thu, 4 Jun 2015 09:40:08 +0000 (15:10 +0530)
committerHarinarayan Bhatta <harinarayan@ti.com>
Thu, 4 Jun 2015 09:56:58 +0000 (15:26 +0530)
1. Replace buffer_extract with buffer map and buffer fill, thus
   avoiding a memory copy.
2. Cleanup some unnecessary code in gst_ducati_viddec_chain.
3. Gst ducati plugin accepts external bufferpool from peer. Fix
   a memory leak by freeing this in finalize function.

Signed-off-by: Pooja Prajod <a0132412@ti.com>
Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
src/gstducatimpeg2dec.c
src/gstducatimpeg4dec.c
src/gstducativc1dec.c
src/gstducatividdec.c
src/gstducatividdec.h
src/gstducatividenc.c

index 9e62fbf6fc16a083df3a48875b092233384beff0..b4585ffa837b57ec78033f59995dbb01ac681170 100644 (file)
@@ -109,39 +109,30 @@ gst_ducati_mpeg2dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf)
 {
   GstDucatiMpeg2Dec *self = GST_DUCATIMPEG2DEC (vdec);
 
-  gsize bufoffset, bufmaxsize, buftotalsize;
-  guint sz;
-  guint8 *data = NULL;
-
-  gsize offset, maxsize, totalsize;
-  guint8 *codecdata = NULL;
-  gsize codecdatasize;
-
-  buftotalsize = gst_buffer_get_sizes (buf, &bufoffset, &bufmaxsize);
-  data = g_slice_alloc (buftotalsize);
-  sz = gst_buffer_extract (buf, bufoffset, data, buftotalsize);
-
-  totalsize = gst_buffer_get_sizes (vdec->codec_data, &offset, &maxsize);
-  codecdata = g_slice_alloc (totalsize);
-  codecdatasize =
-      gst_buffer_extract (vdec->codec_data, offset, codecdata, totalsize);
+  GstMapInfo info;
+  gboolean mapped;
+  mapped = gst_buffer_map (buf, &info, GST_MAP_READ);
 
   /* skip codec_data, which is same as first buffer from mpegvideoparse (and
    * appears to be periodically resent) and instead prepend to next frame..
    */
-  if (vdec->codec_data && (sz == codecdatasize) &&
-      !memcmp (data, codecdata, sz)) {
+  if (vdec->codecdata && (info.size == vdec->codecdatasize) &&
+      !memcmp (info.data, vdec->codecdata, info.size)) {
     GST_DEBUG_OBJECT (self, "skipping codec_data buffer");
     self->prepend_codec_data = TRUE;
   } else {
     if (self->prepend_codec_data) {
       GST_DEBUG_OBJECT (self, "prepending codec_data buffer");
-      push_input (vdec, codecdata, codecdatasize);
+      push_input (vdec, vdec->codecdata, vdec->codecdatasize);
       self->prepend_codec_data = FALSE;
     }
-    push_input (vdec, data, sz);
+    if (mapped) {
+      push_input (vdec, info.data, info.size);
+    }
+  }
+  if (mapped) {
+    gst_buffer_unmap (buf, &info);
   }
-
   gst_buffer_unref (buf);
 
   return NULL;
index b7feb20813348651f4c86f6fc67bb9949801296a..783f61757c78cf615796cdd8b40758703f12880f 100644 (file)
@@ -272,26 +272,19 @@ gst_ducati_mpeg4dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf)
 {
   GstDucatiMpeg4Dec *self = GST_DUCATIMPEG4DEC (vdec);
   GstBuffer *remaining = NULL;
-  gsize bufoffset, bufmaxsize, buftotalsize;
-  gint insize;
+  gint insize = 0;
   guint8 *in = NULL;
   gint size = 0;
   guint8 last_start_code = 0xff;
-  buftotalsize = gst_buffer_get_sizes (buf, &bufoffset, &bufmaxsize);
-  in = g_slice_alloc (buftotalsize);
-  insize = gst_buffer_extract (buf, bufoffset, in, buftotalsize);
-
-  if (G_UNLIKELY (vdec->first_in_buffer) && vdec->codec_data) {
-    gsize offset, maxsize, totalsize;
-    guint8 *codecdata = NULL;
-    gsize codecdatasize;
-
-    totalsize = gst_buffer_get_sizes (vdec->codec_data, &offset, &maxsize);
-    codecdata = g_slice_alloc (totalsize);
-    codecdatasize =
-        gst_buffer_extract (vdec->codec_data, offset, codecdata, totalsize);
-
-    push_input (vdec, codecdata, codecdatasize);
+  GstMapInfo info;
+  gboolean mapped;
+  mapped = gst_buffer_map (buf, &info, GST_MAP_READ);
+  if (mapped) {
+    in = info.data;
+    insize = info.size;
+  }
+  if (G_UNLIKELY (vdec->first_in_buffer) && vdec->codecdata) {
+    push_input (vdec, vdec->codecdata, vdec->codecdatasize);
   }
 
   while (insize > (SC_SZ + 1)) {
@@ -360,7 +353,9 @@ gst_ducati_mpeg4dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf)
           GST_BUFFER_DURATION (buf);
     }
   }
-
+  if (mapped) {
+    gst_buffer_unmap (buf, &info);
+  }
   gst_buffer_unref (buf);
 
   return remaining;
index 023d20006d02db14aedefb16a72366a71ad9d03b..324e75d8a37493f6576a49c9b60fdf64857ef3d0 100644 (file)
@@ -160,10 +160,8 @@ gst_ducati_vc1dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf)
   GstDucatiVC1Dec *self = GST_DUCATIVC1DEC (vdec);
   IVC1VDEC_Params *params = (IVC1VDEC_Params *) vdec->params;
   guint32 val;
-  gsize bufoffset, bufmaxsize, buftotalsize;
-  gsize bufdatasize;
-  guint8 *bufdata = NULL;
-
+  GstMapInfo info;
+  gboolean mapped;
 
   /* need a base ts for frame layer timestamps */
   if (self->first_ts == GST_CLOCK_TIME_NONE)
@@ -238,11 +236,11 @@ gst_ducati_vc1dec_push_input (GstDucatiVidDec * vdec, GstBuffer * buf)
     push_input (vdec, (const guint8 *) &val, 4);
   }
 
-  buftotalsize = gst_buffer_get_sizes (buf, &bufoffset, &bufmaxsize);
-  bufdata = g_slice_alloc (buftotalsize);
-  bufdatasize = gst_buffer_extract (buf, bufoffset, bufdata, buftotalsize);
-  push_input (vdec, bufdata, bufdatasize);
-  g_slice_free1 (buftotalsize, bufdata);
+  mapped = gst_buffer_map (buf, &info, GST_MAP_READ);
+  if (mapped) {
+    push_input (vdec, info.data, info.size);
+    gst_buffer_unmap (buf, &info);
+  }
   gst_buffer_unref (buf);
 
   return NULL;
index a6339d7b77c38b7f507ffaab7dbf68be845f23f9..301c691a7cf608238a0d96cae280fe7e51831a2f 100644 (file)
@@ -275,6 +275,7 @@ codec_create (GstDucatiVidDec * self)
 static inline GstBuffer *
 codec_buffer_pool_get (GstDucatiVidDec * self, GstBuffer * buf)
 {
+  GstBuffer *ret_buf;
   if (G_UNLIKELY (!self->pool)) {
     guint size =
         GST_ROUND_UP_4 (self->padded_width) *
@@ -608,34 +609,35 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
         err = XDM_EFAIL;
       }
       gst_caps_unref (caps);
-
-      /* this buffer still has the old caps so we skip it */
-      send = FALSE;
     }
 
     if (send) {
-      gint crop_width, crop_height;
-
       GstVideoCropMeta *crop = gst_buffer_get_video_crop_meta (outbuf);
-      /* send region of interest to sink on first buffer: */
-      XDM_Rect *r = &(self->outArgs->displayBufs.bufDesc[0].activeFrameRegion);
-
-      crop_width = r->bottomRight.x - r->topLeft.x;
-      crop_height = r->bottomRight.y - r->topLeft.y;
-
-      if (crop_width > self->input_width)
-        crop_width = self->input_width;
-      if (crop_height > self->input_height)
-        crop_height = self->input_height;
-
-      GST_INFO_OBJECT (self, "active frame region %d, %d, %d, %d, crop %dx%d",
-          r->topLeft.x, r->topLeft.y, r->bottomRight.x, r->bottomRight.y,
-          crop_width, crop_height);
-
-      crop->x = r->topLeft.x;
-      crop->y = r->topLeft.y;
-      crop->width = crop_width;
-      crop->height = crop_height;
+      if (crop) {
+        gint crop_width, crop_height;
+        /* send region of interest to sink on first buffer: */
+        XDM_Rect *r =
+            &(self->outArgs->displayBufs.bufDesc[0].activeFrameRegion);
+
+        crop_width = r->bottomRight.x - r->topLeft.x;
+        crop_height = r->bottomRight.y - r->topLeft.y;
+
+        if (crop_width > self->input_width)
+          crop_width = self->input_width;
+        if (crop_height > self->input_height)
+          crop_height = self->input_height;
+
+        GST_INFO_OBJECT (self, "active frame region %d, %d, %d, %d, crop %dx%d",
+            r->topLeft.x, r->topLeft.y, r->bottomRight.x, r->bottomRight.y,
+            crop_width, crop_height);
+
+        crop->x = r->topLeft.x;
+        crop->y = r->topLeft.y;
+        crop->width = crop_width;
+        crop->height = crop_height;
+      } else {
+        GST_INFO_OBJECT (self, "Crop metadata not present in buffer");
+      }
     }
 
     if (G_UNLIKELY (self->first_out_buffer) && send) {
@@ -825,20 +827,28 @@ gst_ducati_viddec_parse_caps (GstDucatiVidDec * self, GstStructure * s)
     if (codec_data) {
       int i;
       GstMapInfo info;
+      gboolean mapped;
       GstBuffer *buffer = gst_value_get_buffer (codec_data);
 
       GST_DEBUG_OBJECT (self, "codec_data: %" GST_PTR_FORMAT, buffer);
 
-      gst_buffer_map (buffer, &info, GST_MAP_READ);
+      mapped = gst_buffer_map (buffer, &info, GST_MAP_READ);
       GST_DEBUG_OBJECT (self, "codec_data dump, size = %d ", info.size);
       for (i = 0; i < info.size; i++) {
         GST_DEBUG_OBJECT (self, "%02x ", info.data[i]);
       }
-      self->codecdata = g_slice_alloc (info.size);
-      memcpy (self->codecdata, info.data, info.size);
-      self->codecdatasize = info.size;
-      gst_buffer_unmap (buffer, &info);
-      self->codec_data = gst_buffer_ref (buffer);
+      if (info.size) {
+        self->codecdata = g_slice_alloc (info.size);
+        if (self->codecdata) {
+          memcpy (self->codecdata, info.data, info.size);
+        } else {
+          GST_DEBUG_OBJECT (self, "g_slice_alloc failed");
+        }
+        self->codecdatasize = info.size;
+      }
+      if (mapped) {
+        gst_buffer_unmap (buffer, &info);
+      }
     }
 
     return TRUE;
@@ -917,18 +927,18 @@ gst_ducati_viddec_allocate_params (GstDucatiVidDec * self, gint params_sz,
 static GstBuffer *
 gst_ducati_viddec_push_input (GstDucatiVidDec * self, GstBuffer * buf)
 {
-  gsize bufoffset, bufmaxsize, buftotalsize;
-  guint sz;
-  guint8 *data = NULL;
+  GstMapInfo info;
+  gboolean mapped;
   if (G_UNLIKELY (self->first_in_buffer) && self->codecdata) {
     push_input (self, self->codecdata, self->codecdatasize);
   }
-
   /* just copy entire buffer */
-  buftotalsize = gst_buffer_get_sizes (buf, &bufoffset, &bufmaxsize);
-  data = g_slice_alloc (buftotalsize);
-  sz = gst_buffer_extract (buf, bufoffset, data, buftotalsize);
-  push_input (self, data, sz);
+
+  mapped = gst_buffer_map (buf, &info, GST_MAP_READ);
+  if (mapped) {
+    push_input (self, info.data, info.size);
+    gst_buffer_unmap (buf, &info);
+  }
   gst_buffer_unref (buf);
 
   return NULL;
@@ -1317,13 +1327,14 @@ allocate_buffer:
         NULL);
     if (ret_acq_buf == GST_FLOW_OK) {
       GstMetaDmaBuf *meta = gst_buffer_get_dma_buf_meta (outbuf);
-      if (!meta) {
-        goto aqcuire_from_own_pool;
+      if (meta) {
+        goto common;
+      } else {
+        gst_buffer_unref (outbuf);
       }
-      goto common;
     }
-  } else {
-    goto aqcuire_from_own_pool;
+    GST_WARNING_OBJECT (self, "acquire buffer from externalpool failed %s",
+        gst_flow_get_name (ret_acq_buf));
   }
 
 aqcuire_from_own_pool:
@@ -1334,47 +1345,10 @@ aqcuire_from_own_pool:
   outbuf = codec_buffer_pool_get (self, NULL);
 
 common:
-  if (ret != GST_FLOW_OK) {
-    GST_WARNING_OBJECT (self, "alloc_buffer failed %s",
-        gst_flow_get_name (ret));
+  if (outbuf == NULL) {
+    GST_WARNING_OBJECT (self, "alloc_buffer failed");
     gst_buffer_unref (buf);
-    return ret;
-  }
-
-  outcaps = gst_pad_get_current_caps (self->srcpad);
-  if (outcaps
-      && !gst_caps_is_equal (outcaps,
-          gst_pad_get_current_caps (self->srcpad))) {
-    GstStructure *s;
-    gsize bufoffset, bufmaxsize, buftotalsize;
-    guint sz;
-    guint8 *data = NULL;
-
-    GST_INFO_OBJECT (self, "doing upstream negotiation bufsize %d",
-        gst_buffer_get_size (outbuf));
-
-    s = gst_caps_get_structure (outcaps, 0);
-    gst_structure_get_int (s, "rowstride", &self->stride);
-    self->outsize =
-        GST_ROUND_UP_4 (self->stride) * GST_ROUND_UP_2 (self->padded_height) *
-        3 / 2;
-
-    GST_INFO_OBJECT (self, "outsize %d stride %d outcaps: %" GST_PTR_FORMAT,
-        self->outsize, self->stride, outcaps);
-
-    gst_pad_set_caps (self->srcpad, outcaps);
-
-    buftotalsize = gst_buffer_get_sizes (outbuf, &bufoffset, &bufmaxsize);
-    data = g_slice_alloc (buftotalsize);
-    sz = gst_buffer_extract (outbuf, bufoffset, data, buftotalsize);
-
-/* TO DO for vpe
-    if (sz != self->outsize) {
-      GST_INFO_OBJECT (self, "dropping buffer (bufsize %d != outsize %d)",
-          sz, self->outsize);
-      gst_buffer_unref (outbuf);
-      goto allocate_buffer;
-    }*/
+    return GST_FLOW_ERROR;
   }
 
   if (G_UNLIKELY (!self->codec)) {
@@ -1721,15 +1695,18 @@ gst_ducati_viddec_finalize (GObject * obj)
   GstDucatiVidDec *self = GST_DUCATIVIDDEC (obj);
 
   codec_delete (self);
+
+  if (self->externalpool) {
+    gst_object_unref (self->externalpool);
+    self->externalpool = NULL;
+  }
+
   engine_close (self);
 
   /* Will unref the remaining buffers if needed */
   g_hash_table_unref (self->dce_locked_bufs);
   g_hash_table_unref (self->passed_in_bufs);
-  if (self->codec_data) {
-    gst_buffer_unref (self->codec_data);
-    self->codec_data = NULL;
-  }
+
   if (self->codecdata) {
     g_slice_free1 (self->codecdatasize, self->codecdata);
     self->codecdata = NULL;
index bd785caa51c3c7f2bf8f4f2adf1dd52c1729fe24..317b4c754d21257e264688734ba768f1933fd376 100644 (file)
@@ -102,7 +102,6 @@ struct _GstDucatiVidDec
   GstBufferPool *externalpool;
 
   /* by default, codec_data from sinkpad is prepended to first buffer: */
-  GstBuffer *codec_data;
 
   guint8 *codecdata;
   gsize codecdatasize;
index ab937d37c2aee8adb8993520a62b8160e6df4276..017cade038d17546a3716cda2e8aac267d2954a3 100644 (file)
@@ -682,21 +682,20 @@ gst_ducati_videnc_handle_frame (GstVideoEncoder * base_video_encoder,
 have_inbuf:
   dmabuf_fd_in = gst_ducati_videnc_buffer_lock (self, inbuf);
   if (dmabuf_fd_in < 0) {
-    gsize offset, maxsize, totalsize;
-    guint8 *codecdata = NULL;
-    gsize codecdatasize;
+    GstMapInfo info;
+    gboolean mapped;
 
     GST_DEBUG_OBJECT (self, "memcpying input");
     gst_buffer_unref (inbuf);
     inbuf = GST_BUFFER (gst_drm_buffer_pool_get (self->input_pool, FALSE));
     gst_buffer_pool_set_active (GST_BUFFER_POOL (self->input_pool), TRUE);
 
-    totalsize = gst_buffer_get_sizes (frame->input_buffer, &offset, &maxsize);
-    codecdata = g_slice_alloc (totalsize);
-    codecdatasize =
-        gst_buffer_extract (frame->input_buffer, offset, codecdata, totalsize);
-    gst_buffer_fill (inbuf, offset, codecdata, codecdatasize);
-    g_free (codecdata);
+    mapped = gst_buffer_map (frame->input_buffer, &info, GST_MAP_READ);
+    if (mapped) {
+      gst_buffer_fill (inbuf, 0, info.data, info.size);
+      gst_buffer_unmap (frame->input_buffer, &info);
+    }
+
     GST_BUFFER_PTS (inbuf) = ts;
     goto have_inbuf;
   }
@@ -773,9 +772,8 @@ have_inbuf:
   }
 
   if (self->outArgs->bytesGenerated > 0) {
-    gsize offset, maxsize, totalsize;
-    guint8 *codecdata = NULL;
-    gsize codecdatasize;
+    GstMapInfo info;
+    gboolean mapped;
     if (GST_DUCATIVIDENC_GET_CLASS (self)->is_sync_point (self,
             self->outArgs->encodedFrameType)) {
       GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
@@ -784,19 +782,14 @@ have_inbuf:
       gst_buffer_unref (frame->output_buffer);
     }
 
-
-    totalsize = gst_buffer_get_sizes (outbuf, &offset, &maxsize);
-    codecdata = g_slice_alloc0 (self->outArgs->bytesGenerated);
-    codecdatasize =
-        gst_buffer_extract (outbuf, offset, codecdata,
-        self->outArgs->bytesGenerated);
-
     frame->output_buffer =
         gst_video_encoder_allocate_output_buffer (GST_VIDEO_ENCODER (self),
         self->outArgs->bytesGenerated);
-
-    gst_buffer_fill (frame->output_buffer, offset, codecdata, codecdatasize);
-    g_free (codecdata);
+    mapped = gst_buffer_map (outbuf, &info, GST_MAP_READ);
+    if (mapped) {
+      gst_buffer_fill (frame->output_buffer, 0, info.data, info.size);
+      gst_buffer_unmap (outbuf, &info);
+    }
 
     GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, self,
         "Encoded frame in %u bytes", self->outArgs->bytesGenerated);