[Pkg-gstreamer-commits] [gstreamer-vaapi] 150/176: encoder: h264: fix default CPB buffer size.

Vincent Cheng vcheng at moszumanska.debian.org
Tue Jun 3 08:09:36 UTC 2014


This is an automated email from the git hooks/post-receive script.

vcheng pushed a commit to branch upstream
in repository gstreamer-vaapi.

commit 9d5fc53899fc05eecc4d7202946e0098427ba8a5
Author: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
Date:   Tue Jan 21 19:04:41 2014 +0100

    encoder: h264: fix default CPB buffer size.
    
    Fix default CPB buffer size to something more reasonable (1500 ms)
    and that still fits the level limits. This is a non configurable
    property for now. The initial CPB removal delay is also fixed to
    750 ms.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=722087
---
 gst-libs/gst/vaapi/gstvaapiencoder_h264.c    | 52 +++++++++++++++++++++++-----
 gst-libs/gst/vaapi/gstvaapiencoder_h264.h    |  3 ++
 gst-libs/gst/vaapi/gstvaapiutils_h264.c      | 36 +++++++++----------
 gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h |  2 ++
 4 files changed, 67 insertions(+), 26 deletions(-)

diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
index bc07711..c4421d9 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
@@ -37,6 +37,12 @@
 /* Define the maximum IDR period */
 #define MAX_IDR_PERIOD 512
 
+/* Default CPB length (in milliseconds) */
+#define DEFAULT_CPB_LENGTH 1500
+
+/* Scale factor for CPB size (HRD cpb_size_scale: min = 4) */
+#define SX_CPB_SIZE 4
+
 /* Scale factor for bitrate (HRD bit_rate_scale: min = 6) */
 #define SX_BITRATE 6
 
@@ -249,7 +255,8 @@ bs_error:
 /* Write an SPS NAL unit */
 static gboolean
 bs_write_sps (GstBitWriter * bs,
-    const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile)
+    const VAEncSequenceParameterBufferH264 * seq_param, GstVaapiProfile profile,
+    const VAEncMiscParameterHRD * hrd_params)
 {
   guint8 profile_idc;
   guint32 constraint_set0_flag, constraint_set1_flag;
@@ -419,13 +426,13 @@ bs_write_sps (GstBitWriter * bs,
       /* cpb_cnt_minus1 */
       WRITE_UE (bs, 0);
       WRITE_UINT32 (bs, SX_BITRATE - 6, 4);     /* bit_rate_scale */
-      WRITE_UINT32 (bs, 6, 4);  /* cpb_size_scale */
+      WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4);    /* cpb_size_scale */
 
       for (i = 0; i < 1; ++i) {
         /* bit_rate_value_minus1[0] */
         WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1);
         /* cpb_size_value_minus1[0] */
-        WRITE_UE (bs, seq_param->bits_per_second / 1000 * 8 - 1);
+        WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1);
         /* cbr_flag[0] */
         WRITE_UINT32 (bs, 1, 1);
       }
@@ -586,6 +593,8 @@ struct _GstVaapiEncoderH264
   GstBuffer *pps_data;
 
   guint bitrate_bits;           // bitrate (bits)
+  guint cpb_length;             // length of CPB buffer (ms)
+  guint cpb_length_bits;        // length of CPB buffer (bits)
 };
 
 static inline void
@@ -763,7 +772,9 @@ ensure_level (GstVaapiEncoderH264 * encoder)
     if (PicSizeMbs <= limits->MaxFS &&
         MaxDpbMbs <= limits->MaxDpbMbs &&
         MaxMBPS <= limits->MaxMBPS && (!encoder->bitrate_bits
-            || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor)))
+            || encoder->bitrate_bits <= (limits->MaxBR * cpb_factor)) &&
+        (!encoder->cpb_length_bits ||
+            encoder->cpb_length_bits <= (limits->MaxCPB * cpb_factor)))
       break;
   }
   if (i == num_limits)
@@ -897,7 +908,7 @@ static void
 fill_hrd_params (GstVaapiEncoderH264 * encoder, VAEncMiscParameterHRD * hrd)
 {
   if (encoder->bitrate_bits > 0) {
-    hrd->buffer_size = encoder->bitrate_bits * 8;
+    hrd->buffer_size = encoder->cpb_length_bits;
     hrd->initial_buffer_fullness = hrd->buffer_size / 2;
   } else {
     hrd->buffer_size = 0;
@@ -915,14 +926,17 @@ add_packed_sequence_header (GstVaapiEncoderH264 * encoder,
   GstBitWriter bs;
   VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
   const VAEncSequenceParameterBufferH264 *const seq_param = sequence->param;
+  VAEncMiscParameterHRD hrd_params;
   guint32 data_bit_size;
   guint8 *data;
 
+  fill_hrd_params (encoder, &hrd_params);
+
   gst_bit_writer_init (&bs, 128 * 8);
   WRITE_UINT32 (&bs, 0x00000001, 32);   /* start code */
   bs_write_nal_header (&bs,
       GST_VAAPI_ENCODER_H264_NAL_REF_IDC_HIGH, GST_VAAPI_ENCODER_H264_NAL_SPS);
-  bs_write_sps (&bs, seq_param, encoder->profile);
+  bs_write_sps (&bs, seq_param, encoder->profile, &hrd_params);
   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
   data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
   data = GST_BIT_WRITER_DATA (&bs);
@@ -1439,7 +1453,7 @@ ensure_misc_params (GstVaapiEncoderH264 * encoder, GstVaapiEncPicture * picture)
     memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl));
     rate_control->bits_per_second = encoder->bitrate_bits;
     rate_control->target_percentage = 70;
-    rate_control->window_size = 500;
+    rate_control->window_size = encoder->cpb_length;
     rate_control->initial_qp = encoder->init_qp;
     rate_control->min_qp = encoder->min_qp;
     rate_control->basic_unit_size = 0;
@@ -1504,7 +1518,7 @@ static void
 ensure_bitrate_hrd (GstVaapiEncoderH264 * encoder)
 {
   GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
-  guint bitrate;
+  guint bitrate, cpb_size;
 
   if (!base_encoder->bitrate) {
     encoder->bitrate_bits = 0;
@@ -1516,6 +1530,13 @@ ensure_bitrate_hrd (GstVaapiEncoderH264 * encoder)
   bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1);
   GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate);
   encoder->bitrate_bits = bitrate;
+
+  /* Round up CPB size. This is an HRD compliance detail */
+  g_assert (SX_CPB_SIZE >= 4);
+  cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) &
+      ~((1U << SX_CPB_SIZE) - 1);
+  GST_DEBUG ("HRD CPB size: %u bits", cpb_size);
+  encoder->cpb_length_bits = cpb_size;
 }
 
 /* Estimates a good enough bitrate if none was supplied */
@@ -2003,6 +2024,9 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
     case GST_VAAPI_ENCODER_H264_PROP_DCT8X8:
       encoder->use_dct8x8 = g_value_get_boolean (value);
       break;
+    case GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH:
+      encoder->cpb_length = g_value_get_uint (value);
+      break;
     default:
       return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
   }
@@ -2131,6 +2155,18 @@ gst_vaapi_encoder_h264_get_default_properties (void)
           "Enable adaptive use of 8x8 transforms in I-frames",
           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstVaapiEncoderH264:cpb-length:
+   *
+   * The size of the CPB buffer in milliseconds.
+   */
+  GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
+      GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH,
+      g_param_spec_uint ("cpb-length",
+          "CPB Length", "Length of the CPB buffer in milliseconds",
+          1, 10000, DEFAULT_CPB_LENGTH,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   return props;
 }
 
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
index 95a0a9a..d4a8a7c 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
@@ -42,6 +42,8 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264;
  * @GST_VAAPI_ENCODER_H264_PROP_CABAC: Enable CABAC entropy coding mode (bool).
  * @GST_VAAPI_ENCODER_H264_PROP_DCT8X8: Enable adaptive use of 8x8
  *   transforms in I-frames (bool).
+ * @GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH: Length of the CPB buffer
+ *   in milliseconds (uint).
  *
  * The set of H.264 encoder specific configurable properties.
  */
@@ -52,6 +54,7 @@ typedef enum {
   GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -4,
   GST_VAAPI_ENCODER_H264_PROP_CABAC = -5,
   GST_VAAPI_ENCODER_H264_PROP_DCT8X8 = -6,
+  GST_VAAPI_ENCODER_H264_PROP_CPB_LENGTH = -7,
 } GstVaapiEncoderH264Prop;
 
 GstVaapiEncoder *
diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c
index c72e017..20da57c 100644
--- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c
@@ -76,24 +76,24 @@ static const struct map gst_vaapi_h264_level_map[] = {
 /* Table A-1 - Level limits */
 /* *INDENT-OFF* */
 static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = {
-  /* level                     idc   MaxMBPS   MaxFS MaxDpbMbs   MaxBR */
-  { GST_VAAPI_LEVEL_H264_L1,    10,     1485,     99,     396,      64 },
-  { GST_VAAPI_LEVEL_H264_L1b,   11,     1485,     99,     396,     128 },
-  { GST_VAAPI_LEVEL_H264_L1_1,  11,     3000,    396,     900,     192 },
-  { GST_VAAPI_LEVEL_H264_L1_2,  12,     6000,    396,    2376,     384 },
-  { GST_VAAPI_LEVEL_H264_L1_3,  13,    11880,    396,    2376,     768 },
-  { GST_VAAPI_LEVEL_H264_L2,    20,    11880,    396,    2376,    2000 },
-  { GST_VAAPI_LEVEL_H264_L2_1,  21,    19800,    792,    4752,    4000 },
-  { GST_VAAPI_LEVEL_H264_L2_2,  22,    20250,   1620,    8100,    4000 },
-  { GST_VAAPI_LEVEL_H264_L3,    30,    40500,   1620,    8100,   10000 },
-  { GST_VAAPI_LEVEL_H264_L3_1,  31,   108000,   3600,   18000,   14000 },
-  { GST_VAAPI_LEVEL_H264_L3_2,  32,   216000,   5120,   20480,   20000 },
-  { GST_VAAPI_LEVEL_H264_L4,    40,   245760,   8192,   32768,   20000 },
-  { GST_VAAPI_LEVEL_H264_L4_1,  41,   245760,   8192,   32768,   50000 },
-  { GST_VAAPI_LEVEL_H264_L4_2,  42,   522240,   8704,   34816,   50000 },
-  { GST_VAAPI_LEVEL_H264_L5,    50,   589824,  22080,  110400,  135000 },
-  { GST_VAAPI_LEVEL_H264_L5_1,  51,   983040,  36864,  184320,  240000 },
-  { GST_VAAPI_LEVEL_H264_L5_2,  52,  2073600,  36864,  184320,  240000 },
+  /* level                     idc   MaxMBPS   MaxFS MaxDpbMbs  MaxBR MaxCPB */
+  { GST_VAAPI_LEVEL_H264_L1,    10,     1485,     99,    396,     64,    175 },
+  { GST_VAAPI_LEVEL_H264_L1b,   11,     1485,     99,    396,    128,    350 },
+  { GST_VAAPI_LEVEL_H264_L1_1,  11,     3000,    396,    900,    192,    500 },
+  { GST_VAAPI_LEVEL_H264_L1_2,  12,     6000,    396,   2376,    384,   1000 },
+  { GST_VAAPI_LEVEL_H264_L1_3,  13,    11880,    396,   2376,    768,   2000 },
+  { GST_VAAPI_LEVEL_H264_L2,    20,    11880,    396,   2376,   2000,   2000 },
+  { GST_VAAPI_LEVEL_H264_L2_1,  21,    19800,    792,   4752,   4000,   4000 },
+  { GST_VAAPI_LEVEL_H264_L2_2,  22,    20250,   1620,   8100,   4000,   4000 },
+  { GST_VAAPI_LEVEL_H264_L3,    30,    40500,   1620,   8100,  10000,  10000 },
+  { GST_VAAPI_LEVEL_H264_L3_1,  31,   108000,   3600,  18000,  14000,  14000 },
+  { GST_VAAPI_LEVEL_H264_L3_2,  32,   216000,   5120,  20480,  20000,  20000 },
+  { GST_VAAPI_LEVEL_H264_L4,    40,   245760,   8192,  32768,  20000,  25000 },
+  { GST_VAAPI_LEVEL_H264_L4_1,  41,   245760,   8192,  32768,  50000,  62500 },
+  { GST_VAAPI_LEVEL_H264_L4_2,  42,   522240,   8704,  34816,  50000,  62500 },
+  { GST_VAAPI_LEVEL_H264_L5,    50,   589824,  22080, 110400, 135000, 135000 },
+  { GST_VAAPI_LEVEL_H264_L5_1,  51,   983040,  36864, 184320, 240000, 240000 },
+  { GST_VAAPI_LEVEL_H264_L5_2,  52,  2073600,  36864, 184320, 240000, 240000 },
   { 0, }
 };
 /* *INDENT-ON* */
diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h
index 1c7db35..8395760 100644
--- a/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiutils_h264_priv.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
  * @MaxFS: the maximum frame size (MBs)
  * @MaxDpbMbs: the maxium decoded picture buffer size (MBs)
  * @MaxBR: the maximum video bit rate (kbps)
+ * @MaxCPB: the maximum CPB size (kbits)
  *
  * The data structure that describes the limits of an H.264 level.
  */
@@ -46,6 +47,7 @@ typedef struct
   guint32 MaxFS;
   guint32 MaxDpbMbs;
   guint32 MaxBR;
+  guint32 MaxCPB;
 } GstVaapiH264LevelLimits;
 
 /* Returns GstVaapiProfile from H.264 profile_idc value */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gstreamer/gstreamer-vaapi.git



More information about the Pkg-gstreamer-commits mailing list