[Pkg-gstreamer-commits] [gstreamer-vaapi] 104/176: encoder: add keyframe period API.

Vincent Cheng vcheng at moszumanska.debian.org
Tue Jun 3 08:09:32 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 59229b20a5965081a210296122efe34e71d9d79f
Author: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
Date:   Fri Jan 10 13:23:48 2014 +0100

    encoder: add keyframe period API.
    
    Add gst_vaapi_encoder_set_keyframe_period() interface to allow the
    user control the maximum distance between two keyframes. This new
    property can only be set prior to gst_vaapi_encoder_set_codec_state().
    
    A value of zero for "keyframe-period" gets it re-evaluated to the
    actual framerate during encoder reconfiguration.
---
 gst-libs/gst/vaapi/gstvaapiencoder.c            | 57 +++++++++++++++++++++++++
 gst-libs/gst/vaapi/gstvaapiencoder.h            |  7 +++
 gst-libs/gst/vaapi/gstvaapiencoder_h264.c       | 31 ++++----------
 gst-libs/gst/vaapi/gstvaapiencoder_h264.h       | 11 ++---
 gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h  |  3 --
 gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c      | 21 +++------
 gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h      |  5 +--
 gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h |  4 --
 gst-libs/gst/vaapi/gstvaapiencoder_priv.h       | 12 ++++++
 9 files changed, 94 insertions(+), 57 deletions(-)

diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c
index d629da1..f222361 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder.c
@@ -139,6 +139,18 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass)
           "The desired bitrate expressed in kbps (0: auto-calculate)",
           0, 100 * 1024, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstVaapiEncoder:keyframe-period:
+   *
+   * The maximal distance between two keyframes.
+   */
+  GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
+      GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD,
+      g_param_spec_uint ("keyframe-period",
+          "Keyframe Period",
+          "Maximal distance between two keyframes (0: auto-calculate)", 1, 300,
+          30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   return props;
 }
 
@@ -478,10 +490,15 @@ static GstVaapiEncoderStatus
 gst_vaapi_encoder_reconfigure_internal (GstVaapiEncoder * encoder)
 {
   GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder);
+  GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
   GstVaapiEncoderStatus status;
   GstVaapiVideoPool *pool;
   guint codedbuf_size;
 
+  /* Generate a keyframe every second */
+  if (!encoder->keyframe_period)
+    encoder->keyframe_period = (vip->fps_n + vip->fps_d - 1) / vip->fps_d;
+
   status = klass->reconfigure (encoder);
   if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
     return status;
@@ -603,6 +620,10 @@ set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value)
       status = gst_vaapi_encoder_set_bitrate (encoder,
           g_value_get_uint (value));
       break;
+    case GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD:
+      status = gst_vaapi_encoder_set_keyframe_period (encoder,
+          g_value_get_uint (value));
+      break;
   }
   return status;
 
@@ -782,6 +803,42 @@ error_operation_failed:
   }
 }
 
+/**
+ * gst_vaapi_encoder_set_keyframe_period:
+ * @encoder: a #GstVaapiEncoder
+ * @keyframe_period: the maximal distance between two keyframes
+ *
+ * Notifies the @encoder to use the supplied @keyframe_period value.
+ *
+ * Note: currently, the keyframe period can only be specified before
+ * the last call to gst_vaapi_encoder_set_codec_state(), which shall
+ * occur before the first frame is encoded. Afterwards, any change to
+ * this parameter causes gst_vaapi_encoder_set_keyframe_period() to
+ * return @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED.
+ *
+ * Return value: a #GstVaapiEncoderStatus
+ */
+GstVaapiEncoderStatus
+gst_vaapi_encoder_set_keyframe_period (GstVaapiEncoder * encoder,
+    guint keyframe_period)
+{
+  g_return_val_if_fail (encoder != NULL, 0);
+
+  if (encoder->keyframe_period != keyframe_period
+      && encoder->num_codedbuf_queued > 0)
+    goto error_operation_failed;
+
+  encoder->keyframe_period = keyframe_period;
+  return GST_VAAPI_ENCODER_STATUS_SUCCESS;
+
+  /* ERRORS */
+error_operation_failed:
+  {
+    GST_ERROR ("could not change keyframe period after encoding started");
+    return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
+  }
+}
+
 /* Initialize default values for configurable properties */
 static gboolean
 gst_vaapi_encoder_init_properties (GstVaapiEncoder * encoder)
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h
index 8f6e6ae..1c3c86b 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder.h
@@ -72,12 +72,15 @@ typedef enum
  * GstVaapiEncoderProp:
  * @GST_VAAPI_ENCODER_PROP_RATECONTROL: Rate control (#GstVaapiRateControl).
  * @GST_VAAPI_ENCODER_PROP_BITRATE: Bitrate expressed in kbps (uint).
+ * @GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD: The maximal distance
+ *   between two keyframes (uint).
  *
  * The set of configurable properties for the encoder.
  */
 typedef enum {
   GST_VAAPI_ENCODER_PROP_RATECONTROL = 1,
   GST_VAAPI_ENCODER_PROP_BITRATE,
+  GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD,
 } GstVaapiEncoderProp;
 
 /**
@@ -126,6 +129,10 @@ gst_vaapi_encoder_put_frame (GstVaapiEncoder * encoder,
     GstVideoCodecFrame * frame);
 
 GstVaapiEncoderStatus
+gst_vaapi_encoder_set_keyframe_period (GstVaapiEncoder * encoder,
+    guint keyframe_period);
+
+GstVaapiEncoderStatus
 gst_vaapi_encoder_get_buffer_with_timeout (GstVaapiEncoder * encoder,
     GstVaapiCodedBufferProxy ** out_codedbuf_proxy_ptr, guint64 timeout);
 
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
index ad79f7c..4cd1021 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c
@@ -854,7 +854,7 @@ fill_va_sequence_param (GstVaapiEncoderH264 * encoder,
   memset (seq, 0, sizeof (VAEncSequenceParameterBufferH264));
   seq->seq_parameter_set_id = 0;
   seq->level_idc = encoder->level;
-  seq->intra_period = encoder->intra_period;
+  seq->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
   seq->ip_period = 0;           // ?
   if (base_encoder->bitrate > 0)
     seq->bits_per_second = base_encoder->bitrate * 1024;
@@ -1284,13 +1284,11 @@ ensure_bitrate (GstVaapiEncoderH264 * encoder)
 static void
 reset_properties (GstVaapiEncoderH264 * encoder)
 {
+  GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
   guint width_mbs, height_mbs, total_mbs;
 
-  if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD)
-    encoder->intra_period = GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD;
-
-  if (encoder->idr_period < encoder->intra_period)
-    encoder->idr_period = encoder->intra_period;
+  if (encoder->idr_period < base_encoder->keyframe_period)
+    encoder->idr_period = base_encoder->keyframe_period;
   if (encoder->idr_period > GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD)
     encoder->idr_period = GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD;
 
@@ -1307,8 +1305,8 @@ reset_properties (GstVaapiEncoderH264 * encoder)
     encoder->slice_num = (total_mbs + 1) / 2;
   g_assert (encoder->slice_num);
 
-  if (encoder->b_frame_num > (encoder->intra_period + 1) / 2)
-    encoder->b_frame_num = (encoder->intra_period + 1) / 2;
+  if (encoder->b_frame_num > (base_encoder->keyframe_period + 1) / 2)
+    encoder->b_frame_num = (base_encoder->keyframe_period + 1) / 2;
 
   if (encoder->b_frame_num > 50)
     encoder->b_frame_num = 50;
@@ -1522,7 +1520,8 @@ gst_vaapi_encoder_h264_reordering (GstVaapiEncoder * base,
 
   /* check key frames */
   if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
-      (encoder->frame_index % encoder->intra_period) == 0) {
+      (encoder->frame_index % GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) ==
+      0) {
     ++encoder->cur_frame_num;
     ++encoder->frame_index;
 
@@ -1710,9 +1709,6 @@ gst_vaapi_encoder_h264_set_property (GstVaapiEncoder * base_encoder,
   GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder);
 
   switch (prop_id) {
-    case GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD:
-      encoder->intra_period = g_value_get_uint (value);
-      break;
     case GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES:
       encoder->b_frame_num = g_value_get_uint (value);
       break;
@@ -1772,17 +1768,6 @@ gst_vaapi_encoder_h264_get_default_properties (void)
     return NULL;
 
   /**
-   * GstVaapiEncoderH264:key-period
-   *
-   * The maximal distance between two keyframes.
-   */
-  GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
-      GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD,
-      g_param_spec_uint ("key-period",
-          "Key Period", "Maximal distance between two key-frames", 1, 300, 30,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  /**
    * GstVaapiEncoderH264:max-bframes:
    *
    * The number of B-frames between I and P.
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
index b6c4a1c..9b3eb49 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.h
@@ -30,8 +30,6 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264;
 
 /**
  * GstVaapiEncoderH264Prop:
- * @GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD: Maximal distance between two
- *   keyframes (uint).
  * @GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES: Number of B-frames between I
  *   and P (uint).
  * @GST_VAAPI_ENCODER_H264_PROP_INIT_QP: Initial quantizer value (uint).
@@ -41,11 +39,10 @@ typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264;
  * The set of H.264 encoder specific configurable properties.
  */
 typedef enum {
-  GST_VAAPI_ENCODER_H264_PROP_KEY_PERIOD = -1,
-  GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES = -2,
-  GST_VAAPI_ENCODER_H264_PROP_INIT_QP = -3,
-  GST_VAAPI_ENCODER_H264_PROP_MIN_QP = -4,
-  GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -5,
+  GST_VAAPI_ENCODER_H264_PROP_MAX_BFRAMES = -1,
+  GST_VAAPI_ENCODER_H264_PROP_INIT_QP = -2,
+  GST_VAAPI_ENCODER_H264_PROP_MIN_QP = -3,
+  GST_VAAPI_ENCODER_H264_PROP_NUM_SLICES = -4,
 } GstVaapiEncoderH264Prop;
 
 GstVaapiEncoder *
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
index fd4cd29..f2b3a8e 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264_priv.h
@@ -57,8 +57,6 @@ typedef enum
 #define GST_VAAPI_ENCODER_H264_DEFAULT_LEVEL        GST_VAAPI_ENCODER_H264_LEVEL_31
 #define GST_VAAPI_ENCODER_H264_DEFAULT_INIT_QP      26
 #define GST_VAAPI_ENCODER_H264_DEFAULT_MIN_QP       1
-#define GST_VAAPI_ENCODER_H264_DEFAULT_INTRA_PERIOD 30
-#define GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD     512
 #define GST_VAAPI_ENCODER_H264_MAX_IDR_PERIOD       512
 
 #define GST_VAAPI_ENCODER_H264_DEFAULT_SLICE_NUM    1
@@ -70,7 +68,6 @@ struct _GstVaapiEncoderH264
   /* public */
   guint32 profile;
   guint32 level;
-  guint32 intra_period;
   guint32 idr_period;
   guint32 init_qp;              /*default 24 */
   guint32 min_qp;               /*default 1 */
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c
index 1c9f6a2..7b88128 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c
@@ -177,7 +177,7 @@ fill_sequence (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncSequence * sequence)
 
   memset (seq, 0, sizeof (VAEncSequenceParameterBufferMPEG2));
 
-  seq->intra_period = encoder->intra_period;
+  seq->intra_period = base_encoder->keyframe_period;
   seq->ip_period = encoder->ip_period;
   seq->picture_width = GST_VAAPI_ENCODER_WIDTH (encoder);
   seq->picture_height = GST_VAAPI_ENCODER_HEIGHT (encoder);
@@ -587,7 +587,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base,
     return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
   }
 
-  if (encoder->frame_num >= encoder->intra_period) {
+  if (encoder->frame_num >= base->keyframe_period) {
     encoder->frame_num = 0;
     clear_references (encoder);
   }
@@ -598,7 +598,7 @@ gst_vaapi_encoder_mpeg2_reordering (GstVaapiEncoder * base,
   } else {
     encoder->new_gop = FALSE;
     if ((encoder->frame_num % (encoder->ip_period + 1)) == 0 ||
-        encoder->frame_num == encoder->intra_period - 1) {
+        encoder->frame_num == base->keyframe_period - 1) {
       picture->type = GST_VAAPI_PICTURE_TYPE_P;
       encoder->dump_frames = TRUE;
     } else {
@@ -680,8 +680,8 @@ gst_vaapi_encoder_mpeg2_reconfigure (GstVaapiEncoder * base_encoder)
   GstVaapiEncoderMpeg2 *const encoder =
       GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
 
-  if (encoder->ip_period > encoder->intra_period) {
-    encoder->ip_period = encoder->intra_period - 1;
+  if (encoder->ip_period > base_encoder->keyframe_period) {
+    encoder->ip_period = base_encoder->keyframe_period - 1;
   }
 
   if (!ensure_profile_and_level (encoder))
@@ -771,9 +771,6 @@ gst_vaapi_encoder_mpeg2_set_property (GstVaapiEncoder * base_encoder,
     case GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER:
       encoder->cqp = g_value_get_uint (value);
       break;
-    case GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD:
-      encoder->intra_period = g_value_get_uint (value);
-      break;
     case GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES:
       encoder->ip_period = g_value_get_uint (value);
       break;
@@ -832,14 +829,6 @@ gst_vaapi_encoder_mpeg2_get_default_properties (void)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
-      GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD,
-      g_param_spec_uint ("key-period",
-          "Key Period", "Maximal distance between two key-frames", 1,
-          GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE,
-          GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
       GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES,
       g_param_spec_uint ("max-bframes", "Max B-Frames",
           "Number of B-frames between I and P", 0,
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h
index bd6d1a7..e4a547d 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.h
@@ -31,8 +31,6 @@ typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2;
 /**
  * GstVaapiEncoderMpeg2Prop:
  * @GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER: Constant quantizer value (uint).
- * @GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD: Maximal distance between two
- *   keyframes (uint).
  * @GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES: Number of B-frames between I
  *   and P (uint).
  *
@@ -40,8 +38,7 @@ typedef struct _GstVaapiEncoderMpeg2 GstVaapiEncoderMpeg2;
  */
 typedef enum {
   GST_VAAPI_ENCODER_MPEG2_PROP_QUANTIZER = -1,
-  GST_VAAPI_ENCODER_MPEG2_PROP_KEY_PERIOD = -2,
-  GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES = -3,
+  GST_VAAPI_ENCODER_MPEG2_PROP_MAX_BFRAMES = -2,
 } GstVaapiEncoderMpeg2Prop;
 
 GstVaapiEncoder *
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h
index df94ab6..b3159bd 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2_priv.h
@@ -53,9 +53,6 @@ typedef enum
 #define GST_VAAPI_ENCODER_MPEG2_MAX_CQP                 62
 #define GST_VAAPI_ENCODER_MPEG2_DEFAULT_CQP             8
 
-#define GST_VAAPI_ENCODER_MPEG2_MAX_GOP_SIZE            512
-#define GST_VAAPI_ENCODER_MPEG2_DEFAULT_GOP_SIZE        30
-
 #define GST_VAAPI_ENCODER_MPEG2_MAX_MAX_BFRAMES         16
 #define GST_VAAPI_ENCODER_MPEG2_DEFAULT_MAX_BFRAMES     2
 
@@ -81,7 +78,6 @@ struct _GstVaapiEncoderMpeg2
   guint32 profile;
   guint32 level;
   guint32 cqp;
-  guint32 intra_period;
   guint32 ip_period;
 
   /* re-ordering */
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
index c469deb..d473a05 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h
@@ -121,6 +121,17 @@ G_BEGIN_DECLS
 #define GST_VAAPI_ENCODER_RATE_CONTROL(encoder) \
   (GST_VAAPI_ENCODER_CAST (encoder)->rate_control)
 
+/**
+ * GST_VAAPI_ENCODER_KEYFRAME_PERIOD:
+ * @encoder: a #GstVaapiEncoder
+ *
+ * Macro that evaluates to the keyframe period.
+ * This is an internal macro that does not do any run-time type check.
+ */
+#undef  GST_VAAPI_ENCODER_KEYFRAME_PERIOD
+#define GST_VAAPI_ENCODER_KEYFRAME_PERIOD(encoder) \
+  (GST_VAAPI_ENCODER_CAST (encoder)->keyframe_period)
+
 #define GST_VAAPI_ENCODER_CHECK_STATUS(exp, err_num, err_reason, ...)   \
   if (!(exp)) {                                                         \
     ret = err_num;                                                      \
@@ -170,6 +181,7 @@ struct _GstVaapiEncoder
   GstVaapiRateControl rate_control;
   guint32 rate_control_mask;
   guint bitrate; /* kbps */
+  guint keyframe_period;
 
   GMutex mutex;
   GCond surface_free;

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