[Mesa-dev,2/2] st/va: fix gop size for rate control

Submitted by Zhang, Boyuan on Nov. 24, 2016, 7:35 p.m.

Details

Message ID 1480016119-5555-2-git-send-email-boyuan.zhang@amd.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Zhang, Boyuan Nov. 24, 2016, 7:35 p.m.
From: Boyuan Zhang <boyuan.zhang@amd.com>

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 <boyuan.zhang@amd.com>
---
 src/gallium/state_trackers/va/picture.c    | 18 ++++++++++++------
 src/gallium/state_trackers/va/va_private.h |  2 ++
 2 files changed, 14 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c
index 592cdef..b5b9a83 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 9e3ba03..900abbc 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 {