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.zh...@amd.com>
Reviewed-by: Christian König <christian.koe...@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:


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to