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/Audio/Encoder",
30 "High-quality free MP3 encoder",
31 "Erik Walthinsen <omega@cse.ogi.edu>",
34 static GstStaticPadTemplate gst_lame_sink_template =
35 GST_STATIC_PAD_TEMPLATE ("sink",
38 GST_STATIC_CAPS ("audio/x-raw-int, "
39 "endianness = (int) BYTE_ORDER, "
40 "signed = (boolean) true, "
43 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
44 "channels = (int) [ 1, 2 ]")
47 static GstStaticPadTemplate gst_lame_src_template =
48 GST_STATIC_PAD_TEMPLATE ("src",
51 GST_STATIC_CAPS ("audio/mpeg, "
52 "mpegversion = (int) 1, "
54 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
55 "channels = (int) [ 1, 2 ]")
58 /********** Define useful types for non-programmatic interfaces **********/
59 #define GST_TYPE_LAME_MODE (gst_lame_mode_get_type())
61 gst_lame_mode_get_type (void)
63 static GType lame_mode_type = 0;
64 static GEnumValue lame_modes[] = {
66 {1, "1", "Joint-Stereo"},
67 {2, "2", "Dual channel"},
73 if (!lame_mode_type) {
74 lame_mode_type = g_enum_register_static ("GstLameMode", lame_modes);
76 return lame_mode_type;
79 #define GST_TYPE_LAME_QUALITY (gst_lame_quality_get_type())
81 gst_lame_quality_get_type (void)
83 static GType lame_quality_type = 0;
84 static GEnumValue lame_quality[] = {
90 {5, "5", "5 - Default"},
94 {9, "9", "9 - Worst"},
98 if (!lame_quality_type) {
99 lame_quality_type = g_enum_register_static ("GstLameQuality", lame_quality);
101 return lame_quality_type;
104 #define GST_TYPE_LAME_PADDING (gst_lame_padding_get_type())
106 gst_lame_padding_get_type (void)
108 static GType lame_padding_type = 0;
109 static GEnumValue lame_padding[] = {
110 {0, "0", "No Padding"},
111 {1, "1", "Always Pad"},
112 {2, "2", "Adjust Padding"},
116 if (!lame_padding_type) {
117 lame_padding_type = g_enum_register_static ("GstLamePadding", lame_padding);
119 return lame_padding_type;
122 /********** Standard stuff for signals and arguments **********/
123 /* GstLame signals and args */
134 ARG_COMPRESSION_RATIO,
141 ARG_ERROR_PROTECTION,
145 ARG_DISABLE_RESERVOIR,
147 ARG_VBR_MEAN_BITRATE,
160 ARG_ALLOW_DIFF_SHORT,
165 static void gst_lame_base_init (gpointer g_class);
166 static void gst_lame_class_init (GstLameClass * klass);
167 static void gst_lame_init (GstLame * gst_lame);
169 static void gst_lame_set_property (GObject * object, guint prop_id,
170 const GValue * value, GParamSpec * pspec);
171 static void gst_lame_get_property (GObject * object, guint prop_id,
172 GValue * value, GParamSpec * pspec);
173 static void gst_lame_chain (GstPad * pad, GstData * _data);
174 static gboolean gst_lame_setup (GstLame * lame);
175 static GstElementStateReturn gst_lame_change_state (GstElement * element);
177 static GstElementClass *parent_class = NULL;
179 /* static guint gst_lame_signals[LAST_SIGNAL] = { 0 }; */
182 gst_lame_get_type (void)
184 static GType gst_lame_type = 0;
186 if (!gst_lame_type) {
187 static const GTypeInfo gst_lame_info = {
188 sizeof (GstLameClass),
191 (GClassInitFunc) gst_lame_class_init,
196 (GInstanceInitFunc) gst_lame_init,
199 static const GInterfaceInfo tag_setter_info = {
206 g_type_register_static (GST_TYPE_ELEMENT, "GstLame", &gst_lame_info, 0);
207 g_type_add_interface_static (gst_lame_type, GST_TYPE_TAG_SETTER,
211 return gst_lame_type;
215 gst_lame_base_init (gpointer g_class)
217 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
219 gst_element_class_add_pad_template (element_class,
220 gst_static_pad_template_get (&gst_lame_src_template));
221 gst_element_class_add_pad_template (element_class,
222 gst_static_pad_template_get (&gst_lame_sink_template));
223 gst_element_class_set_details (element_class, &gst_lame_details);
227 gst_lame_class_init (GstLameClass * klass)
229 GObjectClass *gobject_class;
230 GstElementClass *gstelement_class;
232 gobject_class = (GObjectClass *) klass;
233 gstelement_class = (GstElementClass *) klass;
235 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
237 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
238 g_param_spec_int ("bitrate", "Bitrate (kb/s)", "Bitrate in kbit/sec",
239 8, 320, 128, G_PARAM_READWRITE));
240 g_object_class_install_property (G_OBJECT_CLASS (klass),
241 ARG_COMPRESSION_RATIO, g_param_spec_float ("compression_ratio",
243 "choose bitrate to achive selected compression ratio", 1.0, 200.0,
244 11.0, G_PARAM_READWRITE));
245 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
246 g_param_spec_enum ("quality", "Quality", "Encoding Quality",
247 GST_TYPE_LAME_QUALITY, 5, G_PARAM_READWRITE));
248 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
249 g_param_spec_enum ("mode", "Mode", "Encoding mode", GST_TYPE_LAME_MODE, 0,
251 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FORCE_MS,
252 g_param_spec_boolean ("force_ms", "Force ms",
253 "Force ms_stereo on all frames", TRUE, G_PARAM_READWRITE));
254 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREE_FORMAT,
255 g_param_spec_boolean ("free_format", "Free format",
256 "Produce a free format bitstream", TRUE, G_PARAM_READWRITE));
257 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COPYRIGHT,
258 g_param_spec_boolean ("copyright", "Copyright", "Mark as copyright", TRUE,
260 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ORIGINAL,
261 g_param_spec_boolean ("original", "Original", "Mark as non-original",
262 TRUE, G_PARAM_READWRITE));
263 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_PROTECTION,
264 g_param_spec_boolean ("error_protection", "Error protection",
265 "Adds 16 bit checksum to every frame", TRUE, G_PARAM_READWRITE));
266 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PADDING_TYPE,
267 g_param_spec_enum ("padding_type", "Padding type", "Padding type",
268 GST_TYPE_LAME_PADDING, 0, G_PARAM_READWRITE));
269 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EXTENSION,
270 g_param_spec_boolean ("extension", "Extension", "Extension", TRUE,
272 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STRICT_ISO,
273 g_param_spec_boolean ("strict_iso", "Strict ISO",
274 "Comply as much as possible to ISO MPEG spec", TRUE,
276 g_object_class_install_property (G_OBJECT_CLASS (klass),
277 ARG_DISABLE_RESERVOIR, g_param_spec_boolean ("disable_reservoir",
278 "Disable reservoir", "Disable the bit reservoir", TRUE,
280 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
281 g_param_spec_boolean ("vbr", "VBR", "Use variable bitrate", TRUE,
283 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MEAN_BITRATE,
284 g_param_spec_int ("vbr_mean_bitrate", "VBR mean bitrate",
285 "Specify mean bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
286 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MIN_BITRATE,
287 g_param_spec_int ("vbr_min_bitrate", "VBR min bitrate",
288 "Specify min bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
289 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MAX_BITRATE,
290 g_param_spec_int ("vbr_max_bitrate", "VBR max bitrate",
291 "Specify max bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
292 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_HARD_MIN,
293 g_param_spec_int ("vbr_hard_min", "VBR hard min",
294 "Specify hard min bitrate", 0, G_MAXINT, 0, G_PARAM_READWRITE));
295 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_FREQ,
296 g_param_spec_int ("lowpass_freq", "Lowpass freq",
297 "frequency(kHz), lowpass filter cutoff above freq", 0, 50000, 0,
299 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_WIDTH,
300 g_param_spec_int ("lowpass_width", "Lowpass width",
301 "frequency(kHz) - default 15% of lowpass freq", 0, G_MAXINT, 0,
303 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_FREQ,
304 g_param_spec_int ("highpass_freq", "Highpass freq",
305 "frequency(kHz), highpass filter cutoff below freq", 0, 50000, 0,
307 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_WIDTH,
308 g_param_spec_int ("highpass_width", "Highpass width",
309 "frequency(kHz) - default 15% of highpass freq", 0, G_MAXINT, 0,
311 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_ONLY,
312 g_param_spec_boolean ("ath_only", "ATH only",
313 "Ignore GPSYCHO completely, use ATH only", TRUE, G_PARAM_READWRITE));
314 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_SHORT,
315 g_param_spec_boolean ("ath_short", "ATH short",
316 "Ignore GPSYCHO for short blocks, use ATH only", TRUE,
318 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_ATH,
319 g_param_spec_boolean ("no_ath", "No ath",
320 "turns ATH down to a flat noise floor", TRUE, G_PARAM_READWRITE));
321 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_LOWER,
322 g_param_spec_int ("ath_lower", "ATH lower", "lowers ATH by x dB",
323 G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
324 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CWLIMIT,
325 g_param_spec_int ("cwlimit", "Cwlimit",
326 "Compute tonality up to freq (in kHz) default 8.8717", 0, 50000, 0,
328 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ALLOW_DIFF_SHORT,
329 g_param_spec_boolean ("allow_diff_short", "Allow diff short",
330 "Allow diff short", TRUE, G_PARAM_READWRITE));
331 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_SHORT_BLOCKS,
332 g_param_spec_boolean ("no_short_blocks", "No short blocks",
333 "Do not use short blocks", TRUE, G_PARAM_READWRITE));
334 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EMPHASIS,
335 g_param_spec_boolean ("emphasis", "Emphasis", "Emphasis", TRUE,
338 gobject_class->set_property = gst_lame_set_property;
339 gobject_class->get_property = gst_lame_get_property;
341 gstelement_class->change_state = gst_lame_change_state;
344 static GstPadLinkReturn
345 gst_lame_sink_link (GstPad * pad, const GstCaps * caps)
349 GstStructure *structure;
352 lame = GST_LAME (gst_pad_get_parent (pad));
353 structure = gst_caps_get_structure (caps, 0);
355 gst_structure_get_int (structure, "rate", &lame->samplerate);
356 gst_structure_get_int (structure, "channels", &lame->num_channels);
358 if (!gst_lame_setup (lame)) {
359 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
360 ("could not initialize encoder (wrong parameters?)"));
361 return GST_PAD_LINK_REFUSED;
364 out_samplerate = lame_get_out_samplerate (lame->lgf);
366 gst_caps_new_simple ("audio/mpeg",
367 "mpegversion", G_TYPE_INT, 1,
368 "layer", G_TYPE_INT, 3,
369 "channels", G_TYPE_INT, lame->num_channels,
370 "rate", G_TYPE_INT, out_samplerate, NULL);
372 return gst_pad_try_set_caps (lame->srcpad, othercaps);
376 gst_lame_init (GstLame * lame)
378 GST_DEBUG_OBJECT (lame, "starting initialization");
381 gst_pad_new_from_template (gst_static_pad_template_get
382 (&gst_lame_sink_template), "sink");
383 gst_element_add_pad (GST_ELEMENT (lame), lame->sinkpad);
384 gst_pad_set_chain_function (lame->sinkpad, gst_lame_chain);
385 gst_pad_set_link_function (lame->sinkpad, gst_lame_sink_link);
388 gst_pad_new_from_template (gst_static_pad_template_get
389 (&gst_lame_src_template), "src");
390 gst_element_add_pad (GST_ELEMENT (lame), lame->srcpad);
392 GST_FLAG_SET (lame, GST_ELEMENT_EVENT_AWARE);
394 GST_DEBUG ("setting up lame encoder");
395 lame->lgf = lame_init ();
397 lame->samplerate = 44100;
398 lame->num_channels = 2;
399 lame->initialized = FALSE;
401 lame->bitrate = 128; /* lame_get_brate (lame->lgf); => 0/out of range */
402 lame->compression_ratio = 5; /* lame_get_compression_ratio (lame->lgf); => 0/out of range */
403 lame->quality = 5; /* lame_get_quality (lame->lgf); => -1/out of range */
404 lame->mode = lame_get_mode (lame->lgf);
405 lame->force_ms = lame_get_force_ms (lame->lgf);
406 lame->free_format = lame_get_free_format (lame->lgf);
407 lame->copyright = lame_get_copyright (lame->lgf);
408 lame->original = lame_get_original (lame->lgf);
409 lame->error_protection = lame_get_error_protection (lame->lgf);
410 lame->padding_type = lame_get_padding_type (lame->lgf);
411 lame->extension = lame_get_extension (lame->lgf);
412 lame->strict_iso = lame_get_strict_ISO (lame->lgf);
413 lame->disable_reservoir = lame_get_disable_reservoir (lame->lgf);
414 lame->vbr = lame_get_VBR_q (lame->lgf);
415 lame->vbr_mean_bitrate = lame_get_VBR_mean_bitrate_kbps (lame->lgf);
416 lame->vbr_min_bitrate = lame_get_VBR_min_bitrate_kbps (lame->lgf);
417 lame->vbr_max_bitrate = 320; /* lame_get_VBR_max_bitrate_kbps (lame->lgf); => 0/no vbr possible */
418 lame->vbr_hard_min = lame_get_VBR_hard_min (lame->lgf);
419 lame->lowpass_freq = 50000; /* lame_get_lowpassfreq (lame->lgf); => 0/lowpass on everything ? */
420 lame->lowpass_width = 0; /* lame_get_lowpasswidth (lame->lgf); => -1/out of range */
421 lame->highpass_freq = lame_get_highpassfreq (lame->lgf);
422 lame->highpass_width = 0; /* lame_get_highpasswidth (lame->lgf); => -1/out of range */
423 lame->ath_only = lame_get_ATHonly (lame->lgf);
424 lame->ath_short = lame_get_ATHshort (lame->lgf);
425 lame->no_ath = lame_get_noATH (lame->lgf);
426 /* lame->ath_type = lame_get_ATHtype (lame->lgf); */
427 lame->ath_lower = lame_get_ATHlower (lame->lgf);
428 lame->cwlimit = 8.8717; /* lame_get_cwlimit (lame->lgf); => 0 */
429 lame->allow_diff_short = lame_get_allow_diff_short (lame->lgf);
430 lame->no_short_blocks = lame_get_no_short_blocks (lame->lgf);
431 lame->emphasis = lame_get_emphasis (lame->lgf);
432 lame->tags = gst_tag_list_new ();
434 id3tag_init (lame->lgf);
436 GST_DEBUG_OBJECT (lame, "done initializing");
439 typedef struct _GstLameTagMatch GstLameTagMatch;
440 typedef void (*GstLameTagFunc) (lame_global_flags * gfp, const char *value);
442 struct _GstLameTagMatch
444 gchar *gstreamer_tag;
445 GstLameTagFunc tag_func;
448 static GstLameTagMatch tag_matches[] = {
449 {GST_TAG_TITLE, id3tag_set_title},
450 {GST_TAG_DATE, id3tag_set_year},
451 {GST_TAG_TRACK_NUMBER, id3tag_set_track},
452 {GST_TAG_COMMENT, id3tag_set_comment},
453 {GST_TAG_ARTIST, id3tag_set_artist},
454 {GST_TAG_ALBUM, id3tag_set_album},
455 {GST_TAG_GENRE, (GstLameTagFunc) id3tag_set_genre},
460 add_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data)
466 lame = GST_LAME (user_data);
467 g_return_if_fail (lame != NULL);
469 while (tag_matches[i].gstreamer_tag != NULL) {
470 if (strcmp (tag, tag_matches[i].gstreamer_tag) == 0) {
476 if (tag_matches[i].tag_func == NULL) {
477 g_print ("Couldn't find matching gstreamer tag for %s\n", tag);
481 switch (gst_tag_get_type (tag)) {
485 if (!gst_tag_list_get_uint (list, tag, &ivalue)) {
486 GST_DEBUG ("Error reading \"%s\" tag value\n", tag);
489 value = g_strdup_printf ("%u", ivalue);
493 if (!gst_tag_list_get_string (list, tag, &value)) {
494 GST_DEBUG ("Error reading \"%s\" tag value\n", tag);
499 GST_DEBUG ("Couldn't write tag %s", tag);
503 tag_matches[i].tag_func (lame->lgf, value);
505 if (gst_tag_get_type (tag) == G_TYPE_UINT) {
511 gst_lame_set_metadata (GstLame * lame)
513 const GstTagList *user_tags;
516 g_return_if_fail (lame != NULL);
517 user_tags = gst_tag_setter_get_list (GST_TAG_SETTER (lame));
518 if ((lame->tags == NULL) && (user_tags == NULL)) {
521 copy = gst_tag_list_merge (user_tags, lame->tags,
522 gst_tag_setter_get_merge_mode (GST_TAG_SETTER (lame)));
523 gst_tag_list_foreach ((GstTagList *) copy, add_one_tag, lame);
525 gst_tag_list_free (copy);
531 gst_lame_set_property (GObject * object, guint prop_id, const GValue * value,
536 /* it's not null if we got it, but it might not be ours */
537 g_return_if_fail (GST_IS_LAME (object));
539 lame = GST_LAME (object);
543 lame->bitrate = g_value_get_int (value);
545 case ARG_COMPRESSION_RATIO:
546 lame->compression_ratio = g_value_get_float (value);
549 lame->quality = g_value_get_enum (value);
552 lame->mode = g_value_get_enum (value);
555 lame->force_ms = g_value_get_boolean (value);
557 case ARG_FREE_FORMAT:
558 lame->free_format = g_value_get_boolean (value);
561 lame->copyright = g_value_get_boolean (value);
564 lame->original = g_value_get_boolean (value);
566 case ARG_ERROR_PROTECTION:
567 lame->error_protection = g_value_get_boolean (value);
569 case ARG_PADDING_TYPE:
570 lame->padding_type = g_value_get_int (value);
573 lame->extension = g_value_get_boolean (value);
576 lame->strict_iso = g_value_get_boolean (value);
578 case ARG_DISABLE_RESERVOIR:
579 lame->disable_reservoir = g_value_get_boolean (value);
582 lame->vbr = g_value_get_boolean (value);
584 case ARG_VBR_MEAN_BITRATE:
585 lame->vbr_mean_bitrate = g_value_get_int (value);
587 case ARG_VBR_MIN_BITRATE:
588 lame->vbr_min_bitrate = g_value_get_int (value);
590 case ARG_VBR_MAX_BITRATE:
591 lame->vbr_max_bitrate = g_value_get_int (value);
593 case ARG_VBR_HARD_MIN:
594 lame->vbr_hard_min = g_value_get_int (value);
596 case ARG_LOWPASS_FREQ:
597 lame->lowpass_freq = g_value_get_int (value);
599 case ARG_LOWPASS_WIDTH:
600 lame->lowpass_width = g_value_get_int (value);
602 case ARG_HIGHPASS_FREQ:
603 lame->highpass_freq = g_value_get_int (value);
605 case ARG_HIGHPASS_WIDTH:
606 lame->highpass_width = g_value_get_int (value);
609 lame->ath_only = g_value_get_boolean (value);
612 lame->ath_short = g_value_get_boolean (value);
615 lame->no_ath = g_value_get_boolean (value);
618 lame->ath_lower = g_value_get_int (value);
621 lame->cwlimit = g_value_get_int (value);
623 case ARG_ALLOW_DIFF_SHORT:
624 lame->allow_diff_short = g_value_get_boolean (value);
626 case ARG_NO_SHORT_BLOCKS:
627 lame->no_short_blocks = g_value_get_boolean (value);
630 lame->emphasis = g_value_get_boolean (value);
639 gst_lame_get_property (GObject * object, guint prop_id, GValue * value,
644 /* it's not null if we got it, but it might not be ours */
645 g_return_if_fail (GST_IS_LAME (object));
647 lame = GST_LAME (object);
651 g_value_set_int (value, lame->bitrate);
653 case ARG_COMPRESSION_RATIO:
654 g_value_set_float (value, lame->compression_ratio);
657 g_value_set_enum (value, lame->quality);
660 g_value_set_enum (value, lame->mode);
663 g_value_set_boolean (value, lame->force_ms);
665 case ARG_FREE_FORMAT:
666 g_value_set_boolean (value, lame->free_format);
669 g_value_set_boolean (value, lame->copyright);
672 g_value_set_boolean (value, lame->original);
674 case ARG_ERROR_PROTECTION:
675 g_value_set_boolean (value, lame->error_protection);
677 case ARG_PADDING_TYPE:
678 g_value_set_enum (value, lame->padding_type);
681 g_value_set_boolean (value, lame->extension);
684 g_value_set_boolean (value, lame->strict_iso);
686 case ARG_DISABLE_RESERVOIR:
687 g_value_set_boolean (value, lame->disable_reservoir);
690 g_value_set_boolean (value, lame->vbr);
692 case ARG_VBR_MEAN_BITRATE:
693 g_value_set_int (value, lame->vbr_mean_bitrate);
695 case ARG_VBR_MIN_BITRATE:
696 g_value_set_int (value, lame->vbr_min_bitrate);
698 case ARG_VBR_MAX_BITRATE:
699 g_value_set_int (value, lame->vbr_max_bitrate);
701 case ARG_VBR_HARD_MIN:
702 g_value_set_int (value, lame->vbr_hard_min);
704 case ARG_LOWPASS_FREQ:
705 g_value_set_int (value, lame->lowpass_freq);
707 case ARG_LOWPASS_WIDTH:
708 g_value_set_int (value, lame->lowpass_width);
710 case ARG_HIGHPASS_FREQ:
711 g_value_set_int (value, lame->highpass_freq);
713 case ARG_HIGHPASS_WIDTH:
714 g_value_set_int (value, lame->highpass_width);
717 g_value_set_boolean (value, lame->ath_only);
720 g_value_set_boolean (value, lame->ath_short);
723 g_value_set_boolean (value, lame->no_ath);
726 g_value_set_int (value, lame->ath_lower);
729 g_value_set_int (value, lame->cwlimit);
731 case ARG_ALLOW_DIFF_SHORT:
732 g_value_set_boolean (value, lame->allow_diff_short);
734 case ARG_NO_SHORT_BLOCKS:
735 g_value_set_boolean (value, lame->no_short_blocks);
738 g_value_set_boolean (value, lame->emphasis);
741 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
747 gst_lame_chain (GstPad * pad, GstData * _data)
749 GstBuffer *buf = GST_BUFFER (_data);
752 gchar *mp3_data = NULL;
753 gint mp3_buffer_size, mp3_size = 0;
754 gboolean eos = FALSE;
756 lame = GST_LAME (gst_pad_get_parent (pad));
758 GST_DEBUG ("entered chain");
760 if (GST_IS_EVENT (buf)) {
761 switch (GST_EVENT_TYPE (buf)) {
764 case GST_EVENT_FLUSH:
765 mp3_buffer_size = 7200;
766 mp3_data = g_malloc (mp3_buffer_size);
768 mp3_size = lame_encode_flush (lame->lgf, mp3_data, mp3_buffer_size);
769 gst_event_unref (GST_EVENT (buf));
773 gst_tag_list_insert (lame->tags,
774 gst_event_tag_get_list (GST_EVENT (buf)),
775 gst_tag_setter_get_merge_mode (GST_TAG_SETTER (lame)));
777 g_assert_not_reached ();
779 // gst_pad_event_default (pad, GST_EVENT (buf));
782 gst_pad_event_default (pad, GST_EVENT (buf));
788 if (!lame->initialized) {
789 gst_buffer_unref (buf);
790 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
791 ("encoder not initialized (input is not audio?)"));
795 /* allocate space for output */
797 ((GST_BUFFER_SIZE (buf) / (2 + lame->num_channels)) * 1.25) + 7200;
798 mp3_data = g_malloc (mp3_buffer_size);
800 mp3_size = lame_encode_buffer_interleaved (lame->lgf,
801 (short int *) (GST_BUFFER_DATA (buf)),
802 GST_BUFFER_SIZE (buf) / 2 / lame->num_channels,
803 mp3_data, mp3_buffer_size);
805 GST_DEBUG ("encoded %d bytes of audio to %d bytes of mp3",
806 GST_BUFFER_SIZE (buf), mp3_size);
808 duration = (GST_SECOND * GST_BUFFER_SIZE (buf) /
809 (2 * lame->samplerate * lame->num_channels));
811 if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE &&
812 GST_BUFFER_DURATION (buf) != duration)
813 GST_DEBUG ("mad: incoming buffer had incorrect duration %lld, "
814 "outgoing buffer will have correct duration %lld",
815 GST_BUFFER_DURATION (buf), duration);
817 if (lame->last_ts == GST_CLOCK_TIME_NONE) {
818 lame->last_ts = GST_BUFFER_TIMESTAMP (buf);
819 lame->last_offs = GST_BUFFER_OFFSET (buf);
820 lame->last_duration = duration;
822 lame->last_duration += duration;
825 gst_buffer_unref (buf);
829 outbuf = gst_buffer_new ();
830 GST_BUFFER_DATA (outbuf) = mp3_data;
831 GST_BUFFER_SIZE (outbuf) = mp3_size;
832 GST_BUFFER_TIMESTAMP (outbuf) = lame->last_ts;
833 GST_BUFFER_OFFSET (outbuf) = lame->last_offs;
834 GST_BUFFER_DURATION (outbuf) = lame->last_duration;
836 gst_pad_push (lame->srcpad, GST_DATA (outbuf));
838 lame->last_ts = GST_CLOCK_TIME_NONE;
844 gst_pad_push (lame->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
845 gst_element_set_eos (GST_ELEMENT (lame));
849 /* transition to the READY state by configuring the gst_lame encoder */
851 gst_lame_setup (GstLame * lame)
853 GST_DEBUG_OBJECT (lame, "starting setup");
855 /* check if we're already initialized; if we are, we might want to check
856 * if this initialization is compatible with the previous one */
858 if (lame->initialized)
859 g_warning ("already initialized");
861 /* copy the parameters over */
862 lame_set_in_samplerate (lame->lgf, lame->samplerate);
864 /* force mono encoding if we only have one channel */
865 if (lame->num_channels == 1)
868 lame_set_brate (lame->lgf, lame->bitrate);
869 lame_set_compression_ratio (lame->lgf, lame->compression_ratio);
870 lame_set_quality (lame->lgf, lame->quality);
871 lame_set_mode (lame->lgf, lame->mode);
872 lame_set_force_ms (lame->lgf, lame->force_ms);
873 lame_set_free_format (lame->lgf, lame->free_format);
874 lame_set_copyright (lame->lgf, lame->copyright);
875 lame_set_original (lame->lgf, lame->original);
876 lame_set_error_protection (lame->lgf, lame->error_protection);
877 lame_set_padding_type (lame->lgf, lame->padding_type);
878 lame_set_extension (lame->lgf, lame->extension);
879 lame_set_strict_ISO (lame->lgf, lame->strict_iso);
880 lame_set_disable_reservoir (lame->lgf, lame->disable_reservoir);
881 lame_set_VBR_q (lame->lgf, lame->vbr);
882 lame_set_VBR_mean_bitrate_kbps (lame->lgf, lame->vbr_mean_bitrate);
883 lame_set_VBR_min_bitrate_kbps (lame->lgf, lame->vbr_min_bitrate);
884 lame_set_VBR_max_bitrate_kbps (lame->lgf, lame->vbr_max_bitrate);
885 lame_set_VBR_hard_min (lame->lgf, lame->vbr_hard_min);
886 lame_set_lowpassfreq (lame->lgf, lame->lowpass_freq);
887 lame_set_lowpasswidth (lame->lgf, lame->lowpass_width);
888 lame_set_highpassfreq (lame->lgf, lame->highpass_freq);
889 lame_set_highpasswidth (lame->lgf, lame->highpass_width);
890 lame_set_ATHonly (lame->lgf, lame->ath_only);
891 lame_set_ATHshort (lame->lgf, lame->ath_short);
892 lame_set_noATH (lame->lgf, lame->no_ath);
893 lame_set_ATHlower (lame->lgf, lame->ath_lower);
894 lame_set_cwlimit (lame->lgf, lame->cwlimit);
895 lame_set_allow_diff_short (lame->lgf, lame->allow_diff_short);
896 lame_set_no_short_blocks (lame->lgf, lame->no_short_blocks);
897 lame_set_emphasis (lame->lgf, lame->emphasis);
899 gst_lame_set_metadata (lame);
901 /* initialize the lame encoder */
902 if (lame_init_params (lame->lgf) < 0) {
903 lame->initialized = FALSE;
905 lame->initialized = TRUE;
906 /* FIXME: it would be nice to print out the mode here */
907 GST_INFO ("lame encoder initialized (%d kbit/s, %d Hz, %d channels)",
908 lame->bitrate, lame->samplerate, lame->num_channels);
911 GST_DEBUG_OBJECT (lame, "done with setup");
913 return lame->initialized;
916 static GstElementStateReturn
917 gst_lame_change_state (GstElement * element)
921 g_return_val_if_fail (GST_IS_LAME (element), GST_STATE_FAILURE);
923 lame = GST_LAME (element);
925 GST_DEBUG ("state pending %d", GST_STATE_PENDING (element));
927 switch (GST_STATE_TRANSITION (element)) {
928 case GST_STATE_READY_TO_PAUSED:
929 lame->last_ts = GST_CLOCK_TIME_NONE;
931 case GST_STATE_READY_TO_NULL:
932 if (lame->initialized) {
933 lame_close (lame->lgf);
934 lame->initialized = FALSE;
941 /* if we haven't failed already, give the parent class a chance to ;-) */
942 if (GST_ELEMENT_CLASS (parent_class)->change_state)
943 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
945 return GST_STATE_SUCCESS;
949 plugin_init (GstPlugin * plugin)
951 if (!gst_element_register (plugin, "lame", GST_RANK_NONE, GST_TYPE_LAME))
957 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
960 "Encode MP3's with LAME",
961 plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)