78 changes: 36 additions & 42 deletions libavcodec/8bps.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,25 @@
* http://www.pcisys.net/~melanson/codecs/
*
* Supports: PAL8 (RGB 8bpp, paletted)
* : BGR24 (RGB 24bpp) (can also output it as RGB32)
* : RGB32 (RGB 32bpp, 4th plane is alpha)
* : GBRP (RGB 24bpp)
* : GBRAP (RGB 32bpp, 4th plane is alpha)
*/

#include <string.h>

#include "libavutil/bswap.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/internal.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"


static const enum AVPixelFormat pixfmt_rgb24[] = {
AV_PIX_FMT_BGR24, AV_PIX_FMT_0RGB32, AV_PIX_FMT_NONE };

typedef struct EightBpsContext {
AVCodecContext *avctx;

unsigned char planes;
unsigned char planemap[4];
uint8_t planes;
uint8_t planemap[4];

uint32_t pal[256];
} EightBpsContext;

static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
Expand All @@ -55,15 +53,14 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
EightBpsContext * const c = avctx->priv_data;
const unsigned char *encoded = buf;
unsigned char *pixptr, *pixptr_end;
const uint8_t *encoded = buf;
uint8_t *pixptr, *pixptr_end;
unsigned int height = avctx->height; // Real image height
unsigned int dlen, p, row;
const unsigned char *lp, *dp, *ep;
unsigned char count;
unsigned int px_inc;
unsigned int planes = c->planes;
unsigned char *planemap = c->planemap;
const uint8_t *lp, *dp, *ep;
uint8_t count;
const uint8_t *planemap = c->planemap;
unsigned int planes = c->planes;
int ret;

if (buf_size < planes * height * 2)
Expand All @@ -77,42 +74,38 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
/* Set data pointer after line lengths */
dp = encoded + planes * (height << 1);

px_inc = planes + (avctx->pix_fmt == AV_PIX_FMT_0RGB32);

for (p = 0; p < planes; p++) {
const int pi = planemap[p];
/* Lines length pointer for this plane */
lp = encoded + p * (height << 1);

/* Decode a plane */
for (row = 0; row < height; row++) {
pixptr = frame->data[0] + row * frame->linesize[0] + planemap[p];
pixptr_end = pixptr + frame->linesize[0];
pixptr = frame->data[pi] + row * frame->linesize[pi];
pixptr_end = pixptr + frame->linesize[pi];
if (ep - lp < row * 2 + 2)
return AVERROR_INVALIDDATA;
dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2));
dlen = AV_RB16(lp + row * 2);
/* Decode a row of this plane */
while (dlen > 0) {
if (ep - dp <= 1)
return AVERROR_INVALIDDATA;
if ((count = *dp++) <= 127) {
count++;
dlen -= count + 1;
if (pixptr_end - pixptr < count * px_inc)
if (pixptr_end - pixptr < count)
break;
if (ep - dp < count)
return AVERROR_INVALIDDATA;
while (count--) {
*pixptr = *dp++;
pixptr += px_inc;
}
memcpy(pixptr, dp, count);
pixptr += count;
dp += count;
} else {
count = 257 - count;
if (pixptr_end - pixptr < count * px_inc)
if (pixptr_end - pixptr < count)
break;
while (count--) {
*pixptr = *dp;
pixptr += px_inc;
}
memset(pixptr, dp[0], count);
pixptr += count;
dp++;
dlen -= 2;
}
Expand All @@ -125,10 +118,12 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
FF_DISABLE_DEPRECATION_WARNINGS
frame->palette_has_changed =
#endif
ff_copy_palette(frame->data[1], avpkt, avctx);
ff_copy_palette(c->pal, avpkt, avctx);
#if FF_API_PALETTE_HAS_CHANGED
FF_ENABLE_DEPRECATION_WARNINGS
#endif

memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
}

*got_frame = 1;
Expand All @@ -150,28 +145,27 @@ static av_cold int decode_init(AVCodecContext *avctx)
c->planemap[0] = 0; // 1st plane is palette indexes
break;
case 24:
avctx->pix_fmt = ff_get_format(avctx, pixfmt_rgb24);
avctx->pix_fmt = AV_PIX_FMT_GBRP;
c->planes = 3;
c->planemap[0] = 2; // 1st plane is red
c->planemap[1] = 1; // 2nd plane is green
c->planemap[2] = 0; // 3rd plane is blue
c->planemap[1] = 0; // 2nd plane is green
c->planemap[2] = 1; // 3rd plane is blue
break;
case 32:
avctx->pix_fmt = AV_PIX_FMT_RGB32;
avctx->pix_fmt = AV_PIX_FMT_GBRAP;
c->planes = 4;
/* handle planemap setup later for decoding rgb24 data as rbg32 */
break;
default:
av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n",
avctx->bits_per_coded_sample);
return AVERROR_INVALIDDATA;
}

if (avctx->pix_fmt == AV_PIX_FMT_RGB32) {
c->planemap[0] = HAVE_BIGENDIAN ? 1 : 2; // 1st plane is red
c->planemap[1] = HAVE_BIGENDIAN ? 2 : 1; // 2nd plane is green
c->planemap[2] = HAVE_BIGENDIAN ? 3 : 0; // 3rd plane is blue
c->planemap[3] = HAVE_BIGENDIAN ? 0 : 3; // 4th plane is alpha
if (avctx->pix_fmt == AV_PIX_FMT_GBRAP) {
c->planemap[0] = 2; // 1st plane is red
c->planemap[1] = 0; // 2nd plane is green
c->planemap[2] = 1; // 3rd plane is blue
c->planemap[3] = 3; // 4th plane is alpha
}
return 0;
}
Expand Down
110 changes: 39 additions & 71 deletions libavcodec/Makefile

Large diffs are not rendered by default.

268 changes: 0 additions & 268 deletions libavcodec/aac.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,13 @@


#include "aac_defines.h"
#include "libavutil/channel_layout.h"
#include "libavutil/float_dsp.h"
#include "libavutil/fixed_dsp.h"
#include "libavutil/mem_internal.h"
#include "libavutil/tx.h"
#include "avcodec.h"
#include "mpeg4audio.h"
#include "sbr.h"

#include <stdint.h>

#define MAX_CHANNELS 64
#define MAX_ELEM_ID 16

#define TNS_MAX_ORDER 20
#define MAX_LTP_LONG_SFB 40

#define CLIP_AVOIDANCE_FACTOR 0.95f

enum RawDataBlockType {
TYPE_SCE,
TYPE_CPE,
Expand Down Expand Up @@ -88,8 +76,6 @@ enum BandType {
INTENSITY_BT = 15, ///< Scalefactor data are intensity stereo positions (in phase).
};

#define IS_CODEBOOK_UNSIGNED(x) (((x) - 1) & 10)

enum ChannelPosition {
AAC_CHANNEL_OFF = 0,
AAC_CHANNEL_FRONT = 1,
Expand All @@ -99,34 +85,6 @@ enum ChannelPosition {
AAC_CHANNEL_CC = 5,
};

/**
* The point during decoding at which channel coupling is applied.
*/
enum CouplingPoint {
BEFORE_TNS,
BETWEEN_TNS_AND_IMDCT,
AFTER_IMDCT = 3,
};

/**
* Output configuration status
*/
enum OCStatus {
OC_NONE, ///< Output unconfigured
OC_TRIAL_PCE, ///< Output configuration under trial specified by an inband PCE
OC_TRIAL_FRAME, ///< Output configuration under trial specified by a frame header
OC_GLOBAL_HDR, ///< Output configuration set in a global header but not yet locked
OC_LOCKED, ///< Output configuration locked in place
};

typedef struct OutputConfiguration {
MPEG4AudioConfig m4ac;
uint8_t layout_map[MAX_ELEM_ID*4][3];
int layout_map_tags;
AVChannelLayout ch_layout;
enum OCStatus status;
} OutputConfiguration;

/**
* Predictor State
*/
Expand Down Expand Up @@ -155,237 +113,11 @@ typedef struct PredictorState {
#define NOISE_PRE_BITS 9 ///< length of preamble
#define NOISE_OFFSET 90 ///< subtracted from global gain, used as offset for the preamble

/**
* Long Term Prediction
*/
typedef struct LongTermPrediction {
int8_t present;
int16_t lag;
int coef_idx;
INTFLOAT coef;
int8_t used[MAX_LTP_LONG_SFB];
} LongTermPrediction;

/**
* Individual Channel Stream
*/
typedef struct IndividualChannelStream {
uint8_t max_sfb; ///< number of scalefactor bands per group
enum WindowSequence window_sequence[2];
uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window.
int num_window_groups;
uint8_t group_len[8];
LongTermPrediction ltp;
const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window
const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window
int num_swb; ///< number of scalefactor window bands
int num_windows;
int tns_max_bands;
int predictor_present;
int predictor_initialized;
int predictor_reset_group;
int predictor_reset_count[31]; ///< used by encoder to count prediction resets
uint8_t prediction_used[41];
uint8_t window_clipping[8]; ///< set if a certain window is near clipping
float clip_avoidance_factor; ///< set if any window is near clipping to the necessary atennuation factor to avoid it
} IndividualChannelStream;

/**
* Temporal Noise Shaping
*/
typedef struct TemporalNoiseShaping {
int present;
int n_filt[8];
int length[8][4];
int direction[8][4];
int order[8][4];
int coef_idx[8][4][TNS_MAX_ORDER];
INTFLOAT coef[8][4][TNS_MAX_ORDER];
} TemporalNoiseShaping;

/**
* Dynamic Range Control - decoded from the bitstream but not processed further.
*/
typedef struct DynamicRangeControl {
int pce_instance_tag; ///< Indicates with which program the DRC info is associated.
int dyn_rng_sgn[17]; ///< DRC sign information; 0 - positive, 1 - negative
int dyn_rng_ctl[17]; ///< DRC magnitude information
int exclude_mask[MAX_CHANNELS]; ///< Channels to be excluded from DRC processing.
int band_incr; ///< Number of DRC bands greater than 1 having DRC info.
int interpolation_scheme; ///< Indicates the interpolation scheme used in the SBR QMF domain.
int band_top[17]; ///< Indicates the top of the i-th DRC band in units of 4 spectral lines.
int prog_ref_level; /**< A reference level for the long-term program audio level for all
* channels combined.
*/
} DynamicRangeControl;

typedef struct Pulse {
int num_pulse;
int start;
int pos[4];
int amp[4];
} Pulse;

/**
* coupling parameters
*/
typedef struct ChannelCoupling {
enum CouplingPoint coupling_point; ///< The point during decoding at which coupling is applied.
int num_coupled; ///< number of target elements
enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE.
int id_select[8]; ///< element id
int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel;
* [2] list of gains for left channel; [3] lists of gains for both channels
*/
INTFLOAT gain[16][120];
} ChannelCoupling;

/**
* Single Channel Element - used for both SCE and LFE elements.
*/
typedef struct SingleChannelElement {
IndividualChannelStream ics;
TemporalNoiseShaping tns;
Pulse pulse;
enum BandType band_type[128]; ///< band types
enum BandType band_alt[128]; ///< alternative band type (used by encoder)
int band_type_run_end[120]; ///< band type run end points
INTFLOAT sf[120]; ///< scalefactors
int sf_idx[128]; ///< scalefactor indices (used by encoder)
uint8_t zeroes[128]; ///< band is not coded (used by encoder)
uint8_t can_pns[128]; ///< band is allowed to PNS (informative)
float is_ener[128]; ///< Intensity stereo pos (used by encoder)
float pns_ener[128]; ///< Noise energy values (used by encoder)
DECLARE_ALIGNED(32, INTFLOAT, pcoeffs)[1024]; ///< coefficients for IMDCT, pristine
DECLARE_ALIGNED(32, INTFLOAT, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed
DECLARE_ALIGNED(32, INTFLOAT, saved)[1536]; ///< overlap
DECLARE_ALIGNED(32, INTFLOAT, ret_buf)[2048]; ///< PCM output buffer
DECLARE_ALIGNED(16, INTFLOAT, ltp_state)[3072]; ///< time signal for LTP
DECLARE_ALIGNED(32, AAC_FLOAT, lcoeffs)[1024]; ///< MDCT of LTP coefficients (used by encoder)
DECLARE_ALIGNED(32, AAC_FLOAT, prcoeffs)[1024]; ///< Main prediction coefs (used by encoder)
PredictorState predictor_state[MAX_PREDICTORS];
INTFLOAT *ret; ///< PCM output
} SingleChannelElement;

/**
* channel element - generic struct for SCE/CPE/CCE/LFE
*/
typedef struct ChannelElement {
int present;
// CPE specific
int common_window; ///< Set if channels share a common 'IndividualChannelStream' in bitstream.
int ms_mode; ///< Signals mid/side stereo flags coding mode (used by encoder)
uint8_t is_mode; ///< Set if any bands have been encoded using intensity stereo (used by encoder)
uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band
uint8_t is_mask[128]; ///< Set if intensity stereo is used (used by encoder)
// shared
SingleChannelElement ch[2];
// CCE specific
ChannelCoupling coup;
SpectralBandReplication sbr;
} ChannelElement;

enum AACOutputChannelOrder {
CHANNEL_ORDER_DEFAULT,
CHANNEL_ORDER_CODED,
};

/**
* main AAC context
*/
struct AACContext {
AVClass *class;
AVCodecContext *avctx;
AVFrame *frame;

int is_saved; ///< Set if elements have stored overlap from previous frame.
DynamicRangeControl che_drc;

/**
* @name Channel element related data
* @{
*/
ChannelElement *che[4][MAX_ELEM_ID];
ChannelElement *tag_che_map[4][MAX_ELEM_ID];
int tags_mapped;
int warned_remapping_once;
/** @} */

/**
* @name temporary aligned temporary buffers
* (We do not want to have these on the stack.)
* @{
*/
DECLARE_ALIGNED(32, INTFLOAT, buf_mdct)[1024];
/** @} */

/**
* @name Computed / set up during initialization
* @{
*/
AVTXContext *mdct120;
AVTXContext *mdct128;
AVTXContext *mdct480;
AVTXContext *mdct512;
AVTXContext *mdct960;
AVTXContext *mdct1024;
AVTXContext *mdct_ltp;

av_tx_fn mdct120_fn;
av_tx_fn mdct128_fn;
av_tx_fn mdct480_fn;
av_tx_fn mdct512_fn;
av_tx_fn mdct960_fn;
av_tx_fn mdct1024_fn;
av_tx_fn mdct_ltp_fn;
#if USE_FIXED
AVFixedDSPContext *fdsp;
#else
AVFloatDSPContext *fdsp;
#endif /* USE_FIXED */
int random_state;
/** @} */

/**
* @name Members used for output
* @{
*/
SingleChannelElement *output_element[MAX_CHANNELS]; ///< Points to each SingleChannelElement
/** @} */


/**
* @name Japanese DTV specific extension
* @{
*/
int force_dmono_mode;///< 0->not dmono, 1->use first channel, 2->use second channel
int dmono_mode; ///< 0->not dmono, 1->use first channel, 2->use second channel
/** @} */

enum AACOutputChannelOrder output_channel_order;

DECLARE_ALIGNED(32, INTFLOAT, temp)[128];

OutputConfiguration oc[2];
int warned_num_aac_frames;
int warned_960_sbr;
unsigned warned_71_wide;
int warned_gain_control;
int warned_he_aac_mono;

/* aacdec functions pointers */
void (*imdct_and_windowing)(AACContext *ac, SingleChannelElement *sce);
void (*apply_ltp)(AACContext *ac, SingleChannelElement *sce);
void (*apply_tns)(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
IndividualChannelStream *ics, int decode);
void (*windowing_and_mdct_ltp)(AACContext *ac, INTFLOAT *out,
INTFLOAT *in, IndividualChannelStream *ics);
void (*update_ltp)(AACContext *ac, SingleChannelElement *sce);
void (*vector_pow43)(int *coefs, int len);
void (*subband_scale)(int *dst, int *src, int scale, int offset, int len, void *log_context);

};

void ff_aacdec_init_mips(AACContext *c);

#endif /* AVCODEC_AAC_H */
2 changes: 0 additions & 2 deletions libavcodec/aac_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include "libavutil/softfloat.h"

#define AAC_RENAME(x) x ## _fixed
#define AAC_RENAME_32(x) x ## _fixed_32
#define AAC_RENAME2(x) x ## _fixed
typedef int INTFLOAT;
typedef unsigned UINTFLOAT; ///< Equivalent to INTFLOAT, Used as temporal cast to avoid undefined sign overflow operations.
Expand Down Expand Up @@ -77,7 +76,6 @@ typedef int AAC_SIGNE;
#else

#define AAC_RENAME(x) x
#define AAC_RENAME_32(x) x
#define AAC_RENAME2(x) ff_ ## x
typedef float INTFLOAT;
typedef float UINTFLOAT;
Expand Down
19 changes: 10 additions & 9 deletions libavcodec/aacdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "sinewin.h"

#include "aac.h"
#include "aacdec.h"
#include "aactab.h"
#include "aacdectab.h"
#include "adts_header.h"
Expand Down Expand Up @@ -209,7 +210,7 @@ static av_always_inline void predict(PredictorState *ps, float *coef,
*
* @param index index into coupling gain array
*/
static void apply_dependent_coupling(AACContext *ac,
static void apply_dependent_coupling(AACDecContext *ac,
SingleChannelElement *target,
ChannelElement *cce, int index)
{
Expand Down Expand Up @@ -245,7 +246,7 @@ static void apply_dependent_coupling(AACContext *ac,
*
* @param index index into coupling gain array
*/
static void apply_independent_coupling(AACContext *ac,
static void apply_independent_coupling(AACDecContext *ac,
SingleChannelElement *target,
ChannelElement *cce, int index)
{
Expand All @@ -262,7 +263,7 @@ static void apply_independent_coupling(AACContext *ac,
#define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word

struct LATMContext {
AACContext aac_ctx; ///< containing AACContext
AACDecContext aac_ctx; ///< containing AACContext
int initialized; ///< initialized after a valid extradata was seen

// parser data
Expand All @@ -281,7 +282,7 @@ static inline uint32_t latm_get_value(GetBitContext *b)
static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
GetBitContext *gb, int asclen)
{
AACContext *ac = &latmctx->aac_ctx;
AACDecContext *ac = &latmctx->aac_ctx;
AVCodecContext *avctx = ac->avctx;
MPEG4AudioConfig m4ac = { 0 };
GetBitContext gbc;
Expand Down Expand Up @@ -555,7 +556,7 @@ const FFCodec ff_aac_decoder = {
CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.priv_data_size = sizeof(AACContext),
.priv_data_size = sizeof(AACDecContext),
.init = aac_decode_init,
.close = aac_decode_close,
FF_CODEC_DECODE_CB(aac_decode_frame),
Expand All @@ -564,8 +565,8 @@ const FFCodec ff_aac_decoder = {
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_aac_channel_layout)
.p.ch_layouts = ff_aac_ch_layout,
.flush = flush,
.p.priv_class = &aac_decoder_class,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
Expand All @@ -590,8 +591,8 @@ const FFCodec ff_aac_latm_decoder = {
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_aac_channel_layout)
.p.ch_layouts = ff_aac_ch_layout,
.flush = flush,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
};
280 changes: 280 additions & 0 deletions libavcodec/aacdec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
/*
* AAC decoder definitions and structures
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

/**
* @file
* AAC decoder definitions and structures
* @author Oded Shimon ( ods15 ods15 dyndns org )
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
*/

#ifndef AVCODEC_AACDEC_H
#define AVCODEC_AACDEC_H

#include <stdint.h>

#include "libavutil/channel_layout.h"
#include "libavutil/float_dsp.h"
#include "libavutil/fixed_dsp.h"
#include "libavutil/mem_internal.h"
#include "libavutil/tx.h"

#include "aac.h"
#include "aac_defines.h"
#include "mpeg4audio.h"
#include "sbr.h"

/**
* Output configuration status
*/
enum OCStatus {
OC_NONE, ///< Output unconfigured
OC_TRIAL_PCE, ///< Output configuration under trial specified by an inband PCE
OC_TRIAL_FRAME, ///< Output configuration under trial specified by a frame header
OC_GLOBAL_HDR, ///< Output configuration set in a global header but not yet locked
OC_LOCKED, ///< Output configuration locked in place
};

enum AACOutputChannelOrder {
CHANNEL_ORDER_DEFAULT,
CHANNEL_ORDER_CODED,
};

/**
* The point during decoding at which channel coupling is applied.
*/
enum CouplingPoint {
BEFORE_TNS,
BETWEEN_TNS_AND_IMDCT,
AFTER_IMDCT = 3,
};

/**
* Long Term Prediction
*/
typedef struct LongTermPrediction {
int8_t present;
int16_t lag;
INTFLOAT coef;
int8_t used[MAX_LTP_LONG_SFB];
} LongTermPrediction;

/**
* Individual Channel Stream
*/
typedef struct IndividualChannelStream {
uint8_t max_sfb; ///< number of scalefactor bands per group
enum WindowSequence window_sequence[2];
uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window.
int num_window_groups;
uint8_t group_len[8];
LongTermPrediction ltp;
const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window
int num_swb; ///< number of scalefactor window bands
int num_windows;
int tns_max_bands;
int predictor_present;
int predictor_initialized;
int predictor_reset_group;
uint8_t prediction_used[41];
uint8_t window_clipping[8]; ///< set if a certain window is near clipping
} IndividualChannelStream;

/**
* Temporal Noise Shaping
*/
typedef struct TemporalNoiseShaping {
int present;
int n_filt[8];
int length[8][4];
int direction[8][4];
int order[8][4];
INTFLOAT coef[8][4][TNS_MAX_ORDER];
} TemporalNoiseShaping;

/**
* coupling parameters
*/
typedef struct ChannelCoupling {
enum CouplingPoint coupling_point; ///< The point during decoding at which coupling is applied.
int num_coupled; ///< number of target elements
enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE.
int id_select[8]; ///< element id
int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel;
* [2] list of gains for left channel; [3] lists of gains for both channels
*/
INTFLOAT gain[16][120];
} ChannelCoupling;

/**
* Single Channel Element - used for both SCE and LFE elements.
*/
typedef struct SingleChannelElement {
IndividualChannelStream ics;
TemporalNoiseShaping tns;
enum BandType band_type[128]; ///< band types
int band_type_run_end[120]; ///< band type run end points
INTFLOAT sf[120]; ///< scalefactors
DECLARE_ALIGNED(32, INTFLOAT, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed
DECLARE_ALIGNED(32, INTFLOAT, saved)[1536]; ///< overlap
DECLARE_ALIGNED(32, INTFLOAT, ret_buf)[2048]; ///< PCM output buffer
DECLARE_ALIGNED(16, INTFLOAT, ltp_state)[3072]; ///< time signal for LTP
PredictorState predictor_state[MAX_PREDICTORS];
INTFLOAT *ret; ///< PCM output
} SingleChannelElement;

/**
* channel element - generic struct for SCE/CPE/CCE/LFE
*/
typedef struct ChannelElement {
int present;
// CPE specific
uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band
// shared
SingleChannelElement ch[2];
// CCE specific
ChannelCoupling coup;
SpectralBandReplication sbr;
} ChannelElement;

typedef struct OutputConfiguration {
MPEG4AudioConfig m4ac;
uint8_t layout_map[MAX_ELEM_ID*4][3];
int layout_map_tags;
AVChannelLayout ch_layout;
enum OCStatus status;
} OutputConfiguration;

/**
* Dynamic Range Control - decoded from the bitstream but not processed further.
*/
typedef struct DynamicRangeControl {
int pce_instance_tag; ///< Indicates with which program the DRC info is associated.
int dyn_rng_sgn[17]; ///< DRC sign information; 0 - positive, 1 - negative
int dyn_rng_ctl[17]; ///< DRC magnitude information
int exclude_mask[MAX_CHANNELS]; ///< Channels to be excluded from DRC processing.
int band_incr; ///< Number of DRC bands greater than 1 having DRC info.
int interpolation_scheme; ///< Indicates the interpolation scheme used in the SBR QMF domain.
int band_top[17]; ///< Indicates the top of the i-th DRC band in units of 4 spectral lines.
int prog_ref_level; /**< A reference level for the long-term program audio level for all
* channels combined.
*/
} DynamicRangeControl;

/**
* main AAC decoding context
*/
typedef struct AACDecContext {
const struct AVClass *class;
struct AVCodecContext *avctx;
struct AVFrame *frame;

int is_saved; ///< Set if elements have stored overlap from previous frame.
DynamicRangeControl che_drc;

/**
* @name Channel element related data
* @{
*/
ChannelElement *che[4][MAX_ELEM_ID];
ChannelElement *tag_che_map[4][MAX_ELEM_ID];
int tags_mapped;
int warned_remapping_once;
/** @} */

/**
* @name temporary aligned temporary buffers
* (We do not want to have these on the stack.)
* @{
*/
DECLARE_ALIGNED(32, INTFLOAT, buf_mdct)[1024];
/** @} */

/**
* @name Computed / set up during initialization
* @{
*/
AVTXContext *mdct120;
AVTXContext *mdct128;
AVTXContext *mdct480;
AVTXContext *mdct512;
AVTXContext *mdct960;
AVTXContext *mdct1024;
AVTXContext *mdct_ltp;

av_tx_fn mdct120_fn;
av_tx_fn mdct128_fn;
av_tx_fn mdct480_fn;
av_tx_fn mdct512_fn;
av_tx_fn mdct960_fn;
av_tx_fn mdct1024_fn;
av_tx_fn mdct_ltp_fn;
#if USE_FIXED
AVFixedDSPContext *fdsp;
#else
AVFloatDSPContext *fdsp;
#endif /* USE_FIXED */
int random_state;
/** @} */

/**
* @name Members used for output
* @{
*/
SingleChannelElement *output_element[MAX_CHANNELS]; ///< Points to each SingleChannelElement
/** @} */


/**
* @name Japanese DTV specific extension
* @{
*/
int force_dmono_mode;///< 0->not dmono, 1->use first channel, 2->use second channel
int dmono_mode; ///< 0->not dmono, 1->use first channel, 2->use second channel
/** @} */

enum AACOutputChannelOrder output_channel_order;

DECLARE_ALIGNED(32, INTFLOAT, temp)[128];

OutputConfiguration oc[2];
int warned_num_aac_frames;
int warned_960_sbr;
unsigned warned_71_wide;
int warned_gain_control;
int warned_he_aac_mono;

/* aacdec functions pointers */
void (*imdct_and_windowing)(struct AACDecContext *ac, SingleChannelElement *sce);
void (*apply_ltp)(struct AACDecContext *ac, SingleChannelElement *sce);
void (*apply_tns)(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
IndividualChannelStream *ics, int decode);
void (*windowing_and_mdct_ltp)(struct AACDecContext *ac, INTFLOAT *out,
INTFLOAT *in, IndividualChannelStream *ics);
void (*update_ltp)(struct AACDecContext *ac, SingleChannelElement *sce);
void (*vector_pow43)(int *coefs, int len);
void (*subband_scale)(int *dst, int *src, int scale, int offset, int len, void *log_context);
} AACDecContext;

void ff_aacdec_init_mips(AACDecContext *c);

#endif /* AVCODEC_AACDEC_H */
324 changes: 324 additions & 0 deletions libavcodec/aacdec_common.c

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions libavcodec/aacdec_fixed.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include "sinewin_fixed_tablegen.h"

#include "aac.h"
#include "aacdec.h"
#include "aactab.h"
#include "aacdectab.h"
#include "adts_header.h"
Expand Down Expand Up @@ -354,7 +355,7 @@ static const int cce_scale_fixed[8] = {
*
* @param index index into coupling gain array
*/
static void apply_dependent_coupling_fixed(AACContext *ac,
static void apply_dependent_coupling_fixed(AACDecContext *ac,
SingleChannelElement *target,
ChannelElement *cce, int index)
{
Expand Down Expand Up @@ -418,7 +419,7 @@ static void apply_dependent_coupling_fixed(AACContext *ac,
*
* @param index index into coupling gain array
*/
static void apply_independent_coupling_fixed(AACContext *ac,
static void apply_independent_coupling_fixed(AACDecContext *ac,
SingleChannelElement *target,
ChannelElement *cce, int index)
{
Expand Down Expand Up @@ -456,7 +457,7 @@ const FFCodec ff_aac_fixed_decoder = {
CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_AAC,
.priv_data_size = sizeof(AACContext),
.priv_data_size = sizeof(AACDecContext),
.init = aac_decode_init,
.close = aac_decode_close,
FF_CODEC_DECODE_CB(aac_decode_frame),
Expand All @@ -465,8 +466,8 @@ const FFCodec ff_aac_fixed_decoder = {
},
.p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(aac_channel_layout)
.p.ch_layouts = aac_ch_layout,
CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(ff_aac_channel_layout)
.p.ch_layouts = ff_aac_ch_layout,
.p.priv_class = &aac_decoder_class,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
.flush = flush,
Expand Down
216 changes: 95 additions & 121 deletions libavcodec/aacdec_template.c

Large diffs are not rendered by default.

105 changes: 18 additions & 87 deletions libavcodec/aacdectab.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/*
* AAC decoder data
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
*
* This file is part of FFmpeg.
*
Expand Down Expand Up @@ -30,99 +28,32 @@
#ifndef AVCODEC_AACDECTAB_H
#define AVCODEC_AACDECTAB_H

#include <stdint.h>

#include "vlc.h"

#include "libavutil/attributes_internal.h"
#include "libavutil/channel_layout.h"
#include "aac.h"

#include <stdint.h>
FF_VISIBILITY_PUSH_HIDDEN
void ff_aacdec_common_init_once(void);

extern const VLCElem *ff_aac_sbr_vlc[10];

extern VLCElem ff_vlc_scalefactors[];
extern const VLCElem *ff_vlc_spectral[11];

static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 5, 5, 16, 5, 0 };
extern const int8_t ff_tags_per_config[16];

static const uint8_t aac_channel_layout_map[16][16][3] = {
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { 0, } },
{ { 0, } },
{ { 0, } },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
{
{ TYPE_SCE, 0, AAC_CHANNEL_FRONT }, // SCE1 = FC,
{ TYPE_CPE, 0, AAC_CHANNEL_FRONT }, // CPE1 = FLc and FRc,
{ TYPE_CPE, 1, AAC_CHANNEL_FRONT }, // CPE2 = FL and FR,
{ TYPE_CPE, 2, AAC_CHANNEL_BACK }, // CPE3 = SiL and SiR,
{ TYPE_CPE, 3, AAC_CHANNEL_BACK }, // CPE4 = BL and BR,
{ TYPE_SCE, 1, AAC_CHANNEL_BACK }, // SCE2 = BC,
{ TYPE_LFE, 0, AAC_CHANNEL_LFE }, // LFE1 = LFE1,
{ TYPE_LFE, 1, AAC_CHANNEL_LFE }, // LFE2 = LFE2,
{ TYPE_SCE, 2, AAC_CHANNEL_FRONT }, // SCE3 = TpFC,
{ TYPE_CPE, 4, AAC_CHANNEL_FRONT }, // CPE5 = TpFL and TpFR,
{ TYPE_CPE, 5, AAC_CHANNEL_SIDE }, // CPE6 = TpSiL and TpSiR,
{ TYPE_SCE, 3, AAC_CHANNEL_SIDE }, // SCE4 = TpC,
{ TYPE_CPE, 6, AAC_CHANNEL_BACK }, // CPE7 = TpBL and TpBR,
{ TYPE_SCE, 4, AAC_CHANNEL_BACK }, // SCE5 = TpBC,
{ TYPE_SCE, 5, AAC_CHANNEL_FRONT }, // SCE6 = BtFC,
{ TYPE_CPE, 7, AAC_CHANNEL_FRONT }, // CPE8 = BtFL and BtFR
},
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, { TYPE_CPE, 2, AAC_CHANNEL_FRONT }, },
{ { 0, } },
};
extern const uint8_t ff_aac_channel_layout_map[16][16][3];

static const int16_t aac_channel_map[3][4][6] = {
{
{ AV_CHAN_FRONT_CENTER, AV_CHAN_FRONT_LEFT_OF_CENTER, AV_CHAN_FRONT_RIGHT_OF_CENTER, AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT, AV_CHAN_BACK_LEFT, AV_CHAN_BACK_RIGHT, AV_CHAN_BACK_CENTER },
{ AV_CHAN_LOW_FREQUENCY, AV_CHAN_LOW_FREQUENCY_2, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
},
{
{ AV_CHAN_TOP_FRONT_CENTER, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_FRONT_LEFT, AV_CHAN_TOP_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_UNUSED, AV_CHAN_TOP_SIDE_LEFT, AV_CHAN_TOP_SIDE_RIGHT, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_CENTER},
{ AV_CHAN_UNUSED, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_TOP_BACK_LEFT, AV_CHAN_TOP_BACK_RIGHT, AV_CHAN_TOP_BACK_CENTER},
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE},
},
{
{ AV_CHAN_BOTTOM_FRONT_CENTER, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_BOTTOM_FRONT_LEFT, AV_CHAN_BOTTOM_FRONT_RIGHT, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
{ AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE, AV_CHAN_NONE },
},
};
extern const int16_t ff_aac_channel_map[3][4][6];

#if FF_API_OLD_CHANNEL_LAYOUT
static const uint64_t aac_channel_layout[] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_SURROUND,
AV_CH_LAYOUT_4POINT0,
AV_CH_LAYOUT_5POINT0_BACK,
AV_CH_LAYOUT_5POINT1_BACK,
AV_CH_LAYOUT_7POINT1_WIDE_BACK,
AV_CH_LAYOUT_6POINT1_BACK,
AV_CH_LAYOUT_7POINT1,
AV_CH_LAYOUT_22POINT2,
AV_CH_LAYOUT_7POINT1_TOP_BACK,
0,
};
extern const uint64_t ff_aac_channel_layout[];
#endif

static const AVChannelLayout aac_ch_layout[] = {
AV_CHANNEL_LAYOUT_MONO,
AV_CHANNEL_LAYOUT_STEREO,
AV_CHANNEL_LAYOUT_SURROUND,
AV_CHANNEL_LAYOUT_4POINT0,
AV_CHANNEL_LAYOUT_5POINT0_BACK,
AV_CHANNEL_LAYOUT_5POINT1_BACK,
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
AV_CHANNEL_LAYOUT_6POINT1_BACK,
AV_CHANNEL_LAYOUT_7POINT1,
AV_CHANNEL_LAYOUT_22POINT2,
AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK,
{ 0 },
};
extern const AVChannelLayout ff_aac_ch_layout[];
FF_VISIBILITY_POP_HIDDEN

#endif /* AVCODEC_AACDECTAB_H */
55 changes: 30 additions & 25 deletions libavcodec/aacenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1210,9 +1210,6 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
if (!s->fdsp)
return AVERROR(ENOMEM);

// window init
ff_aac_float_common_init();

if ((ret = av_tx_init(&s->mdct1024, &s->mdct1024_fn, AV_TX_FLOAT_MDCT, 0,
1024, &scale, 0)) < 0)
return ret;
Expand Down Expand Up @@ -1307,36 +1304,36 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
avctx->bit_rate);

/* Profile and option setting */
avctx->profile = avctx->profile == FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW :
avctx->profile = avctx->profile == AV_PROFILE_UNKNOWN ? AV_PROFILE_AAC_LOW :
avctx->profile;
for (i = 0; i < FF_ARRAY_ELEMS(aacenc_profiles); i++)
if (avctx->profile == aacenc_profiles[i])
break;
if (avctx->profile == FF_PROFILE_MPEG2_AAC_LOW) {
avctx->profile = FF_PROFILE_AAC_LOW;
if (avctx->profile == AV_PROFILE_MPEG2_AAC_LOW) {
avctx->profile = AV_PROFILE_AAC_LOW;
ERROR_IF(s->options.pred,
"Main prediction unavailable in the \"mpeg2_aac_low\" profile\n");
ERROR_IF(s->options.ltp,
"LTP prediction unavailable in the \"mpeg2_aac_low\" profile\n");
WARN_IF(s->options.pns,
"PNS unavailable in the \"mpeg2_aac_low\" profile, turning off\n");
s->options.pns = 0;
} else if (avctx->profile == FF_PROFILE_AAC_LTP) {
} else if (avctx->profile == AV_PROFILE_AAC_LTP) {
s->options.ltp = 1;
ERROR_IF(s->options.pred,
"Main prediction unavailable in the \"aac_ltp\" profile\n");
} else if (avctx->profile == FF_PROFILE_AAC_MAIN) {
} else if (avctx->profile == AV_PROFILE_AAC_MAIN) {
s->options.pred = 1;
ERROR_IF(s->options.ltp,
"LTP prediction unavailable in the \"aac_main\" profile\n");
} else if (s->options.ltp) {
avctx->profile = FF_PROFILE_AAC_LTP;
avctx->profile = AV_PROFILE_AAC_LTP;
WARN_IF(1,
"Chainging profile to \"aac_ltp\"\n");
ERROR_IF(s->options.pred,
"Main prediction unavailable in the \"aac_ltp\" profile\n");
} else if (s->options.pred) {
avctx->profile = FF_PROFILE_AAC_MAIN;
avctx->profile = AV_PROFILE_AAC_MAIN;
WARN_IF(1,
"Chainging profile to \"aac_main\"\n");
ERROR_IF(s->options.ltp,
Expand All @@ -1359,6 +1356,9 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
if (s->channels > 3)
s->options.mid_side = 0;

// Initialize static tables
ff_aac_float_common_init();

if ((ret = dsp_init(avctx, s)) < 0)
return ret;

Expand All @@ -1381,29 +1381,19 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON);
s->random_state = 0x1f2e3d4c;

s->abs_pow34 = abs_pow34_v;
s->quant_bands = quantize_bands;

#if ARCH_X86
ff_aac_dsp_init_x86(s);
#endif

#if HAVE_MIPSDSP
ff_aac_coder_init_mips(s);
#endif
ff_aac_dsp_init(s);

ff_af_queue_init(avctx, &s->afq);
ff_aac_tableinit();

return 0;
}

#define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption aacenc_options[] = {
{"aac_coder", "Coding algorithm", offsetof(AACEncContext, options.coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_TWOLOOP}, 0, AAC_CODER_NB-1, AACENC_FLAGS, "coder"},
{"anmr", "ANMR method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
{"twoloop", "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
{"fast", "Default fast search", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
{"aac_coder", "Coding algorithm", offsetof(AACEncContext, options.coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_TWOLOOP}, 0, AAC_CODER_NB-1, AACENC_FLAGS, .unit = "coder"},
{"anmr", "ANMR method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR}, INT_MIN, INT_MAX, AACENC_FLAGS, .unit = "coder"},
{"twoloop", "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, .unit = "coder"},
{"fast", "Default fast search", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST}, INT_MIN, INT_MAX, AACENC_FLAGS, .unit = "coder"},
{"aac_ms", "Force M/S stereo coding", offsetof(AACEncContext, options.mid_side), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AACENC_FLAGS},
{"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
{"aac_pns", "Perceptual noise substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AACENC_FLAGS},
Expand Down Expand Up @@ -1445,3 +1435,18 @@ const FFCodec ff_aac_encoder = {
AV_SAMPLE_FMT_NONE },
.p.priv_class = &aacenc_class,
};

void ff_aac_dsp_init(AACEncContext *s){
s->abs_pow34 = abs_pow34_v;
s->quant_bands = quantize_bands;

#if ARCH_RISCV
ff_aac_dsp_init_riscv(s);
#elif ARCH_X86
ff_aac_dsp_init_x86(s);
#endif

#if HAVE_MIPSDSP
ff_aac_coder_init_mips(s);
#endif
}
91 changes: 91 additions & 0 deletions libavcodec/aacenc.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
#ifndef AVCODEC_AACENC_H
#define AVCODEC_AACENC_H

#include <stdint.h>

#include "libavutil/channel_layout.h"
#include "libavutil/float_dsp.h"
#include "libavutil/mem_internal.h"
#include "libavutil/tx.h"

#include "avcodec.h"
#include "put_bits.h"
Expand All @@ -35,6 +38,8 @@

#include "lpc.h"

#define CLIP_AVOIDANCE_FACTOR 0.95f

typedef enum AACCoder {
AAC_CODER_ANMR = 0,
AAC_CODER_TWOLOOP,
Expand All @@ -54,6 +59,90 @@ typedef struct AACEncOptions {
int intensity_stereo;
} AACEncOptions;

/**
* Long Term Prediction
*/
typedef struct LongTermPrediction {
int8_t present;
int16_t lag;
int coef_idx;
float coef;
int8_t used[MAX_LTP_LONG_SFB];
} LongTermPrediction;

/**
* Individual Channel Stream
*/
typedef struct IndividualChannelStream {
uint8_t max_sfb; ///< number of scalefactor bands per group
enum WindowSequence window_sequence[2];
uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window.
uint8_t group_len[8];
LongTermPrediction ltp;
const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window
const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window
int num_swb; ///< number of scalefactor window bands
int num_windows;
int tns_max_bands;
int predictor_present;
int predictor_initialized;
int predictor_reset_group;
int predictor_reset_count[31]; ///< used to count prediction resets
uint8_t prediction_used[41];
uint8_t window_clipping[8]; ///< set if a certain window is near clipping
float clip_avoidance_factor; ///< set if any window is near clipping to the necessary atennuation factor to avoid it
} IndividualChannelStream;

/**
* Temporal Noise Shaping
*/
typedef struct TemporalNoiseShaping {
int present;
int n_filt[8];
int length[8][4];
int direction[8][4];
int order[8][4];
int coef_idx[8][4][TNS_MAX_ORDER];
float coef[8][4][TNS_MAX_ORDER];
} TemporalNoiseShaping;

/**
* Single Channel Element - used for both SCE and LFE elements.
*/
typedef struct SingleChannelElement {
IndividualChannelStream ics;
TemporalNoiseShaping tns;
Pulse pulse;
enum BandType band_type[128]; ///< band types
enum BandType band_alt[128]; ///< alternative band type
int sf_idx[128]; ///< scalefactor indices
uint8_t zeroes[128]; ///< band is not coded
uint8_t can_pns[128]; ///< band is allowed to PNS (informative)
float is_ener[128]; ///< Intensity stereo pos
float pns_ener[128]; ///< Noise energy values
DECLARE_ALIGNED(32, float, pcoeffs)[1024]; ///< coefficients for IMDCT, pristine
DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT, maybe processed
DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer
DECLARE_ALIGNED(16, float, ltp_state)[3072]; ///< time signal for LTP
DECLARE_ALIGNED(32, float, lcoeffs)[1024]; ///< MDCT of LTP coefficients
DECLARE_ALIGNED(32, float, prcoeffs)[1024]; ///< Main prediction coefs
PredictorState predictor_state[MAX_PREDICTORS];
} SingleChannelElement;

/**
* channel element - generic struct for SCE/CPE/CCE/LFE
*/
typedef struct ChannelElement {
// CPE specific
int common_window; ///< Set if channels share a common 'IndividualChannelStream' in bitstream.
int ms_mode; ///< Signals mid/side stereo flags coding mode
uint8_t is_mode; ///< Set if any bands have been encoded using intensity stereo
uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band
uint8_t is_mask[128]; ///< Set if intensity stereo is used
// shared
SingleChannelElement ch[2];
} ChannelElement;

struct AACEncContext;

typedef struct AACCoefficientsEncoder {
Expand Down Expand Up @@ -154,6 +243,8 @@ typedef struct AACEncContext {
} buffer;
} AACEncContext;

void ff_aac_dsp_init(AACEncContext *s);
void ff_aac_dsp_init_riscv(AACEncContext *s);
void ff_aac_dsp_init_x86(AACEncContext *s);
void ff_aac_coder_init_mips(AACEncContext *c);
void ff_quantize_band_cost_cache_init(struct AACEncContext *s);
Expand Down
4 changes: 2 additions & 2 deletions libavcodec/aacenc_ltp.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void ff_aac_encode_ltp_info(AACEncContext *s, SingleChannelElement *sce,
{
int i;
IndividualChannelStream *ics = &sce->ics;
if (s->profile != FF_PROFILE_AAC_LTP || !ics->predictor_present)
if (s->profile != AV_PROFILE_AAC_LTP || !ics->predictor_present)
return;
if (common_window)
put_bits(&s->pb, 1, 0);
Expand Down Expand Up @@ -119,7 +119,7 @@ void ff_aac_update_ltp(AACEncContext *s, SingleChannelElement *sce)
float *pred_signal = &sce->ltp_state[0];
const float *samples = &s->planar_samples[s->cur_channel][1024];

if (s->profile != FF_PROFILE_AAC_LTP)
if (s->profile != AV_PROFILE_AAC_LTP)
return;

/* Calculate lag */
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/aacenc_pred.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ void ff_aac_encode_main_pred(AACEncContext *s, SingleChannelElement *sce)
IndividualChannelStream *ics = &sce->ics;
const int pmax = FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[s->samplerate_index]);

if (s->profile != FF_PROFILE_AAC_MAIN ||
if (s->profile != AV_PROFILE_AAC_MAIN ||
!ics->predictor_present)
return;

Expand Down
2 changes: 1 addition & 1 deletion libavcodec/aacenc_tns.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce)
const int c_bits = is8 ? TNS_Q_BITS_IS8 == 4 : TNS_Q_BITS == 4;
const int sfb_start = av_clip(tns_min_sfb[is8][s->samplerate_index], 0, mmm);
const int sfb_end = av_clip(sce->ics.num_swb, 0, mmm);
const int order = is8 ? 7 : s->profile == FF_PROFILE_AAC_LOW ? 12 : TNS_MAX_ORDER;
const int order = is8 ? 7 : s->profile == AV_PROFILE_AAC_LOW ? 12 : TNS_MAX_ORDER;
const int slant = sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE ? 1 :
sce->ics.window_sequence[0] == LONG_START_SEQUENCE ? 0 : 2;
const int sfb_len = sfb_end - sfb_start;
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/aacenc_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#define AVCODEC_AACENC_UTILS_H

#include "libavutil/ffmath.h"
#include "aac.h"
#include "aacenc.h"
#include "aacenctab.h"
#include "aactab.h"

Expand Down
9 changes: 5 additions & 4 deletions libavcodec/aacenctab.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "libavutil/channel_layout.h"
#include "aac.h"
#include "defs.h"

/** Total number of usable codebooks **/
#define CB_TOT 12
Expand Down Expand Up @@ -124,10 +125,10 @@ static const unsigned char aac_maxval_cb[] = {
};

static const int aacenc_profiles[] = {
FF_PROFILE_AAC_MAIN,
FF_PROFILE_AAC_LOW,
FF_PROFILE_AAC_LTP,
FF_PROFILE_MPEG2_AAC_LOW,
AV_PROFILE_AAC_MAIN,
AV_PROFILE_AAC_LOW,
AV_PROFILE_AAC_LTP,
AV_PROFILE_MPEG2_AAC_LOW,
};

#endif /* AVCODEC_AACENCTAB_H */
9 changes: 1 addition & 8 deletions libavcodec/aacps.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "libavutil/common.h"
#include "libavutil/mathematics.h"
#include "libavutil/mem_internal.h"
#include "avcodec.h"
#include "aacps.h"
#if USE_FIXED
#include "aacps_fixed_tablegen.h"
Expand Down Expand Up @@ -717,7 +716,7 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
}
}

int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
int AAC_RENAME(ff_ps_apply)(PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
{
INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
Expand All @@ -740,10 +739,4 @@ int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][

av_cold void AAC_RENAME(ff_ps_init)(void) {
ps_tableinit();
ff_ps_init_common();
}

av_cold void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps)
{
AAC_RENAME(ff_psdsp_init)(&ps->dsp);
}
12 changes: 8 additions & 4 deletions libavcodec/aacps.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "libavutil/mem_internal.h"

#include "aacpsdsp.h"
#include "avcodec.h"
#include "get_bits.h"

#define PS_MAX_NUM_ENV 5
Expand Down Expand Up @@ -94,9 +93,14 @@ extern const int8_t ff_k_to_i_34[];

void ff_ps_init_common(void);
void AAC_RENAME(ff_ps_init)(void);
void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps);
int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb,

static inline void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps)
{
AAC_RENAME(ff_psdsp_init)(&ps->dsp);
}

int ff_ps_read_data(void *logctx, GetBitContext *gb,
PSCommonContext *ps, int bits_left);
int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top);
int AAC_RENAME(ff_ps_apply)(PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top);

#endif /* AVCODEC_AACPS_H */
98 changes: 34 additions & 64 deletions libavcodec/aacps_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

#include <stdint.h>
#include "libavutil/common.h"
#include "libavutil/thread.h"
#include "aacps.h"
#include "get_bits.h"
#include "aacpsdata.c"
Expand Down Expand Up @@ -59,31 +58,31 @@ static const int huff_iid[] = {
huff_iid_dt1,
};

static VLC vlc_ps[10];
static const VLCElem *vlc_ps[10];

#define READ_PAR_DATA(PAR, OFFSET, MASK, ERR_CONDITION, NB_BITS, MAX_DEPTH) \
#define READ_PAR_DATA(PAR, MASK, ERR_CONDITION, NB_BITS, MAX_DEPTH) \
/** \
* Read Inter-channel Intensity Difference/Inter-Channel Coherence/ \
* Inter-channel Phase Difference/Overall Phase Difference parameters from the \
* bitstream. \
* \
* @param avctx contains the current codec context \
* @param logctx a context for logging \
* @param gb pointer to the input bitstream \
* @param ps pointer to the Parametric Stereo context \
* @param PAR pointer to the parameter to be read \
* @param e envelope to decode \
* @param dt 1: time delta-coded, 0: frequency delta-coded \
*/ \
static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSCommonContext *ps, \
static int read_ ## PAR ## _data(void *logctx, GetBitContext *gb, PSCommonContext *ps, \
int8_t (*PAR)[PS_MAX_NR_IIDICC], int table_idx, int e, int dt) \
{ \
int b, num = ps->nr_ ## PAR ## _par; \
const VLCElem *vlc_table = vlc_ps[table_idx].table; \
const VLCElem *vlc_table = vlc_ps[table_idx]; \
if (dt) { \
int e_prev = e ? e - 1 : ps->num_env_old - 1; \
e_prev = FFMAX(e_prev, 0); \
for (b = 0; b < num; b++) { \
int val = PAR[e_prev][b] + get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH) - OFFSET; \
int val = PAR[e_prev][b] + get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH); \
if (MASK) val &= MASK; \
PAR[e][b] = val; \
if (ERR_CONDITION) \
Expand All @@ -92,7 +91,7 @@ static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSCom
} else { \
int val = 0; \
for (b = 0; b < num; b++) { \
val += get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH) - OFFSET; \
val += get_vlc2(gb, vlc_table, NB_BITS, MAX_DEPTH); \
if (MASK) val &= MASK; \
PAR[e][b] = val; \
if (ERR_CONDITION) \
Expand All @@ -101,13 +100,13 @@ static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSCom
} \
return 0; \
err: \
av_log(avctx, AV_LOG_ERROR, "illegal "#PAR"\n"); \
av_log(logctx, AV_LOG_ERROR, "illegal "#PAR"\n"); \
return AVERROR_INVALIDDATA; \
}

READ_PAR_DATA(iid, huff_offset[table_idx], 0, FFABS(ps->iid_par[e][b]) > 7 + 8 * ps->iid_quant, 9, 3)
READ_PAR_DATA(icc, huff_offset[table_idx], 0, ps->icc_par[e][b] > 7U, 9, 2)
READ_PAR_DATA(ipdopd, 0, 0x07, 0, 5, 1)
READ_PAR_DATA(iid, 0, FFABS(ps->iid_par[e][b]) > 7 + 8 * ps->iid_quant, 9, 3)
READ_PAR_DATA(icc, 0, ps->icc_par[e][b] > 7U, 9, 2)
READ_PAR_DATA(ipdopd, 0x07, 0, 5, 1)

static int ps_read_extension_data(GetBitContext *gb, PSCommonContext *ps,
int ps_extension_id)
Expand All @@ -131,7 +130,7 @@ static int ps_read_extension_data(GetBitContext *gb, PSCommonContext *ps,
return get_bits_count(gb) - count;
}

int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
int ff_ps_read_data(void *logctx, GetBitContext *gb_host,
PSCommonContext *ps, int bits_left)
{
int e;
Expand All @@ -146,7 +145,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_iid) {
int iid_mode = get_bits(gb, 3);
if (iid_mode > 5) {
av_log(avctx, AV_LOG_ERROR, "iid_mode %d is reserved.\n",
av_log(logctx, AV_LOG_ERROR, "iid_mode %d is reserved.\n",
iid_mode);
goto err;
}
Expand All @@ -158,7 +157,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_icc) {
ps->icc_mode = get_bits(gb, 3);
if (ps->icc_mode > 5) {
av_log(avctx, AV_LOG_ERROR, "icc_mode %d is reserved.\n",
av_log(logctx, AV_LOG_ERROR, "icc_mode %d is reserved.\n",
ps->icc_mode);
goto err;
}
Expand All @@ -176,7 +175,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
for (e = 1; e <= ps->num_env; e++) {
ps->border_position[e] = get_bits(gb, 5);
if (ps->border_position[e] < ps->border_position[e-1]) {
av_log(avctx, AV_LOG_ERROR, "border_position non monotone.\n");
av_log(logctx, AV_LOG_ERROR, "border_position non monotone.\n");
goto err;
}
}
Expand All @@ -187,7 +186,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_iid) {
for (e = 0; e < ps->num_env; e++) {
int dt = get_bits1(gb);
if (read_iid_data(avctx, gb, ps, ps->iid_par, huff_iid[2*dt+ps->iid_quant], e, dt))
if (read_iid_data(logctx, gb, ps, ps->iid_par, huff_iid[2*dt+ps->iid_quant], e, dt))
goto err;
}
} else
Expand All @@ -196,7 +195,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_icc)
for (e = 0; e < ps->num_env; e++) {
int dt = get_bits1(gb);
if (read_icc_data(avctx, gb, ps, ps->icc_par, dt ? huff_icc_dt : huff_icc_df, e, dt))
if (read_icc_data(logctx, gb, ps, ps->icc_par, dt ? huff_icc_dt : huff_icc_df, e, dt))
goto err;
}
else
Expand All @@ -213,7 +212,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
cnt -= 2 + ps_read_extension_data(gb, ps, ps_extension_id);
}
if (cnt < 0) {
av_log(avctx, AV_LOG_ERROR, "ps extension overflow %d\n", cnt);
av_log(logctx, AV_LOG_ERROR, "ps extension overflow %d\n", cnt);
goto err;
}
skip_bits(gb, cnt);
Expand Down Expand Up @@ -241,15 +240,15 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
if (ps->enable_iid){
for (b = 0; b < ps->nr_iid_par; b++) {
if (FFABS(ps->iid_par[ps->num_env][b]) > 7 + 8 * ps->iid_quant) {
av_log(avctx, AV_LOG_ERROR, "iid_par invalid\n");
av_log(logctx, AV_LOG_ERROR, "iid_par invalid\n");
goto err;
}
}
}
if (ps->enable_icc){
for (b = 0; b < ps->nr_iid_par; b++) {
if (ps->icc_par[ps->num_env][b] > 7U) {
av_log(avctx, AV_LOG_ERROR, "icc_par invalid\n");
av_log(logctx, AV_LOG_ERROR, "icc_par invalid\n");
goto err;
}
}
Expand Down Expand Up @@ -278,7 +277,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
skip_bits_long(gb_host, bits_consumed);
return bits_consumed;
}
av_log(avctx, AV_LOG_ERROR, "Expected to read %d PS bits actually read %d.\n", bits_left, bits_consumed);
av_log(logctx, AV_LOG_ERROR, "Expected to read %d PS bits actually read %d.\n", bits_left, bits_consumed);
err:
ps->start = 0;
skip_bits_long(gb_host, bits_left);
Expand All @@ -289,48 +288,19 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
return bits_left;
}

#define PS_INIT_VLC_STATIC(num, nb_bits, size) \
INIT_VLC_STATIC(&vlc_ps[num], nb_bits, ps_tmp[num].table_size / ps_tmp[num].elem_size, \
ps_tmp[num].ps_bits, 1, 1, \
ps_tmp[num].ps_codes, ps_tmp[num].elem_size, ps_tmp[num].elem_size, \
size);

#define PS_VLC_ROW(name) \
{ name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) }

static av_cold void ps_init_common(void)
{
// Syntax initialization
static const struct {
const void *ps_codes, *ps_bits;
const unsigned int table_size, elem_size;
} ps_tmp[] = {
PS_VLC_ROW(huff_iid_df1),
PS_VLC_ROW(huff_iid_dt1),
PS_VLC_ROW(huff_iid_df0),
PS_VLC_ROW(huff_iid_dt0),
PS_VLC_ROW(huff_icc_df),
PS_VLC_ROW(huff_icc_dt),
PS_VLC_ROW(huff_ipd_df),
PS_VLC_ROW(huff_ipd_dt),
PS_VLC_ROW(huff_opd_df),
PS_VLC_ROW(huff_opd_dt),
};

PS_INIT_VLC_STATIC(0, 9, 1544);
PS_INIT_VLC_STATIC(1, 9, 832);
PS_INIT_VLC_STATIC(2, 9, 1024);
PS_INIT_VLC_STATIC(3, 9, 1036);
PS_INIT_VLC_STATIC(4, 9, 544);
PS_INIT_VLC_STATIC(5, 9, 544);
PS_INIT_VLC_STATIC(6, 5, 32);
PS_INIT_VLC_STATIC(7, 5, 32);
PS_INIT_VLC_STATIC(8, 5, 32);
PS_INIT_VLC_STATIC(9, 5, 32);
}

av_cold void ff_ps_init_common(void)
{
static AVOnce init_static_once = AV_ONCE_INIT;
ff_thread_once(&init_static_once, ps_init_common);
static VLCElem vlc_buf[(1544 + 832 + 1024 + 1036) +
(544 + 544) + (32 + 32 + 32 + 32)];
VLCInitState state = VLC_INIT_STATE(vlc_buf);
const uint8_t (*tab)[2] = aacps_huff_tabs;

for (int i = 0; i < FF_ARRAY_ELEMS(vlc_ps); i++) {
vlc_ps[i] =
ff_vlc_init_tables_from_lengths(&state, i <= 5 ? 9 : 5, huff_sizes[i],
&tab[0][1], 2,
&tab[0][0], 2, 1,
huff_offset[i], 0);
tab += huff_sizes[i];
}
}
185 changes: 70 additions & 115 deletions libavcodec/aacpsdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,124 +19,79 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

static const uint8_t huff_iid_df1_bits[] = {
18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15, 14, 14,
13, 12, 12, 11, 10, 10, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7,
8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 17, 18, 18,
18, 18, 18, 18, 18, 18, 18,
};

static const uint32_t huff_iid_df1_codes[] = {
0x01FEB4, 0x01FEB5, 0x01FD76, 0x01FD77, 0x01FD74, 0x01FD75, 0x01FE8A,
0x01FE8B, 0x01FE88, 0x00FE80, 0x01FEB6, 0x00FE82, 0x00FEB8, 0x007F42,
0x007FAE, 0x003FAF, 0x001FD1, 0x001FE9, 0x000FE9, 0x0007EA, 0x0007FB,
0x0003FB, 0x0001FB, 0x0001FF, 0x00007C, 0x00003C, 0x00001C, 0x00000C,
0x000000, 0x000001, 0x000001, 0x000002, 0x000001, 0x00000D, 0x00001D,
0x00003D, 0x00007D, 0x0000FC, 0x0001FC, 0x0003FC, 0x0003F4, 0x0007EB,
0x000FEA, 0x001FEA, 0x001FD6, 0x003FD0, 0x007FAF, 0x007F43, 0x00FEB9,
0x00FE83, 0x01FEB7, 0x00FE81, 0x01FE89, 0x01FE8E, 0x01FE8F, 0x01FE8C,
0x01FE8D, 0x01FEB2, 0x01FEB3, 0x01FEB0, 0x01FEB1,
};

static const uint8_t huff_iid_dt1_bits[] = {
16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 13,
13, 13, 12, 12, 11, 10, 9, 9, 7, 6, 5, 3, 1, 2, 5, 6, 7, 8,
9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16,
};

static const uint16_t huff_iid_dt1_codes[] = {
0x004ED4, 0x004ED5, 0x004ECE, 0x004ECF, 0x004ECC, 0x004ED6, 0x004ED8,
0x004F46, 0x004F60, 0x002718, 0x002719, 0x002764, 0x002765, 0x00276D,
0x0027B1, 0x0013B7, 0x0013D6, 0x0009C7, 0x0009E9, 0x0009ED, 0x0004EE,
0x0004F7, 0x000278, 0x000139, 0x00009A, 0x00009F, 0x000020, 0x000011,
0x00000A, 0x000003, 0x000001, 0x000000, 0x00000B, 0x000012, 0x000021,
0x00004C, 0x00009B, 0x00013A, 0x000279, 0x000270, 0x0004EF, 0x0004E2,
0x0009EA, 0x0009D8, 0x0013D7, 0x0013D0, 0x0027B2, 0x0027A2, 0x00271A,
0x00271B, 0x004F66, 0x004F67, 0x004F61, 0x004F47, 0x004ED9, 0x004ED7,
0x004ECD, 0x004ED2, 0x004ED3, 0x004ED0, 0x004ED1,
};

static const uint8_t huff_iid_df0_bits[] = {
17, 17, 17, 17, 16, 15, 13, 10, 9, 7, 6, 5, 4, 3, 1, 3, 4, 5,
6, 6, 8, 11, 13, 14, 14, 15, 17, 18, 18,
};

static const uint32_t huff_iid_df0_codes[] = {
0x01FFFB, 0x01FFFC, 0x01FFFD, 0x01FFFA, 0x00FFFC, 0x007FFC, 0x001FFD,
0x0003FE, 0x0001FE, 0x00007E, 0x00003C, 0x00001D, 0x00000D, 0x000005,
0x000000, 0x000004, 0x00000C, 0x00001C, 0x00003D, 0x00003E, 0x0000FE,
0x0007FE, 0x001FFC, 0x003FFC, 0x003FFD, 0x007FFD, 0x01FFFE, 0x03FFFE,
0x03FFFF,
};

static const uint8_t huff_iid_dt0_bits[] = {
19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7,
9, 11, 13, 14, 17, 19, 20, 20, 20, 20, 20,
};

static const uint32_t huff_iid_dt0_codes[] = {
0x07FFF9, 0x07FFFA, 0x07FFFB, 0x0FFFF8, 0x0FFFF9, 0x0FFFFA, 0x01FFFD,
0x007FFE, 0x000FFE, 0x0003FE, 0x0000FE, 0x00003E, 0x00000E, 0x000002,
0x000000, 0x000006, 0x00001E, 0x00007E, 0x0001FE, 0x0007FE, 0x001FFE,
0x003FFE, 0x01FFFC, 0x07FFF8, 0x0FFFFB, 0x0FFFFC, 0x0FFFFD, 0x0FFFFE,
0x0FFFFF,
};

static const uint8_t huff_icc_df_bits[] = {
14, 14, 12, 10, 7, 5, 3, 1, 2, 4, 6, 8, 9, 11, 13,
};

static const uint16_t huff_icc_df_codes[] = {
0x3FFF, 0x3FFE, 0x0FFE, 0x03FE, 0x007E, 0x001E, 0x0006, 0x0000,
0x0002, 0x000E, 0x003E, 0x00FE, 0x01FE, 0x07FE, 0x1FFE,
};

static const uint8_t huff_icc_dt_bits[] = {
14, 13, 11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12, 14,
};

static const uint16_t huff_icc_dt_codes[] = {
0x3FFE, 0x1FFE, 0x07FE, 0x01FE, 0x007E, 0x001E, 0x0006, 0x0000,
0x0002, 0x000E, 0x003E, 0x00FE, 0x03FE, 0x0FFE, 0x3FFF,
};

static const uint8_t huff_ipd_df_bits[] = {
1, 3, 4, 4, 4, 4, 4, 4,
};

static const uint8_t huff_ipd_df_codes[] = {
0x01, 0x00, 0x06, 0x04, 0x02, 0x03, 0x05, 0x07,
};

static const uint8_t huff_ipd_dt_bits[] = {
1, 3, 4, 5, 5, 4, 4, 3,
};

static const uint8_t huff_ipd_dt_codes[] = {
0x01, 0x02, 0x02, 0x03, 0x02, 0x00, 0x03, 0x03,
};

static const uint8_t huff_opd_df_bits[] = {
1, 3, 4, 4, 5, 5, 4, 3,
};

static const uint8_t huff_opd_df_codes[] = {
0x01, 0x01, 0x06, 0x04, 0x0F, 0x0E, 0x05, 0x00,
};

static const uint8_t huff_opd_dt_bits[] = {
1, 3, 4, 5, 5, 4, 4, 3,
};

static const uint8_t huff_opd_dt_codes[] = {
0x01, 0x02, 0x01, 0x07, 0x06, 0x00, 0x02, 0x03,
#include <stdint.h>

static const uint8_t huff_sizes[] = { 61, 61, 29, 29, 15, 15, 8, 8, 8, 8 };

static const uint8_t aacps_huff_tabs[][2] = {
/* huff_iid_df1 - 61 entries */
{ 28, 4 }, { 32, 4 }, { 29, 3 }, { 31, 3 }, { 27, 5 },
{ 33, 5 }, { 26, 6 }, { 34, 6 }, { 25, 7 }, { 35, 7 },
{ 24, 8 }, { 36, 8 }, { 37, 9 }, { 40, 11 }, { 19, 12 },
{ 41, 12 }, { 22, 10 }, { 38, 10 }, { 9, 17 }, { 51, 17 },
{ 11, 17 }, { 49, 17 }, { 13, 16 }, { 47, 16 }, { 16, 14 },
{ 18, 13 }, { 42, 13 }, { 44, 14 }, { 12, 17 }, { 48, 17 },
{ 4, 18 }, { 5, 18 }, { 2, 18 }, { 3, 18 }, { 15, 15 },
{ 21, 11 }, { 39, 11 }, { 45, 15 }, { 8, 18 }, { 52, 18 },
{ 6, 18 }, { 7, 18 }, { 55, 18 }, { 56, 18 }, { 53, 18 },
{ 54, 18 }, { 17, 14 }, { 43, 14 }, { 59, 18 }, { 60, 18 },
{ 57, 18 }, { 58, 18 }, { 0, 18 }, { 1, 18 }, { 10, 18 },
{ 50, 18 }, { 14, 16 }, { 46, 16 }, { 20, 12 }, { 23, 10 },
{ 30, 1 },
/* huff_iid_dt1 - 61 entries */
{ 31, 2 }, { 26, 7 }, { 34, 7 }, { 27, 6 }, { 33, 6 },
{ 35, 8 }, { 24, 9 }, { 36, 9 }, { 39, 11 }, { 41, 12 },
{ 9, 15 }, { 10, 15 }, { 48, 15 }, { 49, 15 }, { 17, 13 },
{ 23, 10 }, { 37, 10 }, { 43, 13 }, { 11, 15 }, { 12, 15 },
{ 4, 16 }, { 56, 16 }, { 2, 16 }, { 3, 16 }, { 59, 16 },
{ 60, 16 }, { 57, 16 }, { 58, 16 }, { 0, 16 }, { 1, 16 },
{ 5, 16 }, { 55, 16 }, { 6, 16 }, { 54, 16 }, { 13, 15 },
{ 15, 14 }, { 20, 12 }, { 40, 12 }, { 22, 11 }, { 38, 11 },
{ 45, 14 }, { 47, 15 }, { 7, 16 }, { 53, 16 }, { 18, 13 },
{ 42, 13 }, { 16, 14 }, { 44, 14 }, { 8, 16 }, { 52, 16 },
{ 14, 15 }, { 46, 15 }, { 50, 16 }, { 51, 16 }, { 19, 13 },
{ 21, 12 }, { 25, 9 }, { 28, 5 }, { 32, 5 }, { 29, 3 },
{ 30, 1 },
/* huff_iid_df0 - 29 entries */
{ 14, 1 }, { 15, 3 }, { 13, 3 }, { 16, 4 }, { 12, 4 },
{ 17, 5 }, { 11, 5 }, { 10, 6 }, { 18, 6 }, { 19, 6 },
{ 9, 7 }, { 20, 8 }, { 8, 9 }, { 7, 10 }, { 21, 11 },
{ 22, 13 }, { 6, 13 }, { 23, 14 }, { 24, 14 }, { 5, 15 },
{ 25, 15 }, { 4, 16 }, { 3, 17 }, { 0, 17 }, { 1, 17 },
{ 2, 17 }, { 26, 17 }, { 27, 18 }, { 28, 18 },
/* huff_iid_dt0 - 29 entries */
{ 14, 1 }, { 13, 2 }, { 15, 3 }, { 12, 4 }, { 16, 5 },
{ 11, 6 }, { 17, 7 }, { 10, 8 }, { 18, 9 }, { 9, 10 },
{ 19, 11 }, { 8, 12 }, { 20, 13 }, { 21, 14 }, { 7, 15 },
{ 22, 17 }, { 6, 17 }, { 23, 19 }, { 0, 19 }, { 1, 19 },
{ 2, 19 }, { 3, 20 }, { 4, 20 }, { 5, 20 }, { 24, 20 },
{ 25, 20 }, { 26, 20 }, { 27, 20 }, { 28, 20 },
/* huff_icc_df - 15 entries */
{ 7, 1 }, { 8, 2 }, { 6, 3 }, { 9, 4 }, { 5, 5 },
{ 10, 6 }, { 4, 7 }, { 11, 8 }, { 12, 9 }, { 3, 10 },
{ 13, 11 }, { 2, 12 }, { 14, 13 }, { 1, 14 }, { 0, 14 },
/* huff_icc_dt - 15 entries */
{ 7, 1 }, { 8, 2 }, { 6, 3 }, { 9, 4 }, { 5, 5 },
{ 10, 6 }, { 4, 7 }, { 11, 8 }, { 3, 9 }, { 12, 10 },
{ 2, 11 }, { 13, 12 }, { 1, 13 }, { 0, 14 }, { 14, 14 },
/* huff_ipd_df - 8 entries */
{ 1, 3 }, { 4, 4 }, { 5, 4 }, { 3, 4 }, { 6, 4 },
{ 2, 4 }, { 7, 4 }, { 0, 1 },
/* huff_ipd_dt - 8 entries */
{ 5, 4 }, { 4, 5 }, { 3, 5 }, { 2, 4 }, { 6, 4 },
{ 1, 3 }, { 7, 3 }, { 0, 1 },
/* huff_opd_df - 8 entries */
{ 7, 3 }, { 1, 3 }, { 3, 4 }, { 6, 4 }, { 2, 4 },
{ 5, 5 }, { 4, 5 }, { 0, 1 },
/* huff_opd_dt - 8 entries */
{ 5, 4 }, { 2, 4 }, { 6, 4 }, { 4, 5 }, { 3, 5 },
{ 1, 3 }, { 7, 3 }, { 0, 1 },
};

static const int8_t huff_offset[] = {
30, 30,
14, 14,
7, 7,
-30, -30,
-14, -14,
-7, -7,
0, 0,
0, 0,
};
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/aacpsy.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include "libavutil/ffmath.h"

#include "avcodec.h"
#include "aactab.h"
#include "aac.h"
#include "psymodel.h"

/***********************************
Expand Down
42 changes: 30 additions & 12 deletions libavcodec/aacsbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
#include "sbr.h"
#include "aacsbr.h"
#include "aacsbrdata.h"
#include "internal.h"
#include "aacps.h"
#include "sbrdsp.h"
#include "libavutil/internal.h"
#include "libavutil/intfloat.h"
#include "libavutil/libm.h"
#include "libavutil/avassert.h"
#include "libavutil/mem_internal.h"
Expand All @@ -47,7 +47,25 @@
#include "mips/aacsbr_mips.h"
#endif /* ARCH_MIPS */

static VLC vlc_sbr[10];
/**
* 2^(x) for integer x
* @return correctly rounded float
*/
static av_always_inline float exp2fi(int x) {
/* Normal range */
if (-126 <= x && x <= 128)
return av_int2float((x+127) << 23);
/* Too large */
else if (x > 128)
return INFINITY;
/* Subnormal numbers */
else if (x > -150)
return av_int2float(1 << (x+149));
/* Negligibly small */
else
return 0;
}

static void aacsbr_func_ptr_init(AACSBRContext *c);

static void make_bands(int16_t* bands, int start, int stop, int num_bands)
Expand Down Expand Up @@ -80,13 +98,13 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) {
float temp1, temp2, fac;
if (sbr->data[0].bs_amp_res) {
temp1 = ff_exp2fi(sbr->data[0].env_facs_q[e][k] + 7);
temp2 = ff_exp2fi(pan_offset - sbr->data[1].env_facs_q[e][k]);
temp1 = exp2fi(sbr->data[0].env_facs_q[e][k] + 7);
temp2 = exp2fi(pan_offset - sbr->data[1].env_facs_q[e][k]);
}
else {
temp1 = ff_exp2fi((sbr->data[0].env_facs_q[e][k]>>1) + 7) *
temp1 = exp2fi((sbr->data[0].env_facs_q[e][k]>>1) + 7) *
exp2_tab[sbr->data[0].env_facs_q[e][k] & 1];
temp2 = ff_exp2fi((pan_offset - sbr->data[1].env_facs_q[e][k])>>1) *
temp2 = exp2fi((pan_offset - sbr->data[1].env_facs_q[e][k])>>1) *
exp2_tab[(pan_offset - sbr->data[1].env_facs_q[e][k]) & 1];
}
if (temp1 > 1E20) {
Expand All @@ -100,8 +118,8 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
}
for (e = 1; e <= sbr->data[0].bs_num_noise; e++) {
for (k = 0; k < sbr->n_q; k++) {
float temp1 = ff_exp2fi(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs_q[e][k] + 1);
float temp2 = ff_exp2fi(12 - sbr->data[1].noise_facs_q[e][k]);
float temp1 = exp2fi(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs_q[e][k] + 1);
float temp2 = exp2fi(12 - sbr->data[1].noise_facs_q[e][k]);
float fac;
av_assert0(temp1 <= 1E20);
fac = temp1 / (1.0f + temp2);
Expand All @@ -114,9 +132,9 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
for (e = 1; e <= sbr->data[ch].bs_num_env; e++)
for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){
if (sbr->data[ch].bs_amp_res)
sbr->data[ch].env_facs[e][k] = ff_exp2fi(sbr->data[ch].env_facs_q[e][k] + 6);
sbr->data[ch].env_facs[e][k] = exp2fi(sbr->data[ch].env_facs_q[e][k] + 6);
else
sbr->data[ch].env_facs[e][k] = ff_exp2fi((sbr->data[ch].env_facs_q[e][k]>>1) + 6)
sbr->data[ch].env_facs[e][k] = exp2fi((sbr->data[ch].env_facs_q[e][k]>>1) + 6)
* exp2_tab[sbr->data[ch].env_facs_q[e][k] & 1];
if (sbr->data[ch].env_facs[e][k] > 1E20) {
av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
Expand All @@ -127,7 +145,7 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
for (e = 1; e <= sbr->data[ch].bs_num_noise; e++)
for (k = 0; k < sbr->n_q; k++)
sbr->data[ch].noise_facs[e][k] =
ff_exp2fi(NOISE_FLOOR_OFFSET - sbr->data[ch].noise_facs_q[e][k]);
exp2fi(NOISE_FLOOR_OFFSET - sbr->data[ch].noise_facs_q[e][k]);
}
}
}
Expand Down Expand Up @@ -215,7 +233,7 @@ static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data)
* Calculation of levels of additional HF signal components (14496-3 sp04 p219)
* and Calculation of gain (14496-3 sp04 p219)
*/
static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr,
static void sbr_gain_calc(SpectralBandReplication *sbr,
SBRData *ch_data, const int e_a[2])
{
int e, k, m;
Expand Down
22 changes: 6 additions & 16 deletions libavcodec/aacsbr.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@
#define AVCODEC_AACSBR_H

#include "get_bits.h"
#include "aac.h"
#include "aac_defines.h"
#include "sbr.h"

#define ENVELOPE_ADJUSTMENT_OFFSET 2
#define NOISE_FLOOR_OFFSET 6

struct AACDecContext;

/**
* SBR VLC tables
*/
Expand Down Expand Up @@ -66,29 +68,17 @@ enum {
EXTENSION_ID_PS = 2,
};

static const int8_t vlc_sbr_lav[10] =
{ 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 };

#define SBR_INIT_VLC_STATIC(num, size) \
INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size, \
sbr_tmp[num].sbr_bits , 1, 1, \
sbr_tmp[num].sbr_codes, sbr_tmp[num].elem_size, sbr_tmp[num].elem_size, \
size)

#define SBR_VLC_ROW(name) \
{ name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) }

/** Initialize SBR. */
void AAC_RENAME(ff_aac_sbr_init)(void);
/** Initialize one SBR context. */
int AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac);
int AAC_RENAME(ff_aac_sbr_ctx_init)(struct AACDecContext *ac, SpectralBandReplication *sbr, int id_aac);
/** Close one SBR context. */
void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr);
/** Decode one SBR element. */
int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication *sbr,
int AAC_RENAME(ff_decode_sbr_extension)(struct AACDecContext *ac, SpectralBandReplication *sbr,
GetBitContext *gb, int crc, int cnt, int id_aac);
/** Apply one SBR element to one AAC element. */
void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
void AAC_RENAME(ff_sbr_apply)(struct AACDecContext *ac, SpectralBandReplication *sbr, int id_aac,
INTFLOAT* L, INTFLOAT *R);

void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c);
Expand Down
3 changes: 1 addition & 2 deletions libavcodec/aacsbr_fixed.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
#include <float.h>
#include <math.h>

static VLC vlc_sbr[10];
static void aacsbr_func_ptr_init(AACSBRContext *c);
static const int CONST_LN2 = Q31(0.6931471806/256); // ln(2)/256
static const int CONST_RECIP_LN2 = Q31(0.7213475204); // 0.5/ln(2)
Expand Down Expand Up @@ -395,7 +394,7 @@ static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data)
* Calculation of levels of additional HF signal components (14496-3 sp04 p219)
* and Calculation of gain (14496-3 sp04 p219)
*/
static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr,
static void sbr_gain_calc(SpectralBandReplication *sbr,
SBRData *ch_data, const int e_a[2])
{
int e, k, m;
Expand Down
123 changes: 42 additions & 81 deletions libavcodec/aacsbr_template.c

Large diffs are not rendered by default.

492 changes: 0 additions & 492 deletions libavcodec/aacsbrdata.h

Large diffs are not rendered by default.

119 changes: 54 additions & 65 deletions libavcodec/aactab.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,73 @@
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
*/

#include "config.h"
#include <stddef.h>
#include <stdint.h>

#include "config_components.h"
#include "libavutil/attributes.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
#include "aac.h"
#include "aactab.h"

#include <stdint.h>

float ff_aac_pow2sf_tab[428];
float ff_aac_pow34sf_tab[428];

#if CONFIG_AAC_ENCODER || CONFIG_AAC_DECODER
#include "kbdwin.h"
#include "sinewin.h"

float ff_aac_pow2sf_tab[428];
float ff_aac_pow34sf_tab[428];

DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024];
DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128];

static av_cold void aac_tableinit(void)
{
/* 2^(i/16) for 0 <= i <= 15 */
static const float exp2_lut[] = {
1.00000000000000000000,
1.04427378242741384032,
1.09050773266525765921,
1.13878863475669165370,
1.18920711500272106672,
1.24185781207348404859,
1.29683955465100966593,
1.35425554693689272830,
1.41421356237309504880,
1.47682614593949931139,
1.54221082540794082361,
1.61049033194925430818,
1.68179283050742908606,
1.75625216037329948311,
1.83400808640934246349,
1.91520656139714729387,
};
float t1 = 8.8817841970012523233890533447265625e-16; // 2^(-50)
float t2 = 3.63797880709171295166015625e-12; // 2^(-38)
int t1_inc_cur, t2_inc_cur;
int t1_inc_prev = 0;
int t2_inc_prev = 8;

for (int i = 0; i < 428; i++) {
t1_inc_cur = 4 * (i % 4);
t2_inc_cur = (8 + 3*i) % 16;
if (t1_inc_cur < t1_inc_prev)
t1 *= 2;
if (t2_inc_cur < t2_inc_prev)
t2 *= 2;
// A much more efficient and accurate way of doing:
// ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0);
// ff_aac_pow34sf_tab[i] = pow(ff_aac_pow2sf_tab[i], 3.0/4.0);
ff_aac_pow2sf_tab[i] = t1 * exp2_lut[t1_inc_cur];
ff_aac_pow34sf_tab[i] = t2 * exp2_lut[t2_inc_cur];
t1_inc_prev = t1_inc_cur;
t2_inc_prev = t2_inc_cur;
}
}

static av_cold void aac_float_common_init(void)
{
aac_tableinit();

avpriv_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
avpriv_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
ff_init_ff_sine_windows(10);
Expand Down Expand Up @@ -1285,14 +1331,7 @@ static const uint16_t swb_offset_960_48[] =
672, 704, 736, 768, 800, 832, 864, 896, 928, 960
};

static const uint16_t swb_offset_960_32[] =
{
0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
40, 48, 56, 64, 72, 80, 88, 96, 108, 120,
132, 144, 160, 176, 196, 216, 240, 264, 292, 320,
352, 384, 416, 448, 480, 512, 544, 576, 608, 640,
672, 704, 736, 768, 800, 832, 864, 896, 928, 960
};
#define swb_offset_960_32 swb_offset_960_48

static const uint16_t swb_offset_960_24[] =
{
Expand Down Expand Up @@ -3299,53 +3338,3 @@ const DECLARE_ALIGNED(32, int, ff_aac_eld_window_480_fixed)[1800] = {
0xffecff1c, 0xffed391e, 0xffed740c, 0xffedafb1,
0xffedebe1, 0xffee287d, 0xffee654e, 0xffeea23f,
};

static void aac_tableinit(void)
{
/* 2^(i/16) for 0 <= i <= 15 */
static const float exp2_lut[] = {
1.00000000000000000000,
1.04427378242741384032,
1.09050773266525765921,
1.13878863475669165370,
1.18920711500272106672,
1.24185781207348404859,
1.29683955465100966593,
1.35425554693689272830,
1.41421356237309504880,
1.47682614593949931139,
1.54221082540794082361,
1.61049033194925430818,
1.68179283050742908606,
1.75625216037329948311,
1.83400808640934246349,
1.91520656139714729387,
};
float t1 = 8.8817841970012523233890533447265625e-16; // 2^(-50)
float t2 = 3.63797880709171295166015625e-12; // 2^(-38)
int t1_inc_cur, t2_inc_cur;
int t1_inc_prev = 0;
int t2_inc_prev = 8;

for (int i = 0; i < 428; i++) {
t1_inc_cur = 4 * (i % 4);
t2_inc_cur = (8 + 3*i) % 16;
if (t1_inc_cur < t1_inc_prev)
t1 *= 2;
if (t2_inc_cur < t2_inc_prev)
t2 *= 2;
// A much more efficient and accurate way of doing:
// ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0);
// ff_aac_pow34sf_tab[i] = pow(ff_aac_pow2sf_tab[i], 3.0/4.0);
ff_aac_pow2sf_tab[i] = t1 * exp2_lut[t1_inc_cur];
ff_aac_pow34sf_tab[i] = t2 * exp2_lut[t2_inc_cur];
t1_inc_prev = t1_inc_cur;
t2_inc_prev = t2_inc_cur;
}
}

void ff_aac_tableinit(void)
{
static AVOnce init_static_once = AV_ONCE_INIT;
ff_thread_once(&init_static_once, aac_tableinit);
}
4 changes: 1 addition & 3 deletions libavcodec/aactab.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#define AVCODEC_AACTAB_H

#include "libavutil/mem_internal.h"
#include "aac.h"
#include "aac_defines.h"

#include <stdint.h>

Expand All @@ -42,8 +42,6 @@
extern float ff_aac_pow2sf_tab[428];
extern float ff_aac_pow34sf_tab[428];

void ff_aac_tableinit(void);

/* @name ltp_coef
* Table of the LTP coefficients
*/
Expand Down
3 changes: 0 additions & 3 deletions libavcodec/aarch64/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# subsystems
OBJS-$(CONFIG_FFT) += aarch64/fft_init_aarch64.o
OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_init.o
OBJS-$(CONFIG_H264CHROMA) += aarch64/h264chroma_init_aarch64.o
OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o
Expand Down Expand Up @@ -36,7 +35,6 @@ ARMV8-OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp.o

# subsystems
NEON-OBJS-$(CONFIG_AAC_DECODER) += aarch64/sbrdsp_neon.o
NEON-OBJS-$(CONFIG_FFT) += aarch64/fft_neon.o
NEON-OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_neon.o
NEON-OBJS-$(CONFIG_H264CHROMA) += aarch64/h264cmc_neon.o
NEON-OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_neon.o \
Expand All @@ -47,7 +45,6 @@ NEON-OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_neon.o \
NEON-OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_neon.o
NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_neon.o \
aarch64/simple_idct_neon.o
NEON-OBJS-$(CONFIG_MDCT) += aarch64/mdct_neon.o
NEON-OBJS-$(CONFIG_ME_CMP) += aarch64/me_cmp_neon.o
NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o
NEON-OBJS-$(CONFIG_PIXBLOCKDSP) += aarch64/pixblockdsp_neon.o
Expand Down
218 changes: 109 additions & 109 deletions libavcodec/aarch64/aacpsdsp_neon.S
Original file line number Diff line number Diff line change
Expand Up @@ -19,130 +19,130 @@
#include "libavutil/aarch64/asm.S"

function ff_ps_add_squares_neon, export=1
1: ld1 {v0.4S,v1.4S}, [x1], #32
fmul v0.4S, v0.4S, v0.4S
fmul v1.4S, v1.4S, v1.4S
faddp v2.4S, v0.4S, v1.4S
ld1 {v3.4S}, [x0]
fadd v3.4S, v3.4S, v2.4S
st1 {v3.4S}, [x0], #16
subs w2, w2, #4
b.gt 1b
1: ld1 {v0.4s,v1.4s}, [x1], #32
fmul v0.4s, v0.4s, v0.4s
fmul v1.4s, v1.4s, v1.4s
faddp v2.4s, v0.4s, v1.4s
ld1 {v3.4s}, [x0]
fadd v3.4s, v3.4s, v2.4s
st1 {v3.4s}, [x0], #16
subs w2, w2, #4
b.gt 1b
ret
endfunc

function ff_ps_mul_pair_single_neon, export=1
1: ld1 {v0.4S,v1.4S}, [x1], #32
ld1 {v2.4S}, [x2], #16
zip1 v3.4S, v2.4S, v2.4S
zip2 v4.4S, v2.4S, v2.4S
fmul v0.4S, v0.4S, v3.4S
fmul v1.4S, v1.4S, v4.4S
st1 {v0.4S,v1.4S}, [x0], #32
subs w3, w3, #4
b.gt 1b
1: ld1 {v0.4s,v1.4s}, [x1], #32
ld1 {v2.4s}, [x2], #16
zip1 v3.4s, v2.4s, v2.4s
zip2 v4.4s, v2.4s, v2.4s
fmul v0.4s, v0.4s, v3.4s
fmul v1.4s, v1.4s, v4.4s
st1 {v0.4s,v1.4s}, [x0], #32
subs w3, w3, #4
b.gt 1b
ret
endfunc

function ff_ps_stereo_interpolate_neon, export=1
ld1 {v0.4S}, [x2]
ld1 {v1.4S}, [x3]
zip1 v4.4S, v0.4S, v0.4S
zip2 v5.4S, v0.4S, v0.4S
zip1 v6.4S, v1.4S, v1.4S
zip2 v7.4S, v1.4S, v1.4S
1: ld1 {v2.2S}, [x0]
ld1 {v3.2S}, [x1]
fadd v4.4S, v4.4S, v6.4S
fadd v5.4S, v5.4S, v7.4S
mov v2.D[1], v2.D[0]
mov v3.D[1], v3.D[0]
fmul v2.4S, v2.4S, v4.4S
fmla v2.4S, v3.4S, v5.4S
st1 {v2.D}[0], [x0], #8
st1 {v2.D}[1], [x1], #8
subs w4, w4, #1
b.gt 1b
ld1 {v0.4s}, [x2]
ld1 {v1.4s}, [x3]
zip1 v4.4s, v0.4s, v0.4s
zip2 v5.4s, v0.4s, v0.4s
zip1 v6.4s, v1.4s, v1.4s
zip2 v7.4s, v1.4s, v1.4s
1: ld1 {v2.2s}, [x0]
ld1 {v3.2s}, [x1]
fadd v4.4s, v4.4s, v6.4s
fadd v5.4s, v5.4s, v7.4s
mov v2.d[1], v2.d[0]
mov v3.d[1], v3.d[0]
fmul v2.4s, v2.4s, v4.4s
fmla v2.4s, v3.4s, v5.4s
st1 {v2.d}[0], [x0], #8
st1 {v2.d}[1], [x1], #8
subs w4, w4, #1
b.gt 1b
ret
endfunc

function ff_ps_stereo_interpolate_ipdopd_neon, export=1
ld1 {v0.4S,v1.4S}, [x2]
ld1 {v6.4S,v7.4S}, [x3]
fneg v2.4S, v1.4S
fneg v3.4S, v7.4S
zip1 v16.4S, v0.4S, v0.4S
zip2 v17.4S, v0.4S, v0.4S
zip1 v18.4S, v2.4S, v1.4S
zip2 v19.4S, v2.4S, v1.4S
zip1 v20.4S, v6.4S, v6.4S
zip2 v21.4S, v6.4S, v6.4S
zip1 v22.4S, v3.4S, v7.4S
zip2 v23.4S, v3.4S, v7.4S
1: ld1 {v2.2S}, [x0]
ld1 {v3.2S}, [x1]
fadd v16.4S, v16.4S, v20.4S
fadd v17.4S, v17.4S, v21.4S
mov v2.D[1], v2.D[0]
mov v3.D[1], v3.D[0]
fmul v4.4S, v2.4S, v16.4S
fmla v4.4S, v3.4S, v17.4S
fadd v18.4S, v18.4S, v22.4S
fadd v19.4S, v19.4S, v23.4S
ext v2.16B, v2.16B, v2.16B, #4
ext v3.16B, v3.16B, v3.16B, #4
fmla v4.4S, v2.4S, v18.4S
fmla v4.4S, v3.4S, v19.4S
st1 {v4.D}[0], [x0], #8
st1 {v4.D}[1], [x1], #8
subs w4, w4, #1
b.gt 1b
ld1 {v0.4s,v1.4s}, [x2]
ld1 {v6.4s,v7.4s}, [x3]
fneg v2.4s, v1.4s
fneg v3.4s, v7.4s
zip1 v16.4s, v0.4s, v0.4s
zip2 v17.4s, v0.4s, v0.4s
zip1 v18.4s, v2.4s, v1.4s
zip2 v19.4s, v2.4s, v1.4s
zip1 v20.4s, v6.4s, v6.4s
zip2 v21.4s, v6.4s, v6.4s
zip1 v22.4s, v3.4s, v7.4s
zip2 v23.4s, v3.4s, v7.4s
1: ld1 {v2.2s}, [x0]
ld1 {v3.2s}, [x1]
fadd v16.4s, v16.4s, v20.4s
fadd v17.4s, v17.4s, v21.4s
mov v2.d[1], v2.d[0]
mov v3.d[1], v3.d[0]
fmul v4.4s, v2.4s, v16.4s
fmla v4.4s, v3.4s, v17.4s
fadd v18.4s, v18.4s, v22.4s
fadd v19.4s, v19.4s, v23.4s
ext v2.16b, v2.16b, v2.16b, #4
ext v3.16b, v3.16b, v3.16b, #4
fmla v4.4s, v2.4s, v18.4s
fmla v4.4s, v3.4s, v19.4s
st1 {v4.d}[0], [x0], #8
st1 {v4.d}[1], [x1], #8
subs w4, w4, #1
b.gt 1b
ret
endfunc

function ff_ps_hybrid_analysis_neon, export=1
lsl x3, x3, #3
ld2 {v0.4S,v1.4S}, [x1], #32
ld2 {v2.2S,v3.2S}, [x1], #16
ld1 {v24.2S}, [x1], #8
ld2 {v4.2S,v5.2S}, [x1], #16
ld2 {v6.4S,v7.4S}, [x1]
rev64 v6.4S, v6.4S
rev64 v7.4S, v7.4S
ext v6.16B, v6.16B, v6.16B, #8
ext v7.16B, v7.16B, v7.16B, #8
rev64 v4.2S, v4.2S
rev64 v5.2S, v5.2S
mov v2.D[1], v3.D[0]
mov v4.D[1], v5.D[0]
mov v5.D[1], v2.D[0]
mov v3.D[1], v4.D[0]
fadd v16.4S, v0.4S, v6.4S
fadd v17.4S, v1.4S, v7.4S
fsub v18.4S, v1.4S, v7.4S
fsub v19.4S, v0.4S, v6.4S
fadd v22.4S, v2.4S, v4.4S
fsub v23.4S, v5.4S, v3.4S
trn1 v20.2D, v22.2D, v23.2D // {re4+re8, re5+re7, im8-im4, im7-im5}
trn2 v21.2D, v22.2D, v23.2D // {im4+im8, im5+im7, re4-re8, re5-re7}
1: ld2 {v2.4S,v3.4S}, [x2], #32
ld2 {v4.2S,v5.2S}, [x2], #16
ld1 {v6.2S}, [x2], #8
add x2, x2, #8
mov v4.D[1], v5.D[0]
mov v6.S[1], v6.S[0]
fmul v6.2S, v6.2S, v24.2S
fmul v0.4S, v2.4S, v16.4S
fmul v1.4S, v2.4S, v17.4S
fmls v0.4S, v3.4S, v18.4S
fmla v1.4S, v3.4S, v19.4S
fmla v0.4S, v4.4S, v20.4S
fmla v1.4S, v4.4S, v21.4S
faddp v0.4S, v0.4S, v1.4S
faddp v0.4S, v0.4S, v0.4S
fadd v0.2S, v0.2S, v6.2S
st1 {v0.2S}, [x0], x3
subs w4, w4, #1
b.gt 1b
lsl x3, x3, #3
ld2 {v0.4s,v1.4s}, [x1], #32
ld2 {v2.2s,v3.2s}, [x1], #16
ld1 {v24.2s}, [x1], #8
ld2 {v4.2s,v5.2s}, [x1], #16
ld2 {v6.4s,v7.4s}, [x1]
rev64 v6.4s, v6.4s
rev64 v7.4s, v7.4s
ext v6.16b, v6.16b, v6.16b, #8
ext v7.16b, v7.16b, v7.16b, #8
rev64 v4.2s, v4.2s
rev64 v5.2s, v5.2s
mov v2.d[1], v3.d[0]
mov v4.d[1], v5.d[0]
mov v5.d[1], v2.d[0]
mov v3.d[1], v4.d[0]
fadd v16.4s, v0.4s, v6.4s
fadd v17.4s, v1.4s, v7.4s
fsub v18.4s, v1.4s, v7.4s
fsub v19.4s, v0.4s, v6.4s
fadd v22.4s, v2.4s, v4.4s
fsub v23.4s, v5.4s, v3.4s
trn1 v20.2d, v22.2d, v23.2d // {re4+re8, re5+re7, im8-im4, im7-im5}
trn2 v21.2d, v22.2d, v23.2d // {im4+im8, im5+im7, re4-re8, re5-re7}
1: ld2 {v2.4s,v3.4s}, [x2], #32
ld2 {v4.2s,v5.2s}, [x2], #16
ld1 {v6.2s}, [x2], #8
add x2, x2, #8
mov v4.d[1], v5.d[0]
mov v6.s[1], v6.s[0]
fmul v6.2s, v6.2s, v24.2s
fmul v0.4s, v2.4s, v16.4s
fmul v1.4s, v2.4s, v17.4s
fmls v0.4s, v3.4s, v18.4s
fmla v1.4s, v3.4s, v19.4s
fmla v0.4s, v4.4s, v20.4s
fmla v1.4s, v4.4s, v21.4s
faddp v0.4s, v0.4s, v1.4s
faddp v0.4s, v0.4s, v0.4s
fadd v0.2s, v0.2s, v6.2s
st1 {v0.2s}, [x0], x3
subs w4, w4, #1
b.gt 1b
ret
endfunc
52 changes: 0 additions & 52 deletions libavcodec/aarch64/fft_init_aarch64.c

This file was deleted.

Loading