| @@ -49,6 +49,7 @@ version <next>: | |||||
| - RTP depacketization of JPEG | - RTP depacketization of JPEG | ||||
| - Smooth Streaming live segmenter muxer | - Smooth Streaming live segmenter muxer | ||||
| - RTP packetization of JPEG | - RTP packetization of JPEG | ||||
| - Opus decoder using libopus | |||||
| version 0.8: | version 0.8: | ||||
| @@ -181,6 +181,7 @@ External library support: | |||||
| --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no] | --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no] | ||||
| --enable-libopencv enable video filtering via libopencv [no] | --enable-libopencv enable video filtering via libopencv [no] | ||||
| --enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no] | --enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no] | ||||
| --enable-libopus enable Opus decoding via libopus [no] | |||||
| --enable-libpulse enable Pulseaudio input via libpulse [no] | --enable-libpulse enable Pulseaudio input via libpulse [no] | ||||
| --enable-librtmp enable RTMP[E] support via librtmp [no] | --enable-librtmp enable RTMP[E] support via librtmp [no] | ||||
| --enable-libschroedinger enable Dirac de/encoding via libschroedinger [no] | --enable-libschroedinger enable Dirac de/encoding via libschroedinger [no] | ||||
| @@ -1009,6 +1010,7 @@ CONFIG_LIST=" | |||||
| libopencore_amrwb | libopencore_amrwb | ||||
| libopencv | libopencv | ||||
| libopenjpeg | libopenjpeg | ||||
| libopus | |||||
| libpulse | libpulse | ||||
| librtmp | librtmp | ||||
| libschroedinger | libschroedinger | ||||
| @@ -1580,6 +1582,7 @@ libopencore_amrnb_encoder_deps="libopencore_amrnb" | |||||
| libopencore_amrwb_decoder_deps="libopencore_amrwb" | libopencore_amrwb_decoder_deps="libopencore_amrwb" | ||||
| libopenjpeg_decoder_deps="libopenjpeg" | libopenjpeg_decoder_deps="libopenjpeg" | ||||
| libopenjpeg_encoder_deps="libopenjpeg" | libopenjpeg_encoder_deps="libopenjpeg" | ||||
| libopus_decoder_deps="libopus" | |||||
| libschroedinger_decoder_deps="libschroedinger" | libschroedinger_decoder_deps="libschroedinger" | ||||
| libschroedinger_encoder_deps="libschroedinger" | libschroedinger_encoder_deps="libschroedinger" | ||||
| libspeex_decoder_deps="libspeex" | libspeex_decoder_deps="libspeex" | ||||
| @@ -3291,6 +3294,7 @@ enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_de | |||||
| enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb | enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb | ||||
| enabled libopencv && require_pkg_config opencv opencv/cv.h cvCreateImageHeader | enabled libopencv && require_pkg_config opencv opencv/cv.h cvCreateImageHeader | ||||
| enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version -lopenjpeg | enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version -lopenjpeg | ||||
| enabled libopus && require_pkg_config opus opus_multistream.h opus_multistream_decoder_create | |||||
| enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new | enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_new | ||||
| enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket | enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket | ||||
| enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init | enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init | ||||
| @@ -3589,6 +3593,7 @@ echo "libopencore-amrnb support ${libopencore_amrnb-no}" | |||||
| echo "libopencore-amrwb support ${libopencore_amrwb-no}" | echo "libopencore-amrwb support ${libopencore_amrwb-no}" | ||||
| echo "libopencv support ${libopencv-no}" | echo "libopencv support ${libopencv-no}" | ||||
| echo "libopenjpeg enabled ${libopenjpeg-no}" | echo "libopenjpeg enabled ${libopenjpeg-no}" | ||||
| echo "libopus enabled ${libopus-no}" | |||||
| echo "libpulse enabled ${libpulse-no}" | echo "libpulse enabled ${libpulse-no}" | ||||
| echo "librtmp enabled ${librtmp-no}" | echo "librtmp enabled ${librtmp-no}" | ||||
| echo "libschroedinger enabled ${libschroedinger-no}" | echo "libschroedinger enabled ${libschroedinger-no}" | ||||
| @@ -756,6 +756,8 @@ following image formats are supported: | |||||
| @item Musepack SV7 @tab @tab X | @item Musepack SV7 @tab @tab X | ||||
| @item Musepack SV8 @tab @tab X | @item Musepack SV8 @tab @tab X | ||||
| @item Nellymoser Asao @tab X @tab X | @item Nellymoser Asao @tab X @tab X | ||||
| @item Opus @tab @tab E | |||||
| @tab supported through external library libopus | |||||
| @item PCM A-law @tab X @tab X | @item PCM A-law @tab X @tab X | ||||
| @item PCM mu-law @tab X @tab X | @item PCM mu-law @tab X @tab X | ||||
| @item PCM 16-bit little-endian planar @tab @tab X | @item PCM 16-bit little-endian planar @tab @tab X | ||||
| @@ -581,6 +581,7 @@ OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o | |||||
| OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o | OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o | ||||
| OBJS-$(CONFIG_LIBOPENJPEG_DECODER) += libopenjpegdec.o | OBJS-$(CONFIG_LIBOPENJPEG_DECODER) += libopenjpegdec.o | ||||
| OBJS-$(CONFIG_LIBOPENJPEG_ENCODER) += libopenjpegenc.o | OBJS-$(CONFIG_LIBOPENJPEG_ENCODER) += libopenjpegenc.o | ||||
| OBJS-$(CONFIG_LIBOPUS_DECODER) += libopusdec.o vorbis_data.o | |||||
| OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \ | OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \ | ||||
| libschroedinger.o | libschroedinger.o | ||||
| OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ | OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ | ||||
| @@ -393,6 +393,7 @@ void avcodec_register_all(void) | |||||
| REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb); | REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb); | ||||
| REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb); | REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb); | ||||
| REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); | REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); | ||||
| REGISTER_DECODER (LIBOPUS, libopus); | |||||
| REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); | REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); | ||||
| REGISTER_ENCDEC (LIBSPEEX, libspeex); | REGISTER_ENCDEC (LIBSPEEX, libspeex); | ||||
| REGISTER_ENCODER (LIBTHEORA, libtheora); | REGISTER_ENCODER (LIBTHEORA, libtheora); | ||||
| @@ -0,0 +1,202 @@ | |||||
| /* | |||||
| * Opus decoder using libopus | |||||
| * Copyright (c) 2012 Nicolas George | |||||
| * | |||||
| * This file is part of Libav. | |||||
| * | |||||
| * 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. | |||||
| * | |||||
| * 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 Libav; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| #include <opus.h> | |||||
| #include <opus_multistream.h> | |||||
| #include "libavutil/common.h" | |||||
| #include "libavutil/avassert.h" | |||||
| #include "libavutil/intreadwrite.h" | |||||
| #include "avcodec.h" | |||||
| #include "vorbis.h" | |||||
| #include "mathops.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; | |||||
| avc->sample_rate = 48000; | |||||
| avc->sample_fmt = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ? | |||||
| AV_SAMPLE_FMT_FLT : AV_SAMPLE_FMT_S16; | |||||
| avc->channel_layout = avc->channels > 8 ? 0 : | |||||
| ff_vorbis_channel_layouts[avc->channels - 1]; | |||||
| if (avc->extradata_size >= OPUS_HEAD_SIZE) { | |||||
| gain_db = sign_extend(AV_RL16(avc->extradata + 16), 16); | |||||
| channel_map = AV_RL8 (avc->extradata + 18); | |||||
| } | |||||
| if (avc->extradata_size >= OPUS_HEAD_SIZE + 2 + avc->channels) { | |||||
| nb_streams = avc->extradata[OPUS_HEAD_SIZE + 0]; | |||||
| nb_coupled = avc->extradata[OPUS_HEAD_SIZE + 1]; | |||||
| if (nb_streams + nb_coupled != avc->channels) | |||||
| av_log(avc, AV_LOG_WARNING, "Inconsistent channel mapping.\n"); | |||||
| mapping = avc->extradata + OPUS_HEAD_SIZE + 2; | |||||
| } else { | |||||
| if (avc->channels > 2 || channel_map) { | |||||
| av_log(avc, AV_LOG_ERROR, | |||||
| "No channel mapping for %d channels.\n", avc->channels); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| nb_streams = 1; | |||||
| nb_coupled = avc->channels > 1; | |||||
| mapping = mapping_stereo; | |||||
| } | |||||
| opus->dec = opus_multistream_decoder_create(avc->sample_rate, avc->channels, | |||||
| nb_streams, nb_coupled, | |||||
| mapping, &ret); | |||||
| if (!opus->dec) { | |||||
| av_log(avc, AV_LOG_ERROR, "Unable to create decoder: %s\n", | |||||
| opus_strerror(ret)); | |||||
| return opus_error_to_averror(ret); | |||||
| } | |||||
| ret = opus_multistream_decoder_ctl(opus->dec, OPUS_SET_GAIN(gain_db)); | |||||
| if (ret != OPUS_OK) | |||||
| av_log(avc, AV_LOG_WARNING, "Failed to set gain: %s\n", | |||||
| 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; | |||||
| } | |||||
| static av_cold int libopus_decode_close(AVCodecContext *avc) | |||||
| { | |||||
| struct libopus_context *opus = avc->priv_data; | |||||
| opus_multistream_decoder_destroy(opus->dec); | |||||
| return 0; | |||||
| } | |||||
| #define MAX_FRAME_SIZE (960 * 6) | |||||
| static int libopus_decode(AVCodecContext *avc, void *frame, | |||||
| int *got_frame_ptr, AVPacket *pkt) | |||||
| { | |||||
| struct libopus_context *opus = avc->priv_data; | |||||
| int ret, nb_samples; | |||||
| opus->frame.nb_samples = MAX_FRAME_SIZE; | |||||
| ret = avc->get_buffer(avc, &opus->frame); | |||||
| if (ret < 0) { | |||||
| av_log(avc, AV_LOG_ERROR, "get_buffer() failed\n"); | |||||
| return ret; | |||||
| } | |||||
| 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); | |||||
| else | |||||
| nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, | |||||
| (float *)opus->frame.data[0], | |||||
| opus->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); | |||||
| } | |||||
| 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); | |||||
| } | |||||
| opus->frame.nb_samples = nb_samples; | |||||
| *(AVFrame *)frame = opus->frame; | |||||
| *got_frame_ptr = 1; | |||||
| return pkt->size; | |||||
| } | |||||
| static void libopus_flush(AVCodecContext *avc) | |||||
| { | |||||
| struct libopus_context *opus = avc->priv_data; | |||||
| opus_multistream_decoder_ctl(opus->dec, OPUS_RESET_STATE); | |||||
| } | |||||
| AVCodec ff_libopus_decoder = { | |||||
| .name = "libopus", | |||||
| .type = AVMEDIA_TYPE_AUDIO, | |||||
| .id = AV_CODEC_ID_OPUS, | |||||
| .priv_data_size = sizeof(struct libopus_context), | |||||
| .init = libopus_decode_init, | |||||
| .close = libopus_decode_close, | |||||
| .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 }, | |||||
| }; | |||||
| @@ -27,7 +27,7 @@ | |||||
| */ | */ | ||||
| #define LIBAVCODEC_VERSION_MAJOR 54 | #define LIBAVCODEC_VERSION_MAJOR 54 | ||||
| #define LIBAVCODEC_VERSION_MINOR 29 | |||||
| #define LIBAVCODEC_VERSION_MINOR 30 | |||||
| #define LIBAVCODEC_VERSION_MICRO 0 | #define LIBAVCODEC_VERSION_MICRO 0 | ||||
| #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | ||||