[Libva] [PATCH v2 10/12] VP8 HWEnc: Fix the coded buffer size error issue

Zhong Li zhong.li at intel.com
Tue Jan 13 21:03:41 PST 2015


It seems the last partition size in vp8 status buffer is a little smaller
than reality. so add 3 extra bytes.
Otherwise, the Google software decoder(libvpx) may report frames corrupted,
even can't decode.

Signed-off-by: Zhong Li <zhong.li at intel.com>
---
 src/gen8_mfc.c | 20 ++++++++++++++------
 src/gen9_mfc.c | 19 +++++++++++++------
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c
index b5f00eb..66e10cd 100644
--- a/src/gen8_mfc.c
+++ b/src/gen8_mfc.c
@@ -4045,19 +4045,27 @@ static void gen8_mfc_calc_vp8_coded_buffer_size(VADriverContextP ctx,
                           struct encode_state *encode_state,
                           struct intel_encoder_context *encoder_context)
 {
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
     VAEncPictureParameterBufferVP8 *pic_param = (VAEncPictureParameterBufferVP8 *)encode_state->pic_param_ext->buffer;
     unsigned char is_intra_frame = !pic_param->pic_flags.bits.frame_type;
-    unsigned int *vp8_encoding_status, first_partition_bytes, token_partition_bytes, vp8_coded_bytes;
+    unsigned int *vp8_encoding_status, i, first_partition_bytes, token_partition_bytes, vp8_coded_bytes;
+    
+    int partition_num = 1 << (int)log2(pic_param->pic_flags.bits.num_token_partitions);
+
+    first_partition_bytes = token_partition_bytes = vp8_coded_bytes = 0;
 
     dri_bo_map(mfc_context->vp8_state.token_statistics_bo, 0);
 
     vp8_encoding_status = (unsigned int *)mfc_context->vp8_state.token_statistics_bo->virtual;
-    first_partition_bytes = (*vp8_encoding_status + 7) / 8;
-    token_partition_bytes = (*(unsigned int *)(vp8_encoding_status + 9) + 7) / 8;
-    
-    /*coded_bytes includes P0~P8 partitions bytes + uncompresse date bytes + partion_size bytes in bitstream */
-    vp8_coded_bytes = first_partition_bytes + token_partition_bytes + (3 + 7 * !!is_intra_frame) + (pic_param->pic_flags.bits.num_token_partitions - 1) * 3;
+    first_partition_bytes = (vp8_encoding_status[0] + 7) / 8;
+
+    for (i = 1; i <= partition_num; i++) 
+        token_partition_bytes += (vp8_encoding_status[i] + 7) / 8;
+
+    /*coded_bytes includes P0~P8 partitions bytes + uncompresse date bytes + partion_size bytes in bitstream + 3 extra bytes */
+    /*it seems the last partition size in vp8 status buffer is smaller than reality. so add 3 extra bytes */
+    vp8_coded_bytes = first_partition_bytes + token_partition_bytes + (3 + 7 * !!is_intra_frame) + (partition_num - 1) * 3 + 3;
 
     dri_bo_unmap(mfc_context->vp8_state.token_statistics_bo);
 
diff --git a/src/gen9_mfc.c b/src/gen9_mfc.c
index d54b394..4c926a3 100644
--- a/src/gen9_mfc.c
+++ b/src/gen9_mfc.c
@@ -3199,16 +3199,23 @@ static void gen9_mfc_calc_vp8_coded_buffer_size(VADriverContextP ctx,
     struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
     VAEncPictureParameterBufferVP8 *pic_param = (VAEncPictureParameterBufferVP8 *)encode_state->pic_param_ext->buffer;
     unsigned char is_intra_frame = !pic_param->pic_flags.bits.frame_type;
-    unsigned int *vp8_encoding_status, first_partition_bytes, token_partition_bytes, vp8_coded_bytes;
+    unsigned int *vp8_encoding_status, i, first_partition_bytes, token_partition_bytes, vp8_coded_bytes;
+    
+    int partition_num = 1 << (int)log2(pic_param->pic_flags.bits.num_token_partitions);
+
+    first_partition_bytes = token_partition_bytes = vp8_coded_bytes = 0;
 
     dri_bo_map(mfc_context->vp8_state.token_statistics_bo, 0);
 
     vp8_encoding_status = (unsigned int *)mfc_context->vp8_state.token_statistics_bo->virtual;
-    first_partition_bytes = (*vp8_encoding_status + 7) / 8;
-    token_partition_bytes = (*(unsigned int *)(vp8_encoding_status + 9) + 7) / 8;
-    
-    /*coded_bytes includes P0~P8 partitions bytes + uncompresse date bytes + partion_size bytes in bitstream */
-    vp8_coded_bytes = first_partition_bytes + token_partition_bytes + (3 + 7 * !!is_intra_frame) + (pic_param->pic_flags.bits.num_token_partitions - 1) * 3;
+    first_partition_bytes = (vp8_encoding_status[0] + 7) / 8;
+
+    for (i = 1; i <= partition_num; i++) 
+        token_partition_bytes += (vp8_encoding_status[i] + 7) / 8;
+
+    /*coded_bytes includes P0~P8 partitions bytes + uncompresse date bytes + partion_size bytes in bitstream + 3 extra bytes */
+    /*it seems the last partition size in vp8 status buffer is smaller than reality. so add 3 extra bytes */
+    vp8_coded_bytes = first_partition_bytes + token_partition_bytes + (3 + 7 * !!is_intra_frame) + (partition_num - 1) * 3 + 3;
 
     dri_bo_unmap(mfc_context->vp8_state.token_statistics_bo);
 
-- 
1.9.1



More information about the Libva mailing list