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

Boyuan Zhang boyuan.zhang at amd.com
Mon Aug 15 21:58:32 UTC 2016


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.

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:
-- 
2.7.4



More information about the mesa-dev mailing list