OSDN Git Service

HEVC: append a motion vector temporal buffer to a VA surface
authorXiang, Haihao <haihao.xiang@intel.com>
Thu, 19 Jun 2014 08:49:54 +0000 (16:49 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Sat, 13 Dec 2014 16:42:17 +0000 (00:42 +0800)
It is the current motion vector temporal buffer to the decoded
current surface, and the collocated motion verctor temporal buffer
for reference surface

Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
(cherry picked from commit 1b1019020ebe3064bd0320bcc1391cc73c9b596c)

src/gen9_mfd.c
src/intel_media.h
src/intel_media_common.c

index 8545d1a..2056439 100644 (file)
 #include "i965_decoder_utils.h"
 
 #include "gen9_mfd.h"
+#include "intel_media.h"
+
+static void
+gen9_hcpd_init_hevc_surface(VADriverContextP ctx,
+                            VAPictureParameterBufferHEVC *pic_param,
+                            struct object_surface *obj_surface,
+                            struct gen9_hcpd_context *gen9_hcpd_context)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    GenHevcSurface *gen9_hevc_surface;
+
+    if (!obj_surface)
+        return;
+
+    obj_surface->free_private_data = gen_free_hevc_surface;
+    gen9_hevc_surface = obj_surface->private_data;
+
+    if (!gen9_hevc_surface) {
+        gen9_hevc_surface = calloc(sizeof(GenHevcSurface), 1);
+        obj_surface->private_data = gen9_hevc_surface;
+    }
+
+    if (gen9_hevc_surface->motion_vector_temporal_bo == NULL) {
+        uint32_t size;
+
+        if (gen9_hcpd_context->ctb_size == 16)
+            size = ((gen9_hcpd_context->picture_width_in_pixels + 63) >> 6) *
+                ((gen9_hcpd_context->picture_height_in_pixels + 15) >> 4);
+        else
+            size = ((gen9_hcpd_context->picture_width_in_pixels + 31) >> 5) *
+                ((gen9_hcpd_context->picture_height_in_pixels + 31) >> 5);
+
+        size <<= 6; /* in unit of 64bytes */
+        gen9_hevc_surface->motion_vector_temporal_bo = dri_bo_alloc(i965->intel.bufmgr,
+                                                                    "motion vector temporal buffer",
+                                                                    size,
+                                                                    0x1000);
+    }
+}
 
 static VAStatus
 gen9_hcpd_hevc_decode_init(VADriverContextP ctx,
@@ -45,6 +84,7 @@ gen9_hcpd_hevc_decode_init(VADriverContextP ctx,
                            struct gen9_hcpd_context *gen9_hcpd_context)
 {
     VAPictureParameterBufferHEVC *pic_param;
+    struct object_surface *obj_surface;
 
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
@@ -60,6 +100,10 @@ gen9_hcpd_hevc_decode_init(VADriverContextP ctx,
     gen9_hcpd_context->picture_width_in_min_cb_minus1 = gen9_hcpd_context->picture_width_in_pixels / gen9_hcpd_context->min_cb_size - 1;
     gen9_hcpd_context->picture_height_in_min_cb_minus1 = gen9_hcpd_context->picture_height_in_pixels / gen9_hcpd_context->min_cb_size - 1;
 
+    /* Current decoded picture */
+    obj_surface = decode_state->render_object;
+    gen9_hcpd_init_hevc_surface(ctx, pic_param, obj_surface, gen9_hcpd_context);
+
     return VA_STATUS_SUCCESS;
 }
 
index 2b228e7..e30a3f0 100644 (file)
@@ -52,4 +52,12 @@ extern void gen_free_avc_surface(void **data);
 
 extern int intel_format_convert(float src, int out_int_bits, int out_frac_bits,int out_sign_flag);
 
+typedef struct gen_hevc_surface GenHevcSurface;
+struct gen_hevc_surface
+{
+    dri_bo *motion_vector_temporal_bo;
+};
+
+extern void gen_free_hevc_surface(void **data);
+
 #endif /* INTEL_MEDIA_H */
index 504f9d9..f0e1cae 100644 (file)
@@ -82,3 +82,28 @@ int intel_format_convert(float src, int out_int_bits, int out_frac_bits,int out_
      }
      return output_value;
 }
+
+static pthread_mutex_t free_hevc_surface_lock = PTHREAD_MUTEX_INITIALIZER;
+
+void
+gen_free_hevc_surface(void **data)
+{
+    GenHevcSurface *hevc_surface;
+
+    pthread_mutex_lock(&free_hevc_surface_lock);
+
+    hevc_surface = *data;
+
+    if (!hevc_surface) {
+        pthread_mutex_unlock(&free_hevc_surface_lock);
+        return;
+    }
+
+    dri_bo_unreference(hevc_surface->motion_vector_temporal_bo);
+    hevc_surface->motion_vector_temporal_bo = NULL;
+
+    free(hevc_surface);
+    *data = NULL;
+
+    pthread_mutex_unlock(&free_hevc_surface_lock);
+}