-
-
Save rcombs/16146a3c86bac5ff20fc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 918f5590d43c6f7a39d2986bf446fde73093319d | |
Author: Rodger Combs <rodger.combs@gmail.com> | |
Date: Thu May 7 20:16:39 2015 -0500 | |
lavf/aacenc: Add support for 7.1-channel output | |
In future, we should probably allow writing a PCE for non-standard | |
channel layouts, and we might want to do that for 7.1 as well (since | |
there's history of that layout being used incorrectly; this patch | |
actually does that). | |
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c | |
index 998a875..8222b18 100644 | |
--- a/libavcodec/aacenc.c | |
+++ b/libavcodec/aacenc.c | |
@@ -45,8 +45,6 @@ | |
#include "psymodel.h" | |
-#define AAC_MAX_CHANNELS 6 | |
- | |
#define ERROR_IF(cond, ...) \ | |
if (cond) { \ | |
av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \ | |
@@ -142,13 +140,15 @@ static const uint8_t *swb_size_128[] = { | |
}; | |
/** default channel configurations */ | |
-static const uint8_t aac_chan_configs[6][5] = { | |
+static const uint8_t aac_chan_configs[8][6] = { | |
{1, TYPE_SCE}, // 1 channel - single channel element | |
{1, TYPE_CPE}, // 2 channels - channel pair | |
{2, TYPE_SCE, TYPE_CPE}, // 3 channels - center + stereo | |
{3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels - front center + stereo + back center | |
{3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels - front center + stereo + back stereo | |
{4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE | |
+ {4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE}, // 7 channels - front center + stereo + surround stereo + back stereo | |
+ {5, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 8 channels - front center + stereo + surround stereo + back stereo + LFE | |
}; | |
/** | |
@@ -161,6 +161,8 @@ static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][AAC_MAX_CHANNELS] = { | |
{ 2, 0, 1, 3 }, | |
{ 2, 0, 1, 3, 4 }, | |
{ 2, 0, 1, 4, 5, 3 }, | |
+ { 2, 0, 1, 5, 6, 3, 4 }, | |
+ { 2, 0, 1, 6, 7, 4, 5, 3 }, | |
}; | |
/** | |
@@ -175,7 +177,7 @@ static void put_audio_specific_config(AVCodecContext *avctx) | |
init_put_bits(&pb, avctx->extradata, avctx->extradata_size); | |
put_bits(&pb, 5, 2); //object type - AAC-LC | |
put_bits(&pb, 4, s->samplerate_index); //sample rate index | |
- put_bits(&pb, 4, s->channels); | |
+ put_bits(&pb, 4, s->channel_configuration); | |
//GASpecificConfig | |
put_bits(&pb, 1, 0); //frame length - 1024 samples | |
put_bits(&pb, 1, 0); //does not depend on core coder | |
@@ -756,6 +758,15 @@ alloc_fail: | |
return AVERROR(ENOMEM); | |
} | |
+static av_cold int get_channel_configuration(int channels) | |
+{ | |
+ if (channels < 7) | |
+ return channels; | |
+ else if (channels == 8) | |
+ return 7; | |
+ return 0; | |
+} | |
+ | |
static av_cold int aac_encode_init(AVCodecContext *avctx) | |
{ | |
AACEncContext *s = avctx->priv_data; | |
@@ -771,12 +782,13 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) | |
break; | |
s->channels = avctx->channels; | |
+ s->channel_configuration = get_channel_configuration(s->channels); | |
ERROR_IF(i == 16 | |
|| i >= (sizeof(swb_size_1024) / sizeof(*swb_size_1024)) | |
|| i >= (sizeof(swb_size_128) / sizeof(*swb_size_128)), | |
"Unsupported sample rate %d\n", avctx->sample_rate); | |
- ERROR_IF(s->channels > AAC_MAX_CHANNELS, | |
+ ERROR_IF(s->channel_configuration == 0, | |
"Unsupported number of channels: %d\n", s->channels); | |
ERROR_IF(avctx->profile != FF_PROFILE_UNKNOWN && avctx->profile != FF_PROFILE_AAC_LOW, | |
"Unsupported profile %d\n", avctx->profile); | |
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h | |
index 7c1f277..125b75a 100644 | |
--- a/libavcodec/aacenc.h | |
+++ b/libavcodec/aacenc.h | |
@@ -30,6 +30,8 @@ | |
#include "audio_frame_queue.h" | |
#include "psymodel.h" | |
+#define AAC_MAX_CHANNELS 8 | |
+ | |
typedef enum AACCoder { | |
AAC_CODER_FAAC = 0, | |
AAC_CODER_ANMR, | |
@@ -69,10 +71,11 @@ typedef struct AACEncContext { | |
FFTContext mdct1024; ///< long (1024 samples) frame transform context | |
FFTContext mdct128; ///< short (128 samples) frame transform context | |
AVFloatDSPContext *fdsp; | |
- float *planar_samples[6]; ///< saved preprocessed input | |
+ float *planar_samples[AAC_MAX_CHANNELS]; ///< saved preprocessed input | |
int samplerate_index; ///< MPEG-4 samplerate index | |
int channels; ///< channel count | |
+ int channel_configuration; ///< channel configuration ID | |
const uint8_t *chan_map; ///< channel configuration map | |
ChannelElement *cpe; ///< channel elements |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment