add blend mode tests
[swfdec.git] / swfdec / swfdec_audio_decoder.c
blobc1dbf60516e1e54857088da283a5269ebbd01d15
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 "swfdec_audio_decoder.h"
25 #include "swfdec_debug.h"
26 #include "swfdec_internal.h"
28 G_DEFINE_TYPE (SwfdecAudioDecoder, swfdec_audio_decoder, G_TYPE_OBJECT)
30 static void
31 swfdec_audio_decoder_do_set_codec_data (SwfdecAudioDecoder *decoder,
32 SwfdecBuffer *buffer)
34 SWFDEC_WARNING ("%s does not implement codec data",
35 G_OBJECT_TYPE_NAME (decoder));
38 static void
39 swfdec_audio_decoder_class_init (SwfdecAudioDecoderClass *klass)
41 klass->set_codec_data = swfdec_audio_decoder_do_set_codec_data;
44 static void
45 swfdec_audio_decoder_init (SwfdecAudioDecoder *audio_decoder)
49 static GSList *audio_codecs = NULL;
51 void
52 swfdec_audio_decoder_register (GType type)
54 g_return_if_fail (g_type_is_a (type, SWFDEC_TYPE_AUDIO_DECODER));
56 audio_codecs = g_slist_append (audio_codecs, GSIZE_TO_POINTER ((gsize) type));
59 gboolean
60 swfdec_audio_decoder_prepare (guint codec, SwfdecAudioFormat format, char **missing)
62 char *detail = NULL, *s = NULL;
63 GSList *walk;
65 for (walk = audio_codecs; walk; walk = walk->next) {
66 SwfdecAudioDecoderClass *klass = g_type_class_ref (GPOINTER_TO_SIZE (walk->data));
67 if (klass->prepare (codec, format, &s)) {
68 g_free (detail);
69 g_free (s);
70 if (missing)
71 *missing = NULL;
72 g_type_class_unref (klass);
73 return TRUE;
75 if (s) {
76 if (detail == NULL)
77 detail = s;
78 else
79 g_free (s);
80 s = NULL;
82 g_type_class_unref (klass);
84 if (missing)
85 *missing = detail;
86 else
87 g_free (detail);
88 return FALSE;
91 /**
92 * swfdec_audio_decoder_new:
93 * @codec: codec id
94 * @format: #SwfdecAudioCodec to decode
96 * Creates a decoder suitable for decoding @format. If no decoder is available
97 * for the given for mat, %NULL is returned.
99 * Returns: a new decoder or %NULL
101 SwfdecAudioDecoder *
102 swfdec_audio_decoder_new (guint codec, SwfdecAudioFormat format)
104 SwfdecAudioDecoder *ret = NULL;
105 GSList *walk;
107 g_return_val_if_fail (SWFDEC_IS_AUDIO_FORMAT (format), NULL);
109 for (walk = audio_codecs; walk; walk = walk->next) {
110 SwfdecAudioDecoderClass *klass = g_type_class_ref (GPOINTER_TO_SIZE (walk->data));
111 ret = klass->create (codec, format);
112 g_type_class_unref (klass);
113 if (ret)
114 break;
117 if (ret == NULL) {
118 ret = g_object_new (SWFDEC_TYPE_AUDIO_DECODER, NULL);
119 swfdec_audio_decoder_error (ret, "no suitable decoder for audio codec %u", codec);
122 ret->codec = codec;
123 ret->format = format;
125 return ret;
129 * swfdec_audio_decoder_set_codec_data:
130 * @decoder: an audio decoder
131 * @buffer: setup data for the decoder. May be %NULL
133 * Provides setup data for the audio decoder. This function is usually called
134 * on initialization, but can be called at any time. Currently this
135 * functionality is only used for AAC audio.
137 void
138 swfdec_audio_decoder_set_codec_data (SwfdecAudioDecoder *decoder, SwfdecBuffer *buffer)
140 SwfdecAudioDecoderClass *klass;
142 g_return_if_fail (SWFDEC_IS_AUDIO_DECODER (decoder));
144 if (decoder->error)
145 return;
146 klass = SWFDEC_AUDIO_DECODER_GET_CLASS (decoder);
147 klass->set_codec_data (decoder, buffer);
151 * swfdec_audio_decoder_push:
152 * @decoder: a #SwfdecAudioDecoder
153 * @buffer: a #SwfdecBuffer to process or %NULL to flush
155 * Pushes a new buffer into the decoding pipeline. After this the results can
156 * be queried using swfdec_audio_decoder_pull(). Some decoders may not decode
157 * all available data immediately. So when you are done decoding, you may want
158 * to flush the decoder. Flushing can be achieved by passing %NULL as the
159 * @buffer argument. Do this when you are finished decoding.
161 void
162 swfdec_audio_decoder_push (SwfdecAudioDecoder *decoder, SwfdecBuffer *buffer)
164 SwfdecAudioDecoderClass *klass;
166 g_return_if_fail (SWFDEC_IS_AUDIO_DECODER (decoder));
168 if (decoder->error)
169 return;
170 klass = SWFDEC_AUDIO_DECODER_GET_CLASS (decoder);
171 klass->push (decoder, buffer);
175 * swfdec_audio_decoder_pull:
176 * @decoder: a #SwfdecAudioDecoder
178 * Gets the next buffer of decoded audio data. Since some decoders do not
179 * produce one output buffer per input buffer, any number of buffers may be
180 * available after calling swfdec_audio_decoder_push(), even none. When no more
181 * buffers are available, this function returns %NULL. You need to provide more
182 * input in then. A simple decoding pipeline would look like this:
183 * <informalexample><programlisting>do {
184 * input = next_input_buffer ();
185 * swfdec_audio_decoder_push (decoder, input);
186 * while ((output = swfdec_audio_decoder_pull (decoder))) {
187 * ... process output ...
189 * } while (input != NULL); </programlisting></informalexample>
191 * Returns: the next buffer or %NULL if no more buffers are available.
193 SwfdecBuffer *
194 swfdec_audio_decoder_pull (SwfdecAudioDecoder *decoder)
196 SwfdecAudioDecoderClass *klass;
197 SwfdecBuffer *result;
199 g_return_val_if_fail (SWFDEC_IS_AUDIO_DECODER (decoder), NULL);
201 if (decoder->error)
202 return NULL;
203 klass = SWFDEC_AUDIO_DECODER_GET_CLASS (decoder);
204 result = klass->pull (decoder);
205 /* result must be n samples of 44.1kHz stereo 16bit - and one sample is 4 bytes */
206 g_assert (result == NULL || result->length % 4 == 0);
207 return result;
210 void
211 swfdec_audio_decoder_error (SwfdecAudioDecoder *decoder, const char *error, ...)
213 va_list args;
215 g_return_if_fail (SWFDEC_IS_AUDIO_DECODER (decoder));
216 g_return_if_fail (error != NULL);
218 va_start (args, error);
219 swfdec_audio_decoder_errorv (decoder, error, args);
220 va_end (args);
223 void
224 swfdec_audio_decoder_errorv (SwfdecAudioDecoder *decoder, const char *error, va_list args)
226 char *real;
228 g_return_if_fail (SWFDEC_IS_AUDIO_DECODER (decoder));
229 g_return_if_fail (error != NULL);
231 real = g_strdup_vprintf (error, args);
232 SWFDEC_ERROR ("error decoding audio: %s", real);
233 g_free (real);
234 decoder->error = TRUE;
238 * swfdec_audio_decoder_uses_format:
239 * @decoder: the decoder to check
240 * @codec: the codec the decoder should use
241 * @format: the format the decoder should use
243 * This is a little helper function that checks if the decoder uses the right
244 * format.
246 * Returns: %TRUE if the @decoder uses the given @codec and @format, %FALSE
247 * otherwise.
249 gboolean
250 swfdec_audio_decoder_uses_format (SwfdecAudioDecoder *decoder, guint codec,
251 SwfdecAudioFormat format)
253 g_return_val_if_fail (SWFDEC_IS_AUDIO_DECODER (decoder), FALSE);
254 g_return_val_if_fail (SWFDEC_IS_AUDIO_FORMAT (format), FALSE);
256 return decoder->codec == codec && decoder->format == format;