[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