Actually revert extended channel layouts using PCEs (missed in previous).

from Brad (maintainer)
This commit is contained in:
ajacoutot 2018-11-15 08:30:33 +00:00
parent 47e8ec619b
commit 79ea4d303f
4 changed files with 51 additions and 460 deletions

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.175 2018/11/04 17:57:06 naddy Exp $
# $OpenBSD: Makefile,v 1.176 2018/11/15 08:30:33 ajacoutot Exp $
COMMENT= audio/video converter and streamer
@ -7,7 +7,7 @@ DISTNAME= ffmpeg-${V}
CATEGORIES= graphics multimedia
MASTER_SITES= https://ffmpeg.org/releases/
EXTRACT_SUFX= .tar.xz
REVISION= 1
REVISION= 2
EPOCH= 0
SHARED_LIBS= avcodec 22.2 \

View File

@ -1,4 +1,4 @@
$OpenBSD: patch-libavcodec_aacenc_c,v 1.21 2018/11/01 08:43:26 ajacoutot Exp $
$OpenBSD: patch-libavcodec_aacenc_c,v 1.22 2018/11/15 08:30:33 ajacoutot Exp $
aacenc: copy PRNG from the decoder
@ -86,14 +86,8 @@ aacenc: add SIMD optimizations for abs_pow34 and quantization
aacenc: quit when the audio queue reaches 0 rather than keeping track of empty frames
aacenc: support extended channel layouts using PCEs
aacenc: use the PCE comment field for encoder ID
aacenc: use the fast coder as the default
avcodec/aacenc: report channel layout by name
Index: libavcodec/aacenc.c
--- libavcodec/aacenc.c.orig
+++ libavcodec/aacenc.c
@ -105,65 +99,13 @@ Index: libavcodec/aacenc.c
#include "libavutil/float_dsp.h"
#include "libavutil/opt.h"
#include "avcodec.h"
@@ -46,31 +47,88 @@
#include "psymodel.h"
+static void put_pce(PutBitContext *pb, AVCodecContext *avctx)
+{
+ int i, j;
+ AACEncContext *s = avctx->priv_data;
+ AACPCEInfo *pce = &s->pce;
+ const int bitexact = avctx->flags & AV_CODEC_FLAG_BITEXACT;
+ const char *aux_data = bitexact ? "Lavc" : LIBAVCODEC_IDENT;
+
+ put_bits(pb, 4, 0);
+
+ put_bits(pb, 2, avctx->profile);
+ put_bits(pb, 4, s->samplerate_index);
+
+ put_bits(pb, 4, pce->num_ele[0]); /* Front */
+ put_bits(pb, 4, pce->num_ele[1]); /* Side */
+ put_bits(pb, 4, pce->num_ele[2]); /* Back */
+ put_bits(pb, 2, pce->num_ele[3]); /* LFE */
+ put_bits(pb, 3, 0); /* Assoc data */
+ put_bits(pb, 4, 0); /* CCs */
+
+ put_bits(pb, 1, 0); /* Stereo mixdown */
+ put_bits(pb, 1, 0); /* Mono mixdown */
+ put_bits(pb, 1, 0); /* Something else */
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < pce->num_ele[i]; j++) {
+ if (i < 3)
+ put_bits(pb, 1, pce->pairing[i][j]);
+ put_bits(pb, 4, pce->index[i][j]);
+ }
+ }
+
+ avpriv_align_put_bits(pb);
+ put_bits(pb, 8, strlen(aux_data));
+ avpriv_put_string(pb, aux_data, 0);
+}
+
/**
* Make AAC audio config object.
* @see 1.6.2.1 "Syntax - AudioSpecificConfig"
*/
-static void put_audio_specific_config(AVCodecContext *avctx)
+static int put_audio_specific_config(AVCodecContext *avctx)
@@ -54,11 +55,12 @@ static void put_audio_specific_config(AVCodecContext *
{
PutBitContext pb;
AACEncContext *s = avctx->priv_data;
+ int channels = (!s->needs_pce)*(s->channels - (s->channels == 8 ? 1 : 0));
+ const int max_size = 32;
+ int channels = s->channels - (s->channels == 8 ? 1 : 0);
- init_put_bits(&pb, avctx->extradata, avctx->extradata_size);
+ avctx->extradata = av_mallocz(max_size);
+ if (!avctx->extradata)
+ return AVERROR(ENOMEM);
+
+ init_put_bits(&pb, avctx->extradata, max_size);
init_put_bits(&pb, avctx->extradata, avctx->extradata_size);
put_bits(&pb, 5, s->profile+1); //profile
put_bits(&pb, 4, s->samplerate_index); //sample rate index
- put_bits(&pb, 4, s->channels);
@ -171,18 +113,8 @@ Index: libavcodec/aacenc.c
//GASpecificConfig
put_bits(&pb, 1, 0); //frame length - 1024 samples
put_bits(&pb, 1, 0); //does not depend on core coder
put_bits(&pb, 1, 0); //is not extension
+ if (s->needs_pce)
+ put_pce(&pb, avctx);
//Explicitly Mark SBR absent
put_bits(&pb, 11, 0x2b7); //sync extension
put_bits(&pb, 5, AOT_SBR);
put_bits(&pb, 1, 0);
@@ -71,6 +73,15 @@ static void put_audio_specific_config(AVCodecContext *
flush_put_bits(&pb);
+ avctx->extradata_size = put_bits_count(&pb) >> 3;
+
+ return 0;
}
+void ff_quantize_band_cost_cache_init(struct AACEncContext *s)
@ -197,7 +129,7 @@ Index: libavcodec/aacenc.c
#define WINDOW_FUNC(type) \
static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \
SingleChannelElement *sce, \
@@ -140,7 +198,7 @@ static void apply_window_and_mdct(AACEncContext *s, Si
@@ -140,7 +151,7 @@ static void apply_window_and_mdct(AACEncContext *s, Si
float *audio)
{
int i;
@ -206,7 +138,7 @@ Index: libavcodec/aacenc.c
apply_window[sce->ics.window_sequence[0]](s->fdsp, sce, audio);
@@ -258,6 +316,8 @@ static void apply_intensity_stereo(ChannelElement *cpe
@@ -258,6 +269,8 @@ static void apply_intensity_stereo(ChannelElement *cpe
start += ics->swb_sizes[g];
continue;
}
@ -215,7 +147,7 @@ Index: libavcodec/aacenc.c
for (i = 0; i < ics->swb_sizes[g]; i++) {
float sum = (cpe->ch[0].coeffs[start+i] + p*cpe->ch[1].coeffs[start+i])*scale;
cpe->ch[0].coeffs[start+i] = sum;
@@ -279,7 +339,13 @@ static void apply_mid_side_stereo(ChannelElement *cpe)
@@ -279,7 +292,13 @@ static void apply_mid_side_stereo(ChannelElement *cpe)
for (w2 = 0; w2 < ics->group_len[w]; w2++) {
int start = (w+w2) * 128;
for (g = 0; g < ics->num_swb; g++) {
@ -230,7 +162,7 @@ Index: libavcodec/aacenc.c
start += ics->swb_sizes[g];
continue;
}
@@ -424,6 +490,8 @@ static int encode_individual_channel(AVCodecContext *a
@@ -424,6 +443,8 @@ static int encode_individual_channel(AVCodecContext *a
put_ics_info(s, &sce->ics);
if (s->coder->encode_main_pred)
s->coder->encode_main_pred(s, sce);
@ -239,16 +171,7 @@ Index: libavcodec/aacenc.c
}
encode_band_info(s, sce);
encode_scale_factors(avctx, s, sce);
@@ -464,7 +532,7 @@ static void copy_input_samples(AACEncContext *s, const
{
int ch;
int end = 2048 + (frame ? frame->nb_samples : 0);
- const uint8_t *channel_map = aac_chan_maps[s->channels - 1];
+ const uint8_t *channel_map = s->reorder_map;
/* copy and remap input samples */
for (ch = 0; ch < s->channels; ch++) {
@@ -489,19 +557,21 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -489,19 +510,21 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
float **samples = s->planar_samples, *samples2, *la, *overlap;
ChannelElement *cpe;
SingleChannelElement *sce;
@ -274,7 +197,7 @@ Index: libavcodec/aacenc.c
}
copy_input_samples(s, frame);
@@ -518,19 +588,22 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -518,19 +541,22 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
chans = tag == TYPE_CPE ? 2 : 1;
cpe = &s->cpe[i];
for (ch = 0; ch < chans; ch++) {
@ -301,7 +224,7 @@ Index: libavcodec/aacenc.c
/* Only the lowest 12 coefficients are used in a LFE channel.
* The expression below results in only the bottom 8 coefficients
@@ -538,7 +611,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -538,7 +564,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
*/
ics->num_swb = s->samplerate_index >= 8 ? 1 : 3;
} else {
@ -310,7 +233,7 @@ Index: libavcodec/aacenc.c
ics->window_sequence[0]);
}
ics->window_sequence[1] = ics->window_sequence[0];
@@ -555,10 +628,23 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -555,10 +581,23 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
ics->tns_max_bands = wi[ch].window_type[0] == EIGHT_SHORT_SEQUENCE ?
ff_tns_max_bands_128 [s->samplerate_index]:
ff_tns_max_bands_1024[s->samplerate_index];
@ -335,7 +258,7 @@ Index: libavcodec/aacenc.c
if (wi[ch].clipping[w] > CLIP_AVOIDANCE_FACTOR) {
ics->window_clipping[w] = 1;
clip_avoidance_factor = FFMAX(clip_avoidance_factor, wi[ch].clipping[w]);
@@ -610,15 +696,28 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -610,15 +649,28 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
sce = &cpe->ch[ch];
coeffs[ch] = sce->coeffs;
sce->ics.predictor_present = 0;
@ -365,7 +288,7 @@ Index: libavcodec/aacenc.c
s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda);
}
if (chans > 1
@@ -636,14 +735,14 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -636,14 +688,14 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
for (ch = 0; ch < chans; ch++) { /* TNS and PNS */
sce = &cpe->ch[ch];
s->cur_channel = start_ch + ch;
@ -382,7 +305,7 @@ Index: libavcodec/aacenc.c
}
s->cur_channel = start_ch;
if (s->options.intensity_stereo) { /* Intensity Stereo */
@@ -660,8 +759,8 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -660,8 +712,8 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
s->coder->search_for_pred(s, sce);
if (cpe->ch[ch].ics.predictor_present) pred_mode = 1;
}
@ -393,7 +316,7 @@ Index: libavcodec/aacenc.c
for (ch = 0; ch < chans; ch++) {
sce = &cpe->ch[ch];
s->cur_channel = start_ch + ch;
@@ -670,22 +769,34 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -670,22 +722,34 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
}
s->cur_channel = start_ch;
}
@ -432,7 +355,7 @@ Index: libavcodec/aacenc.c
encode_ms_info(&s->pb, cpe);
if (cpe->ms_mode) ms_mode = 1;
}
@@ -697,38 +808,77 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
@@ -697,38 +761,77 @@ static int aac_encode_frame(AVCodecContext *avctx, AVP
start_ch += chans;
}
@ -532,7 +455,7 @@ Index: libavcodec/aacenc.c
ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
&avpkt->duration);
@@ -742,6 +892,8 @@ static av_cold int aac_encode_end(AVCodecContext *avct
@@ -742,6 +845,8 @@ static av_cold int aac_encode_end(AVCodecContext *avct
{
AACEncContext *s = avctx->priv_data;
@ -541,54 +464,22 @@ Index: libavcodec/aacenc.c
ff_mdct_end(&s->mdct1024);
ff_mdct_end(&s->mdct128);
ff_psy_end(&s->psy);
@@ -782,7 +934,6 @@ static av_cold int alloc_buffers(AVCodecContext *avctx
int ch;
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->buffer.samples, s->channels, 3 * 1024 * sizeof(s->buffer.samples[0]), alloc_fail);
FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->cpe, s->chan_map[0], sizeof(ChannelElement), alloc_fail);
- FF_ALLOCZ_OR_GOTO(avctx, avctx->extradata, 5 + AV_INPUT_BUFFER_PADDING_SIZE, alloc_fail);
for(ch = 0; ch < s->channels; ch++)
s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch;
@@ -800,76 +951,150 @@ static av_cold int aac_encode_init(AVCodecContext *avc
@@ -800,76 +905,129 @@ static av_cold int aac_encode_init(AVCodecContext *avc
uint8_t grouping[AAC_MAX_CHANNELS];
int lengths[2];
+ /* Constants */
+ s->last_frame_pb_count = 0;
+ avctx->extradata_size = 5;
avctx->frame_size = 1024;
+ avctx->initial_padding = 1024;
+ s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120;
- for (i = 0; i < 16; i++)
- if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])
+ /* Channel map and unspecified bitrate guessing */
+
+ s->needs_pce = 1;
+ for (i = 0; i < FF_ARRAY_ELEMS(aac_normal_chan_layouts); i++) {
+ if (avctx->channel_layout == aac_normal_chan_layouts[i]) {
+ s->needs_pce = s->options.pce;
break;
+ }
+ }
- s->channels = avctx->channels;
+ if (s->needs_pce) {
+ char buf[64];
+ for (i = 0; i < FF_ARRAY_ELEMS(aac_pce_configs); i++)
+ if (avctx->channel_layout == aac_pce_configs[i].layout)
+ break;
+ av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout);
+ ERROR_IF(i == FF_ARRAY_ELEMS(aac_pce_configs), "Unsupported channel layout \"%s\"\n", buf);
+ av_log(avctx, AV_LOG_INFO, "Using a PCE to encode channel layout \"%s\"\n", buf);
+ s->pce = aac_pce_configs[i];
+ s->reorder_map = s->pce.reorder_map;
+ s->chan_map = s->pce.config_map;
+ } else {
+ s->reorder_map = aac_chan_maps[s->channels - 1];
+ s->chan_map = aac_chan_configs[s->channels - 1];
+ }
- ERROR_IF(i == 16 || i >= ff_aac_swb_size_1024_len || i >= ff_aac_swb_size_128_len,
+ s->channels = avctx->channels;
+ ERROR_IF(s->channels > AAC_MAX_CHANNELS || s->channels == 7,
+ "Unsupported number of channels: %d\n", s->channels);
+ s->chan_map = aac_chan_configs[s->channels-1];
+ if (!avctx->bit_rate) {
+ for (i = 1; i <= s->chan_map[0]; i++) {
+ avctx->bit_rate += s->chan_map[i] == TYPE_CPE ? 128000 : /* Pair */
@ -598,9 +489,13 @@ Index: libavcodec/aacenc.c
+ }
+
+ /* Samplerate */
+ for (i = 0; i < 16; i++)
+ if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])
+ break;
for (i = 0; i < 16; i++)
if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])
break;
-
- s->channels = avctx->channels;
-
- ERROR_IF(i == 16 || i >= ff_aac_swb_size_1024_len || i >= ff_aac_swb_size_128_len,
+ s->samplerate_index = i;
+ ERROR_IF(s->samplerate_index == 16 ||
+ s->samplerate_index >= ff_aac_swb_size_1024_len ||
@ -696,9 +591,7 @@ Index: libavcodec/aacenc.c
goto fail;
- avctx->extradata_size = 5;
- put_audio_specific_config(avctx);
+ if ((ret = put_audio_specific_config(avctx)))
+ goto fail;
put_audio_specific_config(avctx);
- sizes[0] = ff_aac_swb_size_1024[i];
- sizes[1] = ff_aac_swb_size_128[i];
@ -735,7 +628,7 @@ Index: libavcodec/aacenc.c
ff_af_queue_init(avctx, &s->afq);
return 0;
@@ -880,27 +1105,17 @@ fail:
@@ -880,27 +1038,16 @@ fail:
#define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption aacenc_options[] = {
@ -770,11 +663,10 @@ Index: libavcodec/aacenc.c
+ {"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
+ {"aac_ltp", "Long term prediction", offsetof(AACEncContext, options.ltp), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
+ {"aac_pred", "AAC-Main prediction", offsetof(AACEncContext, options.pred), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
+ {"aac_pce", "Forces the use of PCEs", offsetof(AACEncContext, options.pce), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
{NULL}
};
@@ -911,6 +1126,11 @@ static const AVClass aacenc_class = {
@@ -911,6 +1058,11 @@ static const AVClass aacenc_class = {
LIBAVUTIL_VERSION_INT,
};
@ -786,7 +678,7 @@ Index: libavcodec/aacenc.c
AVCodec ff_aac_encoder = {
.name = "aac",
.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
@@ -920,9 +1140,9 @@ AVCodec ff_aac_encoder = {
@@ -920,9 +1072,9 @@ AVCodec ff_aac_encoder = {
.init = aac_encode_init,
.encode2 = aac_encode_frame,
.close = aac_encode_end,

View File

@ -1,4 +1,4 @@
$OpenBSD: patch-libavcodec_aacenc_h,v 1.11 2018/11/01 08:43:26 ajacoutot Exp $
$OpenBSD: patch-libavcodec_aacenc_h,v 1.12 2018/11/15 08:30:33 ajacoutot Exp $
aacenc: copy PRNG from the decoder
@ -30,8 +30,6 @@ aacenc: add SIMD optimizations for abs_pow34 and quantization
aacenc: quit when the audio queue reaches 0 rather than keeping track of empty frames
aacenc: support extended channel layouts using PCEs
Index: libavcodec/aacenc.h
--- libavcodec/aacenc.h.orig
+++ libavcodec/aacenc.h
@ -45,7 +43,7 @@ Index: libavcodec/aacenc.h
AAC_CODER_TWOLOOP,
AAC_CODER_FAST,
@@ -42,11 +41,13 @@ typedef enum AACCoder {
@@ -42,11 +41,12 @@ typedef enum AACCoder {
}AACCoder;
typedef struct AACEncOptions {
@ -55,13 +53,12 @@ Index: libavcodec/aacenc.h
int pns;
int tns;
+ int ltp;
+ int pce;
int pred;
+ int mid_side;
int intensity_stereo;
} AACEncOptions;
@@ -60,13 +61,19 @@ typedef struct AACCoefficientsEncoder {
@@ -60,13 +60,19 @@ typedef struct AACCoefficientsEncoder {
void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, float *out, int size,
int scale_idx, int cb, const float lambda, int rtz);
void (*encode_tns_info)(struct AACEncContext *s, SingleChannelElement *sce);
@ -82,7 +79,7 @@ Index: libavcodec/aacenc.h
void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe);
void (*search_for_is)(struct AACEncContext *s, AVCodecContext *avctx, ChannelElement *cpe);
void (*search_for_pred)(struct AACEncContext *s, SingleChannelElement *sce);
@@ -74,7 +81,296 @@ typedef struct AACCoefficientsEncoder {
@@ -74,6 +80,15 @@ typedef struct AACCoefficientsEncoder {
extern AACCoefficientsEncoder ff_aac_coders[];
@ -94,308 +91,23 @@ Index: libavcodec/aacenc.h
+ char rtz;
+ uint16_t generation;
+} AACQuantizeBandCostCacheEntry;
+
+typedef struct AACPCEInfo {
+ int64_t layout;
+ int num_ele[4]; ///< front, side, back, lfe
+ int pairing[3][8]; ///< front, side, back
+ int index[4][8]; ///< front, side, back, lfe
+ uint8_t config_map[16]; ///< configs the encoder's channel specific settings
+ uint8_t reorder_map[16]; ///< maps channels from lavc to aac order
+} AACPCEInfo;
+
/**
+ * List of PCE (Program Configuration Element) for the channel layouts listed
+ * in channel_layout.h
+ *
+ * For those wishing in the future to add other layouts:
+ *
+ * - num_ele: number of elements in each group of front, side, back, lfe channels
+ * (an element is of type SCE (single channel), CPE (channel pair) for
+ * the first 3 groups; and is LFE for LFE group).
+ *
+ * - pairing: 0 for an SCE element or 1 for a CPE; does not apply to LFE group
+ *
+ * - index: there are three independent indices for SCE, CPE and LFE;
+ * they are incremented irrespective of the group to which the element belongs;
+ * they are not reset when going from one group to another
+ *
+ * Example: for 7.0 channel layout,
+ * .pairing = { { 1, 0 }, { 1 }, { 1 }, }, (3 CPE and 1 SCE in front group)
+ * .index = { { 0, 0 }, { 1 }, { 2 }, },
+ * (index is 0 for the single SCE but goes from 0 to 2 for the CPEs)
+ *
+ * The index order impacts the channel ordering. But is otherwise arbitrary
+ * (the sequence could have been 2, 0, 1 instead of 0, 1, 2).
+ *
+ * Spec allows for discontinuous indices, e.g. if one has a total of two SCE,
+ * SCE.0 SCE.15 is OK per spec; BUT it won't be decoded by our AAC decoder
+ * which at this time requires that indices fully cover some range starting
+ * from 0 (SCE.1 SCE.0 is OK but not SCE.0 SCE.15).
+ *
+ * - config_map: total number of elements and their types. Beware, the way the
+ * types are ordered impacts the final channel ordering.
+ *
+ * - reorder_map: reorders the channels.
+ *
+ */
+static const AACPCEInfo aac_pce_configs[] = {
+ {
+ .layout = AV_CH_LAYOUT_MONO,
+ .num_ele = { 1, 0, 0, 0 },
+ .pairing = { { 0 }, },
+ .index = { { 0 }, },
+ .config_map = { 1, TYPE_SCE, },
+ .reorder_map = { 0 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_STEREO,
+ .num_ele = { 1, 0, 0, 0 },
+ .pairing = { { 1 }, },
+ .index = { { 0 }, },
+ .config_map = { 1, TYPE_CPE, },
+ .reorder_map = { 0, 1 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_2POINT1,
+ .num_ele = { 1, 0, 0, 1 },
+ .pairing = { { 1 }, },
+ .index = { { 0 },{ 0 },{ 0 },{ 0 } },
+ .config_map = { 2, TYPE_CPE, TYPE_LFE },
+ .reorder_map = { 0, 1, 2 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_2_1,
+ .num_ele = { 1, 0, 1, 0 },
+ .pairing = { { 1 },{ 0 },{ 0 } },
+ .index = { { 0 },{ 0 },{ 0 }, },
+ .config_map = { 2, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_SURROUND,
+ .num_ele = { 2, 0, 0, 0 },
+ .pairing = { { 1, 0 }, },
+ .index = { { 0, 0 }, },
+ .config_map = { 2, TYPE_CPE, TYPE_SCE, },
+ .reorder_map = { 0, 1, 2 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_3POINT1,
+ .num_ele = { 2, 0, 0, 1 },
+ .pairing = { { 1, 0 }, },
+ .index = { { 0, 0 }, { 0 }, { 0 }, { 0 }, },
+ .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_LFE },
+ .reorder_map = { 0, 1, 2, 3 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_4POINT0,
+ .num_ele = { 2, 0, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 0 }, },
+ .index = { { 0, 0 }, { 0 }, { 1 } },
+ .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_4POINT1,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 2 }, { 0 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_2_2,
+ .num_ele = { 1, 1, 0, 0 },
+ .pairing = { { 1 }, { 1 }, },
+ .index = { { 0 }, { 1 }, },
+ .config_map = { 2, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_QUAD,
+ .num_ele = { 1, 0, 1, 0 },
+ .pairing = { { 1 }, { 0 }, { 1 }, },
+ .index = { { 0 }, { 0 }, { 1 } },
+ .config_map = { 2, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_5POINT0,
+ .num_ele = { 2, 1, 0, 0 },
+ .pairing = { { 1, 0 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 } },
+ .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_5POINT1,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_5POINT0_BACK,
+ .num_ele = { 2, 0, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1 } },
+ .index = { { 0, 0 }, { 0 }, { 1 } },
+ .config_map = { 3, TYPE_CPE, TYPE_SCE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_5POINT1_BACK,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_6POINT0,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 1 }, { 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 1 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_6POINT0_FRONT,
+ .num_ele = { 2, 1, 0, 0 },
+ .pairing = { { 1, 1 }, { 1 } },
+ .index = { { 1, 0 }, { 2 }, },
+ .config_map = { 3, TYPE_CPE, TYPE_CPE, TYPE_CPE, },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_HEXAGONAL,
+ .num_ele = { 2, 0, 2, 0 },
+ .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, },
+ .index = { { 0, 0 },{ 0 },{ 1, 1 } },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, },
+ .reorder_map = { 0, 1, 2, 3, 4, 5 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_6POINT1,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, },
+ .index = { { 0, 0 },{ 1 },{ 1, 2 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_6POINT1_BACK,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_6POINT1_FRONT,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_7POINT0,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 1 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 2 }, },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_7POINT0_FRONT,
+ .num_ele = { 2, 1, 1, 0 },
+ .pairing = { { 1, 0 }, { 1 }, { 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 2 }, },
+ .config_map = { 4, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_7POINT1,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_7POINT1_WIDE,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 },{ 1, 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_7POINT1_WIDE_BACK,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, },
+ .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_SCE, TYPE_CPE, TYPE_CPE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_OCTAGONAL,
+ .num_ele = { 2, 1, 2, 0 },
+ .pairing = { { 1, 0 }, { 1 }, { 1, 0 }, },
+ .index = { { 0, 0 }, { 1 }, { 2, 1 } },
+ .config_map = { 5, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
+ },
+ { /* Meant for order 2/mixed ambisonics */
+ .layout = AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER,
+ .num_ele = { 2, 2, 2, 0 },
+ .pairing = { { 1, 0 }, { 1, 0 }, { 1, 0 }, },
+ .index = { { 0, 0 }, { 1, 1 }, { 2, 2 } },
+ .config_map = { 6, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
+ },
+ { /* Meant for order 2/mixed ambisonics */
+ .layout = AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_BACK_CENTER |
+ AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_CENTER,
+ .num_ele = { 2, 2, 2, 0 },
+ .pairing = { { 1, 1 }, { 1, 0 }, { 1, 0 }, },
+ .index = { { 0, 1 }, { 2, 0 }, { 3, 1 } },
+ .config_map = { 6, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
+ },
+ {
+ .layout = AV_CH_LAYOUT_HEXADECAGONAL,
+ .num_ele = { 4, 2, 4, 0 },
+ .pairing = { { 1, 0, 1, 0 }, { 1, 1 }, { 1, 0, 1, 0 }, },
+ .index = { { 0, 0, 1, 1 }, { 2, 3 }, { 4, 2, 5, 3 } },
+ .config_map = { 10, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_SCE, TYPE_CPE, TYPE_SCE },
+ .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+ },
+};
+
+/**
* AAC encoder context
*/
typedef struct AACEncContext {
@@ -84,30 +380,49 @@ typedef struct AACEncContext {
@@ -84,9 +99,10 @@ 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
+ AACPCEInfo pce; ///< PCE data, if needed
+ float *planar_samples[16]; ///< saved preprocessed input
+ float *planar_samples[8]; ///< saved preprocessed input
int profile; ///< copied from avctx
+ int needs_pce; ///< flag for non-standard layout
LPCContext lpc; ///< used by TNS
int samplerate_index; ///< MPEG-4 samplerate index
int channels; ///< channel count
+ const uint8_t *reorder_map; ///< lavc to aac reorder map
const uint8_t *chan_map; ///< channel configuration map
ChannelElement *cpe; ///< channel elements
@@ -96,18 +112,34 @@ typedef struct AACEncContext {
FFPsyContext psy;
struct FFPsyPreprocessContext* psypp;
AACCoefficientsEncoder *coder;

View File

@ -1,4 +1,4 @@
$OpenBSD: patch-libavcodec_aacenctab_h,v 1.5 2018/10/17 08:25:07 ajacoutot Exp $
$OpenBSD: patch-libavcodec_aacenctab_h,v 1.6 2018/11/15 08:30:33 ajacoutot Exp $
AAC encoder: simplify and speed up find_min_book
@ -10,34 +10,21 @@ aacenc: add support for changing options based on a profile
aacenc: partially revert previous commits to set options via a profile
aacenc: support extended channel layouts using PCEs
Index: libavcodec/aacenctab.h
--- libavcodec/aacenctab.h.orig
+++ libavcodec/aacenctab.h
@@ -36,21 +36,34 @@
@@ -36,7 +36,7 @@
/** Total number of codebooks, including special ones **/
#define CB_TOT_ALL 15
-#define AAC_MAX_CHANNELS 6
+#define AAC_MAX_CHANNELS 16
+#define AAC_MAX_CHANNELS 8
extern const uint8_t *ff_aac_swb_size_1024[];
extern const int ff_aac_swb_size_1024_len;
extern const uint8_t *ff_aac_swb_size_128[];
@@ -44,13 +44,15 @@ extern const uint8_t *ff_aac_swb_size_128[];
extern const int ff_aac_swb_size_128_len;
+/* Supported layouts without using a PCE */
+static const int64_t aac_normal_chan_layouts[7] = {
+ AV_CH_LAYOUT_MONO,
+ AV_CH_LAYOUT_STEREO,
+ AV_CH_LAYOUT_SURROUND,
+ AV_CH_LAYOUT_4POINT0,
+ AV_CH_LAYOUT_5POINT0,
+ AV_CH_LAYOUT_5POINT1,
+ AV_CH_LAYOUT_7POINT1,
+};
+
/** default channel configurations */
-static const uint8_t aac_chan_configs[6][5] = {
- {1, TYPE_SCE}, // 1 channel - single channel element
@ -58,7 +45,7 @@ Index: libavcodec/aacenctab.h
};
/**
@@ -63,6 +76,8 @@ static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][A
@@ -63,6 +65,8 @@ static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][A
{ 2, 0, 1, 3 },
{ 2, 0, 1, 3, 4 },
{ 2, 0, 1, 4, 5, 3 },
@ -67,7 +54,7 @@ Index: libavcodec/aacenctab.h
};
/* duplicated from avpriv_mpeg4audio_sample_rates to avoid shared build
@@ -109,5 +124,16 @@ static const uint8_t aac_cb_in_map[CB_TOT_ALL+1] = {0,
@@ -109,5 +113,16 @@ static const uint8_t aac_cb_in_map[CB_TOT_ALL+1] = {0,
static const uint8_t aac_cb_range [12] = {0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
static const uint8_t aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};