[Libva] [PATCH v3 intel-driver 6/9] decoder: h264: enable Picture ID Remapping on Haswell and newer.

Zhao, Yakui yakui.zhao at intel.com
Tue Jun 3 18:47:22 PDT 2014


On Tue, 2014-06-03 at 10:43 -0600, Gwenole Beauchesne wrote:
> Fill and submit MFX_AVC_PICID_STATE commands to Gen7.5+ hardware.
> This optimizes the management of the DPB as the binding array can
> now contain entries in any order. This also makes it possible to
> support H.264 MultiView High profiles, with any particular number
> of views.
> 
> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
> ---
>  src/gen75_mfd.c          |   23 +++--------
>  src/gen8_mfd.c           |   27 ++++---------
>  src/i965_decoder_utils.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++
>  src/i965_decoder_utils.h |   23 +++++++++++
>  4 files changed, 135 insertions(+), 36 deletions(-)
> 
> diff --git a/src/gen75_mfd.c b/src/gen75_mfd.c
> index 01db56c..b080fb8 100644
> --- a/src/gen75_mfd.c
> +++ b/src/gen75_mfd.c
> @@ -632,25 +632,13 @@ gen75_mfd_avc_qm_state(VADriverContextP ctx,
>      }
>  }
>  
> -static void
> +static inline void
>  gen75_mfd_avc_picid_state(VADriverContextP ctx,
>                        struct decode_state *decode_state,
>                        struct gen7_mfd_context *gen7_mfd_context)
>  {
> -    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
> -
> -    BEGIN_BCS_BATCH(batch, 10);
> -    OUT_BCS_BATCH(batch, MFD_AVC_PICID_STATE | (10 - 2));
> -    OUT_BCS_BATCH(batch, 1); // disable Picture ID Remapping
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    ADVANCE_BCS_BATCH(batch);
> +    gen75_send_avc_picid_state(gen7_mfd_context->base.batch,
> +        gen7_mfd_context->reference_surface);
>  }
>  
>  static void
> @@ -1054,7 +1042,8 @@ gen75_mfd_avc_decode_init(VADriverContextP ctx,
>  
>      assert(decode_state->pic_param && decode_state->pic_param->buffer);
>      pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
> -    intel_update_avc_frame_store_index(ctx, decode_state, pic_param, gen7_mfd_context->reference_surface);
> +    gen75_update_avc_frame_store_index(ctx, decode_state, pic_param,
> +        gen7_mfd_context->reference_surface);
>      width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
>      height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1;
>      assert(width_in_mbs > 0 && width_in_mbs <= 256); /* 4K */
> @@ -1139,8 +1128,8 @@ gen75_mfd_avc_decode_picture(VADriverContextP ctx,
>      gen75_mfd_pipe_buf_addr_state(ctx, decode_state, MFX_FORMAT_AVC, gen7_mfd_context);
>      gen75_mfd_bsp_buf_base_addr_state(ctx, decode_state, MFX_FORMAT_AVC, gen7_mfd_context);
>      gen75_mfd_avc_qm_state(ctx, decode_state, gen7_mfd_context);
> -    gen75_mfd_avc_img_state(ctx, decode_state, gen7_mfd_context);
>      gen75_mfd_avc_picid_state(ctx, decode_state, gen7_mfd_context);
> +    gen75_mfd_avc_img_state(ctx, decode_state, gen7_mfd_context);
>  
>      for (j = 0; j < decode_state->num_slice_params; j++) {
>          assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
> diff --git a/src/gen8_mfd.c b/src/gen8_mfd.c
> index 622e0f3..4e0a95a 100644
> --- a/src/gen8_mfd.c
> +++ b/src/gen8_mfd.c
> @@ -499,25 +499,13 @@ gen8_mfd_avc_qm_state(VADriverContextP ctx,
>      }
>  }
>  
> -static void
> +static inline void
>  gen8_mfd_avc_picid_state(VADriverContextP ctx,
> -                      struct decode_state *decode_state,
> -                      struct gen7_mfd_context *gen7_mfd_context)
> +    struct decode_state *decode_state,
> +    struct gen7_mfd_context *gen7_mfd_context)
>  {
> -    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
> -
> -    BEGIN_BCS_BATCH(batch, 10);
> -    OUT_BCS_BATCH(batch, MFD_AVC_PICID_STATE | (10 - 2));
> -    OUT_BCS_BATCH(batch, 1); // disable Picture ID Remapping
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    ADVANCE_BCS_BATCH(batch);
> +    gen75_send_avc_picid_state(gen7_mfd_context->base.batch,
> +        gen7_mfd_context->reference_surface);
>  }
>  
>  static void
> @@ -827,7 +815,8 @@ gen8_mfd_avc_decode_init(VADriverContextP ctx,
>  
>      assert(decode_state->pic_param && decode_state->pic_param->buffer);
>      pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
> -    intel_update_avc_frame_store_index(ctx, decode_state, pic_param, gen7_mfd_context->reference_surface);
> +    gen75_update_avc_frame_store_index(ctx, decode_state, pic_param,
> +        gen7_mfd_context->reference_surface);
>      width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
>      height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1;
>      assert(width_in_mbs > 0 && width_in_mbs <= 256); /* 4K */
> @@ -912,8 +901,8 @@ gen8_mfd_avc_decode_picture(VADriverContextP ctx,
>      gen8_mfd_pipe_buf_addr_state(ctx, decode_state, MFX_FORMAT_AVC, gen7_mfd_context);
>      gen8_mfd_bsp_buf_base_addr_state(ctx, decode_state, MFX_FORMAT_AVC, gen7_mfd_context);
>      gen8_mfd_avc_qm_state(ctx, decode_state, gen7_mfd_context);
> -    gen8_mfd_avc_img_state(ctx, decode_state, gen7_mfd_context);
>      gen8_mfd_avc_picid_state(ctx, decode_state, gen7_mfd_context);
> +    gen8_mfd_avc_img_state(ctx, decode_state, gen7_mfd_context);
>  
>      for (j = 0; j < decode_state->num_slice_params; j++) {
>          assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
> diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
> index 13b717d..22d5b6f 100644
> --- a/src/i965_decoder_utils.c
> +++ b/src/i965_decoder_utils.c
> @@ -252,6 +252,23 @@ avc_gen_default_iq_matrix(VAIQMatrixBufferH264 *iq_matrix)
>      memset(&iq_matrix->ScalingList8x8, 16, sizeof(iq_matrix->ScalingList8x8));
>  }
>  
> +/* Returns a unique picture ID that represents the supplied VA surface object */
> +int
> +avc_get_picture_id(struct object_surface *obj_surface)
> +{
> +    int pic_id;
> +
> +    /* This highly depends on how the internal organization of VA objects.
> +
> +       The VA objects are maintained in heaps so that any released VA
> +       surface will become free again for future allocation. This means
> +       that holes in there are filled in for subsequent allocations.
> +       So, this ultimately means that we could just use the Heap ID of
> +       the VA surface as the resulting picture ID (16 bits) */
> +    pic_id = 1 + (obj_surface->base.id & OBJECT_HEAP_ID_MASK);

The OBJECT_HEAP_ID_MASK is 0xFFFFFF. Maybe the pic_id will be greater
than 0xFFFF. So please directly use the 0xFFFF mask.

> +    return (pic_id <= 0xffff) ? pic_id : -1;
> +}
> +
>  /* Finds the VA/H264 picture associated with the specified VA surface id */
>  VAPictureH264 *
>  avc_find_picture(VASurfaceID id, VAPictureH264 *pic_list, int pic_list_count)
> @@ -508,6 +525,87 @@ intel_update_avc_frame_store_index(
>  }
>  
>  void
> +gen75_update_avc_frame_store_index(
> +    VADriverContextP              ctx,
> +    struct decode_state          *decode_state,
> +    VAPictureParameterBufferH264 *pic_param,
> +    GenFrameStore                 frame_store[MAX_GEN_REFERENCE_FRAMES]
> +)
> +{
> +    int i, n;
> +
> +    /* Construct the Frame Store array */
> +    for (i = 0, n = 0; i < ARRAY_ELEMS(decode_state->reference_objects); i++) {
> +        struct object_surface * const obj_surface =
> +            decode_state->reference_objects[i];
> +        if (!obj_surface)
> +            continue;
> +
> +        GenFrameStore * const fs = &frame_store[n];
> +        fs->surface_id = obj_surface->base.id;
> +        fs->obj_surface = obj_surface;
> +        fs->frame_store_id = n++;
> +    }
> +
> +    /* Any remaining entry is invalid */
> +    for (; n < MAX_GEN_REFERENCE_FRAMES; n++) {
> +        GenFrameStore * const fs = &frame_store[n];
> +        fs->surface_id = VA_INVALID_ID;
> +        fs->obj_surface = NULL;
> +        fs->frame_store_id = -1;
> +    }
> +}
> +
> +bool
> +gen75_fill_avc_picid_list(
> +    uint16_t                            pic_ids[16],
> +    GenFrameStore                       frame_store[MAX_GEN_REFERENCE_FRAMES]
> +)
> +{
> +    int i, pic_id;
> +
> +    /* Fill in with known picture IDs. The Frame Store array is in
> +       compact form, i.e. empty entries are only to be found at the
> +       end of the array: there are no holes in the set of active
> +       reference frames */
> +    for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
> +        GenFrameStore * const fs = &frame_store[i];
> +        if (!fs->obj_surface)
> +            break;
> +        pic_id = avc_get_picture_id(fs->obj_surface);
> +        if (pic_id < 0)
> +            return false;

the below assert of "fs->frame_store_id == i " be removed. 

> +        assert(fs->frame_store_id == i);
> +        pic_ids[i] = pic_id;
> +    }
> +
> +    /* When an element of the list is not relevant the value of the
> +       picture ID shall be set to 0 */
> +    for (; i < MAX_GEN_REFERENCE_FRAMES; i++)
> +        pic_ids[i] = 0;
> +    return true;
> +}
> +
> +bool
> +gen75_send_avc_picid_state(
> +    struct intel_batchbuffer           *batch,
> +    GenFrameStore                       frame_store[MAX_GEN_REFERENCE_FRAMES]
> +)
> +{
> +    uint16_t pic_ids[16];
> +
> +    if (!gen75_fill_avc_picid_list(pic_ids, frame_store))
> +        return false;
> +
> +    BEGIN_BCS_BATCH(batch, 10);
> +    OUT_BCS_BATCH(batch, MFD_AVC_PICID_STATE | (10 - 2));
> +    OUT_BCS_BATCH(batch, 0); // enable Picture ID Remapping
> +    intel_batchbuffer_data(batch, pic_ids, sizeof(pic_ids));
> +    ADVANCE_BCS_BATCH(batch);
> +    return true;
> +}
> +
> +void
>  intel_update_vc1_frame_store_index(VADriverContextP ctx,
>                                     struct decode_state *decode_state,
>                                     VAPictureParameterBufferVC1 *pic_param,
> diff --git a/src/i965_decoder_utils.h b/src/i965_decoder_utils.h
> index a4c9415..0ffbd7f 100644
> --- a/src/i965_decoder_utils.h
> +++ b/src/i965_decoder_utils.h
> @@ -54,6 +54,9 @@ avc_ensure_surface_bo(
>  void
>  avc_gen_default_iq_matrix(VAIQMatrixBufferH264 *iq_matrix);
>  
> +int
> +avc_get_picture_id(struct object_surface *obj_surface);
> +
>  VAPictureH264 *
>  avc_find_picture(VASurfaceID id, VAPictureH264 *pic_list, int pic_list_count);
>  
> @@ -98,6 +101,26 @@ intel_update_avc_frame_store_index(VADriverContextP ctx,
>                                     GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]);
>  
>  void
> +gen75_update_avc_frame_store_index(
> +    VADriverContextP                    ctx,
> +    struct decode_state                *decode_state,
> +    VAPictureParameterBufferH264       *pic_param,
> +    GenFrameStore                       frame_store[MAX_GEN_REFERENCE_FRAMES]
> +);
> +
> +bool
> +gen75_fill_avc_picid_list(
> +    uint16_t                            pic_ids[16],
> +    GenFrameStore                       frame_store[MAX_GEN_REFERENCE_FRAMES]
> +);
> +
> +bool
> +gen75_send_avc_picid_state(
> +    struct intel_batchbuffer           *batch,
> +    GenFrameStore                       frame_store[MAX_GEN_REFERENCE_FRAMES]
> +);
> +
> +void
>  intel_update_vc1_frame_store_index(VADriverContextP ctx,
>                                     struct decode_state *decode_state,
>                                     VAPictureParameterBufferVC1 *pic_param,




More information about the Libva mailing list