Commit | Line | Data |
---|---|---|
0716b577 J |
1 | /* |
2 | * Interface to libmp3lame for mp3 encoding | |
3 | * Copyright (c) 2002 Lennert Buytenhek <buytenh@gnu.org> | |
4 | * | |
b78e7197 DB |
5 | * This file is part of FFmpeg. |
6 | * | |
7 | * FFmpeg is free software; you can redistribute it and/or | |
ff4ec49e FB |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either | |
b78e7197 | 10 | * version 2.1 of the License, or (at your option) any later version. |
0716b577 | 11 | * |
b78e7197 | 12 | * FFmpeg is distributed in the hope that it will be useful, |
0716b577 | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
ff4ec49e FB |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Lesser General Public License for more details. | |
0716b577 | 16 | * |
ff4ec49e | 17 | * You should have received a copy of the GNU Lesser General Public |
b78e7197 | 18 | * License along with FFmpeg; if not, write to the Free Software |
5509bffa | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0716b577 | 20 | */ |
115329f1 | 21 | |
983e3246 MN |
22 | /** |
23 | * @file mp3lameaudio.c | |
24 | * Interface to libmp3lame for mp3 encoding. | |
25 | */ | |
0716b577 J |
26 | |
27 | #include "avcodec.h" | |
0716b577 J |
28 | #include "mpegaudio.h" |
29 | #include <lame/lame.h> | |
30 | ||
c7d96ac6 | 31 | #define BUFFER_SIZE (7200 + MPA_FRAME_SIZE + MPA_FRAME_SIZE/4) |
0716b577 | 32 | typedef struct Mp3AudioContext { |
e344c1ea SH |
33 | lame_global_flags *gfp; |
34 | int stereo; | |
35 | uint8_t buffer[BUFFER_SIZE]; | |
36 | int buffer_index; | |
0716b577 J |
37 | } Mp3AudioContext; |
38 | ||
98a6fff9 | 39 | static av_cold int MP3lame_encode_init(AVCodecContext *avctx) |
0716b577 | 40 | { |
e344c1ea SH |
41 | Mp3AudioContext *s = avctx->priv_data; |
42 | ||
43 | if (avctx->channels > 2) | |
44 | return -1; | |
45 | ||
46 | s->stereo = avctx->channels > 1 ? 1 : 0; | |
47 | ||
48 | if ((s->gfp = lame_init()) == NULL) | |
49 | goto err; | |
50 | lame_set_in_samplerate(s->gfp, avctx->sample_rate); | |
51 | lame_set_out_samplerate(s->gfp, avctx->sample_rate); | |
52 | lame_set_num_channels(s->gfp, avctx->channels); | |
53 | /* lame 3.91 dies on quality != 5 */ | |
54 | lame_set_quality(s->gfp, 5); | |
55 | /* lame 3.91 doesn't work in mono */ | |
56 | lame_set_mode(s->gfp, JOINT_STEREO); | |
57 | lame_set_brate(s->gfp, avctx->bit_rate/1000); | |
c57c770d JR |
58 | if(avctx->flags & CODEC_FLAG_QSCALE) { |
59 | lame_set_brate(s->gfp, 0); | |
60 | lame_set_VBR(s->gfp, vbr_default); | |
61 | lame_set_VBR_q(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA); | |
62 | } | |
e344c1ea | 63 | lame_set_bWriteVbrTag(s->gfp,0); |
f1618fd9 | 64 | lame_set_disable_reservoir(s->gfp, avctx->flags2 & CODEC_FLAG2_BIT_RESERVOIR ? 0 : 1); |
e344c1ea SH |
65 | if (lame_init_params(s->gfp) < 0) |
66 | goto err_close; | |
0716b577 | 67 | |
e344c1ea | 68 | avctx->frame_size = lame_get_framesize(s->gfp); |
115329f1 | 69 | |
e344c1ea SH |
70 | avctx->coded_frame= avcodec_alloc_frame(); |
71 | avctx->coded_frame->key_frame= 1; | |
0716b577 | 72 | |
e344c1ea | 73 | return 0; |
0716b577 J |
74 | |
75 | err_close: | |
e344c1ea | 76 | lame_close(s->gfp); |
0716b577 | 77 | err: |
e344c1ea | 78 | return -1; |
0716b577 J |
79 | } |
80 | ||
2f996b83 MN |
81 | static const int sSampleRates[3] = { |
82 | 44100, 48000, 32000 | |
83 | }; | |
84 | ||
85 | static const int sBitRates[2][3][15] = { | |
86 | { { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448}, | |
87 | { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384}, | |
88 | { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320} | |
89 | }, | |
90 | { { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256}, | |
91 | { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, | |
92 | { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160} | |
93 | }, | |
94 | }; | |
95 | ||
96 | static const int sSamplesPerFrame[2][3] = | |
97 | { | |
98 | { 384, 1152, 1152 }, | |
99 | { 384, 1152, 576 } | |
100 | }; | |
101 | ||
102 | static const int sBitsPerSlot[3] = { | |
103 | 32, | |
104 | 8, | |
105 | 8 | |
106 | }; | |
107 | ||
108 | static int mp3len(void *data, int *samplesPerFrame, int *sampleRate) | |
109 | { | |
2c124cb6 | 110 | uint32_t header = AV_RB32(data); |
2f996b83 MN |
111 | int layerID = 3 - ((header >> 17) & 0x03); |
112 | int bitRateID = ((header >> 12) & 0x0f); | |
113 | int sampleRateID = ((header >> 10) & 0x03); | |
114 | int bitsPerSlot = sBitsPerSlot[layerID]; | |
115 | int isPadded = ((header >> 9) & 0x01); | |
116 | static int const mode_tab[4]= {2,3,1,0}; | |
117 | int mode= mode_tab[(header >> 19) & 0x03]; | |
118 | int mpeg_id= mode>0; | |
119 | int temp0, temp1, bitRate; | |
120 | ||
121 | if ( (( header >> 21 ) & 0x7ff) != 0x7ff || mode == 3 || layerID==3 || sampleRateID==3) { | |
122 | return -1; | |
123 | } | |
115329f1 | 124 | |
2f996b83 MN |
125 | if(!samplesPerFrame) samplesPerFrame= &temp0; |
126 | if(!sampleRate ) sampleRate = &temp1; | |
127 | ||
128 | // *isMono = ((header >> 6) & 0x03) == 0x03; | |
129 | ||
130 | *sampleRate = sSampleRates[sampleRateID]>>mode; | |
131 | bitRate = sBitRates[mpeg_id][layerID][bitRateID] * 1000; | |
132 | *samplesPerFrame = sSamplesPerFrame[mpeg_id][layerID]; | |
133 | //av_log(NULL, AV_LOG_DEBUG, "sr:%d br:%d spf:%d l:%d m:%d\n", *sampleRate, bitRate, *samplesPerFrame, layerID, mode); | |
115329f1 | 134 | |
2f996b83 MN |
135 | return *samplesPerFrame * bitRate / (bitsPerSlot * *sampleRate) + isPadded; |
136 | } | |
137 | ||
8e981daf MR |
138 | static int MP3lame_encode_frame(AVCodecContext *avctx, |
139 | unsigned char *frame, int buf_size, void *data) | |
0716b577 | 140 | { |
e344c1ea SH |
141 | Mp3AudioContext *s = avctx->priv_data; |
142 | int len; | |
143 | int lame_result; | |
0716b577 | 144 | |
e344c1ea | 145 | /* lame 3.91 dies on '1-channel interleaved' data */ |
6f824977 MN |
146 | |
147 | if(data){ | |
148 | if (s->stereo) { | |
0f5c3f21 | 149 | lame_result = lame_encode_buffer_interleaved( |
115329f1 | 150 | s->gfp, |
2f996b83 | 151 | data, |
115329f1 DB |
152 | avctx->frame_size, |
153 | s->buffer + s->buffer_index, | |
2f996b83 MN |
154 | BUFFER_SIZE - s->buffer_index |
155 | ); | |
6f824977 | 156 | } else { |
0f5c3f21 | 157 | lame_result = lame_encode_buffer( |
115329f1 DB |
158 | s->gfp, |
159 | data, | |
160 | data, | |
0f5c3f21 | 161 | avctx->frame_size, |
115329f1 | 162 | s->buffer + s->buffer_index, |
2f996b83 MN |
163 | BUFFER_SIZE - s->buffer_index |
164 | ); | |
6f824977 MN |
165 | } |
166 | }else{ | |
167 | lame_result= lame_encode_flush( | |
115329f1 DB |
168 | s->gfp, |
169 | s->buffer + s->buffer_index, | |
6f824977 MN |
170 | BUFFER_SIZE - s->buffer_index |
171 | ); | |
0f5c3f21 HD |
172 | } |
173 | ||
174 | if(lame_result==-1) { | |
175 | /* output buffer too small */ | |
176 | av_log(avctx, AV_LOG_ERROR, "lame: output buffer too small (buffer index: %d, free bytes: %d)\n", s->buffer_index, BUFFER_SIZE - s->buffer_index); | |
177 | return 0; | |
178 | } | |
179 | ||
180 | s->buffer_index += lame_result; | |
181 | ||
182 | if(s->buffer_index<4) | |
183 | return 0; | |
2f996b83 MN |
184 | |
185 | len= mp3len(s->buffer, NULL, NULL); | |
0f5c3f21 | 186 | //av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n", avctx->frame_size, len, s->buffer_index); |
2f996b83 MN |
187 | if(len <= s->buffer_index){ |
188 | memcpy(frame, s->buffer, len); | |
189 | s->buffer_index -= len; | |
190 | ||
191 | memmove(s->buffer, s->buffer+len, s->buffer_index); | |
755bfeab | 192 | //FIXME fix the audio codec API, so we do not need the memcpy() |
2f996b83 | 193 | /*for(i=0; i<len; i++){ |
c276af04 MN |
194 | av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]); |
195 | }*/ | |
2f996b83 MN |
196 | return len; |
197 | }else | |
198 | return 0; | |
0716b577 J |
199 | } |
200 | ||
98a6fff9 | 201 | static av_cold int MP3lame_encode_close(AVCodecContext *avctx) |
0716b577 | 202 | { |
e344c1ea | 203 | Mp3AudioContext *s = avctx->priv_data; |
115329f1 | 204 | |
e344c1ea | 205 | av_freep(&avctx->coded_frame); |
0716b577 | 206 | |
e344c1ea SH |
207 | lame_close(s->gfp); |
208 | return 0; | |
0716b577 J |
209 | } |
210 | ||
211 | ||
1cc60c47 DB |
212 | AVCodec libmp3lame_encoder = { |
213 | "libmp3lame", | |
0716b577 | 214 | CODEC_TYPE_AUDIO, |
80783dc2 | 215 | CODEC_ID_MP3, |
0716b577 J |
216 | sizeof(Mp3AudioContext), |
217 | MP3lame_encode_init, | |
218 | MP3lame_encode_frame, | |
6f824977 MN |
219 | MP3lame_encode_close, |
220 | .capabilities= CODEC_CAP_DELAY, | |
fd76c37f | 221 | .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, |
fe4bf374 | 222 | .long_name= NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"), |
0716b577 | 223 | }; |