e08621302dd99b477f674693c56204addb3db900
[platform/upstream/gst-plugins-good.git] / gst / avi / gstavitypes.c
1 /* Gnome-Streamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
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.
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  * Library General Public License for more details.
13  *
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.
18  */
19
20
21 //#define GST_DEBUG_ENABLED
22 #include <string.h>
23
24 #include "gstavitypes.h"
25
26
27
28 /* elementfactory information */
29 static GstElementDetails gst_avi_types_details = {
30   "avi type converter",
31   "Decoder/Video",
32   "Converts avi types into gstreamer types",
33   VERSION,
34   "Wim Taymans <wim.taymans@tvd.be>",
35   "(C) 1999",
36 };
37
38 /* AviTypes signals and args */
39 enum {
40   /* FILL ME */
41   LAST_SIGNAL
42 };
43
44 enum {
45   ARG_0,
46   ARG_TYPE_FOUND,
47   /* FILL ME */
48 };
49
50 GST_PADTEMPLATE_FACTORY (sink_templ,
51   "sink",
52   GST_PAD_SINK,
53   GST_PAD_ALWAYS,
54   GST_CAPS_NEW (
55     "avitypes_sink",
56      "video/avi",
57       "format",         GST_PROPS_LIST (
58                           GST_PROPS_STRING ("strf_vids"),
59                           GST_PROPS_STRING ("strf_auds"),
60                           GST_PROPS_STRING ("strf_iavs")
61                         )
62   )
63 )
64
65 GST_PADTEMPLATE_FACTORY (src_templ,
66   "video_src",
67   GST_PAD_SRC,
68   GST_PAD_ALWAYS,
69   GST_CAPS_NEW (
70     "avitypes_src",
71     "video/raw",
72       "format",         GST_PROPS_LIST (
73                           GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','U','Y','2')),
74                           GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' '))
75                         ),
76       "width",          GST_PROPS_INT_RANGE (16, 4096),
77       "height",         GST_PROPS_INT_RANGE (16, 4096)
78   ),
79   GST_CAPS_NEW (
80     "avitypes_src",
81     "video/avi",
82       "format",         GST_PROPS_STRING ("strf_vids")
83   ),
84   GST_CAPS_NEW (
85     "src_audio",
86     "audio/raw",
87       "format",           GST_PROPS_STRING ("int"),
88       "law",              GST_PROPS_INT (0),
89       "endianness",       GST_PROPS_INT (G_BYTE_ORDER),
90       "signed",           GST_PROPS_LIST (
91                             GST_PROPS_BOOLEAN (TRUE),
92                             GST_PROPS_BOOLEAN (FALSE)
93                           ),
94       "width",            GST_PROPS_LIST (
95                             GST_PROPS_INT (8),
96                             GST_PROPS_INT (16)
97                           ),
98       "depth",            GST_PROPS_LIST (
99                             GST_PROPS_INT (8),
100                             GST_PROPS_INT (16)
101                           ),
102       "rate",             GST_PROPS_INT_RANGE (11025, 44100),
103       "channels",         GST_PROPS_INT_RANGE (1, 2)
104   ),
105   GST_CAPS_NEW (
106     "src_audio",
107     "audio/mp3",
108     NULL
109   ),
110   GST_CAPS_NEW (
111     "src_video",
112     "video/jpeg",
113     NULL
114   ),
115   GST_CAPS_NEW (
116     "src_dv",
117     "video/dv",
118     NULL
119   )
120 )
121
122 static void     gst_avi_types_class_init        (GstAviTypesClass *klass);
123 static void     gst_avi_types_init              (GstAviTypes *avi_types);
124
125 static void     gst_avi_types_chain             (GstPad *pad, GstBuffer *buffer); 
126
127 static void     gst_avi_types_get_property      (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
128
129
130 static GstElementClass *parent_class = NULL;
131 //static guint gst_avi_types_signals[LAST_SIGNAL] = { 0 };
132
133 GType
134 gst_avi_types_get_type(void) 
135 {
136   static GType avi_types_type = 0;
137
138   if (!avi_types_type) {
139     static const GTypeInfo avi_types_info = {
140       sizeof(GstAviTypesClass),      
141       NULL,
142       NULL,
143       (GClassInitFunc)gst_avi_types_class_init,
144       NULL,
145       NULL,
146       sizeof(GstAviTypes),
147       0,
148       (GInstanceInitFunc)gst_avi_types_init,
149     };
150     avi_types_type = g_type_register_static(GST_TYPE_ELEMENT, "GstAviTypes", &avi_types_info, 0);
151   }
152   return avi_types_type;
153 }
154
155 static void
156 gst_avi_types_class_init (GstAviTypesClass *klass) 
157 {
158   GObjectClass *gobject_class;
159   GstElementClass *gstelement_class;
160
161   gobject_class = (GObjectClass*)klass;
162   gstelement_class = (GstElementClass*)klass;
163
164   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
165   
166   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TYPE_FOUND,
167     g_param_spec_boolean ("type_found","type_found","type_found",
168                      FALSE, G_PARAM_READABLE));
169
170   gobject_class->get_property = gst_avi_types_get_property;
171 }
172
173 static GstPadConnectReturn 
174 gst_avi_types_sinkconnect (GstPad *pad, GstCaps *caps) 
175 {
176   GstAviTypes *avi_types;
177   const gchar *format;
178   GstCaps *newcaps = NULL;
179
180   avi_types = GST_AVI_TYPES (gst_pad_get_parent (pad));
181
182   format = gst_caps_get_string (caps, "format");
183
184   if (!strcmp (format, "strf_vids")) {
185     gulong video_format = gst_caps_get_fourcc_int (caps, "compression");
186
187     switch (video_format) {
188       case GST_MAKE_FOURCC ('M','J','P','G'):
189         newcaps = gst_caps_new ("avi_type_mjpg",
190                       "video/jpeg", NULL);
191         break;
192       case GST_MAKE_FOURCC ('d','v','s','d'):
193         newcaps = gst_caps_new ("avi_type_dv", 
194                             "video/dv", 
195                             gst_props_new (
196                               "format",         GST_PROPS_STRING ("NTSC"),
197                               NULL));
198       default:
199         /* else we simply don't convert, and hope there is a native decoder
200          * available */
201         newcaps = caps;
202         break;
203     }
204   }
205   else if (!strcmp (format, "strf_auds")) {
206     gint16 audio_format         = gst_caps_get_int (caps, "fmt");
207     gint blockalign             = gst_caps_get_int (caps, "blockalign");
208     gint size                   = gst_caps_get_int (caps, "size");
209     gint channels               = gst_caps_get_int (caps, "channels");
210     gint rate                   = gst_caps_get_int (caps, "rate");
211     gboolean sign               = (size == 8 ? FALSE : TRUE);
212
213     GST_DEBUG (GST_CAT_PLUGIN_INFO, "avitypes: new caps with audio format:%04x\n", audio_format);
214
215     switch (audio_format) {
216       case 0x0001:
217         newcaps = gst_caps_new ("avi_type_pcm",
218                     "audio/raw",
219                     gst_props_new (
220                       "format",           GST_PROPS_STRING ("int"),
221                       "law",              GST_PROPS_INT (0),
222                       "endianness",       GST_PROPS_INT (G_BYTE_ORDER),
223                       "signed",           GST_PROPS_BOOLEAN (sign),
224                       "width",            GST_PROPS_INT ((blockalign*8)/channels),
225                       "depth",            GST_PROPS_INT (size),
226                       "rate",             GST_PROPS_INT (rate),
227                       "channels",         GST_PROPS_INT (channels),
228                       NULL
229                     ));
230         break;
231       case 0x0050:
232       case 0x0055:
233         newcaps = gst_caps_new ("avi_type_mp3",
234                       "audio/mp3", NULL);
235         break;
236       default:
237         break;
238     }
239   }
240   else if (!strcmp (format, "strf_iavs")) {
241     newcaps = gst_caps_new ("avi_type_dv", 
242                             "video/dv", 
243                             gst_props_new (
244                               "format",         GST_PROPS_STRING ("NTSC"),
245                               NULL));
246   }
247   
248   if (newcaps) {
249     gst_pad_try_set_caps (avi_types->srcpad, newcaps);
250     avi_types->type_found = TRUE;
251     return GST_PAD_CONNECT_OK;
252   }
253   return GST_PAD_CONNECT_REFUSED;
254 }
255
256 static void 
257 gst_avi_types_init (GstAviTypes *avi_types) 
258 {
259   avi_types->sinkpad = gst_pad_new_from_template (
260                   GST_PADTEMPLATE_GET (sink_templ), "sink");
261   gst_element_add_pad (GST_ELEMENT (avi_types), avi_types->sinkpad);
262   gst_pad_set_connect_function (avi_types->sinkpad, gst_avi_types_sinkconnect);
263   gst_pad_set_chain_function (avi_types->sinkpad, gst_avi_types_chain);
264
265   avi_types->srcpad = gst_pad_new_from_template (
266                   GST_PADTEMPLATE_GET (src_templ), "src");
267   gst_element_add_pad (GST_ELEMENT (avi_types), avi_types->srcpad);
268
269   avi_types->type_found = FALSE;
270 }
271
272 static void 
273 gst_avi_types_chain (GstPad *pad, GstBuffer *buffer) 
274 {
275   GstAviTypes *avi_types;
276
277   avi_types = GST_AVI_TYPES (gst_pad_get_parent (pad));
278
279   if (GST_PAD_IS_CONNECTED (avi_types->srcpad))
280     gst_pad_push (avi_types->srcpad, buffer);
281   else
282     gst_buffer_unref (buffer);
283 }
284
285 static void
286 gst_avi_types_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
287 {
288   GstAviTypes *src;
289
290   /* it's not null if we got it, but it might not be ours */
291   g_return_if_fail (GST_IS_AVI_TYPES (object));
292
293   src = GST_AVI_TYPES (object);
294
295   switch (prop_id) {
296     case ARG_TYPE_FOUND:
297       g_value_set_boolean (value, src->type_found);
298       break;
299     default:
300       break;
301   }
302 }
303
304 static gboolean
305 plugin_init (GModule *module, GstPlugin *plugin)
306 {
307   GstElementFactory *factory;
308
309   /* create an elementfactory for the avi_types element */
310   factory = gst_elementfactory_new ("avitypes",GST_TYPE_AVI_TYPES,
311                                     &gst_avi_types_details);
312   g_return_val_if_fail (factory != NULL, FALSE);
313
314   //gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_templ));
315   gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_templ));
316
317   gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
318
319   return TRUE;
320 }
321
322 GstPluginDesc plugin_desc = {
323   GST_VERSION_MAJOR,
324   GST_VERSION_MINOR,
325   "avitypes",
326   plugin_init
327 };
328