Fix memory leak for vpp, refine code
authorZhao Halley <halley.zhao@intel.com>
Wed, 24 Apr 2013 09:02:35 +0000 (17:02 +0800)
committerZhao Halley <halley.zhao@intel.com>
Thu, 25 Apr 2013 06:26:22 +0000 (14:26 +0800)
1. gst_vaapi_video_buffer_new_with_surface() leak memory,
    use gst_vaapi_video_buffer_new_from_pool instead.
2. since surface is created in gstvaapipostproc,
   remove width/height/format in gstvaapipostprocessing

gst-libs/gst/vaapi/gstvaapipostprocess.c
gst-libs/gst/vaapi/gstvaapipostprocess.h
gst/vaapi/gstvaapipostproc.c
gst/vaapi/gstvaapipostproc.h

index cc57dbb..4a027df 100755 (executable)
@@ -185,15 +185,6 @@ gst_vaapi_pp_set_property_filter_attributes(
          case PROP_DENOISE_LEVEL:
              pattrs->denoise_level = g_value_get_float(value);
              break;
-         case PROP_FORMAT:
-             pattrs->out_format = g_value_get_uint(value);
-             break;
-         case PROP_WIDTH:
-             pattrs->out_width = g_value_get_uint(value);
-             break;
-         case PROP_HEIGHT:
-             pattrs->out_height = g_value_get_uint(value);
-             break;
         case PROP_HUE:
             pattrs->hue = g_value_get_float(value);
             break;
@@ -267,15 +258,6 @@ gst_vaapi_pp_get_property_filter_attributes(
         case PROP_DENOISE_LEVEL:
             g_value_set_float(value, pattrs->denoise_level);
             break;
-        case PROP_FORMAT:
-            g_value_set_uint(value, pattrs->out_format);
-            break;
-        case PROP_WIDTH:
-            g_value_set_uint(value, pattrs->out_width);
-            break;
-        case PROP_HEIGHT:
-            g_value_set_uint(value, pattrs->out_height);
-            break;
         case PROP_HUE:
             g_value_set_float(value, pattrs->hue);
             break;
@@ -470,45 +452,17 @@ static gboolean gst_vaapipostproc_filters_setup(GstVaapiPostprocess *postprocess
 }
 
 static gboolean
-gst_vaapipostproc_process(GstVaapiPostprocess *postprocess, GstVaapiSurface *in_surface, GstVaapiSurface **out__surface)
+gst_vaapipostproc_process(GstVaapiPostprocess *postprocess, GstVaapiSurface *in_surface, GstVaapiSurface *out_surface)
 
 {
     GstVaapiDisplay * const display= GST_VAAPI_OBJECT_DISPLAY(postprocess);
     VADisplay va_dpy = gst_vaapi_display_get_display(display);
     GstVaapiPostprocessPrivate * priv = postprocess->priv;
     GstVaapiPPFilterAttributes * pattrs = &priv->filter_attributes;
-    int chroma_type = 0;
     VAStatus va_status;
     VAProcPipelineParameterBuffer *pipeline_param = NULL;
     VABufferID pipeline_param_buffer_id;
     VARectangle input_region, output_region;
-    int out_width, out_height;
-
-    *out__surface = NULL;
-
-    if (pattrs->out_format == 0) {
-        chroma_type = gst_vaapi_surface_get_chroma_type(in_surface);
-    }
-
-    if (pattrs->out_width == 0 || pattrs->out_height == 0) {
-        out_width = gst_vaapi_surface_get_width(in_surface);
-        out_height = gst_vaapi_surface_get_height(in_surface);
-    }
-    else {
-        out_width = pattrs->out_width;
-        out_height = pattrs->out_height;
-    }
-    GstVaapiSurface *out_surface = NULL;
-    if (pattrs->out_format) {
-        out_surface = gst_vaapi_surface_new_with_fourcc(
-                    display, pattrs->out_format,
-                    out_width, out_height);
-    }
-    else {
-        out_surface = gst_vaapi_surface_new(
-                    display, chroma_type,
-                    out_width, out_height);
-    }
 
     if (pattrs->filter_update_required) { 
         gst_vaapipostproc_filters_setup(postprocess);
@@ -526,8 +480,8 @@ gst_vaapipostproc_process(GstVaapiPostprocess *postprocess, GstVaapiSurface *in_
     input_region.height = gst_vaapi_surface_get_height(in_surface);
     output_region.x = 0;
     output_region.y = 0;
-    output_region.width = out_width;
-    output_region.height = out_height;
+    output_region.width = gst_vaapi_surface_get_width(out_surface);
+    output_region.height = gst_vaapi_surface_get_height(out_surface);
 
     va_status = vaCreateBuffer (va_dpy, priv->context_id,
                                 VAProcPipelineParameterBufferType,
@@ -565,8 +519,6 @@ gst_vaapipostproc_process(GstVaapiPostprocess *postprocess, GstVaapiSurface *in_
         return FALSE;
     }
 
-    *out__surface = out_surface;
-
     return TRUE;
 
 }
@@ -618,37 +570,6 @@ void gst_vaapi_pp_install_property_filter_attributes(GObjectClass *object_class)
                            0.0, 1.0, 0.5, 
                            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     
-    // output surface format
-    g_object_class_install_property
-        (object_class,
-         PROP_FORMAT,
-         g_param_spec_uint("out-surface-format",
-                             "out-surface-format",
-                             "out surface froamt (fourcc), input surfae format is used when it is not specified",
-                             0, G_MAXINT, 0,
-                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-    // output surface width
-    g_object_class_install_property
-        (object_class,
-         PROP_WIDTH,
-         g_param_spec_uint("out-surface-width",
-                           "out surface width",
-                           "out surface width, input surface width is used when it is not specified",
-                           0, G_MAXINT, 0, // use 0 to indicate keep same to input surface
-                           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-
-    // output surface height
-    g_object_class_install_property
-        (object_class,
-         PROP_HEIGHT,
-         g_param_spec_uint("out-surface-height",
-                           "out surface height",
-                           "out surface height, input surface height is used when it is not specified",
-                           0, G_MAXINT, 0, // use 0 to indicate keep same to input surface
-                           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
     // hue
     g_object_class_install_property
         (object_class,
@@ -753,9 +674,6 @@ void gst_vaapi_pp_init_filter_attributes(GstVaapiPPFilterAttributes *pattrs)
     pattrs->deinterlace_method        = DEFAULT_DEINTERLACE_METHOD;
     pattrs->denoise                   = FALSE;
     pattrs->denoise_level             = 0.5;
-    pattrs->out_format                = 0;
-    pattrs->out_width                 = 0;
-    pattrs->out_height                = 0;
     pattrs->hue                       = HUE_DEFAULT;
     pattrs->saturation                = SATURATION_DEFAULT;
     pattrs->brightness                = BRIGHTNESS_DEFAULT;
index df3cef7..b54772f 100755 (executable)
@@ -131,9 +131,6 @@ struct _GstVaapiPPFilterAttributes{
     GstVaapiDeinterlaceMethod   deinterlace_method;
     gboolean                    denoise;
     float                       denoise_level;
-    guint                       out_format;
-    guint                       out_width;
-    guint                       out_height;
     float                       hue;
     float                       saturation;
     float                       brightness;
@@ -150,7 +147,7 @@ struct _GstVaapiPPFilterAttributes{
  */
  typedef int (*fun_ptr)(int,int); 
 typedef gboolean 
-(*vaapipostprocess_process)(GstVaapiPostprocess *postproc, GstVaapiSurface *in_surface, GstVaapiSurface **out_surface);
+(*vaapipostprocess_process)(GstVaapiPostprocess *postproc, GstVaapiSurface *in_surface, GstVaapiSurface *out_surface);
 
 struct _GstVaapiPostprocess {
     /*< private >*/
index a7071e0..543e3c2 100755 (executable)
@@ -314,6 +314,32 @@ error_push_buffer:
 }
 
 #else
+static gboolean
+ensure_surface_pool(GstVaapiPostproc *postproc, GstCaps *caps)
+{
+    GstStructure * const structure = gst_caps_get_structure(caps, 0);
+    gint width, height, format;
+    GstVideoFormat vformat;
+
+    if (!caps)
+        return FALSE;
+
+    gst_structure_get_int(structure, "width",  &width);
+    gst_structure_get_int(structure, "height", &height);
+    gst_video_format_parse_caps(caps, &vformat, NULL, NULL);
+    format = gst_vaapi_image_format_from_video(vformat);
+
+    if (width != postproc->surface_width || height != postproc->surface_height || format != postproc->surface_format) {
+        postproc->surface_width  = width;
+        postproc->surface_height = height;
+        postproc->surface_format = format;
+        g_clear_object(&postproc->surfaces);
+        postproc->surfaces = gst_vaapi_surface_pool_new(postproc->display, caps);
+        if (!postproc->surfaces)
+            return FALSE;
+    }
+    return TRUE;
+}
 
 static GstBuffer *
 gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
@@ -322,8 +348,16 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
     VADisplay va_dpy = gst_vaapi_display_get_display(postproc->display);
     GstVaapiSurface *in_surface = gst_vaapi_video_buffer_get_surface(vbuf);
     GstVaapiSurface *out_surface=NULL;
+    GstBuffer *buffer = NULL;
     GstVaapiPPFilterAttributes *pattrs = &postproc->filter_attributes;
 
+    if (!ensure_surface_pool(postproc, postproc->srcpad_caps)) {
+        return NULL;
+    }
+    buffer = gst_vaapi_video_buffer_new_from_pool(postproc->surfaces);
+    if (!buffer) return NULL;
+    GstVaapiVideoBuffer *vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);
+    out_surface = gst_vaapi_video_buffer_get_surface(vbuffer);
     if (pattrs->filter_update_required) {
         // update parameters to GstVaapiPostprocess
         g_object_set(postproc->vpp, 
@@ -331,9 +365,6 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
                     "deinterlace-method", pattrs->deinterlace_method,
                     "denoise", pattrs->denoise,
                     "denoise-level", pattrs->denoise_level,
-                    "out-surface-format", pattrs->out_format,
-                    "out-surface-width", pattrs->out_width,
-                    "out-surface-height", pattrs->out_height,
                     "hue", pattrs->hue,
                     "saturation", pattrs->saturation,
                     "brightness", pattrs->brightness,
@@ -346,21 +377,23 @@ gst_vaapipostproc_process(GstVaapiPostproc *postproc, GstBuffer *buf)
                     NULL);
     }
 
-    postproc->vpp->process(postproc->vpp, in_surface, &out_surface);
+    if (! postproc->vpp->process(postproc->vpp, in_surface, out_surface)) {
+        gst_buffer_unref(buffer);
+        return NULL;
+    }
     
-    GstBuffer *new_buf = gst_vaapi_video_buffer_new_with_surface(out_surface);
-    GST_BUFFER_TIMESTAMP(new_buf) = GST_BUFFER_TIMESTAMP(buf);
-    GST_BUFFER_DURATION(new_buf)  = GST_BUFFER_DURATION(buf);
-    gst_buffer_set_caps(new_buf, postproc->srcpad_caps);
+    GST_BUFFER_TIMESTAMP(buffer) = GST_BUFFER_TIMESTAMP(buf);
+    GST_BUFFER_DURATION(buffer)  = GST_BUFFER_DURATION(buf);
+    gst_buffer_set_caps(buffer, postproc->srcpad_caps);
 
     if (pattrs->deinterlace) {
         guint flags = gst_vaapi_video_buffer_get_render_flags(vbuf);
         // flags &= ~(GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD| GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD);
         flags |= GST_VAAPI_PICTURE_STRUCTURE_FRAME;
-        gst_vaapi_video_buffer_set_render_flags(GST_VAAPI_VIDEO_BUFFER(new_buf), flags);
+        gst_vaapi_video_buffer_set_render_flags(GST_VAAPI_VIDEO_BUFFER(buffer), flags);
     }                
 
-    return new_buf;
+    return buffer;
 
 }
 #endif
@@ -454,9 +487,6 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *sink_caps
     src_caps_2 = gst_caps_intersect(src_caps_1, sink_caps_copy);
 
     structure    = gst_caps_get_structure(src_caps_2, 0);
-    gst_structure_get_int(structure, "width", &pattrs->out_width);
-    gst_structure_get_int(structure, "height", &pattrs->out_height);
-    gst_structure_get_fourcc(structure, "format", &pattrs->out_format);
     pattrs->filter_update_required = TRUE;
     
     if (pattrs->deinterlace) {
index 6438af0..afc7043 100755 (executable)
@@ -84,8 +84,10 @@ struct _GstVaapiPostproc {
     GstCaps                    *postproc_caps;
 
     GstVaapiDisplay            *display;
-    guint                       surface_width;
-    guint                       surface_height;
+    gint                       surface_width;
+    gint                       surface_height;
+    gint                       surface_format;
+
 
     /* Deinterlacing */
     GstVaapiDeinterlaceMode     deinterlace_mode;
@@ -99,6 +101,7 @@ struct _GstVaapiPostproc {
 #else
     GstVaapiPostprocess        *vpp;
     GstVaapiPPFilterAttributes  filter_attributes;
+    GstVaapiVideoPool          *surfaces;
 #endif
 };