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\"\n", 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 gst_element_set_state (type, GST_STATE_READY);
220 gst_pad_connect (pad, gst_element_get_pad (type, "sink"));
221 type_found = gst_util_get_bool_arg (G_OBJECT (type), "type_found");
225 gst_bin_add (GST_BIN (avi_decoder), type);
227 pad = gst_element_get_pad (type, "src");
228 caps = gst_pad_get_caps (pad);
230 if (gst_caps_check_compatibility (caps, targetcaps)) {
231 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
232 gst_element_get_pad (type, "src"), gpadname);
234 avi_decoder->count++;
237 #ifndef GST_DISABLE_AUTOPLUG
239 GstAutoplug *autoplug;
240 autoplug = gst_autoplugfactory_make("static");
242 new_element = gst_autoplug_to_caps (autoplug, caps, targetcaps, NULL);
246 #endif /* GST_DISABLE_AUTOPLUG */
249 if (!new_element && (media_type == AVI_TYPE_VIDEO)) {
252 else if (!new_element && (media_type == AVI_TYPE_AUDIO)) {
258 gst_pad_connect (pad, gst_element_get_pad (new_element, "sink"));
259 gst_element_set_name (new_element, g_strdup_printf ("element%d", avi_decoder->count));
260 gst_bin_add (GST_BIN (avi_decoder), new_element);
262 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
263 gst_element_get_pad (new_element, padname), gpadname);
265 avi_decoder->count++;
268 g_warning ("avidecoder: could not autoplug\n");
272 gst_element_set_state (GST_ELEMENT (avi_decoder), GST_STATE_PLAYING);
276 gst_avi_decoder_init (GstAviDecoder *avi_decoder)
278 avi_decoder->demuxer = gst_elementfactory_make ("avidemux", "demux");
280 if (avi_decoder->demuxer) {
281 gst_bin_add (GST_BIN (avi_decoder), avi_decoder->demuxer);
283 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
284 gst_element_get_pad (avi_decoder->demuxer, "sink"), "sink");
286 g_signal_connect (G_OBJECT (avi_decoder->demuxer),"new_pad", G_CALLBACK (gst_avi_decoder_new_pad),
290 g_warning ("wow!, no avi demuxer found. help me\n");
293 avi_decoder->count = 0;
294 avi_decoder->audio_count = 0;
295 avi_decoder->video_count = 0;
299 avi_typefind (GstBuffer *buf,
302 gchar *data = GST_BUFFER_DATA (buf);
305 GST_DEBUG (0,"avi_decoder: typefind\n");
306 if (strncmp (&data[0], "RIFF", 4)) return NULL;
307 if (strncmp (&data[8], "AVI ", 4)) return NULL;
309 new = GST_CAPS_NEW ("avi_typefind",
311 "RIFF", GST_PROPS_STRING ("AVI"));
317 gst_avi_decoder_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
321 g_return_if_fail (GST_IS_AVI_DECODER (object));
323 src = GST_AVI_DECODER (object);
329 g_value_set_long (value, gst_util_get_long_arg (G_OBJECT (src->demuxer), "media_time"));
331 case ARG_CURRENT_TIME:
332 g_value_set_long (value, gst_util_get_long_arg (G_OBJECT (src->demuxer), "current_time"));
341 plugin_init (GModule *module, GstPlugin *plugin)
343 GstElementFactory *factory;
344 GstTypeFactory *type;
346 /* create an elementfactory for the avi_decoder element */
347 factory = gst_elementfactory_new ("avidecoder", GST_TYPE_AVI_DECODER,
348 &gst_avi_decoder_details);
349 g_return_val_if_fail (factory != NULL, FALSE);
351 gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_audio_templ));
352 gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_video_templ));
353 gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_templ));
355 type = gst_typefactory_new (&avidefinition);
356 gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
358 gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
363 GstPluginDesc plugin_desc = {