X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fatrac3.c;h=2e1fd3c13362bea9aba935785bfdb4df952756ae;hb=901f9c0a32985f48672fd68594111dc55d88a57a;hp=69b42fd07d68cf883cd4396062553b0c9015d5bb;hpb=78edce3f1973cf8d611e0408b8d3681038828cfc;p=ffmpeg diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 69b42fd07d6..2e1fd3c1336 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -1,5 +1,5 @@ /* - * Atrac 3 compatible decoder + * ATRAC3 compatible decoder * Copyright (c) 2006-2008 Maxim Poliakovski * Copyright (c) 2006-2008 Benjamin Larsson * @@ -22,10 +22,10 @@ /** * @file - * Atrac 3 compatible decoder. + * ATRAC3 compatible decoder. * This decoder handles Sony's ATRAC3 data. * - * Container formats used to store atrac 3 data: + * Container formats used to store ATRAC3 data: * RealMedia (.rm), RIFF WAV (.wav, .at3), Sony OpenMG (.oma, .aa3). * * To use this decoder, a calling application must supply the extradata @@ -36,12 +36,13 @@ #include #include +#include "libavutil/attributes.h" #include "libavutil/float_dsp.h" #include "avcodec.h" #include "bytestream.h" #include "fft.h" -#include "fmtconvert.h" #include "get_bits.h" +#include "internal.h" #include "atrac.h" #include "atrac3data.h" @@ -52,14 +53,8 @@ #define SAMPLES_PER_FRAME 1024 #define MDCT_SIZE 512 -typedef struct GainInfo { - int num_gain_data; - int lev_code[8]; - int loc_code[8]; -} GainInfo; - typedef struct GainBlock { - GainInfo g_block[4]; + AtracGainInfo g_block[4]; } GainBlock; typedef struct TonalComponent { @@ -85,12 +80,10 @@ typedef struct ChannelUnit { } ChannelUnit; typedef struct ATRAC3Context { - AVFrame frame; GetBitContext gb; //@{ /** stream data */ int coding_mode; - int sample_rate; ChannelUnit *units; //@} @@ -111,18 +104,16 @@ typedef struct ATRAC3Context { int scrambled_stream; //@} + AtracGCContext gainc_ctx; FFTContext mdct_ctx; - FmtConvertContext fmt_conv; AVFloatDSPContext fdsp; } ATRAC3Context; static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE]; +static VLC_TYPE atrac3_vlc_table[4096][2]; static VLC spectral_coeff_tab[7]; -static float gain_tab1[16]; -static float gain_tab2[31]; - -/* +/** * Regular 512 points IMDCT without overlapping, with the exception of the * swapping of odd bands caused by the reverse spectra of the QMF. * @@ -163,32 +154,32 @@ static int decode_bytes(const uint8_t *input, uint8_t *out, int bytes) off = (intptr_t)input & 3; buf = (const uint32_t *)(input - off); - c = av_be2ne32((0x537F6103 >> (off * 8)) | (0x537F6103 << (32 - (off * 8)))); + if (off) + c = av_be2ne32((0x537F6103U >> (off * 8)) | (0x537F6103U << (32 - (off * 8)))); + else + c = av_be2ne32(0x537F6103U); bytes += 3 + off; for (i = 0; i < bytes / 4; i++) output[i] = c ^ buf[i]; if (off) - av_log_ask_for_sample(NULL, "Offset of %d not handled.\n", off); + avpriv_request_sample(NULL, "Offset of %d", off); return off; } -static av_cold void init_atrac3_window(void) +static av_cold void init_imdct_window(void) { - float enc_window[256]; - int i; + int i, j; /* generate the mdct window, for details see * http://wiki.multimedia.cx/index.php?title=RealAudio_atrc#Windows */ - for (i = 0; i < 256; i++) - enc_window[i] = (sin(((i + 0.5) / 256.0 - 0.5) * M_PI) + 1.0) * 0.5; - - for (i = 0; i < 256; i++) { - mdct_window[i] = enc_window[i] / - (enc_window[ i] * enc_window[ i] + - enc_window[255 - i] * enc_window[255 - i]); - mdct_window[511 - i] = mdct_window[i]; + for (i = 0, j = 255; i < 128; i++, j--) { + float wi = sin(((i + 0.5) / 256.0 - 0.5) * M_PI) + 1.0; + float wj = sin(((j + 0.5) / 256.0 - 0.5) * M_PI) + 1.0; + float w = 0.5 * (wi * wi + wj * wj); + mdct_window[i] = mdct_window[511 - i] = wi / w; + mdct_window[j] = mdct_window[511 - j] = wj / w; } } @@ -204,7 +195,7 @@ static av_cold int atrac3_decode_close(AVCodecContext *avctx) return 0; } -/* +/** * Mantissa decoding * * @param selector which table the output values are coded with @@ -266,7 +257,7 @@ static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, } } -/* +/** * Restore the quantized band spectrum coefficients * * @return subband count, fix for broken specification/files @@ -313,17 +304,17 @@ static int decode_spectrum(GetBitContext *gb, float *output) output[first] = mantissas[j] * scale_factor; } else { /* this subband was not coded, so zero the entire subband */ - memset(output + first, 0, subband_size * sizeof(float)); + memset(output + first, 0, subband_size * sizeof(*output)); } } /* clear the subbands that were not coded */ first = subband_tab[i]; - memset(output + first, 0, (SAMPLES_PER_FRAME - first) * sizeof(float)); + memset(output + first, 0, (SAMPLES_PER_FRAME - first) * sizeof(*output)); return num_subbands; } -/* +/** * Restore the quantized tonal components * * @param components tonal components @@ -407,7 +398,7 @@ static int decode_tonal_components(GetBitContext *gb, return component_count; } -/* +/** * Decode gain parameters for the coded bands * * @param block the gainblock for the current band @@ -416,90 +407,32 @@ static int decode_tonal_components(GetBitContext *gb, static int decode_gain_control(GetBitContext *gb, GainBlock *block, int num_bands) { - int i, cf, num_data; + int i, j; int *level, *loc; - GainInfo *gain = block->g_block; + AtracGainInfo *gain = block->g_block; for (i = 0; i <= num_bands; i++) { - num_data = get_bits(gb, 3); - gain[i].num_gain_data = num_data; + gain[i].num_points = get_bits(gb, 3); level = gain[i].lev_code; loc = gain[i].loc_code; - for (cf = 0; cf < gain[i].num_gain_data; cf++) { - level[cf] = get_bits(gb, 4); - loc [cf] = get_bits(gb, 5); - if (cf && loc[cf] <= loc[cf - 1]) + for (j = 0; j < gain[i].num_points; j++) { + level[j] = get_bits(gb, 4); + loc[j] = get_bits(gb, 5); + if (j && loc[j] <= loc[j - 1]) return AVERROR_INVALIDDATA; } } /* Clear the unused blocks. */ for (; i < 4 ; i++) - gain[i].num_gain_data = 0; + gain[i].num_points = 0; return 0; } -/* - * Apply gain parameters and perform the MDCT overlapping part - * - * @param input input buffer - * @param prev previous buffer to perform overlap against - * @param output output buffer - * @param gain1 current band gain info - * @param gain2 next band gain info - */ -static void gain_compensate_and_overlap(float *input, float *prev, - float *output, GainInfo *gain1, - GainInfo *gain2) -{ - float g1, g2, gain_inc; - int i, j, num_data, start_loc, end_loc; - - - if (gain2->num_gain_data == 0) - g1 = 1.0; - else - g1 = gain_tab1[gain2->lev_code[0]]; - - if (gain1->num_gain_data == 0) { - for (i = 0; i < 256; i++) - output[i] = input[i] * g1 + prev[i]; - } else { - num_data = gain1->num_gain_data; - gain1->loc_code[num_data] = 32; - gain1->lev_code[num_data] = 4; - - for (i = 0, j = 0; i < num_data; i++) { - start_loc = gain1->loc_code[i] * 8; - end_loc = start_loc + 8; - - g2 = gain_tab1[gain1->lev_code[i]]; - gain_inc = gain_tab2[gain1->lev_code[i + 1] - - gain1->lev_code[i ] + 15]; - - /* interpolate */ - for (; j < start_loc; j++) - output[j] = (input[j] * g1 + prev[j]) * g2; - - /* interpolation is done over eight samples */ - for (; j < end_loc; j++) { - output[j] = (input[j] * g1 + prev[j]) * g2; - g2 *= gain_inc; - } - } - - for (; j < 256; j++) - output[j] = input[j] * g1 + prev[j]; - } - - /* Delay for the overlapping part. */ - memcpy(prev, &input[256], 256 * sizeof(float)); -} - -/* +/** * Combine the tonal band spectrum and regular band spectrum * * @param spectrum output spectrum buffer @@ -519,7 +452,7 @@ static int add_tonal_components(float *spectrum, int num_components, output = &spectrum[components[i].pos]; for (j = 0; j < components[i].num_coefs; j++) - output[i] += input[i]; + output[j] += input[j]; } return last_pos; @@ -626,7 +559,7 @@ static void channel_weighting(float *su1, float *su2, int *p3) } } -/* +/** * Decode a Sound Unit * * @param snd the channel unit to be used @@ -663,8 +596,8 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, snd->num_components = decode_tonal_components(gb, snd->components, snd->bands_coded); - if (snd->num_components == -1) - return -1; + if (snd->num_components < 0) + return snd->num_components; num_subbands = decode_spectrum(gb, snd->spectrum); @@ -686,14 +619,13 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, if (band <= num_bands) imlt(q, &snd->spectrum[band * 256], snd->imdct_buf, band & 1); else - memset(snd->imdct_buf, 0, 512 * sizeof(float)); + memset(snd->imdct_buf, 0, 512 * sizeof(*snd->imdct_buf)); /* gain compensation and overlapping */ - gain_compensate_and_overlap(snd->imdct_buf, - &snd->prev_frame[band * 256], - &output[band * 256], - &gain1->g_block[band], - &gain2->g_block[band]); + ff_atrac_gain_compensation(&q->gainc_ctx, snd->imdct_buf, + &snd->prev_frame[band * 256], + &gain1->g_block[band], &gain2->g_block[band], + 256, &output[band * 256]); } /* Swap the gain control buffers for the next frame. */ @@ -741,10 +673,11 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, /* set the bitstream reader at the start of the second Sound Unit*/ - init_get_bits(&q->gb, ptr1, avctx->block_align * 8); + init_get_bits(&q->gb, ptr1, (avctx->block_align - i) * 8); /* Fill the Weighting coeffs delay buffer */ - memmove(q->weighting_delay, &q->weighting_delay[2], 4 * sizeof(int)); + memmove(q->weighting_delay, &q->weighting_delay[2], + 4 * sizeof(*q->weighting_delay)); q->weighting_delay[4] = get_bits1(&q->gb); q->weighting_delay[5] = get_bits(&q->gb, 3); @@ -799,6 +732,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, static int atrac3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; ATRAC3Context *q = avctx->priv_data; @@ -812,8 +746,8 @@ static int atrac3_decode_frame(AVCodecContext *avctx, void *data, } /* get output buffer */ - q->frame.nb_samples = SAMPLES_PER_FRAME; - if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) { + frame->nb_samples = SAMPLES_PER_FRAME; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -826,29 +760,41 @@ static int atrac3_decode_frame(AVCodecContext *avctx, void *data, databuf = buf; } - ret = decode_frame(avctx, databuf, (float **)q->frame.extended_data); + ret = decode_frame(avctx, databuf, (float **)frame->extended_data); if (ret) { av_log(NULL, AV_LOG_ERROR, "Frame decoding error!\n"); return ret; } - *got_frame_ptr = 1; - *(AVFrame *)data = q->frame; + *got_frame_ptr = 1; return avctx->block_align; } +static av_cold void atrac3_init_static_data(AVCodec *codec) +{ + int i; + + init_imdct_window(); + ff_atrac_generate_tables(); + + /* Initialize the VLC tables. */ + for (i = 0; i < 7; i++) { + spectral_coeff_tab[i].table = &atrac3_vlc_table[atrac3_vlc_offs[i]]; + spectral_coeff_tab[i].table_allocated = atrac3_vlc_offs[i + 1] - + atrac3_vlc_offs[i ]; + init_vlc(&spectral_coeff_tab[i], 9, huff_tab_sizes[i], + huff_bits[i], 1, 1, + huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + } +} + static av_cold int atrac3_decode_init(AVCodecContext *avctx) { int i, ret; int version, delay, samples_per_frame, frame_factor; const uint8_t *edata_ptr = avctx->extradata; ATRAC3Context *q = avctx->priv_data; - static VLC_TYPE atrac3_vlc_table[4096][2]; - static int vlcs_initialized = 0; - - /* Take data from the AVCodecContext (RM container). */ - q->sample_rate = avctx->sample_rate; if (avctx->channels <= 0 || avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "Channel configuration error!\n"); @@ -894,6 +840,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) } else { av_log(NULL, AV_LOG_ERROR, "Unknown extradata size %d.\n", avctx->extradata_size); + return AVERROR(EINVAL); } /* Check the extradata */ @@ -918,9 +865,11 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if (q->coding_mode == STEREO) av_log(avctx, AV_LOG_DEBUG, "Normal stereo detected.\n"); - else if (q->coding_mode == JOINT_STEREO) + else if (q->coding_mode == JOINT_STEREO) { + if (avctx->channels != 2) + return AVERROR_INVALIDDATA; av_log(avctx, AV_LOG_DEBUG, "Joint stereo detected.\n"); - else { + } else { av_log(avctx, AV_LOG_ERROR, "Unknown channel coding mode %x!\n", q->coding_mode); return AVERROR_INVALIDDATA; @@ -929,26 +878,11 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if (avctx->block_align >= UINT_MAX / 2) return AVERROR(EINVAL); - q->decoded_bytes_buffer = av_mallocz(avctx->block_align + - (4 - avctx->block_align % 4) + - FF_INPUT_BUFFER_PADDING_SIZE); - if (q->decoded_bytes_buffer == NULL) + q->decoded_bytes_buffer = av_mallocz(FFALIGN(avctx->block_align, 4) + + AV_INPUT_BUFFER_PADDING_SIZE); + if (!q->decoded_bytes_buffer) return AVERROR(ENOMEM); - - /* Initialize the VLC tables. */ - if (!vlcs_initialized) { - for (i = 0; i < 7; i++) { - spectral_coeff_tab[i].table = &atrac3_vlc_table[atrac3_vlc_offs[i]]; - spectral_coeff_tab[i].table_allocated = atrac3_vlc_offs[i + 1] - - atrac3_vlc_offs[i ]; - init_vlc(&spectral_coeff_tab[i], 9, huff_tab_sizes[i], - huff_bits[i], 1, 1, - huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - vlcs_initialized = 1; - } - avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* initialize the MDCT transform */ @@ -958,16 +892,6 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) return ret; } - init_atrac3_window(); - ff_atrac_generate_tables(); - - /* Generate gain tables */ - for (i = 0; i < 16; i++) - gain_tab1[i] = powf(2.0, (4 - i)); - - for (i = -15; i < 16; i++) - gain_tab2[i + 15] = powf(2.0, i * -0.125); - /* init the joint-stereo decoding data */ q->weighting_delay[0] = 0; q->weighting_delay[1] = 7; @@ -982,31 +906,29 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) q->matrix_coeff_index_next[i] = 3; } - avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); - ff_fmt_convert_init(&q->fmt_conv, avctx); + ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3); + avpriv_float_dsp_init(&q->fdsp, avctx->flags & AV_CODEC_FLAG_BITEXACT); - q->units = av_mallocz(sizeof(ChannelUnit) * avctx->channels); + q->units = av_mallocz(sizeof(*q->units) * avctx->channels); if (!q->units) { atrac3_decode_close(avctx); return AVERROR(ENOMEM); } - avcodec_get_frame_defaults(&q->frame); - avctx->coded_frame = &q->frame; - return 0; } AVCodec ff_atrac3_decoder = { .name = "atrac3", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_ATRAC3, .priv_data_size = sizeof(ATRAC3Context), .init = atrac3_decode_init, + .init_static_data = atrac3_init_static_data, .close = atrac3_decode_close, .decode = atrac3_decode_frame, - .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"), + .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, };