[Libva] [PATCH] vp8: fix support for segmentation-enabled streams.

Gwenole Beauchesne gb.devel at gmail.com
Thu Apr 24 02:34:57 PDT 2014


Pushed to git master and staging branches with minor cosmetics
(comments, function name clarification).

2014-04-23 17:29 GMT+02:00 Gwenole Beauchesne <gb.devel at gmail.com>:
> If segmentation is enabled, then the segmentation map shall be live
> across frames until the current frame updates the segment ids. This
> means that the driver needs to maintain the segmentation map buffer
> allocation and enable writes (resp. reads) whenever necessary.
>
> This fixes decoding of 00-comprehensive-010.ivf.
>
> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
> ---
>  src/gen7_mfd.h           |  1 +
>  src/gen8_mfd.c           | 35 ++++++++++++++++++++++++++++++-----
>  src/i965_decoder_utils.c | 24 ++++++++++++++++++++++++
>  src/i965_decoder_utils.h |  4 ++++
>  4 files changed, 59 insertions(+), 5 deletions(-)
>
> diff --git a/src/gen7_mfd.h b/src/gen7_mfd.h
> index e3111ab..0200216 100644
> --- a/src/gen7_mfd.h
> +++ b/src/gen7_mfd.h
> @@ -85,6 +85,7 @@ struct gen7_mfd_context
>      GenBuffer           bsd_mpc_row_store_scratch_buffer;
>      GenBuffer           mpr_row_store_scratch_buffer;
>      GenBuffer           bitplane_read_buffer;
> +    GenBuffer           segmentation_buffer;
>
>      VASurfaceID jpeg_wa_surface_id;
>      struct object_surface *jpeg_wa_surface_object;
> diff --git a/src/gen8_mfd.c b/src/gen8_mfd.c
> index 177a11d..61a9900 100644
> --- a/src/gen8_mfd.c
> +++ b/src/gen8_mfd.c
> @@ -2789,6 +2789,9 @@ gen8_mfd_vp8_decode_init(VADriverContextP ctx,
>      dri_bo_reference(gen7_mfd_context->pre_deblocking_output.bo);
>      gen7_mfd_context->pre_deblocking_output.valid = pic_param->pic_fields.bits.loop_filter_disable;
>
> +    intel_ensure_segmentation_buffer(ctx,
> +        &gen7_mfd_context->segmentation_buffer, width_in_mbs, height_in_mbs);
> +
>      /* The same as AVC */
>      dri_bo_unreference(gen7_mfd_context->intra_row_store_scratch_buffer.bo);
>      bo = dri_bo_alloc(i965->intel.bufmgr,
> @@ -2842,6 +2845,13 @@ gen8_mfd_vp8_pic_state(VADriverContextP ctx,
>      int i, j,log2num;
>      unsigned int quantization_value[4][6];
>
> +    /* There is no safe way to error out if the segmentation buffer
> +       could not be allocated. So, instead aborting, decode something
> +       even if the result may look totally inacurate */
> +    const unsigned int enable_segmentation =
> +        pic_param->pic_fields.bits.segmentation_enabled &&
> +        gen7_mfd_context->segmentation_buffer.valid;
> +
>      log2num = (int)log2(slice_param->num_of_partitions - 1);
>
>      BEGIN_BCS_BATCH(batch, 38);
> @@ -2858,8 +2868,10 @@ gen8_mfd_vp8_pic_state(VADriverContextP ctx,
>                    pic_param->pic_fields.bits.mb_no_coeff_skip << 10 |
>                    pic_param->pic_fields.bits.update_mb_segmentation_map << 9 |
>                    pic_param->pic_fields.bits.segmentation_enabled << 8 |
> -                  0 << 7 | /* segmentation id streamin disabled */
> -                  0 << 6 | /* segmentation id streamout disabled */
> +                  (enable_segmentation &&
> +                   !pic_param->pic_fields.bits.update_mb_segmentation_map) << 7 |
> +                  (enable_segmentation &&
> +                   pic_param->pic_fields.bits.update_mb_segmentation_map) << 6 |
>                    (pic_param->pic_fields.bits.key_frame == 0 ? 1 : 0) << 5 |    /* 0 indicate an intra frame in VP8 stream/spec($9.1)*/
>                    pic_param->pic_fields.bits.filter_type << 4 |
>                    (pic_param->pic_fields.bits.version == 3) << 1 | /* full pixel mode for version 3 */
> @@ -2954,9 +2966,18 @@ gen8_mfd_vp8_pic_state(VADriverContextP ctx,
>                    (pic_param->loop_filter_deltas_mode[0] & 0x7f) <<  0);
>
>      /* segmentation id stream base address, DW35-DW37 */
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> -    OUT_BCS_BATCH(batch, 0);
> +    if (enable_segmentation) {
> +        OUT_BCS_RELOC(batch, gen7_mfd_context->segmentation_buffer.bo,
> +                      0, I915_GEM_DOMAIN_INSTRUCTION,
> +                      0);
> +        OUT_BCS_BATCH(batch, 0);
> +        OUT_BCS_BATCH(batch, 0);
> +    }
> +    else {
> +        OUT_BCS_BATCH(batch, 0);
> +        OUT_BCS_BATCH(batch, 0);
> +        OUT_BCS_BATCH(batch, 0);
> +    }
>      ADVANCE_BCS_BATCH(batch);
>  }
>
> @@ -3146,6 +3167,9 @@ gen8_mfd_context_destroy(void *hw_context)
>      dri_bo_unreference(gen7_mfd_context->bitplane_read_buffer.bo);
>      gen7_mfd_context->bitplane_read_buffer.bo = NULL;
>
> +    dri_bo_unreference(gen7_mfd_context->segmentation_buffer.bo);
> +    gen7_mfd_context->segmentation_buffer.bo = NULL;
> +
>      dri_bo_unreference(gen7_mfd_context->jpeg_wa_slice_data_bo);
>
>      intel_batchbuffer_free(gen7_mfd_context->base.batch);
> @@ -3178,6 +3202,7 @@ gen8_dec_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
>      }
>
>      gen7_mfd_context->jpeg_wa_surface_id = VA_INVALID_SURFACE;
> +    gen7_mfd_context->segmentation_buffer.valid = 0;
>
>      switch (obj_config->profile) {
>      case VAProfileMPEG2Simple:
> diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
> index 064074f..ae8b762 100644
> --- a/src/i965_decoder_utils.c
> +++ b/src/i965_decoder_utils.c
> @@ -827,3 +827,27 @@ intel_mpeg2_find_next_slice(struct decode_state *decode_state,
>
>      return NULL;
>  }
> +
> +/* Ensure the segmentation buffer is large enough for the supplied
> +   number of MBs, or re-allocate it */
> +bool
> +intel_ensure_segmentation_buffer(VADriverContextP ctx, GenBuffer *buf,
> +    unsigned int mb_width, unsigned int mb_height)
> +{
> +    struct i965_driver_data * const i965 = i965_driver_data(ctx);
> +    /* The segmentation map is a 64-byte aligned linear buffer, with
> +       each cache line holding only 8 bits for 4 continuous MBs */
> +    const unsigned int buf_size = ((mb_width + 3) / 4) * 64 * mb_height;
> +
> +    if (buf->valid) {
> +        if (buf->bo && buf->bo->size >= buf_size)
> +            return true;
> +        drm_intel_bo_unreference(buf->bo);
> +        buf->valid = false;
> +    }
> +
> +    buf->bo = drm_intel_bo_alloc(i965->intel.bufmgr, "segmentation map",
> +        buf_size, 0x1000);
> +    buf->valid = buf->bo != NULL;
> +    return buf->valid;
> +}
> diff --git a/src/i965_decoder_utils.h b/src/i965_decoder_utils.h
> index 8f64dfb..1368af8 100644
> --- a/src/i965_decoder_utils.h
> +++ b/src/i965_decoder_utils.h
> @@ -106,4 +106,8 @@ intel_update_vp8_frame_store_index(VADriverContextP ctx,
>                                     VAPictureParameterBufferVP8 *pic_param,
>                                     GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES]);
>
> +bool
> +intel_ensure_segmentation_buffer(VADriverContextP ctx, GenBuffer *buf,
> +    unsigned int mb_width, unsigned int mb_height);
> +
>  #endif /* I965_DECODER_UTILS_H */
> --
> 1.8.3.2
>


More information about the Libva mailing list