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 =
29 "L.A.M.E. mp3 encoder",
30 "Codec/Audio/Encoder",
32 "High-quality free MP3 encoder",
34 "Erik Walthinsen <omega@cse.ogi.edu>",
38 GST_PAD_TEMPLATE_FACTORY (gst_lame_sink_factory,
45 "endianness", GST_PROPS_INT (G_BYTE_ORDER),
46 "signed", GST_PROPS_BOOLEAN (TRUE),
47 "width", GST_PROPS_INT (16),
48 "depth", GST_PROPS_INT (16),
49 "rate", GST_PROPS_LIST (
51 GST_PROPS_INT (11025),
52 GST_PROPS_INT (12000),
53 GST_PROPS_INT (16000),
54 GST_PROPS_INT (22050),
55 GST_PROPS_INT (24000),
56 GST_PROPS_INT (32000),
57 GST_PROPS_INT (44100),
60 "channels", GST_PROPS_INT_RANGE (1, 2)
64 GST_PAD_TEMPLATE_FACTORY (gst_lame_src_factory,
71 "mpegversion", GST_PROPS_INT (1),
72 "layer", GST_PROPS_INT (3),
73 "rate", GST_PROPS_LIST (
75 GST_PROPS_INT (11025),
76 GST_PROPS_INT (12000),
77 GST_PROPS_INT (16000),
78 GST_PROPS_INT (22050),
79 GST_PROPS_INT (24000),
80 GST_PROPS_INT (32000),
81 GST_PROPS_INT (44100),
84 "channels", GST_PROPS_INT_RANGE (1, 2)
88 /********** Define useful types for non-programmatic interfaces **********/
89 #define GST_TYPE_LAME_MODE (gst_lame_mode_get_type())
91 gst_lame_mode_get_type (void)
93 static GType lame_mode_type = 0;
94 static GEnumValue lame_modes[] = {
96 { 1, "1", "Joint-Stereo" },
97 { 2, "2", "Dual channel" },
102 if (!lame_mode_type) {
103 lame_mode_type = g_enum_register_static ("GstLameMode", lame_modes);
105 return lame_mode_type;
108 #define GST_TYPE_LAME_QUALITY (gst_lame_quality_get_type())
110 gst_lame_quality_get_type (void)
112 static GType lame_quality_type = 0;
113 static GEnumValue lame_quality[] = {
114 { 0, "0", "0 - Best" },
119 { 5, "5", "5 - Default" },
123 { 9, "9", "9 - Worst" },
126 if (!lame_quality_type) {
127 lame_quality_type = g_enum_register_static ("GstLameQuality", lame_quality);
129 return lame_quality_type;
132 #define GST_TYPE_LAME_PADDING (gst_lame_padding_get_type())
134 gst_lame_padding_get_type (void)
136 static GType lame_padding_type = 0;
137 static GEnumValue lame_padding[] = {
138 { 0, "0", "No Padding" },
139 { 1, "1", "Always Pad" },
140 { 2, "2", "Adjust Padding" },
143 if (!lame_padding_type) {
144 lame_padding_type = g_enum_register_static ("GstLamePadding", lame_padding);
146 return lame_padding_type;
149 /********** Standard stuff for signals and arguments **********/
150 /* GstLame signals and args */
159 ARG_COMPRESSION_RATIO,
166 ARG_ERROR_PROTECTION,
170 ARG_DISABLE_RESERVOIR,
172 ARG_VBR_MEAN_BITRATE,
185 ARG_ALLOW_DIFF_SHORT,
192 static void gst_lame_class_init (GstLameClass *klass);
193 static void gst_lame_init (GstLame *gst_lame);
195 static void gst_lame_set_property (GObject *object, guint prop_id,
196 const GValue *value, GParamSpec *pspec);
197 static void gst_lame_get_property (GObject *object, guint prop_id,
198 GValue *value, GParamSpec *pspec);
199 static void gst_lame_chain (GstPad *pad, GstBuffer *buf);
200 static gboolean gst_lame_setup (GstLame *lame);
201 static GstElementStateReturn gst_lame_change_state (GstElement *element);
203 static GstElementClass *parent_class = NULL;
204 /* static guint gst_lame_signals[LAST_SIGNAL] = { 0 }; */
207 gst_lame_get_type (void)
209 static GType gst_lame_type = 0;
211 if (!gst_lame_type) {
212 static const GTypeInfo gst_lame_info = {
213 sizeof (GstLameClass),
216 (GClassInitFunc) gst_lame_class_init,
221 (GInstanceInitFunc) gst_lame_init,
223 gst_lame_type = g_type_register_static (GST_TYPE_ELEMENT, "GstLame", &gst_lame_info, 0);
225 return gst_lame_type;
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), ARG_COMPRESSION_RATIO,
243 g_param_spec_float ("compression_ratio", "Compression Ratio",
244 "choose bitrate to achive selected compression ratio",
245 1.0, 200.0, 11.0, G_PARAM_READWRITE));
246 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
247 g_param_spec_enum ("quality", "Quality", "Encoding Quality",
248 GST_TYPE_LAME_QUALITY, 5, G_PARAM_READWRITE));
249 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
250 g_param_spec_enum ("mode", "Mode", "Encoding mode",
251 GST_TYPE_LAME_MODE, 0, G_PARAM_READWRITE));
252 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FORCE_MS,
253 g_param_spec_boolean ("force_ms","Force ms","Force ms_stereo on all frames",
254 TRUE, G_PARAM_READWRITE));
255 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREE_FORMAT,
256 g_param_spec_boolean ("free_format","Free format","Produce a free format bitstream",
257 TRUE, G_PARAM_READWRITE));
258 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COPYRIGHT,
259 g_param_spec_boolean ("copyright","Copyright","Mark as copyright",
260 TRUE, G_PARAM_READWRITE));
261 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ORIGINAL,
262 g_param_spec_boolean("original", "Original", "Mark as non-original",
263 TRUE, G_PARAM_READWRITE));
264 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_PROTECTION,
265 g_param_spec_boolean ("error_protection","Error protection",
266 "Adds 16 bit checksum to every frame",
267 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",
273 TRUE, 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",
277 TRUE, G_PARAM_READWRITE));
278 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DISABLE_RESERVOIR,
279 g_param_spec_boolean ("disable_reservoir", "Disable reservoir", "Disable the bit reservoir",
280 TRUE, G_PARAM_READWRITE));
281 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
282 g_param_spec_boolean ("vbr", "VBR", "Use variable bitrate",
283 TRUE, G_PARAM_READWRITE));
284 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MEAN_BITRATE,
285 g_param_spec_int ("vbr_mean_bitrate", "VBR mean bitrate", "Specify mean bitrate",
286 0, G_MAXINT, 0, G_PARAM_READWRITE));
287 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MIN_BITRATE,
288 g_param_spec_int ("vbr_min_bitrate", "VBR min bitrate", "Specify min bitrate",
289 0, G_MAXINT, 0, G_PARAM_READWRITE));
290 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VBR_MAX_BITRATE,
291 g_param_spec_int ("vbr_max_bitrate", "VBR max bitrate", "Specify max bitrate",
292 0, G_MAXINT, 0, G_PARAM_READWRITE));
293 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VBR_HARD_MIN,
294 g_param_spec_int ("vbr_hard_min", "VBR hard min", "Specify hard min bitrate",
295 0, G_MAXINT, 0, G_PARAM_READWRITE));
296 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_FREQ,
297 g_param_spec_int ("lowpass_freq", "Lowpass freq",
298 "frequency(kHz), lowpass filter cutoff above freq",
299 0, 50000, 0, G_PARAM_READWRITE));
300 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_WIDTH,
301 g_param_spec_int ("lowpass_width", "Lowpass width",
302 "frequency(kHz) - default 15% of lowpass freq",
303 0, G_MAXINT, 0, G_PARAM_READWRITE));
304 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_FREQ,
305 g_param_spec_int ("highpass_freq", "Highpass freq",
306 "frequency(kHz), highpass filter cutoff below freq",
307 0, 50000, 0, G_PARAM_READWRITE));
308 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_WIDTH,
309 g_param_spec_int ("highpass_width", "Highpass width",
310 "frequency(kHz) - default 15% of highpass freq",
311 0, G_MAXINT, 0, G_PARAM_READWRITE));
312 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_ONLY,
313 g_param_spec_boolean ("ath_only", "ATH only",
314 "Ignore GPSYCHO completely, use ATH only",
315 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",
319 TRUE, 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", "turns ATH down to a flat noise floor",
322 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", "Compute tonality up to freq (in kHz) default 8.8717",
328 0, 50000, 0, G_PARAM_READWRITE));
329 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ALLOW_DIFF_SHORT,
330 g_param_spec_boolean ("allow_diff_short", "Allow diff short", "Allow diff short",
331 TRUE, G_PARAM_READWRITE));
332 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_SHORT_BLOCKS,
333 g_param_spec_boolean ("no_short_blocks", "No short blocks", "Do not use short blocks",
334 TRUE, G_PARAM_READWRITE));
335 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EMPHASIS,
336 g_param_spec_boolean ("emphasis", "Emphasis", "Emphasis",
337 TRUE, G_PARAM_READWRITE));
339 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_METADATA,
340 g_param_spec_boxed ("metadata", "Metadata", "Metadata to add to the stream,",
341 GST_TYPE_CAPS, G_PARAM_READWRITE));
344 gobject_class->set_property = gst_lame_set_property;
345 gobject_class->get_property = gst_lame_get_property;
347 gstelement_class->change_state = gst_lame_change_state;
350 static GstPadLinkReturn
351 gst_lame_sinkconnect (GstPad *pad, GstCaps *caps)
355 lame = GST_LAME (gst_pad_get_parent (pad));
357 if (!GST_CAPS_IS_FIXED (caps)) {
358 GST_DEBUG ("caps on lame pad %s:%s not fixed, delayed",
359 GST_DEBUG_PAD_NAME (pad));
360 return GST_PAD_LINK_DELAYED;
363 gst_caps_get_int (caps, "rate", &lame->samplerate);
364 gst_caps_get_int (caps, "channels", &lame->num_channels);
366 if (!gst_lame_setup (lame)) {
367 gst_element_error (GST_ELEMENT (lame),
368 "could not initialize encoder (wrong parameters?)");
369 return GST_PAD_LINK_REFUSED;
372 caps = GST_CAPS_NEW ("lame_src_caps",
374 "mpegversion", GST_PROPS_INT (1),
375 "layer", GST_PROPS_INT (3),
376 "channels", GST_PROPS_INT (lame->num_channels),
377 "rate", GST_PROPS_INT (lame->samplerate));
379 return gst_pad_try_set_caps (lame->srcpad, caps);
383 gst_lame_init (GstLame *lame)
385 GST_DEBUG_OBJECT (lame, "starting initialization");
387 lame->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (gst_lame_sink_factory), "sink");
388 gst_element_add_pad (GST_ELEMENT (lame), lame->sinkpad);
389 gst_pad_set_chain_function (lame->sinkpad, gst_lame_chain);
390 gst_pad_set_link_function (lame->sinkpad, gst_lame_sinkconnect);
392 lame->srcpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (gst_lame_src_factory), "src");
393 gst_element_add_pad (GST_ELEMENT (lame), lame->srcpad);
395 GST_FLAG_SET (lame, GST_ELEMENT_EVENT_AWARE);
397 GST_DEBUG ("setting up lame encoder");
398 lame->lgf = lame_init ();
400 lame->samplerate = 44100;
401 lame->num_channels = 2;
402 lame->initialized = FALSE;
404 lame->bitrate = lame_get_brate (lame->lgf);
405 lame->compression_ratio = lame_get_compression_ratio (lame->lgf);
406 lame->quality = lame_get_quality (lame->lgf);
407 lame->mode = lame_get_mode (lame->lgf);
408 lame->force_ms = lame_get_force_ms (lame->lgf);
409 lame->free_format = lame_get_free_format (lame->lgf);
410 lame->copyright = lame_get_copyright (lame->lgf);
411 lame->original = lame_get_original (lame->lgf);
412 lame->error_protection = lame_get_error_protection (lame->lgf);
413 lame->padding_type = lame_get_padding_type (lame->lgf);
414 lame->extension = lame_get_extension (lame->lgf);
415 lame->strict_iso = lame_get_strict_ISO (lame->lgf);
416 lame->disable_reservoir = lame_get_disable_reservoir (lame->lgf);
417 lame->vbr = lame_get_VBR_q (lame->lgf);
418 lame->vbr_mean_bitrate = lame_get_VBR_mean_bitrate_kbps (lame->lgf);
419 lame->vbr_min_bitrate = lame_get_VBR_min_bitrate_kbps (lame->lgf);
420 lame->vbr_max_bitrate = lame_get_VBR_max_bitrate_kbps (lame->lgf);
421 lame->vbr_hard_min = lame_get_VBR_hard_min (lame->lgf);
422 lame->lowpass_freq = lame_get_lowpassfreq (lame->lgf);
423 lame->lowpass_width = lame_get_lowpasswidth (lame->lgf);
424 lame->highpass_freq = lame_get_highpassfreq (lame->lgf);
425 lame->highpass_width = lame_get_highpasswidth (lame->lgf);
426 lame->ath_only = lame_get_ATHonly (lame->lgf);
427 lame->ath_short = lame_get_ATHshort (lame->lgf);
428 lame->no_ath = lame_get_noATH (lame->lgf);
429 /* lame->ath_type = lame_get_ATHtype (lame->lgf); */
430 lame->ath_lower = lame_get_ATHlower (lame->lgf);
431 lame->cwlimit = lame_get_cwlimit (lame->lgf);
432 lame->allow_diff_short = lame_get_allow_diff_short (lame->lgf);
433 lame->no_short_blocks = lame_get_no_short_blocks (lame->lgf);
434 lame->emphasis = lame_get_emphasis (lame->lgf);
436 lame->metadata = GST_CAPS_NEW (
438 "application/x-gst-metadata",
439 "comment", GST_PROPS_STRING ("Track encoded with GStreamer"),
440 "year", GST_PROPS_STRING (""),
441 "tracknumber", GST_PROPS_STRING (""),
442 "title", GST_PROPS_STRING (""),
443 "artist", GST_PROPS_STRING (""),
444 "album", GST_PROPS_STRING (""),
445 "genre", GST_PROPS_STRING ("")
448 id3tag_init (lame->lgf);
450 GST_DEBUG_OBJECT (lame, "done initializing");
454 gst_lame_add_metadata (GstLame *lame, GstCaps *caps)
462 props = gst_caps_get_props (caps)->properties;
464 prop = (GstPropsEntry*)(props->data);
465 props = g_list_next(props);
467 if (gst_props_entry_get_props_type (prop) == GST_PROPS_STRING_TYPE) {
468 const gchar *name = gst_props_entry_get_name (prop);
471 gst_props_entry_get_string (prop, &value);
473 if (!value || strlen (value) == 0)
476 if (strcmp (name, "comment") == 0) {
477 id3tag_set_comment (lame->lgf, value);
478 } else if (strcmp (name, "date") == 0) {
479 id3tag_set_year (lame->lgf, value);
480 } else if (strcmp (name, "tracknumber") == 0) {
481 id3tag_set_track (lame->lgf, value);
482 } else if (strcmp (name, "title") == 0) {
483 id3tag_set_title (lame->lgf, value);
484 } else if (strcmp (name, "artist") == 0) {
485 id3tag_set_artist (lame->lgf, value);
486 } else if (strcmp (name, "album") == 0) {
487 id3tag_set_album (lame->lgf, value);
488 } else if (strcmp (name, "genre") == 0) {
489 id3tag_set_genre (lame->lgf, value);
496 gst_lame_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
500 /* it's not null if we got it, but it might not be ours */
501 g_return_if_fail (GST_IS_LAME (object));
503 lame = GST_LAME (object);
507 lame->bitrate = g_value_get_int (value);
509 case ARG_COMPRESSION_RATIO:
510 lame->compression_ratio = g_value_get_float (value);
513 lame->quality = g_value_get_enum (value);
516 lame->mode = g_value_get_enum (value);
519 lame->force_ms = g_value_get_boolean (value);
521 case ARG_FREE_FORMAT:
522 lame->free_format = g_value_get_boolean (value);
525 lame->copyright = g_value_get_boolean (value);
528 lame->original = g_value_get_boolean (value);
530 case ARG_ERROR_PROTECTION:
531 lame->error_protection = g_value_get_boolean (value);
533 case ARG_PADDING_TYPE:
534 lame->padding_type = g_value_get_int (value);
537 lame->extension = g_value_get_boolean (value);
540 lame->strict_iso = g_value_get_boolean (value);
542 case ARG_DISABLE_RESERVOIR:
543 lame->disable_reservoir = g_value_get_boolean (value);
546 lame->vbr = g_value_get_boolean (value);
548 case ARG_VBR_MEAN_BITRATE:
549 lame->vbr_mean_bitrate = g_value_get_int (value);
551 case ARG_VBR_MIN_BITRATE:
552 lame->vbr_min_bitrate = g_value_get_int (value);
554 case ARG_VBR_MAX_BITRATE:
555 lame->vbr_max_bitrate = g_value_get_int (value);
557 case ARG_VBR_HARD_MIN:
558 lame->vbr_hard_min = g_value_get_int (value);
560 case ARG_LOWPASS_FREQ:
561 lame->lowpass_freq = g_value_get_int (value);
563 case ARG_LOWPASS_WIDTH:
564 lame->lowpass_width = g_value_get_int (value);
566 case ARG_HIGHPASS_FREQ:
567 lame->highpass_freq = g_value_get_int (value);
569 case ARG_HIGHPASS_WIDTH:
570 lame->highpass_width = g_value_get_int (value);
573 lame->ath_only = g_value_get_boolean (value);
576 lame->ath_short = g_value_get_boolean (value);
579 lame->no_ath = g_value_get_boolean (value);
582 lame->ath_lower = g_value_get_int (value);
585 lame->cwlimit = g_value_get_int (value);
587 case ARG_ALLOW_DIFF_SHORT:
588 lame->allow_diff_short = g_value_get_boolean (value);
590 case ARG_NO_SHORT_BLOCKS:
591 lame->no_short_blocks = g_value_get_boolean (value);
594 lame->emphasis = g_value_get_boolean (value);
597 lame->metadata = g_value_get_boxed (value);
606 gst_lame_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
610 /* it's not null if we got it, but it might not be ours */
611 g_return_if_fail (GST_IS_LAME (object));
613 lame = GST_LAME (object);
617 g_value_set_int (value, lame->bitrate);
619 case ARG_COMPRESSION_RATIO:
620 g_value_set_float (value, lame->compression_ratio);
623 g_value_set_enum (value, lame->quality);
626 g_value_set_enum (value, lame->mode);
629 g_value_set_boolean (value, lame->force_ms);
631 case ARG_FREE_FORMAT:
632 g_value_set_boolean (value, lame->free_format);
635 g_value_set_boolean (value, lame->copyright);
638 g_value_set_boolean (value, lame->original);
640 case ARG_ERROR_PROTECTION:
641 g_value_set_boolean (value, lame->error_protection);
643 case ARG_PADDING_TYPE:
644 g_value_set_enum (value, lame->padding_type);
647 g_value_set_boolean (value, lame->extension);
650 g_value_set_boolean (value, lame->strict_iso);
652 case ARG_DISABLE_RESERVOIR:
653 g_value_set_boolean (value, lame->disable_reservoir);
656 g_value_set_boolean (value, lame->vbr);
658 case ARG_VBR_MEAN_BITRATE:
659 g_value_set_int (value, lame->vbr_mean_bitrate);
661 case ARG_VBR_MIN_BITRATE:
662 g_value_set_int (value, lame->vbr_min_bitrate);
664 case ARG_VBR_MAX_BITRATE:
665 g_value_set_int (value, lame->vbr_max_bitrate);
667 case ARG_VBR_HARD_MIN:
668 g_value_set_int (value, lame->vbr_hard_min);
670 case ARG_LOWPASS_FREQ:
671 g_value_set_int (value, lame->lowpass_freq);
673 case ARG_LOWPASS_WIDTH:
674 g_value_set_int (value, lame->lowpass_width);
676 case ARG_HIGHPASS_FREQ:
677 g_value_set_int (value, lame->highpass_freq);
679 case ARG_HIGHPASS_WIDTH:
680 g_value_set_int (value, lame->highpass_width);
683 g_value_set_boolean (value, lame->ath_only);
686 g_value_set_boolean (value, lame->ath_short);
689 g_value_set_boolean (value, lame->no_ath);
692 g_value_set_int (value, lame->ath_lower);
695 g_value_set_int (value, lame->cwlimit);
697 case ARG_ALLOW_DIFF_SHORT:
698 g_value_set_boolean (value, lame->allow_diff_short);
700 case ARG_NO_SHORT_BLOCKS:
701 g_value_set_boolean (value, lame->no_short_blocks);
704 g_value_set_boolean (value, lame->emphasis);
707 g_value_set_static_boxed (value, lame->metadata);
710 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
716 gst_lame_chain (GstPad *pad, GstBuffer *buf)
720 gchar *mp3_data = NULL;
721 gint mp3_buffer_size, mp3_size = 0;
722 gboolean eos = FALSE;
724 lame = GST_LAME (gst_pad_get_parent (pad));
726 GST_DEBUG ("entered chain");
728 if (GST_IS_EVENT (buf)) {
729 switch (GST_EVENT_TYPE (buf)) {
732 case GST_EVENT_FLUSH:
733 mp3_buffer_size = 7200;
734 mp3_data = g_malloc (mp3_buffer_size);
736 mp3_size = lame_encode_flush (lame->lgf, mp3_data, mp3_buffer_size);
737 gst_event_unref (GST_EVENT (buf));
740 gst_pad_event_default (pad, GST_EVENT (buf));
747 if (!lame->initialized) {
748 gst_buffer_unref (buf);
749 gst_element_error (GST_ELEMENT (lame), "encoder not initialized (input is not audio?)");
753 /* allocate space for output */
754 mp3_buffer_size = ((GST_BUFFER_SIZE(buf) / (2+lame->num_channels)) * 1.25) + 7200;
755 mp3_data = g_malloc (mp3_buffer_size);
757 if (lame->num_channels == 2) {
758 mp3_size = lame_encode_buffer_interleaved (lame->lgf,
759 (short int *) (GST_BUFFER_DATA (buf)),
760 GST_BUFFER_SIZE (buf) / 4,
761 mp3_data, mp3_buffer_size);
764 mp3_size = lame_encode_buffer (lame->lgf,
765 (short int *) (GST_BUFFER_DATA (buf)),
766 (short int *) (GST_BUFFER_DATA (buf)),
767 GST_BUFFER_SIZE (buf) / 2,
768 mp3_data, mp3_buffer_size);
772 "encoded %d bytes of audio to %d bytes of mp3",
773 GST_BUFFER_SIZE (buf), mp3_size);
775 duration = (GST_SECOND * GST_BUFFER_SIZE (buf) /
776 (2 * lame->samplerate * lame->num_channels));
778 if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE &&
779 GST_BUFFER_DURATION (buf) != duration)
781 "mad: incoming buffer had incorrect duration %lld, "
782 "outgoing buffer will have correct duration %lld",
783 GST_BUFFER_DURATION (buf), duration);
785 if (lame->last_ts == GST_CLOCK_TIME_NONE) {
786 lame->last_ts = GST_BUFFER_TIMESTAMP (buf);
787 lame->last_offs = GST_BUFFER_OFFSET (buf);
788 lame->last_duration = duration;
790 lame->last_duration += duration;
793 gst_buffer_unref (buf);
797 outbuf = gst_buffer_new ();
798 GST_BUFFER_DATA (outbuf) = mp3_data;
799 GST_BUFFER_SIZE (outbuf) = mp3_size;
800 GST_BUFFER_TIMESTAMP (outbuf) = lame->last_ts;
801 GST_BUFFER_OFFSET (outbuf) = lame->last_offs;
802 GST_BUFFER_DURATION (outbuf) = lame->last_duration;
804 gst_pad_push (lame->srcpad,outbuf);
806 lame->last_ts = GST_CLOCK_TIME_NONE;
813 gst_pad_push (lame->srcpad, GST_BUFFER (gst_event_new (GST_EVENT_EOS)));
814 gst_element_set_eos (GST_ELEMENT (lame));
818 /* transition to the READY state by configuring the gst_lame encoder */
820 gst_lame_setup (GstLame *lame)
822 GST_DEBUG_OBJECT (lame, "starting setup");
824 /* check if we're already initialized; if we are, we might want to check
825 * if this initialization is compatible with the previous one */
827 if (lame->initialized)
828 g_warning ("already initialized");
830 /* copy the parameters over */
831 lame_set_in_samplerate (lame->lgf, lame->samplerate);
833 /* force mono encoding if we only have one channel */
834 if (lame->num_channels == 1)
837 lame_set_brate (lame->lgf, lame->bitrate);
838 lame_set_compression_ratio (lame->lgf, lame->compression_ratio);
839 lame_set_quality (lame->lgf, lame->quality);
840 lame_set_mode (lame->lgf, lame->mode);
841 lame_set_force_ms (lame->lgf, lame->force_ms);
842 lame_set_free_format (lame->lgf, lame->free_format);
843 lame_set_copyright (lame->lgf, lame->copyright);
844 lame_set_original (lame->lgf, lame->original);
845 lame_set_error_protection (lame->lgf, lame->error_protection);
846 lame_set_padding_type (lame->lgf, lame->padding_type);
847 lame_set_extension (lame->lgf, lame->extension);
848 lame_set_strict_ISO (lame->lgf, lame->strict_iso);
849 lame_set_disable_reservoir (lame->lgf, lame->disable_reservoir);
850 lame_set_VBR_q (lame->lgf, lame->vbr);
851 lame_set_VBR_mean_bitrate_kbps (lame->lgf, lame->vbr_mean_bitrate);
852 lame_set_VBR_min_bitrate_kbps (lame->lgf, lame->vbr_min_bitrate);
853 lame_set_VBR_max_bitrate_kbps (lame->lgf, lame->vbr_max_bitrate);
854 lame_set_VBR_hard_min (lame->lgf, lame->vbr_hard_min);
855 lame_set_lowpassfreq (lame->lgf, lame->lowpass_freq);
856 lame_set_lowpasswidth (lame->lgf, lame->lowpass_width);
857 lame_set_highpassfreq (lame->lgf, lame->highpass_freq);
858 lame_set_highpasswidth (lame->lgf, lame->highpass_width);
859 lame_set_ATHonly (lame->lgf, lame->ath_only);
860 lame_set_ATHshort (lame->lgf, lame->ath_short);
861 lame_set_noATH (lame->lgf, lame->no_ath);
862 lame_set_ATHlower (lame->lgf, lame->ath_lower);
863 lame_set_cwlimit (lame->lgf, lame->cwlimit);
864 lame_set_allow_diff_short (lame->lgf, lame->allow_diff_short);
865 lame_set_no_short_blocks (lame->lgf, lame->no_short_blocks);
866 lame_set_emphasis (lame->lgf, lame->emphasis);
868 gst_lame_add_metadata (lame, lame->metadata);
870 /* initialize the lame encoder */
871 if (lame_init_params (lame->lgf) < 0) {
872 lame->initialized = FALSE;
875 lame->initialized = TRUE;
876 /* FIXME: it would be nice to print out the mode here */
878 "lame encoder initialized (%d kbit/s, %d Hz, %d channels)",
879 lame->bitrate, lame->samplerate, lame->num_channels);
882 GST_DEBUG_OBJECT (lame, "done with setup");
884 return lame->initialized;
887 static GstElementStateReturn
888 gst_lame_change_state (GstElement *element)
892 g_return_val_if_fail (GST_IS_LAME (element), GST_STATE_FAILURE);
894 lame = GST_LAME (element);
896 GST_DEBUG ("state pending %d", GST_STATE_PENDING (element));
898 switch (GST_STATE_TRANSITION (element)) {
899 case GST_STATE_READY_TO_PAUSED:
900 lame->last_ts = GST_CLOCK_TIME_NONE;
902 case GST_STATE_READY_TO_NULL:
903 if (lame->initialized) {
904 lame_close (lame->lgf);
905 lame->initialized = FALSE;
912 /* if we haven't failed already, give the parent class a chance to ;-) */
913 if (GST_ELEMENT_CLASS (parent_class)->change_state)
914 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
916 return GST_STATE_SUCCESS;
920 plugin_init (GModule *module, GstPlugin *plugin)
922 GstElementFactory *factory;
924 /* create an elementfactory for the gst_lame element */
925 factory = gst_element_factory_new ("lame", GST_TYPE_LAME,
927 g_return_val_if_fail (factory != NULL, FALSE);
929 /* register the source's padtemplate */
930 gst_element_factory_add_pad_template (factory,
931 GST_PAD_TEMPLATE_GET (gst_lame_src_factory));
933 /* register the sink's padtemplate */
934 gst_element_factory_add_pad_template (factory,
935 GST_PAD_TEMPLATE_GET (gst_lame_sink_factory));
937 /* and add the gst_lame element factory to the plugin */
938 gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
943 GstPluginDesc plugin_desc = {