mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
fdkaacenc: add support for HE-AACv1 and HE-AACv2
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1785>
This commit is contained in:
parent
2a59e8af97
commit
8cda666cb0
2 changed files with 62 additions and 8 deletions
|
@ -16708,7 +16708,7 @@
|
||||||
"presence": "always"
|
"presence": "always"
|
||||||
},
|
},
|
||||||
"src": {
|
"src": {
|
||||||
"caps": "audio/mpeg:\n mpegversion: 4\n rate: { (int)8000, (int)11025, (int)12000, (int)16000, (int)22050, (int)24000, (int)32000, (int)44100, (int)48000, (int)64000, (int)88200, (int)96000 }\n channels: { (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)8 }\n stream-format: { (string)adts, (string)adif, (string)raw }\n base-profile: lc\n framed: true\n",
|
"caps": "audio/mpeg:\n mpegversion: 4\n rate: { (int)8000, (int)11025, (int)12000, (int)16000, (int)22050, (int)24000, (int)32000, (int)44100, (int)48000, (int)64000, (int)88200, (int)96000 }\n channels: { (int)1, (int)2, (int)3, (int)4, (int)5, (int)6, (int)8 }\n stream-format: { (string)adts, (string)adif, (string)raw }\n profile: { (string)lc, (string)sbr, (string)ps }\n framed: true\n",
|
||||||
"direction": "src",
|
"direction": "src",
|
||||||
"presence": "always"
|
"presence": "always"
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
"rate = (int) { " SAMPLE_RATES " }, "
|
"rate = (int) { " SAMPLE_RATES " }, "
|
||||||
"channels = (int) {1, 2, 3, 4, 5, 6, 8}, "
|
"channels = (int) {1, 2, 3, 4, 5, 6, 8}, "
|
||||||
"stream-format = (string) { adts, adif, raw }, "
|
"stream-format = (string) { adts, adif, raw }, "
|
||||||
"base-profile = (string) lc, " "framed = (boolean) true")
|
"profile = (string) { lc, sbr, ps }, " "framed = (boolean) true")
|
||||||
);
|
);
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_fdkaacenc_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_fdkaacenc_debug);
|
||||||
|
@ -162,14 +162,34 @@ static GstCaps *
|
||||||
gst_fdkaacenc_get_caps (GstAudioEncoder * enc, GstCaps * filter)
|
gst_fdkaacenc_get_caps (GstAudioEncoder * enc, GstCaps * filter)
|
||||||
{
|
{
|
||||||
const GstFdkAacChannelLayout *layout;
|
const GstFdkAacChannelLayout *layout;
|
||||||
GstCaps *res, *caps;
|
GstCaps *res, *caps, *allowed_caps;
|
||||||
|
gboolean allow_mono = TRUE;
|
||||||
|
|
||||||
|
allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (enc));
|
||||||
|
GST_DEBUG_OBJECT (enc, "allowed caps %" GST_PTR_FORMAT, allowed_caps);
|
||||||
|
|
||||||
|
/* We need at least 2 channels if Parametric Stereo is in use. */
|
||||||
|
if (allowed_caps && gst_caps_get_size (allowed_caps) > 0) {
|
||||||
|
GstStructure *s = gst_caps_get_structure (allowed_caps, 0);
|
||||||
|
const gchar *profile = NULL;
|
||||||
|
|
||||||
|
if ((profile = gst_structure_get_string (s, "profile"))
|
||||||
|
&& strcmp (profile, "ps") == 0) {
|
||||||
|
allow_mono = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gst_clear_caps (&allowed_caps);
|
||||||
|
|
||||||
caps = gst_caps_new_empty ();
|
caps = gst_caps_new_empty ();
|
||||||
|
|
||||||
for (layout = channel_layouts; layout->channels; layout++) {
|
for (layout = channel_layouts; layout->channels; layout++) {
|
||||||
|
GstCaps *tmp;
|
||||||
gint channels = layout->channels;
|
gint channels = layout->channels;
|
||||||
GstCaps *tmp =
|
|
||||||
gst_caps_make_writable (gst_pad_get_pad_template_caps
|
if (channels == 1 && !allow_mono)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tmp = gst_caps_make_writable (gst_pad_get_pad_template_caps
|
||||||
(GST_AUDIO_ENCODER_SINK_PAD (enc)));
|
(GST_AUDIO_ENCODER_SINK_PAD (enc)));
|
||||||
|
|
||||||
if (channels == 1) {
|
if (channels == 1) {
|
||||||
|
@ -203,7 +223,8 @@ gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
|
||||||
gint mpegversion = 4;
|
gint mpegversion = 4;
|
||||||
CHANNEL_MODE channel_mode;
|
CHANNEL_MODE channel_mode;
|
||||||
AACENC_InfoStruct enc_info = { 0 };
|
AACENC_InfoStruct enc_info = { 0 };
|
||||||
gint bitrate;
|
gint bitrate, signaling_mode;
|
||||||
|
const gchar *ext_profile;
|
||||||
|
|
||||||
if (self->enc && !self->is_drained) {
|
if (self->enc && !self->is_drained) {
|
||||||
/* drain */
|
/* drain */
|
||||||
|
@ -233,6 +254,19 @@ gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((str = gst_structure_get_string (s, "profile"))) {
|
||||||
|
if (strcmp (str, "lc") == 0) {
|
||||||
|
GST_DEBUG_OBJECT (self, "using LC profile for output");
|
||||||
|
aot = AOT_AAC_LC;
|
||||||
|
} else if (strcmp (str, "sbr") == 0) {
|
||||||
|
GST_DEBUG_OBJECT (self, "using SBR (HE-AAC) profile for output");
|
||||||
|
aot = AOT_SBR;
|
||||||
|
} else if (strcmp (str, "ps") == 0) {
|
||||||
|
GST_DEBUG_OBJECT (self, "using PS (HE-AACv2) profile for output");
|
||||||
|
aot = AOT_PS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gst_structure_get_int (s, "mpegversion", &mpegversion);
|
gst_structure_get_int (s, "mpegversion", &mpegversion);
|
||||||
}
|
}
|
||||||
if (allowed_caps)
|
if (allowed_caps)
|
||||||
|
@ -244,13 +278,25 @@ gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
aot = AOT_AAC_LC;
|
|
||||||
|
|
||||||
if ((err = aacEncoder_SetParam (self->enc, AACENC_AOT, aot)) != AACENC_OK) {
|
if ((err = aacEncoder_SetParam (self->enc, AACENC_AOT, aot)) != AACENC_OK) {
|
||||||
GST_ERROR_OBJECT (self, "Unable to set AOT %d: %d", aot, err);
|
GST_ERROR_OBJECT (self, "Unable to set AOT %d: %d", aot, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use explicit hierarchical signaling (2) with raw output stream-format
|
||||||
|
* and implicit signaling (0) with ADTS/ADIF */
|
||||||
|
if (transmux == 0)
|
||||||
|
signaling_mode = 2;
|
||||||
|
else
|
||||||
|
signaling_mode = 0;
|
||||||
|
|
||||||
|
if ((err = aacEncoder_SetParam (self->enc, AACENC_SIGNALING_MODE,
|
||||||
|
signaling_mode)) != AACENC_OK) {
|
||||||
|
GST_ERROR_OBJECT (self, "Unable to set signaling mode %d: %d",
|
||||||
|
signaling_mode, err);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((err = aacEncoder_SetParam (self->enc, AACENC_SAMPLERATE,
|
if ((err = aacEncoder_SetParam (self->enc, AACENC_SAMPLERATE,
|
||||||
GST_AUDIO_INFO_RATE (info))) != AACENC_OK) {
|
GST_AUDIO_INFO_RATE (info))) != AACENC_OK) {
|
||||||
GST_ERROR_OBJECT (self, "Unable to set sample rate %d: %d",
|
GST_ERROR_OBJECT (self, "Unable to set sample rate %d: %d",
|
||||||
|
@ -415,6 +461,14 @@ gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
|
||||||
gst_codec_utils_aac_caps_set_level_and_profile (src_caps, enc_info.confBuf,
|
gst_codec_utils_aac_caps_set_level_and_profile (src_caps, enc_info.confBuf,
|
||||||
enc_info.confSize);
|
enc_info.confSize);
|
||||||
|
|
||||||
|
/* The above only parses the "base" profile, which is always going to be LC.
|
||||||
|
* Let's retrieve the extension AOT and set it as our profile in the caps. */
|
||||||
|
ext_profile = gst_codec_utils_aac_get_extension_profile (enc_info.confBuf,
|
||||||
|
enc_info.confSize);
|
||||||
|
|
||||||
|
if (ext_profile)
|
||||||
|
gst_caps_set_simple (src_caps, "profile", G_TYPE_STRING, ext_profile, NULL);
|
||||||
|
|
||||||
ret = gst_audio_encoder_set_output_format (enc, src_caps);
|
ret = gst_audio_encoder_set_output_format (enc, src_caps);
|
||||||
gst_caps_unref (src_caps);
|
gst_caps_unref (src_caps);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue