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
));
54 caps
= gst_caps_from_string (s
);
60 G_DEFINE_TYPE (SwfdecAudioDecoderGst
, swfdec_audio_decoder_gst
, SWFDEC_TYPE_AUDIO_DECODER
)
63 swfdec_audio_decoder_gst_prepare (guint codec
, SwfdecAudioFormat format
, char **detail
)
65 GstElementFactory
*factory
;
68 /* Check if we can handle the format at all. If not, no plugin will help us. */
69 caps
= swfdec_audio_decoder_get_caps (codec
, format
);
73 /* If we can already handle it, woohoo! */
74 factory
= swfdec_gst_get_element_factory (caps
);
75 if (factory
!= NULL
) {
76 gst_object_unref (factory
);
77 gst_caps_unref (caps
);
81 /* need to install plugins... */
82 *detail
= gst_missing_decoder_installer_detail_new (caps
);
83 gst_caps_unref (caps
);
88 swfdec_audio_decoder_get_resampler (void)
90 /* FIXME: This is hardcoded as there's no autopluggable way to get the
91 * best resampler by rank.
92 * Even if there were, audioresample (which has the highest rank) is so slow
93 * it takes roughly a second to resample stuff that ffaudioresample does in
96 static const char *options
[] = { "ffaudioresample", "speexresample", "audioresample" };
99 for (i
= 0; i
< G_N_ELEMENTS (options
); i
++) {
100 GstElementFactory
*factory
= gst_element_factory_find (options
[i
]);
102 gst_object_unref (factory
);
106 SWFDEC_ERROR ("no resampling element found. Check that GStreamer's base plugins are installed.");
110 static SwfdecAudioDecoder
*
111 swfdec_audio_decoder_gst_create (guint type
, SwfdecAudioFormat format
, SwfdecBuffer
*data
)
113 SwfdecAudioDecoderGst
*player
;
114 GstCaps
*srccaps
, *sinkcaps
;
115 const char *resample
;
117 srccaps
= swfdec_audio_decoder_get_caps (type
, format
);
121 player
= g_object_new (SWFDEC_TYPE_AUDIO_DECODER_GST
, NULL
);
124 sinkcaps
= gst_caps_from_string ("audio/x-raw-int, endianness=byte_order, signed=(boolean)true, width=16, depth=16, rate=44100, channels=2");
126 resample
= swfdec_audio_decoder_get_resampler ();
127 if (resample
== NULL
)
129 if (!swfdec_gst_decoder_init (&player
->dec
, srccaps
, sinkcaps
,
130 "audioconvert", resample
, NULL
))
133 gst_caps_unref (srccaps
);
134 gst_caps_unref (sinkcaps
);
135 return SWFDEC_AUDIO_DECODER (player
);
138 g_object_unref (player
);
139 gst_caps_unref (srccaps
);
140 gst_caps_unref (sinkcaps
);
145 swfdec_audio_decoder_gst_push (SwfdecAudioDecoder
*dec
, SwfdecBuffer
*buffer
)
147 SwfdecAudioDecoderGst
*player
= SWFDEC_AUDIO_DECODER_GST (dec
);
150 if (buffer
== NULL
) {
151 swfdec_gst_decoder_push_eos (&player
->dec
);
153 swfdec_buffer_ref (buffer
);
154 buf
= swfdec_gst_buffer_new (buffer
);
155 if (!swfdec_gst_decoder_push (&player
->dec
, buf
))
156 swfdec_audio_decoder_error (dec
, "error pushing");
160 static SwfdecBuffer
*
161 swfdec_audio_decoder_gst_pull (SwfdecAudioDecoder
*dec
)
163 SwfdecAudioDecoderGst
*player
= SWFDEC_AUDIO_DECODER_GST (dec
);
166 buf
= swfdec_gst_decoder_pull (&player
->dec
);
169 return swfdec_buffer_new_from_gst (buf
);
173 swfdec_audio_decoder_gst_dispose (GObject
*object
)
175 SwfdecAudioDecoderGst
*player
= (SwfdecAudioDecoderGst
*) object
;
177 swfdec_gst_decoder_finish (&player
->dec
);
179 G_OBJECT_CLASS (swfdec_audio_decoder_gst_parent_class
)->dispose (object
);
183 swfdec_audio_decoder_gst_class_init (SwfdecAudioDecoderGstClass
*klass
)
185 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
186 SwfdecAudioDecoderClass
*decoder_class
= SWFDEC_AUDIO_DECODER_CLASS (klass
);
188 object_class
->dispose
= swfdec_audio_decoder_gst_dispose
;
190 decoder_class
->prepare
= swfdec_audio_decoder_gst_prepare
;
191 decoder_class
->create
= swfdec_audio_decoder_gst_create
;
192 decoder_class
->pull
= swfdec_audio_decoder_gst_pull
;
193 decoder_class
->push
= swfdec_audio_decoder_gst_push
;
197 swfdec_audio_decoder_gst_init (SwfdecAudioDecoderGst
*audio_decoder_gst
)