This is a megapatch with the following changes:
[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 "gsttypefind.h"
29
30 //#define GST_DEBUG_ENABLED
31
32 GstElementDetails gst_typefind_details = {
33   "TypeFind",
34   "TypeFind",
35   "Finds the media type",
36   VERSION,
37   "Erik Walthinsen <omega@cse.ogi.edu>"
38   "Wim Taymans <wim.taymans@chello.be>",
39   "(C) 1999",
40 };
41
42
43 /* TypeFind signals and args */
44 enum {
45   HAVE_TYPE,
46   LAST_SIGNAL
47 };
48
49 enum {
50   ARG_0,
51   ARG_CAPS,
52 };
53
54
55 static void     gst_typefind_class_init (GstTypeFindClass *klass);
56 static void     gst_typefind_init       (GstTypeFind *typefind);
57
58 static void     gst_typefind_set_arg    (GtkObject *object, GtkArg *arg, guint id);
59 static void     gst_typefind_get_arg    (GtkObject *object, GtkArg *arg, guint id);
60
61 static void     gst_typefind_chain      (GstPad *pad, GstBuffer *buf);
62
63 static GstElementClass *parent_class = NULL;
64 static guint gst_typefind_signals[LAST_SIGNAL] = { 0 };
65
66 GtkType
67 gst_typefind_get_type(void) {
68   static GtkType typefind_type = 0;
69
70   if (!typefind_type) {
71     static const GtkTypeInfo typefind_info = {
72       "GstTypeFind",
73       sizeof(GstTypeFind),
74       sizeof(GstTypeFindClass),
75       (GtkClassInitFunc)gst_typefind_class_init,
76       (GtkObjectInitFunc)gst_typefind_init,
77       (GtkArgSetFunc)gst_typefind_set_arg,
78       (GtkArgGetFunc)gst_typefind_get_arg,
79       (GtkClassInitFunc)NULL,
80     };
81     typefind_type = gtk_type_unique(GST_TYPE_ELEMENT,&typefind_info);
82   }
83   return typefind_type;
84 }
85
86 static void
87 gst_typefind_class_init (GstTypeFindClass *klass) 
88 {
89   GtkObjectClass *gtkobject_class;
90
91   gtkobject_class = (GtkObjectClass*)klass;
92
93   parent_class = gtk_type_class (GST_TYPE_ELEMENT);
94
95   gtk_object_add_arg_type("GstTypeFind::caps", GTK_TYPE_POINTER,
96                           GTK_ARG_READABLE, ARG_CAPS);
97
98   gst_typefind_signals[HAVE_TYPE] =
99       gtk_signal_new ("have_type", GTK_RUN_LAST, gtkobject_class->type,
100                       GTK_SIGNAL_OFFSET (GstTypeFindClass, have_type),
101                       gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
102
103   gtk_object_class_add_signals (gtkobject_class, gst_typefind_signals,
104                                 LAST_SIGNAL);
105
106   gtkobject_class->set_arg = gst_typefind_set_arg;
107   gtkobject_class->get_arg = gst_typefind_get_arg;
108 }
109
110 static void 
111 gst_typefind_init (GstTypeFind *typefind) 
112 {
113   typefind->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
114   gst_element_add_pad (GST_ELEMENT (typefind), typefind->sinkpad);
115   gst_pad_set_chain_function (typefind->sinkpad, gst_typefind_chain);
116 }
117
118 static void 
119 gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id) 
120 {
121   GstTypeFind *typefind;
122
123   /* it's not null if we got it, but it might not be ours */
124   g_return_if_fail (GST_IS_TYPEFIND (object));
125   
126   typefind = GST_TYPEFIND (object);
127
128   switch(id) {
129     default:
130       break;
131   }
132 }
133
134 static void 
135 gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id) 
136 {
137   GstTypeFind *typefind;
138
139   /* it's not null if we got it, but it might not be ours */
140   g_return_if_fail (GST_IS_TYPEFIND (object));
141   
142   typefind = GST_TYPEFIND (object);
143
144   switch(id) {
145     case ARG_CAPS:
146       GTK_VALUE_POINTER (*arg) =  typefind->caps;
147       break;
148     default:
149       break;
150   }
151 }
152
153 static void 
154 gst_typefind_chain (GstPad *pad, GstBuffer *buf) 
155 {
156   GstTypeFind *typefind;
157   GList *type_list;
158   GstType *type;
159
160   g_return_if_fail (pad != NULL);
161   g_return_if_fail (GST_IS_PAD (pad));
162   g_return_if_fail (buf != NULL);
163
164   typefind = GST_TYPEFIND (GST_OBJECT_PARENT (pad));
165   GST_DEBUG (0,"got buffer of %d bytes in '%s'\n",
166         GST_BUFFER_SIZE (buf), GST_OBJECT_NAME (typefind));
167
168   type_list = gst_type_get_list ();
169
170   while (type_list) {
171     GSList *funcs;
172     type = (GstType *)type_list->data;
173
174     funcs = type->typefindfuncs;
175
176     while (funcs) {
177       GstTypeFindFunc typefindfunc = (GstTypeFindFunc)funcs->data;
178       GstCaps *caps;
179
180       GST_DEBUG (0,"try type :%d \"%s\"\n", type->id, type->mime);
181       if (typefindfunc && (caps = typefindfunc (buf, type))) {
182         GST_DEBUG (0,"found type :%d \"%s\"\n", caps->id, type->mime);
183         typefind->caps = caps;
184         gtk_signal_emit (GTK_OBJECT (typefind), gst_typefind_signals[HAVE_TYPE],
185                               typefind->caps);
186         goto end;
187       }
188       funcs = g_slist_next (funcs);
189     }
190
191     type_list = g_list_next (type_list);
192   }
193 end:
194   gst_buffer_unref (buf);
195 }