X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flibopusdec.c;h=398450f4d45ea5963b5be7c6b79d7ba2ff788be4;hb=452860d7e056f9a894cac2fe52cdedeae4c38251;hp=9d24e6e33b48e3b8cfc9642201f7c104a14958bc;hpb=44617d6ec975b307183d88f0e0b207a9913a8de2;p=ffmpeg diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c index 9d24e6e33b4..398450f4d45 100644 --- a/libavcodec/libopusdec.c +++ b/libavcodec/libopusdec.c @@ -22,62 +22,25 @@ #include #include -#include "libavutil/common.h" #include "libavutil/avassert.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" #include "vorbis.h" #include "mathops.h" +#include "libopus.h" struct libopus_context { OpusMSDecoder *dec; - AVFrame frame; }; -static int opus_error_to_averror(int err) -{ - switch (err) { - case OPUS_BAD_ARG: - return AVERROR(EINVAL); - case OPUS_BUFFER_TOO_SMALL: - return AVERROR_UNKNOWN; - case OPUS_INTERNAL_ERROR: - return AVERROR(EFAULT); - case OPUS_INVALID_PACKET: - return AVERROR_INVALIDDATA; - case OPUS_UNIMPLEMENTED: - return AVERROR(ENOSYS); - case OPUS_INVALID_STATE: - return AVERROR_UNKNOWN; - case OPUS_ALLOC_FAIL: - return AVERROR(ENOMEM); - default: - return AVERROR(EINVAL); - } -} - -static inline void reorder(uint8_t *data, unsigned channels, unsigned bps, - unsigned samples, const uint8_t *map) -{ - uint8_t tmp[8 * 4]; - unsigned i; - - av_assert1(channels * bps <= sizeof(tmp)); - for (; samples > 0; samples--) { - for (i = 0; i < channels; i++) - memcpy(tmp + bps * i, data + bps * map[i], bps); - memcpy(data, tmp, bps * channels); - data += bps * channels; - } -} - #define OPUS_HEAD_SIZE 19 static av_cold int libopus_decode_init(AVCodecContext *avc) { struct libopus_context *opus = avc->priv_data; int ret, channel_map = 0, gain_db = 0, nb_streams, nb_coupled; - uint8_t mapping_stereo[] = { 0, 1 }, *mapping; + uint8_t mapping_arr[8] = { 0, 1 }, *mapping; avc->sample_rate = 48000; avc->sample_fmt = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ? @@ -103,7 +66,17 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) } nb_streams = 1; nb_coupled = avc->channels > 1; - mapping = mapping_stereo; + mapping = mapping_arr; + } + + if (avc->channels > 2 && avc->channels <= 8) { + const uint8_t *vorbis_offset = ff_vorbis_channel_layout_offsets[avc->channels - 1]; + int ch; + + /* Remap channels from vorbis order to libav order */ + for (ch = 0; ch < avc->channels; ch++) + mapping_arr[ch] = mapping[vorbis_offset[ch]]; + mapping = mapping_arr; } opus->dec = opus_multistream_decoder_create(avc->sample_rate, avc->channels, @@ -112,7 +85,7 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) if (!opus->dec) { av_log(avc, AV_LOG_ERROR, "Unable to create decoder: %s\n", opus_strerror(ret)); - return opus_error_to_averror(ret); + return ff_opus_error_to_averror(ret); } ret = opus_multistream_decoder_ctl(opus->dec, OPUS_SET_GAIN(gain_db)); @@ -121,8 +94,7 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) opus_strerror(ret)); avc->delay = 3840; /* Decoder delay (in samples) at 48kHz */ - avcodec_get_frame_defaults(&opus->frame); - avc->coded_frame = &opus->frame; + return 0; } @@ -136,14 +108,15 @@ static av_cold int libopus_decode_close(AVCodecContext *avc) #define MAX_FRAME_SIZE (960 * 6) -static int libopus_decode(AVCodecContext *avc, void *frame, +static int libopus_decode(AVCodecContext *avc, void *data, int *got_frame_ptr, AVPacket *pkt) { struct libopus_context *opus = avc->priv_data; + AVFrame *frame = data; int ret, nb_samples; - opus->frame.nb_samples = MAX_FRAME_SIZE; - ret = avc->get_buffer(avc, &opus->frame); + frame->nb_samples = MAX_FRAME_SIZE; + ret = ff_get_buffer(avc, frame, 0); if (ret < 0) { av_log(avc, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; @@ -151,30 +124,22 @@ static int libopus_decode(AVCodecContext *avc, void *frame, if (avc->sample_fmt == AV_SAMPLE_FMT_S16) nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size, - (opus_int16 *)opus->frame.data[0], - opus->frame.nb_samples, 0); + (opus_int16 *)frame->data[0], + frame->nb_samples, 0); else nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, - (float *)opus->frame.data[0], - opus->frame.nb_samples, 0); + (float *)frame->data[0], + frame->nb_samples, 0); if (nb_samples < 0) { av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n", opus_strerror(nb_samples)); - return opus_error_to_averror(nb_samples); + return ff_opus_error_to_averror(nb_samples); } - if (avc->channels > 3 && avc->channels <= 8) { - const uint8_t *m = ff_vorbis_channel_layout_offsets[avc->channels - 1]; - if (avc->sample_fmt == AV_SAMPLE_FMT_S16) - reorder(opus->frame.data[0], avc->channels, 2, nb_samples, m); - else - reorder(opus->frame.data[0], avc->channels, 4, nb_samples, m); - } + frame->nb_samples = nb_samples; + *got_frame_ptr = 1; - opus->frame.nb_samples = nb_samples; - *(AVFrame *)frame = opus->frame; - *got_frame_ptr = 1; return pkt->size; } @@ -187,6 +152,7 @@ static void libopus_flush(AVCodecContext *avc) AVCodec ff_libopus_decoder = { .name = "libopus", + .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_OPUS, .priv_data_size = sizeof(struct libopus_context), @@ -195,7 +161,6 @@ AVCodec ff_libopus_decoder = { .decode = libopus_decode, .flush = libopus_flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },