From 21c95dbc4281f123f096e8d956d8f2fa4f285f2f Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 13 Jan 2014 10:48:25 +0100 Subject: [PATCH] encoder: add tuning options API. Add encoder "tune" option to override the default behaviour that is to favor maximum decoder compatibility at the expense of lower compression ratios. Expected tuning options to be developed are: - "high-compression": improve compression, target best-in-class decoders; - "low-latency": tune for low-latency decoding; - "low-power": tune for encoding in low power / resources conditions. --- gst-libs/gst/vaapi/gstvaapiencoder.c | 79 ++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder.h | 30 ++++++++++++ gst-libs/gst/vaapi/gstvaapiencoder_h264.c | 4 ++ gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c | 4 ++ gst-libs/gst/vaapi/gstvaapiencoder_priv.h | 32 ++++++++++++ 5 files changed, 149 insertions(+) diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.c b/gst-libs/gst/vaapi/gstvaapiencoder.c index 1a99147..89b77e5 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder.c @@ -153,6 +153,19 @@ gst_vaapi_encoder_properties_get_default (const GstVaapiEncoderClass * klass) "Maximal distance between two keyframes (0: auto-calculate)", 1, 300, 30, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstVaapiEncoder:tune: + * + * The desired encoder tuning option. + */ + GST_VAAPI_ENCODER_PROPERTIES_APPEND (props, + GST_VAAPI_ENCODER_PROP_TUNE, + g_param_spec_enum ("tune", + "Encoder Tuning", + "Encoder tuning option", + cdata->encoder_tune_get_type (), cdata->default_encoder_tune, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + return props; } @@ -626,6 +639,9 @@ set_property (GstVaapiEncoder * encoder, gint prop_id, const GValue * value) status = gst_vaapi_encoder_set_keyframe_period (encoder, g_value_get_uint (value)); break; + case GST_VAAPI_ENCODER_PROP_TUNE: + status = gst_vaapi_encoder_set_tuning (encoder, g_value_get_enum (value)); + break; } return status; @@ -841,6 +857,41 @@ error_operation_failed: } } +/** + * gst_vaapi_encoder_set_tuning: + * @encoder: a #GstVaapiEncoder + * @tuning: the #GstVaapiEncoderTune option + * + * Notifies the @encoder to use the supplied @tuning option. + * + * Note: currently, the tuning option 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_tuning() to return + * @GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED. + * + * Return value: a #GstVaapiEncoderStatus + */ +GstVaapiEncoderStatus +gst_vaapi_encoder_set_tuning (GstVaapiEncoder * encoder, + GstVaapiEncoderTune tuning) +{ + g_return_val_if_fail (encoder != NULL, 0); + + if (encoder->tune != tuning && encoder->num_codedbuf_queued > 0) + goto error_operation_failed; + + encoder->tune = tuning; + return GST_VAAPI_ENCODER_STATUS_SUCCESS; + + /* ERRORS */ +error_operation_failed: + { + GST_ERROR ("could not change tuning options 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) @@ -963,3 +1014,31 @@ error: gst_vaapi_encoder_unref (encoder); return NULL; } + +/** Returns a GType for the #GstVaapiEncoderTune set */ +GType +gst_vaapi_encoder_tune_get_type (void) +{ + static volatile gsize g_type = 0; + + static const GEnumValue encoder_tune_values[] = { + /* *INDENT-OFF* */ + { GST_VAAPI_ENCODER_TUNE_NONE, + "None", "none" }, + { GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION, + "High compression", "high-compression" }, + { GST_VAAPI_ENCODER_TUNE_LOW_LATENCY, + "Low latency", "low-latency" }, + { GST_VAAPI_ENCODER_TUNE_LOW_POWER, + "Low power mode", "low-power" }, + { 0, NULL, NULL }, + /* *INDENT-ON* */ + }; + + if (g_once_init_enter (&g_type)) { + GType type = + g_enum_register_static ("GstVaapiEncoderTune", encoder_tune_values); + g_once_init_leave (&g_type, type); + } + return g_type; +} diff --git a/gst-libs/gst/vaapi/gstvaapiencoder.h b/gst-libs/gst/vaapi/gstvaapiencoder.h index 5df548e..4b07700 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder.h @@ -69,11 +69,33 @@ typedef enum } GstVaapiEncoderStatus; /** + * GstVaapiEncoderTune: + * @GST_VAAPI_ENCODER_TUNE_NONE: No tuning option set. + * @GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION: Tune for higher compression + * ratios, at the expense of lower compatibility at decoding time. + * @GST_VAAPI_ENCODER_TUNE_LOW_LATENCY: Tune for low latency decoding. + * @GST_VAAPI_ENCODER_TUNE_LOW_POWER: Tune encoder for low power / + * resources conditions. This can affect compression ratio or visual + * quality to match low power conditions. + * + * The set of tuning options for a #GstVaapiEncoder. By default, + * maximum compatibility for decoding is preferred, so the lowest + * coding tools are enabled. + */ +typedef enum { + GST_VAAPI_ENCODER_TUNE_NONE = 0, + GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION, + GST_VAAPI_ENCODER_TUNE_LOW_LATENCY, + GST_VAAPI_ENCODER_TUNE_LOW_POWER, +} GstVaapiEncoderTune; + +/** * 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). + * @GST_VAAPI_ENCODER_PROP_TUNE: The tuning options (#GstVaapiEncoderTune). * * The set of configurable properties for the encoder. */ @@ -81,6 +103,7 @@ typedef enum { GST_VAAPI_ENCODER_PROP_RATECONTROL = 1, GST_VAAPI_ENCODER_PROP_BITRATE, GST_VAAPI_ENCODER_PROP_KEYFRAME_PERIOD, + GST_VAAPI_ENCODER_PROP_TUNE, } GstVaapiEncoderProp; /** @@ -95,6 +118,9 @@ typedef struct { GParamSpec *const pspec; } GstVaapiEncoderPropInfo; +GType +gst_vaapi_encoder_tune_get_type (void) G_GNUC_CONST; + GstVaapiEncoder * gst_vaapi_encoder_ref (GstVaapiEncoder * encoder); @@ -133,6 +159,10 @@ gst_vaapi_encoder_set_keyframe_period (GstVaapiEncoder * encoder, guint keyframe_period); GstVaapiEncoderStatus +gst_vaapi_encoder_set_tuning (GstVaapiEncoder * encoder, + GstVaapiEncoderTune tuning); + +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 28bccd8..050c144 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h264.c @@ -47,6 +47,10 @@ GST_VAAPI_RATECONTROL_MASK (VBR) | \ GST_VAAPI_RATECONTROL_MASK (VBR_CONSTRAINED)) +/* Supported set of tuning options, within this implementation */ +#define SUPPORTED_TUNE_OPTIONS \ + (GST_VAAPI_ENCODER_TUNE_MASK (NONE)) + #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_NONE 0 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_LOW 1 #define GST_VAAPI_ENCODER_H264_NAL_REF_IDC_MEDIUM 2 diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c index 6f5ca72..4f25218 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_mpeg2.c @@ -46,6 +46,10 @@ GST_VAAPI_RATECONTROL_MASK (CQP) | \ GST_VAAPI_RATECONTROL_MASK (CBR)) +/* Supported set of tuning options, within this implementation */ +#define SUPPORTED_TUNE_OPTIONS \ + (GST_VAAPI_ENCODER_TUNE_MASK (NONE)) + static gboolean gst_bit_writer_write_sps (GstBitWriter * bitwriter, VAEncSequenceParameterBufferMPEG2 * seq, GstVaapiEncoderMpeg2 * encoder); diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h index 78d9da0..abe3309 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapiencoder_priv.h @@ -139,6 +139,24 @@ G_BEGIN_DECLS #define GST_VAAPI_ENCODER_KEYFRAME_PERIOD(encoder) \ (GST_VAAPI_ENCODER_CAST (encoder)->keyframe_period) +/** + * GST_VAAPI_ENCODER_TUNE: + * @encoder: a #GstVaapiEncoder + * + * Macro that evaluates to the tuning option. + * This is an internal macro that does not do any run-time type check. + */ +#undef GST_VAAPI_ENCODER_TUNE +#define GST_VAAPI_ENCODER_TUNE(encoder) \ + (GST_VAAPI_ENCODER_CAST (encoder)->tune) + +/* Generate a mask for the supplied tuning option (internal) */ +#define GST_VAAPI_ENCODER_TUNE_MASK(TUNE) \ + (1U << G_PASTE (GST_VAAPI_ENCODER_TUNE_, TUNE)) + +#define GST_VAAPI_TYPE_ENCODER_TUNE \ + (gst_vaapi_encoder_tune_get_type ()) + typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass; typedef struct _GstVaapiEncoderClassData GstVaapiEncoderClassData; @@ -172,6 +190,7 @@ struct _GstVaapiEncoder GstVaapiDisplay *display; GstVaapiContext *context; GstVaapiContextInfo context_info; + GstVaapiEncoderTune tune; VADisplay va_display; VAContextID va_context; @@ -200,6 +219,10 @@ struct _GstVaapiEncoderClassData GType (*rate_control_get_type)(void); GstVaapiRateControl default_rate_control; guint32 rate_control_mask; + + GType (*encoder_tune_get_type)(void); + GstVaapiEncoderTune default_encoder_tune; + guint32 encoder_tune_mask; }; #define GST_VAAPI_ENCODER_DEFINE_CLASS_DATA(CODEC) \ @@ -208,12 +231,21 @@ struct _GstVaapiEncoderClassData G_PASTE (gst_vaapi_rate_control_, CODEC), \ GST_VAAPI_TYPE_RATE_CONTROL, SUPPORTED_RATECONTROLS); \ \ + GST_VAAPI_TYPE_DEFINE_ENUM_SUBSET_FROM_MASK( \ + G_PASTE (GstVaapiEncoderTune, CODEC), \ + G_PASTE (gst_vaapi_encoder_tune_, CODEC), \ + GST_VAAPI_TYPE_ENCODER_TUNE, SUPPORTED_TUNE_OPTIONS); \ + \ static const GstVaapiEncoderClassData g_class_data = { \ .codec = G_PASTE (GST_VAAPI_CODEC_, CODEC), \ .rate_control_get_type = \ G_PASTE (G_PASTE (gst_vaapi_rate_control_, CODEC), _get_type), \ .default_rate_control = DEFAULT_RATECONTROL, \ .rate_control_mask = SUPPORTED_RATECONTROLS, \ + .encoder_tune_get_type = \ + G_PASTE (G_PASTE (gst_vaapi_encoder_tune_, CODEC), _get_type), \ + .default_encoder_tune = GST_VAAPI_ENCODER_TUNE_NONE, \ + .encoder_tune_mask = SUPPORTED_TUNE_OPTIONS, \ } struct _GstVaapiEncoderClass -- 2.7.4