X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Famrwbdec.c;h=668c84d1f38b93455e5281d9ff69be35a390931a;hb=436ced244fadcde2c0b925627920e84b25482542;hp=8bbc31c9bd2ce48379af545dba203bedc764ed0e;hpb=b70feb405386cda5ea7a7d2a9921a7f2f17976a4;p=ffmpeg diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 8bbc31c9bd2..668c84d1f38 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -24,15 +24,18 @@ * AMR wideband decoder */ +#include "libavutil/channel_layout.h" +#include "libavutil/common.h" +#include "libavutil/float_dsp.h" #include "libavutil/lfg.h" #include "avcodec.h" #include "lsp.h" -#include "celp_math.h" #include "celp_filters.h" #include "acelp_filters.h" #include "acelp_vectors.h" #include "acelp_pitch_delay.h" +#include "internal.h" #define AMR_USE_16BIT_TABLES #include "amr.h" @@ -40,7 +43,6 @@ #include "amrwbdata.h" typedef struct { - AVFrame avframe; ///< AVFrame for decoded samples AMRWBFrame frame; ///< AMRWB parameters decoded from bitstream enum Mode fr_cur_mode; ///< mode index of current frame uint8_t fr_quality; ///< frame quality index (FQI) @@ -89,7 +91,15 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx) AMRWBContext *ctx = 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 = 16000; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; av_lfg_init(&ctx->prng, 1); @@ -102,9 +112,6 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx) for (i = 0; i < 4; i++) ctx->prediction_error[i] = MIN_ENERGY; - avcodec_get_frame_defaults(&ctx->avframe); - avctx->coded_frame = &ctx->avframe; - return 0; } @@ -121,7 +128,7 @@ static int decode_mime_header(AMRWBContext *ctx, const uint8_t *buf) { /* Decode frame header (1st octet) */ ctx->fr_cur_mode = buf[0] >> 3 & 0x0F; - ctx->fr_quality = (buf[0] & 0x4) != 0x4; + ctx->fr_quality = (buf[0] & 0x4) == 0x4; return 1; } @@ -584,10 +591,12 @@ static void pitch_sharpening(AMRWBContext *ctx, float *fixed_vector) static float voice_factor(float *p_vector, float p_gain, float *f_vector, float f_gain) { - double p_ener = (double) ff_dot_productf(p_vector, p_vector, - AMRWB_SFR_SIZE) * p_gain * p_gain; - double f_ener = (double) ff_dot_productf(f_vector, f_vector, - AMRWB_SFR_SIZE) * f_gain * f_gain; + double p_ener = (double) avpriv_scalarproduct_float_c(p_vector, p_vector, + AMRWB_SFR_SIZE) * + p_gain * p_gain; + double f_ener = (double) avpriv_scalarproduct_float_c(f_vector, f_vector, + AMRWB_SFR_SIZE) * + f_gain * f_gain; return (p_ener - f_ener) / (p_ener + f_ener); } @@ -755,8 +764,8 @@ static void synthesis(AMRWBContext *ctx, float *lpc, float *excitation, /* emphasize pitch vector contribution in low bitrate modes */ if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) { int i; - float energy = ff_dot_productf(excitation, excitation, - AMRWB_SFR_SIZE); + float energy = avpriv_scalarproduct_float_c(excitation, excitation, + AMRWB_SFR_SIZE); // XXX: Weird part in both ref code and spec. A unknown parameter // {beta} seems to be identical to the current pitch gain @@ -815,8 +824,9 @@ static void upsample_5_4(float *out, const float *in, int o_size) i++; for (k = 1; k < 5; k++) { - out[i] = ff_dot_productf(in0 + int_part, upsample_fir[4 - frac_part], - UPS_MEM_SIZE); + out[i] = avpriv_scalarproduct_float_c(in0 + int_part, + upsample_fir[4 - frac_part], + UPS_MEM_SIZE); int_part++; frac_part--; i++; @@ -842,8 +852,8 @@ static float find_hb_gain(AMRWBContext *ctx, const float *synth, if (ctx->fr_cur_mode == MODE_23k85) return qua_hb_gain[hb_idx] * (1.0f / (1 << 14)); - tilt = ff_dot_productf(synth, synth + 1, AMRWB_SFR_SIZE - 1) / - ff_dot_productf(synth, synth, AMRWB_SFR_SIZE); + tilt = avpriv_scalarproduct_float_c(synth, synth + 1, AMRWB_SFR_SIZE - 1) / + avpriv_scalarproduct_float_c(synth, synth, AMRWB_SFR_SIZE); /* return gain bounded by [0.1, 1.0] */ return av_clipf((1.0 - FFMAX(0.0, tilt)) * (1.25 - 0.25 * wsp), 0.1, 1.0); @@ -862,7 +872,8 @@ static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc, const float *synth_exc, float hb_gain) { int i; - float energy = ff_dot_productf(synth_exc, synth_exc, AMRWB_SFR_SIZE); + float energy = avpriv_scalarproduct_float_c(synth_exc, synth_exc, + AMRWB_SFR_SIZE); /* Generate a white-noise excitation */ for (i = 0; i < AMRWB_SFR_SIZE_16k; i++) @@ -898,10 +909,9 @@ static float auto_correlation(float *diff_isf, float mean, int lag) static void extrapolate_isf(float isf[LP_ORDER_16k]) { float diff_isf[LP_ORDER - 2], diff_mean; - float *diff_hi = diff_isf - LP_ORDER + 1; // diff array for extrapolated indexes float corr_lag[3]; float est, scale; - int i, i_max_corr; + int i, j, i_max_corr; isf[LP_ORDER_16k - 1] = isf[LP_ORDER - 1]; @@ -932,20 +942,20 @@ static void extrapolate_isf(float isf[LP_ORDER_16k]) scale = 0.5 * (FFMIN(est, 7600) - isf[LP_ORDER - 2]) / (isf[LP_ORDER_16k - 2] - isf[LP_ORDER - 2]); - for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++) - diff_hi[i] = scale * (isf[i] - isf[i - 1]); + for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++) + diff_isf[j] = scale * (isf[i] - isf[i - 1]); /* Stability insurance */ - for (i = LP_ORDER; i < LP_ORDER_16k - 1; i++) - if (diff_hi[i] + diff_hi[i - 1] < 5.0) { - if (diff_hi[i] > diff_hi[i - 1]) { - diff_hi[i - 1] = 5.0 - diff_hi[i]; + for (i = 1; i < LP_ORDER_16k - LP_ORDER; i++) + if (diff_isf[i] + diff_isf[i - 1] < 5.0) { + if (diff_isf[i] > diff_isf[i - 1]) { + diff_isf[i - 1] = 5.0 - diff_isf[i]; } else - diff_hi[i] = 5.0 - diff_hi[i - 1]; + diff_isf[i] = 5.0 - diff_isf[i - 1]; } - for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++) - isf[i] = isf[i - 1] + diff_hi[i] * (1.0f / (1 << 15)); + for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++) + isf[i] = isf[i - 1] + diff_isf[j] * (1.0f / (1 << 15)); /* Scale the ISF vector for 16000 Hz */ for (i = 0; i < LP_ORDER_16k - 1; i++) @@ -1063,6 +1073,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AMRWBContext *ctx = avctx->priv_data; + AVFrame *frame = data; AMRWBFrame *cf = &ctx->frame; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; @@ -1080,12 +1091,12 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int sub, i, ret; /* get output buffer */ - ctx->avframe.nb_samples = 4 * AMRWB_SFR_SIZE_16k; - if ((ret = avctx->get_buffer(avctx, &ctx->avframe)) < 0) { + frame->nb_samples = 4 * AMRWB_SFR_SIZE_16k; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - buf_out = (float *)ctx->avframe.data[0]; + buf_out = (float *)frame->data[0]; header_size = decode_mime_header(ctx, buf); if (ctx->fr_cur_mode > MODE_SID) { @@ -1106,8 +1117,8 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n"); if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */ - av_log_missing_feature(avctx, "SID mode", 1); - return -1; + avpriv_request_sample(avctx, "SID mode"); + return AVERROR_PATCHWELCOME; } ff_amr_bit_reorder((uint16_t *) &ctx->frame, sizeof(AMRWBFrame), @@ -1155,8 +1166,10 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, ctx->fixed_gain[0] = ff_amr_set_fixed_gain(fixed_gain_factor, - ff_dot_productf(ctx->fixed_vector, ctx->fixed_vector, - AMRWB_SFR_SIZE) / AMRWB_SFR_SIZE, + avpriv_scalarproduct_float_c(ctx->fixed_vector, + ctx->fixed_vector, + AMRWB_SFR_SIZE) / + AMRWB_SFR_SIZE, ctx->prediction_error, ENERGY_MEAN, energy_pred_fac); @@ -1228,20 +1241,20 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0])); memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float)); - *got_frame_ptr = 1; - *(AVFrame *)data = ctx->avframe; + *got_frame_ptr = 1; return expected_fr_size; } AVCodec ff_amrwb_decoder = { .name = "amrwb", + .long_name = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"), .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_AMR_WB, + .id = AV_CODEC_ID_AMR_WB, .priv_data_size = sizeof(AMRWBContext), .init = amrwb_decode_init, .decode = amrwb_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Adaptive Multi-Rate WideBand"), - .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE}, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, + AV_SAMPLE_FMT_NONE }, };