"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;
}
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;
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;
}
}
+/**
+ * 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)
* 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;
/**
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);
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;
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;
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;
/* 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;
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;
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.
/**
* 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).
* 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 *
#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
/* public */
guint32 profile;
guint32 level;
- guint32 intra_period;
guint32 idr_period;
guint32 init_qp; /*default 24 */
guint32 min_qp; /*default 1 */
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);
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);
}
} 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 {
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))
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;
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,
/**
* 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).
*
*/
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 *
#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
guint32 profile;
guint32 level;
guint32 cqp;
- guint32 intra_period;
guint32 ip_period;
/* re-ordering */
#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; \
GstVaapiRateControl rate_control;
guint32 rate_control_mask;
guint bitrate; /* kbps */
+ guint keyframe_period;
GMutex mutex;
GCond surface_free;