sync mp3 caps
[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 /* elementfactory information */
27 static GstElementDetails gst_lame_details = {
28   "L.A.M.E. mp3 encoder",
29   "Codec/Encoder/Audio",
30   "High-quality free MP3 encoder",
31   "Erik Walthinsen <omega@cse.ogi.edu>",
32 };
33
34 /* LAME can do MPEG-1, MPEG-2, and MPEG-2.5, so it has 9 possible
35  * sample rates it supports */
36 static GstStaticPadTemplate gst_lame_sink_template =
37 GST_STATIC_PAD_TEMPLATE ("sink",
38     GST_PAD_SINK,
39     GST_PAD_ALWAYS,
40     GST_STATIC_CAPS ("audio/x-raw-int, "
41         "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", "
42         "signed = (boolean) true, "
43         "width = (int) 16, "
44         "depth = (int) 16, "
45         "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
46         "channels = (int) [ 1, 2 ]")
47     );
48
49 static GstStaticPadTemplate gst_lame_src_template =
50 GST_STATIC_PAD_TEMPLATE ("src",
51     GST_PAD_SRC,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("audio/mpeg, "
54         "mpegversion = (int) 1, "
55         "layer = (int) 3, "
56         "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
57         "channels = (int) [ 1, 2 ]")
58     );
59
60 /********** Define useful types for non-programmatic interfaces **********/
61 #define GST_TYPE_LAME_MODE (gst_lame_mode_get_type())
62 static GType
63 gst_lame_mode_get_type (void)
64 {
65   static GType lame_mode_type = 0;
66   static GEnumValue lame_modes[] = {
67     {0, "0", "Stereo"},
68     {1, "1", "Joint-Stereo"},
69     {2, "2", "Dual channel"},
70     {3, "3", "Mono"},
71     {4, "4", "Auto"},
72     {0, NULL, NULL},
73   };
74
75   if (!lame_mode_type) {
76     lame_mode_type = g_enum_register_static ("GstLameMode", lame_modes);
77   }
78   return lame_mode_type;
79 }
80
81 #define GST_TYPE_LAME_QUALITY (gst_lame_quality_get_type())
82 static GType
83 gst_lame_quality_get_type (void)
84 {
85   static GType lame_quality_type = 0;
86   static GEnumValue lame_quality[] = {
87     {0, "0", "0 - Best"},
88     {1, "1", "1"},
89     {2, "2", "2"},
90     {3, "3", "3"},
91     {4, "4", "4"},
92     {5, "5", "5 - Default"},
93     {6, "6", "6"},
94     {7, "7", "7"},
95     {8, "8", "8"},
96     {9, "9", "9 - Worst"},
97     {0, NULL, NULL},
98   };
99
100   if (!lame_quality_type) {
101     lame_quality_type = g_enum_register_static ("GstLameQuality", lame_quality);
102   }
103   return lame_quality_type;
104 }
105
106 #define GST_TYPE_LAME_PADDING (gst_lame_padding_get_type())
107 static GType
108 gst_lame_padding_get_type (void)
109 {
110   static GType lame_padding_type = 0;
111   static GEnumValue lame_padding[] = {
112     {0, "0", "No Padding"},
113     {1, "1", "Always Pad"},
114     {2, "2", "Adjust Padding"},
115     {0, NULL, NULL},
116   };
117
118   if (!lame_padding_type) {
119     lame_padding_type = g_enum_register_static ("GstLamePadding", lame_padding);
120   }
121   return lame_padding_type;
122 }
123
124 /********** Standard stuff for signals and arguments **********/
125 /* GstLame signals and args */
126 enum
127 {
128   /* FILL_ME */
129   LAST_SIGNAL
130 };
131
132 enum
133 {
134   ARG_0,
135   ARG_BITRATE,
136   ARG_COMPRESSION_RATIO,
137   ARG_QUALITY,
138   ARG_MODE,
139   ARG_FORCE_MS,
140   ARG_FREE_FORMAT,
141   ARG_COPYRIGHT,
142   ARG_ORIGINAL,
143   ARG_ERROR_PROTECTION,
144   ARG_PADDING_TYPE,
145   ARG_EXTENSION,
146   ARG_STRICT_ISO,
147   ARG_DISABLE_RESERVOIR,
148   ARG_VBR,
149   ARG_VBR_MEAN_BITRATE,
150   ARG_VBR_MIN_BITRATE,
151   ARG_VBR_MAX_BITRATE,
152   ARG_VBR_HARD_MIN,
153   ARG_LOWPASS_FREQ,
154   ARG_LOWPASS_WIDTH,
155   ARG_HIGHPASS_FREQ,
156   ARG_HIGHPASS_WIDTH,
157   ARG_ATH_ONLY,
158   ARG_ATH_SHORT,
159   ARG_NO_ATH,
160   ARG_ATH_LOWER,
161   ARG_CWLIMIT,
162   ARG_ALLOW_DIFF_SHORT,
163   ARG_NO_SHORT_BLOCKS,
164   ARG_EMPHASIS
165 };
166
167 static void gst_lame_base_init (gpointer g_class);
168 static void gst_lame_class_init (GstLameClass * klass);
169 static void gst_lame_init (GstLame * gst_lame);
170
171 static void gst_lame_set_property (GObject * object, guint prop_id,
172     const GValue * value, GParamSpec * pspec);
173 static void gst_lame_get_property (GObject * object, guint prop_id,
174     GValue * value, GParamSpec * pspec);
175 static void gst_lame_chain (GstPad * pad, GstData * _data);
176 static gboolean gst_lame_setup (GstLame * lame);
177 static GstElementStateReturn gst_lame_change_state (GstElement * element);
178
179 static GstElementClass *parent_class = NULL;
180
181 /* static guint gst_lame_signals[LAST_SIGNAL] = { 0 }; */
182
183 GType
184 gst_lame_get_type (void)
185 {
186   static GType gst_lame_type = 0;
187
188   if (!gst_lame_type) {
189     static const GTypeInfo gst_lame_info = {
190       sizeof (GstLameClass),
191       gst_lame_base_init,
192       NULL,
193       (GClassInitFunc) gst_lame_class_init,
194       NULL,
195       NULL,
196       sizeof (GstLame),
197       0,
198       (GInstanceInitFunc) gst_lame_init,
199     };
200
201     static const GInterfaceInfo tag_setter_info = {
202       NULL,
203       NULL,
204       NULL
205     };
206
207     gst_lame_type =
208         g_type_register_static (GST_TYPE_ELEMENT, "GstLame", &gst_lame_info, 0);
209     g_type_add_interface_static (gst_lame_type, GST_TYPE_TAG_SETTER,
210         &tag_setter_info);
211
212   }
213   return gst_lame_type;
214 }
215
216 static void
217 gst_lame_base_init (gpointer g_class)
218 {
219   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
220
221   gst_element_class_add_pad_template (element_class,
222       gst_static_pad_template_get (&gst_lame_src_template));
223   gst_element_class_add_pad_template (element_class,
224       gst_static_pad_template_get (&gst_lame_sink_template));
225   gst_element_class_set_details (element_class, &gst_lame_details);
226 }
227
228 static void
229 gst_lame_class_init (GstLameClass * klass)
230 {
231   GObjectClass *gobject_class;
232   GstElementClass *gstelement_class;
233
234   gobject_class = (GObjectClass *) klass;
235   gstelement_class = (GstElementClass *) klass;
236
237   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
238
239   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
240       g_param_spec_int ("bitrate", "Bitrate (kb/s)", "Bitrate in kbit/sec",
241           8, 320, 128, G_PARAM_READWRITE));
242   g_object_class_install_property (G_OBJECT_CLASS (klass),
243       ARG_COMPRESSION_RATIO, g_param_spec_float ("compression_ratio",
244           "Compression Ratio",
245           "choose bitrate to achive selected compression ratio", 1.0, 200.0,
246           11.0, G_PARAM_READWRITE));
247   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
248       g_param_spec_enum ("quality", "Quality", "Encoding Quality",
249           GST_TYPE_LAME_QUALITY, 5, G_PARAM_READWRITE));
250   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
251       g_param_spec_enum ("mode", "Mode", "Encoding mode", GST_TYPE_LAME_MODE, 0,
252           G_PARAM_READWRITE));
253   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FORCE_MS,
254       g_param_spec_boolean ("force_ms", "Force ms",
255           "Force ms_stereo on all frames", TRUE, G_PARAM_READWRITE));
256   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREE_FORMAT,
257       g_param_spec_boolean ("free_format", "Free format",
258           "Produce a free format bitstream", TRUE, G_PARAM_READWRITE));
259   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COPYRIGHT,
260       g_param_spec_boolean ("copyright", "Copyright", "Mark as copyright", TRUE,
261           G_PARAM_READWRITE));
262   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ORIGINAL,
263       g_param_spec_boolean ("original", "Original", "Mark as non-original",
264           TRUE, G_PARAM_READWRITE));
265   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_PROTECTION,
266       g_param_spec_boolean ("error_protection", "Error protection",
267           "Adds 16 bit checksum to every frame", TRUE, G_PARAM_READWRITE));
268   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PADDING_TYPE,
269       g_param_spec_enum ("padding_type", "Padding type", "Padding type",
270           GST_TYPE_LAME_PADDING, 0, G_PARAM_READWRITE));
271   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EXTENSION,
272       g_param_spec_boolean ("extension", "Extension", "Extension", TRUE,
273           G_PARAM_READWRITE));
274   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STRICT_ISO,
275       g_param_spec_boolean ("strict_iso", "Strict ISO",
276           "Comply as much as possible to ISO MPEG spec", TRUE,
277           G_PARAM_READWRITE));
278   g_object_class_install_property (G_OBJECT_CLASS (klass),
279       ARG_DISABLE_RESERVOIR, g_param_spec_boolean ("disable_reservoir",
280           "Disable reservoir", "Disable the bit reservoir", TRUE,
281           G_PARAM_READWRITE));
282   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
283       g_param_spec_boolean ("vbr", "VBR", "Use variable bitrate", TRUE,
284           G_PARAM_READWRITE));
285   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MEAN_BITRATE,
286       g_param_spec_int ("vbr_mean_bitrate", "VBR mean bitrate",
287           "Specify mean bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
288   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MIN_BITRATE,
289       g_param_spec_int ("vbr_min_bitrate", "VBR min bitrate",
290           "Specify min bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
291   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MAX_BITRATE,
292       g_param_spec_int ("vbr_max_bitrate", "VBR max bitrate",
293           "Specify max bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
294   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_HARD_MIN,
295       g_param_spec_int ("vbr_hard_min", "VBR hard min",
296           "Specify hard min bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
297   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_FREQ,
298       g_param_spec_int ("lowpass_freq", "Lowpass freq",
299           "frequency(kHz), lowpass filter cutoff above freq", 0, 50000, 0,
300           G_PARAM_READWRITE));
301   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_WIDTH,
302       g_param_spec_int ("lowpass_width", "Lowpass width",
303           "frequency(kHz) - default 15% of lowpass freq", 0, G_MAXINT, 0,
304           G_PARAM_READWRITE));
305   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_FREQ,
306       g_param_spec_int ("highpass_freq", "Highpass freq",
307           "frequency(kHz), highpass filter cutoff below freq", 0, 50000, 0,
308           G_PARAM_READWRITE));
309   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_WIDTH,
310       g_param_spec_int ("highpass_width", "Highpass width",
311           "frequency(kHz) - default 15% of highpass freq", 0, G_MAXINT, 0,
312           G_PARAM_READWRITE));
313   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_ONLY,
314       g_param_spec_boolean ("ath_only", "ATH only",
315           "Ignore GPSYCHO completely, use ATH only", TRUE, G_PARAM_READWRITE));
316   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_SHORT,
317       g_param_spec_boolean ("ath_short", "ATH short",
318           "Ignore GPSYCHO for short blocks, use ATH only", TRUE,
319           G_PARAM_READWRITE));
320   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_ATH,
321       g_param_spec_boolean ("no_ath", "No ath",
322           "turns ATH down to a flat noise floor", TRUE, G_PARAM_READWRITE));
323   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_LOWER,
324       g_param_spec_int ("ath_lower", "ATH lower", "lowers ATH by x dB",
325           G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
326   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CWLIMIT,
327       g_param_spec_int ("cwlimit", "Cwlimit",
328           "Compute tonality up to freq (in kHz) default 8.8717", 0, 50000, 0,
329           G_PARAM_READWRITE));
330   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ALLOW_DIFF_SHORT,
331       g_param_spec_boolean ("allow_diff_short", "Allow diff short",
332           "Allow diff short", TRUE, G_PARAM_READWRITE));
333   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_SHORT_BLOCKS,
334       g_param_spec_boolean ("no_short_blocks", "No short blocks",
335           "Do not use short blocks", TRUE, G_PARAM_READWRITE));
336   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EMPHASIS,
337       g_param_spec_boolean ("emphasis", "Emphasis", "Emphasis", TRUE,
338           G_PARAM_READWRITE));
339
340   gobject_class->set_property = gst_lame_set_property;
341   gobject_class->get_property = gst_lame_get_property;
342
343   gstelement_class->change_state = gst_lame_change_state;
344 }
345
346 static GstPadLinkReturn
347 gst_lame_sink_link (GstPad * pad, const GstCaps * caps)
348 {
349   GstLame *lame;
350   gint out_samplerate;
351   GstStructure *structure;
352   GstCaps *othercaps;
353
354   lame = GST_LAME (gst_pad_get_parent (pad));
355   structure = gst_caps_get_structure (caps, 0);
356
357   gst_structure_get_int (structure, "rate", &lame->samplerate);
358   gst_structure_get_int (structure, "channels", &lame->num_channels);
359
360   if (!gst_lame_setup (lame)) {
361     GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
362         ("could not initialize encoder (wrong parameters?)"));
363     return GST_PAD_LINK_REFUSED;
364   }
365
366   out_samplerate = lame_get_out_samplerate (lame->lgf);
367   othercaps =
368       gst_caps_new_simple ("audio/mpeg",
369       "mpegversion", G_TYPE_INT, 1,
370       "layer", G_TYPE_INT, 3,
371       "channels", G_TYPE_INT, lame->num_channels,
372       "rate", G_TYPE_INT, out_samplerate, NULL);
373
374   return gst_pad_try_set_caps (lame->srcpad, othercaps);
375 }
376
377 static void
378 gst_lame_init (GstLame * lame)
379 {
380   GST_DEBUG_OBJECT (lame, "starting initialization");
381
382   lame->sinkpad =
383       gst_pad_new_from_template (gst_static_pad_template_get
384       (&gst_lame_sink_template), "sink");
385   gst_element_add_pad (GST_ELEMENT (lame), lame->sinkpad);
386   gst_pad_set_chain_function (lame->sinkpad, gst_lame_chain);
387   gst_pad_set_link_function (lame->sinkpad, gst_lame_sink_link);
388
389   lame->srcpad =
390       gst_pad_new_from_template (gst_static_pad_template_get
391       (&gst_lame_src_template), "src");
392   gst_element_add_pad (GST_ELEMENT (lame), lame->srcpad);
393
394   GST_FLAG_SET (lame, GST_ELEMENT_EVENT_AWARE);
395
396   GST_DEBUG ("setting up lame encoder");
397   lame->lgf = lame_init ();
398
399   lame->samplerate = 44100;
400   lame->num_channels = 2;
401   lame->initialized = FALSE;
402
403   lame->bitrate = 128;          /* lame_get_brate (lame->lgf); => 0/out of range */
404   lame->compression_ratio = 5;  /* lame_get_compression_ratio (lame->lgf); => 0/out of range */
405   lame->quality = 5;            /* lame_get_quality (lame->lgf); => -1/out of range */
406   lame->mode = lame_get_mode (lame->lgf);
407   lame->force_ms = lame_get_force_ms (lame->lgf);
408   lame->free_format = lame_get_free_format (lame->lgf);
409   lame->copyright = lame_get_copyright (lame->lgf);
410   lame->original = lame_get_original (lame->lgf);
411   lame->error_protection = lame_get_error_protection (lame->lgf);
412   lame->padding_type = lame_get_padding_type (lame->lgf);
413   lame->extension = lame_get_extension (lame->lgf);
414   lame->strict_iso = lame_get_strict_ISO (lame->lgf);
415   lame->disable_reservoir = lame_get_disable_reservoir (lame->lgf);
416   lame->vbr = lame_get_VBR_q (lame->lgf);
417   lame->vbr_mean_bitrate = lame_get_VBR_mean_bitrate_kbps (lame->lgf);
418   lame->vbr_min_bitrate = lame_get_VBR_min_bitrate_kbps (lame->lgf);
419   lame->vbr_max_bitrate = 320;  /* lame_get_VBR_max_bitrate_kbps (lame->lgf); => 0/no vbr possible */
420   lame->vbr_hard_min = lame_get_VBR_hard_min (lame->lgf);
421   lame->lowpass_freq = 50000;   /* lame_get_lowpassfreq (lame->lgf); => 0/lowpass on everything ? */
422   lame->lowpass_width = 0;      /* lame_get_lowpasswidth (lame->lgf); => -1/out of range */
423   lame->highpass_freq = lame_get_highpassfreq (lame->lgf);
424   lame->highpass_width = 0;     /* lame_get_highpasswidth (lame->lgf); => -1/out of range */
425   lame->ath_only = lame_get_ATHonly (lame->lgf);
426   lame->ath_short = lame_get_ATHshort (lame->lgf);
427   lame->no_ath = lame_get_noATH (lame->lgf);
428   /*  lame->ath_type = lame_get_ATHtype (lame->lgf); */
429   lame->ath_lower = lame_get_ATHlower (lame->lgf);
430   lame->cwlimit = 8.8717;       /* lame_get_cwlimit (lame->lgf); => 0 */
431   lame->allow_diff_short = lame_get_allow_diff_short (lame->lgf);
432   lame->no_short_blocks = lame_get_no_short_blocks (lame->lgf);
433   lame->emphasis = lame_get_emphasis (lame->lgf);
434   lame->tags = gst_tag_list_new ();
435
436   id3tag_init (lame->lgf);
437
438   GST_DEBUG_OBJECT (lame, "done initializing");
439 }
440
441 typedef struct _GstLameTagMatch GstLameTagMatch;
442 typedef void (*GstLameTagFunc) (lame_global_flags * gfp, const char *value);
443
444 struct _GstLameTagMatch
445 {
446   gchar *gstreamer_tag;
447   GstLameTagFunc tag_func;
448 };
449
450 static GstLameTagMatch tag_matches[] = {
451   {GST_TAG_TITLE, id3tag_set_title},
452   {GST_TAG_DATE, id3tag_set_year},
453   {GST_TAG_TRACK_NUMBER, id3tag_set_track},
454   {GST_TAG_COMMENT, id3tag_set_comment},
455   {GST_TAG_ARTIST, id3tag_set_artist},
456   {GST_TAG_ALBUM, id3tag_set_album},
457   {GST_TAG_GENRE, (GstLameTagFunc) id3tag_set_genre},
458   {NULL, NULL}
459 };
460
461 static void
462 add_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data)
463 {
464   GstLame *lame;
465   gchar *value;
466   int i = 0;
467
468   lame = GST_LAME (user_data);
469   g_return_if_fail (lame != NULL);
470
471   while (tag_matches[i].gstreamer_tag != NULL) {
472     if (strcmp (tag, tag_matches[i].gstreamer_tag) == 0) {
473       break;
474     }
475     i++;
476   }
477
478   if (tag_matches[i].tag_func == NULL) {
479     g_print ("Couldn't find matching gstreamer tag for %s\n", tag);
480     return;
481   }
482
483   switch (gst_tag_get_type (tag)) {
484     case G_TYPE_UINT:{
485       guint ivalue;
486
487       if (!gst_tag_list_get_uint (list, tag, &ivalue)) {
488         GST_DEBUG ("Error reading \"%s\" tag value\n", tag);
489         return;
490       }
491       value = g_strdup_printf ("%u", ivalue);
492       break;
493     }
494     case G_TYPE_STRING:
495       if (!gst_tag_list_get_string (list, tag, &value)) {
496         GST_DEBUG ("Error reading \"%s\" tag value\n", tag);
497         return;
498       };
499       break;
500     default:
501       GST_DEBUG ("Couldn't write tag %s", tag);
502       break;
503   }
504
505   tag_matches[i].tag_func (lame->lgf, value);
506
507   if (gst_tag_get_type (tag) == G_TYPE_UINT) {
508     g_free (value);
509   }
510 }
511
512 static void
513 gst_lame_set_metadata (GstLame * lame)
514 {
515   const GstTagList *user_tags;
516   GstTagList *copy;
517
518   g_return_if_fail (lame != NULL);
519   user_tags = gst_tag_setter_get_list (GST_TAG_SETTER (lame));
520   if ((lame->tags == NULL) && (user_tags == NULL)) {
521     return;
522   }
523   copy = gst_tag_list_merge (user_tags, lame->tags,
524       gst_tag_setter_get_merge_mode (GST_TAG_SETTER (lame)));
525   gst_tag_list_foreach ((GstTagList *) copy, add_one_tag, lame);
526
527   gst_tag_list_free (copy);
528 }
529
530
531
532 static void
533 gst_lame_set_property (GObject * object, guint prop_id, const GValue * value,
534     GParamSpec * pspec)
535 {
536   GstLame *lame;
537
538   /* it's not null if we got it, but it might not be ours */
539   g_return_if_fail (GST_IS_LAME (object));
540
541   lame = GST_LAME (object);
542
543   switch (prop_id) {
544     case ARG_BITRATE:
545       lame->bitrate = g_value_get_int (value);
546       break;
547     case ARG_COMPRESSION_RATIO:
548       lame->compression_ratio = g_value_get_float (value);
549       break;
550     case ARG_QUALITY:
551       lame->quality = g_value_get_enum (value);
552       break;
553     case ARG_MODE:
554       lame->mode = g_value_get_enum (value);
555       break;
556     case ARG_FORCE_MS:
557       lame->force_ms = g_value_get_boolean (value);
558       break;
559     case ARG_FREE_FORMAT:
560       lame->free_format = g_value_get_boolean (value);
561       break;
562     case ARG_COPYRIGHT:
563       lame->copyright = g_value_get_boolean (value);
564       break;
565     case ARG_ORIGINAL:
566       lame->original = g_value_get_boolean (value);
567       break;
568     case ARG_ERROR_PROTECTION:
569       lame->error_protection = g_value_get_boolean (value);
570       break;
571     case ARG_PADDING_TYPE:
572       lame->padding_type = g_value_get_int (value);
573       break;
574     case ARG_EXTENSION:
575       lame->extension = g_value_get_boolean (value);
576       break;
577     case ARG_STRICT_ISO:
578       lame->strict_iso = g_value_get_boolean (value);
579       break;
580     case ARG_DISABLE_RESERVOIR:
581       lame->disable_reservoir = g_value_get_boolean (value);
582       break;
583     case ARG_VBR:
584       lame->vbr = g_value_get_boolean (value);
585       break;
586     case ARG_VBR_MEAN_BITRATE:
587       lame->vbr_mean_bitrate = g_value_get_int (value);
588       break;
589     case ARG_VBR_MIN_BITRATE:
590       lame->vbr_min_bitrate = g_value_get_int (value);
591       break;
592     case ARG_VBR_MAX_BITRATE:
593       lame->vbr_max_bitrate = g_value_get_int (value);
594       break;
595     case ARG_VBR_HARD_MIN:
596       lame->vbr_hard_min = g_value_get_int (value);
597       break;
598     case ARG_LOWPASS_FREQ:
599       lame->lowpass_freq = g_value_get_int (value);
600       break;
601     case ARG_LOWPASS_WIDTH:
602       lame->lowpass_width = g_value_get_int (value);
603       break;
604     case ARG_HIGHPASS_FREQ:
605       lame->highpass_freq = g_value_get_int (value);
606       break;
607     case ARG_HIGHPASS_WIDTH:
608       lame->highpass_width = g_value_get_int (value);
609       break;
610     case ARG_ATH_ONLY:
611       lame->ath_only = g_value_get_boolean (value);
612       break;
613     case ARG_ATH_SHORT:
614       lame->ath_short = g_value_get_boolean (value);
615       break;
616     case ARG_NO_ATH:
617       lame->no_ath = g_value_get_boolean (value);
618       break;
619     case ARG_ATH_LOWER:
620       lame->ath_lower = g_value_get_int (value);
621       break;
622     case ARG_CWLIMIT:
623       lame->cwlimit = g_value_get_int (value);
624       break;
625     case ARG_ALLOW_DIFF_SHORT:
626       lame->allow_diff_short = g_value_get_boolean (value);
627       break;
628     case ARG_NO_SHORT_BLOCKS:
629       lame->no_short_blocks = g_value_get_boolean (value);
630       break;
631     case ARG_EMPHASIS:
632       lame->emphasis = g_value_get_boolean (value);
633       break;
634     default:
635       break;
636   }
637
638 }
639
640 static void
641 gst_lame_get_property (GObject * object, guint prop_id, GValue * value,
642     GParamSpec * pspec)
643 {
644   GstLame *lame;
645
646   /* it's not null if we got it, but it might not be ours */
647   g_return_if_fail (GST_IS_LAME (object));
648
649   lame = GST_LAME (object);
650
651   switch (prop_id) {
652     case ARG_BITRATE:
653       g_value_set_int (value, lame->bitrate);
654       break;
655     case ARG_COMPRESSION_RATIO:
656       g_value_set_float (value, lame->compression_ratio);
657       break;
658     case ARG_QUALITY:
659       g_value_set_enum (value, lame->quality);
660       break;
661     case ARG_MODE:
662       g_value_set_enum (value, lame->mode);
663       break;
664     case ARG_FORCE_MS:
665       g_value_set_boolean (value, lame->force_ms);
666       break;
667     case ARG_FREE_FORMAT:
668       g_value_set_boolean (value, lame->free_format);
669       break;
670     case ARG_COPYRIGHT:
671       g_value_set_boolean (value, lame->copyright);
672       break;
673     case ARG_ORIGINAL:
674       g_value_set_boolean (value, lame->original);
675       break;
676     case ARG_ERROR_PROTECTION:
677       g_value_set_boolean (value, lame->error_protection);
678       break;
679     case ARG_PADDING_TYPE:
680       g_value_set_enum (value, lame->padding_type);
681       break;
682     case ARG_EXTENSION:
683       g_value_set_boolean (value, lame->extension);
684       break;
685     case ARG_STRICT_ISO:
686       g_value_set_boolean (value, lame->strict_iso);
687       break;
688     case ARG_DISABLE_RESERVOIR:
689       g_value_set_boolean (value, lame->disable_reservoir);
690       break;
691     case ARG_VBR:
692       g_value_set_boolean (value, lame->vbr);
693       break;
694     case ARG_VBR_MEAN_BITRATE:
695       g_value_set_int (value, lame->vbr_mean_bitrate);
696       break;
697     case ARG_VBR_MIN_BITRATE:
698       g_value_set_int (value, lame->vbr_min_bitrate);
699       break;
700     case ARG_VBR_MAX_BITRATE:
701       g_value_set_int (value, lame->vbr_max_bitrate);
702       break;
703     case ARG_VBR_HARD_MIN:
704       g_value_set_int (value, lame->vbr_hard_min);
705       break;
706     case ARG_LOWPASS_FREQ:
707       g_value_set_int (value, lame->lowpass_freq);
708       break;
709     case ARG_LOWPASS_WIDTH:
710       g_value_set_int (value, lame->lowpass_width);
711       break;
712     case ARG_HIGHPASS_FREQ:
713       g_value_set_int (value, lame->highpass_freq);
714       break;
715     case ARG_HIGHPASS_WIDTH:
716       g_value_set_int (value, lame->highpass_width);
717       break;
718     case ARG_ATH_ONLY:
719       g_value_set_boolean (value, lame->ath_only);
720       break;
721     case ARG_ATH_SHORT:
722       g_value_set_boolean (value, lame->ath_short);
723       break;
724     case ARG_NO_ATH:
725       g_value_set_boolean (value, lame->no_ath);
726       break;
727     case ARG_ATH_LOWER:
728       g_value_set_int (value, lame->ath_lower);
729       break;
730     case ARG_CWLIMIT:
731       g_value_set_int (value, lame->cwlimit);
732       break;
733     case ARG_ALLOW_DIFF_SHORT:
734       g_value_set_boolean (value, lame->allow_diff_short);
735       break;
736     case ARG_NO_SHORT_BLOCKS:
737       g_value_set_boolean (value, lame->no_short_blocks);
738       break;
739     case ARG_EMPHASIS:
740       g_value_set_boolean (value, lame->emphasis);
741       break;
742     default:
743       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
744       break;
745   }
746 }
747
748 static void
749 gst_lame_chain (GstPad * pad, GstData * _data)
750 {
751   GstBuffer *buf = GST_BUFFER (_data);
752   GstLame *lame;
753   GstBuffer *outbuf;
754   gchar *mp3_data = NULL;
755   gint mp3_buffer_size, mp3_size = 0;
756   gboolean eos = FALSE;
757
758   lame = GST_LAME (gst_pad_get_parent (pad));
759
760   GST_DEBUG ("entered chain");
761
762   if (GST_IS_EVENT (buf)) {
763     switch (GST_EVENT_TYPE (buf)) {
764       case GST_EVENT_EOS:
765         eos = TRUE;
766       case GST_EVENT_FLUSH:
767         mp3_buffer_size = 7200;
768         mp3_data = g_malloc (mp3_buffer_size);
769
770         mp3_size = lame_encode_flush (lame->lgf, mp3_data, mp3_buffer_size);
771         gst_event_unref (GST_EVENT (buf));
772         break;
773       case GST_EVENT_TAG:
774         if (lame->tags) {
775           gst_tag_list_insert (lame->tags,
776               gst_event_tag_get_list (GST_EVENT (buf)),
777               gst_tag_setter_get_merge_mode (GST_TAG_SETTER (lame)));
778         } else {
779           g_assert_not_reached ();
780         }
781         //      gst_pad_event_default (pad, GST_EVENT (buf));
782         break;
783       default:
784         gst_pad_event_default (pad, GST_EVENT (buf));
785         break;
786     }
787   } else {
788     gint64 duration;
789
790     if (!lame->initialized) {
791       gst_buffer_unref (buf);
792       GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
793           ("encoder not initialized (input is not audio?)"));
794       return;
795     }
796
797     /* allocate space for output */
798     mp3_buffer_size =
799         ((GST_BUFFER_SIZE (buf) / (2 + lame->num_channels)) * 1.25) + 7200;
800     mp3_data = g_malloc (mp3_buffer_size);
801
802     mp3_size = lame_encode_buffer_interleaved (lame->lgf,
803         (short int *) (GST_BUFFER_DATA (buf)),
804         GST_BUFFER_SIZE (buf) / 2 / lame->num_channels,
805         mp3_data, mp3_buffer_size);
806
807     GST_DEBUG ("encoded %d bytes of audio to %d bytes of mp3",
808         GST_BUFFER_SIZE (buf), mp3_size);
809
810     duration = (GST_SECOND * GST_BUFFER_SIZE (buf) /
811         (2 * lame->samplerate * lame->num_channels));
812
813     if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE &&
814         GST_BUFFER_DURATION (buf) != duration)
815       GST_DEBUG ("mad: incoming buffer had incorrect duration %lld, "
816           "outgoing buffer will have correct duration %lld",
817           GST_BUFFER_DURATION (buf), duration);
818
819     if (lame->last_ts == GST_CLOCK_TIME_NONE) {
820       lame->last_ts = GST_BUFFER_TIMESTAMP (buf);
821       lame->last_offs = GST_BUFFER_OFFSET (buf);
822       lame->last_duration = duration;
823     } else {
824       lame->last_duration += duration;
825     }
826
827     gst_buffer_unref (buf);
828   }
829
830   if (mp3_size > 0) {
831     outbuf = gst_buffer_new ();
832     GST_BUFFER_DATA (outbuf) = mp3_data;
833     GST_BUFFER_SIZE (outbuf) = mp3_size;
834     GST_BUFFER_TIMESTAMP (outbuf) = lame->last_ts;
835     GST_BUFFER_OFFSET (outbuf) = lame->last_offs;
836     GST_BUFFER_DURATION (outbuf) = lame->last_duration;
837
838     gst_pad_push (lame->srcpad, GST_DATA (outbuf));
839
840     lame->last_ts = GST_CLOCK_TIME_NONE;
841   } else {
842     g_free (mp3_data);
843   }
844
845   if (eos) {
846     gst_pad_push (lame->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
847     gst_element_set_eos (GST_ELEMENT (lame));
848   }
849 }
850
851 /* transition to the READY state by configuring the gst_lame encoder */
852 static gboolean
853 gst_lame_setup (GstLame * lame)
854 {
855   GST_DEBUG_OBJECT (lame, "starting setup");
856
857   /* check if we're already initialized; if we are, we might want to check
858    * if this initialization is compatible with the previous one */
859   /* FIXME: do this */
860   if (lame->initialized)
861     g_warning ("already initialized");
862
863   /* copy the parameters over */
864   lame_set_in_samplerate (lame->lgf, lame->samplerate);
865
866   /* force mono encoding if we only have one channel */
867   if (lame->num_channels == 1)
868     lame->mode = 3;
869
870   lame_set_brate (lame->lgf, lame->bitrate);
871   lame_set_compression_ratio (lame->lgf, lame->compression_ratio);
872   lame_set_quality (lame->lgf, lame->quality);
873   lame_set_mode (lame->lgf, lame->mode);
874   lame_set_force_ms (lame->lgf, lame->force_ms);
875   lame_set_free_format (lame->lgf, lame->free_format);
876   lame_set_copyright (lame->lgf, lame->copyright);
877   lame_set_original (lame->lgf, lame->original);
878   lame_set_error_protection (lame->lgf, lame->error_protection);
879   lame_set_padding_type (lame->lgf, lame->padding_type);
880   lame_set_extension (lame->lgf, lame->extension);
881   lame_set_strict_ISO (lame->lgf, lame->strict_iso);
882   lame_set_disable_reservoir (lame->lgf, lame->disable_reservoir);
883   lame_set_VBR_q (lame->lgf, lame->vbr);
884   lame_set_VBR_mean_bitrate_kbps (lame->lgf, lame->vbr_mean_bitrate);
885   lame_set_VBR_min_bitrate_kbps (lame->lgf, lame->vbr_min_bitrate);
886   lame_set_VBR_max_bitrate_kbps (lame->lgf, lame->vbr_max_bitrate);
887   lame_set_VBR_hard_min (lame->lgf, lame->vbr_hard_min);
888   lame_set_lowpassfreq (lame->lgf, lame->lowpass_freq);
889   lame_set_lowpasswidth (lame->lgf, lame->lowpass_width);
890   lame_set_highpassfreq (lame->lgf, lame->highpass_freq);
891   lame_set_highpasswidth (lame->lgf, lame->highpass_width);
892   lame_set_ATHonly (lame->lgf, lame->ath_only);
893   lame_set_ATHshort (lame->lgf, lame->ath_short);
894   lame_set_noATH (lame->lgf, lame->no_ath);
895   lame_set_ATHlower (lame->lgf, lame->ath_lower);
896   lame_set_cwlimit (lame->lgf, lame->cwlimit);
897   lame_set_allow_diff_short (lame->lgf, lame->allow_diff_short);
898   lame_set_no_short_blocks (lame->lgf, lame->no_short_blocks);
899   lame_set_emphasis (lame->lgf, lame->emphasis);
900
901   gst_lame_set_metadata (lame);
902
903   /* initialize the lame encoder */
904   if (lame_init_params (lame->lgf) < 0) {
905     lame->initialized = FALSE;
906   } else {
907     lame->initialized = TRUE;
908     /* FIXME: it would be nice to print out the mode here */
909     GST_INFO ("lame encoder initialized (%d kbit/s, %d Hz, %d channels)",
910         lame->bitrate, lame->samplerate, lame->num_channels);
911   }
912
913   GST_DEBUG_OBJECT (lame, "done with setup");
914
915   return lame->initialized;
916 }
917
918 static GstElementStateReturn
919 gst_lame_change_state (GstElement * element)
920 {
921   GstLame *lame;
922
923   g_return_val_if_fail (GST_IS_LAME (element), GST_STATE_FAILURE);
924
925   lame = GST_LAME (element);
926
927   GST_DEBUG ("state pending %d", GST_STATE_PENDING (element));
928
929   switch (GST_STATE_TRANSITION (element)) {
930     case GST_STATE_READY_TO_PAUSED:
931       lame->last_ts = GST_CLOCK_TIME_NONE;
932       break;
933     case GST_STATE_READY_TO_NULL:
934       if (lame->initialized) {
935         lame_close (lame->lgf);
936         lame->initialized = FALSE;
937       }
938       break;
939     default:
940       break;
941   }
942
943   /* if we haven't failed already, give the parent class a chance to ;-) */
944   if (GST_ELEMENT_CLASS (parent_class)->change_state)
945     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
946
947   return GST_STATE_SUCCESS;
948 }
949
950 static gboolean
951 plugin_init (GstPlugin * plugin)
952 {
953   if (!gst_element_register (plugin, "lame", GST_RANK_NONE, GST_TYPE_LAME))
954     return FALSE;
955
956   return TRUE;
957 }
958
959 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
960     GST_VERSION_MINOR,
961     "lame",
962     "Encode MP3's with LAME",
963     plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)