chromium/third_party/ffmpeg/libavcodec/mpegaudiodec_template.c

/*
 * MPEG Audio decoder
 * Copyright (c) 2001, 2002 Fabrice Bellard
 *
 * 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
 * MPEG Audio decoder
 */

#include "config_components.h"

#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
#include "libavutil/float_dsp.h"
#include "libavutil/libm.h"
#include "libavutil/mem.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"

#include "avcodec.h"
#include "decode.h"
#include "get_bits.h"
#include "mathops.h"
#include "mpegaudiodsp.h"

/*
 * TODO:
 *  - test lsf / mpeg25 extensively.
 */

#include "mpegaudio.h"
#include "mpegaudiodecheader.h"

#define BACKSTEP_SIZE
#define EXTRABYTES
#define LAST_BUF_SIZE

/* layer 3 "granule" */
GranuleDef;

MPADecodeContext;

#define HEADER_SIZE

#include "mpegaudiodata.h"

#include "mpegaudio_tablegen.h"
/* intensity stereo coef table */
static INTFLOAT is_table_lsf[2][2][16];

/* [i][j]:  2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
static int32_t scale_factor_mult[15][3];
/* mult table for layer 2 group quantization */

#define SCALE_GEN(v)

static const int32_t scale_factor_mult2[3][3] =;

/**
 * Convert region offsets to region sizes and truncate
 * size to big_values.
 */
static void region_offset2size(GranuleDef *g)
{}

static void init_short_region(MPADecodeContext *s, GranuleDef *g)
{}

static void init_long_region(MPADecodeContext *s, GranuleDef *g,
                             int ra1, int ra2)
{}

static void compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
{}

/* layer 1 unscaling */
/* n = number of bits of the mantissa minus 1 */
static inline int l1_unscale(int n, int mant, int scale_factor)
{}

static inline int l2_unscale_group(int steps, int mant, int scale_factor)
{}

/* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */
static inline int l3_unscale(int value, int exponent)
{}

static av_cold void decode_init_static(void)
{}

static av_cold int decode_init(AVCodecContext * avctx)
{}

#define C3
#define C4
#define C5
#define C6

/* 12 points IMDCT. We compute it "by hand" by factorizing obvious
   cases. */
static void imdct12(INTFLOAT *out, SUINTFLOAT *in)
{}

static int handle_crc(MPADecodeContext *s, int sec_len)
{}

/* return the number of decoded frames */
static int mp_decode_layer1(MPADecodeContext *s)
{}

static int mp_decode_layer2(MPADecodeContext *s)
{}

#define SPLIT(dst,sf,n)

static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2,
                                           int n3)
{}

static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g,
                                         int16_t *exponents)
{}

static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos,
                          int *end_pos2)
{}

/* Following is an optimized code for
            INTFLOAT v = *src
            if(get_bits1(&s->gb))
                v = -v;
            *dst = v;
*/
#if USE_FLOATS
#define READ_FLIP_SIGN
#else
#define READ_FLIP_SIGN(dst,src)
#endif

static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
                          int16_t *exponents, int end_pos2)
{}

/* Reorder short blocks from bitstream order to interleaved order. It
   would be faster to do it in parsing, but the code would be far more
   complicated */
static void reorder_block(MPADecodeContext *s, GranuleDef *g)
{}

#define ISQRT2

static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1)
{}

#if USE_FLOATS
#if HAVE_MIPSFPU
#   include "mips/compute_antialias_float.h"
#endif /* HAVE_MIPSFPU */
#else
#if HAVE_MIPSDSP
#   include "mips/compute_antialias_fixed.h"
#endif /* HAVE_MIPSDSP */
#endif /* USE_FLOATS */

#ifndef compute_antialias
#if USE_FLOATS
#define AA
#else
#define AA(j)
#endif

static void compute_antialias(MPADecodeContext *s, GranuleDef *g)
{}
#endif /* compute_antialias */

static void compute_imdct(MPADecodeContext *s, GranuleDef *g,
                          INTFLOAT *sb_samples, INTFLOAT *mdct_buf)
{}

/* main layer3 decoding function */
static int mp_decode_layer3(MPADecodeContext *s)
{}

static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples,
                           const uint8_t *buf, int buf_size)
{}

static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
                        int *got_frame_ptr, AVPacket *avpkt)
{}

static void mp_flush(MPADecodeContext *ctx)
{}

static void flush(AVCodecContext *avctx)
{}

#if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER
static int decode_frame_adu(AVCodecContext *avctx, AVFrame *frame,
                            int *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf  = avpkt->data;
    int buf_size        = avpkt->size;
    MPADecodeContext *s = avctx->priv_data;
    uint32_t header;
    int len, ret;

    len = buf_size;

    // Discard too short frames
    if (buf_size < HEADER_SIZE) {
        av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
        return AVERROR_INVALIDDATA;
    }


    if (len > MPA_MAX_CODED_FRAME_SIZE)
        len = MPA_MAX_CODED_FRAME_SIZE;

    // Get header and restore sync word
    header = AV_RB32(buf) | 0xffe00000;

    ret = avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n");
        return ret;
    }
    /* update codec info */
    avctx->sample_rate = s->sample_rate;
    av_channel_layout_uninit(&avctx->ch_layout);
    avctx->ch_layout = s->nb_channels == 1 ? (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO :
                                             (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
    if (!avctx->bit_rate)
        avctx->bit_rate = s->bit_rate;

    s->frame_size = len;

    s->frame = frame;

    ret = mp_decode_frame(s, NULL, buf, buf_size);
    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
        return ret;
    }

    *got_frame_ptr = 1;

    return buf_size;
}
#endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */

#if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER

/**
 * Context for MP3On4 decoder
 */
typedef struct MP3On4DecodeContext {
    int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
    int syncword;                   ///< syncword patch
    const uint8_t *coff;            ///< channel offsets in output buffer
    MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
} MP3On4DecodeContext;

#include "mpeg4audio.h"

/* Next 3 arrays are indexed by channel config number (passed via codecdata) */

/* number of mp3 decoder instances */
static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 };

/* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */
static const uint8_t chan_offset[8][5] = {
    { 0             },
    { 0             },  // C
    { 0             },  // FLR
    { 2, 0          },  // C FLR
    { 2, 0, 3       },  // C FLR BS
    { 2, 0, 3       },  // C FLR BLRS
    { 2, 0, 4, 3    },  // C FLR BLRS LFE
    { 2, 0, 6, 4, 3 },  // C FLR BLRS BLR LFE
};

/* mp3on4 channel layouts */
static const int16_t chan_layout[8] = {
    0,
    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
};

static av_cold int decode_close_mp3on4(AVCodecContext * avctx)
{
    MP3On4DecodeContext *s = avctx->priv_data;
    int i;

    for (i = 0; i < s->frames; i++)
        av_freep(&s->mp3decctx[i]);

    return 0;
}


static av_cold int decode_init_mp3on4(AVCodecContext * avctx)
{
    MP3On4DecodeContext *s = avctx->priv_data;
    MPEG4AudioConfig cfg;
    int i, ret;

    if ((avctx->extradata_size < 2) || !avctx->extradata) {
        av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n");
        return AVERROR_INVALIDDATA;
    }

    avpriv_mpeg4audio_get_config2(&cfg, avctx->extradata,
                                  avctx->extradata_size, 1, avctx);
    if (!cfg.chan_config || cfg.chan_config > 7) {
        av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
        return AVERROR_INVALIDDATA;
    }
    s->frames             = mp3Frames[cfg.chan_config];
    s->coff               = chan_offset[cfg.chan_config];
    av_channel_layout_uninit(&avctx->ch_layout);
    av_channel_layout_from_mask(&avctx->ch_layout, chan_layout[cfg.chan_config]);

    if (cfg.sample_rate < 16000)
        s->syncword = 0xffe00000;
    else
        s->syncword = 0xfff00000;

    /* Init the first mp3 decoder in standard way, so that all tables get builded
     * We replace avctx->priv_data with the context of the first decoder so that
     * decode_init() does not have to be changed.
     * Other decoders will be initialized here copying data from the first context
     */
    // Allocate zeroed memory for the first decoder context
    s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext));
    if (!s->mp3decctx[0])
        return AVERROR(ENOMEM);
    // Put decoder context in place to make init_decode() happy
    avctx->priv_data = s->mp3decctx[0];
    ret = decode_init(avctx);
    // Restore mp3on4 context pointer
    avctx->priv_data = s;
    if (ret < 0)
        return ret;
    s->mp3decctx[0]->adu_mode = 1; // Set adu mode

    /* Create a separate codec/context for each frame (first is already ok).
     * Each frame is 1 or 2 channels - up to 5 frames allowed
     */
    for (i = 1; i < s->frames; i++) {
        s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext));
        if (!s->mp3decctx[i])
            return AVERROR(ENOMEM);
        s->mp3decctx[i]->adu_mode = 1;
        s->mp3decctx[i]->avctx = avctx;
        s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;
        s->mp3decctx[i]->butterflies_float = s->mp3decctx[0]->butterflies_float;
    }

    return 0;
}


static void flush_mp3on4(AVCodecContext *avctx)
{
    int i;
    MP3On4DecodeContext *s = avctx->priv_data;

    for (i = 0; i < s->frames; i++)
        mp_flush(s->mp3decctx[i]);
}


static int decode_frame_mp3on4(AVCodecContext *avctx, AVFrame *frame,
                               int *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf     = avpkt->data;
    int buf_size           = avpkt->size;
    MP3On4DecodeContext *s = avctx->priv_data;
    MPADecodeContext *m;
    int fsize, len = buf_size, out_size = 0;
    uint32_t header;
    OUT_INT **out_samples;
    OUT_INT *outptr[2];
    int fr, ch, ret;

    /* get output buffer */
    frame->nb_samples = MPA_FRAME_SIZE;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;
    out_samples = (OUT_INT **)frame->extended_data;

    // Discard too short frames
    if (buf_size < HEADER_SIZE)
        return AVERROR_INVALIDDATA;

    avctx->bit_rate = 0;

    ch = 0;
    for (fr = 0; fr < s->frames; fr++) {
        fsize = AV_RB16(buf) >> 4;
        fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);
        m     = s->mp3decctx[fr];
        av_assert1(m);

        if (fsize < HEADER_SIZE) {
            av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
            return AVERROR_INVALIDDATA;
        }
        header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header

        ret = avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
        if (ret < 0) {
            av_log(avctx, AV_LOG_ERROR, "Bad header, discard block\n");
            return AVERROR_INVALIDDATA;
        }

        if (ch + m->nb_channels > avctx->ch_layout.nb_channels ||
            s->coff[fr] + m->nb_channels > avctx->ch_layout.nb_channels) {
            av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
                                        "channel count\n");
            return AVERROR_INVALIDDATA;
        }
        ch += m->nb_channels;

        outptr[0] = out_samples[s->coff[fr]];
        if (m->nb_channels > 1)
            outptr[1] = out_samples[s->coff[fr] + 1];

        if ((ret = mp_decode_frame(m, outptr, buf, fsize)) < 0) {
            av_log(avctx, AV_LOG_ERROR, "failed to decode channel %d\n", ch);
            memset(outptr[0], 0, MPA_FRAME_SIZE*sizeof(OUT_INT));
            if (m->nb_channels > 1)
                memset(outptr[1], 0, MPA_FRAME_SIZE*sizeof(OUT_INT));
            ret = m->nb_channels * MPA_FRAME_SIZE*sizeof(OUT_INT);
        }

        out_size += ret;
        buf      += fsize;
        len      -= fsize;

        avctx->bit_rate += m->bit_rate;
    }
    if (ch != avctx->ch_layout.nb_channels) {
        av_log(avctx, AV_LOG_ERROR, "failed to decode all channels\n");
        return AVERROR_INVALIDDATA;
    }

    /* update codec info */
    avctx->sample_rate = s->mp3decctx[0]->sample_rate;

    frame->nb_samples = out_size / (avctx->ch_layout.nb_channels * sizeof(OUT_INT));
    *got_frame_ptr    = 1;

    return buf_size;
}
#endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */