diff options
author | Mark Nauwelaerts | 2011-09-23 08:26:48 -0500 |
---|---|---|
committer | Nikhil Devshatwar | 2013-05-17 04:40:41 -0500 |
commit | 9df0c681104941fa242a74f46c801b7a1187767a (patch) | |
tree | 08cb432d7e2a0424a006ccd873493044fd5df50b | |
parent | 89a186d65e5c92abcfd5acea8515027b8d9b009a (diff) | |
download | gst-plugins-ugly0-10-9df0c681104941fa242a74f46c801b7a1187767a.tar.gz gst-plugins-ugly0-10-9df0c681104941fa242a74f46c801b7a1187767a.tar.xz gst-plugins-ugly0-10-9df0c681104941fa242a74f46c801b7a1187767a.zip |
lame: port to audioencoder
-rw-r--r-- | ext/lame/gstlame.c | 326 | ||||
-rw-r--r-- | ext/lame/gstlame.h | 6 |
2 files changed, 102 insertions, 230 deletions
diff --git a/ext/lame/gstlame.c b/ext/lame/gstlame.c index b4aecf9f..36e40879 100644 --- a/ext/lame/gstlame.c +++ b/ext/lame/gstlame.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | /** | 22 | /** |
23 | * SECTION:element-lame | 23 | * SECTION:element-lame |
24 | * @see_also: lamemp3enc, mad, vorbisenc | 24 | * @see_also: lame, mad, vorbisenc |
25 | * | 25 | * |
26 | * This element encodes raw integer audio into an MPEG-1 layer 3 (MP3) stream. | 26 | * This element encodes raw integer audio into an MPEG-1 layer 3 (MP3) stream. |
27 | * Note that <ulink url="http://en.wikipedia.org/wiki/MP3">MP3</ulink> is not | 27 | * Note that <ulink url="http://en.wikipedia.org/wiki/MP3">MP3</ulink> is not |
@@ -31,7 +31,7 @@ | |||
31 | * | 31 | * |
32 | * <refsect2> | 32 | * <refsect2> |
33 | * <title>Note</title> | 33 | * <title>Note</title> |
34 | * This element is deprecated, use the lamemp3enc element instead | 34 | * This element is deprecated, use the lame element instead |
35 | * which provides a much simpler interface and results in better MP3 files. | 35 | * which provides a much simpler interface and results in better MP3 files. |
36 | * </refsect2> | 36 | * </refsect2> |
37 | * | 37 | * |
@@ -309,15 +309,19 @@ static void gst_lame_base_init (gpointer g_class); | |||
309 | static void gst_lame_class_init (GstLameClass * klass); | 309 | static void gst_lame_class_init (GstLameClass * klass); |
310 | static void gst_lame_init (GstLame * gst_lame); | 310 | static void gst_lame_init (GstLame * gst_lame); |
311 | 311 | ||
312 | static gboolean gst_lame_start (GstAudioEncoder * enc); | ||
313 | static gboolean gst_lame_stop (GstAudioEncoder * enc); | ||
314 | static gboolean gst_lame_set_format (GstAudioEncoder * enc, | ||
315 | GstAudioInfo * info); | ||
316 | static GstFlowReturn gst_lame_handle_frame (GstAudioEncoder * enc, | ||
317 | GstBuffer * in_buf); | ||
318 | static void gst_lame_flush (GstAudioEncoder * enc); | ||
319 | |||
312 | static void gst_lame_set_property (GObject * object, guint prop_id, | 320 | static void gst_lame_set_property (GObject * object, guint prop_id, |
313 | const GValue * value, GParamSpec * pspec); | 321 | const GValue * value, GParamSpec * pspec); |
314 | static void gst_lame_get_property (GObject * object, guint prop_id, | 322 | static void gst_lame_get_property (GObject * object, guint prop_id, |
315 | GValue * value, GParamSpec * pspec); | 323 | GValue * value, GParamSpec * pspec); |
316 | static gboolean gst_lame_sink_event (GstPad * pad, GstEvent * event); | ||
317 | static GstFlowReturn gst_lame_chain (GstPad * pad, GstBuffer * buf); | ||
318 | static gboolean gst_lame_setup (GstLame * lame); | 324 | static gboolean gst_lame_setup (GstLame * lame); |
319 | static GstStateChangeReturn gst_lame_change_state (GstElement * element, | ||
320 | GstStateChange transition); | ||
321 | 325 | ||
322 | static GstElementClass *parent_class = NULL; | 326 | static GstElementClass *parent_class = NULL; |
323 | 327 | ||
@@ -352,7 +356,8 @@ gst_lame_get_type (void) | |||
352 | }; | 356 | }; |
353 | 357 | ||
354 | gst_lame_type = | 358 | gst_lame_type = |
355 | g_type_register_static (GST_TYPE_ELEMENT, "GstLame", &gst_lame_info, 0); | 359 | g_type_register_static (GST_TYPE_AUDIO_ENCODER, "GstLame", |
360 | &gst_lame_info, 0); | ||
356 | g_type_add_interface_static (gst_lame_type, GST_TYPE_TAG_SETTER, | 361 | g_type_add_interface_static (gst_lame_type, GST_TYPE_TAG_SETTER, |
357 | &tag_setter_info); | 362 | &tag_setter_info); |
358 | g_type_add_interface_static (gst_lame_type, GST_TYPE_PRESET, &preset_info); | 363 | g_type_add_interface_static (gst_lame_type, GST_TYPE_PRESET, &preset_info); |
@@ -397,9 +402,11 @@ gst_lame_class_init (GstLameClass * klass) | |||
397 | { | 402 | { |
398 | GObjectClass *gobject_class; | 403 | GObjectClass *gobject_class; |
399 | GstElementClass *gstelement_class; | 404 | GstElementClass *gstelement_class; |
405 | GstAudioEncoderClass *base_class; | ||
400 | 406 | ||
401 | gobject_class = (GObjectClass *) klass; | 407 | gobject_class = (GObjectClass *) klass; |
402 | gstelement_class = (GstElementClass *) klass; | 408 | gstelement_class = (GstElementClass *) klass; |
409 | base_class = (GstAudioEncoderClass *) klass; | ||
403 | 410 | ||
404 | parent_class = g_type_class_peek_parent (klass); | 411 | parent_class = g_type_class_peek_parent (klass); |
405 | 412 | ||
@@ -407,6 +414,12 @@ gst_lame_class_init (GstLameClass * klass) | |||
407 | gobject_class->get_property = gst_lame_get_property; | 414 | gobject_class->get_property = gst_lame_get_property; |
408 | gobject_class->finalize = gst_lame_finalize; | 415 | gobject_class->finalize = gst_lame_finalize; |
409 | 416 | ||
417 | base_class->start = GST_DEBUG_FUNCPTR (gst_lame_start); | ||
418 | base_class->stop = GST_DEBUG_FUNCPTR (gst_lame_stop); | ||
419 | base_class->set_format = GST_DEBUG_FUNCPTR (gst_lame_set_format); | ||
420 | base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_lame_handle_frame); | ||
421 | base_class->flush = GST_DEBUG_FUNCPTR (gst_lame_flush); | ||
422 | |||
410 | g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE, | 423 | g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE, |
411 | g_param_spec_int ("bitrate", "Bitrate (kb/s)", | 424 | g_param_spec_int ("bitrate", "Bitrate (kb/s)", |
412 | "Bitrate in kbit/sec (8, 16, 24, 32, 40, 48, 56, 64, 80, 96, " | 425 | "Bitrate in kbit/sec (8, 16, 24, 32, 40, 48, 56, 64, 80, 96, " |
@@ -565,39 +578,30 @@ gst_lame_class_init (GstLameClass * klass) | |||
565 | GST_TYPE_LAME_PRESET, gst_lame_default_settings.preset, | 578 | GST_TYPE_LAME_PRESET, gst_lame_default_settings.preset, |
566 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); | 579 | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
567 | #endif | 580 | #endif |
568 | |||
569 | gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_lame_change_state); | ||
570 | } | ||
571 | |||
572 | static gboolean | ||
573 | gst_lame_src_setcaps (GstPad * pad, GstCaps * caps) | ||
574 | { | ||
575 | GST_DEBUG_OBJECT (pad, "caps: %" GST_PTR_FORMAT, caps); | ||
576 | return TRUE; | ||
577 | } | 581 | } |
578 | 582 | ||
579 | static gboolean | 583 | static gboolean |
580 | gst_lame_sink_setcaps (GstPad * pad, GstCaps * caps) | 584 | gst_lame_set_format (GstAudioEncoder * enc, GstAudioInfo * info) |
581 | { | 585 | { |
582 | GstLame *lame; | 586 | GstLame *lame; |
583 | gint out_samplerate; | 587 | gint out_samplerate; |
584 | gint version; | 588 | gint version; |
585 | GstStructure *structure; | ||
586 | GstCaps *othercaps; | 589 | GstCaps *othercaps; |
590 | GstClockTime latency; | ||
591 | |||
592 | lame = GST_LAME (enc); | ||
587 | 593 | ||
588 | lame = GST_LAME (GST_PAD_PARENT (pad)); | 594 | /* parameters already parsed for us */ |
589 | structure = gst_caps_get_structure (caps, 0); | 595 | lame->samplerate = GST_AUDIO_INFO_RATE (info); |
596 | lame->num_channels = GST_AUDIO_INFO_CHANNELS (info); | ||
590 | 597 | ||
591 | if (!gst_structure_get_int (structure, "rate", &lame->samplerate)) | 598 | /* but we might be asked to reconfigure, so reset */ |
592 | goto no_rate; | 599 | gst_lame_release_memory (lame); |
593 | if (!gst_structure_get_int (structure, "channels", &lame->num_channels)) | ||
594 | goto no_channels; | ||
595 | 600 | ||
596 | GST_DEBUG_OBJECT (lame, "setting up lame"); | 601 | GST_DEBUG_OBJECT (lame, "setting up lame"); |
597 | if (!gst_lame_setup (lame)) | 602 | if (!gst_lame_setup (lame)) |
598 | goto setup_failed; | 603 | goto setup_failed; |
599 | 604 | ||
600 | |||
601 | out_samplerate = lame_get_out_samplerate (lame->lgf); | 605 | out_samplerate = lame_get_out_samplerate (lame->lgf); |
602 | if (out_samplerate == 0) | 606 | if (out_samplerate == 0) |
603 | goto zero_output_rate; | 607 | goto zero_output_rate; |
@@ -624,21 +628,18 @@ gst_lame_sink_setcaps (GstPad * pad, GstCaps * caps) | |||
624 | "rate", G_TYPE_INT, out_samplerate, NULL); | 628 | "rate", G_TYPE_INT, out_samplerate, NULL); |
625 | 629 | ||
626 | /* and use these caps */ | 630 | /* and use these caps */ |
627 | gst_pad_set_caps (lame->srcpad, othercaps); | 631 | gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (lame), othercaps); |
628 | gst_caps_unref (othercaps); | 632 | gst_caps_unref (othercaps); |
629 | 633 | ||
634 | /* base class feedback: | ||
635 | * - we will handle buffers, just hand us all available | ||
636 | * - report latency */ | ||
637 | latency = gst_util_uint64_scale_int (lame_get_framesize (lame->lgf), | ||
638 | GST_SECOND, lame->samplerate); | ||
639 | gst_audio_encoder_set_latency (enc, latency, latency); | ||
640 | |||
630 | return TRUE; | 641 | return TRUE; |
631 | 642 | ||
632 | no_rate: | ||
633 | { | ||
634 | GST_ERROR_OBJECT (lame, "input caps have no sample rate field"); | ||
635 | return FALSE; | ||
636 | } | ||
637 | no_channels: | ||
638 | { | ||
639 | GST_ERROR_OBJECT (lame, "input caps have no channels field"); | ||
640 | return FALSE; | ||
641 | } | ||
642 | zero_output_rate: | 643 | zero_output_rate: |
643 | { | 644 | { |
644 | GST_ELEMENT_ERROR (lame, LIBRARY, SETTINGS, (NULL), | 645 | GST_ELEMENT_ERROR (lame, LIBRARY, SETTINGS, (NULL), |
@@ -658,26 +659,6 @@ gst_lame_init (GstLame * lame) | |||
658 | { | 659 | { |
659 | GST_DEBUG_OBJECT (lame, "starting initialization"); | 660 | GST_DEBUG_OBJECT (lame, "starting initialization"); |
660 | 661 | ||
661 | lame->sinkpad = | ||
662 | gst_pad_new_from_static_template (&gst_lame_sink_template, "sink"); | ||
663 | gst_pad_set_event_function (lame->sinkpad, | ||
664 | GST_DEBUG_FUNCPTR (gst_lame_sink_event)); | ||
665 | gst_pad_set_chain_function (lame->sinkpad, | ||
666 | GST_DEBUG_FUNCPTR (gst_lame_chain)); | ||
667 | gst_pad_set_setcaps_function (lame->sinkpad, | ||
668 | GST_DEBUG_FUNCPTR (gst_lame_sink_setcaps)); | ||
669 | gst_element_add_pad (GST_ELEMENT (lame), lame->sinkpad); | ||
670 | |||
671 | lame->srcpad = | ||
672 | gst_pad_new_from_static_template (&gst_lame_src_template, "src"); | ||
673 | gst_pad_set_setcaps_function (lame->srcpad, | ||
674 | GST_DEBUG_FUNCPTR (gst_lame_src_setcaps)); | ||
675 | gst_element_add_pad (GST_ELEMENT (lame), lame->srcpad); | ||
676 | |||
677 | lame->samplerate = 44100; | ||
678 | lame->num_channels = 2; | ||
679 | lame->setup = FALSE; | ||
680 | |||
681 | /* Set default settings */ | 662 | /* Set default settings */ |
682 | lame->bitrate = gst_lame_default_settings.bitrate; | 663 | lame->bitrate = gst_lame_default_settings.bitrate; |
683 | lame->compression_ratio = gst_lame_default_settings.compression_ratio; | 664 | lame->compression_ratio = gst_lame_default_settings.compression_ratio; |
@@ -714,6 +695,27 @@ gst_lame_init (GstLame * lame) | |||
714 | GST_DEBUG_OBJECT (lame, "done initializing"); | 695 | GST_DEBUG_OBJECT (lame, "done initializing"); |
715 | } | 696 | } |
716 | 697 | ||
698 | static gboolean | ||
699 | gst_lame_start (GstAudioEncoder * enc) | ||
700 | { | ||
701 | GstLame *lame = GST_LAME (enc); | ||
702 | |||
703 | GST_DEBUG_OBJECT (lame, "start"); | ||
704 | return TRUE; | ||
705 | } | ||
706 | |||
707 | static gboolean | ||
708 | gst_lame_stop (GstAudioEncoder * enc) | ||
709 | { | ||
710 | GstLame *lame = GST_LAME (enc); | ||
711 | |||
712 | GST_DEBUG_OBJECT (lame, "stop"); | ||
713 | |||
714 | gst_lame_release_memory (lame); | ||
715 | return TRUE; | ||
716 | } | ||
717 | |||
718 | |||
717 | /* <php-emulation-mode>three underscores for ___rate is really really really | 719 | /* <php-emulation-mode>three underscores for ___rate is really really really |
718 | * private as opposed to one underscore<php-emulation-mode> */ | 720 | * private as opposed to one underscore<php-emulation-mode> */ |
719 | /* call this MACRO outside of the NULL state so that we have a higher chance | 721 | /* call this MACRO outside of the NULL state so that we have a higher chance |
@@ -979,108 +981,54 @@ gst_lame_get_property (GObject * object, guint prop_id, GValue * value, | |||
979 | } | 981 | } |
980 | } | 982 | } |
981 | 983 | ||
982 | static gboolean | 984 | static GstFlowReturn |
983 | gst_lame_sink_event (GstPad * pad, GstEvent * event) | 985 | gst_lame_flush_full (GstLame * lame, gboolean push) |
984 | { | 986 | { |
985 | gboolean ret; | 987 | GstBuffer *buf; |
986 | GstLame *lame; | 988 | gint size; |
987 | 989 | GstFlowReturn result = GST_FLOW_OK; | |
988 | lame = GST_LAME (gst_pad_get_parent (pad)); | ||
989 | |||
990 | switch (GST_EVENT_TYPE (event)) { | ||
991 | case GST_EVENT_EOS:{ | ||
992 | GST_DEBUG_OBJECT (lame, "handling EOS event"); | ||
993 | |||
994 | if (lame->lgf != NULL) { | ||
995 | GstBuffer *buf; | ||
996 | gint size; | ||
997 | |||
998 | buf = gst_buffer_new_and_alloc (7200); | ||
999 | size = lame_encode_flush (lame->lgf, GST_BUFFER_DATA (buf), 7200); | ||
1000 | |||
1001 | if (size > 0 && lame->last_flow == GST_FLOW_OK) { | ||
1002 | gint64 duration; | ||
1003 | |||
1004 | duration = gst_util_uint64_scale (size, 8 * GST_SECOND, | ||
1005 | 1000 * lame->bitrate); | ||
1006 | |||
1007 | if (lame->last_ts == GST_CLOCK_TIME_NONE) { | ||
1008 | lame->last_ts = lame->eos_ts; | ||
1009 | lame->last_duration = duration; | ||
1010 | } else { | ||
1011 | lame->last_duration += duration; | ||
1012 | } | ||
1013 | |||
1014 | GST_BUFFER_TIMESTAMP (buf) = lame->last_ts; | ||
1015 | GST_BUFFER_DURATION (buf) = lame->last_duration; | ||
1016 | lame->last_ts = GST_CLOCK_TIME_NONE; | ||
1017 | GST_BUFFER_SIZE (buf) = size; | ||
1018 | GST_DEBUG_OBJECT (lame, "pushing final packet of %u bytes", size); | ||
1019 | gst_buffer_set_caps (buf, GST_PAD_CAPS (lame->srcpad)); | ||
1020 | gst_pad_push (lame->srcpad, buf); | ||
1021 | } else { | ||
1022 | GST_DEBUG_OBJECT (lame, "no final packet (size=%d, last_flow=%s)", | ||
1023 | size, gst_flow_get_name (lame->last_flow)); | ||
1024 | gst_buffer_unref (buf); | ||
1025 | } | ||
1026 | } | ||
1027 | |||
1028 | ret = gst_pad_event_default (pad, event); | ||
1029 | break; | ||
1030 | } | ||
1031 | case GST_EVENT_FLUSH_START: | ||
1032 | GST_DEBUG_OBJECT (lame, "handling FLUSH start event"); | ||
1033 | /* forward event */ | ||
1034 | ret = gst_pad_push_event (lame->srcpad, event); | ||
1035 | break; | ||
1036 | case GST_EVENT_FLUSH_STOP: | ||
1037 | { | ||
1038 | guchar *mp3_data = NULL; | ||
1039 | gint mp3_buffer_size; | ||
1040 | 990 | ||
1041 | GST_DEBUG_OBJECT (lame, "handling FLUSH stop event"); | 991 | if (!lame->lgf) |
992 | return GST_FLOW_OK; | ||
1042 | 993 | ||
1043 | if (lame->lgf) { | 994 | buf = gst_buffer_new_and_alloc (7200); |
1044 | /* clear buffers if we already have lame set up */ | 995 | size = lame_encode_flush (lame->lgf, GST_BUFFER_DATA (buf), 7200); |
1045 | mp3_buffer_size = 7200; | ||
1046 | mp3_data = g_malloc (mp3_buffer_size); | ||
1047 | lame_encode_flush (lame->lgf, mp3_data, mp3_buffer_size); | ||
1048 | g_free (mp3_data); | ||
1049 | } | ||
1050 | 996 | ||
1051 | ret = gst_pad_push_event (lame->srcpad, event); | 997 | if (size > 0 && push) { |
1052 | break; | 998 | GST_BUFFER_SIZE (buf) = size; |
1053 | } | 999 | GST_DEBUG_OBJECT (lame, "pushing final packet of %u bytes", size); |
1054 | case GST_EVENT_TAG: | 1000 | result = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (lame), buf, -1); |
1055 | GST_DEBUG_OBJECT (lame, "ignoring TAG event, passing it on"); | 1001 | } else { |
1056 | ret = gst_pad_push_event (lame->srcpad, event); | 1002 | GST_DEBUG_OBJECT (lame, "no final packet (size=%d, push=%d)", size, push); |
1057 | break; | 1003 | gst_buffer_unref (buf); |
1058 | default: | 1004 | result = GST_FLOW_OK; |
1059 | ret = gst_pad_event_default (pad, event); | ||
1060 | break; | ||
1061 | } | 1005 | } |
1062 | gst_object_unref (lame); | 1006 | return result; |
1063 | return ret; | 1007 | } |
1008 | |||
1009 | static void | ||
1010 | gst_lame_flush (GstAudioEncoder * enc) | ||
1011 | { | ||
1012 | gst_lame_flush_full (GST_LAME (enc), FALSE); | ||
1064 | } | 1013 | } |
1065 | 1014 | ||
1066 | static GstFlowReturn | 1015 | static GstFlowReturn |
1067 | gst_lame_chain (GstPad * pad, GstBuffer * buf) | 1016 | gst_lame_handle_frame (GstAudioEncoder * enc, GstBuffer * buf) |
1068 | { | 1017 | { |
1069 | GstLame *lame; | 1018 | GstLame *lame; |
1070 | guchar *mp3_data; | 1019 | guchar *mp3_data; |
1020 | GstBuffer *mp3_buf; | ||
1071 | gint mp3_buffer_size, mp3_size; | 1021 | gint mp3_buffer_size, mp3_size; |
1072 | gint64 duration; | ||
1073 | GstFlowReturn result; | 1022 | GstFlowReturn result; |
1074 | gint num_samples; | 1023 | gint num_samples; |
1075 | guint8 *data; | 1024 | guint8 *data; |
1076 | guint size; | 1025 | guint size; |
1077 | 1026 | ||
1078 | lame = GST_LAME (GST_PAD_PARENT (pad)); | 1027 | lame = GST_LAME (enc); |
1079 | |||
1080 | GST_LOG_OBJECT (lame, "entered chain"); | ||
1081 | 1028 | ||
1082 | if (!lame->setup) | 1029 | /* squeeze remaining and push */ |
1083 | goto not_setup; | 1030 | if (G_UNLIKELY (buf == NULL)) |
1031 | return gst_lame_flush_full (lame, TRUE); | ||
1084 | 1032 | ||
1085 | data = GST_BUFFER_DATA (buf); | 1033 | data = GST_BUFFER_DATA (buf); |
1086 | size = GST_BUFFER_SIZE (buf); | 1034 | size = GST_BUFFER_SIZE (buf); |
@@ -1089,7 +1037,8 @@ gst_lame_chain (GstPad * pad, GstBuffer * buf) | |||
1089 | 1037 | ||
1090 | /* allocate space for output */ | 1038 | /* allocate space for output */ |
1091 | mp3_buffer_size = 1.25 * num_samples + 7200; | 1039 | mp3_buffer_size = 1.25 * num_samples + 7200; |
1092 | mp3_data = g_malloc (mp3_buffer_size); | 1040 | mp3_buf = gst_buffer_new_and_alloc (mp3_buffer_size); |
1041 | mp3_data = GST_BUFFER_DATA (mp3_buf); | ||
1093 | 1042 | ||
1094 | /* lame seems to be too stupid to get mono interleaved going */ | 1043 | /* lame seems to be too stupid to get mono interleaved going */ |
1095 | if (lame->num_channels == 1) { | 1044 | if (lame->num_channels == 1) { |
@@ -1105,69 +1054,23 @@ gst_lame_chain (GstPad * pad, GstBuffer * buf) | |||
1105 | GST_LOG_OBJECT (lame, "encoded %d bytes of audio to %d bytes of mp3", | 1054 | GST_LOG_OBJECT (lame, "encoded %d bytes of audio to %d bytes of mp3", |
1106 | size, mp3_size); | 1055 | size, mp3_size); |
1107 | 1056 | ||
1108 | duration = gst_util_uint64_scale_int (size, GST_SECOND, | ||
1109 | 2 * lame->samplerate * lame->num_channels); | ||
1110 | |||
1111 | if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE && | ||
1112 | GST_BUFFER_DURATION (buf) != duration) { | ||
1113 | GST_DEBUG_OBJECT (lame, "incoming buffer had incorrect duration %" | ||
1114 | GST_TIME_FORMAT ", outgoing buffer will have correct duration %" | ||
1115 | GST_TIME_FORMAT, | ||
1116 | GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_TIME_ARGS (duration)); | ||
1117 | } | ||
1118 | |||
1119 | if (lame->last_ts == GST_CLOCK_TIME_NONE) { | ||
1120 | lame->last_ts = GST_BUFFER_TIMESTAMP (buf); | ||
1121 | lame->last_offs = GST_BUFFER_OFFSET (buf); | ||
1122 | lame->last_duration = duration; | ||
1123 | } else { | ||
1124 | lame->last_duration += duration; | ||
1125 | } | ||
1126 | |||
1127 | gst_buffer_unref (buf); | ||
1128 | |||
1129 | if (mp3_size < 0) { | 1057 | if (mp3_size < 0) { |
1130 | g_warning ("error %d", mp3_size); | 1058 | g_warning ("error %d", mp3_size); |
1131 | } | 1059 | } |
1132 | 1060 | ||
1133 | if (mp3_size > 0) { | 1061 | if (G_LIKELY (mp3_size > 0)) { |
1134 | GstBuffer *outbuf; | 1062 | GST_BUFFER_SIZE (mp3_buf) = mp3_size; |
1135 | 1063 | result = gst_audio_encoder_finish_frame (enc, mp3_buf, -1); | |
1136 | outbuf = gst_buffer_new (); | ||
1137 | GST_BUFFER_DATA (outbuf) = mp3_data; | ||
1138 | GST_BUFFER_MALLOCDATA (outbuf) = mp3_data; | ||
1139 | GST_BUFFER_SIZE (outbuf) = mp3_size; | ||
1140 | GST_BUFFER_TIMESTAMP (outbuf) = lame->last_ts; | ||
1141 | GST_BUFFER_OFFSET (outbuf) = lame->last_offs; | ||
1142 | GST_BUFFER_DURATION (outbuf) = lame->last_duration; | ||
1143 | gst_buffer_set_caps (outbuf, GST_PAD_CAPS (lame->srcpad)); | ||
1144 | |||
1145 | result = gst_pad_push (lame->srcpad, outbuf); | ||
1146 | lame->last_flow = result; | ||
1147 | if (result != GST_FLOW_OK) { | ||
1148 | GST_DEBUG_OBJECT (lame, "flow return: %s", gst_flow_get_name (result)); | ||
1149 | } | ||
1150 | |||
1151 | if (GST_CLOCK_TIME_IS_VALID (lame->last_ts)) | ||
1152 | lame->eos_ts = lame->last_ts + lame->last_duration; | ||
1153 | else | ||
1154 | lame->eos_ts = GST_CLOCK_TIME_NONE; | ||
1155 | lame->last_ts = GST_CLOCK_TIME_NONE; | ||
1156 | } else { | 1064 | } else { |
1157 | g_free (mp3_data); | 1065 | if (mp3_size < 0) { |
1066 | /* eat error ? */ | ||
1067 | g_warning ("error %d", mp3_size); | ||
1068 | } | ||
1158 | result = GST_FLOW_OK; | 1069 | result = GST_FLOW_OK; |
1070 | gst_buffer_unref (mp3_buf); | ||
1159 | } | 1071 | } |
1160 | 1072 | ||
1161 | return result; | 1073 | return result; |
1162 | |||
1163 | /* ERRORS */ | ||
1164 | not_setup: | ||
1165 | { | ||
1166 | gst_buffer_unref (buf); | ||
1167 | GST_ELEMENT_ERROR (lame, CORE, NEGOTIATION, (NULL), | ||
1168 | ("encoder not initialized (input is not audio?)")); | ||
1169 | return GST_FLOW_ERROR; | ||
1170 | } | ||
1171 | } | 1074 | } |
1172 | 1075 | ||
1173 | /* set up the encoder state */ | 1076 | /* set up the encoder state */ |
@@ -1204,7 +1107,7 @@ gst_lame_setup (GstLame * lame) | |||
1204 | lame_set_in_samplerate (lame->lgf, lame->samplerate); | 1107 | lame_set_in_samplerate (lame->lgf, lame->samplerate); |
1205 | 1108 | ||
1206 | /* let lame choose default samplerate unless outgoing sample rate is fixed */ | 1109 | /* let lame choose default samplerate unless outgoing sample rate is fixed */ |
1207 | allowed_caps = gst_pad_get_allowed_caps (lame->srcpad); | 1110 | allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (lame)); |
1208 | 1111 | ||
1209 | if (allowed_caps != NULL) { | 1112 | if (allowed_caps != NULL) { |
1210 | GstStructure *structure; | 1113 | GstStructure *structure; |
@@ -1294,37 +1197,6 @@ gst_lame_setup (GstLame * lame) | |||
1294 | #undef CHECK_ERROR | 1197 | #undef CHECK_ERROR |
1295 | } | 1198 | } |
1296 | 1199 | ||
1297 | static GstStateChangeReturn | ||
1298 | gst_lame_change_state (GstElement * element, GstStateChange transition) | ||
1299 | { | ||
1300 | GstLame *lame; | ||
1301 | GstStateChangeReturn result; | ||
1302 | |||
1303 | lame = GST_LAME (element); | ||
1304 | |||
1305 | switch (transition) { | ||
1306 | case GST_STATE_CHANGE_READY_TO_PAUSED: | ||
1307 | lame->last_flow = GST_FLOW_OK; | ||
1308 | lame->last_ts = GST_CLOCK_TIME_NONE; | ||
1309 | lame->eos_ts = GST_CLOCK_TIME_NONE; | ||
1310 | break; | ||
1311 | default: | ||
1312 | break; | ||
1313 | } | ||
1314 | |||
1315 | result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); | ||
1316 | |||
1317 | switch (transition) { | ||
1318 | case GST_STATE_CHANGE_READY_TO_NULL: | ||
1319 | gst_lame_release_memory (lame); | ||
1320 | break; | ||
1321 | default: | ||
1322 | break; | ||
1323 | } | ||
1324 | |||
1325 | return result; | ||
1326 | } | ||
1327 | |||
1328 | static gboolean | 1200 | static gboolean |
1329 | gst_lame_get_default_settings (void) | 1201 | gst_lame_get_default_settings (void) |
1330 | { | 1202 | { |
diff --git a/ext/lame/gstlame.h b/ext/lame/gstlame.h index f9a1370c..b84cca3f 100644 --- a/ext/lame/gstlame.h +++ b/ext/lame/gstlame.h | |||
@@ -27,6 +27,7 @@ | |||
27 | G_BEGIN_DECLS | 27 | G_BEGIN_DECLS |
28 | 28 | ||
29 | #include <lame/lame.h> | 29 | #include <lame/lame.h> |
30 | #include <gst/audio/gstaudioencoder.h> | ||
30 | 31 | ||
31 | #define GST_TYPE_LAME \ | 32 | #define GST_TYPE_LAME \ |
32 | (gst_lame_get_type()) | 33 | (gst_lame_get_type()) |
@@ -48,10 +49,9 @@ typedef struct _GstLameClass GstLameClass; | |||
48 | * Opaque data structure. | 49 | * Opaque data structure. |
49 | */ | 50 | */ |
50 | struct _GstLame { | 51 | struct _GstLame { |
51 | GstElement element; | 52 | GstAudioEncoder element; |
52 | 53 | ||
53 | /*< private >*/ | 54 | /*< private >*/ |
54 | GstPad *srcpad, *sinkpad; | ||
55 | 55 | ||
56 | gint samplerate; | 56 | gint samplerate; |
57 | gint num_channels; | 57 | gint num_channels; |
@@ -100,7 +100,7 @@ struct _GstLame { | |||
100 | }; | 100 | }; |
101 | 101 | ||
102 | struct _GstLameClass { | 102 | struct _GstLameClass { |
103 | GstElementClass parent_class; | 103 | GstAudioEncoderClass parent_class; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | GType gst_lame_get_type(void); | 106 | GType gst_lame_get_type(void); |