Calculate the required space of batch buffer to avoid buffer overflow in encoding
authorZhao Yakui <yakui.zhao@intel.com>
Fri, 8 Nov 2013 07:36:28 +0000 (15:36 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Wed, 13 Nov 2013 07:33:37 +0000 (15:33 +0800)
The required size is based on the number of macroblocks and slice parameter.
Then it can avoid that too large buffer is allocated or possible overflow.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
(cherry picked from commit 8acdfd023e50af37a5642e2517683c34accd78b0)

src/gen6_mfc.c
src/gen6_mfc.h
src/gen75_mfc.c

index 4d13e1f..d6b66b3 100644 (file)
@@ -528,6 +528,7 @@ gen6_mfc_init(VADriverContextP ctx,
     int i;
     int width_in_mbs = 0;
     int height_in_mbs = 0;
+    int slice_batchbuffer_size;
 
     if (encoder_context->codec == CODEC_H264) {
         VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
@@ -542,6 +543,9 @@ gen6_mfc_init(VADriverContextP ctx,
         height_in_mbs = ALIGN(pSequenceParameter->picture_height, 16) / 16;
     }
 
+    slice_batchbuffer_size = 64 * width_in_mbs * height_in_mbs + 4096 +
+               (SLICE_HEADER + SLICE_TAIL) * encode_state->num_slice_params_ext;
+
     /*Encode common setup for MFC*/
     dri_bo_unreference(mfc_context->post_deblocking_output.bo);
     mfc_context->post_deblocking_output.bo = NULL;
@@ -608,7 +612,8 @@ gen6_mfc_init(VADriverContextP ctx,
     if (mfc_context->aux_batchbuffer)
         intel_batchbuffer_free(mfc_context->aux_batchbuffer);
 
-    mfc_context->aux_batchbuffer = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD, 0);
+    mfc_context->aux_batchbuffer = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD,
+                                                        slice_batchbuffer_size);
     mfc_context->aux_batchbuffer_surface.bo = mfc_context->aux_batchbuffer->buffer;
     dri_bo_reference(mfc_context->aux_batchbuffer_surface.bo);
     mfc_context->aux_batchbuffer_surface.pitch = 16;
index 1b71218..6a5777f 100644 (file)
@@ -42,6 +42,13 @@ struct encode_state;
 
 #define INTRA_MB_FLAG_MASK              0x00002000
 
+/* The space required for slice header SLICE_STATE + header.
+ * Is it enough? */
+#define SLICE_HEADER                   80
+
+/* the space required for slice tail. */
+#define SLICE_TAIL                     16
+
 #define __SOFTWARE__    0
 
 #define SURFACE_STATE_PADDED_SIZE_0_GEN7        ALIGN(sizeof(struct gen7_surface_state), 32)
index 93cf30f..e16e649 100644 (file)
@@ -427,6 +427,7 @@ static void gen75_mfc_init(VADriverContextP ctx,
     int i;
     int width_in_mbs = 0;
     int height_in_mbs = 0;
+    int slice_batchbuffer_size;
 
     if (encoder_context->codec == CODEC_H264) {
         VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
@@ -441,6 +442,9 @@ static void gen75_mfc_init(VADriverContextP ctx,
         height_in_mbs = ALIGN(pSequenceParameter->picture_height, 16) / 16;
     }
 
+    slice_batchbuffer_size = 64 * width_in_mbs * height_in_mbs + 4096 +
+               (SLICE_HEADER + SLICE_TAIL) * encode_state->num_slice_params_ext;
+
     /*Encode common setup for MFC*/
     dri_bo_unreference(mfc_context->post_deblocking_output.bo);
     mfc_context->post_deblocking_output.bo = NULL;
@@ -507,7 +511,8 @@ static void gen75_mfc_init(VADriverContextP ctx,
     if (mfc_context->aux_batchbuffer)
         intel_batchbuffer_free(mfc_context->aux_batchbuffer);
 
-    mfc_context->aux_batchbuffer = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD, 0);
+    mfc_context->aux_batchbuffer = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD,
+                                                       slice_batchbuffer_size);
     mfc_context->aux_batchbuffer_surface.bo = mfc_context->aux_batchbuffer->buffer;
     dri_bo_reference(mfc_context->aux_batchbuffer_surface.bo);
     mfc_context->aux_batchbuffer_surface.pitch = 16;