Initialize Tizen 2.3
[framework/multimedia/gst-plugins-base0.10.git] / mobile / gst / playback / gststreaminfo.c
1 /* GStreamer
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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <string.h>
25 #include <gst/gst.h>
26 #include "gststreaminfo.h"
27
28 GST_DEBUG_CATEGORY_STATIC (gst_streaminfo_debug);
29 #define GST_CAT_DEFAULT gst_streaminfo_debug
30
31 /* props */
32 enum
33 {
34   ARG_0,
35   ARG_PAD,
36   ARG_TYPE,
37   ARG_DECODER,
38   ARG_MUTE,
39   ARG_CAPS,
40   ARG_LANG_CODE,
41   ARG_CODEC
42 };
43
44 /* signals */
45 enum
46 {
47   SIGNAL_MUTED,
48   LAST_SIGNAL
49 };
50
51 static guint gst_stream_info_signals[LAST_SIGNAL] = { 0 };
52
53 #define GST_TYPE_STREAM_TYPE (gst_stream_type_get_type())
54 static GType
55 gst_stream_type_get_type (void)
56 {
57   static GType stream_type_type = 0;
58   static const GEnumValue stream_type[] = {
59     {GST_STREAM_TYPE_UNKNOWN, "Unknown stream", "unknown"},
60     {GST_STREAM_TYPE_AUDIO, "Audio stream", "audio"},
61     {GST_STREAM_TYPE_VIDEO, "Video stream", "video"},
62     {GST_STREAM_TYPE_TEXT, "Text stream", "text"},
63     {GST_STREAM_TYPE_SUBPICTURE, "Subpicture stream", "subpicture"},
64     {GST_STREAM_TYPE_ELEMENT,
65         "Stream handled by element", "element"},
66     {0, NULL, NULL},
67   };
68
69   if (!stream_type_type) {
70     stream_type_type = g_enum_register_static ("GstStreamType", stream_type);
71   }
72   return stream_type_type;
73 }
74
75 static void gst_stream_info_class_init (GstStreamInfoClass * klass);
76 static void gst_stream_info_init (GstStreamInfo * stream_info);
77 static void gst_stream_info_dispose (GObject * object);
78
79 static void stream_info_change_state (GstElement * element,
80     gint old_state, gint new_state, gpointer data);
81
82 static void gst_stream_info_set_property (GObject * object, guint prop_id,
83     const GValue * value, GParamSpec * spec);
84 static void gst_stream_info_get_property (GObject * object, guint prop_id,
85     GValue * value, GParamSpec * spec);
86
87 static GObjectClass *parent_class;
88
89 //static guint gst_stream_info_signals[LAST_SIGNAL] = { 0 };
90
91 GType
92 gst_stream_info_get_type (void)
93 {
94   static GType gst_stream_info_type = 0;
95
96   if (!gst_stream_info_type) {
97     static const GTypeInfo gst_stream_info_info = {
98       sizeof (GstStreamInfoClass),
99       NULL,
100       NULL,
101       (GClassInitFunc) gst_stream_info_class_init,
102       NULL,
103       NULL,
104       sizeof (GstStreamInfo),
105       0,
106       (GInstanceInitFunc) gst_stream_info_init,
107       NULL
108     };
109     gst_stream_info_type = g_type_register_static (G_TYPE_OBJECT,
110         "GstStreamInfo", &gst_stream_info_info, 0);
111   }
112
113   return gst_stream_info_type;
114 }
115
116 static void
117 gst_stream_info_class_init (GstStreamInfoClass * klass)
118 {
119   GObjectClass *gobject_klass;
120
121   gobject_klass = (GObjectClass *) klass;
122
123   parent_class = g_type_class_peek_parent (klass);
124
125   gobject_klass->set_property = gst_stream_info_set_property;
126   gobject_klass->get_property = gst_stream_info_get_property;
127
128   g_object_class_install_property (gobject_klass, ARG_PAD,
129       g_param_spec_object ("object", "object",
130           "Source Pad or object of the stream", GST_TYPE_OBJECT,
131           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
132   g_object_class_install_property (gobject_klass, ARG_TYPE,
133       g_param_spec_enum ("type", "Type", "Type of the stream",
134           GST_TYPE_STREAM_TYPE, GST_STREAM_TYPE_UNKNOWN,
135           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
136   g_object_class_install_property (gobject_klass, ARG_DECODER,
137       g_param_spec_string ("decoder", "Decoder",
138           "The decoder used to decode the stream", NULL,
139           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
140   g_object_class_install_property (gobject_klass, ARG_MUTE,
141       g_param_spec_boolean ("mute", "Mute", "Mute or unmute this stream", FALSE,
142           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
143   g_object_class_install_property (gobject_klass, ARG_CAPS,
144       g_param_spec_boxed ("caps", "Capabilities",
145           "Capabilities (or type) of this stream", GST_TYPE_CAPS,
146           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
147   g_object_class_install_property (gobject_klass, ARG_LANG_CODE,
148       g_param_spec_string ("language-code", "Language code",
149           "Language code for this stream, conforming to ISO-639-1", NULL,
150           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
151   g_object_class_install_property (gobject_klass, ARG_CODEC,
152       g_param_spec_string ("codec", "Codec", "Codec used to encode the stream",
153           NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
154
155   gst_stream_info_signals[SIGNAL_MUTED] =
156       g_signal_new ("muted", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
157       G_STRUCT_OFFSET (GstStreamInfoClass, muted), NULL, NULL,
158       gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
159
160   gobject_klass->dispose = gst_stream_info_dispose;
161
162   GST_DEBUG_CATEGORY_INIT (gst_streaminfo_debug, "streaminfo", 0,
163       "Playbin Stream Info");
164 }
165
166
167 static void
168 gst_stream_info_init (GstStreamInfo * stream_info)
169 {
170   stream_info->object = NULL;
171   stream_info->origin = NULL;
172   stream_info->type = GST_STREAM_TYPE_UNKNOWN;
173   stream_info->decoder = NULL;
174   stream_info->mute = FALSE;
175   stream_info->caps = NULL;
176 }
177
178 static gboolean
179 cb_probe (GstPad * pad, GstEvent * e, gpointer user_data)
180 {
181   GstStreamInfo *info = user_data;
182
183   if (GST_EVENT_TYPE (e) == GST_EVENT_TAG) {
184     gchar *codec, *lang;
185     GstTagList *list;
186
187     gst_event_parse_tag (e, &list);
188
189     if (info->type != GST_STREAM_TYPE_AUDIO &&
190         gst_tag_list_get_string (list, GST_TAG_VIDEO_CODEC, &codec)) {
191       g_free (info->codec);
192       info->codec = codec;
193       GST_LOG_OBJECT (pad, "codec = %s (video)", codec);
194       g_object_notify (G_OBJECT (info), "codec");
195     } else if (info->type != GST_STREAM_TYPE_VIDEO &&
196         gst_tag_list_get_string (list, GST_TAG_AUDIO_CODEC, &codec)) {
197       g_free (info->codec);
198       info->codec = codec;
199       GST_LOG_OBJECT (pad, "codec = %s (audio)", codec);
200       g_object_notify (G_OBJECT (info), "codec");
201     } else if (gst_tag_list_get_string (list, GST_TAG_CODEC, &codec)) {
202       g_free (info->codec);
203       info->codec = codec;
204       GST_LOG_OBJECT (pad, "codec = %s (generic)", codec);
205       g_object_notify (G_OBJECT (info), "codec");
206     }
207     if (gst_tag_list_get_string (list, GST_TAG_LANGUAGE_CODE, &lang)) {
208       g_free (info->langcode);
209       info->langcode = lang;
210       GST_LOG_OBJECT (pad, "language-code = %s", lang);
211       g_object_notify (G_OBJECT (info), "language-code");
212     }
213   }
214
215   return TRUE;
216 }
217
218 GstStreamInfo *
219 gst_stream_info_new (GstObject * object,
220     GstStreamType type, const gchar * decoder, const GstCaps * caps)
221 {
222   GstStreamInfo *info;
223
224   info = g_object_new (GST_TYPE_STREAM_INFO, NULL);
225
226   gst_object_ref (object);
227   if (GST_IS_PAD (object)) {
228     gst_pad_add_event_probe (GST_PAD_CAST (object),
229         G_CALLBACK (cb_probe), info);
230   }
231   info->object = object;
232   info->type = type;
233   info->decoder = g_strdup (decoder);
234   info->origin = object;
235   if (caps) {
236     info->caps = gst_caps_copy (caps);
237   }
238
239   return info;
240 }
241
242 static void
243 gst_stream_info_dispose (GObject * object)
244 {
245   GstStreamInfo *stream_info;
246
247   stream_info = GST_STREAM_INFO (object);
248
249   if (stream_info->object) {
250     GstElement *parent;
251
252     parent = gst_pad_get_parent_element ((GstPad *)
253         GST_PAD_CAST (stream_info->object));
254     if (parent != NULL) {
255       g_signal_handlers_disconnect_by_func (parent,
256           (gpointer) stream_info_change_state, stream_info);
257       gst_object_unref (parent);
258     }
259
260     gst_object_unref (stream_info->object);
261     stream_info->object = NULL;
262   }
263   stream_info->origin = NULL;
264   stream_info->type = GST_STREAM_TYPE_UNKNOWN;
265   g_free (stream_info->decoder);
266   stream_info->decoder = NULL;
267   g_free (stream_info->langcode);
268   stream_info->langcode = NULL;
269   g_free (stream_info->codec);
270   stream_info->codec = NULL;
271   if (stream_info->caps) {
272     gst_caps_unref (stream_info->caps);
273     stream_info->caps = NULL;
274   }
275
276   if (G_OBJECT_CLASS (parent_class)->dispose) {
277     G_OBJECT_CLASS (parent_class)->dispose (object);
278   }
279 }
280
281 static void
282 stream_info_change_state (GstElement * element,
283     gint old_state, gint new_state, gpointer data)
284 {
285   GstStreamInfo *stream_info = data;
286
287   if (new_state == GST_STATE_PLAYING) {
288     /* state change will annoy us */
289     g_return_if_fail (stream_info->mute == TRUE);
290     GST_DEBUG_OBJECT (stream_info, "Re-muting pads after state-change");
291     //gst_pad_set_active_recursive (GST_PAD (stream_info->object), FALSE);
292     g_warning ("FIXME");
293   }
294 }
295
296 gboolean
297 gst_stream_info_set_mute (GstStreamInfo * stream_info, gboolean mute)
298 {
299   g_return_val_if_fail (GST_IS_STREAM_INFO (stream_info), FALSE);
300
301   if (stream_info->type == GST_STREAM_TYPE_ELEMENT) {
302     g_warning ("cannot mute element stream");
303     return FALSE;
304   }
305
306   if (mute != stream_info->mute) {
307     /* nothing really happens here. it looks like gstplaybasebin installs a
308      * buffer probe hat drops buffers when muting. but the this removes it self
309      * after first call.
310      */
311
312     stream_info->mute = mute;
313 #if 0
314     gst_pad_set_active ((GstPad *) GST_PAD_CAST (stream_info->object), !mute);
315 #endif
316 #if 0
317     {
318       GstElement *element;
319
320       element = gst_pad_get_parent_element ((GstPad *)
321           GST_PAD_CAST (stream_info->object));
322       if (element) {
323         if (mute) {
324           g_signal_connect (element, "state-changed",
325               G_CALLBACK (stream_info_change_state), stream_info);
326         } else {
327           g_signal_handlers_disconnect_by_func (element,
328               G_CALLBACK (stream_info_change_state), stream_info);
329         }
330         gst_object_unref (element);
331       }
332     }
333 #endif
334   }
335   return TRUE;
336 }
337
338 gboolean
339 gst_stream_info_is_mute (GstStreamInfo * stream_info)
340 {
341   g_return_val_if_fail (GST_IS_STREAM_INFO (stream_info), TRUE);
342
343   return stream_info->mute;
344 }
345
346 static void
347 gst_stream_info_set_property (GObject * object, guint prop_id,
348     const GValue * value, GParamSpec * pspec)
349 {
350   GstStreamInfo *stream_info;
351
352   g_return_if_fail (GST_IS_STREAM_INFO (object));
353
354   stream_info = GST_STREAM_INFO (object);
355
356   switch (prop_id) {
357     case ARG_MUTE:
358       gst_stream_info_set_mute (stream_info, g_value_get_boolean (value));
359       break;
360     default:
361       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
362       break;
363   }
364 }
365
366 static void
367 gst_stream_info_get_property (GObject * object, guint prop_id, GValue * value,
368     GParamSpec * pspec)
369 {
370   GstStreamInfo *stream_info;
371
372   g_return_if_fail (GST_IS_STREAM_INFO (object));
373
374   stream_info = GST_STREAM_INFO (object);
375
376   switch (prop_id) {
377     case ARG_PAD:
378       g_value_set_object (value, stream_info->object);
379       break;
380     case ARG_TYPE:
381       g_value_set_enum (value, stream_info->type);
382       break;
383     case ARG_DECODER:
384       g_value_set_string (value, stream_info->decoder);
385       break;
386     case ARG_MUTE:
387       g_value_set_boolean (value, stream_info->mute);
388       break;
389     case ARG_CAPS:
390       g_value_set_boxed (value, stream_info->caps);
391       break;
392     case ARG_LANG_CODE:
393       g_value_set_string (value, stream_info->langcode);
394       break;
395     case ARG_CODEC:
396       g_value_set_string (value, stream_info->codec);
397       break;
398     default:
399       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
400       break;
401   }
402 }