2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
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.
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.
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.
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>",
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",
40 GST_STATIC_CAPS ("audio/x-raw-int, "
41 "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", "
42 "signed = (boolean) true, "
45 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
46 "channels = (int) [ 1, 2 ]")
49 static GstStaticPadTemplate gst_lame_src_template =
50 GST_STATIC_PAD_TEMPLATE ("src",
53 GST_STATIC_CAPS ("audio/mpeg, "
54 "mpegversion = (int) 1, "
56 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
57 "channels = (int) [ 1, 2 ]")
60 /********** Define useful types for non-programmatic interfaces **********/
61 #define GST_TYPE_LAME_MODE (gst_lame_mode_get_type())
63 gst_lame_mode_get_type (void)
65 static GType lame_mode_type = 0;
66 static GEnumValue lame_modes[] = {
68 {1, "1", "Joint-Stereo"},
69 {2, "2", "Dual channel"},
75 if (!lame_mode_type) {
76 lame_mode_type = g_enum_register_static ("GstLameMode", lame_modes);
78 return lame_mode_type;
81 #define GST_TYPE_LAME_QUALITY (gst_lame_quality_get_type())
83 gst_lame_quality_get_type (void)
85 static GType lame_quality_type = 0;
86 static GEnumValue lame_quality[] = {
92 {5, "5", "5 - Default"},
96 {9, "9", "9 - Worst"},
100 if (!lame_quality_type) {
101 lame_quality_type = g_enum_register_static ("GstLameQuality", lame_quality);
103 return lame_quality_type;
106 #define GST_TYPE_LAME_PADDING (gst_lame_padding_get_type())
108 gst_lame_padding_get_type (void)
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"},
118 if (!lame_padding_type) {
119 lame_padding_type = g_enum_register_static ("GstLamePadding", lame_padding);
121 return lame_padding_type;
124 /********** Standard stuff for signals and arguments **********/
125 /* GstLame signals and args */
136 ARG_COMPRESSION_RATIO,
143 ARG_ERROR_PROTECTION,
147 ARG_DISABLE_RESERVOIR,
149 ARG_VBR_MEAN_BITRATE,
162 ARG_ALLOW_DIFF_SHORT,
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);
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);
179 static GstElementClass *parent_class = NULL;
181 /* static guint gst_lame_signals[LAST_SIGNAL] = { 0 }; */
184 gst_lame_get_type (void)
186 static GType gst_lame_type = 0;
188 if (!gst_lame_type) {
189 static const GTypeInfo gst_lame_info = {
190 sizeof (GstLameClass),
193 (GClassInitFunc) gst_lame_class_init,
198 (GInstanceInitFunc) gst_lame_init,
201 static const GInterfaceInfo tag_setter_info = {
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,
213 return gst_lame_type;
217 gst_lame_base_init (gpointer g_class)
219 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
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);
229 gst_lame_class_init (GstLameClass * klass)
231 GObjectClass *gobject_class;
232 GstElementClass *gstelement_class;
234 gobject_class = (GObjectClass *) klass;
235 gstelement_class = (GstElementClass *) klass;
237 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
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",
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,
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,
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,
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,
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,
282 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
283 g_param_spec_boolean ("vbr", "VBR", "Use variable bitrate", TRUE,
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,
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,
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,
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,
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,
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,
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,
340 gobject_class->set_property = gst_lame_set_property;
341 gobject_class->get_property = gst_lame_get_property;
343 gstelement_class->change_state = gst_lame_change_state;
346 static GstPadLinkReturn
347 gst_lame_sink_link (GstPad * pad, const GstCaps * caps)
351 GstStructure *structure;
354 lame = GST_LAME (gst_pad_get_parent (pad));
355 structure = gst_caps_get_structure (caps, 0);
357 gst_structure_get_int (structure, "rate", &lame->samplerate);
358 gst_structure_get_int (structure, "channels", &lame->num_channels);
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;
366 out_samplerate = lame_get_out_samplerate (lame->lgf);
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);
374 return gst_pad_try_set_caps (lame->srcpad, othercaps);
378 gst_lame_init (GstLame * lame)
380 GST_DEBUG_OBJECT (lame, "starting initialization");
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);
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);
394 GST_FLAG_SET (lame, GST_ELEMENT_EVENT_AWARE);
396 GST_DEBUG ("setting up lame encoder");
397 lame->lgf = lame_init ();
399 lame->samplerate = 44100;
400 lame->num_channels = 2;
401 lame->initialized = FALSE;
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 ();
436 id3tag_init (lame->lgf);
438 GST_DEBUG_OBJECT (lame, "done initializing");
441 typedef struct _GstLameTagMatch GstLameTagMatch;
442 typedef void (*GstLameTagFunc) (lame_global_flags * gfp, const char *value);
444 struct _GstLameTagMatch
446 gchar *gstreamer_tag;
447 GstLameTagFunc tag_func;
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},
462 add_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data)
468 lame = GST_LAME (user_data);
469 g_return_if_fail (lame != NULL);
471 while (tag_matches[i].gstreamer_tag != NULL) {
472 if (strcmp (tag, tag_matches[i].gstreamer_tag) == 0) {
478 if (tag_matches[i].tag_func == NULL) {
479 g_print ("Couldn't find matching gstreamer tag for %s\n", tag);
483 switch (gst_tag_get_type (tag)) {
487 if (!gst_tag_list_get_uint (list, tag, &ivalue)) {
488 GST_DEBUG ("Error reading \"%s\" tag value\n", tag);
491 value = g_strdup_printf ("%u", ivalue);
495 if (!gst_tag_list_get_string (list, tag, &value)) {
496 GST_DEBUG ("Error reading \"%s\" tag value\n", tag);
501 GST_DEBUG ("Couldn't write tag %s", tag);
505 tag_matches[i].tag_func (lame->lgf, value);
507 if (gst_tag_get_type (tag) == G_TYPE_UINT) {
513 gst_lame_set_metadata (GstLame * lame)
515 const GstTagList *user_tags;
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)) {
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);
527 gst_tag_list_free (copy);
533 gst_lame_set_property (GObject * object, guint prop_id, const GValue * value,
538 /* it's not null if we got it, but it might not be ours */
539 g_return_if_fail (GST_IS_LAME (object));
541 lame = GST_LAME (object);
545 lame->bitrate = g_value_get_int (value);
547 case ARG_COMPRESSION_RATIO:
548 lame->compression_ratio = g_value_get_float (value);
551 lame->quality = g_value_get_enum (value);
554 lame->mode = g_value_get_enum (value);
557 lame->force_ms = g_value_get_boolean (value);
559 case ARG_FREE_FORMAT:
560 lame->free_format = g_value_get_boolean (value);
563 lame->copyright = g_value_get_boolean (value);
566 lame->original = g_value_get_boolean (value);
568 case ARG_ERROR_PROTECTION:
569 lame->error_protection = g_value_get_boolean (value);
571 case ARG_PADDING_TYPE:
572 lame->padding_type = g_value_get_int (value);
575 lame->extension = g_value_get_boolean (value);
578 lame->strict_iso = g_value_get_boolean (value);
580 case ARG_DISABLE_RESERVOIR:
581 lame->disable_reservoir = g_value_get_boolean (value);
584 lame->vbr = g_value_get_boolean (value);
586 case ARG_VBR_MEAN_BITRATE:
587 lame->vbr_mean_bitrate = g_value_get_int (value);
589 case ARG_VBR_MIN_BITRATE:
590 lame->vbr_min_bitrate = g_value_get_int (value);
592 case ARG_VBR_MAX_BITRATE:
593 lame->vbr_max_bitrate = g_value_get_int (value);
595 case ARG_VBR_HARD_MIN:
596 lame->vbr_hard_min = g_value_get_int (value);
598 case ARG_LOWPASS_FREQ:
599 lame->lowpass_freq = g_value_get_int (value);
601 case ARG_LOWPASS_WIDTH:
602 lame->lowpass_width = g_value_get_int (value);
604 case ARG_HIGHPASS_FREQ:
605 lame->highpass_freq = g_value_get_int (value);
607 case ARG_HIGHPASS_WIDTH:
608 lame->highpass_width = g_value_get_int (value);
611 lame->ath_only = g_value_get_boolean (value);
614 lame->ath_short = g_value_get_boolean (value);
617 lame->no_ath = g_value_get_boolean (value);
620 lame->ath_lower = g_value_get_int (value);
623 lame->cwlimit = g_value_get_int (value);
625 case ARG_ALLOW_DIFF_SHORT:
626 lame->allow_diff_short = g_value_get_boolean (value);
628 case ARG_NO_SHORT_BLOCKS:
629 lame->no_short_blocks = g_value_get_boolean (value);
632 lame->emphasis = g_value_get_boolean (value);
641 gst_lame_get_property (GObject * object, guint prop_id, GValue * value,
646 /* it's not null if we got it, but it might not be ours */
647 g_return_if_fail (GST_IS_LAME (object));
649 lame = GST_LAME (object);
653 g_value_set_int (value, lame->bitrate);
655 case ARG_COMPRESSION_RATIO:
656 g_value_set_float (value, lame->compression_ratio);
659 g_value_set_enum (value, lame->quality);
662 g_value_set_enum (value, lame->mode);
665 g_value_set_boolean (value, lame->force_ms);
667 case ARG_FREE_FORMAT:
668 g_value_set_boolean (value, lame->free_format);
671 g_value_set_boolean (value, lame->copyright);
674 g_value_set_boolean (value, lame->original);
676 case ARG_ERROR_PROTECTION:
677 g_value_set_boolean (value, lame->error_protection);
679 case ARG_PADDING_TYPE:
680 g_value_set_enum (value, lame->padding_type);
683 g_value_set_boolean (value, lame->extension);
686 g_value_set_boolean (value, lame->strict_iso);
688 case ARG_DISABLE_RESERVOIR:
689 g_value_set_boolean (value, lame->disable_reservoir);
692 g_value_set_boolean (value, lame->vbr);
694 case ARG_VBR_MEAN_BITRATE:
695 g_value_set_int (value, lame->vbr_mean_bitrate);
697 case ARG_VBR_MIN_BITRATE:
698 g_value_set_int (value, lame->vbr_min_bitrate);
700 case ARG_VBR_MAX_BITRATE:
701 g_value_set_int (value, lame->vbr_max_bitrate);
703 case ARG_VBR_HARD_MIN:
704 g_value_set_int (value, lame->vbr_hard_min);
706 case ARG_LOWPASS_FREQ:
707 g_value_set_int (value, lame->lowpass_freq);
709 case ARG_LOWPASS_WIDTH:
710 g_value_set_int (value, lame->lowpass_width);
712 case ARG_HIGHPASS_FREQ:
713 g_value_set_int (value, lame->highpass_freq);
715 case ARG_HIGHPASS_WIDTH:
716 g_value_set_int (value, lame->highpass_width);
719 g_value_set_boolean (value, lame->ath_only);
722 g_value_set_boolean (value, lame->ath_short);
725 g_value_set_boolean (value, lame->no_ath);
728 g_value_set_int (value, lame->ath_lower);
731 g_value_set_int (value, lame->cwlimit);
733 case ARG_ALLOW_DIFF_SHORT:
734 g_value_set_boolean (value, lame->allow_diff_short);
736 case ARG_NO_SHORT_BLOCKS:
737 g_value_set_boolean (value, lame->no_short_blocks);
740 g_value_set_boolean (value, lame->emphasis);
743 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
749 gst_lame_chain (GstPad * pad, GstData * _data)
751 GstBuffer *buf = GST_BUFFER (_data);
754 gchar *mp3_data = NULL;
755 gint mp3_buffer_size, mp3_size = 0;
756 gboolean eos = FALSE;
758 lame = GST_LAME (gst_pad_get_parent (pad));
760 GST_DEBUG ("entered chain");
762 if (GST_IS_EVENT (buf)) {
763 switch (GST_EVENT_TYPE (buf)) {
766 case GST_EVENT_FLUSH:
767 mp3_buffer_size = 7200;
768 mp3_data = g_malloc (mp3_buffer_size);
770 mp3_size = lame_encode_flush (lame->lgf, mp3_data, mp3_buffer_size);
771 gst_event_unref (GST_EVENT (buf));
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)));
779 g_assert_not_reached ();
781 // gst_pad_event_default (pad, GST_EVENT (buf));
784 gst_pad_event_default (pad, GST_EVENT (buf));
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?)"));
797 /* allocate space for output */
799 ((GST_BUFFER_SIZE (buf) / (2 + lame->num_channels)) * 1.25) + 7200;
800 mp3_data = g_malloc (mp3_buffer_size);
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);
807 GST_DEBUG ("encoded %d bytes of audio to %d bytes of mp3",
808 GST_BUFFER_SIZE (buf), mp3_size);
810 duration = (GST_SECOND * GST_BUFFER_SIZE (buf) /
811 (2 * lame->samplerate * lame->num_channels));
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);
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;
824 lame->last_duration += duration;
827 gst_buffer_unref (buf);
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;
838 gst_pad_push (lame->srcpad, GST_DATA (outbuf));
840 lame->last_ts = GST_CLOCK_TIME_NONE;
846 gst_pad_push (lame->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
847 gst_element_set_eos (GST_ELEMENT (lame));
851 /* transition to the READY state by configuring the gst_lame encoder */
853 gst_lame_setup (GstLame * lame)
855 GST_DEBUG_OBJECT (lame, "starting setup");
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 */
860 if (lame->initialized)
861 g_warning ("already initialized");
863 /* copy the parameters over */
864 lame_set_in_samplerate (lame->lgf, lame->samplerate);
866 /* force mono encoding if we only have one channel */
867 if (lame->num_channels == 1)
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);
901 gst_lame_set_metadata (lame);
903 /* initialize the lame encoder */
904 if (lame_init_params (lame->lgf) < 0) {
905 lame->initialized = FALSE;
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);
913 GST_DEBUG_OBJECT (lame, "done with setup");
915 return lame->initialized;
918 static GstElementStateReturn
919 gst_lame_change_state (GstElement * element)
923 g_return_val_if_fail (GST_IS_LAME (element), GST_STATE_FAILURE);
925 lame = GST_LAME (element);
927 GST_DEBUG ("state pending %d", GST_STATE_PENDING (element));
929 switch (GST_STATE_TRANSITION (element)) {
930 case GST_STATE_READY_TO_PAUSED:
931 lame->last_ts = GST_CLOCK_TIME_NONE;
933 case GST_STATE_READY_TO_NULL:
934 if (lame->initialized) {
935 lame_close (lame->lgf);
936 lame->initialized = FALSE;
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);
947 return GST_STATE_SUCCESS;
951 plugin_init (GstPlugin * plugin)
953 if (!gst_element_register (plugin, "lame", GST_RANK_NONE, GST_TYPE_LAME))
959 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
962 "Encode MP3's with LAME",
963 plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)