From 3949d7c6ead25e6191c6529a1805ba7ada6892cc Mon Sep 17 00:00:00 2001 From: Boyuan Zhang Date: Fri, 18 Nov 2016 15:29:56 -0500 Subject: [PATCH] st/va: fix gop size for rate control MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang Acked-by: Christian König --- src/gallium/state_trackers/va/picture.c | 18 ++++++++++++------ src/gallium/state_trackers/va/va_private.h | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 592cdefc46c..b5b9a8361b9 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -351,7 +351,11 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; } - context->desc.h264enc.gop_size = h264->intra_idr_period; + + context->gop_coeff = ((1024 + h264->intra_idr_period - 1) / h264->intra_idr_period + 1) / 2 * 2; + if (context->gop_coeff > VL_VA_ENC_GOP_COEFF) + context->gop_coeff = VL_VA_ENC_GOP_COEFF; + context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = 1; return VA_STATUS_SUCCESS; @@ -391,10 +395,10 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.not_referenced = false; context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; - if (context->desc.h264enc.is_idr) - context->desc.h264enc.i_remain = 1; - else - context->desc.h264enc.i_remain = 0; + if (context->desc.h264enc.gop_cnt == 0) + context->desc.h264enc.i_remain = context->gop_coeff; + else if (context->desc.h264enc.frame_num == 1) + context->desc.h264enc.i_remain--; context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; @@ -578,6 +582,8 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->end_frame(context->decoder, context->target, &context->desc.base); if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + int idr_period = context->desc.h264enc.gop_size / context->gop_coeff; + int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->force_flushed = false; if (context->first_single_submitted) { @@ -585,7 +591,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->first_single_submitted = false; surf->force_flushed = true; } - if (context->desc.h264enc.p_remain == 1) { + if (p_remain_in_idr == 1) { if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { context->decoder->flush(context->decoder); context->first_single_submitted = true; diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 9e3ba038778..900abbc5904 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -50,6 +50,7 @@ #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) #define VL_VA_MAX_IMAGE_FORMATS 9 +#define VL_VA_ENC_GOP_COEFF 16 static inline enum pipe_video_chroma_format ChromaToPipe(int format) @@ -245,6 +246,7 @@ typedef struct { struct vlVaBuffer *coded_buf; int target_id; bool first_single_submitted; + int gop_coeff; } vlVaContext; typedef struct { -- 2.30.2