[Mesa-dev] [PATCH 1/2] st/va: enable dual instances encode by sync surface

Andy Furniss adf.lists at gmail.com
Sun Aug 21 20:40:18 UTC 2016


Boyuan Zhang wrote:
> This patch improves the performance of Vaapi Encode by enabling dual instances encoding. flush function is not called after each end_frame call. radeon/vce will do flush whenever 2 frames are submitted for encoding. Implement sync surface function to flush only if the frame hasn't been flushed yet.

Sorry I didn't see this before it went in, but it breaks cqp encoding on 
tonga. cbr seems OK (but is slower than cqp).

Not every run will be corrupt. On runs that are the corruption seems to 
be on/around IDR frames, though that's just a guess judging by frequency.

Unrelated but relevant for future as gstreamer changed default from 
baseline to high. I see vainfo is advertising main/high, it didn't in 
the past.

Easy to patch the driver to fix this, but it breaks omx, and omx seems 
to work with high (well b-frames) anyway.



> Signed-off-by: Boyuan Zhang <boyuan.zhang at amd.com>
> Reviewed-by: Christian König <christian.koenig at amd.com>
> ---
>   src/gallium/state_trackers/va/picture.c    | 12 ++++++++---
>   src/gallium/state_trackers/va/surface.c    | 32 ++++++++++++++++++++++++++++++
>   src/gallium/state_trackers/va/va_private.h |  5 +++++
>   3 files changed, 46 insertions(+), 3 deletions(-)
>
> diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c
> index b187452..87567be 100644
> --- a/src/gallium/state_trackers/va/picture.c
> +++ b/src/gallium/state_trackers/va/picture.c
> @@ -62,6 +62,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
>      if (!surf || !surf->buffer)
>         return VA_STATUS_ERROR_INVALID_SURFACE;
>
> +   context->target_id = render_target;
> +   surf->ctx = context_id;
>      context->target = surf->buffer;
>
>      if (!context->decoder) {
> @@ -536,6 +538,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
>      vlVaDriver *drv;
>      vlVaContext *context;
>      vlVaBuffer *coded_buf;
> +   vlVaSurface *surf;
>      unsigned int coded_size;
>      void *feedback;
>
> @@ -560,6 +563,8 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
>         return VA_STATUS_SUCCESS;
>      }
>
> +   pipe_mutex_lock(drv->mutex);
> +   surf = handle_table_get(drv->htab, context->target_id);
>      context->mpeg4.frame_num++;
>
>      if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
> @@ -568,13 +573,14 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
>         context->decoder->begin_frame(context->decoder, context->target, &context->desc.base);
>         context->decoder->encode_bitstream(context->decoder, context->target,
>                                            coded_buf->derived_surface.resource, &feedback);
> +      surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt;
> +      surf->feedback = feedback;
> +      surf->coded_buf = coded_buf;
>         context->decoder->end_frame(context->decoder, context->target, &context->desc.base);
> -      context->decoder->flush(context->decoder);
> -      context->decoder->get_feedback(context->decoder, feedback, &coded_size);
> -      coded_buf->coded_size = coded_size;
>      }
>      else
>         context->decoder->end_frame(context->decoder, context->target, &context->desc.base);
>
> +   pipe_mutex_unlock(drv->mutex);
>      return VA_STATUS_SUCCESS;
>   }
> diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c
> index 63727b6..012e48e 100644
> --- a/src/gallium/state_trackers/va/surface.c
> +++ b/src/gallium/state_trackers/va/surface.c
> @@ -91,9 +91,41 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur
>   VAStatus
>   vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target)
>   {
> +   vlVaDriver *drv;
> +   vlVaContext *context;
> +   vlVaSurface *surf;
> +   void *pbuff;
> +
>      if (!ctx)
>         return VA_STATUS_ERROR_INVALID_CONTEXT;
>
> +   drv = VL_VA_DRIVER(ctx);
> +   if (!drv)
> +      return VA_STATUS_ERROR_INVALID_CONTEXT;
> +
> +   pipe_mutex_lock(drv->mutex);
> +   surf = handle_table_get(drv->htab, render_target);
> +
> +   if (!surf || !surf->buffer)
> +      return VA_STATUS_ERROR_INVALID_SURFACE;
> +
> +   context = handle_table_get(drv->htab, surf->ctx);
> +   if (!context) {
> +      pipe_mutex_unlock(drv->mutex);
> +      return VA_STATUS_ERROR_INVALID_CONTEXT;
> +   }
> +
> +   if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
> +      int frame_diff;
> +      if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt)
> +         frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt;
> +      else
> +         frame_diff = 0xFFFFFFFF - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt;
> +      if (frame_diff < 2)
> +         context->decoder->flush(context->decoder);
> +      context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size));
> +   }
> +   pipe_mutex_unlock(drv->mutex);
>      return VA_STATUS_SUCCESS;
>   }
>
> diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
> index 6d3ac38..bfcea6d 100644
> --- a/src/gallium/state_trackers/va/va_private.h
> +++ b/src/gallium/state_trackers/va/va_private.h
> @@ -243,6 +243,7 @@ typedef struct {
>
>      struct vl_deint_filter *deint;
>      struct vlVaBuffer *coded_buf;
> +   int target_id;
>   } vlVaContext;
>
>   typedef struct {
> @@ -268,6 +269,10 @@ typedef struct {
>   typedef struct {
>      struct pipe_video_buffer templat, *buffer;
>      struct util_dynarray subpics; /* vlVaSubpicture */
> +   VAContextID ctx;
> +   vlVaBuffer *coded_buf;
> +   void *feedback;
> +   unsigned int frame_num_cnt;
>   } vlVaSurface;
>
>   // Public functions:
>



More information about the mesa-dev mailing list