Browse code

libtwolame MP2 encoding support

Signed-off-by: Paul B Mahol <onemda@gmail.com>

Paul B Mahol authored on 2012/08/01 23:33:34
Showing 6 changed files
... ...
@@ -40,6 +40,7 @@ version next:
40 40
 - flite filter
41 41
 - Canopus Lossless Codec decoder
42 42
 - bitmap subtitles in filters (experimental and temporary)
43
+- MP2 encoding via TwoLAME
43 44
 
44 45
 
45 46
 version 0.11:
... ...
@@ -202,6 +202,7 @@ External library support:
202 202
   --enable-libspeex        enable Speex de/encoding via libspeex [no]
203 203
   --enable-libstagefright-h264  enable H.264 decoding via libstagefright [no]
204 204
   --enable-libtheora       enable Theora encoding via libtheora [no]
205
+  --enable-libtwolame      enable MP2 encoding via libtwolame [no]
205 206
   --enable-libutvideo      enable Ut Video encoding and decoding via libutvideo [no]
206 207
   --enable-libv4l2         enable libv4l2/v4l-utils [no]
207 208
   --enable-libvo-aacenc    enable AAC encoding via libvo-aacenc [no]
... ...
@@ -1101,6 +1102,7 @@ CONFIG_LIST="
1101 1101
     libspeex
1102 1102
     libstagefright_h264
1103 1103
     libtheora
1104
+    libtwolame
1104 1105
     libutvideo
1105 1106
     libv4l2
1106 1107
     libvo_aacenc
... ...
@@ -1676,6 +1678,7 @@ libspeex_decoder_deps="libspeex"
1676 1676
 libspeex_encoder_deps="libspeex"
1677 1677
 libstagefright_h264_decoder_deps="libstagefright_h264"
1678 1678
 libtheora_encoder_deps="libtheora"
1679
+libtwolame_encoder_deps="libtwolame"
1679 1680
 libvo_aacenc_encoder_deps="libvo_aacenc"
1680 1681
 libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
1681 1682
 libvorbis_decoder_deps="libvorbis"
... ...
@@ -3440,6 +3443,7 @@ enabled libstagefright_h264  && require_cpp libstagefright_h264 "binder/ProcessS
3440 3440
     media/stagefright/MediaBufferGroup.h media/stagefright/MediaDebug.h media/stagefright/MediaDefs.h
3441 3441
     media/stagefright/OMXClient.h media/stagefright/OMXCodec.h" android::OMXClient -lstagefright -lmedia -lutils -lbinder -lgnustl_static
3442 3442
 enabled libtheora  && require  libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
3443
+enabled libtwolame && require  libtwolame twolame.h twolame_init -ltwolame
3443 3444
 enabled libutvideo    && require_cpp utvideo "stdint.h stdlib.h utvideo/utvideo.h utvideo/Codec.h" 'CCodec*' -lutvideo -lstdc++
3444 3445
 enabled libv4l2    && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
3445 3446
 enabled libvo_aacenc && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc
... ...
@@ -3825,6 +3829,7 @@ echo "libschroedinger enabled   ${libschroedinger-no}"
3825 3825
 echo "libspeex enabled          ${libspeex-no}"
3826 3826
 echo "libstagefright-h264 enabled    ${libstagefright_h264-no}"
3827 3827
 echo "libtheora enabled         ${libtheora-no}"
3828
+echo "libtwolame enabled        ${libtwolame-no}"
3828 3829
 echo "libutvideo enabled        ${libutvideo-no}"
3829 3830
 echo "libv4l2 enabled           ${libv4l2-no}"
3830 3831
 echo "libvo-aacenc support      ${libvo_aacenc-no}"
... ...
@@ -79,6 +79,14 @@ Go to @url{http://lame.sourceforge.net/} and follow the
79 79
 instructions for installing the library.
80 80
 Then pass @code{--enable-libmp3lame} to configure to enable it.
81 81
 
82
+@section TwoLAME
83
+
84
+FFmpeg can make use of the TwoLAME library for MP2 encoding.
85
+
86
+Go to @url{http://www.twolame.org/} and follow the
87
+instructions for installing the library.
88
+Then pass @code{--enable-libtwolame} to configure to enable it.
89
+
82 90
 @section libvpx
83 91
 
84 92
 FFmpeg can make use of the libvpx library for VP8 encoding.
... ...
@@ -797,6 +805,7 @@ following image formats are supported:
797 797
     @tab Only versions 3.97-3.99 are supported.
798 798
 @item MP1 (MPEG audio layer 1)  @tab     @tab IX
799 799
 @item MP2 (MPEG audio layer 2)  @tab IX  @tab IX
800
+    @tab libtwolame can be used alternatively for encoding.
800 801
 @item MP3 (MPEG audio layer 3)  @tab  E  @tab IX
801 802
     @tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported
802 803
 @item MPEG-4 Audio Lossless Coding (ALS)  @tab     @tab  X
... ...
@@ -697,6 +697,7 @@ OBJS-$(CONFIG_LIBSPEEX_DECODER)           += libspeexdec.o
697 697
 OBJS-$(CONFIG_LIBSPEEX_ENCODER)           += libspeexenc.o audio_frame_queue.o
698 698
 OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o
699 699
 OBJS-$(CONFIG_LIBTHEORA_ENCODER)          += libtheoraenc.o
700
+OBJS-$(CONFIG_LIBTWOLAME_ENCODER)         += libtwolame.o
700 701
 OBJS-$(CONFIG_LIBUTVIDEO_DECODER)         += libutvideodec.o
701 702
 OBJS-$(CONFIG_LIBUTVIDEO_ENCODER)         += libutvideoenc.o
702 703
 OBJS-$(CONFIG_LIBVO_AACENC_ENCODER)       += libvo-aacenc.o mpeg4audio.o \
... ...
@@ -434,6 +434,7 @@ void avcodec_register_all(void)
434 434
     REGISTER_ENCDEC  (LIBSPEEX, libspeex);
435 435
     REGISTER_DECODER (LIBSTAGEFRIGHT_H264, libstagefright_h264);
436 436
     REGISTER_ENCODER (LIBTHEORA, libtheora);
437
+    REGISTER_ENCODER (LIBTWOLAME, libtwolame);
437 438
     REGISTER_ENCDEC  (LIBUTVIDEO, libutvideo);
438 439
     REGISTER_ENCODER (LIBVO_AACENC, libvo_aacenc);
439 440
     REGISTER_ENCODER (LIBVO_AMRWBENC, libvo_amrwbenc);
440 441
new file mode 100644
... ...
@@ -0,0 +1,196 @@
0
+/*
1
+ * Interface to libtwolame for mp2 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
+/**
22
+ * @file
23
+ * Interface to libtwolame for mp2 encoding.
24
+ */
25
+
26
+#include <twolame.h>
27
+
28
+#include "libavutil/opt.h"
29
+#include "avcodec.h"
30
+#include "internal.h"
31
+#include "mpegaudio.h"
32
+
33
+typedef struct TWOLAMEContext {
34
+    AVClass  *class;
35
+    int      mode;
36
+    int      psymodel;
37
+    int      energy;
38
+    int      error_protection;
39
+    int      copyright;
40
+    int      original;
41
+
42
+    twolame_options *glopts;
43
+    int64_t  next_pts;
44
+} TWOLAMEContext;
45
+
46
+static av_cold int twolame_encode_close(AVCodecContext *avctx)
47
+{
48
+    TWOLAMEContext *s = avctx->priv_data;
49
+    twolame_close(&s->glopts);
50
+    return 0;
51
+}
52
+
53
+static av_cold int twolame_encode_init(AVCodecContext *avctx)
54
+{
55
+    TWOLAMEContext *s = avctx->priv_data;
56
+    int ret;
57
+
58
+    avctx->frame_size = TWOLAME_SAMPLES_PER_FRAME;
59
+
60
+    s->glopts = twolame_init();
61
+    if (!s->glopts)
62
+        return AVERROR(ENOMEM);
63
+
64
+    twolame_set_verbosity(s->glopts, 0);
65
+    twolame_set_mode(s->glopts, s->mode);
66
+    twolame_set_psymodel(s->glopts, s->psymodel);
67
+    twolame_set_energy_levels(s->glopts, s->energy);
68
+    twolame_set_error_protection(s->glopts, s->error_protection);
69
+
70
+    twolame_set_num_channels(s->glopts, avctx->channels);
71
+    twolame_set_in_samplerate(s->glopts, avctx->sample_rate);
72
+    twolame_set_out_samplerate(s->glopts, avctx->sample_rate);
73
+    if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) {
74
+        twolame_set_VBR(s->glopts, TRUE);
75
+        twolame_set_VBR_level(s->glopts, avctx->global_quality);
76
+        av_log(avctx, AV_LOG_WARNING, "VBR mode is experimental!\n");
77
+    } else {
78
+        twolame_set_bitrate(s->glopts, avctx->bit_rate / 1000);
79
+    }
80
+
81
+    if ((ret = twolame_init_params(s->glopts)))
82
+        goto error;
83
+
84
+    return 0;
85
+error:
86
+    twolame_encode_close(avctx);
87
+    return ret;
88
+}
89
+
90
+static int twolame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
91
+                                const AVFrame *frame, int *got_packet_ptr)
92
+{
93
+    TWOLAMEContext *s = avctx->priv_data;
94
+    int ret;
95
+
96
+    if ((ret = ff_alloc_packet2(avctx, avpkt, MPA_MAX_CODED_FRAME_SIZE)))
97
+        return ret;
98
+
99
+    if (frame) {
100
+        switch (avctx->sample_fmt) {
101
+        case AV_SAMPLE_FMT_FLT:
102
+            ret = twolame_encode_buffer_float32_interleaved(s->glopts,
103
+                                        frame->data[0],
104
+                                        frame->nb_samples,
105
+                                        avpkt->data, avpkt->size);
106
+            break;
107
+        case AV_SAMPLE_FMT_FLTP:
108
+            ret = twolame_encode_buffer_float32(s->glopts,
109
+                                        frame->data[0], frame->data[1],
110
+                                        frame->nb_samples,
111
+                                        avpkt->data, avpkt->size);
112
+            break;
113
+        case AV_SAMPLE_FMT_S16:
114
+            ret = twolame_encode_buffer_interleaved(s->glopts,
115
+                                        frame->data[0],
116
+                                        frame->nb_samples,
117
+                                        avpkt->data, avpkt->size);
118
+            break;
119
+        case AV_SAMPLE_FMT_S16P:
120
+            ret = twolame_encode_buffer(s->glopts,
121
+                                        frame->data[0], frame->data[1],
122
+                                        frame->nb_samples,
123
+                                        avpkt->data, avpkt->size);
124
+            break;
125
+        default:
126
+            return AVERROR_BUG;
127
+        }
128
+    } else {
129
+        ret = twolame_encode_flush(s->glopts, avpkt->data, avpkt->size);
130
+    }
131
+
132
+    if (ret > 0) {
133
+        avpkt->duration = ff_samples_to_time_base(avctx, avctx->frame_size);
134
+        if (frame) {
135
+            if (frame->pts != AV_NOPTS_VALUE)
136
+                avpkt->pts  = frame->pts;
137
+        } else {
138
+            avpkt->pts = s->next_pts;
139
+        }
140
+        if (avpkt->pts != AV_NOPTS_VALUE)
141
+            s->next_pts = avpkt->pts + avpkt->duration;
142
+
143
+        avpkt->size     = ret;
144
+        *got_packet_ptr = 1;
145
+        return 0;
146
+    }
147
+
148
+    return ret;
149
+}
150
+
151
+#define OFFSET(x) offsetof(TWOLAMEContext, x)
152
+#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
153
+static const AVOption options[] = {
154
+    { "mode",         "Mpeg Mode", OFFSET(mode), AV_OPT_TYPE_INT, { TWOLAME_AUTO_MODE }, TWOLAME_AUTO_MODE, TWOLAME_MONO, AE, "mode"},
155
+    { "auto",         NULL,         0, AV_OPT_TYPE_CONST, { TWOLAME_AUTO_MODE },          0, 0, AE, "mode" },
156
+    { "stereo",       NULL,         0, AV_OPT_TYPE_CONST, { TWOLAME_STEREO },             0, 0, AE, "mode" },
157
+    { "joint_stereo", NULL,         0, AV_OPT_TYPE_CONST, { TWOLAME_JOINT_STEREO },       0, 0, AE, "mode" },
158
+    { "dual_channel", NULL,         0, AV_OPT_TYPE_CONST, { TWOLAME_DUAL_CHANNEL },       0, 0, AE, "mode" },
159
+    { "mono",         NULL,         0, AV_OPT_TYPE_CONST, { TWOLAME_MONO },               0, 0, AE, "mode" },
160
+    { "psymodel",    "Psychoacoustic Model",  OFFSET(psymodel), AV_OPT_TYPE_INT, { 3 }, -1, 4, AE},
161
+    { "energy_levels","enable energy levels", OFFSET(energy),   AV_OPT_TYPE_INT, { 0 },  0, 1, AE},
162
+    { "error_protection","enable CRC error protection", OFFSET(error_protection), AV_OPT_TYPE_INT, { 0 },  0, 1, AE},
163
+    { "copyright",    "set MPEG Audio Copyright flag",  OFFSET(copyright), AV_OPT_TYPE_INT, { 0 },  0, 1, AE},
164
+    { "original",     "set MPEG Audio Original flag",   OFFSET(original),  AV_OPT_TYPE_INT, { 0 },  0, 1, AE},
165
+    { NULL },
166
+};
167
+
168
+static const AVClass libtwolame_class = {
169
+    .class_name = "libtwolame encoder",
170
+    .item_name  = av_default_item_name,
171
+    .option     = options,
172
+    .version    = LIBAVUTIL_VERSION_INT,
173
+};
174
+
175
+AVCodec ff_libtwolame_encoder = {
176
+    .name                  = "libtwolame",
177
+    .type                  = AVMEDIA_TYPE_AUDIO,
178
+    .id                    = CODEC_ID_MP3,
179
+    .priv_data_size        = sizeof(TWOLAMEContext),
180
+    .init                  = twolame_encode_init,
181
+    .encode2               = twolame_encode_frame,
182
+    .close                 = twolame_encode_close,
183
+    .capabilities          = CODEC_CAP_DELAY,
184
+    .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
185
+                                                             AV_SAMPLE_FMT_FLTP,
186
+                                                             AV_SAMPLE_FMT_S16,
187
+                                                             AV_SAMPLE_FMT_S16P,
188
+                                                             AV_SAMPLE_FMT_NONE },
189
+    .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
190
+                                                  AV_CH_LAYOUT_STEREO,
191
+                                                  0 },
192
+    .supported_samplerates = (const int[]){ 16000, 22050, 24000, 32000, 44100, 48000, 0 },
193
+    .long_name             = NULL_IF_CONFIG_SMALL("libtwolame MP2 (MPEG audio layer 2)"),
194
+    .priv_class            = &libtwolame_class,
195
+};