9 #include "libmpdemux/aviheader.h"
10 #include "libmpdemux/ms_hdr.h"
11 #include "stream/stream.h"
12 #include "libmpdemux/muxer.h"
15 #include "libaf/af_format.h"
16 #include "libmpdemux/mp3_hdr.h"
19 #include <lame/lame.h>
21 lame_global_flags
*lame
;
22 static int lame_param_quality
=0; // best
23 static int lame_param_algqual
=5; // same as old default
24 static int lame_param_vbr
=vbr_default
;
25 static int lame_param_mode
=-1; // unset
26 static int lame_param_padding
=-1; // unset
27 static int lame_param_br
=-1; // unset
28 static int lame_param_ratio
=-1; // unset
29 static float lame_param_scale
=-1; // unset
30 static int lame_param_lowpassfreq
= 0; //auto
31 static int lame_param_highpassfreq
= 0; //auto
32 static int lame_param_free_format
= 0; //disabled
33 static int lame_param_br_min
= 0; //not specified
34 static int lame_param_br_max
= 0; //not specified
36 #ifdef HAVE_MP3LAME_PRESET
37 int lame_param_fast
=0; // unset
38 static char* lame_param_preset
=NULL
; // unset
39 static int lame_presets_set( lame_t gfp
, int fast
, int cbr
, const char* preset_name
);
43 m_option_t lameopts_conf
[]={
44 {"q", &lame_param_quality
, CONF_TYPE_INT
, CONF_RANGE
, 0, 9, NULL
},
45 {"aq", &lame_param_algqual
, CONF_TYPE_INT
, CONF_RANGE
, 0, 9, NULL
},
46 {"vbr", &lame_param_vbr
, CONF_TYPE_INT
, CONF_RANGE
, 0, vbr_max_indicator
, NULL
},
47 {"cbr", &lame_param_vbr
, CONF_TYPE_FLAG
, 0, 0, 0, NULL
},
48 {"abr", &lame_param_vbr
, CONF_TYPE_FLAG
, 0, 0, vbr_abr
, NULL
},
49 {"mode", &lame_param_mode
, CONF_TYPE_INT
, CONF_RANGE
, 0, MAX_INDICATOR
, NULL
},
50 {"padding", &lame_param_padding
, CONF_TYPE_INT
, CONF_RANGE
, 0, PAD_MAX_INDICATOR
, NULL
},
51 {"br", &lame_param_br
, CONF_TYPE_INT
, CONF_RANGE
, 0, 1024, NULL
},
52 {"ratio", &lame_param_ratio
, CONF_TYPE_INT
, CONF_RANGE
, 0, 100, NULL
},
53 {"vol", &lame_param_scale
, CONF_TYPE_FLOAT
, CONF_RANGE
, 0, 10, NULL
},
54 {"lowpassfreq",&lame_param_lowpassfreq
, CONF_TYPE_INT
, CONF_RANGE
, -1, 48000,0},
55 {"highpassfreq",&lame_param_highpassfreq
, CONF_TYPE_INT
, CONF_RANGE
, -1, 48000,0},
56 {"nofree", &lame_param_free_format
, CONF_TYPE_FLAG
, 0, 0, 0, NULL
},
57 {"free", &lame_param_free_format
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
58 {"br_min", &lame_param_br_min
, CONF_TYPE_INT
, CONF_RANGE
, 0, 1024, NULL
},
59 {"br_max", &lame_param_br_max
, CONF_TYPE_INT
, CONF_RANGE
, 0, 1024, NULL
},
60 #ifdef HAVE_MP3LAME_PRESET
61 {"fast", &lame_param_fast
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
62 {"preset", &lame_param_preset
, CONF_TYPE_STRING
, 0, 0, 0, NULL
},
64 {"fast", "MPlayer was built without -lameopts fast support (requires libmp3lame >=3.92).\n", CONF_TYPE_PRINT
, CONF_NOCFG
, 0, 0, NULL
},
65 {"preset", "MPlayer was built without -lameopts preset support (requires libmp3lame >=3.92).\n", CONF_TYPE_PRINT
, CONF_NOCFG
, 0, 0, NULL
},
67 {"help", MSGTR_MEncoderMP3LameHelp
, CONF_TYPE_PRINT
, CONF_NOCFG
, 0, 0, NULL
},
68 {NULL
, NULL
, 0, 0, 0, 0, NULL
}
72 static int bind_lame(audio_encoder_t
*encoder
, muxer_stream_t
*mux_a
)
74 mp_msg(MSGT_MENCODER
, MSGL_INFO
, MSGTR_MP3AudioSelected
);
75 mux_a
->h
.dwSampleSize
=0; // VBR
76 mux_a
->h
.dwRate
=encoder
->params
.sample_rate
;
77 mux_a
->h
.dwScale
=encoder
->params
.samples_per_frame
; // samples/frame
78 if(sizeof(MPEGLAYER3WAVEFORMAT
)!=30) mp_msg(MSGT_MENCODER
,MSGL_WARN
,MSGTR_MP3WaveFormatSizeNot30
,sizeof(MPEGLAYER3WAVEFORMAT
));
79 mux_a
->wf
=malloc(sizeof(MPEGLAYER3WAVEFORMAT
)); // should be 30
80 mux_a
->wf
->wFormatTag
=0x55; // MP3
81 mux_a
->wf
->nChannels
= (lame_param_mode
<0) ? encoder
->params
.channels
: ((lame_param_mode
==3) ? 1 : 2);
82 mux_a
->wf
->nSamplesPerSec
=mux_a
->h
.dwRate
;
84 mux_a
->wf
->nAvgBytesPerSec
=lame_param_br
* 125;
86 mux_a
->wf
->nAvgBytesPerSec
=192000/8; // FIXME!
87 mux_a
->wf
->nBlockAlign
=encoder
->params
.samples_per_frame
; // required for l3codeca.acm + WMP 6.4
88 mux_a
->wf
->wBitsPerSample
=0; //16;
89 // from NaNdub: (requires for l3codeca.acm)
91 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->wID
=1;
92 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->fdwFlags
=2;
93 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->nBlockSize
=encoder
->params
.samples_per_frame
; // ???
94 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->nFramesPerBlock
=1;
95 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->nCodecDelay
=0;
97 encoder
->input_format
= AF_FORMAT_S16_NE
;
98 encoder
->min_buffer_size
= 4608;
99 encoder
->max_buffer_size
= mux_a
->h
.dwRate
* mux_a
->wf
->nChannels
* 2;
104 #define min(a, b) ((a) <= (b) ? (a) : (b))
106 static int get_frame_size(audio_encoder_t
*encoder
)
109 if(encoder
->stream
->buffer_len
< 4)
111 sz
= mp_decode_mp3_header(encoder
->stream
->buffer
);
117 static int encode_lame(audio_encoder_t
*encoder
, uint8_t *dest
, void *src
, int len
, int max_size
)
120 if(encoder
->params
.channels
== 1)
121 n
= lame_encode_buffer(lame
, (short *)src
, (short *)src
, len
/2, dest
, max_size
);
123 n
= lame_encode_buffer_interleaved(lame
,(short *)src
, len
/4, dest
, max_size
);
125 return (n
< 0 ? 0 : n
);
129 static int close_lame(audio_encoder_t
*encoder
)
134 static void fixup(audio_encoder_t
*encoder
)
136 // fixup CBR mp3 audio header:
137 if(!lame_param_vbr
) {
138 encoder
->stream
->h
.dwSampleSize
=1;
139 ((MPEGLAYER3WAVEFORMAT
*)(encoder
->stream
->wf
))->nBlockSize
=
140 (encoder
->stream
->size
+(encoder
->stream
->h
.dwLength
>>1))/encoder
->stream
->h
.dwLength
;
141 encoder
->stream
->h
.dwLength
=encoder
->stream
->size
;
142 encoder
->stream
->h
.dwRate
=encoder
->stream
->wf
->nAvgBytesPerSec
;
143 encoder
->stream
->h
.dwScale
=1;
144 encoder
->stream
->wf
->nBlockAlign
=1;
145 mp_msg(MSGT_MENCODER
, MSGL_V
, MSGTR_CBRAudioByterate
,
146 encoder
->stream
->h
.dwRate
,((MPEGLAYER3WAVEFORMAT
*)(encoder
->stream
->wf
))->nBlockSize
);
150 int mpae_init_lame(audio_encoder_t
*encoder
)
152 encoder
->params
.bitrate
= lame_param_br
* 125;
153 encoder
->params
.samples_per_frame
= encoder
->params
.sample_rate
< 32000 ? 576 : 1152;
154 encoder
->decode_buffer_size
= 2304;
157 lame_set_bWriteVbrTag(lame
,0);
158 lame_set_in_samplerate(lame
,encoder
->params
.sample_rate
);
159 //lame_set_in_samplerate(lame,sh_audio->samplerate); // if resampling done by lame
160 lame_set_num_channels(lame
,encoder
->params
.channels
);
161 lame_set_out_samplerate(lame
,encoder
->params
.sample_rate
);
162 lame_set_quality(lame
,lame_param_algqual
); // 0 = best q
163 if(lame_param_free_format
) lame_set_free_format(lame
,1);
164 if(lame_param_vbr
){ // VBR:
165 lame_set_VBR(lame
,lame_param_vbr
); // vbr mode
166 lame_set_VBR_q(lame
,lame_param_quality
); // 0 = best vbr q 5=~128k
167 if(lame_param_br
>0) lame_set_VBR_mean_bitrate_kbps(lame
,lame_param_br
);
168 if(lame_param_br_min
>0) lame_set_VBR_min_bitrate_kbps(lame
,lame_param_br_min
);
169 if(lame_param_br_max
>0) lame_set_VBR_max_bitrate_kbps(lame
,lame_param_br_max
);
171 if(lame_param_br
>0) lame_set_brate(lame
,lame_param_br
);
173 if(lame_param_mode
>=0) lame_set_mode(lame
,lame_param_mode
); // j-st
174 if(lame_param_ratio
>0) lame_set_compression_ratio(lame
,lame_param_ratio
);
175 if(lame_param_scale
>0) {
176 mp_msg(MSGT_MENCODER
, MSGL_V
, MSGTR_SettingAudioInputGain
, lame_param_scale
);
177 lame_set_scale(lame
,lame_param_scale
);
179 if(lame_param_lowpassfreq
>=-1) lame_set_lowpassfreq(lame
,lame_param_lowpassfreq
);
180 if(lame_param_highpassfreq
>=-1) lame_set_highpassfreq(lame
,lame_param_highpassfreq
);
181 #ifdef HAVE_MP3LAME_PRESET
182 if(lame_param_preset
!= NULL
) {
183 mp_msg(MSGT_MENCODER
, MSGL_V
, MSGTR_LamePresetEquals
,lame_param_preset
);
184 if(lame_presets_set(lame
,lame_param_fast
, (lame_param_vbr
==0), lame_param_preset
) < 0)
188 if(lame_init_params(lame
) == -1) {
189 mp_msg(MSGT_MENCODER
, MSGL_FATAL
, MSGTR_LameCantInit
);
192 if( mp_msg_test(MSGT_MENCODER
,MSGL_V
) ) {
193 lame_print_config(lame
);
194 lame_print_internals(lame
);
197 encoder
->bind
= bind_lame
;
198 encoder
->get_frame_size
= get_frame_size
;
199 encoder
->encode
= encode_lame
;
200 encoder
->fixup
= fixup
;
201 encoder
->close
= close_lame
;
205 #ifdef HAVE_MP3LAME_PRESET
207 taken out of presets_set in lame-3.93.1/frontend/parse.c and modified */
208 static int lame_presets_set( lame_t gfp
, int fast
, int cbr
, const char* preset_name
)
212 if (strcmp(preset_name
, "help") == 0) {
213 mp_msg(MSGT_MENCODER
, MSGL_FATAL
, MSGTR_LameVersion
, get_lame_version(), get_lame_url());
214 mp_msg(MSGT_MENCODER
, MSGL_FATAL
, MSGTR_LamePresetsLongInfo
);
218 //aliases for compatibility with old presets
220 if (strcmp(preset_name
, "phone") == 0) {
224 if ( (strcmp(preset_name
, "phon+") == 0) ||
225 (strcmp(preset_name
, "lw") == 0) ||
226 (strcmp(preset_name
, "mw-eu") == 0) ||
227 (strcmp(preset_name
, "sw") == 0)) {
231 if (strcmp(preset_name
, "mw-us") == 0) {
235 if (strcmp(preset_name
, "voice") == 0) {
239 if (strcmp(preset_name
, "fm") == 0) {
242 if ( (strcmp(preset_name
, "radio") == 0) ||
243 (strcmp(preset_name
, "tape") == 0)) {
246 if (strcmp(preset_name
, "hifi") == 0) {
249 if (strcmp(preset_name
, "cd") == 0) {
252 if (strcmp(preset_name
, "studio") == 0) {
256 #ifdef HAVE_MP3LAME_PRESET_MEDIUM
257 if (strcmp(preset_name
, "medium") == 0) {
259 lame_set_preset(gfp
, MEDIUM_FAST
);
261 lame_set_preset(gfp
, MEDIUM
);
267 if (strcmp(preset_name
, "standard") == 0) {
269 lame_set_preset(gfp
, STANDARD_FAST
);
271 lame_set_preset(gfp
, STANDARD
);
276 else if (strcmp(preset_name
, "extreme") == 0){
278 lame_set_preset(gfp
, EXTREME_FAST
);
280 lame_set_preset(gfp
, EXTREME
);
285 else if (((strcmp(preset_name
, "insane") == 0) ||
286 (strcmp(preset_name
, "320" ) == 0)) && (fast
< 1)) {
288 lame_set_preset(gfp
, INSANE
);
293 // Generic ABR Preset
294 if (((atoi(preset_name
)) > 0) && (fast
< 1)) {
295 if ((atoi(preset_name
)) >= 8 && (atoi(preset_name
)) <= 320){
296 lame_set_preset(gfp
, atoi(preset_name
));
299 lame_set_VBR(gfp
, vbr_off
);
302 lame_set_mode(gfp
, MONO
);
309 mp_msg(MSGT_MENCODER
, MSGL_FATAL
, MSGTR_LameVersion
, get_lame_version(), get_lame_url());
310 mp_msg(MSGT_MENCODER
, MSGL_FATAL
, MSGTR_InvalidBitrateForLamePreset
);
315 mp_msg(MSGT_MENCODER
, MSGL_FATAL
, MSGTR_LameVersion
, get_lame_version(), get_lame_url());
316 mp_msg(MSGT_MENCODER
, MSGL_FATAL
, MSGTR_InvalidLamePresetOptions
);