2 * Copyright (C) 2006-2008 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
24 #include <gst/pbutils/pbutils.h>
26 #include "swfdec_audio_decoder_gst.h"
27 #include "swfdec_debug.h"
28 #include "swfdec_internal.h"
30 /*** CAPS MATCHING ***/
33 swfdec_audio_decoder_get_caps (guint codec
, SwfdecAudioFormat format
)
39 case SWFDEC_AUDIO_CODEC_MP3
:
40 s
= g_strdup ("audio/mpeg, mpegversion=(int)1, layer=(int)3");
42 case SWFDEC_AUDIO_CODEC_NELLYMOSER_8KHZ
:
43 s
= g_strdup ("audio/x-nellymoser, rate=8000, channels=1");
45 case SWFDEC_AUDIO_CODEC_NELLYMOSER
:
46 s
= g_strdup_printf ("audio/x-nellymoser, rate=%d, channels=%d",
47 swfdec_audio_format_get_rate (format
),
48 swfdec_audio_format_get_channels (format
));
50 case SWFDEC_AUDIO_CODEC_AAC
:
51 s
= g_strdup_printf ("audio/mpeg, mpegversion=4");
57 caps
= gst_caps_from_string (s
);
63 G_DEFINE_TYPE (SwfdecAudioDecoderGst
, swfdec_audio_decoder_gst
, SWFDEC_TYPE_AUDIO_DECODER
)
66 swfdec_audio_decoder_gst_prepare (guint codec
, SwfdecAudioFormat format
, char **detail
)
68 GstElementFactory
*factory
;
71 /* Check if we can handle the format at all. If not, no plugin will help us. */
72 caps
= swfdec_audio_decoder_get_caps (codec
, format
);
76 /* If we can already handle it, woohoo! */
77 factory
= swfdec_gst_get_element_factory (caps
);
78 if (factory
!= NULL
) {
79 gst_object_unref (factory
);
80 gst_caps_unref (caps
);
84 /* need to install plugins... */
85 *detail
= gst_missing_decoder_installer_detail_new (caps
);
86 gst_caps_unref (caps
);
91 swfdec_audio_decoder_get_resampler (void)
93 /* FIXME: This is hardcoded as there's no autopluggable way to get the
94 * best resampler by rank.
95 * Even if there were, audioresample (which has the highest rank) is so slow
96 * it takes roughly a second to resample stuff that ffaudioresample does in
99 static const char *options
[] = { "ffaudioresample", "speexresample", "audioresample" };
102 for (i
= 0; i
< G_N_ELEMENTS (options
); i
++) {
103 GstElementFactory
*factory
= gst_element_factory_find (options
[i
]);
105 gst_object_unref (factory
);
109 SWFDEC_ERROR ("no resampling element found. Check that GStreamer's base plugins are installed.");
113 static SwfdecAudioDecoder
*
114 swfdec_audio_decoder_gst_create (guint type
, SwfdecAudioFormat format
)
116 SwfdecAudioDecoderGst
*player
;
117 GstCaps
*srccaps
, *sinkcaps
;
118 const char *resample
;
120 srccaps
= swfdec_audio_decoder_get_caps (type
, format
);
124 player
= g_object_new (SWFDEC_TYPE_AUDIO_DECODER_GST
, NULL
);
127 sinkcaps
= gst_caps_from_string ("audio/x-raw-int, endianness=byte_order, signed=(boolean)true, width=16, depth=16, rate=44100, channels=2");
129 resample
= swfdec_audio_decoder_get_resampler ();
130 if (resample
== NULL
)
132 if (!swfdec_gst_decoder_init (&player
->dec
, srccaps
, sinkcaps
,
133 "audioconvert", resample
, NULL
))
136 gst_caps_unref (srccaps
);
137 gst_caps_unref (sinkcaps
);
138 return SWFDEC_AUDIO_DECODER (player
);
141 g_object_unref (player
);
142 gst_caps_unref (srccaps
);
143 gst_caps_unref (sinkcaps
);
148 swfdec_audio_decoder_gst_set_codec_data (SwfdecAudioDecoder
*dec
, SwfdecBuffer
*buffer
)
150 SwfdecAudioDecoderGst
*player
= SWFDEC_AUDIO_DECODER_GST (dec
);
153 GstBuffer
*buf
= swfdec_gst_buffer_new (swfdec_buffer_ref (buffer
));
154 swfdec_gst_decoder_set_codec_data (&player
->dec
, buf
);
155 gst_buffer_unref (buf
);
157 swfdec_gst_decoder_set_codec_data (&player
->dec
, NULL
);
162 swfdec_audio_decoder_gst_push (SwfdecAudioDecoder
*dec
, SwfdecBuffer
*buffer
)
164 SwfdecAudioDecoderGst
*player
= SWFDEC_AUDIO_DECODER_GST (dec
);
167 if (buffer
== NULL
) {
168 swfdec_gst_decoder_push_eos (&player
->dec
);
170 swfdec_buffer_ref (buffer
);
171 buf
= swfdec_gst_buffer_new (buffer
);
172 if (!swfdec_gst_decoder_push (&player
->dec
, buf
))
173 swfdec_audio_decoder_error (dec
, "error pushing");
177 static SwfdecBuffer
*
178 swfdec_audio_decoder_gst_pull (SwfdecAudioDecoder
*dec
)
180 SwfdecAudioDecoderGst
*player
= SWFDEC_AUDIO_DECODER_GST (dec
);
183 buf
= swfdec_gst_decoder_pull (&player
->dec
);
186 return swfdec_buffer_new_from_gst (buf
);
190 swfdec_audio_decoder_gst_dispose (GObject
*object
)
192 SwfdecAudioDecoderGst
*player
= (SwfdecAudioDecoderGst
*) object
;
194 swfdec_gst_decoder_finish (&player
->dec
);
196 G_OBJECT_CLASS (swfdec_audio_decoder_gst_parent_class
)->dispose (object
);
200 swfdec_audio_decoder_gst_class_init (SwfdecAudioDecoderGstClass
*klass
)
202 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
203 SwfdecAudioDecoderClass
*decoder_class
= SWFDEC_AUDIO_DECODER_CLASS (klass
);
205 object_class
->dispose
= swfdec_audio_decoder_gst_dispose
;
207 decoder_class
->prepare
= swfdec_audio_decoder_gst_prepare
;
208 decoder_class
->create
= swfdec_audio_decoder_gst_create
;
209 decoder_class
->set_codec_data
= swfdec_audio_decoder_gst_set_codec_data
;
210 decoder_class
->pull
= swfdec_audio_decoder_gst_pull
;
211 decoder_class
->push
= swfdec_audio_decoder_gst_push
;
215 swfdec_audio_decoder_gst_init (SwfdecAudioDecoderGst
*audio_decoder_gst
)