Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2012/07/30 03:20:00... | ... |
@@ -218,6 +218,7 @@ External library support: |
218 | 218 |
--enable-libquvi enable quvi input via libquvi [no] |
219 | 219 |
--enable-librtmp enable RTMP[E] support via librtmp [no] |
220 | 220 |
--enable-libschroedinger enable Dirac de/encoding via libschroedinger [no] |
221 |
+ --enable-libshine enable fixed-point MP3 encoding via libshine [no] |
|
221 | 222 |
--enable-libsoxr enable Include libsoxr resampling [no] |
222 | 223 |
--enable-libspeex enable Speex de/encoding via libspeex [no] |
223 | 224 |
--enable-libstagefright-h264 enable H.264 decoding via libstagefright [no] |
... | ... |
@@ -1172,6 +1173,7 @@ EXTERNAL_LIBRARY_LIST=" |
1172 | 1172 |
libquvi |
1173 | 1173 |
librtmp |
1174 | 1174 |
libschroedinger |
1175 |
+ libshine |
|
1175 | 1176 |
libsoxr |
1176 | 1177 |
libspeex |
1177 | 1178 |
libstagefright_h264 |
... | ... |
@@ -1976,6 +1978,8 @@ libopus_encoder_select="audio_frame_queue" |
1976 | 1976 |
libquvi_demuxer_deps="libquvi" |
1977 | 1977 |
libschroedinger_decoder_deps="libschroedinger" |
1978 | 1978 |
libschroedinger_encoder_deps="libschroedinger" |
1979 |
+libshine_encoder_deps="libshine" |
|
1980 |
+libshine_encoder_select="audio_frame_queue" |
|
1979 | 1981 |
libspeex_decoder_deps="libspeex" |
1980 | 1982 |
libspeex_encoder_deps="libspeex" |
1981 | 1983 |
libspeex_encoder_select="audio_frame_queue" |
... | ... |
@@ -3997,6 +4001,7 @@ enabled libpulse && require_pkg_config libpulse-simple pulse/simple.h pa_simple_ |
3997 | 3997 |
enabled libquvi && require_pkg_config libquvi quvi/quvi.h quvi_init |
3998 | 3998 |
enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket |
3999 | 3999 |
enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init |
4000 |
+enabled libshine && require_pkg_config shine shine/layer3.h shine_encode_frame |
|
4000 | 4001 |
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr |
4001 | 4002 |
enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex |
4002 | 4003 |
enabled libstagefright_h264 && require_cpp libstagefright_h264 "binder/ProcessState.h media/stagefright/MetaData.h |
... | ... |
@@ -4398,6 +4403,7 @@ echo "threading support ${thread_type-no}" |
4398 | 4398 |
echo "safe bitstream reader ${safe_bitstream_reader-no}" |
4399 | 4399 |
echo "SDL support ${sdl-no}" |
4400 | 4400 |
echo "opencl enabled ${opencl-no}" |
4401 |
+echo "libshine enabled ${libshine-no}" |
|
4401 | 4402 |
echo "texi2html enabled ${texi2html-no}" |
4402 | 4403 |
echo "perl enabled ${perl-no}" |
4403 | 4404 |
echo "pod2man enabled ${pod2man-no}" |
... | ... |
@@ -687,6 +687,7 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \ |
687 | 687 |
libschroedinger.o |
688 | 688 |
OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ |
689 | 689 |
libschroedinger.o |
690 |
+OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o |
|
690 | 691 |
OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o |
691 | 692 |
OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o |
692 | 693 |
OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o |
... | ... |
@@ -482,6 +482,7 @@ void avcodec_register_all(void) |
482 | 482 |
REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); |
483 | 483 |
REGISTER_ENCDEC (LIBOPUS, libopus); |
484 | 484 |
REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); |
485 |
+ REGISTER_ENCODER(LIBSHINE, libshine); |
|
485 | 486 |
REGISTER_ENCDEC (LIBSPEEX, libspeex); |
486 | 487 |
REGISTER_DECODER(LIBSTAGEFRIGHT_H264, libstagefright_h264); |
487 | 488 |
REGISTER_ENCODER(LIBTHEORA, libtheora); |
488 | 489 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,149 @@ |
0 |
+/* |
|
1 |
+ * Interface to libshine for mp3 encoding |
|
2 |
+ * Copyright (c) 2012 Paul B Mahol |
|
3 |
+ * |
|
4 |
+ * This file is part of FFmpeg. |
|
5 |
+ * |
|
6 |
+ * FFmpeg is free software; you can redistribute it and/or |
|
7 |
+ * modify it under the terms of the GNU Lesser General Public |
|
8 |
+ * License as published by the Free Software Foundation; either |
|
9 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
10 |
+ * |
|
11 |
+ * FFmpeg is distributed in the hope that it will be useful, |
|
12 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
+ * Lesser General Public License for more details. |
|
15 |
+ * |
|
16 |
+ * You should have received a copy of the GNU Lesser General Public |
|
17 |
+ * License along with FFmpeg; if not, write to the Free Software |
|
18 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
19 |
+ */ |
|
20 |
+ |
|
21 |
+#include <shine/layer3.h> |
|
22 |
+ |
|
23 |
+#include "libavutil/intreadwrite.h" |
|
24 |
+#include "audio_frame_queue.h" |
|
25 |
+#include "avcodec.h" |
|
26 |
+#include "internal.h" |
|
27 |
+#include "mpegaudio.h" |
|
28 |
+#include "mpegaudiodecheader.h" |
|
29 |
+ |
|
30 |
+#define BUFFER_SIZE (4096 * 20) |
|
31 |
+ |
|
32 |
+typedef struct SHINEContext { |
|
33 |
+ shine_config_t config; |
|
34 |
+ shine_t shine; |
|
35 |
+ uint8_t buffer[BUFFER_SIZE]; |
|
36 |
+ int buffer_index; |
|
37 |
+ AudioFrameQueue afq; |
|
38 |
+} SHINEContext; |
|
39 |
+ |
|
40 |
+static av_cold int libshine_encode_init(AVCodecContext *avctx) |
|
41 |
+{ |
|
42 |
+ SHINEContext *s = avctx->priv_data; |
|
43 |
+ |
|
44 |
+ if (avctx->channels <= 0 || avctx->channels > 2){ |
|
45 |
+ av_log(avctx, AV_LOG_ERROR, "only mono or stereo is supported\n"); |
|
46 |
+ return AVERROR(EINVAL); |
|
47 |
+ } |
|
48 |
+ |
|
49 |
+ shine_set_config_mpeg_defaults(&s->config.mpeg); |
|
50 |
+ if (avctx->bit_rate) |
|
51 |
+ s->config.mpeg.bitr = avctx->bit_rate / 1000; |
|
52 |
+ if (shine_find_bitrate_index(s->config.mpeg.bitr) < 0) { |
|
53 |
+ av_log(avctx, AV_LOG_ERROR, "invalid bitrate\n"); |
|
54 |
+ return AVERROR(EINVAL); |
|
55 |
+ } |
|
56 |
+ s->config.mpeg.mode = avctx->channels == 2 ? STEREO : MONO; |
|
57 |
+ s->config.wave.samplerate = avctx->sample_rate; |
|
58 |
+ s->config.wave.channels = avctx->channels == 2 ? PCM_STEREO : PCM_MONO; |
|
59 |
+ s->shine = shine_initialise(&s->config); |
|
60 |
+ if (!s->shine) |
|
61 |
+ return AVERROR(ENOMEM); |
|
62 |
+ avctx->frame_size = samp_per_frame; |
|
63 |
+ ff_af_queue_init(avctx, &s->afq); |
|
64 |
+ return 0; |
|
65 |
+} |
|
66 |
+ |
|
67 |
+static int libshine_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
|
68 |
+ const AVFrame *frame, int *got_packet_ptr) |
|
69 |
+{ |
|
70 |
+ SHINEContext *s = avctx->priv_data; |
|
71 |
+ MPADecodeHeader hdr; |
|
72 |
+ unsigned char *data; |
|
73 |
+ long written; |
|
74 |
+ int ret, len; |
|
75 |
+ |
|
76 |
+ if (frame) |
|
77 |
+ data = shine_encode_frame(s->shine, frame->data[0], &written); |
|
78 |
+ else |
|
79 |
+ data = shine_flush(s->shine, &written); |
|
80 |
+ if (written < 0) |
|
81 |
+ return -1; |
|
82 |
+ if (written > 0) { |
|
83 |
+ if (s->buffer_index + written > BUFFER_SIZE) { |
|
84 |
+ av_log(avctx, AV_LOG_ERROR, "internal buffer too small\n"); |
|
85 |
+ return AVERROR_BUG; |
|
86 |
+ } |
|
87 |
+ memcpy(s->buffer + s->buffer_index, data, written); |
|
88 |
+ s->buffer_index += written; |
|
89 |
+ } |
|
90 |
+ if (frame) { |
|
91 |
+ if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) |
|
92 |
+ return ret; |
|
93 |
+ } |
|
94 |
+ |
|
95 |
+ if (s->buffer_index < 4 || !s->afq.frame_count) |
|
96 |
+ return 0; |
|
97 |
+ if (avpriv_mpegaudio_decode_header(&hdr, AV_RB32(s->buffer))) { |
|
98 |
+ av_log(avctx, AV_LOG_ERROR, "free format output not supported\n"); |
|
99 |
+ return -1; |
|
100 |
+ } |
|
101 |
+ |
|
102 |
+ len = hdr.frame_size; |
|
103 |
+ if (len <= s->buffer_index) { |
|
104 |
+ if ((ret = ff_alloc_packet2(avctx, avpkt, len))) |
|
105 |
+ return ret; |
|
106 |
+ memcpy(avpkt->data, s->buffer, len); |
|
107 |
+ s->buffer_index -= len; |
|
108 |
+ memmove(s->buffer, s->buffer + len, s->buffer_index); |
|
109 |
+ |
|
110 |
+ ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts, |
|
111 |
+ &avpkt->duration); |
|
112 |
+ |
|
113 |
+ avpkt->size = len; |
|
114 |
+ *got_packet_ptr = 1; |
|
115 |
+ } |
|
116 |
+ return 0; |
|
117 |
+} |
|
118 |
+ |
|
119 |
+static av_cold int libshine_encode_close(AVCodecContext *avctx) |
|
120 |
+{ |
|
121 |
+ SHINEContext *s = avctx->priv_data; |
|
122 |
+ |
|
123 |
+ ff_af_queue_close(&s->afq); |
|
124 |
+ shine_close(s->shine); |
|
125 |
+ return 0; |
|
126 |
+} |
|
127 |
+ |
|
128 |
+static const int libshine_sample_rates[] = { |
|
129 |
+ 44100, 48000, 32000, 0 |
|
130 |
+}; |
|
131 |
+ |
|
132 |
+AVCodec ff_libshine_encoder = { |
|
133 |
+ .name = "libshine", |
|
134 |
+ .type = AVMEDIA_TYPE_AUDIO, |
|
135 |
+ .id = CODEC_ID_MP3, |
|
136 |
+ .priv_data_size = sizeof(SHINEContext), |
|
137 |
+ .init = libshine_encode_init, |
|
138 |
+ .encode2 = libshine_encode_frame, |
|
139 |
+ .close = libshine_encode_close, |
|
140 |
+ .capabilities = CODEC_CAP_DELAY, |
|
141 |
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P, |
|
142 |
+ AV_SAMPLE_FMT_NONE }, |
|
143 |
+ .supported_samplerates = libshine_sample_rates, |
|
144 |
+ .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, |
|
145 |
+ AV_CH_LAYOUT_STEREO, |
|
146 |
+ 0 }, |
|
147 |
+ .long_name = NULL_IF_CONFIG_SMALL("libshine MP3 (MPEG audio layer 3)"), |
|
148 |
+}; |