X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Famrnbdec.c;h=7692cf01c6f92918625b4c0f9709f726cd924c56;hb=3aca10bf762a94d7de555cedf1ff0e4f6792bf41;hp=cecb4ce9271b1973f72f17b425720e7699ac24db;hpb=ba87f0801d77c21eb1e4891ca1f846500bbb0939;p=ffmpeg diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index cecb4ce9271..7692cf01c6f 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -3,20 +3,20 @@ * Copyright (c) 2006-2007 Robert Swain * Copyright (c) 2009 Colin McQuillan * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav 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, + * Libav 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 + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -43,15 +43,17 @@ #include #include +#include "libavutil/channel_layout.h" +#include "libavutil/float_dsp.h" #include "avcodec.h" -#include "get_bits.h" #include "libavutil/common.h" -#include "celp_math.h" #include "celp_filters.h" #include "acelp_filters.h" #include "acelp_vectors.h" #include "acelp_pitch_delay.h" #include "lsp.h" +#include "amr.h" +#include "internal.h" #include "amrnbdata.h" @@ -82,7 +84,7 @@ /** Maximum sharpening factor * * The specification says 0.8, which should be 13107, but the reference C code - * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in g729dec.c.) + * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in bitexact G.729.) */ #define SHARP_MAX 0.79449462890625 @@ -153,7 +155,15 @@ static av_cold int amrnb_decode_init(AVCodecContext *avctx) AMRContext *p = avctx->priv_data; int i; - avctx->sample_fmt = SAMPLE_FMT_FLT; + if (avctx->channels > 1) { + avpriv_report_missing_feature(avctx, "multi-channel AMR"); + return AVERROR_PATCHWELCOME; + } + + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_rate = 8000; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; // p->excitation always points to the same position in p->excitation_buf p->excitation = &p->excitation_buf[PITCH_DELAY_MAX + LP_FILTER_ORDER + 1]; @@ -184,57 +194,27 @@ static av_cold int amrnb_decode_init(AVCodecContext *avctx) static enum Mode unpack_bitstream(AMRContext *p, const uint8_t *buf, int buf_size) { - GetBitContext gb; enum Mode mode; - init_get_bits(&gb, buf, buf_size * 8); - // Decode the first octet. - skip_bits(&gb, 1); // padding bit - mode = get_bits(&gb, 4); // frame type - p->bad_frame_indicator = !get_bits1(&gb); // quality bit - skip_bits(&gb, 2); // two padding bits - - if (mode <= MODE_DTX) { - uint16_t *data = (uint16_t *)&p->frame; - const uint8_t *order = amr_unpacking_bitmaps_per_mode[mode]; - int field_size; - - memset(&p->frame, 0, sizeof(AMRNBFrame)); - buf++; - while ((field_size = *order++)) { - int field = 0; - int field_offset = *order++; - while (field_size--) { - int bit = *order++; - field <<= 1; - field |= buf[bit >> 3] >> (bit & 7) & 1; - } - data[field_offset] = field; - } + mode = buf[0] >> 3 & 0x0F; // frame type + p->bad_frame_indicator = (buf[0] & 0x4) != 0x4; // quality bit + + if (mode >= N_MODES || buf_size < frame_sizes_nb[mode] + 1) { + return NO_DATA; } + if (mode < MODE_DTX) + ff_amr_bit_reorder((uint16_t *) &p->frame, sizeof(AMRNBFrame), buf + 1, + amr_unpacking_bitmaps_per_mode[mode]); + return mode; } -/// @defgroup amr_lpc_decoding AMR pitch LPC coefficient decoding functions +/// @name AMR pitch LPC coefficient decoding functions /// @{ -/** - * Convert an lsf vector into an lsp vector. - * - * @param lsf input lsf vector - * @param lsp output lsp vector - */ -static void lsf2lsp(const float *lsf, double *lsp) -{ - int i; - - for (i = 0; i < LP_FILTER_ORDER; i++) - lsp[i] = cos(2.0 * M_PI * lsf[i]); -} - /** * Interpolate the LSF vector (used for fixed gain smoothing). * The interpolation is done over all four subframes even in MODE_12k2. @@ -283,7 +263,7 @@ static void lsf2lsp_for_mode12k2(AMRContext *p, double lsp[LP_FILTER_ORDER], } if (update) - memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(float)); + memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(*lsf_r)); for (i = 0; i < LP_FILTER_ORDER; i++) lsf_q[i] = lsf_r[i] * (LSF_R_FAC / 8000.0) + lsf_no_r[i] * (1.0 / 8000.0); @@ -293,7 +273,7 @@ static void lsf2lsp_for_mode12k2(AMRContext *p, double lsp[LP_FILTER_ORDER], if (update) interpolate_lsf(p->lsf_q, lsf_q); - lsf2lsp(lsf_q, lsp); + ff_acelp_lsf2lspd(lsp, lsf_q, LP_FILTER_ORDER); } /** @@ -357,7 +337,7 @@ static void lsf2lsp_3(AMRContext *p) interpolate_lsf(p->lsf_q, lsf_q); memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(*lsf_r)); - lsf2lsp(lsf_q, p->lsp[3]); + ff_acelp_lsf2lspd(p->lsp[3], lsf_q, LP_FILTER_ORDER); // interpolate LSP vectors at subframes 1, 2 and 3 for (i = 1; i <= 3; i++) @@ -369,7 +349,7 @@ static void lsf2lsp_3(AMRContext *p) /// @} -/// @defgroup amr_pitch_vector_decoding AMR pitch vector decoding functions +/// @name AMR pitch vector decoding functions /// @{ /** @@ -431,7 +411,7 @@ static void decode_pitch_vector(AMRContext *p, /// @} -/// @defgroup amr_algebraic_code_book AMR algebraic code book (fixed) vector decoding functions +/// @name AMR algebraic code book (fixed) vector decoding functions /// @{ /** @@ -575,7 +555,7 @@ static void pitch_sharpening(AMRContext *p, int subframe, enum Mode mode, /// @} -/// @defgroup amr_gain_decoding AMR gain decoding functions +/// @name AMR gain decoding functions /// @{ /** @@ -661,7 +641,7 @@ static void decode_gains(AMRContext *p, const AMRNBSubframe *amr_subframe, /// @} -/// @defgroup amr_pre_processing AMR pre-processing functions +/// @name AMR preprocessing functions /// @{ /** @@ -677,7 +657,7 @@ static void decode_gains(AMRContext *p, const AMRNBSubframe *amr_subframe, static void apply_ir_filter(float *out, const AMRFixed *in, const float *filter) { - float filter1[AMR_SUBFRAME_SIZE], //!< filters at pitch lag*1 and *2 + float filter1[AMR_SUBFRAME_SIZE], ///< filters at pitch lag*1 and *2 filter2[AMR_SUBFRAME_SIZE]; int lag = in->pitch_lag; float fac = in->pitch_fac; @@ -779,7 +759,7 @@ static const float *anti_sparseness(AMRContext *p, AMRFixed *fixed_sparse, /// @} -/// @defgroup amr_synthesis AMR synthesis functions +/// @name AMR synthesis functions /// @{ /** @@ -796,7 +776,7 @@ static int synthesis(AMRContext *p, float *lpc, float fixed_gain, const float *fixed_vector, float *samples, uint8_t overflow) { - int i, overflow_temp = 0; + int i; float excitation[AMR_SUBFRAME_SIZE]; // if an overflow has been detected, the pitch vector is scaled down by a @@ -810,8 +790,8 @@ static int synthesis(AMRContext *p, float *lpc, // emphasize pitch vector contribution if (p->pitch_gain[4] > 0.5 && !overflow) { - float energy = ff_dot_productf(excitation, excitation, - AMR_SUBFRAME_SIZE); + float energy = avpriv_scalarproduct_float_c(excitation, excitation, + AMR_SUBFRAME_SIZE); float pitch_factor = p->pitch_gain[4] * (p->cur_frame_mode == MODE_12k2 ? @@ -831,18 +811,16 @@ static int synthesis(AMRContext *p, float *lpc, // detect overflow for (i = 0; i < AMR_SUBFRAME_SIZE; i++) if (fabsf(samples[i]) > AMR_SAMPLE_BOUND) { - overflow_temp = 1; - samples[i] = av_clipf(samples[i], -AMR_SAMPLE_BOUND, - AMR_SAMPLE_BOUND); + return 1; } - return overflow_temp; + return 0; } /// @} -/// @defgroup amr_update AMR update functions +/// @name AMR update functions /// @{ /** @@ -867,7 +845,7 @@ static void update_state(AMRContext *p) /// @} -/// @defgroup amr_postproc AMR Post processing functions +/// @name AMR Postprocessing functions /// @{ /** @@ -889,8 +867,8 @@ static float tilt_factor(float *lpc_n, float *lpc_d) ff_celp_lp_synthesis_filterf(hf, lpc_d, hf, AMR_TILT_RESPONSE, LP_FILTER_ORDER); - rh0 = ff_dot_productf(hf, hf, AMR_TILT_RESPONSE); - rh1 = ff_dot_productf(hf, hf + 1, AMR_TILT_RESPONSE - 1); + rh0 = avpriv_scalarproduct_float_c(hf, hf, AMR_TILT_RESPONSE); + rh1 = avpriv_scalarproduct_float_c(hf, hf + 1, AMR_TILT_RESPONSE - 1); // The spec only specifies this check for 12.2 and 10.2 kbit/s // modes. But in the ref source the tilt is always non-negative. @@ -910,8 +888,8 @@ static void postfilter(AMRContext *p, float *lpc, float *buf_out) int i; float *samples = p->samples_in + LP_FILTER_ORDER; // Start of input - float speech_gain = ff_dot_productf(samples, samples, - AMR_SUBFRAME_SIZE); + float speech_gain = avpriv_scalarproduct_float_c(samples, samples, + AMR_SUBFRAME_SIZE); float pole_out[AMR_SUBFRAME_SIZE + LP_FILTER_ORDER]; // Output of pole filter const float *gamma_n, *gamma_d; // Formant filter factor table @@ -943,31 +921,44 @@ static void postfilter(AMRContext *p, float *lpc, float *buf_out) ff_tilt_compensation(&p->tilt_mem, tilt_factor(lpc_n, lpc_d), buf_out, AMR_SUBFRAME_SIZE); - ff_adaptive_gain_control(buf_out, speech_gain, AMR_SUBFRAME_SIZE, + ff_adaptive_gain_control(buf_out, buf_out, speech_gain, AMR_SUBFRAME_SIZE, AMR_AGC_ALPHA, &p->postfilter_agc); } /// @} -static int amrnb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) +static int amrnb_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) { AMRContext *p = avctx->priv_data; // pointer to private data + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - float *buf_out = data; // pointer to the output data buffer - int i, subframe; + float *buf_out; // pointer to the output data buffer + int i, subframe, ret; float fixed_gain_factor; AMRFixed fixed_sparse = {0}; // fixed vector up to anti-sparseness processing float spare_vector[AMR_SUBFRAME_SIZE]; // extra stack space to hold result from anti-sparseness processing float synth_fixed_gain; // the fixed gain that synthesis should use const float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use + /* get output buffer */ + frame->nb_samples = AMR_BLOCK_SIZE; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + buf_out = (float *)frame->data[0]; + p->cur_frame_mode = unpack_bitstream(p, buf, buf_size); + if (p->cur_frame_mode == NO_DATA) { + av_log(avctx, AV_LOG_ERROR, "Corrupt bitstream\n"); + return AVERROR_INVALIDDATA; + } if (p->cur_frame_mode == MODE_DTX) { - av_log_missing_feature(avctx, "dtx mode", 1); - return -1; + avpriv_request_sample(avctx, "dtx mode"); + return AVERROR_PATCHWELCOME; } if (p->cur_frame_mode == MODE_12k2) { @@ -995,13 +986,19 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, pitch_sharpening(p, subframe, p->cur_frame_mode, &fixed_sparse); + if (fixed_sparse.pitch_lag == 0) { + av_log(avctx, AV_LOG_ERROR, "The file is corrupted, pitch_lag = 0 is not allowed\n"); + return AVERROR_INVALIDDATA; + } ff_set_fixed_vector(p->fixed_vector, &fixed_sparse, 1.0, AMR_SUBFRAME_SIZE); p->fixed_gain[4] = ff_amr_set_fixed_gain(fixed_gain_factor, - ff_dot_productf(p->fixed_vector, p->fixed_vector, - AMR_SUBFRAME_SIZE)/AMR_SUBFRAME_SIZE, + avpriv_scalarproduct_float_c(p->fixed_vector, + p->fixed_vector, + AMR_SUBFRAME_SIZE) / + AMR_SUBFRAME_SIZE, p->prediction_error, energy_mean[p->cur_frame_mode], energy_pred_fac); @@ -1044,14 +1041,11 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, update_state(p); } - ff_acelp_apply_order_2_transfer_function(buf_out, highpass_zeros, - highpass_poles, highpass_gain, + ff_acelp_apply_order_2_transfer_function(buf_out, buf_out, highpass_zeros, + highpass_poles, + highpass_gain * AMR_SAMPLE_SCALE, p->high_pass_mem, AMR_BLOCK_SIZE); - for (i = 0; i < AMR_BLOCK_SIZE; i++) - buf_out[i] = av_clipf(buf_out[i] * AMR_SAMPLE_SCALE, - -1.0, 32767.0 / 32768.0); - /* Update averaged lsf vector (used for fixed gain smoothing). * * Note that lsf_avg should not incorporate the current frame's LSFs @@ -1061,21 +1055,22 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, ff_weighted_vector_sumf(p->lsf_avg, p->lsf_avg, p->lsf_q[3], 0.84, 0.16, LP_FILTER_ORDER); - /* report how many samples we got */ - *data_size = AMR_BLOCK_SIZE * sizeof(float); + *got_frame_ptr = 1; /* return the amount of bytes consumed if everything was OK */ return frame_sizes_nb[p->cur_frame_mode] + 1; // +7 for rounding and +8 for TOC } -AVCodec amrnb_decoder = { +AVCodec ff_amrnb_decoder = { .name = "amrnb", + .long_name = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"), .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_AMR_NB, + .id = AV_CODEC_ID_AMR_NB, .priv_data_size = sizeof(AMRContext), .init = amrnb_decode_init, .decode = amrnb_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Adaptive Multi-Rate NarrowBand"), - .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_FLT,SAMPLE_FMT_NONE}, + .capabilities = CODEC_CAP_DR1, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, + AV_SAMPLE_FMT_NONE }, };