d2cfd4bb33c6c11913fc6753259853f397c8db75
[platform/upstream/gst-plugins-good.git] / ext / lame / gstlame.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include "string.h"
24 #include "gstlame.h"
25
26 #ifdef lame_set_preset
27 #define GST_LAME_PRESET
28 #endif
29
30 GST_DEBUG_CATEGORY_STATIC (debug);
31 #define GST_CAT_DEFAULT debug
32
33 /* elementfactory information */
34 static GstElementDetails gst_lame_details = {
35   "L.A.M.E. mp3 encoder",
36   "Codec/Encoder/Audio",
37   "High-quality free MP3 encoder",
38   "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>",
39 };
40
41 /* LAME can do MPEG-1, MPEG-2, and MPEG-2.5, so it has 9 possible
42  * sample rates it supports */
43 static GstStaticPadTemplate gst_lame_sink_template =
44 GST_STATIC_PAD_TEMPLATE ("sink",
45     GST_PAD_SINK,
46     GST_PAD_ALWAYS,
47     GST_STATIC_CAPS ("audio/x-raw-int, "
48         "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", "
49         "signed = (boolean) true, "
50         "width = (int) 16, "
51         "depth = (int) 16, "
52         "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
53         "channels = (int) [ 1, 2 ]")
54     );
55
56 static GstStaticPadTemplate gst_lame_src_template =
57 GST_STATIC_PAD_TEMPLATE ("src",
58     GST_PAD_SRC,
59     GST_PAD_ALWAYS,
60     GST_STATIC_CAPS ("audio/mpeg, "
61         "mpegversion = (int) 1, "
62         "layer = (int) 3, "
63         "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
64         "channels = (int) [ 1, 2 ]")
65     );
66
67 /********** Define useful types for non-programmatic interfaces **********/
68 #define GST_TYPE_LAME_MODE (gst_lame_mode_get_type())
69 static GType
70 gst_lame_mode_get_type (void)
71 {
72   static GType lame_mode_type = 0;
73   static GEnumValue lame_modes[] = {
74     {0, "0", "Stereo"},
75     {1, "1", "Joint-Stereo"},
76     {2, "2", "Dual channel"},
77     {3, "3", "Mono"},
78     {4, "4", "Auto"},
79     {0, NULL, NULL}
80   };
81
82   if (!lame_mode_type) {
83     lame_mode_type = g_enum_register_static ("GstLameMode", lame_modes);
84   }
85   return lame_mode_type;
86 }
87
88 #define GST_TYPE_LAME_QUALITY (gst_lame_quality_get_type())
89 static GType
90 gst_lame_quality_get_type (void)
91 {
92   static GType lame_quality_type = 0;
93   static GEnumValue lame_quality[] = {
94     {0, "0", "0 - Best"},
95     {1, "1", "1"},
96     {2, "2", "2"},
97     {3, "3", "3"},
98     {4, "4", "4"},
99     {5, "5", "5 - Default"},
100     {6, "6", "6"},
101     {7, "7", "7"},
102     {8, "8", "8"},
103     {9, "9", "9 - Worst"},
104     {0, NULL, NULL}
105   };
106
107   if (!lame_quality_type) {
108     lame_quality_type = g_enum_register_static ("GstLameQuality", lame_quality);
109   }
110   return lame_quality_type;
111 }
112
113 #define GST_TYPE_LAME_PADDING (gst_lame_padding_get_type())
114 static GType
115 gst_lame_padding_get_type (void)
116 {
117   static GType lame_padding_type = 0;
118   static GEnumValue lame_padding[] = {
119     {0, "0", "No Padding"},
120     {1, "1", "Always Pad"},
121     {2, "2", "Adjust Padding"},
122     {0, NULL, NULL}
123   };
124
125   if (!lame_padding_type) {
126     lame_padding_type = g_enum_register_static ("GstLamePadding", lame_padding);
127   }
128   return lame_padding_type;
129 }
130
131 #define GST_TYPE_LAME_VBRMODE (gst_lame_vbrmode_get_type())
132 static GType
133 gst_lame_vbrmode_get_type (void)
134 {
135   static GType lame_vbrmode_type = 0;
136   static GEnumValue lame_vbrmode[] = {
137     {vbr_off, "cbr", "No VBR (Constant Bitrate)"},
138     {vbr_rh, "old", "Lame's old VBR algorithm"},
139     {vbr_abr, "abr", "VBR Average Bitrate"},
140     {vbr_mtrh, "new", "Lame's new VBR algorithm"},
141     {0, NULL, NULL}
142   };
143
144   if (!lame_vbrmode_type) {
145     lame_vbrmode_type = g_enum_register_static ("GstLameVbrmode", lame_vbrmode);
146   }
147
148   return lame_vbrmode_type;
149 }
150
151 #ifdef GSTLAME_PRESET
152 #define GST_TYPE_LAME_PRESET (gst_lame_preset_get_type())
153 static GType
154 gst_lame_preset_get_type (void)
155 {
156   static GType gst_lame_preset = 0;
157   static GEnumValue gst_lame_presets[] = {
158     {0, "none", "None"},
159     {MEDIUM, "medium", "Medium"},
160     {STANDARD, "standard", "Standard"},
161     {EXTREME, "extreme", "Extreme"},
162     {INSANE, "insane", "Insane"},
163     {0, NULL, NULL}
164   };
165
166   if (!gst_lame_preset) {
167     gst_lame_preset =
168         g_enum_register_static ("GstLamePreset", gst_lame_presets);
169   }
170
171   return gst_lame_preset;
172 }
173 #endif
174
175 /********** Standard stuff for signals and arguments **********/
176 /* GstLame signals and args */
177 enum
178 {
179   /* FILL_ME */
180   LAST_SIGNAL
181 };
182
183 enum
184 {
185   ARG_0,
186   ARG_BITRATE,
187   ARG_COMPRESSION_RATIO,
188   ARG_QUALITY,
189   ARG_MODE,
190   ARG_FORCE_MS,
191   ARG_FREE_FORMAT,
192   ARG_COPYRIGHT,
193   ARG_ORIGINAL,
194   ARG_ERROR_PROTECTION,
195   ARG_PADDING_TYPE,
196   ARG_EXTENSION,
197   ARG_STRICT_ISO,
198   ARG_DISABLE_RESERVOIR,
199   ARG_VBR,
200   ARG_VBR_MEAN_BITRATE,
201   ARG_VBR_MIN_BITRATE,
202   ARG_VBR_MAX_BITRATE,
203   ARG_VBR_HARD_MIN,
204   ARG_LOWPASS_FREQ,
205   ARG_LOWPASS_WIDTH,
206   ARG_HIGHPASS_FREQ,
207   ARG_HIGHPASS_WIDTH,
208   ARG_ATH_ONLY,
209   ARG_ATH_SHORT,
210   ARG_NO_ATH,
211   ARG_ATH_LOWER,
212   ARG_CWLIMIT,
213   ARG_ALLOW_DIFF_SHORT,
214   ARG_NO_SHORT_BLOCKS,
215   ARG_EMPHASIS,
216   ARG_VBR_QUALITY,
217 #ifdef GSTLAME_PRESET
218   ARG_XINGHEADER,
219   ARG_PRESET
220 #else
221   ARG_XINGHEADER
222 #endif
223 };
224
225 static void gst_lame_base_init (gpointer g_class);
226 static void gst_lame_class_init (GstLameClass * klass);
227 static void gst_lame_init (GstLame * gst_lame);
228
229 static void gst_lame_set_property (GObject * object, guint prop_id,
230     const GValue * value, GParamSpec * pspec);
231 static void gst_lame_get_property (GObject * object, guint prop_id,
232     GValue * value, GParamSpec * pspec);
233 static gboolean gst_lame_sink_event (GstPad * pad, GstEvent * event);
234 static GstFlowReturn gst_lame_chain (GstPad * pad, GstBuffer * buf);
235 static gboolean gst_lame_setup (GstLame * lame);
236 static GstElementStateReturn gst_lame_change_state (GstElement * element);
237
238 static GstElementClass *parent_class = NULL;
239
240 /* static guint gst_lame_signals[LAST_SIGNAL] = { 0 }; */
241
242 GType
243 gst_lame_get_type (void)
244 {
245   static GType gst_lame_type = 0;
246
247   if (!gst_lame_type) {
248     static const GTypeInfo gst_lame_info = {
249       sizeof (GstLameClass),
250       gst_lame_base_init,
251       NULL,
252       (GClassInitFunc) gst_lame_class_init,
253       NULL,
254       NULL,
255       sizeof (GstLame),
256       0,
257       (GInstanceInitFunc) gst_lame_init,
258     };
259
260     static const GInterfaceInfo tag_setter_info = {
261       NULL,
262       NULL,
263       NULL
264     };
265
266     gst_lame_type =
267         g_type_register_static (GST_TYPE_ELEMENT, "GstLame", &gst_lame_info, 0);
268     g_type_add_interface_static (gst_lame_type, GST_TYPE_TAG_SETTER,
269         &tag_setter_info);
270
271   }
272   return gst_lame_type;
273 }
274
275 static void
276 gst_lame_base_init (gpointer g_class)
277 {
278   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
279
280   gst_element_class_add_pad_template (element_class,
281       gst_static_pad_template_get (&gst_lame_src_template));
282   gst_element_class_add_pad_template (element_class,
283       gst_static_pad_template_get (&gst_lame_sink_template));
284   gst_element_class_set_details (element_class, &gst_lame_details);
285 }
286
287 static void
288 gst_lame_class_init (GstLameClass * klass)
289 {
290   GObjectClass *gobject_class;
291   GstElementClass *gstelement_class;
292
293   gobject_class = (GObjectClass *) klass;
294   gstelement_class = (GstElementClass *) klass;
295
296   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
297
298   gobject_class->set_property = gst_lame_set_property;
299   gobject_class->get_property = gst_lame_get_property;
300
301   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
302       g_param_spec_int ("bitrate", "Bitrate (kb/s)", "Bitrate in kbit/sec",
303           8, 320, 128, G_PARAM_READWRITE));
304   /* compression ratio set to 0.0 by default otherwise it overrides the bitrate setting */
305   g_object_class_install_property (G_OBJECT_CLASS (klass),
306       ARG_COMPRESSION_RATIO, g_param_spec_float ("compression_ratio",
307           "Compression Ratio",
308           "let lame choose bitrate to achieve selected compression ratio", 0.0,
309           200.0, 0.0, G_PARAM_READWRITE));
310   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
311       g_param_spec_enum ("quality", "Quality",
312           "Quality of algorithm used for encoding", GST_TYPE_LAME_QUALITY, 5,
313           G_PARAM_READWRITE));
314   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
315       g_param_spec_enum ("mode", "Mode", "Encoding mode", GST_TYPE_LAME_MODE, 0,
316           G_PARAM_READWRITE));
317   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FORCE_MS,
318       g_param_spec_boolean ("force_ms", "Force ms",
319           "Force ms_stereo on all frames", TRUE, G_PARAM_READWRITE));
320   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREE_FORMAT,
321       g_param_spec_boolean ("free_format", "Free format",
322           "Produce a free format bitstream", TRUE, G_PARAM_READWRITE));
323   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COPYRIGHT,
324       g_param_spec_boolean ("copyright", "Copyright", "Mark as copyright", TRUE,
325           G_PARAM_READWRITE));
326   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ORIGINAL,
327       g_param_spec_boolean ("original", "Original", "Mark as non-original",
328           TRUE, G_PARAM_READWRITE));
329   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_PROTECTION,
330       g_param_spec_boolean ("error_protection", "Error protection",
331           "Adds 16 bit checksum to every frame", TRUE, G_PARAM_READWRITE));
332   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PADDING_TYPE,
333       g_param_spec_enum ("padding_type", "Padding type", "Padding type",
334           GST_TYPE_LAME_PADDING, 0, G_PARAM_READWRITE));
335   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EXTENSION,
336       g_param_spec_boolean ("extension", "Extension", "Extension", TRUE,
337           G_PARAM_READWRITE));
338   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STRICT_ISO,
339       g_param_spec_boolean ("strict_iso", "Strict ISO",
340           "Comply as much as possible to ISO MPEG spec", TRUE,
341           G_PARAM_READWRITE));
342   g_object_class_install_property (G_OBJECT_CLASS (klass),
343       ARG_DISABLE_RESERVOIR, g_param_spec_boolean ("disable_reservoir",
344           "Disable reservoir", "Disable the bit reservoir", TRUE,
345           G_PARAM_READWRITE));
346   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
347       g_param_spec_enum ("vbr", "VBR", "Specify bitrate mode",
348           GST_TYPE_LAME_VBRMODE, vbr_off, G_PARAM_READWRITE));
349   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_QUALITY,
350       g_param_spec_enum ("vbr_quality", "VBR Quality", "VBR Quality",
351           GST_TYPE_LAME_QUALITY, 5, G_PARAM_READWRITE));
352   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MEAN_BITRATE,
353       g_param_spec_int ("vbr_mean_bitrate", "VBR mean bitrate",
354           "Specify mean bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
355   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MIN_BITRATE,
356       g_param_spec_int ("vbr_min_bitrate", "VBR min bitrate",
357           "Specify min bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
358   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MAX_BITRATE,
359       g_param_spec_int ("vbr_max_bitrate", "VBR max bitrate",
360           "Specify max bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
361   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_HARD_MIN,
362       g_param_spec_int ("vbr_hard_min", "VBR hard min",
363           "Specify hard min bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
364   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_FREQ,
365       g_param_spec_int ("lowpass_freq", "Lowpass freq",
366           "frequency(kHz), lowpass filter cutoff above freq", 0, 50000, 0,
367           G_PARAM_READWRITE));
368   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_WIDTH,
369       g_param_spec_int ("lowpass_width", "Lowpass width",
370           "frequency(kHz) - default 15% of lowpass freq", 0, G_MAXINT, 0,
371           G_PARAM_READWRITE));
372   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_FREQ,
373       g_param_spec_int ("highpass_freq", "Highpass freq",
374           "frequency(kHz), highpass filter cutoff below freq", 0, 50000, 0,
375           G_PARAM_READWRITE));
376   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_WIDTH,
377       g_param_spec_int ("highpass_width", "Highpass width",
378           "frequency(kHz) - default 15% of highpass freq", 0, G_MAXINT, 0,
379           G_PARAM_READWRITE));
380   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_ONLY,
381       g_param_spec_boolean ("ath_only", "ATH only",
382           "Ignore GPSYCHO completely, use ATH only", TRUE, G_PARAM_READWRITE));
383   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_SHORT,
384       g_param_spec_boolean ("ath_short", "ATH short",
385           "Ignore GPSYCHO for short blocks, use ATH only", TRUE,
386           G_PARAM_READWRITE));
387   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_ATH,
388       g_param_spec_boolean ("no_ath", "No ath",
389           "turns ATH down to a flat noise floor", TRUE, G_PARAM_READWRITE));
390   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_LOWER,
391       g_param_spec_int ("ath_lower", "ATH lower", "lowers ATH by x dB",
392           G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
393   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CWLIMIT,
394       g_param_spec_int ("cwlimit", "Cwlimit",
395           "Compute tonality up to freq (in kHz) default 8.8717", 0, 50000, 0,
396           G_PARAM_READWRITE));
397   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ALLOW_DIFF_SHORT,
398       g_param_spec_boolean ("allow_diff_short", "Allow diff short",
399           "Allow diff short", TRUE, G_PARAM_READWRITE));
400   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_SHORT_BLOCKS,
401       g_param_spec_boolean ("no_short_blocks", "No short blocks",
402           "Do not use short blocks", TRUE, G_PARAM_READWRITE));
403   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EMPHASIS,
404       g_param_spec_boolean ("emphasis", "Emphasis", "Emphasis", TRUE,
405           G_PARAM_READWRITE));
406   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_XINGHEADER,
407       g_param_spec_boolean ("xingheader", "Output Xing Header",
408           "Output Xing Header", FALSE, G_PARAM_READWRITE));
409 #ifdef GSTLAME_PRESET
410   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PRESET,
411       g_param_spec_enum ("preset", "Lame Preset", "Lame Preset",
412           GST_TYPE_LAME_PRESET, 0, G_PARAM_READWRITE));
413 #endif
414
415   gstelement_class->change_state = gst_lame_change_state;
416 }
417
418 static GstCaps *
419 gst_lame_src_getcaps (GstPad * pad)
420 {
421   GstLame *lame;
422   GstCaps *caps;
423
424   lame = GST_LAME (gst_pad_get_parent (pad));
425
426   if (!gst_lame_setup (lame)) {
427     GST_DEBUG_OBJECT (lame, "problem doing lame setup");
428     caps =
429         gst_caps_copy (gst_pad_template_get_caps (gst_static_pad_template_get
430             (&gst_lame_src_template)));
431   } else {
432     caps = gst_caps_new_simple ("audio/mpeg",
433         "mpegversion", G_TYPE_INT, 1,
434         "layer", G_TYPE_INT, 3,
435         "rate", G_TYPE_INT, lame_get_out_samplerate (lame->lgf),
436         "channels", G_TYPE_INT, lame->num_channels, NULL);
437   }
438
439   gst_object_unref (lame);
440
441   return caps;
442 }
443
444 #if 0
445 static gboolean
446 gst_lame_src_setcaps (GstPad * pad, GstCaps * caps)
447 {
448   GstLame *lame;
449   gint out_samplerate;
450   GstStructure *structure;
451   GstCaps *othercaps, *channelcaps;
452   GstPadLinkReturn result;
453
454   lame = GST_LAME (GST_PAD_PARENT (pad));
455   structure = gst_caps_get_structure (caps, 0);
456
457   /* we need channels and rate */
458   if (!gst_structure_get_int (structure, "rate", &out_samplerate));
459   goto no_rate;
460   if (!gst_structure_get_int (structure, "channels", &lame->num_channels));
461   goto no_channels;
462
463   if (lame_set_out_samplerate (lame->lgf, out_samplerate) != 0)
464     goto could_not_set_samplerate;
465
466   /* we don't do channel conversion */
467   channelcaps = gst_caps_new_simple ("audio/x-raw-int", "channels", G_TYPE_INT,
468       lame->num_channels, NULL);
469   othercaps = gst_caps_intersect (gst_pad_get_pad_template_caps (lame->sinkpad),
470       channelcaps);
471   gst_caps_free (channelcaps);
472
473   result = gst_pad_try_set_caps_nonfixed (lame->sinkpad, othercaps);
474
475   if (GST_PAD_LINK_FAILED (result))
476     return result;
477
478   caps = gst_pad_get_negotiated_caps (lame->sinkpad);
479   structure = gst_caps_get_structure (caps, 0);
480   if (!gst_structure_get_int (structure, "rate", &lame->samplerate))
481     g_return_val_if_reached (GST_PAD_LINK_REFUSED);
482
483   if (!gst_lame_setup (lame)) {
484     GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
485         ("could not initialize encoder (wrong parameters?)"));
486     return GST_PAD_LINK_REFUSED;
487   }
488
489   return result;
490
491 no_rate:
492   {
493     GST_DEBUG ("no rate specified in caps");
494     return FALSE;
495   }
496 no_channels:
497   {
498     GST_DEBUG ("no channels specified in caps");
499     return FALSE;
500   }
501 could_not_set_samplerate:
502   {
503     GST_DEBUG ("could not set samplerate");
504     return FALSE;
505   }
506 }
507 #endif
508
509 static gboolean
510 gst_lame_sink_setcaps (GstPad * pad, GstCaps * caps)
511 {
512   GstLame *lame;
513   gint out_samplerate;
514   GstStructure *structure;
515   GstCaps *othercaps;
516
517   lame = GST_LAME (gst_pad_get_parent (pad));
518   structure = gst_caps_get_structure (caps, 0);
519
520   if (!gst_structure_get_int (structure, "rate", &lame->samplerate))
521     goto no_rate;
522   if (!gst_structure_get_int (structure, "channels", &lame->num_channels))
523     goto no_channels;
524
525   /* let lame choose a default samplerate */
526   lame_set_out_samplerate (lame->lgf, 0);
527   if (!gst_lame_setup (lame))
528     goto setup_failed;
529
530   out_samplerate = lame_get_out_samplerate (lame->lgf);
531   othercaps =
532       gst_caps_new_simple ("audio/mpeg",
533       "mpegversion", G_TYPE_INT, 1,
534       "layer", G_TYPE_INT, 3,
535       "channels", G_TYPE_INT, lame->num_channels,
536       "rate", G_TYPE_INT, out_samplerate, NULL);
537
538   /* and use these caps */
539   gst_pad_set_caps (lame->srcpad, othercaps);
540   gst_caps_unref (othercaps);
541
542   return TRUE;
543
544 no_rate:
545   {
546     GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
547         ("no rate specified in input"));
548     return FALSE;
549   }
550 no_channels:
551   {
552     GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
553         ("no channels specified in input"));
554     return FALSE;
555   }
556 setup_failed:
557   {
558     GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
559         ("could not initialize encoder (wrong parameters?)"));
560     return FALSE;
561   }
562 }
563
564 static void
565 gst_lame_init (GstLame * lame)
566 {
567   GST_DEBUG_OBJECT (lame, "starting initialization");
568
569   lame->sinkpad =
570       gst_pad_new_from_template (gst_static_pad_template_get
571       (&gst_lame_sink_template), "sink");
572   gst_pad_set_event_function (lame->sinkpad, gst_lame_sink_event);
573   gst_pad_set_chain_function (lame->sinkpad, gst_lame_chain);
574   gst_pad_set_setcaps_function (lame->sinkpad, gst_lame_sink_setcaps);
575   gst_element_add_pad (GST_ELEMENT (lame), lame->sinkpad);
576
577   lame->srcpad =
578       gst_pad_new_from_template (gst_static_pad_template_get
579       (&gst_lame_src_template), "src");
580   gst_pad_set_getcaps_function (lame->srcpad, gst_lame_src_getcaps);
581   gst_element_add_pad (GST_ELEMENT (lame), lame->srcpad);
582
583   GST_DEBUG ("setting up lame encoder");
584   lame->lgf = lame_init ();
585
586   lame->samplerate = 44100;
587   lame->num_channels = 2;
588   lame->initialized = FALSE;
589
590   lame->bitrate = 128;          /* lame_get_brate (lame->lgf); => 0/out of range */
591   lame->compression_ratio = 0.0;        /* lame_get_compression_ratio (lame->lgf); => 0/out of range ... NOTE: 0.0 makes bitrate take precedence */
592   lame->quality = 5;            /* lame_get_quality (lame->lgf); => -1/out of range */
593   lame->mode = lame_get_mode (lame->lgf);
594   lame->force_ms = lame_get_force_ms (lame->lgf);
595   lame->free_format = lame_get_free_format (lame->lgf);
596   lame->copyright = lame_get_copyright (lame->lgf);
597   lame->original = lame_get_original (lame->lgf);
598   lame->error_protection = lame_get_error_protection (lame->lgf);
599   lame->padding_type = lame_get_padding_type (lame->lgf);
600   lame->extension = lame_get_extension (lame->lgf);
601   lame->strict_iso = lame_get_strict_ISO (lame->lgf);
602   lame->disable_reservoir = lame_get_disable_reservoir (lame->lgf);
603   lame->vbr = vbr_off;          /* lame_get_VBR (lame->lgf); */
604   lame->vbr_quality = 5;
605   lame->vbr_mean_bitrate = lame_get_VBR_mean_bitrate_kbps (lame->lgf);
606   lame->vbr_min_bitrate = lame_get_VBR_min_bitrate_kbps (lame->lgf);
607   lame->vbr_max_bitrate = 320;  /* lame_get_VBR_max_bitrate_kbps (lame->lgf); => 0/no vbr possible */
608   lame->vbr_hard_min = lame_get_VBR_hard_min (lame->lgf);
609   //lame->lowpass_freq = 50000;   /* lame_get_lowpassfreq (lame->lgf); => 0/lowpass on everything ? */
610   lame->lowpass_freq = 0;
611   lame->lowpass_width = 0;      /* lame_get_lowpasswidth (lame->lgf); => -1/out of range */
612   lame->highpass_freq = lame_get_highpassfreq (lame->lgf);
613   lame->highpass_width = 0;     /* lame_get_highpasswidth (lame->lgf); => -1/out of range */
614   lame->ath_only = lame_get_ATHonly (lame->lgf);
615   lame->ath_short = lame_get_ATHshort (lame->lgf);
616   lame->no_ath = lame_get_noATH (lame->lgf);
617   /*  lame->ath_type = lame_get_ATHtype (lame->lgf); */
618   lame->ath_lower = lame_get_ATHlower (lame->lgf);
619   lame->cwlimit = 8.8717;       /* lame_get_cwlimit (lame->lgf); => 0 */
620   lame->allow_diff_short = lame_get_allow_diff_short (lame->lgf);
621   lame->no_short_blocks = TRUE; /* lame_get_no_short_blocks (lame->lgf); */
622   lame->emphasis = lame_get_emphasis (lame->lgf);
623   lame->xingheader = FALSE;
624   lame->preset = 0;
625   lame->tags = gst_tag_list_new ();
626
627   id3tag_init (lame->lgf);
628
629   GST_DEBUG_OBJECT (lame, "done initializing");
630 }
631
632 typedef struct _GstLameTagMatch GstLameTagMatch;
633 typedef void (*GstLameTagFunc) (lame_global_flags * gfp, const char *value);
634
635 struct _GstLameTagMatch
636 {
637   gchar *gstreamer_tag;
638   GstLameTagFunc tag_func;
639 };
640
641 static GstLameTagMatch tag_matches[] = {
642   {GST_TAG_TITLE, id3tag_set_title},
643   {GST_TAG_DATE, id3tag_set_year},
644   {GST_TAG_TRACK_NUMBER, id3tag_set_track},
645   {GST_TAG_COMMENT, id3tag_set_comment},
646   {GST_TAG_ARTIST, id3tag_set_artist},
647   {GST_TAG_ALBUM, id3tag_set_album},
648   {GST_TAG_GENRE, (GstLameTagFunc) id3tag_set_genre},
649   {NULL, NULL}
650 };
651
652 static void
653 add_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data)
654 {
655   GstLame *lame;
656   gchar *value;
657   int i = 0;
658
659   lame = GST_LAME (user_data);
660   g_return_if_fail (lame != NULL);
661
662   while (tag_matches[i].gstreamer_tag != NULL) {
663     if (strcmp (tag, tag_matches[i].gstreamer_tag) == 0) {
664       break;
665     }
666     i++;
667   }
668
669   if (tag_matches[i].tag_func == NULL) {
670     g_print ("Couldn't find matching gstreamer tag for %s\n", tag);
671     return;
672   }
673
674   switch (gst_tag_get_type (tag)) {
675     case G_TYPE_UINT:{
676       guint ivalue;
677
678       if (!gst_tag_list_get_uint (list, tag, &ivalue)) {
679         GST_DEBUG ("Error reading \"%s\" tag value\n", tag);
680         return;
681       }
682       value = g_strdup_printf ("%u", ivalue);
683       break;
684     }
685     case G_TYPE_STRING:
686       if (!gst_tag_list_get_string (list, tag, &value)) {
687         GST_DEBUG ("Error reading \"%s\" tag value\n", tag);
688         return;
689       };
690       break;
691     default:
692       GST_DEBUG ("Couldn't write tag %s", tag);
693       break;
694   }
695
696   tag_matches[i].tag_func (lame->lgf, value);
697
698   if (gst_tag_get_type (tag) == G_TYPE_UINT) {
699     g_free (value);
700   }
701 }
702
703 static void
704 gst_lame_set_metadata (GstLame * lame)
705 {
706   const GstTagList *user_tags;
707   GstTagList *copy;
708
709   g_return_if_fail (lame != NULL);
710   user_tags = gst_tag_setter_get_list (GST_TAG_SETTER (lame));
711   if ((lame->tags == NULL) && (user_tags == NULL)) {
712     return;
713   }
714   copy = gst_tag_list_merge (user_tags, lame->tags,
715       gst_tag_setter_get_merge_mode (GST_TAG_SETTER (lame)));
716   gst_tag_list_foreach ((GstTagList *) copy, add_one_tag, lame);
717
718   gst_tag_list_free (copy);
719 }
720
721
722
723 static void
724 gst_lame_set_property (GObject * object, guint prop_id, const GValue * value,
725     GParamSpec * pspec)
726 {
727   GstLame *lame;
728
729   g_return_if_fail (GST_IS_LAME (object));
730
731   lame = GST_LAME (object);
732
733   switch (prop_id) {
734     case ARG_BITRATE:
735       lame->bitrate = g_value_get_int (value);
736       break;
737     case ARG_COMPRESSION_RATIO:
738       lame->compression_ratio = g_value_get_float (value);
739       break;
740     case ARG_QUALITY:
741       lame->quality = g_value_get_enum (value);
742       break;
743     case ARG_MODE:
744       lame->mode = g_value_get_enum (value);
745       break;
746     case ARG_FORCE_MS:
747       lame->force_ms = g_value_get_boolean (value);
748       break;
749     case ARG_FREE_FORMAT:
750       lame->free_format = g_value_get_boolean (value);
751       break;
752     case ARG_COPYRIGHT:
753       lame->copyright = g_value_get_boolean (value);
754       break;
755     case ARG_ORIGINAL:
756       lame->original = g_value_get_boolean (value);
757       break;
758     case ARG_ERROR_PROTECTION:
759       lame->error_protection = g_value_get_boolean (value);
760       break;
761     case ARG_PADDING_TYPE:
762       lame->padding_type = g_value_get_int (value);
763       break;
764     case ARG_EXTENSION:
765       lame->extension = g_value_get_boolean (value);
766       break;
767     case ARG_STRICT_ISO:
768       lame->strict_iso = g_value_get_boolean (value);
769       break;
770     case ARG_DISABLE_RESERVOIR:
771       lame->disable_reservoir = g_value_get_boolean (value);
772       break;
773     case ARG_VBR:
774       lame->vbr = g_value_get_enum (value);
775       break;
776     case ARG_VBR_QUALITY:
777       lame->vbr_quality = g_value_get_enum (value);
778       break;
779     case ARG_VBR_MEAN_BITRATE:
780       lame->vbr_mean_bitrate = g_value_get_int (value);
781       break;
782     case ARG_VBR_MIN_BITRATE:
783       lame->vbr_min_bitrate = g_value_get_int (value);
784       break;
785     case ARG_VBR_MAX_BITRATE:
786       lame->vbr_max_bitrate = g_value_get_int (value);
787       break;
788     case ARG_VBR_HARD_MIN:
789       lame->vbr_hard_min = g_value_get_int (value);
790       break;
791     case ARG_LOWPASS_FREQ:
792       lame->lowpass_freq = g_value_get_int (value);
793       break;
794     case ARG_LOWPASS_WIDTH:
795       lame->lowpass_width = g_value_get_int (value);
796       break;
797     case ARG_HIGHPASS_FREQ:
798       lame->highpass_freq = g_value_get_int (value);
799       break;
800     case ARG_HIGHPASS_WIDTH:
801       lame->highpass_width = g_value_get_int (value);
802       break;
803     case ARG_ATH_ONLY:
804       lame->ath_only = g_value_get_boolean (value);
805       break;
806     case ARG_ATH_SHORT:
807       lame->ath_short = g_value_get_boolean (value);
808       break;
809     case ARG_NO_ATH:
810       lame->no_ath = g_value_get_boolean (value);
811       break;
812     case ARG_ATH_LOWER:
813       lame->ath_lower = g_value_get_int (value);
814       break;
815     case ARG_CWLIMIT:
816       lame->cwlimit = g_value_get_int (value);
817       break;
818     case ARG_ALLOW_DIFF_SHORT:
819       lame->allow_diff_short = g_value_get_boolean (value);
820       break;
821     case ARG_NO_SHORT_BLOCKS:
822       lame->no_short_blocks = g_value_get_boolean (value);
823       break;
824     case ARG_EMPHASIS:
825       lame->emphasis = g_value_get_boolean (value);
826       break;
827     case ARG_XINGHEADER:
828       lame->xingheader = g_value_get_boolean (value);
829       break;
830 #ifdef GSTLAME_PRESET
831     case ARG_PRESET:
832       lame->preset = g_value_get_enum (value);
833       break;
834 #endif
835     default:
836       break;
837   }
838
839 }
840
841 static void
842 gst_lame_get_property (GObject * object, guint prop_id, GValue * value,
843     GParamSpec * pspec)
844 {
845   GstLame *lame;
846
847   g_return_if_fail (GST_IS_LAME (object));
848
849   lame = GST_LAME (object);
850
851   switch (prop_id) {
852     case ARG_BITRATE:
853       g_value_set_int (value, lame->bitrate);
854       break;
855     case ARG_COMPRESSION_RATIO:
856       g_value_set_float (value, lame->compression_ratio);
857       break;
858     case ARG_QUALITY:
859       g_value_set_enum (value, lame->quality);
860       break;
861     case ARG_MODE:
862       g_value_set_enum (value, lame->mode);
863       break;
864     case ARG_FORCE_MS:
865       g_value_set_boolean (value, lame->force_ms);
866       break;
867     case ARG_FREE_FORMAT:
868       g_value_set_boolean (value, lame->free_format);
869       break;
870     case ARG_COPYRIGHT:
871       g_value_set_boolean (value, lame->copyright);
872       break;
873     case ARG_ORIGINAL:
874       g_value_set_boolean (value, lame->original);
875       break;
876     case ARG_ERROR_PROTECTION:
877       g_value_set_boolean (value, lame->error_protection);
878       break;
879     case ARG_PADDING_TYPE:
880       g_value_set_enum (value, lame->padding_type);
881       break;
882     case ARG_EXTENSION:
883       g_value_set_boolean (value, lame->extension);
884       break;
885     case ARG_STRICT_ISO:
886       g_value_set_boolean (value, lame->strict_iso);
887       break;
888     case ARG_DISABLE_RESERVOIR:
889       g_value_set_boolean (value, lame->disable_reservoir);
890       break;
891     case ARG_VBR:
892       g_value_set_enum (value, lame->vbr);
893       break;
894     case ARG_VBR_QUALITY:
895       g_value_set_enum (value, lame->vbr_quality);
896       break;
897     case ARG_VBR_MEAN_BITRATE:
898       g_value_set_int (value, lame->vbr_mean_bitrate);
899       break;
900     case ARG_VBR_MIN_BITRATE:
901       g_value_set_int (value, lame->vbr_min_bitrate);
902       break;
903     case ARG_VBR_MAX_BITRATE:
904       g_value_set_int (value, lame->vbr_max_bitrate);
905       break;
906     case ARG_VBR_HARD_MIN:
907       g_value_set_int (value, lame->vbr_hard_min);
908       break;
909     case ARG_LOWPASS_FREQ:
910       g_value_set_int (value, lame->lowpass_freq);
911       break;
912     case ARG_LOWPASS_WIDTH:
913       g_value_set_int (value, lame->lowpass_width);
914       break;
915     case ARG_HIGHPASS_FREQ:
916       g_value_set_int (value, lame->highpass_freq);
917       break;
918     case ARG_HIGHPASS_WIDTH:
919       g_value_set_int (value, lame->highpass_width);
920       break;
921     case ARG_ATH_ONLY:
922       g_value_set_boolean (value, lame->ath_only);
923       break;
924     case ARG_ATH_SHORT:
925       g_value_set_boolean (value, lame->ath_short);
926       break;
927     case ARG_NO_ATH:
928       g_value_set_boolean (value, lame->no_ath);
929       break;
930     case ARG_ATH_LOWER:
931       g_value_set_int (value, lame->ath_lower);
932       break;
933     case ARG_CWLIMIT:
934       g_value_set_int (value, lame->cwlimit);
935       break;
936     case ARG_ALLOW_DIFF_SHORT:
937       g_value_set_boolean (value, lame->allow_diff_short);
938       break;
939     case ARG_NO_SHORT_BLOCKS:
940       g_value_set_boolean (value, lame->no_short_blocks);
941       break;
942     case ARG_EMPHASIS:
943       g_value_set_boolean (value, lame->emphasis);
944       break;
945     case ARG_XINGHEADER:
946       g_value_set_boolean (value, lame->xingheader);
947       break;
948 #ifdef GSTLAME_PRESET
949     case ARG_PRESET:
950       g_value_set_enum (value, lame->preset);
951       break;
952 #endif
953     default:
954       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
955       break;
956   }
957 }
958
959 static gboolean
960 gst_lame_sink_event (GstPad * pad, GstEvent * event)
961 {
962   GstLame *lame;
963
964   lame = GST_LAME (gst_pad_get_parent (pad));
965
966   switch (GST_EVENT_TYPE (event)) {
967     case GST_EVENT_EOS:
968       GST_DEBUG_OBJECT (lame, "handling EOS event");
969       /* FIXME, push last data packet */
970
971       gst_pad_push_event (lame->srcpad, event);
972       break;
973     case GST_EVENT_FLUSH_START:
974       GST_DEBUG_OBJECT (lame, "handling FLUSH start event");
975       /* forward event */
976       gst_pad_push_event (lame->srcpad, event);
977
978       /* make streaming stop */
979       GST_STREAM_LOCK (pad);
980       GST_STREAM_UNLOCK (pad);
981       break;
982     case GST_EVENT_FLUSH_STOP:
983     {
984       guchar *mp3_data = NULL;
985       gint mp3_buffer_size, mp3_size = 0;
986
987       GST_DEBUG_OBJECT (lame, "handling FLUSH stop event");
988
989       /* clear buffers */
990       GST_STREAM_LOCK (pad);
991       mp3_buffer_size = 7200;
992       mp3_data = g_malloc (mp3_buffer_size);
993       mp3_size = lame_encode_flush (lame->lgf, mp3_data, mp3_buffer_size);
994
995       gst_pad_push_event (lame->srcpad, event);
996       GST_STREAM_UNLOCK (pad);
997       break;
998     }
999     case GST_EVENT_TAG:
1000       GST_DEBUG_OBJECT (lame, "handling TAG event");
1001       if (lame->tags) {
1002         GstTagList *taglist;
1003
1004         gst_event_parse_tag (event, &taglist),
1005             gst_tag_list_insert (lame->tags, taglist,
1006             gst_tag_setter_get_merge_mode (GST_TAG_SETTER (lame)));
1007       } else {
1008         g_assert_not_reached ();
1009       }
1010       gst_pad_push_event (lame->srcpad, event);
1011       break;
1012     default:
1013       gst_pad_push_event (lame->srcpad, event);
1014       break;
1015   }
1016   return TRUE;
1017 }
1018
1019 static GstFlowReturn
1020 gst_lame_chain (GstPad * pad, GstBuffer * buf)
1021 {
1022   GstLame *lame;
1023   GstBuffer *outbuf;
1024   guchar *mp3_data = NULL;
1025   gint mp3_buffer_size, mp3_size = 0;
1026   gint64 duration;
1027   GstFlowReturn result;
1028
1029   lame = GST_LAME (gst_pad_get_parent (pad));
1030
1031   GST_LOG_OBJECT (lame, "entered chain");
1032
1033   if (!lame->initialized)
1034     goto not_initialized;
1035
1036   /* allocate space for output */
1037   mp3_buffer_size =
1038       ((GST_BUFFER_SIZE (buf) / (2 + lame->num_channels)) * 1.25) + 7200;
1039   mp3_data = g_malloc (mp3_buffer_size);
1040
1041   /* lame seems to be too stupid to get mono interleaved going */
1042   if (lame->num_channels == 1) {
1043     mp3_size = lame_encode_buffer (lame->lgf,
1044         (short int *) (GST_BUFFER_DATA (buf)),
1045         (short int *) (GST_BUFFER_DATA (buf)),
1046         GST_BUFFER_SIZE (buf) / 2, mp3_data, mp3_buffer_size);
1047   } else {
1048     mp3_size = lame_encode_buffer_interleaved (lame->lgf,
1049         (short int *) (GST_BUFFER_DATA (buf)),
1050         GST_BUFFER_SIZE (buf) / 2 / lame->num_channels,
1051         mp3_data, mp3_buffer_size);
1052   }
1053
1054   GST_LOG_OBJECT (lame, "encoded %d bytes of audio to %d bytes of mp3",
1055       GST_BUFFER_SIZE (buf), mp3_size);
1056
1057   duration = (GST_SECOND * GST_BUFFER_SIZE (buf) /
1058       (2 * lame->samplerate * lame->num_channels));
1059
1060   if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE &&
1061       GST_BUFFER_DURATION (buf) != duration)
1062     GST_DEBUG_OBJECT (lame, "incoming buffer had incorrect duration %"
1063         GST_TIME_FORMAT "outgoing buffer will have correct duration %"
1064         GST_TIME_FORMAT,
1065         GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_TIME_ARGS (duration));
1066
1067   if (lame->last_ts == GST_CLOCK_TIME_NONE) {
1068     lame->last_ts = GST_BUFFER_TIMESTAMP (buf);
1069     lame->last_offs = GST_BUFFER_OFFSET (buf);
1070     lame->last_duration = duration;
1071   } else {
1072     lame->last_duration += duration;
1073   }
1074
1075   gst_buffer_unref (buf);
1076
1077   if (mp3_size > 0) {
1078     outbuf = gst_buffer_new ();
1079     GST_BUFFER_DATA (outbuf) = mp3_data;
1080     GST_BUFFER_SIZE (outbuf) = mp3_size;
1081     GST_BUFFER_TIMESTAMP (outbuf) = lame->last_ts;
1082     GST_BUFFER_OFFSET (outbuf) = lame->last_offs;
1083     GST_BUFFER_DURATION (outbuf) = lame->last_duration;
1084
1085     result = gst_pad_push (lame->srcpad, outbuf);
1086
1087     lame->last_ts = GST_CLOCK_TIME_NONE;
1088   } else {
1089     g_free (mp3_data);
1090     result = GST_FLOW_OK;
1091   }
1092   gst_object_unref (lame);
1093
1094   return result;
1095
1096   /* ERRORS */
1097 not_initialized:
1098   {
1099     gst_buffer_unref (buf);
1100     GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
1101         ("encoder not initialized (input is not audio?)"));
1102     gst_object_unref (lame);
1103     return GST_FLOW_ERROR;
1104   }
1105 }
1106
1107 /* transition to the READY state by configuring the gst_lame encoder */
1108 static gboolean
1109 gst_lame_setup (GstLame * lame)
1110 {
1111 #define CHECK_ERROR(command) G_STMT_START {\
1112   if ((command) < 0) { \
1113     GST_ERROR_OBJECT (lame, "setup failed: " G_STRINGIFY (command)); \
1114     return FALSE; \
1115   } \
1116 }G_STMT_END
1117   int retval;
1118
1119   GST_DEBUG_OBJECT (lame, "starting setup");
1120
1121   /* check if we're already initialized; if we are, we might want to check
1122    * if this initialization is compatible with the previous one */
1123   /* FIXME: do this */
1124   if (lame->initialized) {
1125     GST_WARNING_OBJECT (lame, "already initialized");
1126     lame->initialized = FALSE;
1127   }
1128
1129   /* copy the parameters over */
1130   lame_set_in_samplerate (lame->lgf, lame->samplerate);
1131
1132   /* force mono encoding if we only have one channel */
1133   if (lame->num_channels == 1)
1134     lame->mode = 3;
1135
1136   CHECK_ERROR (lame_set_num_channels (lame->lgf, lame->num_channels));
1137   CHECK_ERROR (lame_set_brate (lame->lgf, lame->bitrate));
1138   CHECK_ERROR (lame_set_compression_ratio (lame->lgf, lame->compression_ratio));
1139   CHECK_ERROR (lame_set_quality (lame->lgf, lame->quality));
1140   CHECK_ERROR (lame_set_mode (lame->lgf, lame->mode));
1141   CHECK_ERROR (lame_set_force_ms (lame->lgf, lame->force_ms));
1142   CHECK_ERROR (lame_set_free_format (lame->lgf, lame->free_format));
1143   CHECK_ERROR (lame_set_copyright (lame->lgf, lame->copyright));
1144   CHECK_ERROR (lame_set_original (lame->lgf, lame->original));
1145   CHECK_ERROR (lame_set_error_protection (lame->lgf, lame->error_protection));
1146   CHECK_ERROR (lame_set_padding_type (lame->lgf, lame->padding_type));
1147   CHECK_ERROR (lame_set_extension (lame->lgf, lame->extension));
1148   CHECK_ERROR (lame_set_strict_ISO (lame->lgf, lame->strict_iso));
1149   CHECK_ERROR (lame_set_disable_reservoir (lame->lgf, lame->disable_reservoir));
1150   CHECK_ERROR (lame_set_VBR (lame->lgf, lame->vbr));
1151   CHECK_ERROR (lame_set_VBR_q (lame->lgf, lame->vbr_quality));
1152   CHECK_ERROR (lame_set_VBR_mean_bitrate_kbps (lame->lgf,
1153           lame->vbr_mean_bitrate));
1154   CHECK_ERROR (lame_set_VBR_min_bitrate_kbps (lame->lgf,
1155           lame->vbr_min_bitrate));
1156   CHECK_ERROR (lame_set_VBR_max_bitrate_kbps (lame->lgf,
1157           lame->vbr_max_bitrate));
1158   CHECK_ERROR (lame_set_VBR_hard_min (lame->lgf, lame->vbr_hard_min));
1159   CHECK_ERROR (lame_set_lowpassfreq (lame->lgf, lame->lowpass_freq));
1160   CHECK_ERROR (lame_set_lowpasswidth (lame->lgf, lame->lowpass_width));
1161   CHECK_ERROR (lame_set_highpassfreq (lame->lgf, lame->highpass_freq));
1162   CHECK_ERROR (lame_set_highpasswidth (lame->lgf, lame->highpass_width));
1163   CHECK_ERROR (lame_set_ATHonly (lame->lgf, lame->ath_only));
1164   CHECK_ERROR (lame_set_ATHshort (lame->lgf, lame->ath_short));
1165   CHECK_ERROR (lame_set_noATH (lame->lgf, lame->no_ath));
1166   CHECK_ERROR (lame_set_ATHlower (lame->lgf, lame->ath_lower));
1167   CHECK_ERROR (lame_set_cwlimit (lame->lgf, lame->cwlimit));
1168   CHECK_ERROR (lame_set_allow_diff_short (lame->lgf, lame->allow_diff_short));
1169   CHECK_ERROR (lame_set_no_short_blocks (lame->lgf, lame->no_short_blocks));
1170   CHECK_ERROR (lame_set_emphasis (lame->lgf, lame->emphasis));
1171   CHECK_ERROR (lame_set_bWriteVbrTag (lame->lgf, lame->xingheader ? 1 : 0));
1172 #ifdef GSTLAME_PRESET
1173   if (lame->preset > 0) {
1174     CHECK_ERROR (lame_set_preset (lame->lgf, lame->preset));
1175   }
1176 #endif
1177   gst_lame_set_metadata (lame);
1178
1179   /* initialize the lame encoder */
1180   if ((retval = lame_init_params (lame->lgf)) >= 0) {
1181     lame->initialized = TRUE;
1182     /* FIXME: it would be nice to print out the mode here */
1183     GST_INFO ("lame encoder initialized (%d kbit/s, %d Hz, %d channels)",
1184         lame->bitrate, lame->samplerate, lame->num_channels);
1185   } else {
1186     GST_ERROR_OBJECT (lame, "lame_init_params returned %d", retval);
1187   }
1188
1189   GST_DEBUG_OBJECT (lame, "done with setup");
1190
1191   return lame->initialized;
1192 #undef CHECK_ERROR
1193 }
1194
1195 static GstElementStateReturn
1196 gst_lame_change_state (GstElement * element)
1197 {
1198   GstLame *lame;
1199   gint transition;
1200   GstElementStateReturn result;
1201
1202   lame = GST_LAME (element);
1203
1204   transition = GST_STATE_TRANSITION (lame);
1205
1206   switch (transition) {
1207     case GST_STATE_READY_TO_PAUSED:
1208       lame->last_ts = GST_CLOCK_TIME_NONE;
1209       break;
1210     default:
1211       break;
1212   }
1213
1214   /* if we haven't failed already, give the parent class a chance to ;-) */
1215   result = GST_ELEMENT_CLASS (parent_class)->change_state (element);
1216
1217   switch (transition) {
1218     case GST_STATE_PAUSED_TO_READY:
1219       if (lame->initialized) {
1220         lame_close (lame->lgf);
1221         lame->lgf = lame_init ();
1222         lame->initialized = FALSE;
1223       }
1224       break;
1225     default:
1226       break;
1227   }
1228
1229   return result;
1230 }
1231
1232 static gboolean
1233 plugin_init (GstPlugin * plugin)
1234 {
1235   if (!gst_element_register (plugin, "lame", GST_RANK_NONE, GST_TYPE_LAME))
1236     return FALSE;
1237
1238   GST_DEBUG_CATEGORY_INIT (debug, "lame", 0, "lame mp3 encoder");
1239   return TRUE;
1240 }
1241
1242 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1243     GST_VERSION_MINOR,
1244     "lame",
1245     "Encode MP3's with LAME",
1246     plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)