fdkaacenc: Add support for setting bitrate mode

This commit is contained in:
Sanchayan Maity 2022-10-29 12:19:58 +05:30
parent 595dd7a1ed
commit f0ceb9ea4f
3 changed files with 213 additions and 4 deletions

View file

@ -16753,14 +16753,84 @@
"readable": true, "readable": true,
"type": "gint", "type": "gint",
"writable": true "writable": true
} },
"rate-control": {
"blurb": "Whether Constant or Variable Bitrate should be used",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "cbr (0)",
"mutable": "null",
"readable": true,
"type": "GstFdkAacRateControl",
"writable": true
},
"vbr-preset": {
"blurb": "AAC Variable Bitrate configurations",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "medium (3)",
"mutable": "null",
"readable": true,
"type": "GstFdkAacVbrPreset",
"writable": true
}
}, },
"rank": "primary" "rank": "primary"
} }
}, },
"filename": "gstfdkaac", "filename": "gstfdkaac",
"license": "LGPL", "license": "LGPL",
"other-types": {}, "other-types": {
"GstFdkAacRateControl": {
"kind": "enum",
"values": [
{
"desc": "Constant Bitrate",
"name": "cbr",
"value": "0"
},
{
"desc": "Variable Bitrate",
"name": "vbr",
"value": "1"
}
]
},
"GstFdkAacVbrPreset": {
"kind": "enum",
"values": [
{
"desc": "Very Low Variable Bitrate",
"name": "very-low",
"value": "1"
},
{
"desc": "Low Variable Bitrate",
"name": "low",
"value": "2"
},
{
"desc": "Medium Variable Bitrate",
"name": "medium",
"value": "3"
},
{
"desc": "High Variable Bitrate",
"name": "high",
"value": "4"
},
{
"desc": "Very High Variable Bitrate",
"name": "very-high",
"value": "5"
}
]
}
},
"package": "GStreamer Bad Plug-ins", "package": "GStreamer Bad Plug-ins",
"source": "gst-plugins-bad", "source": "gst-plugins-bad",
"tracers": {}, "tracers": {},

View file

@ -30,7 +30,6 @@
/* TODO: /* TODO:
* - Add support for other AOT / profiles * - Add support for other AOT / profiles
* - Expose more properties, e.g. vbr
* - Signal encoder delay * - Signal encoder delay
* - LOAS / LATM support * - LOAS / LATM support
*/ */
@ -40,11 +39,15 @@ enum
PROP_0, PROP_0,
PROP_AFTERBURNER, PROP_AFTERBURNER,
PROP_BITRATE, PROP_BITRATE,
PROP_PEAK_BITRATE PROP_PEAK_BITRATE,
PROP_RATE_CONTROL,
PROP_VBR_PRESET,
}; };
#define DEFAULT_BITRATE (0) #define DEFAULT_BITRATE (0)
#define DEFAULT_PEAK_BITRATE (0) #define DEFAULT_PEAK_BITRATE (0)
#define DEFAULT_RATE_CONTROL (GST_FDK_AAC_RATE_CONTROL_CONSTANT_BITRATE)
#define DEFAULT_VBR_PRESET (GST_FDK_AAC_VBR_PRESET_MEDIUM)
#define SAMPLE_RATES " 8000, " \ #define SAMPLE_RATES " 8000, " \
"11025, " \ "11025, " \
@ -102,6 +105,45 @@ G_DEFINE_TYPE (GstFdkAacEnc, gst_fdkaacenc, GST_TYPE_AUDIO_ENCODER);
GST_ELEMENT_REGISTER_DEFINE (fdkaacenc, "fdkaacenc", GST_RANK_PRIMARY, GST_ELEMENT_REGISTER_DEFINE (fdkaacenc, "fdkaacenc", GST_RANK_PRIMARY,
GST_TYPE_FDKAACENC); GST_TYPE_FDKAACENC);
#define GST_FDK_AAC_VBR_PRESET (gst_fdk_aac_vbr_preset_get_type ())
static GType
gst_fdk_aac_vbr_preset_get_type (void)
{
static GType fdk_aac_vbr_preset_type = 0;
static const GEnumValue vbr_preset_types[] = {
{GST_FDK_AAC_VBR_PRESET_VERY_LOW, "Very Low Variable Bitrate", "very-low"},
{GST_FDK_AAC_VBR_PRESET_LOW, "Low Variable Bitrate", "low"},
{GST_FDK_AAC_VBR_PRESET_MEDIUM, "Medium Variable Bitrate", "medium"},
{GST_FDK_AAC_VBR_PRESET_HIGH, "High Variable Bitrate", "high"},
{GST_FDK_AAC_VBR_PRESET_VERY_HIGH, "Very High Variable Bitrate",
"very-high"},
{0, NULL, NULL}
};
if (!fdk_aac_vbr_preset_type)
fdk_aac_vbr_preset_type =
g_enum_register_static ("GstFdkAacVbrPreset", vbr_preset_types);
return fdk_aac_vbr_preset_type;
}
#define GST_FDK_AAC_RATE_CONTROL (gst_fdk_aac_rate_control_get_type ())
static GType
gst_fdk_aac_rate_control_get_type (void)
{
static GType fdk_aac_rate_control_type = 0;
static const GEnumValue rate_control_types[] = {
{GST_FDK_AAC_RATE_CONTROL_CONSTANT_BITRATE, "Constant Bitrate", "cbr"},
{GST_FDK_AAC_RATE_CONTROL_VARIABLE_BITRATE, "Variable Bitrate", "vbr"},
};
if (!fdk_aac_rate_control_type)
fdk_aac_rate_control_type =
g_enum_register_static ("GstFdkAacRateControl", rate_control_types);
return fdk_aac_rate_control_type;
}
static void static void
gst_fdkaacenc_set_property (GObject * object, guint prop_id, gst_fdkaacenc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec) const GValue * value, GParamSpec * pspec)
@ -118,6 +160,12 @@ gst_fdkaacenc_set_property (GObject * object, guint prop_id,
case PROP_PEAK_BITRATE: case PROP_PEAK_BITRATE:
self->peak_bitrate = g_value_get_int (value); self->peak_bitrate = g_value_get_int (value);
break; break;
case PROP_RATE_CONTROL:
self->rate_control = g_value_get_enum (value);
break;
case PROP_VBR_PRESET:
self->vbr_preset = g_value_get_enum (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -141,6 +189,12 @@ gst_fdkaacenc_get_property (GObject * object, guint prop_id,
case PROP_PEAK_BITRATE: case PROP_PEAK_BITRATE:
g_value_set_int (value, self->peak_bitrate); g_value_set_int (value, self->peak_bitrate);
break; break;
case PROP_RATE_CONTROL:
g_value_set_enum (value, self->rate_control);
break;
case PROP_VBR_PRESET:
g_value_set_enum (value, self->vbr_preset);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -242,6 +296,7 @@ gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
CHANNEL_MODE channel_mode; CHANNEL_MODE channel_mode;
AACENC_InfoStruct enc_info = { 0 }; AACENC_InfoStruct enc_info = { 0 };
gint bitrate, signaling_mode; gint bitrate, signaling_mode;
guint bitrate_mode;
if (self->enc && !self->is_drained) { if (self->enc && !self->is_drained) {
/* drain */ /* drain */
@ -442,6 +497,23 @@ gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
return FALSE; return FALSE;
} }
if (self->rate_control == GST_FDK_AAC_RATE_CONTROL_CONSTANT_BITRATE) {
/*
* Note that the `bitrate` property is honoured only when using
* constant bit rate.
*/
bitrate_mode = 0; // Constant Bitrate
} else {
bitrate_mode = self->vbr_preset;
}
if ((err = aacEncoder_SetParam (self->enc, AACENC_BITRATEMODE,
bitrate_mode)) != AACENC_OK) {
GST_ERROR_OBJECT (self, "Unable to set bitrate mode %d: %d",
bitrate_mode, err);
return FALSE;
}
if (self->peak_bitrate) { if (self->peak_bitrate) {
if ((err = aacEncoder_SetParam (self->enc, AACENC_PEAK_BITRATE, if ((err = aacEncoder_SetParam (self->enc, AACENC_PEAK_BITRATE,
self->peak_bitrate)) != AACENC_OK) { self->peak_bitrate)) != AACENC_OK) {
@ -651,6 +723,8 @@ gst_fdkaacenc_init (GstFdkAacEnc * self)
self->is_drained = TRUE; self->is_drained = TRUE;
self->afterburner = FALSE; self->afterburner = FALSE;
self->peak_bitrate = DEFAULT_PEAK_BITRATE; self->peak_bitrate = DEFAULT_PEAK_BITRATE;
self->rate_control = DEFAULT_RATE_CONTROL;
self->vbr_preset = DEFAULT_VBR_PRESET;
gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (self), TRUE); gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (self), TRUE);
} }
@ -706,6 +780,33 @@ gst_fdkaacenc_class_init (GstFdkAacEncClass * klass)
g_param_spec_boolean ("afterburner", "Afterburner - Quality Parameter", g_param_spec_boolean ("afterburner", "Afterburner - Quality Parameter",
"Additional quality control parameter. Can cause workload increase.", "Additional quality control parameter. Can cause workload increase.",
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstFdkAacEnc:rate-control:
*
* Rate Control.
*
* Since: 1.22
*/
g_object_class_install_property (object_class, PROP_RATE_CONTROL,
g_param_spec_enum ("rate-control", "Rate Control",
"Whether Constant or Variable Bitrate should be used.",
GST_FDK_AAC_RATE_CONTROL, DEFAULT_RATE_CONTROL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstFdkAacEnc:vbr-preset:
*
* AAC Variable Bitrate configurations.
*
* Since: 1.22
*/
g_object_class_install_property (object_class, PROP_VBR_PRESET,
g_param_spec_enum ("vbr-preset", "Variable Bitrate Preset",
"AAC Variable Bitrate configurations. Requires rate-control as vbr.",
GST_FDK_AAC_VBR_PRESET, DEFAULT_VBR_PRESET,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_static_pad_template (element_class, &sink_template); gst_element_class_add_static_pad_template (element_class, &sink_template);
gst_element_class_add_static_pad_template (element_class, &src_template); gst_element_class_add_static_pad_template (element_class, &src_template);
@ -715,4 +816,7 @@ gst_fdkaacenc_class_init (GstFdkAacEncClass * klass)
GST_DEBUG_CATEGORY_INIT (gst_fdkaacenc_debug, "fdkaacenc", 0, GST_DEBUG_CATEGORY_INIT (gst_fdkaacenc_debug, "fdkaacenc", 0,
"fdkaac encoder"); "fdkaac encoder");
gst_type_mark_as_plugin_api (GST_FDK_AAC_VBR_PRESET, 0);
gst_type_mark_as_plugin_api (GST_FDK_AAC_RATE_CONTROL, 0);
} }

View file

@ -41,6 +41,38 @@ G_BEGIN_DECLS
typedef struct _GstFdkAacEnc GstFdkAacEnc; typedef struct _GstFdkAacEnc GstFdkAacEnc;
typedef struct _GstFdkAacEncClass GstFdkAacEncClass; typedef struct _GstFdkAacEncClass GstFdkAacEncClass;
/**
* GstFdkAacVbrPreset:
* @GST_FDK_AAC_VBR_PRESET_VERY_LOW: Very Low Variable Bitrate.
* @GST_FDK_AAC_VBR_PRESET_LOW: Low Variable Bitrate.
* @GST_FDK_AAC_VBR_PRESET_MEDIUM: Medium Variable Bitrate.
* @GST_FDK_AAC_VBR_PRESET_HIGH: High Variable Bitrate.
* @GST_FDK_AAC_VBR_PRESET_VERY_HIGH: Very High Variable Bitrate.
*
* Since: 1.22
*/
typedef enum
{
GST_FDK_AAC_VBR_PRESET_VERY_LOW = 1,
GST_FDK_AAC_VBR_PRESET_LOW,
GST_FDK_AAC_VBR_PRESET_MEDIUM,
GST_FDK_AAC_VBR_PRESET_HIGH,
GST_FDK_AAC_VBR_PRESET_VERY_HIGH
} GstFdkAacVbrPreset;
/**
* GstFdkAacRateControl:
* @GST_FDK_AAC_RATE_CONTROL_CONSTANT_BITRATE: Constant Bitrate.
* @GST_FDK_AAC_RATE_CONTROL_VARIABLE_BITRATE: Variable Bitrate.
*
* Since: 1.22
*/
typedef enum
{
GST_FDK_AAC_RATE_CONTROL_CONSTANT_BITRATE = 0,
GST_FDK_AAC_RATE_CONTROL_VARIABLE_BITRATE,
} GstFdkAacRateControl;
struct _GstFdkAacEnc { struct _GstFdkAacEnc {
GstAudioEncoder element; GstAudioEncoder element;
@ -54,6 +86,9 @@ struct _GstFdkAacEnc {
guint peak_bitrate; guint peak_bitrate;
gboolean afterburner; gboolean afterburner;
GstFdkAacRateControl rate_control;
GstFdkAacVbrPreset vbr_preset;
}; };
struct _GstFdkAacEncClass { struct _GstFdkAacEncClass {