Skip to content

Instantly share code, notes, and snippets.

@rcombs

rcombs/stdin Secret

Created May 8, 2015 01:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rcombs/16146a3c86bac5ff20fc to your computer and use it in GitHub Desktop.
Save rcombs/16146a3c86bac5ff20fc to your computer and use it in GitHub Desktop.
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