diff options
Diffstat (limited to 'libavcodec/opusdec.c')
-rw-r--r-- | libavcodec/opusdec.c | 91 |
1 files changed, 49 insertions, 42 deletions
diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c index 771922e973..2ee3f2ad36 100644 --- a/libavcodec/opusdec.c +++ b/libavcodec/opusdec.c @@ -3,20 +3,20 @@ * Copyright (c) 2012 Andrew D'Addesio * Copyright (c) 2013-2014 Mozilla Corporation * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -40,11 +40,9 @@ #include "libavutil/channel_layout.h" #include "libavutil/opt.h" -#include "libavresample/avresample.h" +#include "libswresample/swresample.h" #include "avcodec.h" -#include "celp_filters.h" -#include "fft.h" #include "get_bits.h" #include "internal.h" #include "mathops.h" @@ -114,9 +112,9 @@ static int opus_flush_resample(OpusStreamContext *s, int nb_samples) { int celt_size = av_audio_fifo_size(s->celt_delay); int ret, i; - - ret = avresample_convert(s->avr, (uint8_t**)s->out, s->out_size, nb_samples, - NULL, 0, 0); + ret = swr_convert(s->swr, + (uint8_t**)s->out, nb_samples, + NULL, 0); if (ret < 0) return ret; else if (ret != nb_samples) { @@ -155,19 +153,20 @@ static int opus_flush_resample(OpusStreamContext *s, int nb_samples) static int opus_init_resample(OpusStreamContext *s) { - float delay[16] = { 0.0 }; - uint8_t *delayptr[2] = { (uint8_t*)delay, (uint8_t*)delay }; + static const float delay[16] = { 0.0 }; + const uint8_t *delayptr[2] = { (uint8_t*)delay, (uint8_t*)delay }; int ret; - av_opt_set_int(s->avr, "in_sample_rate", s->silk_samplerate, 0); - ret = avresample_open(s->avr); + av_opt_set_int(s->swr, "in_sample_rate", s->silk_samplerate, 0); + ret = swr_init(s->swr); if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error opening the resampler.\n"); return ret; } - ret = avresample_convert(s->avr, NULL, 0, 0, delayptr, sizeof(delay), - silk_resample_delay[s->packet.bandwidth]); + ret = swr_convert(s->swr, + NULL, 0, + delayptr, silk_resample_delay[s->packet.bandwidth]); if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error feeding initial silence to the resampler.\n"); @@ -218,7 +217,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size /* decode the silk frame */ if (s->packet.mode == OPUS_MODE_SILK || s->packet.mode == OPUS_MODE_HYBRID) { - if (!avresample_is_open(s->avr)) { + if (!swr_is_initialized(s->swr)) { ret = opus_init_resample(s); if (ret < 0) return ret; @@ -232,16 +231,14 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size av_log(s->avctx, AV_LOG_ERROR, "Error decoding a SILK frame.\n"); return samples; } - - samples = avresample_convert(s->avr, (uint8_t**)s->out, s->out_size, - s->packet.frame_duration, - (uint8_t**)s->silk_output, - sizeof(s->silk_buf[0]), - samples); + samples = swr_convert(s->swr, + (uint8_t**)s->out, s->packet.frame_duration, + (const uint8_t**)s->silk_output, samples); if (samples < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error resampling SILK data.\n"); return samples; } + av_assert2((samples & 7) == 0); s->delayed_samples += s->packet.frame_duration - samples; } else ff_silk_flush(s->silk); @@ -374,10 +371,10 @@ static int opus_decode_subpacket(OpusStreamContext *s, int i, j, ret; /* check if we need to flush the resampler */ - if (avresample_is_open(s->avr)) { + if (swr_is_initialized(s->swr)) { if (buf) { int64_t cur_samplerate; - av_opt_get_int(s->avr, "in_sample_rate", 0, &cur_samplerate); + av_opt_get_int(s->swr, "in_sample_rate", 0, &cur_samplerate); flush_needed = (s->packet.mode == OPUS_MODE_CELT) || (cur_samplerate != s->silk_samplerate); } else { flush_needed = !!s->delayed_samples; @@ -406,7 +403,7 @@ static int opus_decode_subpacket(OpusStreamContext *s, av_log(s->avctx, AV_LOG_ERROR, "Error flushing the resampler.\n"); return ret; } - avresample_close(s->avr); + swr_close(s->swr); output_samples += s->delayed_samples; s->delayed_samples = 0; @@ -452,6 +449,14 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, int coded_samples = 0; int decoded_samples = 0; int i, ret; + int delayed_samples = 0; + + for (i = 0; i < c->nb_streams; i++) { + OpusStreamContext *s = &c->streams[i]; + s->out[0] = + s->out[1] = NULL; + delayed_samples = FFMAX(delayed_samples, s->delayed_samples); + } /* decode the header of the first sub-packet to find out the sample count */ if (buf) { @@ -465,7 +470,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, c->streams[0].silk_samplerate = get_silk_samplerate(pkt->config); } - frame->nb_samples = coded_samples + c->streams[0].delayed_samples; + frame->nb_samples = coded_samples + delayed_samples; /* no input or buffered data => nothing to do */ if (!frame->nb_samples) { @@ -475,10 +480,8 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, /* setup the data buffers */ ret = ff_get_buffer(avctx, frame, 0); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + if (ret < 0) return ret; - } frame->nb_samples = 0; for (i = 0; i < avctx->channels; i++) { @@ -536,7 +539,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, } if (c->gain_i) { - c->fdsp.vector_fmul_scalar((float*)frame->extended_data[i], + c->fdsp->vector_fmul_scalar((float*)frame->extended_data[i], (float*)frame->extended_data[i], c->gain, FFALIGN(decoded_samples, 8)); } @@ -561,7 +564,7 @@ static av_cold void opus_decode_flush(AVCodecContext *ctx) if (s->celt_delay) av_audio_fifo_drain(s->celt_delay, av_audio_fifo_size(s->celt_delay)); - avresample_close(s->avr); + swr_close(s->swr); ff_silk_flush(s->silk); ff_celt_flush(s->celt); @@ -583,13 +586,14 @@ static av_cold int opus_decode_close(AVCodecContext *avctx) s->out_dummy_allocated_size = 0; av_audio_fifo_free(s->celt_delay); - avresample_free(&s->avr); + swr_free(&s->swr); } av_freep(&c->streams); c->nb_streams = 0; av_freep(&c->channel_maps); + av_freep(&c->fdsp); return 0; } @@ -602,7 +606,9 @@ static av_cold int opus_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; avctx->sample_rate = 48000; - avpriv_float_dsp_init(&c->fdsp, 0); + c->fdsp = avpriv_float_dsp_alloc(0); + if (!c->fdsp) + return AVERROR(ENOMEM); /* find out the channel configuration */ ret = ff_opus_parse_extradata(avctx, c); @@ -631,18 +637,19 @@ static av_cold int opus_decode_init(AVCodecContext *avctx) s->redundancy_output[j] = s->redundancy_buf[j]; } - s->fdsp = &c->fdsp; + s->fdsp = c->fdsp; - s->avr = avresample_alloc_context(); - if (!s->avr) + s->swr =swr_alloc(); + if (!s->swr) goto fail; layout = (s->output_channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; - av_opt_set_int(s->avr, "in_sample_fmt", avctx->sample_fmt, 0); - av_opt_set_int(s->avr, "out_sample_fmt", avctx->sample_fmt, 0); - av_opt_set_int(s->avr, "in_channel_layout", layout, 0); - av_opt_set_int(s->avr, "out_channel_layout", layout, 0); - av_opt_set_int(s->avr, "out_sample_rate", avctx->sample_rate, 0); + av_opt_set_int(s->swr, "in_sample_fmt", avctx->sample_fmt, 0); + av_opt_set_int(s->swr, "out_sample_fmt", avctx->sample_fmt, 0); + av_opt_set_int(s->swr, "in_channel_layout", layout, 0); + av_opt_set_int(s->swr, "out_channel_layout", layout, 0); + av_opt_set_int(s->swr, "out_sample_rate", avctx->sample_rate, 0); + av_opt_set_int(s->swr, "filter_size", 16, 0); ret = ff_silk_init(avctx, &s->silk, s->output_channels); if (ret < 0) |