From c59628d11b134fc016388a170880f7646e100d6f Mon Sep 17 00:00:00 2001 From: Boyuan Zhang Date: Mon, 15 Aug 2016 13:23:30 -0400 Subject: [PATCH] st/va: enable dual instances encode by sync surface MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Christian König --- 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 b18745273c1..87567be10e7 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 63727b6355d..012e48eb32f 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 dba0d4a7251..e9ccdbf7263 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.11.0