From 59529ae918d49f16a5782fd94d260c8ad944d6f6 Mon Sep 17 00:00:00 2001 From: Yatin Mann Date: Mon, 11 Jul 2022 11:03:16 +0530 Subject: [PATCH] aom: av1enc: Expose more properties Part-of: --- .../docs/plugins/gst_plugins_cache.json | 112 ++++++++++++- .../gst-plugins-bad/ext/aom/gstav1enc.c | 150 +++++++++++++++++- .../gst-plugins-bad/ext/aom/gstav1enc.h | 57 ++++++- 3 files changed, 314 insertions(+), 5 deletions(-) diff --git a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json index 00d4861048..d8cc112d78 100644 --- a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json @@ -1204,7 +1204,7 @@ "construct-only": false, "controllable": false, "default": "0", - "max": "5", + "max": "10", "min": "0", "mutable": "null", "readable": true, @@ -1225,6 +1225,18 @@ "type": "guint", "writable": true }, + "enc-pass": { + "blurb": "Current phase for multi-pass encoding or @GST_AV1_ENC_ONE_PASS for single pass", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "one-pass (0)", + "mutable": "null", + "readable": true, + "type": "GstAV1EncEncPass", + "writable": true + }, "end-usage": { "blurb": "Rate control algorithm to use, indicates the end usage of this stream", "conditionally-available": false, @@ -1237,6 +1249,32 @@ "type": "GstAV1EncEndUsageMode", "writable": true }, + "keyframe-mode": { + "blurb": "Determines whether keyframes are placed automatically by the encoder", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "auto (1)", + "mutable": "null", + "readable": true, + "type": "GstAV1EncKFMode", + "writable": true + }, + "lag-in-frames": { + "blurb": "Maximum number of future frames the encoder is allowed to consume before producing the current output frame. Set value to 0 for disabling lagged encoding.", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "-1", + "min": "0", + "mutable": "null", + "readable": true, + "type": "guint", + "writable": true + }, "max-quantizer": { "blurb": "Maximum (worst quality) quantizer", "conditionally-available": false, @@ -1468,6 +1506,18 @@ "readable": true, "type": "guint", "writable": true + }, + "usage-profile": { + "blurb": "Usage profile is used to guide the default config for the encoder", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "good-quality (0)", + "mutable": "null", + "readable": true, + "type": "GstAV1EncUsageProfile", + "writable": true } }, "rank": "primary" @@ -1476,6 +1526,31 @@ "filename": "gstaom", "license": "LGPL", "other-types": { + "GstAV1EncEncPass": { + "kind": "enum", + "values": [ + { + "desc": "Single pass mode", + "name": "one-pass", + "value": "0" + }, + { + "desc": "First pass of multi-pass mode", + "name": "first-pass", + "value": "1" + }, + { + "desc": "Second pass of multi-pass mode", + "name": "second-pass", + "value": "2" + }, + { + "desc": "Third pass of multi-pass mode", + "name": "third-pass", + "value": "3" + } + ] + }, "GstAV1EncEndUsageMode": { "kind": "enum", "values": [ @@ -1501,6 +1576,21 @@ } ] }, + "GstAV1EncKFMode": { + "kind": "enum", + "values": [ + { + "desc": "Encoder determines optimal keyframe placement automatically", + "name": "auto", + "value": "1" + }, + { + "desc": "Encoder does not place keyframes", + "name": "disabled", + "value": "0" + } + ] + }, "GstAV1EncResizeMode": { "kind": "enum", "values": [ @@ -1545,6 +1635,26 @@ "value": "3" } ] + }, + "GstAV1EncUsageProfile": { + "kind": "enum", + "values": [ + { + "desc": "Good Quality profile", + "name": "good-quality", + "value": "0" + }, + { + "desc": "Realtime profile", + "name": "realtime", + "value": "1" + }, + { + "desc": "All Intra profile", + "name": "all-intra", + "value": "2" + } + ] } }, "package": "GStreamer Bad Plug-ins", diff --git a/subprojects/gst-plugins-bad/ext/aom/gstav1enc.c b/subprojects/gst-plugins-bad/ext/aom/gstav1enc.c index cb32d98d75..a3fcfb089f 100644 --- a/subprojects/gst-plugins-bad/ext/aom/gstav1enc.c +++ b/subprojects/gst-plugins-bad/ext/aom/gstav1enc.c @@ -116,6 +116,63 @@ gst_end_usage_mode_get_type (void) return end_usage_mode_type; } +#define GST_TYPE_KF_MODE (gst_kf_mode_get_type()) +static GType +gst_kf_mode_get_type (void) +{ + static GType kf_mode_type = 0; + static const GEnumValue kf_mode[] = { + {GST_AV1_ENC_KF_AUTO, + "Encoder determines optimal keyframe placement automatically", + "auto"}, + {GST_AV1_ENC_KF_DISABLED, "Encoder does not place keyframes", "disabled"}, + {0, NULL, NULL}, + }; + + if (!kf_mode_type) { + kf_mode_type = g_enum_register_static ("GstAV1EncKFMode", kf_mode); + } + return kf_mode_type; +} + +#define GST_TYPE_ENC_PASS (gst_enc_pass_get_type()) +static GType +gst_enc_pass_get_type (void) +{ + static GType enc_pass_type = 0; + static const GEnumValue enc_pass[] = { + {GST_AV1_ENC_ONE_PASS, "Single pass mode", "one-pass"}, + {GST_AV1_ENC_FIRST_PASS, "First pass of multi-pass mode", "first-pass"}, + {GST_AV1_ENC_SECOND_PASS, "Second pass of multi-pass mode", "second-pass"}, + {GST_AV1_ENC_THIRD_PASS, "Third pass of multi-pass mode", "third-pass"}, + {0, NULL, NULL}, + }; + + if (!enc_pass_type) { + enc_pass_type = g_enum_register_static ("GstAV1EncEncPass", enc_pass); + } + return enc_pass_type; +} + +#define GST_TYPE_USAGE_PROFILE (gst_usage_profile_get_type()) +static GType +gst_usage_profile_get_type (void) +{ + static GType usage_profile_type = 0; + static const GEnumValue usage_profile[] = { + {GST_AV1_ENC_USAGE_GOOD_QUALITY, "Good Quality profile", "good-quality"}, + {GST_AV1_ENC_USAGE_REALTIME, "Realtime profile", "realtime"}, + {GST_AV1_ENC_USAGE_ALL_INTRA, "All Intra profile", "all-intra"}, + {0, NULL, NULL}, + }; + + if (!usage_profile_type) { + usage_profile_type = + g_enum_register_static ("GstAV1EncUsageProfile", usage_profile); + } + return usage_profile_type; +} + enum { LAST_SIGNAL @@ -146,7 +203,11 @@ enum PROP_THREADS, PROP_ROW_MT, PROP_TILE_COLUMNS, - PROP_TILE_ROWS + PROP_TILE_ROWS, + PROP_KF_MODE, + PROP_ENC_PASS, + PROP_USAGE_PROFILE, + PROP_LAG_IN_FRAMES, }; /* From av1/av1_cx_iface.c */ @@ -177,6 +238,10 @@ enum #define DEFAULT_ROW_MT TRUE #define DEFAULT_TILE_COLUMNS 0 #define DEFAULT_TILE_ROWS 0 +#define DEFAULT_KF_MODE GST_AV1_ENC_KF_AUTO +#define DEFAULT_ENC_PASS GST_AV1_ENC_ONE_PASS +#define DEFAULT_USAGE_PROFILE GST_AV1_ENC_USAGE_GOOD_QUALITY +#define DEFAULT_LAG_IN_FRAMES 0 static void gst_av1_enc_finalize (GObject * object); static void gst_av1_enc_set_property (GObject * object, guint prop_id, @@ -259,7 +324,7 @@ gst_av1_enc_class_init (GstAV1EncClass * klass) g_object_class_install_property (gobject_class, PROP_CPU_USED, g_param_spec_int ("cpu-used", "CPU Used", "CPU Used. A Value greater than 0 will increase encoder speed at the expense of quality.", - 0, 5, DEFAULT_CPU_USED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + 0, 10, DEFAULT_CPU_USED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /* Rate control configurations */ g_object_class_install_property (gobject_class, PROP_DROP_FRAME, @@ -400,9 +465,58 @@ gst_av1_enc_class_init (GstAV1EncClass * klass) "can enable parallel encoding", 0, 6, DEFAULT_TILE_ROWS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * av1enc:keyframe-mode: + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_KF_MODE, + g_param_spec_enum ("keyframe-mode", "Keyframe placement mode", + "Determines whether keyframes are placed automatically by the encoder", + GST_TYPE_KF_MODE, DEFAULT_KF_MODE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * av1enc:enc-pass: + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_ENC_PASS, + g_param_spec_enum ("enc-pass", "Multi-pass Encoding Pass", + "Current phase for multi-pass encoding or @GST_AV1_ENC_ONE_PASS for single pass", + GST_TYPE_ENC_PASS, DEFAULT_ENC_PASS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * av1enc:usage-profile: + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_USAGE_PROFILE, + g_param_spec_enum ("usage-profile", "Usage value", + "Usage profile is used to guide the default config for the encoder", + GST_TYPE_USAGE_PROFILE, DEFAULT_USAGE_PROFILE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * av1enc:lag-in-frames: + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_LAG_IN_FRAMES, + g_param_spec_uint ("lag-in-frames", "Allow lagged encoding", + "Maximum number of future frames the encoder is allowed to consume " + "before producing the current output frame. " + "Set value to 0 for disabling lagged encoding.", + 0, G_MAXUINT, DEFAULT_LAG_IN_FRAMES, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_type_mark_as_plugin_api (GST_TYPE_END_USAGE_MODE, 0); gst_type_mark_as_plugin_api (GST_TYPE_RESIZE_MODE, 0); gst_type_mark_as_plugin_api (GST_TYPE_SUPERRES_MODE, 0); + gst_type_mark_as_plugin_api (GST_TYPE_KF_MODE, 0); + gst_type_mark_as_plugin_api (GST_TYPE_ENC_PASS, 0); + gst_type_mark_as_plugin_api (GST_TYPE_USAGE_PROFILE, 0); } static void @@ -457,6 +571,10 @@ gst_av1_enc_init (GstAV1Enc * av1enc) av1enc->aom_cfg.g_timebase.den = DEFAULT_TIMEBASE_D; av1enc->aom_cfg.g_bit_depth = DEFAULT_BIT_DEPTH; av1enc->aom_cfg.g_input_bit_depth = (unsigned int) DEFAULT_BIT_DEPTH; + av1enc->aom_cfg.kf_mode = (enum aom_kf_mode) DEFAULT_KF_MODE; + av1enc->aom_cfg.g_pass = (enum aom_enc_pass) DEFAULT_ENC_PASS; + av1enc->aom_cfg.g_usage = (unsigned int) DEFAULT_USAGE_PROFILE; + av1enc->aom_cfg.g_lag_in_frames = DEFAULT_LAG_IN_FRAMES; g_mutex_init (&av1enc->encoder_lock); } @@ -1069,6 +1187,22 @@ gst_av1_enc_set_property (GObject * object, guint prop_id, GST_AV1_ENC_APPLY_CODEC_CONTROL (av1enc, AV1E_SET_TILE_ROWS, av1enc->tile_rows); break; + case PROP_KF_MODE: + av1enc->aom_cfg.kf_mode = g_value_get_enum (value); + global = TRUE; + break; + case PROP_ENC_PASS: + av1enc->aom_cfg.g_pass = g_value_get_enum (value); + global = TRUE; + break; + case PROP_USAGE_PROFILE: + av1enc->aom_cfg.g_usage = g_value_get_enum (value); + global = TRUE; + break; + case PROP_LAG_IN_FRAMES: + av1enc->aom_cfg.g_lag_in_frames = g_value_get_uint (value); + global = TRUE; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1164,6 +1298,18 @@ gst_av1_enc_get_property (GObject * object, guint prop_id, GValue * value, case PROP_TILE_ROWS: g_value_set_uint (value, av1enc->tile_rows); break; + case PROP_KF_MODE: + g_value_set_enum (value, av1enc->aom_cfg.kf_mode); + break; + case PROP_ENC_PASS: + g_value_set_enum (value, av1enc->aom_cfg.g_pass); + break; + case PROP_USAGE_PROFILE: + g_value_set_enum (value, av1enc->aom_cfg.g_usage); + break; + case PROP_LAG_IN_FRAMES: + g_value_set_uint (value, av1enc->aom_cfg.g_lag_in_frames); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/subprojects/gst-plugins-bad/ext/aom/gstav1enc.h b/subprojects/gst-plugins-bad/ext/aom/gstav1enc.h index bcf3ddb1f5..c52d650180 100644 --- a/subprojects/gst-plugins-bad/ext/aom/gstav1enc.h +++ b/subprojects/gst-plugins-bad/ext/aom/gstav1enc.h @@ -65,7 +65,7 @@ typedef enum } GstAV1EncResizeMode; /** - * GstAV1EncSuperresMode + * GstAV1EncSuperresMode: * @GST_AV1_ENC_SUPERRES_NONE: No frame superres allowed * @GST_AV1_ENC_SUPERRES_FIXED: All frames are coded at the specified scale and * super-resolved @@ -83,7 +83,7 @@ typedef enum } GstAV1EncSuperresMode; /** - * GstAV1EncEndUsageMode + * GstAV1EncEndUsageMode: * @GST_AV1_ENC_END_USAGE_VBR: Variable Bit Rate Mode * @GST_AV1_ENC_END_USAGE_CBR: Constant Bit Rate Mode * @GST_AV1_ENC_END_USAGE_CQ: Constrained Quality Mode @@ -100,6 +100,59 @@ typedef enum GST_AV1_ENC_END_USAGE_Q = 3, } GstAV1EncEndUsageMode; +/** + * GstAV1EncKFMode: + * @GST_AV1_ENC_KF_DISABLED: Encoder does not place keyframes + * @GST_AV1_ENC_KF_AUTO: Encoder determines optimal keyframe placement automatically + * + * Determines whether keyframes are placed automatically by the encoder + * + * Since: 1.22 + */ + +typedef enum +{ + GST_AV1_ENC_KF_DISABLED = 0, + GST_AV1_ENC_KF_AUTO = 1, +} GstAV1EncKFMode; + +/** + * GstAV1EncEncPass: + * @GST_AV1_ENC_ONE_PASS: Single pass mode + * @GST_AV1_ENC_FIRST_PASS: First pass of multi-pass mode + * @GST_AV1_ENC_SECOND_PASS: Second pass of multi-pass mode + * @GST_AV1_ENC_THIRD_PASS: Third pass of multi-pass mode + * Current phase for multi-pass encoding or @GST_AV1_ENC_ONE_PASS for single pass + * + * Since: 1.22 + */ + +typedef enum +{ + GST_AV1_ENC_ONE_PASS = 0, + GST_AV1_ENC_FIRST_PASS = 1, + GST_AV1_ENC_SECOND_PASS = 2, + GST_AV1_ENC_THIRD_PASS = 3, +} GstAV1EncEncPass; + +/** + * GstAV1EncUsageProfile: + * @GST_AV1_ENC_USAGE_GOOD_QUALITY: Good Quality profile + * @GST_AV1_ENC_USAGE_REALTIME: Realtime profile + * @GST_AV1_ENC_USAGE_ALL_INTRA: All Intra profile + * + * Usage profile is used to guide the default config for the encoder + * + * Since: 1.22 + */ + +typedef enum +{ + GST_AV1_ENC_USAGE_GOOD_QUALITY = 0, + GST_AV1_ENC_USAGE_REALTIME = 1, + GST_AV1_ENC_USAGE_ALL_INTRA = 2, +} GstAV1EncUsageProfile; + struct _GstAV1Enc { GstVideoEncoder base_video_encoder;