[Pkg-gstreamer-commits] [gstreamer-vaapi] 115/176: encoder: h264: derive profile and level from active coding tools.

Vincent Cheng vcheng at moszumanska.debian.org
Tue Jun 3 08:09:33 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 b59a5572af08c1ce504232d3a9eed0cbf0cecec5
Author: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
Date:   Fri Jan 10 18:18:25 2014 +0100

    encoder: h264: derive profile and level from active coding tools.
    
    Automatically derive the minimum profile and level to be used for
    encoding, based on the activated coding tools. The encoder will
    be trying to generate a bitstream that has the best chances to be
    decoded on most platforms by default.
    
    Also change the default profile to "constrained-baseline" so that
    to ensure maximum compatibility when the stream is decoded.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=719691
---
 gst-libs/gst/vaapi/gstvaapiencoder_h264.c      | 153 +++++++++++--------------
 gst-libs/gst/vaapi/gstvaapiencoder_h264.h      |   5 +
 gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h |  25 +---
 3 files changed, 78 insertions(+), 105 deletions(-)

diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
index 16dcb64..2f4ed92 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
@@ -209,96 +209,52 @@ ensure_profile (GstVaapiEncoderH264 * encoder)
 {
   GstVaapiProfile profile;
 
-  profile = GST_VAAPI_PROFILE_H264_BASELINE;
+  /* Always start from "constrained-baseline" profile for maximum
+     compatibility */
+  profile = GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE;
+
+  /* Main profile coding tools */
+  if (encoder->num_bframes > 0)
+    profile = GST_VAAPI_PROFILE_H264_MAIN;
 
   encoder->profile = profile;
+  encoder->profile_idc = gst_vaapi_utils_h264_get_profile_idc (profile);
   return TRUE;
 }
 
-static void
-_set_level (GstVaapiEncoderH264 * encoder)
+static gboolean
+ensure_level (GstVaapiEncoderH264 * encoder)
 {
-  guint pic_mb_size;
-  guint MaxDpbMbs, MaxMBPS;
-  guint dbp_level, mbps_level, profile_level;
-
-  if (encoder->level_idc) {
-    if (encoder->level_idc < GST_VAAPI_ENCODER_H264_LEVEL_10)
-      encoder->level_idc = GST_VAAPI_ENCODER_H264_LEVEL_10;
-    else if (encoder->level_idc > GST_VAAPI_ENCODER_H264_LEVEL_51)
-      encoder->level_idc = GST_VAAPI_ENCODER_H264_LEVEL_51;
-    return;
+  const guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate;
+  const GstVaapiH264LevelLimits *limits_table;
+  guint i, num_limits, PicSizeMbs, MaxDpbMbs, MaxMBPS;
+
+  PicSizeMbs = encoder->mb_width * encoder->mb_height;
+  MaxDpbMbs = PicSizeMbs * ((encoder->num_bframes) ? 2 : 1);
+  MaxMBPS = gst_util_uint64_scale_int_ceil (PicSizeMbs,
+      GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder));
+
+  limits_table = gst_vaapi_utils_h264_get_level_limits_table (&num_limits);
+  for (i = 0; i < num_limits; i++) {
+    const GstVaapiH264LevelLimits *const limits = &limits_table[i];
+    if (PicSizeMbs <= limits->MaxFS &&
+        MaxDpbMbs <= limits->MaxDpbMbs &&
+        MaxMBPS <= limits->MaxMBPS && (!bitrate || bitrate <= limits->MaxBR))
+      break;
   }
+  if (i == num_limits)
+    goto error_unsupported_level;
 
-  /* calculate level */
-  pic_mb_size = ((GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16) *
-      ((GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16);
-  MaxDpbMbs = pic_mb_size * ((encoder->num_bframes) ? 2 : 1);
-  MaxMBPS = pic_mb_size * GST_VAAPI_ENCODER_FPS_N (encoder) /
-      GST_VAAPI_ENCODER_FPS_D (encoder);
-
-  /* calculate from MaxDbpMbs */
-  if (MaxDpbMbs > 110400)
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_51;
-  else if (MaxDpbMbs > 34816)
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_50;
-  else if (MaxDpbMbs > 32768)
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_42;
-  else if (MaxDpbMbs > 20480)   /* 41 or 40 */
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
-  else if (MaxDpbMbs > 18000)
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_32;
-  else if (MaxDpbMbs > 8100)
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_31;
-  else if (MaxDpbMbs > 4752)    /* 30 or 22 */
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
-  else if (MaxDpbMbs > 2376)
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_21;
-  else if (MaxDpbMbs > 900)     /* 20, 13, 12 */
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
-  else if (MaxDpbMbs > 396)
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_11;
-  else
-    dbp_level = GST_VAAPI_ENCODER_H264_LEVEL_10;
-
-  /* calculate from Max Mb processing rate */
-  if (MaxMBPS > 589824)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_51;
-  else if (MaxMBPS > 522240)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_50;
-  else if (MaxMBPS > 245760)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_42;
-  else if (MaxMBPS > 216000)    /* 40 or 41 */
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
-  else if (MaxMBPS > 108000)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_32;
-  else if (MaxMBPS > 40500)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_31;
-  else if (MaxMBPS > 20250)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
-  else if (MaxMBPS > 19800)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_22;
-  else if (MaxMBPS > 11800)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_21;
-  else if (MaxMBPS > 6000)      /*13 or 20 */
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
-  else if (MaxMBPS > 3000)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_12;
-  else if (MaxMBPS > 1485)
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_11;
-  else
-    mbps_level = GST_VAAPI_ENCODER_H264_LEVEL_10;
-
-  if (encoder->profile == GST_VAAPI_PROFILE_H264_HIGH)
-    profile_level = GST_VAAPI_ENCODER_H264_LEVEL_41;
-  else if (encoder->profile == GST_VAAPI_PROFILE_H264_MAIN)
-    profile_level = GST_VAAPI_ENCODER_H264_LEVEL_30;
-  else
-    profile_level = GST_VAAPI_ENCODER_H264_LEVEL_20;
+  encoder->level = limits_table[i].level;
+  encoder->level_idc = limits_table[i].level_idc;
+  return TRUE;
 
-  encoder->level_idc = (dbp_level > mbps_level ? dbp_level : mbps_level);
-  if (encoder->level_idc < profile_level)
-    encoder->level_idc = profile_level;
+  /* ERRORS */
+error_unsupported_level:
+  {
+    GST_ERROR ("failed to find a suitable level matching codec config");
+    return FALSE;
+  }
 }
 
 static inline void
@@ -1015,7 +971,7 @@ fill_va_picture_param (GstVaapiEncoderH264 * encoder,
   pic_param->pic_fields.bits.weighted_pred_flag = FALSE;
   pic_param->pic_fields.bits.weighted_bipred_idc = 0;
   pic_param->pic_fields.bits.constrained_intra_pred_flag = 0;
-  pic_param->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile >= GST_VAAPI_PROFILE_H264_HIGH);       /* enable 8x8 */
+  pic_param->pic_fields.bits.transform_8x8_mode_flag = (encoder->profile_idc >= 100);       /* enable 8x8 */
   /* enable debloking */
   pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE;
   pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = FALSE;
@@ -1282,8 +1238,8 @@ ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
 {
   if (!ensure_profile (encoder))
     return FALSE;
-
-  _set_level (encoder);
+  if (!ensure_level (encoder))
+    return FALSE;
   return TRUE;
 }
 
@@ -1831,3 +1787,32 @@ gst_vaapi_encoder_h264_get_default_properties (void)
 
   return props;
 }
+
+/**
+ * gst_vaapi_encoder_h264_get_profile_and_level:
+ * @encoder: a #GstVaapiEncoderH264
+ * @out_profile_ptr: return location for the #GstVaapiProfile
+ * @out_level_ptr: return location for the #GstVaapiLevelH264
+ *
+ * Queries the H.264 @encoder for the active profile and level. That
+ * information is only constructed and valid after the encoder is
+ * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
+ * function is called.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
+    GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr)
+{
+  g_return_val_if_fail (encoder != NULL, FALSE);
+
+  if (!encoder->profile || !encoder->level)
+    return FALSE;
+
+  if (out_profile_ptr)
+    *out_profile_ptr = encoder->profile;
+  if (out_level_ptr)
+    *out_level_ptr = encoder->level;
+  return TRUE;
+}
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
index f02e40e..7d5f053 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
@@ -23,6 +23,7 @@
 #define GST_VAAPI_ENCODER_H264_H
 
 #include <gst/vaapi/gstvaapiencoder.h>
+#include <gst/vaapi/gstvaapiutils_h264.h>
 
 G_BEGIN_DECLS
 
@@ -54,6 +55,10 @@ gst_vaapi_encoder_h264_new (GstVaapiDisplay * display);
 GPtrArray *
 gst_vaapi_encoder_h264_get_default_properties (void);
 
+gboolean
+gst_vaapi_encoder_h264_get_profile_and_level (GstVaapiEncoderH264 * encoder,
+    GstVaapiProfile * out_profile_ptr, GstVaapiLevelH264 * out_level_ptr);
+
 G_END_DECLS
 
 #endif /*GST_VAAPI_ENCODER_H264_H */
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
index a2eb65b..bf9958a 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
@@ -23,32 +23,13 @@
 #define GST_VAAPI_ENCODER_H264_PRIV_H
 
 #include "gstvaapiencoder_priv.h"
+#include "gstvaapiutils_h264.h"
 
 G_BEGIN_DECLS
 
 #define GST_VAAPI_ENCODER_H264_CAST(encoder) \
     ((GstVaapiEncoderH264 *)(encoder))
 
-typedef enum
-{
-  GST_VAAPI_ENCODER_H264_LEVEL_10 = 10, /* QCIF format, < 380160 samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_11 = 11, /* CIF format,   < 768000 samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_12 = 12, /* CIF format,   < 1536000  samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_13 = 13, /* CIF format,   < 3041280  samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_20 = 20, /* CIF format,   < 3041280  samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_21 = 21, /* HHR format,  < 5068800  samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_22 = 22, /* SD/4CIF format,     < 5184000      samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_30 = 30, /* SD/4CIF format,     < 10368000    samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_31 = 31, /* 720pHD format,      < 27648000    samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_32 = 32, /* SXGA  format,         < 55296000    samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_40 = 40, /* 2Kx1K format,         < 62914560    samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_41 = 41, /* 2Kx1K format,         < 62914560    samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_42 = 42, /* 2Kx1K format,         < 125829120  samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_50 = 50, /* 3672x1536 format,  < 150994944  samples/sec */
-  GST_VAAPI_ENCODER_H264_LEVEL_51 = 51, /* 4096x2304 format,  < 251658240  samples/sec */
-} GstVaapiEncoderH264Level;
-
-#define GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL        GST_VAAPI_ENCODER_H264_LEVEL_31
 #define GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD       512
 
 struct _GstVaapiEncoderH264
@@ -56,7 +37,9 @@ struct _GstVaapiEncoderH264
   GstVaapiEncoder parent_instance;
 
   GstVaapiProfile profile;
-  guint32 level_idc;
+  GstVaapiLevelH264 level;
+  guint8 profile_idc;
+  guint8 level_idc;
   guint32 idr_period;
   guint32 init_qp;
   guint32 min_qp;

-- 
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