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",
31 "High-quality free MP3 encoder",
32 "Erik Walthinsen <omega@cse.ogi.edu>",
35 static GstStaticPadTemplate gst_lame_sink_template =
36 GST_STATIC_PAD_TEMPLATE (
42 "endianness = (int) BYTE_ORDER, "
43 "signed = (boolean) true, "
46 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
47 "channels = (int) [ 1, 2 ]"
51 static GstStaticPadTemplate gst_lame_src_template =
52 GST_STATIC_PAD_TEMPLATE (
58 "mpegversion = (int) 1, "
60 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, "
61 "channels = (int) [ 1, 2 ]"
65 /********** Define useful types for non-programmatic interfaces **********/
66 #define GST_TYPE_LAME_MODE (gst_lame_mode_get_type())
68 gst_lame_mode_get_type (void)
70 static GType lame_mode_type = 0;
71 static GEnumValue lame_modes[] = {
73 { 1, "1", "Joint-Stereo" },
74 { 2, "2", "Dual channel" },
79 if (!lame_mode_type) {
80 lame_mode_type = g_enum_register_static ("GstLameMode", lame_modes);
82 return lame_mode_type;
85 #define GST_TYPE_LAME_QUALITY (gst_lame_quality_get_type())
87 gst_lame_quality_get_type (void)
89 static GType lame_quality_type = 0;
90 static GEnumValue lame_quality[] = {
91 { 0, "0", "0 - Best" },
96 { 5, "5", "5 - Default" },
100 { 9, "9", "9 - Worst" },
103 if (!lame_quality_type) {
104 lame_quality_type = g_enum_register_static ("GstLameQuality", lame_quality);
106 return lame_quality_type;
109 #define GST_TYPE_LAME_PADDING (gst_lame_padding_get_type())
111 gst_lame_padding_get_type (void)
113 static GType lame_padding_type = 0;
114 static GEnumValue lame_padding[] = {
115 { 0, "0", "No Padding" },
116 { 1, "1", "Always Pad" },
117 { 2, "2", "Adjust Padding" },
120 if (!lame_padding_type) {
121 lame_padding_type = g_enum_register_static ("GstLamePadding", lame_padding);
123 return lame_padding_type;
126 /********** Standard stuff for signals and arguments **********/
127 /* 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;
180 /* static guint gst_lame_signals[LAST_SIGNAL] = { 0 }; */
183 gst_lame_get_type (void)
185 static GType gst_lame_type = 0;
187 if (!gst_lame_type) {
188 static const GTypeInfo gst_lame_info = {
189 sizeof (GstLameClass),
192 (GClassInitFunc) gst_lame_class_init,
197 (GInstanceInitFunc) gst_lame_init,
200 static const GInterfaceInfo tag_setter_info = {
206 gst_lame_type = 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, &tag_setter_info);
210 return gst_lame_type;
214 gst_lame_base_init (gpointer g_class)
216 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
218 gst_element_class_add_pad_template (element_class,
219 gst_static_pad_template_get (&gst_lame_src_template));
220 gst_element_class_add_pad_template (element_class,
221 gst_static_pad_template_get (&gst_lame_sink_template));
222 gst_element_class_set_details (element_class, &gst_lame_details);
226 gst_lame_class_init (GstLameClass *klass)
228 GObjectClass *gobject_class;
229 GstElementClass *gstelement_class;
231 gobject_class = (GObjectClass*)klass;
232 gstelement_class = (GstElementClass*)klass;
234 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
236 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
237 g_param_spec_int("bitrate", "Bitrate (kb/s)", "Bitrate in kbit/sec",
238 8, 320, 128, G_PARAM_READWRITE));
239 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COMPRESSION_RATIO,
240 g_param_spec_float ("compression_ratio", "Compression Ratio",
241 "choose bitrate to achive selected compression ratio",
242 1.0, 200.0, 11.0, G_PARAM_READWRITE));
243 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
244 g_param_spec_enum ("quality", "Quality", "Encoding Quality",
245 GST_TYPE_LAME_QUALITY, 5, G_PARAM_READWRITE));
246 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
247 g_param_spec_enum ("mode", "Mode", "Encoding mode",
248 GST_TYPE_LAME_MODE, 0, G_PARAM_READWRITE));
249 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FORCE_MS,
250 g_param_spec_boolean ("force_ms","Force ms","Force ms_stereo on all frames",
251 TRUE, G_PARAM_READWRITE));
252 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREE_FORMAT,
253 g_param_spec_boolean ("free_format","Free format","Produce a free format bitstream",
254 TRUE, G_PARAM_READWRITE));
255 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COPYRIGHT,
256 g_param_spec_boolean ("copyright","Copyright","Mark as copyright",
257 TRUE, G_PARAM_READWRITE));
258 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ORIGINAL,
259 g_param_spec_boolean("original", "Original", "Mark as non-original",
260 TRUE, G_PARAM_READWRITE));
261 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_PROTECTION,
262 g_param_spec_boolean ("error_protection","Error protection",
263 "Adds 16 bit checksum to every frame",
264 TRUE, G_PARAM_READWRITE));
265 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PADDING_TYPE,
266 g_param_spec_enum ("padding_type", "Padding type", "Padding type",
267 GST_TYPE_LAME_PADDING, 0, G_PARAM_READWRITE));
268 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EXTENSION,
269 g_param_spec_boolean ("extension", "Extension", "Extension",
270 TRUE, G_PARAM_READWRITE));
271 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STRICT_ISO,
272 g_param_spec_boolean ("strict_iso", "Strict ISO",
273 "Comply as much as possible to ISO MPEG spec",
274 TRUE, G_PARAM_READWRITE));
275 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DISABLE_RESERVOIR,
276 g_param_spec_boolean ("disable_reservoir", "Disable reservoir", "Disable the bit reservoir",
277 TRUE, G_PARAM_READWRITE));
278 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
279 g_param_spec_boolean ("vbr", "VBR", "Use variable bitrate",
280 TRUE, G_PARAM_READWRITE));
281 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MEAN_BITRATE,
282 g_param_spec_int ("vbr_mean_bitrate", "VBR mean bitrate", "Specify mean bitrate",
283 0, G_MAXINT, 0, G_PARAM_READWRITE));
284 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MIN_BITRATE,
285 g_param_spec_int ("vbr_min_bitrate", "VBR min bitrate", "Specify min bitrate",
286 0, G_MAXINT, 0, G_PARAM_READWRITE));
287 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VBR_MAX_BITRATE,
288 g_param_spec_int ("vbr_max_bitrate", "VBR max bitrate", "Specify max bitrate",
289 0, G_MAXINT, 0, G_PARAM_READWRITE));
290 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VBR_HARD_MIN,
291 g_param_spec_int ("vbr_hard_min", "VBR hard min", "Specify hard min bitrate",
292 0, G_MAXINT, 0, G_PARAM_READWRITE));
293 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_FREQ,
294 g_param_spec_int ("lowpass_freq", "Lowpass freq",
295 "frequency(kHz), lowpass filter cutoff above freq",
296 0, 50000, 0, G_PARAM_READWRITE));
297 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWPASS_WIDTH,
298 g_param_spec_int ("lowpass_width", "Lowpass width",
299 "frequency(kHz) - default 15% of lowpass freq",
300 0, G_MAXINT, 0, G_PARAM_READWRITE));
301 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_FREQ,
302 g_param_spec_int ("highpass_freq", "Highpass freq",
303 "frequency(kHz), highpass filter cutoff below freq",
304 0, 50000, 0, G_PARAM_READWRITE));
305 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HIGHPASS_WIDTH,
306 g_param_spec_int ("highpass_width", "Highpass width",
307 "frequency(kHz) - default 15% of highpass freq",
308 0, G_MAXINT, 0, G_PARAM_READWRITE));
309 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_ONLY,
310 g_param_spec_boolean ("ath_only", "ATH only",
311 "Ignore GPSYCHO completely, use ATH only",
312 TRUE, G_PARAM_READWRITE));
313 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_SHORT,
314 g_param_spec_boolean ("ath_short", "ATH short",
315 "Ignore GPSYCHO for short blocks, use ATH only",
316 TRUE, G_PARAM_READWRITE));
317 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_ATH,
318 g_param_spec_boolean ("no_ath", "No ath", "turns ATH down to a flat noise floor",
319 TRUE, G_PARAM_READWRITE));
320 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_LOWER,
321 g_param_spec_int ("ath_lower", "ATH lower", "lowers ATH by x dB",
322 G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
323 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CWLIMIT,
324 g_param_spec_int ("cwlimit", "Cwlimit", "Compute tonality up to freq (in kHz) default 8.8717",
325 0, 50000, 0, G_PARAM_READWRITE));
326 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ALLOW_DIFF_SHORT,
327 g_param_spec_boolean ("allow_diff_short", "Allow diff short", "Allow diff short",
328 TRUE, G_PARAM_READWRITE));
329 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NO_SHORT_BLOCKS,
330 g_param_spec_boolean ("no_short_blocks", "No short blocks", "Do not use short blocks",
331 TRUE, G_PARAM_READWRITE));
332 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EMPHASIS,
333 g_param_spec_boolean ("emphasis", "Emphasis", "Emphasis",
334 TRUE, G_PARAM_READWRITE));
336 gobject_class->set_property = gst_lame_set_property;
337 gobject_class->get_property = gst_lame_get_property;
339 gstelement_class->change_state = gst_lame_change_state;
342 static GstPadLinkReturn
343 gst_lame_sink_link (GstPad *pad, const GstCaps *caps)
347 GstStructure *structure;
350 lame = GST_LAME (gst_pad_get_parent (pad));
351 structure = gst_caps_get_structure (caps, 0);
353 gst_structure_get_int (structure, "rate", &lame->samplerate);
354 gst_structure_get_int (structure, "channels", &lame->num_channels);
356 if (!gst_lame_setup (lame)) {
357 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
358 ("could not initialize encoder (wrong parameters?)"));
359 return GST_PAD_LINK_REFUSED;
362 out_samplerate = lame_get_out_samplerate (lame->lgf);
364 gst_caps_new_simple (
366 "mpegversion", G_TYPE_INT, 1,
367 "layer", G_TYPE_INT, 3,
368 "channels", G_TYPE_INT, lame->num_channels,
369 "rate", G_TYPE_INT, out_samplerate,
373 return gst_pad_try_set_caps (lame->srcpad, othercaps);
377 gst_lame_init (GstLame *lame)
379 GST_DEBUG_OBJECT (lame, "starting initialization");
381 lame->sinkpad = gst_pad_new_from_template (
382 gst_static_pad_template_get (&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);
387 lame->srcpad = gst_pad_new_from_template (
388 gst_static_pad_template_get (&gst_lame_src_template), "src");
389 gst_element_add_pad (GST_ELEMENT (lame), lame->srcpad);
391 GST_FLAG_SET (lame, GST_ELEMENT_EVENT_AWARE);
393 GST_DEBUG ("setting up lame encoder");
394 lame->lgf = lame_init ();
396 lame->samplerate = 44100;
397 lame->num_channels = 2;
398 lame->initialized = FALSE;
400 lame->bitrate = lame_get_brate (lame->lgf);
401 lame->compression_ratio = lame_get_compression_ratio (lame->lgf);
402 lame->quality = lame_get_quality (lame->lgf);
403 lame->mode = lame_get_mode (lame->lgf);
404 lame->force_ms = lame_get_force_ms (lame->lgf);
405 lame->free_format = lame_get_free_format (lame->lgf);
406 lame->copyright = lame_get_copyright (lame->lgf);
407 lame->original = lame_get_original (lame->lgf);
408 lame->error_protection = lame_get_error_protection (lame->lgf);
409 lame->padding_type = lame_get_padding_type (lame->lgf);
410 lame->extension = lame_get_extension (lame->lgf);
411 lame->strict_iso = lame_get_strict_ISO (lame->lgf);
412 lame->disable_reservoir = lame_get_disable_reservoir (lame->lgf);
413 lame->vbr = lame_get_VBR_q (lame->lgf);
414 lame->vbr_mean_bitrate = lame_get_VBR_mean_bitrate_kbps (lame->lgf);
415 lame->vbr_min_bitrate = lame_get_VBR_min_bitrate_kbps (lame->lgf);
416 lame->vbr_max_bitrate = lame_get_VBR_max_bitrate_kbps (lame->lgf);
417 lame->vbr_hard_min = lame_get_VBR_hard_min (lame->lgf);
418 lame->lowpass_freq = lame_get_lowpassfreq (lame->lgf);
419 lame->lowpass_width = lame_get_lowpasswidth (lame->lgf);
420 lame->highpass_freq = lame_get_highpassfreq (lame->lgf);
421 lame->highpass_width = lame_get_highpasswidth (lame->lgf);
422 lame->ath_only = lame_get_ATHonly (lame->lgf);
423 lame->ath_short = lame_get_ATHshort (lame->lgf);
424 lame->no_ath = lame_get_noATH (lame->lgf);
425 /* lame->ath_type = lame_get_ATHtype (lame->lgf); */
426 lame->ath_lower = lame_get_ATHlower (lame->lgf);
427 lame->cwlimit = lame_get_cwlimit (lame->lgf);
428 lame->allow_diff_short = lame_get_allow_diff_short (lame->lgf);
429 lame->no_short_blocks = lame_get_no_short_blocks (lame->lgf);
430 lame->emphasis = lame_get_emphasis (lame->lgf);
431 lame->tags = gst_tag_list_new ();
433 id3tag_init (lame->lgf);
435 GST_DEBUG_OBJECT (lame, "done initializing");
438 typedef struct _GstLameTagMatch GstLameTagMatch;
439 typedef void (*GstLameTagFunc)(lame_global_flags* gfp, const char *value);
441 struct _GstLameTagMatch
443 gchar *gstreamer_tag;
444 GstLameTagFunc tag_func;
447 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,
467 lame = GST_LAME (user_data);
468 g_return_if_fail (lame != NULL);
470 while (tag_matches[i].gstreamer_tag != NULL) {
471 if (strcmp (tag, tag_matches[i].gstreamer_tag) == 0) {
477 if (tag_matches[i].tag_func == NULL) {
478 g_print ("Couldn't find matching gstreamer tag for %s\n", tag);
482 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, GParamSpec *pspec)
535 /* it's not null if we got it, but it might not be ours */
536 g_return_if_fail (GST_IS_LAME (object));
538 lame = GST_LAME (object);
542 lame->bitrate = g_value_get_int (value);
544 case ARG_COMPRESSION_RATIO:
545 lame->compression_ratio = g_value_get_float (value);
548 lame->quality = g_value_get_enum (value);
551 lame->mode = g_value_get_enum (value);
554 lame->force_ms = g_value_get_boolean (value);
556 case ARG_FREE_FORMAT:
557 lame->free_format = g_value_get_boolean (value);
560 lame->copyright = g_value_get_boolean (value);
563 lame->original = g_value_get_boolean (value);
565 case ARG_ERROR_PROTECTION:
566 lame->error_protection = g_value_get_boolean (value);
568 case ARG_PADDING_TYPE:
569 lame->padding_type = g_value_get_int (value);
572 lame->extension = g_value_get_boolean (value);
575 lame->strict_iso = g_value_get_boolean (value);
577 case ARG_DISABLE_RESERVOIR:
578 lame->disable_reservoir = g_value_get_boolean (value);
581 lame->vbr = g_value_get_boolean (value);
583 case ARG_VBR_MEAN_BITRATE:
584 lame->vbr_mean_bitrate = g_value_get_int (value);
586 case ARG_VBR_MIN_BITRATE:
587 lame->vbr_min_bitrate = g_value_get_int (value);
589 case ARG_VBR_MAX_BITRATE:
590 lame->vbr_max_bitrate = g_value_get_int (value);
592 case ARG_VBR_HARD_MIN:
593 lame->vbr_hard_min = g_value_get_int (value);
595 case ARG_LOWPASS_FREQ:
596 lame->lowpass_freq = g_value_get_int (value);
598 case ARG_LOWPASS_WIDTH:
599 lame->lowpass_width = g_value_get_int (value);
601 case ARG_HIGHPASS_FREQ:
602 lame->highpass_freq = g_value_get_int (value);
604 case ARG_HIGHPASS_WIDTH:
605 lame->highpass_width = g_value_get_int (value);
608 lame->ath_only = g_value_get_boolean (value);
611 lame->ath_short = g_value_get_boolean (value);
614 lame->no_ath = g_value_get_boolean (value);
617 lame->ath_lower = g_value_get_int (value);
620 lame->cwlimit = g_value_get_int (value);
622 case ARG_ALLOW_DIFF_SHORT:
623 lame->allow_diff_short = g_value_get_boolean (value);
625 case ARG_NO_SHORT_BLOCKS:
626 lame->no_short_blocks = g_value_get_boolean (value);
629 lame->emphasis = g_value_get_boolean (value);
638 gst_lame_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
642 /* it's not null if we got it, but it might not be ours */
643 g_return_if_fail (GST_IS_LAME (object));
645 lame = GST_LAME (object);
649 g_value_set_int (value, lame->bitrate);
651 case ARG_COMPRESSION_RATIO:
652 g_value_set_float (value, lame->compression_ratio);
655 g_value_set_enum (value, lame->quality);
658 g_value_set_enum (value, lame->mode);
661 g_value_set_boolean (value, lame->force_ms);
663 case ARG_FREE_FORMAT:
664 g_value_set_boolean (value, lame->free_format);
667 g_value_set_boolean (value, lame->copyright);
670 g_value_set_boolean (value, lame->original);
672 case ARG_ERROR_PROTECTION:
673 g_value_set_boolean (value, lame->error_protection);
675 case ARG_PADDING_TYPE:
676 g_value_set_enum (value, lame->padding_type);
679 g_value_set_boolean (value, lame->extension);
682 g_value_set_boolean (value, lame->strict_iso);
684 case ARG_DISABLE_RESERVOIR:
685 g_value_set_boolean (value, lame->disable_reservoir);
688 g_value_set_boolean (value, lame->vbr);
690 case ARG_VBR_MEAN_BITRATE:
691 g_value_set_int (value, lame->vbr_mean_bitrate);
693 case ARG_VBR_MIN_BITRATE:
694 g_value_set_int (value, lame->vbr_min_bitrate);
696 case ARG_VBR_MAX_BITRATE:
697 g_value_set_int (value, lame->vbr_max_bitrate);
699 case ARG_VBR_HARD_MIN:
700 g_value_set_int (value, lame->vbr_hard_min);
702 case ARG_LOWPASS_FREQ:
703 g_value_set_int (value, lame->lowpass_freq);
705 case ARG_LOWPASS_WIDTH:
706 g_value_set_int (value, lame->lowpass_width);
708 case ARG_HIGHPASS_FREQ:
709 g_value_set_int (value, lame->highpass_freq);
711 case ARG_HIGHPASS_WIDTH:
712 g_value_set_int (value, lame->highpass_width);
715 g_value_set_boolean (value, lame->ath_only);
718 g_value_set_boolean (value, lame->ath_short);
721 g_value_set_boolean (value, lame->no_ath);
724 g_value_set_int (value, lame->ath_lower);
727 g_value_set_int (value, lame->cwlimit);
729 case ARG_ALLOW_DIFF_SHORT:
730 g_value_set_boolean (value, lame->allow_diff_short);
732 case ARG_NO_SHORT_BLOCKS:
733 g_value_set_boolean (value, lame->no_short_blocks);
736 g_value_set_boolean (value, lame->emphasis);
739 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
745 gst_lame_chain (GstPad *pad, GstData *_data)
747 GstBuffer *buf = GST_BUFFER (_data);
750 gchar *mp3_data = NULL;
751 gint mp3_buffer_size, mp3_size = 0;
752 gboolean eos = FALSE;
754 lame = GST_LAME (gst_pad_get_parent (pad));
756 GST_DEBUG ("entered chain");
758 if (GST_IS_EVENT (buf)) {
759 switch (GST_EVENT_TYPE (buf)) {
762 case GST_EVENT_FLUSH:
763 mp3_buffer_size = 7200;
764 mp3_data = g_malloc (mp3_buffer_size);
766 mp3_size = lame_encode_flush (lame->lgf, mp3_data, mp3_buffer_size);
767 gst_event_unref (GST_EVENT (buf));
771 gst_tag_list_insert (lame->tags, gst_event_tag_get_list (GST_EVENT (buf)),
772 gst_tag_setter_get_merge_mode (GST_TAG_SETTER (lame)));
774 g_assert_not_reached ();
776 // gst_pad_event_default (pad, GST_EVENT (buf));
779 gst_pad_event_default (pad, GST_EVENT (buf));
786 if (!lame->initialized) {
787 gst_buffer_unref (buf);
788 GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL),
789 ("encoder not initialized (input is not audio?)"));
793 /* allocate space for output */
794 mp3_buffer_size = ((GST_BUFFER_SIZE(buf) / (2+lame->num_channels)) * 1.25) + 7200;
795 mp3_data = g_malloc (mp3_buffer_size);
797 if (lame->num_channels == 2) {
798 mp3_size = lame_encode_buffer_interleaved (lame->lgf,
799 (short int *) (GST_BUFFER_DATA (buf)),
800 GST_BUFFER_SIZE (buf) / 4,
801 mp3_data, mp3_buffer_size);
804 mp3_size = lame_encode_buffer (lame->lgf,
805 (short int *) (GST_BUFFER_DATA (buf)),
806 (short int *) (GST_BUFFER_DATA (buf)),
807 GST_BUFFER_SIZE (buf) / 2,
808 mp3_data, mp3_buffer_size);
812 "encoded %d bytes of audio to %d bytes of mp3",
813 GST_BUFFER_SIZE (buf), mp3_size);
815 duration = (GST_SECOND * GST_BUFFER_SIZE (buf) /
816 (2 * lame->samplerate * lame->num_channels));
818 if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE &&
819 GST_BUFFER_DURATION (buf) != duration)
821 "mad: incoming buffer had incorrect duration %lld, "
822 "outgoing buffer will have correct duration %lld",
823 GST_BUFFER_DURATION (buf), duration);
825 if (lame->last_ts == GST_CLOCK_TIME_NONE) {
826 lame->last_ts = GST_BUFFER_TIMESTAMP (buf);
827 lame->last_offs = GST_BUFFER_OFFSET (buf);
828 lame->last_duration = duration;
830 lame->last_duration += duration;
833 gst_buffer_unref (buf);
837 outbuf = gst_buffer_new ();
838 GST_BUFFER_DATA (outbuf) = mp3_data;
839 GST_BUFFER_SIZE (outbuf) = mp3_size;
840 GST_BUFFER_TIMESTAMP (outbuf) = lame->last_ts;
841 GST_BUFFER_OFFSET (outbuf) = lame->last_offs;
842 GST_BUFFER_DURATION (outbuf) = lame->last_duration;
844 gst_pad_push (lame->srcpad,GST_DATA (outbuf));
846 lame->last_ts = GST_CLOCK_TIME_NONE;
853 gst_pad_push (lame->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
854 gst_element_set_eos (GST_ELEMENT (lame));
858 /* transition to the READY state by configuring the gst_lame encoder */
860 gst_lame_setup (GstLame *lame)
862 GST_DEBUG_OBJECT (lame, "starting setup");
864 /* check if we're already initialized; if we are, we might want to check
865 * if this initialization is compatible with the previous one */
867 if (lame->initialized)
868 g_warning ("already initialized");
870 /* copy the parameters over */
871 lame_set_in_samplerate (lame->lgf, lame->samplerate);
873 /* force mono encoding if we only have one channel */
874 if (lame->num_channels == 1)
877 lame_set_brate (lame->lgf, lame->bitrate);
878 lame_set_compression_ratio (lame->lgf, lame->compression_ratio);
879 lame_set_quality (lame->lgf, lame->quality);
880 lame_set_mode (lame->lgf, lame->mode);
881 lame_set_force_ms (lame->lgf, lame->force_ms);
882 lame_set_free_format (lame->lgf, lame->free_format);
883 lame_set_copyright (lame->lgf, lame->copyright);
884 lame_set_original (lame->lgf, lame->original);
885 lame_set_error_protection (lame->lgf, lame->error_protection);
886 lame_set_padding_type (lame->lgf, lame->padding_type);
887 lame_set_extension (lame->lgf, lame->extension);
888 lame_set_strict_ISO (lame->lgf, lame->strict_iso);
889 lame_set_disable_reservoir (lame->lgf, lame->disable_reservoir);
890 lame_set_VBR_q (lame->lgf, lame->vbr);
891 lame_set_VBR_mean_bitrate_kbps (lame->lgf, lame->vbr_mean_bitrate);
892 lame_set_VBR_min_bitrate_kbps (lame->lgf, lame->vbr_min_bitrate);
893 lame_set_VBR_max_bitrate_kbps (lame->lgf, lame->vbr_max_bitrate);
894 lame_set_VBR_hard_min (lame->lgf, lame->vbr_hard_min);
895 lame_set_lowpassfreq (lame->lgf, lame->lowpass_freq);
896 lame_set_lowpasswidth (lame->lgf, lame->lowpass_width);
897 lame_set_highpassfreq (lame->lgf, lame->highpass_freq);
898 lame_set_highpasswidth (lame->lgf, lame->highpass_width);
899 lame_set_ATHonly (lame->lgf, lame->ath_only);
900 lame_set_ATHshort (lame->lgf, lame->ath_short);
901 lame_set_noATH (lame->lgf, lame->no_ath);
902 lame_set_ATHlower (lame->lgf, lame->ath_lower);
903 lame_set_cwlimit (lame->lgf, lame->cwlimit);
904 lame_set_allow_diff_short (lame->lgf, lame->allow_diff_short);
905 lame_set_no_short_blocks (lame->lgf, lame->no_short_blocks);
906 lame_set_emphasis (lame->lgf, lame->emphasis);
908 gst_lame_set_metadata (lame);
910 /* initialize the lame encoder */
911 if (lame_init_params (lame->lgf) < 0) {
912 lame->initialized = FALSE;
915 lame->initialized = TRUE;
916 /* FIXME: it would be nice to print out the mode here */
918 "lame encoder initialized (%d kbit/s, %d Hz, %d channels)",
919 lame->bitrate, lame->samplerate, lame->num_channels);
922 GST_DEBUG_OBJECT (lame, "done with setup");
924 return lame->initialized;
927 static GstElementStateReturn
928 gst_lame_change_state (GstElement *element)
932 g_return_val_if_fail (GST_IS_LAME (element), GST_STATE_FAILURE);
934 lame = GST_LAME (element);
936 GST_DEBUG ("state pending %d", GST_STATE_PENDING (element));
938 switch (GST_STATE_TRANSITION (element)) {
939 case GST_STATE_READY_TO_PAUSED:
940 lame->last_ts = GST_CLOCK_TIME_NONE;
942 case GST_STATE_READY_TO_NULL:
943 if (lame->initialized) {
944 lame_close (lame->lgf);
945 lame->initialized = FALSE;
952 /* if we haven't failed already, give the parent class a chance to ;-) */
953 if (GST_ELEMENT_CLASS (parent_class)->change_state)
954 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
956 return GST_STATE_SUCCESS;
960 plugin_init (GstPlugin *plugin)
962 if (!gst_element_register (plugin, "lame", GST_RANK_NONE, GST_TYPE_LAME))
972 "Encode MP3's with LAME",