[Libva] [PATCH 2/4] HEVC encoder: use generic rate control parameters

Mark Thompson sw at jkqxz.net
Thu Dec 8 22:57:19 UTC 2016


Signed-off-by: Mark Thompson <sw at jkqxz.net>
---
 src/gen9_mfc.h      |  6 -----
 src/gen9_mfc_hevc.c | 67 +++++----------------------------------------
 src/i965_encoder.c  | 78 +++++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 80 insertions(+), 71 deletions(-)

diff --git a/src/gen9_mfc.h b/src/gen9_mfc.h
index f7dc572..8e7d5ad 100644
--- a/src/gen9_mfc.h
+++ b/src/gen9_mfc.h
@@ -153,12 +153,6 @@ struct gen9_hcpe_context {
         int target_frame_size[3]; // I,P,B
         double bits_per_frame;
         double qpf_rounding_accumulator;
-
-        double saved_bps;
-        double saved_fps;
-        int saved_intra_period;
-        int saved_ip_period;
-        int saved_idr_period;
     } brc;
 
     struct {
diff --git a/src/gen9_mfc_hevc.c b/src/gen9_mfc_hevc.c
index be5666c..b4eca4f 100644
--- a/src/gen9_mfc_hevc.c
+++ b/src/gen9_mfc_hevc.c
@@ -2214,11 +2214,9 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
 {
     struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context;
     VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
-    VAEncMiscParameterHRD* pParameterHRD = NULL;
-    VAEncMiscParameterBuffer* pMiscParamHRD = NULL;
 
     double bitrate = pSequenceParameter->bits_per_second * 1.0;
-    double framerate = (double)pSequenceParameter->vui_time_scale / (double)pSequenceParameter->vui_num_units_in_tick;
+    double framerate = (double)encoder_context->brc.framerate_num[0] / (double)encoder_context->brc.framerate_den[0];
     int inum = 1, pnum = 0, bnum = 0; /* Gop structure: number of I, P, B frames in the Gop. */
     int intra_period = pSequenceParameter->intra_period;
     int ip_period = pSequenceParameter->ip_period;
@@ -2238,12 +2236,6 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
     qp1_size = qp1_size * bpp;
     qp51_size = qp51_size * bpp;
 
-    if (!encode_state->misc_param[VAEncMiscParameterTypeHRD][0] || !encode_state->misc_param[VAEncMiscParameterTypeHRD][0]->buffer)
-        return;
-
-    pMiscParamHRD = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeHRD][0]->buffer;
-    pParameterHRD = (VAEncMiscParameterHRD*)pMiscParamHRD->data;
-
     if (pSequenceParameter->ip_period) {
         pnum = (intra_period + ip_period - 1) / ip_period - 1;
         bnum = intra_period - inum - pnum;
@@ -2262,7 +2254,7 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
 
     bpf = mfc_context->brc.bits_per_frame = bitrate / framerate;
 
-    if (!pParameterHRD || pParameterHRD->buffer_size <= 0)
+    if (!encoder_context->brc.hrd_buffer_size)
     {
         mfc_context->hrd.buffer_size = bitrate * ratio;
         mfc_context->hrd.current_buffer_fullness =
@@ -2270,7 +2262,7 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
             bitrate * ratio/2 : mfc_context->hrd.buffer_size / 2.;
     }else
     {
-        buffer_size = (double)pParameterHRD->buffer_size ;
+        buffer_size = (double)encoder_context->brc.hrd_buffer_size;
         if(buffer_size < bitrate * ratio_min)
         {
             buffer_size = bitrate * ratio_min;
@@ -2279,11 +2271,11 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state,
             buffer_size = bitrate * ratio_max ;
         }
         mfc_context->hrd.buffer_size =buffer_size;
-        if(pParameterHRD->initial_buffer_fullness > 0)
+        if(encoder_context->brc.hrd_initial_buffer_fullness)
         {
             mfc_context->hrd.current_buffer_fullness =
-                (double)(pParameterHRD->initial_buffer_fullness < mfc_context->hrd.buffer_size) ?
-                pParameterHRD->initial_buffer_fullness : mfc_context->hrd.buffer_size / 2.;
+                (double)(encoder_context->brc.hrd_initial_buffer_fullness < mfc_context->hrd.buffer_size) ?
+                encoder_context->brc.hrd_initial_buffer_fullness : mfc_context->hrd.buffer_size / 2.;
         }else
         {
             mfc_context->hrd.current_buffer_fullness = mfc_context->hrd.buffer_size / 2.;
@@ -2519,51 +2511,6 @@ int intel_hcpe_interlace_check(VADriverContextP ctx,
     return 1;
 }
 
-/*
- * Check whether the parameters related with CBR are updated and decide whether
- * it needs to reinitialize the configuration related with CBR.
- * Currently it will check the following parameters:
- *      bits_per_second
- *      frame_rate
- *      gop_configuration(intra_period, ip_period, intra_idr_period)
- */
-static bool intel_hcpe_brc_updated_check(struct encode_state *encode_state,
-        struct intel_encoder_context *encoder_context)
-{
-    /* to do */
-    unsigned int rate_control_mode = encoder_context->rate_control_mode;
-    struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context;
-    double cur_fps, cur_bitrate;
-    VAEncSequenceParameterBufferHEVC *pSequenceParameter;
-
-
-    if (rate_control_mode != VA_RC_CBR) {
-        return false;
-    }
-
-    pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
-
-    cur_bitrate = pSequenceParameter->bits_per_second;
-    cur_fps = (double)pSequenceParameter->vui_time_scale /
-              (double)pSequenceParameter->vui_num_units_in_tick;
-
-    if ((cur_bitrate == mfc_context->brc.saved_bps) &&
-        (cur_fps == mfc_context->brc.saved_fps) &&
-        (pSequenceParameter->intra_period == mfc_context->brc.saved_intra_period) &&
-        (pSequenceParameter->intra_idr_period == mfc_context->brc.saved_idr_period) &&
-        (pSequenceParameter->intra_period == mfc_context->brc.saved_intra_period)) {
-        /* the parameters related with CBR are not updaetd */
-        return false;
-    }
-
-    mfc_context->brc.saved_ip_period = pSequenceParameter->ip_period;
-    mfc_context->brc.saved_intra_period = pSequenceParameter->intra_period;
-    mfc_context->brc.saved_idr_period = pSequenceParameter->intra_idr_period;
-    mfc_context->brc.saved_fps = cur_fps;
-    mfc_context->brc.saved_bps = cur_bitrate;
-    return true;
-}
-
 void intel_hcpe_brc_prepare(struct encode_state *encode_state,
                             struct intel_encoder_context *encoder_context)
 {
@@ -2574,7 +2521,7 @@ void intel_hcpe_brc_prepare(struct encode_state *encode_state,
         bool brc_updated;
         assert(encoder_context->codec != CODEC_MPEG2);
 
-        brc_updated = intel_hcpe_brc_updated_check(encode_state, encoder_context);
+        brc_updated = encoder_context->brc.need_reset;
 
         /*Programing bit rate control */
         if ((mfc_context->bit_rate_control_context[HEVC_SLICE_I].MaxSizeInWord == 0) ||
diff --git a/src/i965_encoder.c b/src/i965_encoder.c
index 75a6a1f..fc2557a 100644
--- a/src/i965_encoder.c
+++ b/src/i965_encoder.c
@@ -436,19 +436,87 @@ intel_encoder_check_brc_vp8_sequence_parameter(VADriverContextP ctx,
 }
 
 static VAStatus
+intel_encoder_check_brc_hevc_sequence_parameter(VADriverContextP ctx,
+                                                struct encode_state *encode_state,
+                                                struct intel_encoder_context *encoder_context)
+{
+    VAEncSequenceParameterBufferHEVC *seq_param = (VAEncSequenceParameterBufferHEVC*)encode_state->seq_param_ext->buffer;
+    unsigned int framerate_num, framerate_den;
+    unsigned int gop_size, num_iframes_in_gop, num_pframes_in_gop, num_bframes_in_gop;
+
+    if (!encoder_context->is_new_sequence)
+        return VA_STATUS_SUCCESS;
+    if (!seq_param)
+        return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+    if (!seq_param->vui_time_scale || !seq_param->vui_num_units_in_tick) {
+        framerate_num = 30;
+        framerate_den = 1;
+    } else {
+        framerate_num = seq_param->vui_time_scale;
+        framerate_den = seq_param->vui_num_units_in_tick;
+    }
+    reduce_fraction(&framerate_num, &framerate_den);
+
+    num_iframes_in_gop = 1;
+    if (seq_param->intra_period == 0) {
+        gop_size = -1;
+        num_pframes_in_gop = -1;
+    } else if (seq_param->intra_period == 1) {
+        gop_size = 1;
+        num_pframes_in_gop = 0;
+    } else {
+        gop_size = seq_param->intra_period;
+        num_pframes_in_gop = (seq_param->intra_period + seq_param->ip_period - 1) / seq_param->ip_period - 1;
+    }
+    num_bframes_in_gop = gop_size - num_iframes_in_gop - num_pframes_in_gop;
+
+    if (encoder_context->brc.framerate_num[0] != framerate_num ||
+        encoder_context->brc.framerate_den[0] != framerate_den) {
+        encoder_context->brc.framerate_num[0] = framerate_num;
+        encoder_context->brc.framerate_den[0] = framerate_den;
+        encoder_context->brc.need_reset = 1;
+    }
+
+    if (encoder_context->brc.gop_size != gop_size ||
+        encoder_context->brc.num_iframes_in_gop != num_iframes_in_gop ||
+        encoder_context->brc.num_pframes_in_gop != num_pframes_in_gop ||
+        encoder_context->brc.num_bframes_in_gop != num_bframes_in_gop) {
+        encoder_context->brc.gop_size = gop_size;
+        encoder_context->brc.num_iframes_in_gop = num_iframes_in_gop;
+        encoder_context->brc.num_pframes_in_gop = num_pframes_in_gop;
+        encoder_context->brc.num_bframes_in_gop = num_bframes_in_gop;
+        encoder_context->brc.need_reset = 1;
+    }
+
+    if (encoder_context->brc.bits_per_second[0] != seq_param->bits_per_second) {
+        encoder_context->brc.bits_per_second[0] = seq_param->bits_per_second;
+        encoder_context->brc.need_reset = 1;
+    }
+
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
 intel_encoder_check_brc_sequence_parameter(VADriverContextP ctx,
                                            struct encode_state *encode_state,
                                            struct intel_encoder_context *encoder_context)
 {
-    if (encoder_context->codec == CODEC_H264 ||
-        encoder_context->codec == CODEC_H264_MVC)
+    switch (encoder_context->codec) {
+    case CODEC_H264:
+    case CODEC_H264_MVC:
         return intel_encoder_check_brc_h264_sequence_parameter(ctx, encode_state, encoder_context);
 
-    if (encoder_context->codec == CODEC_VP8)
+    case CODEC_VP8:
         return intel_encoder_check_brc_vp8_sequence_parameter(ctx, encode_state, encoder_context);
 
-    // TODO: other codecs
-    return VA_STATUS_SUCCESS;
+    case CODEC_HEVC:
+        return intel_encoder_check_brc_hevc_sequence_parameter(ctx, encode_state, encoder_context);
+
+    default:
+        // TODO: other codecs
+        return VA_STATUS_SUCCESS;
+    }
 }
 
 static void
-- 
2.10.2


More information about the Libva mailing list