style stuff
[platform/upstream/gstreamer.git] / gst / gsttypefind.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gsttypefind.c: 
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23
24 #include "gst_private.h"
25
26 #include "gsttype.h"
27
28 #include "gstlog.h"
29 #include "gsttypefind.h"
30
31 /* #define GST_DEBUG_ENABLED */
32
33 GstElementDetails gst_type_find_details = {
34   "TypeFind",
35   "Generic",
36   "LGPL",
37   "Finds the media type of a stream",
38   VERSION,
39   "Erik Walthinsen <omega@cse.ogi.edu>,"
40   "Wim Taymans <wim.taymans@chello.be>",
41   "(C) 1999",
42 };
43
44
45 /* TypeFind signals and args */
46 enum {
47   HAVE_TYPE,
48   LAST_SIGNAL
49 };
50
51 enum {
52   ARG_0,
53   ARG_CAPS,
54 };
55
56
57 static void     gst_type_find_class_init        (GstTypeFindClass *klass);
58 static void     gst_type_find_init              (GstTypeFind *typefind);
59
60 static void     gst_type_find_set_property      (GObject *object, guint prop_id,
61                                                  const GValue *value, 
62                                                  GParamSpec *pspec);
63 static void     gst_type_find_get_property      (GObject *object, guint prop_id,
64                                                  GValue *value, 
65                                                  GParamSpec *pspec);
66
67 static void     gst_type_find_chain             (GstPad *pad, GstBuffer *buf);
68
69 static GstElementClass *parent_class = NULL;
70 static guint gst_type_find_signals[LAST_SIGNAL] = { 0 };
71
72 GType
73 gst_type_find_get_type (void)
74 {
75   static GType typefind_type = 0;
76
77   if (!typefind_type) {
78     static const GTypeInfo typefind_info = {
79       sizeof(GstTypeFindClass),
80       NULL,
81       NULL,
82       (GClassInitFunc)gst_type_find_class_init,
83       NULL,
84       NULL,
85       sizeof(GstTypeFind),
86       0,
87       (GInstanceInitFunc)gst_type_find_init,
88       NULL
89     };
90     typefind_type = g_type_register_static (GST_TYPE_ELEMENT, "GstTypeFind", &typefind_info, 0);
91   }
92   return typefind_type;
93 }
94
95 static void
96 gst_type_find_class_init (GstTypeFindClass *klass)
97 {
98   GObjectClass *gobject_class;
99
100   gobject_class = (GObjectClass*)klass;
101
102   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
103
104   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CAPS,
105     g_param_spec_pointer("caps", "Caps", "Found capabilities", G_PARAM_READABLE));
106
107   gst_type_find_signals[HAVE_TYPE] =
108       g_signal_new ("have_type", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
109                      G_STRUCT_OFFSET (GstTypeFindClass, have_type), NULL, NULL,
110                      g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
111                      G_TYPE_POINTER);
112
113   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_type_find_set_property);
114   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_type_find_get_property);
115 }
116
117 static void
118 gst_type_find_init (GstTypeFind *typefind)
119 {
120   typefind->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
121   gst_element_add_pad (GST_ELEMENT (typefind), typefind->sinkpad);
122   gst_pad_set_chain_function (typefind->sinkpad, gst_type_find_chain);
123 }
124
125 static void
126 gst_type_find_set_property (GObject *object, guint prop_id, 
127                             const GValue *value, GParamSpec *pspec)
128 {
129   GstTypeFind *typefind;
130
131   g_return_if_fail (GST_IS_TYPE_FIND (object));
132
133   typefind = GST_TYPE_FIND (object);
134
135   switch (prop_id) {
136     default:
137       break;
138   }
139 }
140
141 static void
142 gst_type_find_get_property (GObject *object, guint prop_id, 
143                             GValue *value, GParamSpec *pspec)
144 {
145   GstTypeFind *typefind;
146
147   g_return_if_fail (GST_IS_TYPE_FIND (object));
148
149   typefind = GST_TYPE_FIND (object);
150
151   switch (prop_id) {
152     case ARG_CAPS:
153       g_value_set_pointer(value, typefind->caps);
154       break;
155     default:
156       break;
157   }
158 }
159
160 static void
161 gst_type_find_chain (GstPad *pad, GstBuffer *buf)
162 {
163   GstTypeFind *typefind;
164   GList *type_list;
165   GstType *type;
166
167   g_return_if_fail (pad != NULL);
168   g_return_if_fail (GST_IS_PAD (pad));
169   g_return_if_fail (buf != NULL);
170
171   typefind = GST_TYPE_FIND (GST_OBJECT_PARENT (pad));
172   GST_DEBUG (0,"got buffer of %d bytes in '%s'",
173         GST_BUFFER_SIZE (buf), GST_OBJECT_NAME (typefind));
174
175   type_list = (GList *) gst_type_get_list ();
176
177   while (type_list) {
178     GSList *factories;
179     type = (GstType *) type_list->data;
180
181     factories = type->factories;
182
183     while (factories) {
184       GstTypeFactory *factory = GST_TYPE_FACTORY (factories->data);
185       GstTypeFindFunc typefindfunc = (GstTypeFindFunc)factory->typefindfunc;
186       GstCaps *caps;
187
188       GST_DEBUG (GST_CAT_TYPES, "try type (%p) :%d \"%s\" %p", 
189                  factory, type->id, type->mime, typefindfunc);
190       if (typefindfunc && (caps = typefindfunc (buf, factory))) {
191         GST_DEBUG (GST_CAT_TYPES, "found type: %d \"%s\" \"%s\"", 
192                    caps->id, type->mime, gst_caps_get_name (caps));
193         typefind->caps = caps;
194
195         if (gst_pad_try_set_caps (pad, caps) <= 0) {
196           g_warning ("typefind: found type but peer didn't accept it");
197         }
198
199         {
200           /* int oldstate = GST_STATE(typefind);*/
201           gst_object_ref (GST_OBJECT (typefind));
202           g_signal_emit (G_OBJECT (typefind), gst_type_find_signals[HAVE_TYPE], 0,
203                               typefind->caps);
204 /*          if (GST_STATE(typefind) != oldstate) {
205             GST_DEBUG(0, "state changed during signal, aborting");
206             gst_element_interrupt (GST_ELEMENT (typefind));
207             } */
208           gst_object_unref (GST_OBJECT (typefind));
209
210           goto end;
211         }
212       }
213       factories = g_slist_next (factories);
214     }
215
216     type_list = g_list_next (type_list);
217   }
218 end:
219   gst_buffer_unref (buf);
220 }