2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 /*#define GST_DEBUG_ENABLED */
24 #include "gstavidecoder.h"
28 /* elementfactory information */
29 static GstElementDetails gst_avi_decoder_details = {
32 "Decodes a .avi file into audio and video",
34 "Erik Walthinsen <omega@cse.ogi.edu>\n"
35 "Wim Taymans <wim.taymans@tvd.be>",
39 static GstCaps* avi_typefind (GstBuffer *buf, gpointer private);
41 /* typefactory for 'avi' */
42 static GstTypeDefinition avidefinition = {
43 "avidecoder_video/avi",
49 /* AviDecoder signals and args */
63 GST_PADTEMPLATE_FACTORY (sink_templ,
70 "RIFF", GST_PROPS_STRING ("AVI")
74 GST_PADTEMPLATE_FACTORY (src_video_templ,
81 "format", GST_PROPS_LIST (
82 GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','U','Y','2')),
83 GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')),
84 GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' '))
86 "width", GST_PROPS_INT_RANGE (16, 4096),
87 "height", GST_PROPS_INT_RANGE (16, 4096)
91 GST_PADTEMPLATE_FACTORY (src_audio_templ,
98 "format", GST_PROPS_STRING ("int"),
99 "law", GST_PROPS_INT (0),
100 "endianness", GST_PROPS_INT (G_BYTE_ORDER),
101 "signed", GST_PROPS_LIST (
102 GST_PROPS_BOOLEAN (TRUE),
103 GST_PROPS_BOOLEAN (FALSE)
105 "width", GST_PROPS_LIST (
109 "depth", GST_PROPS_LIST (
113 "rate", GST_PROPS_INT_RANGE (11025, 48000),
114 "channels", GST_PROPS_INT_RANGE (1, 2)
118 static void gst_avi_decoder_class_init (GstAviDecoderClass *klass);
119 static void gst_avi_decoder_init (GstAviDecoder *avi_decoder);
121 static void gst_avi_decoder_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
125 static GstElementClass *parent_class = NULL;
126 /*static guint gst_avi_decoder_signals[LAST_SIGNAL] = { 0 }; */
129 gst_avi_decoder_get_type(void)
131 static GType avi_decoder_type = 0;
133 if (!avi_decoder_type) {
134 static const GTypeInfo avi_decoder_info = {
135 sizeof(GstAviDecoderClass),
138 (GClassInitFunc)gst_avi_decoder_class_init,
141 sizeof(GstAviDecoder),
143 (GInstanceInitFunc)gst_avi_decoder_init,
145 avi_decoder_type = g_type_register_static(GST_TYPE_BIN, "GstAviDecoder", &avi_decoder_info, 0);
147 return avi_decoder_type;
151 gst_avi_decoder_class_init (GstAviDecoderClass *klass)
153 GObjectClass *gobject_class;
154 GstElementClass *gstelement_class;
156 gobject_class = (GObjectClass*)klass;
157 gstelement_class = (GstElementClass*)klass;
159 g_object_class_install_property (G_OBJECT_CLASS(klass), ARG_BITRATE,
160 g_param_spec_long ("bitrate","bitrate","bitrate",
161 G_MINLONG, G_MAXLONG, 0, G_PARAM_READABLE)); /* CHECKME */
162 g_object_class_install_property (G_OBJECT_CLASS(klass), ARG_MEDIA_TIME,
163 g_param_spec_long ("media_time","media_time","media_time",
164 G_MINLONG, G_MAXLONG, 0, G_PARAM_READABLE)); /* CHECKME */
165 g_object_class_install_property (G_OBJECT_CLASS(klass), ARG_CURRENT_TIME,
166 g_param_spec_long ("current_time","current_time","current_time",
167 G_MINLONG, G_MAXLONG, 0, G_PARAM_READABLE)); /* CHECKME */
169 parent_class = g_type_class_ref (GST_TYPE_BIN);
171 gobject_class->get_property = gst_avi_decoder_get_property;
175 gst_avi_decoder_new_pad (GstElement *element, GstPad *pad, GstAviDecoder *avi_decoder)
178 GstCaps *targetcaps = NULL;
182 GstElement *new_element = NULL;
183 gchar *padname = NULL;
184 gchar *gpadname = NULL;
185 #define AVI_TYPE_VIDEO 1
186 #define AVI_TYPE_AUDIO 2
189 GST_DEBUG (0, "avidecoder: new pad for element \"%s\"", gst_element_get_name (element));
191 caps = gst_pad_get_caps (pad);
192 format = gst_caps_get_string (caps, "format");
194 if (!strcmp (format, "strf_vids")) {
195 targetcaps = gst_padtemplate_get_caps (GST_PADTEMPLATE_GET (src_video_templ));
196 media_type = AVI_TYPE_VIDEO;
197 gpadname = g_strdup_printf ("video_%02d", avi_decoder->video_count++);
199 else if (!strcmp (format, "strf_auds")) {
200 targetcaps = gst_padtemplate_get_caps (GST_PADTEMPLATE_GET (src_audio_templ));
201 media_type = AVI_TYPE_AUDIO;
202 gpadname = g_strdup_printf ("audio_%02d", avi_decoder->audio_count++);
204 else if (!strcmp (format, "strf_iavs")) {
205 targetcaps = gst_padtemplate_get_caps (GST_PADTEMPLATE_GET (src_video_templ));
206 media_type = AVI_TYPE_VIDEO;
207 gpadname = g_strdup_printf ("video_%02d", avi_decoder->video_count++);
210 g_assert_not_reached ();
213 gst_element_set_state (GST_ELEMENT (avi_decoder), GST_STATE_PAUSED);
215 type = gst_elementfactory_make ("avitypes",
216 g_strdup_printf ("typeconvert%d", avi_decoder->count));
218 /* brin the element to the READY state so it can do our caps negotiation */
219 gst_element_set_state (type, GST_STATE_READY);
221 gst_pad_connect (pad, gst_element_get_pad (type, "sink"));
222 type_found = gst_util_get_bool_arg (G_OBJECT (type), "type_found");
226 gst_bin_add (GST_BIN (avi_decoder), type);
228 pad = gst_element_get_pad (type, "src");
229 caps = gst_pad_get_caps (pad);
231 if (gst_caps_is_always_compatible (caps, targetcaps)) {
232 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
233 gst_element_get_pad (type, "src"), gpadname);
235 avi_decoder->count++;
238 #ifndef GST_DISABLE_AUTOPLUG
240 GstAutoplug *autoplug;
241 autoplug = gst_autoplugfactory_make("static");
243 new_element = gst_autoplug_to_caps (autoplug, caps, targetcaps, NULL);
247 #endif /* GST_DISABLE_AUTOPLUG */
250 if (!new_element && (media_type == AVI_TYPE_VIDEO)) {
253 else if (!new_element && (media_type == AVI_TYPE_AUDIO)) {
259 gst_pad_connect (pad, gst_element_get_pad (new_element, "sink"));
260 gst_element_set_name (new_element, g_strdup_printf ("element%d", avi_decoder->count));
261 gst_bin_add (GST_BIN (avi_decoder), new_element);
263 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
264 gst_element_get_pad (new_element, padname), gpadname);
266 avi_decoder->count++;
269 g_warning ("avidecoder: could not autoplug\n");
273 gst_element_set_state (GST_ELEMENT (avi_decoder), GST_STATE_PLAYING);
277 gst_avi_decoder_init (GstAviDecoder *avi_decoder)
279 avi_decoder->demuxer = gst_elementfactory_make ("avidemux", "demux");
281 if (avi_decoder->demuxer) {
282 gst_bin_add (GST_BIN (avi_decoder), avi_decoder->demuxer);
284 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
285 gst_element_get_pad (avi_decoder->demuxer, "sink"), "sink");
287 g_signal_connect (G_OBJECT (avi_decoder->demuxer),"new_pad", G_CALLBACK (gst_avi_decoder_new_pad),
291 g_warning ("wow!, no avi demuxer found. help me\n");
294 avi_decoder->count = 0;
295 avi_decoder->audio_count = 0;
296 avi_decoder->video_count = 0;
300 avi_typefind (GstBuffer *buf,
303 gchar *data = GST_BUFFER_DATA (buf);
306 GST_DEBUG (0,"avi_decoder: typefind");
307 if (strncmp (&data[0], "RIFF", 4)) return NULL;
308 if (strncmp (&data[8], "AVI ", 4)) return NULL;
310 new = GST_CAPS_NEW ("avi_typefind",
312 "RIFF", GST_PROPS_STRING ("AVI"));
318 gst_avi_decoder_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
322 g_return_if_fail (GST_IS_AVI_DECODER (object));
324 src = GST_AVI_DECODER (object);
330 g_value_set_long (value, gst_util_get_long_arg (G_OBJECT (src->demuxer), "media_time"));
332 case ARG_CURRENT_TIME:
333 g_value_set_long (value, gst_util_get_long_arg (G_OBJECT (src->demuxer), "current_time"));
342 plugin_init (GModule *module, GstPlugin *plugin)
344 GstElementFactory *factory;
345 GstTypeFactory *type;
347 /* create an elementfactory for the avi_decoder element */
348 factory = gst_elementfactory_new ("avidecoder", GST_TYPE_AVI_DECODER,
349 &gst_avi_decoder_details);
350 g_return_val_if_fail (factory != NULL, FALSE);
352 gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_audio_templ));
353 gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_video_templ));
354 gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_templ));
356 type = gst_typefactory_new (&avidefinition);
357 gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
359 gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
364 GstPluginDesc plugin_desc = {