Signed-off-by: Paul B Mahol <onemda@gmail.com>tags/n2.0
| @@ -218,6 +218,7 @@ External library support: | |||||
| --enable-libquvi enable quvi input via libquvi [no] | --enable-libquvi enable quvi input via libquvi [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] | ||||
| --enable-libshine enable fixed-point MP3 encoding via libshine [no] | |||||
| --enable-libsoxr enable Include libsoxr resampling [no] | --enable-libsoxr enable Include libsoxr resampling [no] | ||||
| --enable-libspeex enable Speex de/encoding via libspeex [no] | --enable-libspeex enable Speex de/encoding via libspeex [no] | ||||
| --enable-libstagefright-h264 enable H.264 decoding via libstagefright [no] | --enable-libstagefright-h264 enable H.264 decoding via libstagefright [no] | ||||
| @@ -1172,6 +1173,7 @@ EXTERNAL_LIBRARY_LIST=" | |||||
| libquvi | libquvi | ||||
| librtmp | librtmp | ||||
| libschroedinger | libschroedinger | ||||
| libshine | |||||
| libsoxr | libsoxr | ||||
| libspeex | libspeex | ||||
| libstagefright_h264 | libstagefright_h264 | ||||
| @@ -1976,6 +1978,8 @@ libopus_encoder_select="audio_frame_queue" | |||||
| libquvi_demuxer_deps="libquvi" | libquvi_demuxer_deps="libquvi" | ||||
| libschroedinger_decoder_deps="libschroedinger" | libschroedinger_decoder_deps="libschroedinger" | ||||
| libschroedinger_encoder_deps="libschroedinger" | libschroedinger_encoder_deps="libschroedinger" | ||||
| libshine_encoder_deps="libshine" | |||||
| libshine_encoder_select="audio_frame_queue" | |||||
| libspeex_decoder_deps="libspeex" | libspeex_decoder_deps="libspeex" | ||||
| libspeex_encoder_deps="libspeex" | libspeex_encoder_deps="libspeex" | ||||
| libspeex_encoder_select="audio_frame_queue" | libspeex_encoder_select="audio_frame_queue" | ||||
| @@ -3997,6 +4001,7 @@ enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_ | |||||
| enabled libquvi && require_pkg_config libquvi quvi/quvi.h quvi_init | enabled libquvi && require_pkg_config libquvi quvi/quvi.h quvi_init | ||||
| 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 | ||||
| enabled libshine && require_pkg_config shine shine/layer3.h shine_encode_frame | |||||
| enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr | enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr | ||||
| enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex | enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex | ||||
| enabled libstagefright_h264 && require_cpp libstagefright_h264 "binder/ProcessState.h media/stagefright/MetaData.h | enabled libstagefright_h264 && require_cpp libstagefright_h264 "binder/ProcessState.h media/stagefright/MetaData.h | ||||
| @@ -4398,6 +4403,7 @@ echo "threading support ${thread_type-no}" | |||||
| echo "safe bitstream reader ${safe_bitstream_reader-no}" | echo "safe bitstream reader ${safe_bitstream_reader-no}" | ||||
| echo "SDL support ${sdl-no}" | echo "SDL support ${sdl-no}" | ||||
| echo "opencl enabled ${opencl-no}" | echo "opencl enabled ${opencl-no}" | ||||
| echo "libshine enabled ${libshine-no}" | |||||
| echo "texi2html enabled ${texi2html-no}" | echo "texi2html enabled ${texi2html-no}" | ||||
| echo "perl enabled ${perl-no}" | echo "perl enabled ${perl-no}" | ||||
| echo "pod2man enabled ${pod2man-no}" | echo "pod2man enabled ${pod2man-no}" | ||||
| @@ -687,6 +687,7 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \ | |||||
| libschroedinger.o | libschroedinger.o | ||||
| OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ | OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ | ||||
| libschroedinger.o | libschroedinger.o | ||||
| OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o | |||||
| OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o | OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o | ||||
| OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o | OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o | ||||
| OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o | OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o | ||||
| @@ -482,6 +482,7 @@ void avcodec_register_all(void) | |||||
| REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); | REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); | ||||
| REGISTER_ENCDEC (LIBOPUS, libopus); | REGISTER_ENCDEC (LIBOPUS, libopus); | ||||
| REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); | REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); | ||||
| REGISTER_ENCODER(LIBSHINE, libshine); | |||||
| REGISTER_ENCDEC (LIBSPEEX, libspeex); | REGISTER_ENCDEC (LIBSPEEX, libspeex); | ||||
| REGISTER_DECODER(LIBSTAGEFRIGHT_H264, libstagefright_h264); | REGISTER_DECODER(LIBSTAGEFRIGHT_H264, libstagefright_h264); | ||||
| REGISTER_ENCODER(LIBTHEORA, libtheora); | REGISTER_ENCODER(LIBTHEORA, libtheora); | ||||
| @@ -0,0 +1,149 @@ | |||||
| /* | |||||
| * Interface to libshine for mp3 encoding | |||||
| * Copyright (c) 2012 Paul B Mahol | |||||
| * | |||||
| * This file is part of FFmpeg. | |||||
| * | |||||
| * 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. | |||||
| * | |||||
| * 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 FFmpeg; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| #include <shine/layer3.h> | |||||
| #include "libavutil/intreadwrite.h" | |||||
| #include "audio_frame_queue.h" | |||||
| #include "avcodec.h" | |||||
| #include "internal.h" | |||||
| #include "mpegaudio.h" | |||||
| #include "mpegaudiodecheader.h" | |||||
| #define BUFFER_SIZE (4096 * 20) | |||||
| typedef struct SHINEContext { | |||||
| shine_config_t config; | |||||
| shine_t shine; | |||||
| uint8_t buffer[BUFFER_SIZE]; | |||||
| int buffer_index; | |||||
| AudioFrameQueue afq; | |||||
| } SHINEContext; | |||||
| static av_cold int libshine_encode_init(AVCodecContext *avctx) | |||||
| { | |||||
| SHINEContext *s = avctx->priv_data; | |||||
| if (avctx->channels <= 0 || avctx->channels > 2){ | |||||
| av_log(avctx, AV_LOG_ERROR, "only mono or stereo is supported\n"); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| shine_set_config_mpeg_defaults(&s->config.mpeg); | |||||
| if (avctx->bit_rate) | |||||
| s->config.mpeg.bitr = avctx->bit_rate / 1000; | |||||
| if (shine_find_bitrate_index(s->config.mpeg.bitr) < 0) { | |||||
| av_log(avctx, AV_LOG_ERROR, "invalid bitrate\n"); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| s->config.mpeg.mode = avctx->channels == 2 ? STEREO : MONO; | |||||
| s->config.wave.samplerate = avctx->sample_rate; | |||||
| s->config.wave.channels = avctx->channels == 2 ? PCM_STEREO : PCM_MONO; | |||||
| s->shine = shine_initialise(&s->config); | |||||
| if (!s->shine) | |||||
| return AVERROR(ENOMEM); | |||||
| avctx->frame_size = samp_per_frame; | |||||
| ff_af_queue_init(avctx, &s->afq); | |||||
| return 0; | |||||
| } | |||||
| static int libshine_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, | |||||
| const AVFrame *frame, int *got_packet_ptr) | |||||
| { | |||||
| SHINEContext *s = avctx->priv_data; | |||||
| MPADecodeHeader hdr; | |||||
| unsigned char *data; | |||||
| long written; | |||||
| int ret, len; | |||||
| if (frame) | |||||
| data = shine_encode_frame(s->shine, frame->data[0], &written); | |||||
| else | |||||
| data = shine_flush(s->shine, &written); | |||||
| if (written < 0) | |||||
| return -1; | |||||
| if (written > 0) { | |||||
| if (s->buffer_index + written > BUFFER_SIZE) { | |||||
| av_log(avctx, AV_LOG_ERROR, "internal buffer too small\n"); | |||||
| return AVERROR_BUG; | |||||
| } | |||||
| memcpy(s->buffer + s->buffer_index, data, written); | |||||
| s->buffer_index += written; | |||||
| } | |||||
| if (frame) { | |||||
| if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) | |||||
| return ret; | |||||
| } | |||||
| if (s->buffer_index < 4 || !s->afq.frame_count) | |||||
| return 0; | |||||
| if (avpriv_mpegaudio_decode_header(&hdr, AV_RB32(s->buffer))) { | |||||
| av_log(avctx, AV_LOG_ERROR, "free format output not supported\n"); | |||||
| return -1; | |||||
| } | |||||
| len = hdr.frame_size; | |||||
| if (len <= s->buffer_index) { | |||||
| if ((ret = ff_alloc_packet2(avctx, avpkt, len))) | |||||
| return ret; | |||||
| memcpy(avpkt->data, s->buffer, len); | |||||
| s->buffer_index -= len; | |||||
| memmove(s->buffer, s->buffer + len, s->buffer_index); | |||||
| ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts, | |||||
| &avpkt->duration); | |||||
| avpkt->size = len; | |||||
| *got_packet_ptr = 1; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| static av_cold int libshine_encode_close(AVCodecContext *avctx) | |||||
| { | |||||
| SHINEContext *s = avctx->priv_data; | |||||
| ff_af_queue_close(&s->afq); | |||||
| shine_close(s->shine); | |||||
| return 0; | |||||
| } | |||||
| static const int libshine_sample_rates[] = { | |||||
| 44100, 48000, 32000, 0 | |||||
| }; | |||||
| AVCodec ff_libshine_encoder = { | |||||
| .name = "libshine", | |||||
| .type = AVMEDIA_TYPE_AUDIO, | |||||
| .id = CODEC_ID_MP3, | |||||
| .priv_data_size = sizeof(SHINEContext), | |||||
| .init = libshine_encode_init, | |||||
| .encode2 = libshine_encode_frame, | |||||
| .close = libshine_encode_close, | |||||
| .capabilities = CODEC_CAP_DELAY, | |||||
| .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P, | |||||
| AV_SAMPLE_FMT_NONE }, | |||||
| .supported_samplerates = libshine_sample_rates, | |||||
| .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, | |||||
| AV_CH_LAYOUT_STEREO, | |||||
| 0 }, | |||||
| .long_name = NULL_IF_CONFIG_SMALL("libshine MP3 (MPEG audio layer 3)"), | |||||
| }; | |||||