2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
4 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
28 #ifdef lame_set_preset
29 #define GST_LAME_PRESET
32 GST_DEBUG_CATEGORY_STATIC (debug);
33 #define GST_CAT_DEFAULT debug
35 /* elementfactory information */
36 static GstElementDetails gst_lame_details = {
37 "L.A.M.E. mp3 encoder",
38 "Codec/Encoder/Audio",
39 "High-quality free MP3 encoder",
40 "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>",
43 /* LAME can do MPEG-1, MPEG-2, and MPEG-2.5, so it has 9 possible
44 * sample rates it supports */
45 static GstStaticPadTemplate gst_lame_sink_template =
46 GST_STATIC_PAD_TEMPLATE ("sink",
49 GST_STATIC_CAPS ("audio/x-raw-int, "
50 "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", "
51 "signed = (boolean) true, "
54 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
55 "channels = (int) [ 1, 2 ]")
58 static GstStaticPadTemplate gst_lame_src_template =
59 GST_STATIC_PAD_TEMPLATE ("src",
62 GST_STATIC_CAPS ("audio/mpeg, "
63 "mpegversion = (int) 1, "
65 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
66 "channels = (int) [ 1, 2 ]")
69 /********** Define useful types for non-programmatic interfaces **********/
70 #define GST_TYPE_LAME_MODE (gst_lame_mode_get_type())
72 gst_lame_mode_get_type (void)
74 static GType lame_mode_type = 0;
75 static GEnumValue lame_modes[] = {
76 {0, "Stereo", "stereo"},
77 {1, "Joint Stereo", "joint"},
78 {2, "Dual Channel", "dual"},
84 if (!lame_mode_type) {
85 lame_mode_type = g_enum_register_static ("GstLameMode", lame_modes);
87 return lame_mode_type;
90 #define GST_TYPE_LAME_QUALITY (gst_lame_quality_get_type())
92 gst_lame_quality_get_type (void)
94 static GType lame_quality_type = 0;
95 static GEnumValue lame_quality[] = {
101 {5, "5 - Default", "5"},
105 {9, "9 - Worst", "9"},
109 if (!lame_quality_type) {
110 lame_quality_type = g_enum_register_static ("GstLameQuality", lame_quality);
112 return lame_quality_type;
115 #define GST_TYPE_LAME_PADDING (gst_lame_padding_get_type())
117 gst_lame_padding_get_type (void)
119 static GType lame_padding_type = 0;
120 static GEnumValue lame_padding[] = {
121 {0, "No Padding", "never"},
122 {1, "Always Pad", "always"},
123 {2, "Adjust Padding", "adjust"},
127 if (!lame_padding_type) {
128 lame_padding_type = g_enum_register_static ("GstLamePadding", lame_padding);
130 return lame_padding_type;
133 #define GST_TYPE_LAME_VBRMODE (gst_lame_vbrmode_get_type())
135 gst_lame_vbrmode_get_type (void)
137 static GType lame_vbrmode_type = 0;
138 static GEnumValue lame_vbrmode[] = {
139 {vbr_off, "No VBR (Constant Bitrate)", "none"},
140 {vbr_rh, "Lame's old VBR algorithm", "old"},
141 {vbr_abr, "VBR Average Bitrate", "abr"},
142 {vbr_mtrh, "Lame's new VBR algorithm", "new"},
146 if (!lame_vbrmode_type) {
147 lame_vbrmode_type = g_enum_register_static ("GstLameVbrmode", lame_vbrmode);
150 return lame_vbrmode_type;
153 #ifdef GSTLAME_PRESET
154 #define GST_TYPE_LAME_PRESET (gst_lame_preset_get_type())
156 gst_lame_preset_get_type (void)
158 static GType gst_lame_preset = 0;
159 static GEnumValue gst_lame_presets[] = {
161 {MEDIUM, "Medium", "medium"},
162 {STANDARD, "Standard", "standard"},
163 {EXTREME, "Extreme", "extreme"},
164 {INSANE, "Insane", "insane"},
168 if (!gst_lame_preset) {
170 g_enum_register_static ("GstLamePreset", gst_lame_presets);
173 return gst_lame_preset;
177 /********** Standard stuff for signals and arguments **********/
178 /* GstLame signals and args */
189 ARG_COMPRESSION_RATIO,
196 ARG_ERROR_PROTECTION,
200 ARG_DISABLE_RESERVOIR,
202 ARG_VBR_MEAN_BITRATE,
215 ARG_ALLOW_DIFF_SHORT,
219 #ifdef GSTLAME_PRESET
227 static void gst_lame_base_init (gpointer g_class);
228 static void gst_lame_class_init (GstLameClass * klass);
229 static void gst_lame_init (GstLame * gst_lame);
231 static void gst_lame_set_property (GObject * object, guint prop_id,
232 const GValue * value, GParamSpec * pspec);
233 static void gst_lame_get_property (GObject * object, guint prop_id,
234 GValue * value, GParamSpec * pspec);
235 static gboolean gst_lame_sink_event (GstPad * pad, GstEvent * event);
236 static GstFlowReturn gst_lame_chain (GstPad * pad, GstBuffer * buf);
237 static gboolean gst_lame_setup (GstLame * lame);
238 static GstStateChangeReturn gst_lame_change_state (GstElement * element,
239 GstStateChange transition);
241 static GstElementClass *parent_class = NULL;
243 /* static guint gst_lame_signals[LAST_SIGNAL] = { 0 }; */
246 gst_lame_get_type (void)
248 static GType gst_lame_type = 0;
250 if (!gst_lame_type) {
251 static const GTypeInfo gst_lame_info = {
252 sizeof (GstLameClass),
255 (GClassInitFunc) gst_lame_class_init,
260 (GInstanceInitFunc) gst_lame_init,
263 static const GInterfaceInfo tag_setter_info = {
270 g_type_register_static (GST_TYPE_ELEMENT, "GstLame", &gst_lame_info, 0);
271 g_type_add_interface_static (gst_lame_type, GST_TYPE_TAG_SETTER,
275 return gst_lame_type;
279 gst_lame_finalize (GObject * obj)
281 GstLame *lame = GST_LAME (obj);
283 g_slist_foreach (lame->tag_strings, (GFunc) g_free, NULL);
284 g_slist_free (lame->tag_strings);
285 lame->tag_strings = NULL;
287 G_OBJECT_CLASS (parent_class)->finalize (obj);
291 gst_lame_base_init (gpointer g_class)
293 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
295 gst_element_class_add_pad_template (element_class,
296 gst_static_pad_template_get (&gst_lame_src_template));
297 gst_element_class_add_pad_template (element_class,
298 gst_static_pad_template_get (&gst_lame_sink_template));
299 gst_element_class_set_details (element_class, &gst_lame_details);
303 gst_lame_class_init (GstLameClass * klass)
305 GObjectClass *gobject_class;
306 GstElementClass *gstelement_class;
308 gobject_class = (GObjectClass *) klass;
309 gstelement_class = (GstElementClass *) klass;
311 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
313 gobject_class->set_property = gst_lame_set_property;
314 gobject_class->get_property = gst_lame_get_property;
315 gobject_class->finalize = gst_lame_finalize;
317 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
318 g_param_spec_int ("bitrate", "Bitrate (kb/s)", "Bitrate in kbit/sec",
319 8, 320, 128, G_PARAM_READWRITE));
320 /* compression ratio set to 0.0 by default otherwise it overrides the bitrate setting */
321 g_object_class_install_property (G_OBJECT_CLASS (klass),
322 ARG_COMPRESSION_RATIO, g_param_spec_float ("compression_ratio",
324 "let lame choose bitrate to achieve selected compression ratio", 0.0,
325 200.0, 0.0, G_PARAM_READWRITE));
326 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
327 g_param_spec_enum ("quality", "Quality",
328 "Quality of algorithm used for encoding", GST_TYPE_LAME_QUALITY, 5,
330 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
331 g_param_spec_enum ("mode", "Mode", "Encoding mode", GST_TYPE_LAME_MODE, 0,
333 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FORCE_MS,
334 g_param_spec_boolean ("force_ms", "Force ms",
335 "Force ms_stereo on all frames", TRUE, G_PARAM_READWRITE));
336 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREE_FORMAT,
337 g_param_spec_boolean ("free_format", "Free format",
338 "Produce a free format bitstream", TRUE, G_PARAM_READWRITE));
339 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COPYRIGHT,
340 g_param_spec_boolean ("copyright", "Copyright", "Mark as copyright", TRUE,
342 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ORIGINAL,
343 g_param_spec_boolean ("original", "Original", "Mark as non-original",
344 TRUE, G_PARAM_READWRITE));
345 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_PROTECTION,
346 g_param_spec_boolean ("error_protection", "Error protection",
347 "Adds 16 bit checksum to every frame", TRUE, G_PARAM_READWRITE));
348 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PADDING_TYPE,
349 g_param_spec_enum ("padding_type", "Padding type", "Padding type",
350 GST_TYPE_LAME_PADDING, 0, G_PARAM_READWRITE));
351 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EXTENSION,
352 g_param_spec_boolean ("extension", "Extension", "Extension", TRUE,
354 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STRICT_ISO,
355 g_param_spec_boolean ("strict_iso", "Strict ISO",
356 "Comply as much as possible to ISO MPEG spec", TRUE,
358 g_object_class_install_property (G_OBJECT_CLASS (klass),
359 ARG_DISABLE_RESERVOIR, g_param_spec_boolean ("disable_reservoir",
360 "Disable reservoir", "Disable the bit reservoir", TRUE,
362 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
363 g_param_spec_enum ("vbr", "VBR", "Specify bitrate mode",
364 GST_TYPE_LAME_VBRMODE, vbr_off, G_PARAM_READWRITE));
365 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_QUALITY,
366 g_param_spec_enum ("vbr_quality", "VBR Quality", "VBR Quality",
367 GST_TYPE_LAME_QUALITY, 5, G_PARAM_READWRITE));
368 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MEAN_BITRATE,
369 g_param_spec_int ("vbr_mean_bitrate", "VBR mean bitrate",
370 "Specify mean bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
371 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MIN_BITRATE,
372 g_param_spec_int ("vbr_min_bitrate", "VBR min bitrate",
373 "Specify min bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
374 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MAX_BITRATE,
375 g_param_spec_int ("vbr_max_bitrate", "VBR max bitrate",
376 "Specify max bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
377 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_HARD_MIN,
378 g_param_spec_int ("vbr_hard_min", "VBR hard min",
379 "Specify hard min bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
380 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_FREQ,
381 g_param_spec_int ("lowpass_freq", "Lowpass freq",
382 "frequency(kHz), lowpass filter cutoff above freq", 0, 50000, 0,
384 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_WIDTH,
385 g_param_spec_int ("lowpass_width", "Lowpass width",
386 "frequency(kHz) - default 15% of lowpass freq", 0, G_MAXINT, 0,
388 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_FREQ,
389 g_param_spec_int ("highpass_freq", "Highpass freq",
390 "frequency(kHz), highpass filter cutoff below freq", 0, 50000, 0,
392 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_WIDTH,
393 g_param_spec_int ("highpass_width", "Highpass width",
394 "frequency(kHz) - default 15% of highpass freq", 0, G_MAXINT, 0,
396 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_ONLY,
397 g_param_spec_boolean ("ath_only", "ATH only",
398 "Ignore GPSYCHO completely, use ATH only", TRUE, G_PARAM_READWRITE));
399 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_SHORT,
400 g_param_spec_boolean ("ath_short", "ATH short",
401 "Ignore GPSYCHO for short blocks, use ATH only", TRUE,
403 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_ATH,
404 g_param_spec_boolean ("no_ath", "No ath",
405 "turns ATH down to a flat noise floor", TRUE, G_PARAM_READWRITE));
406 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_LOWER,
407 g_param_spec_int ("ath_lower", "ATH lower", "lowers ATH by x dB",
408 G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
409 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CWLIMIT,
410 g_param_spec_int ("cwlimit", "Cwlimit",
411 "Compute tonality up to freq (in kHz) default 8.8717", 0, 50000, 0,
413 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ALLOW_DIFF_SHORT,
414 g_param_spec_boolean ("allow_diff_short", "Allow diff short",
415 "Allow diff short", TRUE, G_PARAM_READWRITE));
416 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_SHORT_BLOCKS,
417 g_param_spec_boolean ("no_short_blocks", "No short blocks",
418 "Do not use short blocks", TRUE, G_PARAM_READWRITE));
419 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EMPHASIS,
420 g_param_spec_boolean ("emphasis", "Emphasis", "Emphasis", TRUE,
422 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_XINGHEADER,
423 g_param_spec_boolean ("xingheader", "Output Xing Header",
424 "Output Xing Header", FALSE, G_PARAM_READWRITE));
425 #ifdef GSTLAME_PRESET
426 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PRESET,
427 g_param_spec_enum ("preset", "Lame Preset", "Lame Preset",
428 GST_TYPE_LAME_PRESET, 0, G_PARAM_READWRITE));
431 gstelement_class->change_state = gst_lame_change_state;
435 gst_lame_sink_setcaps (GstPad * pad, GstCaps * caps)
439 GstStructure *structure;
442 lame = GST_LAME (gst_pad_get_parent (pad));
443 structure = gst_caps_get_structure (caps, 0);
445 if (!gst_structure_get_int (structure, "rate", &lame->samplerate))
447 if (!gst_structure_get_int (structure, "channels", &lame->num_channels))
450 GST_DEBUG_OBJECT (lame, "sink_setcaps, setting up lame");
451 if (!gst_lame_setup (lame))
455 out_samplerate = lame_get_out_samplerate (lame->lgf);
456 if (out_samplerate == 0)
457 goto zero_output_rate;
460 gst_caps_new_simple ("audio/mpeg",
461 "mpegversion", G_TYPE_INT, 1,
462 "layer", G_TYPE_INT, 3,
463 "channels", G_TYPE_INT, lame->num_channels,
464 "rate", G_TYPE_INT, out_samplerate, NULL);
466 /* and use these caps */
467 gst_pad_set_caps (lame->srcpad, othercaps);
468 gst_caps_unref (othercaps);
474 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
475 ("no rate specified in input"));
480 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
481 ("no channels specified in input"));
486 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
487 ("lame decided on a zero sample rate"));
492 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
493 ("could not initialize encoder (wrong parameters?)"));
499 gst_lame_init (GstLame * lame)
501 GST_DEBUG_OBJECT (lame, "starting initialization");
504 gst_pad_new_from_template (gst_static_pad_template_get
505 (&gst_lame_sink_template), "sink");
506 gst_pad_set_event_function (lame->sinkpad, gst_lame_sink_event);
507 gst_pad_set_chain_function (lame->sinkpad, gst_lame_chain);
508 gst_pad_set_setcaps_function (lame->sinkpad, gst_lame_sink_setcaps);
509 gst_element_add_pad (GST_ELEMENT (lame), lame->sinkpad);
512 gst_pad_new_from_template (gst_static_pad_template_get
513 (&gst_lame_src_template), "src");
514 gst_element_add_pad (GST_ELEMENT (lame), lame->srcpad);
516 /* create an encoder state so we can ask about defaults */
517 lame->lgf = lame_init ();
519 lame->samplerate = 44100;
520 lame->num_channels = 2;
523 lame->bitrate = 128; /* lame_get_brate (lame->lgf);
524 * => 0/out of range */
525 lame->compression_ratio = 0.0; /* lame_get_compression_ratio (lame->lgf);
526 * => 0/out of range ...
527 * NOTE: 0.0 makes bitrate take precedence */
528 lame->quality = 5; /* lame_get_quality (lame->lgf);
529 * => -1/out of range */
530 lame->mode = lame_get_mode (lame->lgf);
531 lame->force_ms = lame_get_force_ms (lame->lgf);
532 lame->free_format = lame_get_free_format (lame->lgf);
533 lame->copyright = lame_get_copyright (lame->lgf);
534 lame->original = lame_get_original (lame->lgf);
535 lame->error_protection = lame_get_error_protection (lame->lgf);
536 lame->padding_type = lame_get_padding_type (lame->lgf);
537 lame->extension = lame_get_extension (lame->lgf);
538 lame->strict_iso = lame_get_strict_ISO (lame->lgf);
539 lame->disable_reservoir = lame_get_disable_reservoir (lame->lgf);
540 lame->vbr = vbr_off; /* lame_get_VBR (lame->lgf); */
541 lame->vbr_quality = 5;
542 lame->vbr_mean_bitrate = lame_get_VBR_mean_bitrate_kbps (lame->lgf);
543 lame->vbr_min_bitrate = lame_get_VBR_min_bitrate_kbps (lame->lgf);
544 lame->vbr_max_bitrate = 0; /* lame_get_VBR_max_bitrate_kbps (lame->lgf);
545 * => 0/no vbr possible */
546 lame->vbr_hard_min = lame_get_VBR_hard_min (lame->lgf);
547 /* lame->lowpass_freq = 50000; lame_get_lowpassfreq (lame->lgf);
548 * => 0/lowpass on everything ? */
549 lame->lowpass_freq = 0;
550 lame->lowpass_width = 0; /* lame_get_lowpasswidth (lame->lgf);
551 * => -1/out of range */
552 lame->highpass_freq = lame_get_highpassfreq (lame->lgf);
553 lame->highpass_width = 0; /* lame_get_highpasswidth (lame->lgf);
554 * => -1/out of range */
555 lame->ath_only = lame_get_ATHonly (lame->lgf);
556 lame->ath_short = lame_get_ATHshort (lame->lgf);
557 lame->no_ath = lame_get_noATH (lame->lgf);
558 /* lame->ath_type = lame_get_ATHtype (lame->lgf); */
559 lame->ath_lower = lame_get_ATHlower (lame->lgf);
560 lame->cwlimit = 8.8717; /* lame_get_cwlimit (lame->lgf); => 0 */
561 lame->allow_diff_short = lame_get_allow_diff_short (lame->lgf);
562 lame->no_short_blocks = TRUE; /* lame_get_no_short_blocks (lame->lgf); */
563 lame->emphasis = lame_get_emphasis (lame->lgf);
564 lame->xingheader = FALSE;
566 lame_close (lame->lgf);
568 lame->tag_strings = NULL;
570 GST_DEBUG_OBJECT (lame, "done initializing");
573 typedef struct _GstLameTagMatch GstLameTagMatch;
574 typedef void (*GstLameTagFunc) (lame_global_flags * gfp, const char *value);
576 struct _GstLameTagMatch
578 gchar *gstreamer_tag;
579 GstLameTagFunc tag_func;
582 static GstLameTagMatch tag_matches[] = {
583 {GST_TAG_TITLE, id3tag_set_title},
584 {GST_TAG_DATE, id3tag_set_year},
585 {GST_TAG_TRACK_NUMBER, id3tag_set_track},
586 {GST_TAG_COMMENT, id3tag_set_comment},
587 {GST_TAG_ARTIST, id3tag_set_artist},
588 {GST_TAG_ALBUM, id3tag_set_album},
589 {GST_TAG_GENRE, (GstLameTagFunc) id3tag_set_genre},
594 add_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data)
600 lame = GST_LAME (user_data);
601 g_return_if_fail (lame != NULL);
603 while (tag_matches[i].gstreamer_tag != NULL) {
604 if (strcmp (tag, tag_matches[i].gstreamer_tag) == 0) {
610 if (tag_matches[i].tag_func == NULL) {
611 GST_WARNING_OBJECT (lame,
612 "Couldn't find matching gstreamer tag for \"%s\"", tag);
616 switch (gst_tag_get_type (tag)) {
620 if (!gst_tag_list_get_uint (list, tag, &ivalue)) {
621 GST_WARNING_OBJECT (lame, "Error reading \"%s\" tag value", tag);
624 value = g_strdup_printf ("%u", ivalue);
628 if (!gst_tag_list_get_string (list, tag, &value)) {
629 GST_WARNING_OBJECT (lame, "Error reading \"%s\" tag value", tag);
634 if (strcmp (tag, GST_TAG_DATE) == 0) {
637 if (!gst_tag_list_get_date (list, tag, &date) || date == NULL) {
638 GST_WARNING_OBJECT (lame, "Error reading \"%s\" tag value", tag);
640 value = g_strdup_printf ("%u", g_date_get_year (date));
644 GST_WARNING_OBJECT (lame, "Couldn't write tag %s", tag);
650 if (value != NULL && *value != '\0') {
651 GST_LOG_OBJECT (lame, "Adding tag %s:%s", tag, value);
652 tag_matches[i].tag_func (lame->lgf, value);
655 /* lame does not copy strings passed to it and expects them
656 * to be around later, but it does not free them for us either,
657 * so we just add them to a list and free it later when it's safe */
658 lame->tag_strings = g_slist_prepend (lame->tag_strings, value);
662 gst_lame_set_metadata (GstLame * lame)
664 const GstTagList *user_tags;
667 g_return_if_fail (lame != NULL);
669 user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (lame));
671 GST_DEBUG_OBJECT (lame, "lame->tags = %" GST_PTR_FORMAT, lame->tags);
672 GST_DEBUG_OBJECT (lame, "user tags = %" GST_PTR_FORMAT, user_tags);
674 if ((lame->tags == NULL) && (user_tags == NULL)) {
678 copy = gst_tag_list_merge (user_tags, lame->tags,
679 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (lame)));
681 GST_DEBUG_OBJECT (lame, "merged tags = %" GST_PTR_FORMAT, copy);
683 gst_tag_list_foreach ((GstTagList *) copy, add_one_tag, lame);
685 gst_tag_list_free (copy);
691 gst_lame_set_property (GObject * object, guint prop_id, const GValue * value,
696 g_return_if_fail (GST_IS_LAME (object));
698 lame = GST_LAME (object);
702 lame->bitrate = g_value_get_int (value);
704 case ARG_COMPRESSION_RATIO:
705 lame->compression_ratio = g_value_get_float (value);
708 lame->quality = g_value_get_enum (value);
711 lame->mode = g_value_get_enum (value);
714 lame->force_ms = g_value_get_boolean (value);
716 case ARG_FREE_FORMAT:
717 lame->free_format = g_value_get_boolean (value);
720 lame->copyright = g_value_get_boolean (value);
723 lame->original = g_value_get_boolean (value);
725 case ARG_ERROR_PROTECTION:
726 lame->error_protection = g_value_get_boolean (value);
728 case ARG_PADDING_TYPE:
729 lame->padding_type = g_value_get_int (value);
732 lame->extension = g_value_get_boolean (value);
735 lame->strict_iso = g_value_get_boolean (value);
737 case ARG_DISABLE_RESERVOIR:
738 lame->disable_reservoir = g_value_get_boolean (value);
741 lame->vbr = g_value_get_enum (value);
743 case ARG_VBR_QUALITY:
744 lame->vbr_quality = g_value_get_enum (value);
746 case ARG_VBR_MEAN_BITRATE:
747 lame->vbr_mean_bitrate = g_value_get_int (value);
749 case ARG_VBR_MIN_BITRATE:
750 lame->vbr_min_bitrate = g_value_get_int (value);
752 case ARG_VBR_MAX_BITRATE:
753 lame->vbr_max_bitrate = g_value_get_int (value);
755 case ARG_VBR_HARD_MIN:
756 lame->vbr_hard_min = g_value_get_int (value);
758 case ARG_LOWPASS_FREQ:
759 lame->lowpass_freq = g_value_get_int (value);
761 case ARG_LOWPASS_WIDTH:
762 lame->lowpass_width = g_value_get_int (value);
764 case ARG_HIGHPASS_FREQ:
765 lame->highpass_freq = g_value_get_int (value);
767 case ARG_HIGHPASS_WIDTH:
768 lame->highpass_width = g_value_get_int (value);
771 lame->ath_only = g_value_get_boolean (value);
774 lame->ath_short = g_value_get_boolean (value);
777 lame->no_ath = g_value_get_boolean (value);
780 lame->ath_lower = g_value_get_int (value);
783 lame->cwlimit = g_value_get_int (value);
785 case ARG_ALLOW_DIFF_SHORT:
786 lame->allow_diff_short = g_value_get_boolean (value);
788 case ARG_NO_SHORT_BLOCKS:
789 lame->no_short_blocks = g_value_get_boolean (value);
792 lame->emphasis = g_value_get_boolean (value);
795 lame->xingheader = g_value_get_boolean (value);
797 #ifdef GSTLAME_PRESET
799 lame->preset = g_value_get_enum (value);
809 gst_lame_get_property (GObject * object, guint prop_id, GValue * value,
814 g_return_if_fail (GST_IS_LAME (object));
816 lame = GST_LAME (object);
820 g_value_set_int (value, lame->bitrate);
822 case ARG_COMPRESSION_RATIO:
823 g_value_set_float (value, lame->compression_ratio);
826 g_value_set_enum (value, lame->quality);
829 g_value_set_enum (value, lame->mode);
832 g_value_set_boolean (value, lame->force_ms);
834 case ARG_FREE_FORMAT:
835 g_value_set_boolean (value, lame->free_format);
838 g_value_set_boolean (value, lame->copyright);
841 g_value_set_boolean (value, lame->original);
843 case ARG_ERROR_PROTECTION:
844 g_value_set_boolean (value, lame->error_protection);
846 case ARG_PADDING_TYPE:
847 g_value_set_enum (value, lame->padding_type);
850 g_value_set_boolean (value, lame->extension);
853 g_value_set_boolean (value, lame->strict_iso);
855 case ARG_DISABLE_RESERVOIR:
856 g_value_set_boolean (value, lame->disable_reservoir);
859 g_value_set_enum (value, lame->vbr);
861 case ARG_VBR_QUALITY:
862 g_value_set_enum (value, lame->vbr_quality);
864 case ARG_VBR_MEAN_BITRATE:
865 g_value_set_int (value, lame->vbr_mean_bitrate);
867 case ARG_VBR_MIN_BITRATE:
868 g_value_set_int (value, lame->vbr_min_bitrate);
870 case ARG_VBR_MAX_BITRATE:
871 g_value_set_int (value, lame->vbr_max_bitrate);
873 case ARG_VBR_HARD_MIN:
874 g_value_set_int (value, lame->vbr_hard_min);
876 case ARG_LOWPASS_FREQ:
877 g_value_set_int (value, lame->lowpass_freq);
879 case ARG_LOWPASS_WIDTH:
880 g_value_set_int (value, lame->lowpass_width);
882 case ARG_HIGHPASS_FREQ:
883 g_value_set_int (value, lame->highpass_freq);
885 case ARG_HIGHPASS_WIDTH:
886 g_value_set_int (value, lame->highpass_width);
889 g_value_set_boolean (value, lame->ath_only);
892 g_value_set_boolean (value, lame->ath_short);
895 g_value_set_boolean (value, lame->no_ath);
898 g_value_set_int (value, lame->ath_lower);
901 g_value_set_int (value, lame->cwlimit);
903 case ARG_ALLOW_DIFF_SHORT:
904 g_value_set_boolean (value, lame->allow_diff_short);
906 case ARG_NO_SHORT_BLOCKS:
907 g_value_set_boolean (value, lame->no_short_blocks);
910 g_value_set_boolean (value, lame->emphasis);
913 g_value_set_boolean (value, lame->xingheader);
915 #ifdef GSTLAME_PRESET
917 g_value_set_enum (value, lame->preset);
921 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
927 gst_lame_sink_event (GstPad * pad, GstEvent * event)
931 lame = GST_LAME (gst_pad_get_parent (pad));
933 switch (GST_EVENT_TYPE (event)) {
935 GST_DEBUG_OBJECT (lame, "handling EOS event");
936 /* FIXME, push last data packet */
938 gst_pad_push_event (lame->srcpad, event);
940 case GST_EVENT_FLUSH_START:
941 GST_DEBUG_OBJECT (lame, "handling FLUSH start event");
943 gst_pad_push_event (lame->srcpad, event);
946 case GST_EVENT_FLUSH_STOP:
948 guchar *mp3_data = NULL;
949 gint mp3_buffer_size, mp3_size = 0;
951 GST_DEBUG_OBJECT (lame, "handling FLUSH stop event");
954 mp3_buffer_size = 7200;
955 mp3_data = g_malloc (mp3_buffer_size);
956 mp3_size = lame_encode_flush (lame->lgf, mp3_data, mp3_buffer_size);
958 gst_pad_push_event (lame->srcpad, event);
962 GST_DEBUG_OBJECT (lame, "handling TAG event");
966 gst_event_parse_tag (event, &taglist),
967 gst_tag_list_insert (lame->tags, taglist,
968 gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (lame)));
970 g_assert_not_reached ();
972 gst_pad_push_event (lame->srcpad, event);
975 gst_pad_push_event (lame->srcpad, event);
982 gst_lame_chain (GstPad * pad, GstBuffer * buf)
986 gint mp3_buffer_size, mp3_size;
988 GstFlowReturn result;
993 lame = GST_LAME (gst_pad_get_parent (pad));
995 GST_LOG_OBJECT (lame, "entered chain");
1000 data = GST_BUFFER_DATA (buf);
1001 size = GST_BUFFER_SIZE (buf);
1003 num_samples = size / 2;
1005 /* allocate space for output */
1006 mp3_buffer_size = 1.25 * num_samples + 7200;
1007 mp3_data = g_malloc (mp3_buffer_size);
1009 /* lame seems to be too stupid to get mono interleaved going */
1010 if (lame->num_channels == 1) {
1011 mp3_size = lame_encode_buffer (lame->lgf,
1013 (short int *) data, num_samples, mp3_data, mp3_buffer_size);
1015 mp3_size = lame_encode_buffer_interleaved (lame->lgf,
1017 num_samples / lame->num_channels, mp3_data, mp3_buffer_size);
1020 GST_LOG_OBJECT (lame, "encoded %d bytes of audio to %d bytes of mp3",
1021 GST_BUFFER_SIZE (buf), mp3_size);
1023 duration = gst_util_uint64_scale_int (size, GST_SECOND,
1024 2 * lame->samplerate * lame->num_channels);
1026 if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE &&
1027 GST_BUFFER_DURATION (buf) != duration)
1028 GST_DEBUG_OBJECT (lame, "incoming buffer had incorrect duration %"
1029 GST_TIME_FORMAT "outgoing buffer will have correct duration %"
1031 GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_TIME_ARGS (duration));
1033 if (lame->last_ts == GST_CLOCK_TIME_NONE) {
1034 lame->last_ts = GST_BUFFER_TIMESTAMP (buf);
1035 lame->last_offs = GST_BUFFER_OFFSET (buf);
1036 lame->last_duration = duration;
1038 lame->last_duration += duration;
1041 gst_buffer_unref (buf);
1044 g_warning ("error %d", mp3_size);
1050 outbuf = gst_buffer_new ();
1051 GST_BUFFER_DATA (outbuf) = mp3_data;
1052 GST_BUFFER_MALLOCDATA (outbuf) = mp3_data;
1053 GST_BUFFER_SIZE (outbuf) = mp3_size;
1054 GST_BUFFER_TIMESTAMP (outbuf) = lame->last_ts;
1055 GST_BUFFER_OFFSET (outbuf) = lame->last_offs;
1056 GST_BUFFER_DURATION (outbuf) = lame->last_duration;
1057 gst_buffer_set_caps (outbuf, GST_PAD_CAPS (lame->srcpad));
1059 result = gst_pad_push (lame->srcpad, outbuf);
1061 lame->last_ts = GST_CLOCK_TIME_NONE;
1064 result = GST_FLOW_OK;
1066 gst_object_unref (lame);
1073 gst_buffer_unref (buf);
1074 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
1075 ("encoder not initialized (input is not audio?)"));
1076 gst_object_unref (lame);
1077 return GST_FLOW_ERROR;
1081 /* set up the encoder state */
1083 gst_lame_setup (GstLame * lame)
1085 #define CHECK_ERROR(command) G_STMT_START {\
1086 if ((command) < 0) { \
1087 GST_ERROR_OBJECT (lame, "setup failed: " G_STRINGIFY (command)); \
1093 GST_DEBUG_OBJECT (lame, "starting setup");
1095 /* check if we're already setup; if we are, we might want to check
1096 * if this initialization is compatible with the previous one */
1097 /* FIXME: do this */
1099 GST_WARNING_OBJECT (lame, "already setup");
1100 lame->setup = FALSE;
1103 lame->lgf = lame_init ();
1104 id3tag_init (lame->lgf);
1106 /* let lame choose a default samplerate */
1107 lame_set_out_samplerate (lame->lgf, 0);
1109 /* copy the parameters over */
1110 lame_set_in_samplerate (lame->lgf, lame->samplerate);
1112 /* force mono encoding if we only have one channel */
1113 if (lame->num_channels == 1)
1116 CHECK_ERROR (lame_set_num_channels (lame->lgf, lame->num_channels));
1117 CHECK_ERROR (lame_set_brate (lame->lgf, lame->bitrate));
1118 CHECK_ERROR (lame_set_compression_ratio (lame->lgf, lame->compression_ratio));
1119 CHECK_ERROR (lame_set_quality (lame->lgf, lame->quality));
1120 CHECK_ERROR (lame_set_mode (lame->lgf, lame->mode));
1121 CHECK_ERROR (lame_set_force_ms (lame->lgf, lame->force_ms));
1122 CHECK_ERROR (lame_set_free_format (lame->lgf, lame->free_format));
1123 CHECK_ERROR (lame_set_copyright (lame->lgf, lame->copyright));
1124 CHECK_ERROR (lame_set_original (lame->lgf, lame->original));
1125 CHECK_ERROR (lame_set_error_protection (lame->lgf, lame->error_protection));
1126 CHECK_ERROR (lame_set_padding_type (lame->lgf, lame->padding_type));
1127 CHECK_ERROR (lame_set_extension (lame->lgf, lame->extension));
1128 CHECK_ERROR (lame_set_strict_ISO (lame->lgf, lame->strict_iso));
1129 CHECK_ERROR (lame_set_disable_reservoir (lame->lgf, lame->disable_reservoir));
1130 CHECK_ERROR (lame_set_VBR (lame->lgf, lame->vbr));
1131 CHECK_ERROR (lame_set_VBR_q (lame->lgf, lame->vbr_quality));
1132 CHECK_ERROR (lame_set_VBR_mean_bitrate_kbps (lame->lgf,
1133 lame->vbr_mean_bitrate));
1134 CHECK_ERROR (lame_set_VBR_min_bitrate_kbps (lame->lgf,
1135 lame->vbr_min_bitrate));
1136 CHECK_ERROR (lame_set_VBR_max_bitrate_kbps (lame->lgf,
1137 lame->vbr_max_bitrate));
1138 CHECK_ERROR (lame_set_VBR_hard_min (lame->lgf, lame->vbr_hard_min));
1139 CHECK_ERROR (lame_set_lowpassfreq (lame->lgf, lame->lowpass_freq));
1140 CHECK_ERROR (lame_set_lowpasswidth (lame->lgf, lame->lowpass_width));
1141 CHECK_ERROR (lame_set_highpassfreq (lame->lgf, lame->highpass_freq));
1142 CHECK_ERROR (lame_set_highpasswidth (lame->lgf, lame->highpass_width));
1143 CHECK_ERROR (lame_set_ATHonly (lame->lgf, lame->ath_only));
1144 CHECK_ERROR (lame_set_ATHshort (lame->lgf, lame->ath_short));
1145 CHECK_ERROR (lame_set_noATH (lame->lgf, lame->no_ath));
1146 CHECK_ERROR (lame_set_ATHlower (lame->lgf, lame->ath_lower));
1147 CHECK_ERROR (lame_set_cwlimit (lame->lgf, lame->cwlimit));
1148 CHECK_ERROR (lame_set_allow_diff_short (lame->lgf, lame->allow_diff_short));
1149 CHECK_ERROR (lame_set_no_short_blocks (lame->lgf, lame->no_short_blocks));
1150 CHECK_ERROR (lame_set_emphasis (lame->lgf, lame->emphasis));
1151 CHECK_ERROR (lame_set_bWriteVbrTag (lame->lgf, lame->xingheader ? 1 : 0));
1152 #ifdef GSTLAME_PRESET
1153 if (lame->preset > 0) {
1154 CHECK_ERROR (lame_set_preset (lame->lgf, lame->preset));
1157 gst_lame_set_metadata (lame);
1159 /* initialize the lame encoder */
1160 if ((retval = lame_init_params (lame->lgf)) >= 0) {
1162 /* FIXME: it would be nice to print out the mode here */
1163 GST_INFO ("lame encoder setup (%d kbit/s, %d Hz, %d channels)",
1164 lame->bitrate, lame->samplerate, lame->num_channels);
1166 GST_ERROR_OBJECT (lame, "lame_init_params returned %d", retval);
1169 GST_DEBUG_OBJECT (lame, "done with setup");
1175 static GstStateChangeReturn
1176 gst_lame_change_state (GstElement * element, GstStateChange transition)
1179 GstStateChangeReturn result;
1181 lame = GST_LAME (element);
1183 switch (transition) {
1184 case GST_STATE_CHANGE_NULL_TO_READY:
1185 lame->tags = gst_tag_list_new ();
1186 case GST_STATE_CHANGE_READY_TO_PAUSED:
1187 lame->last_ts = GST_CLOCK_TIME_NONE;
1193 result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1195 switch (transition) {
1196 case GST_STATE_CHANGE_READY_TO_NULL:
1197 gst_tag_list_free (lame->tags);
1207 plugin_init (GstPlugin * plugin)
1209 if (!gst_element_register (plugin, "lame", GST_RANK_NONE, GST_TYPE_LAME))
1212 GST_DEBUG_CATEGORY_INIT (debug, "lame", 0, "lame mp3 encoder");
1216 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1219 "Encode MP3's with LAME",
1220 plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)