[Pkg-gstreamer-commits] [gstreamer-vaapi] 27/176: vaapiencode: optimize _handle_frame() to avoid extra allocation.

Vincent Cheng vcheng at moszumanska.debian.org
Tue Jun 3 08:09:24 UTC 2014


This is an automated email from the git hooks/post-receive script.

vcheng pushed a commit to branch upstream
in repository gstreamer-vaapi.

commit 30f382fcdfb9ff790ce23aae7a076ad6fdf7b606
Author: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
Date:   Thu Nov 28 15:56:53 2013 +0100

    vaapiencode: optimize _handle_frame() to avoid extra allocation.
    
    Optimize gst_vaapiencode_handle_frame() to avoid extra memory allocation,
    and in particular the GstVaapiEncObjUserData object. i.e. directly use
    the VA surface proxy from the source buffer. This also makes the user
    data attached to the GstVideoCodecFrame more consistent between both
    the decoder and encoder plug-in elements.
---
 gst-libs/gst/vaapi/gstvaapiencoder_objects.c |  30 ++++----
 gst-libs/gst/vaapi/gstvaapiencoder_objects.h |   6 +-
 gst/vaapi/gstvaapiencode.c                   | 111 ++++++++++++---------------
 3 files changed, 66 insertions(+), 81 deletions(-)

diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c
index e87538c..2a61736 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.c
@@ -25,6 +25,7 @@
 #include "gstvaapiencoder_objects.h"
 #include "gstvaapiencoder.h"
 #include "gstvaapiencoder_priv.h"
+#include "gstvaapisurfaceproxy_priv.h"
 #include "gstvaapiutils.h"
 
 #define DEBUG 1
@@ -387,7 +388,7 @@ gst_vaapi_enc_picture_destroy (GstVaapiEncPicture * picture)
   gst_vaapi_mini_object_replace (
       (GstVaapiMiniObject **) (&picture->sequence), NULL);
 
-  g_assert (picture->surface);
+  gst_vaapi_surface_proxy_replace (&picture->proxy, NULL);
   picture->surface_id = VA_INVALID_ID;
   picture->surface = NULL;
 
@@ -405,19 +406,22 @@ gboolean
 gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture,
     const GstVaapiCodecObjectConstructorArgs * args)
 {
-  GstVideoCodecFrame *frame;
-  GstVaapiSurface *surface;
-  GstVaapiEncObjUserDataHead *user_data;
+  GstVideoCodecFrame *const frame = (GstVideoCodecFrame *)args->data;
   gboolean success;
 
-  g_assert (args->data);
-  g_return_val_if_fail (args->data, FALSE);
+  g_return_val_if_fail (frame != NULL, FALSE);
 
-  frame = (GstVideoCodecFrame *) args->data;
-  user_data = gst_video_codec_frame_get_user_data (frame);
-  g_assert (user_data);
-  surface = user_data->surface;
-  g_return_val_if_fail (surface, FALSE);
+  picture->proxy = gst_video_codec_frame_get_user_data (frame);
+  if (!gst_vaapi_surface_proxy_ref (picture->proxy))
+    return FALSE;
+
+  picture->surface = GST_VAAPI_SURFACE_PROXY_SURFACE (picture->proxy);
+  if (!picture->surface)
+    return FALSE;
+
+  picture->surface_id = GST_VAAPI_OBJECT_ID (picture->surface);
+  if (picture->surface_id == VA_INVALID_ID)
+    return FALSE;
 
   picture->sequence = NULL;
   picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
@@ -446,10 +450,6 @@ gst_vaapi_enc_picture_create (GstVaapiEncPicture * picture,
     return FALSE;
 
   picture->frame = gst_video_codec_frame_ref (frame);
-  picture->surface = surface;
-  g_assert (picture->surface);
-  picture->surface_id = gst_vaapi_surface_get_id (picture->surface);
-  g_assert (picture->surface_id != VA_INVALID_SURFACE);
 
   return TRUE;
 }
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h
index 240d55b..fdc960e 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_objects.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_objects.h
@@ -261,11 +261,6 @@ typedef enum
 #define GST_VAAPI_ENC_PICTURE_GET_FRAME(picture) \
     (picture)->frame
 
-typedef struct
-{
-  GstVaapiSurface *surface;
-} GstVaapiEncObjUserDataHead;
-
 /**
  * GstVaapiEncPicture:
  *
@@ -276,6 +271,7 @@ struct _GstVaapiEncPicture
   /*< private > */
   GstVaapiCodecObject parent_instance;
   GstVideoCodecFrame *frame;
+  GstVaapiSurfaceProxy *proxy;
   GstVaapiSurface *surface;
   GstVaapiEncSequence *sequence;
   /*< private >, picture packed header */
diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c
index 86b630c..a6bab13 100644
--- a/gst/vaapi/gstvaapiencode.c
+++ b/gst/vaapi/gstvaapiencode.c
@@ -41,12 +41,6 @@
 #define GST_VAAPI_ENCODE_FLOW_CONVERT_ERROR     GST_FLOW_CUSTOM_ERROR_1
 #define GST_VAAPI_ENCODE_FLOW_CODEC_DATA_ERROR  GST_FLOW_CUSTOM_ERROR_2
 
-typedef struct _GstVaapiEncodeFrameUserData
-{
-  GstVaapiEncObjUserDataHead head;
-  GstBuffer *vaapi_buf;
-} GstVaapiEncodeFrameUserData;
-
 GST_DEBUG_CATEGORY_STATIC (gst_vaapiencode_debug);
 #define GST_CAT_DEFAULT gst_vaapiencode_debug
 
@@ -630,7 +624,6 @@ get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer,
   gboolean success;
 #endif
 
-  *out_buffer_ptr = NULL;
   meta = gst_buffer_get_vaapi_video_meta (src_buffer);
   if (meta) {
     *out_buffer_ptr = gst_buffer_ref (src_buffer);
@@ -728,77 +721,73 @@ error_copy_buffer:
   }
 }
 
-static inline gpointer
-_create_user_data (GstBuffer * buf)
-{
-  GstVaapiVideoMeta *meta;
-  GstVaapiSurface *surface;
-  GstVaapiEncodeFrameUserData *user_data;
-
-  meta = gst_buffer_get_vaapi_video_meta (buf);
-  if (!meta) {
-    GST_DEBUG ("convert to vaapi buffer failed");
-    return NULL;
-  }
-  surface = gst_vaapi_video_meta_get_surface (meta);
-  if (!surface) {
-    GST_DEBUG ("vaapi_meta of codec frame doesn't have vaapisurfaceproxy");
-    return NULL;
-  }
-
-  user_data = g_slice_new0 (GstVaapiEncodeFrameUserData);
-  user_data->head.surface = surface;
-  user_data->vaapi_buf = gst_buffer_ref (buf);
-  return user_data;
-}
-
-static void
-_destroy_user_data (gpointer data)
-{
-  GstVaapiEncodeFrameUserData *user_data = (GstVaapiEncodeFrameUserData *) data;
-
-  g_assert (data);
-  if (!user_data)
-    return;
-  gst_buffer_replace (&user_data->vaapi_buf, NULL);
-  g_slice_free (GstVaapiEncodeFrameUserData, user_data);
-}
-
 static GstFlowReturn
 gst_vaapiencode_handle_frame (GstVideoEncoder * venc,
     GstVideoCodecFrame * frame)
 {
   GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc);
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstVaapiEncoderStatus status = GST_VAAPI_ENCODER_STATUS_SUCCESS;
+  GstVaapiEncoderStatus status;
+  GstVaapiVideoMeta *meta;
+  GstVaapiSurfaceProxy *proxy;
+  GstFlowReturn ret;
   GstBuffer *buf;
-  gpointer user_data;
-
-  g_assert (encode && encode->encoder);
-  g_assert (frame && frame->input_buffer);
 
+  buf = NULL;
   ret = get_source_buffer (encode, frame->input_buffer, &buf);
   if (ret != GST_FLOW_OK)
-    return ret;
+    goto error_buffer_invalid;
+
+  gst_buffer_replace (&frame->input_buffer, buf);
+  gst_buffer_unref (buf);
+
+  meta = gst_buffer_get_vaapi_video_meta (buf);
+  if (!meta)
+    goto error_buffer_no_meta;
 
-  user_data = _create_user_data (buf);
-  GST_VAAPI_ENCODER_CHECK_STATUS (user_data,
-      ret, "create frame user data failed");
+  proxy = gst_vaapi_video_meta_get_surface_proxy (meta);
+  if (!proxy)
+    goto error_buffer_no_surface_proxy;
 
-  gst_video_codec_frame_set_user_data (frame, user_data, _destroy_user_data);
+  gst_video_codec_frame_set_user_data (frame,
+      gst_vaapi_surface_proxy_ref (proxy),
+      (GDestroyNotify)gst_vaapi_surface_proxy_unref);
 
   GST_VIDEO_ENCODER_STREAM_UNLOCK (encode);
-  /*encoding frames */
   status = gst_vaapi_encoder_put_frame (encode->encoder, frame);
   GST_VIDEO_ENCODER_STREAM_LOCK (encode);
+  if (status < GST_VAAPI_ENCODER_STATUS_SUCCESS)
+    goto error_encode_frame;
 
-  GST_VAAPI_ENCODER_CHECK_STATUS (GST_VAAPI_ENCODER_STATUS_SUCCESS <=
-      status, GST_FLOW_ERROR, "gst_vaapiencoder_encode failed.");
-
-end:
   gst_video_codec_frame_unref (frame);
-  gst_buffer_replace (&buf, NULL);
-  return ret;
+  return GST_FLOW_OK;
+
+  /* ERRORS */
+error_buffer_invalid:
+  {
+    if (buf)
+      gst_buffer_unref (buf);
+    gst_video_codec_frame_unref (frame);
+    return ret;
+  }
+error_buffer_no_meta:
+  {
+    GST_ERROR ("failed to get GstVaapiVideoMeta information");
+    gst_video_codec_frame_unref (frame);
+    return GST_FLOW_ERROR;
+  }
+error_buffer_no_surface_proxy:
+  {
+    GST_ERROR ("failed to get VA surface proxy");
+    gst_video_codec_frame_unref (frame);
+    return GST_FLOW_ERROR;
+  }
+error_encode_frame:
+  {
+    GST_ERROR ("failed to encode frame %d (status %d)",
+        frame->system_frame_number, status);
+    gst_video_codec_frame_unref (frame);
+    return GST_FLOW_ERROR;
+  }
 }
 
 static GstFlowReturn

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gstreamer/gstreamer-vaapi.git



More information about the Pkg-gstreamer-commits mailing list