X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Famrnbdec.c;h=fcaaab386fa32547363230b2a84fbb9e3e338390;hb=6fee1b90ce3bf4fbdfde7016e0890057c9000487;hp=926014f83c019357a33daf0e6fd6079c7e67ac38;hpb=c68fafe0d2bdf3d4943a3602c52b0a7c83be8171;p=ffmpeg diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index 926014f83c0..fcaaab386fa 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -43,16 +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" @@ -95,7 +96,6 @@ #define AMR_AGC_ALPHA 0.9 typedef struct AMRContext { - AVFrame avframe; ///< AVFrame for decoded samples AMRNBFrame frame; ///< decoded AMR parameters (lsf coefficients, codebook indexes, etc) uint8_t bad_frame_indicator; ///< bad frame ? 1 : 0 enum Mode cur_frame_mode; @@ -155,7 +155,15 @@ static av_cold int amrnb_decode_init(AVCodecContext *avctx) AMRContext *p = avctx->priv_data; int i; - avctx->sample_fmt = AV_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]; @@ -168,9 +176,6 @@ static av_cold int amrnb_decode_init(AVCodecContext *avctx) for (i = 0; i < 4; i++) p->prediction_error[i] = MIN_ENERGY; - avcodec_get_frame_defaults(&p->avframe); - avctx->coded_frame = &p->avframe; - return 0; } @@ -189,16 +194,15 @@ 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 + 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, @@ -786,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 ? @@ -863,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. @@ -884,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 @@ -928,6 +932,7 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, { 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; // pointer to the output data buffer @@ -939,17 +944,21 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, const float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use /* get output buffer */ - p->avframe.nb_samples = AMR_BLOCK_SIZE; - if ((ret = avctx->get_buffer(avctx, &p->avframe)) < 0) { + 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 *)p->avframe.data[0]; + 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) { @@ -977,13 +986,19 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, 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); @@ -1040,8 +1055,7 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, ff_weighted_vector_sumf(p->lsf_avg, p->lsf_avg, p->lsf_q[3], 0.84, 0.16, LP_FILTER_ORDER); - *got_frame_ptr = 1; - *(AVFrame *)data = p->avframe; + *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 @@ -1051,11 +1065,12 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, AVCodec ff_amrnb_decoder = { .name = "amrnb", .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, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Adaptive Multi-Rate NarrowBand"), - .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"), + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, + AV_SAMPLE_FMT_NONE }, };