fix build for --disable-gtk-doc
[swfdec.git] / swfdec / swfdec_audio_decoder_gst.c
blob7354d72ec8d11b5fd7ba051ee2c3c7dba0b2c5fd
1 /* Swfdec
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.
8 *
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
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
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 ***/
32 static GstCaps *
33 swfdec_audio_decoder_get_caps (guint codec, SwfdecAudioFormat format)
35 GstCaps *caps;
36 char *s;
38 switch (codec) {
39 case SWFDEC_AUDIO_CODEC_MP3:
40 s = g_strdup ("audio/mpeg, mpegversion=(int)1, layer=(int)3");
41 break;
42 case SWFDEC_AUDIO_CODEC_NELLYMOSER_8KHZ:
43 s = g_strdup ("audio/x-nellymoser, rate=8000, channels=1");
44 break;
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));
49 break;
50 case SWFDEC_AUDIO_CODEC_AAC:
51 s = g_strdup_printf ("audio/mpeg, mpegversion=4");
52 break;
53 default:
54 return NULL;
57 caps = gst_caps_from_string (s);
58 g_assert (caps);
59 g_free (s);
60 return caps;
63 G_DEFINE_TYPE (SwfdecAudioDecoderGst, swfdec_audio_decoder_gst, SWFDEC_TYPE_AUDIO_DECODER)
65 static gboolean
66 swfdec_audio_decoder_gst_prepare (guint codec, SwfdecAudioFormat format, char **detail)
68 GstElementFactory *factory;
69 GstCaps *caps;
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);
73 if (caps == NULL)
74 return FALSE;
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);
81 return TRUE;
84 /* need to install plugins... */
85 *detail = gst_missing_decoder_installer_detail_new (caps);
86 gst_caps_unref (caps);
87 return FALSE;
90 static const char *
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
97 * 0.05 seconds.
99 static const char *options[] = { "ffaudioresample", "speexresample", "audioresample" };
100 guint i;
102 for (i = 0; i < G_N_ELEMENTS (options); i++) {
103 GstElementFactory *factory = gst_element_factory_find (options[i]);
104 if (factory) {
105 gst_object_unref (factory);
106 return options[i];
109 SWFDEC_ERROR ("no resampling element found. Check that GStreamer's base plugins are installed.");
110 return NULL;
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);
121 if (srccaps == NULL)
122 return NULL;
124 player = g_object_new (SWFDEC_TYPE_AUDIO_DECODER_GST, NULL);
126 /* create decoder */
127 sinkcaps = gst_caps_from_string ("audio/x-raw-int, endianness=byte_order, signed=(boolean)true, width=16, depth=16, rate=44100, channels=2");
128 g_assert (sinkcaps);
129 resample = swfdec_audio_decoder_get_resampler ();
130 if (resample == NULL)
131 goto error;
132 if (!swfdec_gst_decoder_init (&player->dec, srccaps, sinkcaps,
133 "audioconvert", resample, NULL))
134 goto error;
136 gst_caps_unref (srccaps);
137 gst_caps_unref (sinkcaps);
138 return SWFDEC_AUDIO_DECODER (player);
140 error:
141 g_object_unref (player);
142 gst_caps_unref (srccaps);
143 gst_caps_unref (sinkcaps);
144 return NULL;
147 static void
148 swfdec_audio_decoder_gst_set_codec_data (SwfdecAudioDecoder *dec, SwfdecBuffer *buffer)
150 SwfdecAudioDecoderGst *player = SWFDEC_AUDIO_DECODER_GST (dec);
152 if (buffer) {
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);
156 } else {
157 swfdec_gst_decoder_set_codec_data (&player->dec, NULL);
161 static void
162 swfdec_audio_decoder_gst_push (SwfdecAudioDecoder *dec, SwfdecBuffer *buffer)
164 SwfdecAudioDecoderGst *player = SWFDEC_AUDIO_DECODER_GST (dec);
165 GstBuffer *buf;
167 if (buffer == NULL) {
168 swfdec_gst_decoder_push_eos (&player->dec);
169 } else {
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);
181 GstBuffer *buf;
183 buf = swfdec_gst_decoder_pull (&player->dec);
184 if (buf == NULL)
185 return NULL;
186 return swfdec_buffer_new_from_gst (buf);
189 static void
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);
199 static void
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;
214 static void
215 swfdec_audio_decoder_gst_init (SwfdecAudioDecoderGst *audio_decoder_gst)