fdkaacdec: Enable 8-channel playback

The decoder seems to default to 6 channels max, downmixing 7.1 to 5.1.
Disable the channel limit to expose all channels to GStreamer.

In addition, none of the standard configurations use ACT_SIDE channels.
The rear channels of the 7.1 configuration have to be taken from
ACT_BACK. See the table in aacenc_lib.h, reproduced here:

----------------------------------------------------------------------------------------
 ChannelMode           | ChCfg | Height | front_El      | side_El  | back_El  | lfe_El
-----------------------+-------+--------+---------------+----------+----------+---------
MODE_1                 |     1 | NORM   | SCE           |          |          |
MODE_2                 |     2 | NORM   | CPE           |          |          |
MODE_1_2               |     3 | NORM   | SCE, CPE      |          |          |
MODE_1_2_1             |     4 | NORM   | SCE, CPE      |          | SCE      |
MODE_1_2_2             |     5 | NORM   | SCE, CPE      |          | CPE      |
MODE_1_2_2_1           |     6 | NORM   | SCE, CPE      |          | CPE      | LFE
MODE_1_2_2_2_1         |     7 | NORM   | SCE, CPE, CPE |          | CPE      | LFE
MODE_6_1               |    11 | NORM   | SCE, CPE      |          | CPE, SCE | LFE
MODE_7_1_BACK          |    12 | NORM   | SCE, CPE      |          | CPE, CPE | LFE
-----------------------+-------+--------+---------------+----------+----------+---------
MODE_7_1_TOP_FRONT     |    14 | NORM   | SCE, CPE      |          | CPE      | LFE
                       |       | TOP    | CPE           |          |          |
-----------------------+-------+--------+---------------+----------+----------+---------
MODE_7_1_REAR_SURROUND |     0 | NORM   | SCE, CPE      |          | CPE, CPE | LFE
MODE_7_1_FRONT_CENTER  |     0 | NORM   | SCE, CPE, CPE |          | CPE      | LFE
----------------------------------------------------------------------------------------
- NORM: Normal Height Layer.     - TOP: Top Height Layer.  - BTM: Bottom Height Layer.
- SCE: Single Channel Element.   - CPE: Channel Pair.      - LFE: Low Frequency Element.

Restores 8 channels to
https://www2.iis.fraunhofer.de/AAC/7.1auditionOutLeader_v2_rtb.mp4
This commit is contained in:
Jan Alexander Steffens (heftig) 2018-12-04 18:33:09 +01:00 committed by Sebastian Dröge
parent 4ec3f2f193
commit c5a17000b6

View file

@ -151,6 +151,13 @@ gst_fdkaacdec_set_format (GstAudioDecoder * dec, GstCaps * caps)
gst_buffer_unref (codec_data);
}
if ((err =
aacDecoder_SetParam (self->dec, AAC_PCM_MAX_OUTPUT_CHANNELS,
0)) != AAC_DEC_OK) {
GST_ERROR_OBJECT (self, "Failed to disable downmixing: %d", err);
return FALSE;
}
/* Choose WAV channel mapping to get interleaving even with libfdk-aac 2.0.0
* The pChannelIndices retain the indices from the standard MPEG mapping so
* we're agnostic to the actual order. */
@ -228,14 +235,12 @@ gst_fdkaacdec_handle_frame (GstAudioDecoder * dec, GstBuffer * inbuf)
if (stream_info->numChannels == 1) {
pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
} else {
gint n_front = 0, n_side = 0, n_back = 0, n_lfe = 0;
gint n_front = 0, n_back = 0, n_lfe = 0;
/* FIXME: Can this be simplified somehow? */
for (i = 0; i < stream_info->numChannels; i++) {
if (stream_info->pChannelType[i] == ACT_FRONT) {
n_front++;
} else if (stream_info->pChannelType[i] == ACT_SIDE) {
n_side++;
} else if (stream_info->pChannelType[i] == ACT_BACK) {
n_back++;
} else if (stream_info->pChannelType[i] == ACT_LFE) {
@ -299,35 +304,48 @@ gst_fdkaacdec_handle_frame (GstAudioDecoder * dec, GstBuffer * inbuf)
ret = GST_FLOW_NOT_NEGOTIATED;
goto out;
}
} else if (stream_info->pChannelType[i] == ACT_SIDE) {
if (n_side & 1) {
GST_ERROR_OBJECT (self, "Odd number of side channels not supported");
ret = GST_FLOW_NOT_NEGOTIATED;
goto out;
} else if (stream_info->pChannelIndices[i] == 0) {
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
} else if (stream_info->pChannelIndices[i] == 1) {
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
} else {
GST_ERROR_OBJECT (self, "Side channel index %d not supported",
stream_info->pChannelIndices[i]);
ret = GST_FLOW_NOT_NEGOTIATED;
goto out;
}
} else if (stream_info->pChannelType[i] == ACT_BACK) {
if (stream_info->pChannelIndices[i] == 0) {
if (n_back & 1)
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
else if (n_back > 2)
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
else
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
} else if (stream_info->pChannelIndices[i] == 1) {
if (n_back & 1)
if ((n_back & 1) && n_back > 3)
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
else if (n_back & 1)
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
else if (n_back > 2)
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
else
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
} else if (stream_info->pChannelIndices[i] == 2) {
if (n_back & 1)
if ((n_back & 1) && n_back > 3)
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
else if (n_back & 1)
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
else if (n_back > 2)
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
else
g_assert_not_reached ();
} else if (stream_info->pChannelIndices[i] == 3) {
if ((n_back & 1) && n_back > 3)
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
else if (n_back & 1)
g_assert_not_reached ();
else if (n_back > 2)
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
else
g_assert_not_reached ();
} else if (stream_info->pChannelIndices[i] == 4) {
if ((n_back & 1) && n_back > 3)
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
else if (n_back & 1)
g_assert_not_reached ();
else if (n_back > 2)
g_assert_not_reached ();
else
g_assert_not_reached ();
} else {