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" "Wim Taymans <wim.taymans@tvd.be>",
38 static GstCaps *avi_typefind (GstBuffer * buf, gpointer private);
40 /* typefactory for 'avi' */
41 static GstTypeDefinition avidefinition = {
42 "avidecoder_video/avi",
48 /* AviDecoder signals and args */
64 GST_PADTEMPLATE_FACTORY (sink_templ,
68 GST_CAPS_NEW ("avidecoder_sink",
69 "video/avi", "RIFF", GST_PROPS_STRING ("AVI")
73 GST_PADTEMPLATE_FACTORY (src_video_templ,
77 GST_CAPS_NEW ("wincodec_src",
79 "format", GST_PROPS_LIST (GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y', 'U', 'Y',
80 '2')), GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I', '4', '2', '0')),
81 GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R', 'G', 'B', ' '))
82 ), "width", GST_PROPS_INT_RANGE (16, 4096), "height",
83 GST_PROPS_INT_RANGE (16, 4096)
87 GST_PADTEMPLATE_FACTORY (src_audio_templ,
91 GST_CAPS_NEW ("src_audio",
93 "format", GST_PROPS_STRING ("int"),
94 "law", GST_PROPS_INT (0),
95 "endianness", GST_PROPS_INT (G_BYTE_ORDER),
96 "signed", GST_PROPS_LIST (GST_PROPS_BOOLEAN (TRUE),
97 GST_PROPS_BOOLEAN (FALSE)
98 ), "width", GST_PROPS_LIST (GST_PROPS_INT (8), GST_PROPS_INT (16)
99 ), "depth", GST_PROPS_LIST (GST_PROPS_INT (8), GST_PROPS_INT (16)
101 "rate", GST_PROPS_INT_RANGE (11025, 48000),
102 "channels", GST_PROPS_INT_RANGE (1, 2)
106 static void gst_avi_decoder_class_init (GstAviDecoderClass * klass);
107 static void gst_avi_decoder_init (GstAviDecoder * avi_decoder);
109 static void gst_avi_decoder_get_property (GObject * object, guint prop_id,
110 GValue * value, GParamSpec * pspec);
114 static GstElementClass *parent_class = NULL;
116 /*static guint gst_avi_decoder_signals[LAST_SIGNAL] = { 0 }; */
119 gst_avi_decoder_get_type (void)
121 static GType avi_decoder_type = 0;
123 if (!avi_decoder_type) {
124 static const GTypeInfo avi_decoder_info = {
125 sizeof (GstAviDecoderClass),
128 (GClassInitFunc) gst_avi_decoder_class_init,
131 sizeof (GstAviDecoder),
133 (GInstanceInitFunc) gst_avi_decoder_init,
136 g_type_register_static (GST_TYPE_BIN, "GstAviDecoder",
137 &avi_decoder_info, 0);
139 return avi_decoder_type;
143 gst_avi_decoder_class_init (GstAviDecoderClass * klass)
145 GObjectClass *gobject_class;
146 GstElementClass *gstelement_class;
148 gobject_class = (GObjectClass *) klass;
149 gstelement_class = (GstElementClass *) klass;
151 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE, g_param_spec_long ("bitrate", "bitrate", "bitrate", G_MINLONG, G_MAXLONG, 0, G_PARAM_READABLE)); /* CHECKME */
152 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MEDIA_TIME, g_param_spec_long ("media_time", "media_time", "media_time", G_MINLONG, G_MAXLONG, 0, G_PARAM_READABLE)); /* CHECKME */
153 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CURRENT_TIME, g_param_spec_long ("current_time", "current_time", "current_time", G_MINLONG, G_MAXLONG, 0, G_PARAM_READABLE)); /* CHECKME */
155 parent_class = g_type_class_ref (GST_TYPE_BIN);
157 gobject_class->get_property = gst_avi_decoder_get_property;
161 gst_avi_decoder_new_pad (GstElement * element, GstPad * pad,
162 GstAviDecoder * avi_decoder)
165 GstCaps *targetcaps = NULL;
169 GstElement *new_element = NULL;
170 gchar *padname = NULL;
171 gchar *gpadname = NULL;
173 #define AVI_TYPE_VIDEO 1
174 #define AVI_TYPE_AUDIO 2
177 GST_DEBUG (0, "avidecoder: new pad for element \"%s\"",
178 gst_element_get_name (element));
180 caps = gst_pad_get_caps (pad);
181 format = gst_caps_get_string (caps, "format");
183 if (!strcmp (format, "strf_vids")) {
185 gst_padtemplate_get_caps (GST_PADTEMPLATE_GET (src_video_templ));
186 media_type = AVI_TYPE_VIDEO;
187 gpadname = g_strdup_printf ("video_%02d", avi_decoder->video_count++);
188 } else if (!strcmp (format, "strf_auds")) {
190 gst_padtemplate_get_caps (GST_PADTEMPLATE_GET (src_audio_templ));
191 media_type = AVI_TYPE_AUDIO;
192 gpadname = g_strdup_printf ("audio_%02d", avi_decoder->audio_count++);
193 } else if (!strcmp (format, "strf_iavs")) {
195 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 g_assert_not_reached ();
202 gst_element_set_state (GST_ELEMENT (avi_decoder), GST_STATE_PAUSED);
204 type = gst_elementfactory_make ("avitypes",
205 g_strdup_printf ("typeconvert%d", avi_decoder->count));
207 /* brin the element to the READY state so it can do our caps negotiation */
208 gst_element_set_state (type, GST_STATE_READY);
210 gst_pad_connect (pad, gst_element_get_pad (type, "sink"));
211 type_found = gst_util_get_bool_arg (G_OBJECT (type), "type_found");
215 gst_bin_add (GST_BIN (avi_decoder), type);
217 pad = gst_element_get_pad (type, "src");
218 caps = gst_pad_get_caps (pad);
220 if (gst_caps_is_always_compatible (caps, targetcaps)) {
221 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
222 gst_element_get_pad (type, "src"), gpadname);
224 avi_decoder->count++;
227 #ifndef GST_DISABLE_AUTOPLUG
229 GstAutoplug *autoplug;
231 autoplug = gst_autoplugfactory_make ("static");
233 new_element = gst_autoplug_to_caps (autoplug, caps, targetcaps, NULL);
237 #endif /* GST_DISABLE_AUTOPLUG */
240 if (!new_element && (media_type == AVI_TYPE_VIDEO)) {
242 } else if (!new_element && (media_type == AVI_TYPE_AUDIO)) {
248 gst_pad_connect (pad, gst_element_get_pad (new_element, "sink"));
249 gst_element_set_name (new_element, g_strdup_printf ("element%d",
250 avi_decoder->count));
251 gst_bin_add (GST_BIN (avi_decoder), new_element);
253 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
254 gst_element_get_pad (new_element, padname), gpadname);
256 avi_decoder->count++;
258 g_warning ("avidecoder: could not autoplug\n");
262 gst_element_set_state (GST_ELEMENT (avi_decoder), GST_STATE_PLAYING);
266 gst_avi_decoder_init (GstAviDecoder * avi_decoder)
268 avi_decoder->demuxer = gst_elementfactory_make ("avidemux", "demux");
270 if (avi_decoder->demuxer) {
271 gst_bin_add (GST_BIN (avi_decoder), avi_decoder->demuxer);
273 gst_element_add_ghost_pad (GST_ELEMENT (avi_decoder),
274 gst_element_get_pad (avi_decoder->demuxer, "sink"), "sink");
276 g_signal_connect (G_OBJECT (avi_decoder->demuxer), "new_pad",
277 G_CALLBACK (gst_avi_decoder_new_pad), avi_decoder);
279 g_warning ("wow!, no avi demuxer found. help me\n");
282 avi_decoder->count = 0;
283 avi_decoder->audio_count = 0;
284 avi_decoder->video_count = 0;
288 avi_typefind (GstBuffer * buf, gpointer private)
290 gchar *data = GST_BUFFER_DATA (buf);
293 GST_DEBUG (0, "avi_decoder: typefind");
294 if (strncmp (&data[0], "RIFF", 4))
296 if (strncmp (&data[8], "AVI ", 4))
299 new = GST_CAPS_NEW ("avi_typefind",
300 "video/avi", "RIFF", GST_PROPS_STRING ("AVI"));
306 gst_avi_decoder_get_property (GObject * object, guint prop_id, GValue * value,
311 g_return_if_fail (GST_IS_AVI_DECODER (object));
313 src = GST_AVI_DECODER (object);
319 g_value_set_long (value, gst_util_get_long_arg (G_OBJECT (src->demuxer),
322 case ARG_CURRENT_TIME:
323 g_value_set_long (value, gst_util_get_long_arg (G_OBJECT (src->demuxer),
333 plugin_init (GModule * module, GstPlugin * plugin)
335 GstElementFactory *factory;
336 GstTypeFactory *type;
338 /* create an elementfactory for the avi_decoder element */
339 factory = gst_elementfactory_new ("avidecoder", GST_TYPE_AVI_DECODER,
340 &gst_avi_decoder_details);
341 g_return_val_if_fail (factory != NULL, FALSE);
343 gst_elementfactory_add_padtemplate (factory,
344 GST_PADTEMPLATE_GET (src_audio_templ));
345 gst_elementfactory_add_padtemplate (factory,
346 GST_PADTEMPLATE_GET (src_video_templ));
347 gst_elementfactory_add_padtemplate (factory,
348 GST_PADTEMPLATE_GET (sink_templ));
350 type = gst_typefactory_new (&avidefinition);
351 gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
353 gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
358 GstPluginDesc plugin_desc = {