renatofilho@787
|
1 |
/* GStreamer
|
renatofilho@797
|
2 |
* Copyright (C) <2007> Renato Araujo Oliveira Filho <renato.filho@indt.org.br>
|
renatofilho@787
|
3 |
*
|
renatofilho@787
|
4 |
* This library is free software; you can redistribute it and/or
|
renatofilho@787
|
5 |
* modify it under the terms of the GNU Library General Public
|
renatofilho@787
|
6 |
* License as published by the Free Software Foundation; either
|
renatofilho@787
|
7 |
* version 2 of the License, or (at your option) any later version.
|
renatofilho@787
|
8 |
*
|
renatofilho@787
|
9 |
* This library is distributed in the hope that it will be useful,
|
renatofilho@787
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
renatofilho@787
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
renatofilho@787
|
12 |
* Library General Public License for more details.
|
renatofilho@787
|
13 |
*
|
renatofilho@787
|
14 |
* You should have received a copy of the GNU Library General Public
|
renatofilho@787
|
15 |
* License along with this library; if not, write to the
|
renatofilho@787
|
16 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
renatofilho@787
|
17 |
* Boston, MA 02111-1307, USA.
|
renatofilho@787
|
18 |
*/
|
renatofilho@787
|
19 |
|
renatofilho@787
|
20 |
#ifdef HAVE_CONFIG_H
|
renatofilho@787
|
21 |
#include "config.h"
|
renatofilho@787
|
22 |
#endif
|
renatofilho@787
|
23 |
|
renatofilho@787
|
24 |
#include <glib/gi18n.h>
|
renatofilho@787
|
25 |
#include <string.h>
|
renatofilho@787
|
26 |
#include <gst/gst.h>
|
renatofilho@787
|
27 |
#include <gst/gsterror.h>
|
renatofilho@787
|
28 |
#include <gst/gstplugin.h>
|
renatofilho@787
|
29 |
#include <gst/interfaces/xoverlay.h>
|
renatofilho@787
|
30 |
#include <X11/Xlib.h>
|
renatofilho@787
|
31 |
//#include <gst/pbutils/pbutils.h>
|
renatofilho@787
|
32 |
#include "gstplaybinmaemo.h"
|
renatofilho@787
|
33 |
|
renatofilho@787
|
34 |
|
renatofilho@787
|
35 |
GST_DEBUG_CATEGORY_STATIC (gst_play_bin_maemo_debug);
|
renatofilho@787
|
36 |
#define GST_CAT_DEFAULT gst_play_bin_maemo_debug
|
renatofilho@787
|
37 |
|
renatofilho@787
|
38 |
#define DEFAULT_VOLUME 10
|
renatofilho@787
|
39 |
#define DEFAULT_XID -1
|
renatofilho@787
|
40 |
|
renatofilho@787
|
41 |
/* props */
|
renatofilho@787
|
42 |
enum
|
renatofilho@787
|
43 |
{
|
renatofilho@787
|
44 |
ARG_0,
|
renatofilho@787
|
45 |
ARG_URI,
|
renatofilho@787
|
46 |
ARG_QUEUE_SIZE,
|
renatofilho@787
|
47 |
ARG_QUEUE_MIN_THRESHOLD,
|
renatofilho@787
|
48 |
ARG_SOURCE,
|
renatofilho@787
|
49 |
ARG_VOLUME,
|
renatofilho@788
|
50 |
ARG_PARSE_METADATA,
|
renatofilho@787
|
51 |
ARG_XID
|
renatofilho@787
|
52 |
};
|
renatofilho@787
|
53 |
|
renatofilho@787
|
54 |
static const GstElementDetails gst_play_bin_maemo_details =
|
leo_sobral@796
|
55 |
GST_ELEMENT_DETAILS("playbinmaemo",
|
renatofilho@787
|
56 |
"Generic/Bin/Player",
|
renatofilho@787
|
57 |
"Autoplug and play media from an uri used on maemo plataform",
|
renatofilho@787
|
58 |
"Renato Araujo Oliveira Filho <renato.filho@indt.org.br>");
|
renatofilho@787
|
59 |
|
renatofilho@787
|
60 |
static void gst_play_bin_maemo_dispose (GObject * object);
|
renatofilho@787
|
61 |
static void gst_play_bin_maemo_finalize (GObject * object);
|
renatofilho@787
|
62 |
static void gst_play_bin_maemo_set_property (GObject * object, guint prop_id,
|
renatofilho@787
|
63 |
const GValue * value, GParamSpec * spec);
|
renatofilho@787
|
64 |
static void gst_play_bin_maemo_get_property (GObject * object, guint prop_id,
|
renatofilho@787
|
65 |
GValue * value, GParamSpec * spec);
|
renatofilho@787
|
66 |
static GstStateChangeReturn
|
renatofilho@787
|
67 |
gst_play_bin_maemo_change_state (GstElement *element,
|
renatofilho@787
|
68 |
GstStateChange transition);
|
renatofilho@787
|
69 |
static gboolean factory_filter_sinks (GstPluginFeature *feature,
|
renatofilho@787
|
70 |
GstPlayBinMaemo *pbm);
|
renatofilho@787
|
71 |
static gint compare_ranks (GstPluginFeature * f1,
|
renatofilho@787
|
72 |
GstPluginFeature * f2);
|
renatofilho@787
|
73 |
static GList *find_compatibles (GstPlayBinMaemo *pbm,
|
renatofilho@787
|
74 |
const GstCaps *caps);
|
renatofilho@787
|
75 |
static GstPad *find_sink_pad (GstElement * element);
|
renatofilho@787
|
76 |
static void update_volume (GstPlayBinMaemo *pbm);
|
renatofilho@787
|
77 |
static void update_xid (GstPlayBinMaemo *pbm);
|
renatofilho@787
|
78 |
static void new_decoded_pad_cb (GstElement *object,
|
renatofilho@787
|
79 |
GstPad* pad,
|
renatofilho@787
|
80 |
gboolean arg,
|
renatofilho@787
|
81 |
gpointer user_data);
|
renatofilho@787
|
82 |
static void unknown_type_cb (GstElement *object,
|
renatofilho@787
|
83 |
GstPad *pad,
|
renatofilho@787
|
84 |
GstCaps *casp,
|
renatofilho@787
|
85 |
gpointer user_data);
|
renatofilho@787
|
86 |
static gboolean autoplug_continue_cb (GstElement* object,
|
renatofilho@787
|
87 |
GstCaps* caps,
|
renatofilho@787
|
88 |
gpointer user_data);
|
renatofilho@792
|
89 |
static gboolean add_element (GstPlayBinMaemo *pbm,
|
renatofilho@792
|
90 |
GstElement *child);
|
renatofilho@792
|
91 |
static void clear_elements (GstPlayBinMaemo *pbm);
|
leo_sobral@808
|
92 |
static int x_error_handler (Display *display,
|
leo_sobral@808
|
93 |
XErrorEvent *event);
|
renatofilho@787
|
94 |
|
renatofilho@787
|
95 |
GST_BOILERPLATE(GstPlayBinMaemo, gst_play_bin_maemo, GstPipeline, GST_TYPE_PIPELINE)
|
renatofilho@787
|
96 |
|
renatofilho@787
|
97 |
|
renatofilho@787
|
98 |
static void
|
renatofilho@787
|
99 |
gst_play_bin_maemo_base_init (gpointer klass)
|
renatofilho@787
|
100 |
{
|
renatofilho@787
|
101 |
GstElementClass *element_class = GST_ELEMENT_CLASS(klass);
|
renatofilho@787
|
102 |
|
renatofilho@787
|
103 |
gst_element_class_set_details (element_class, &gst_play_bin_maemo_details);
|
renatofilho@787
|
104 |
}
|
renatofilho@787
|
105 |
|
renatofilho@787
|
106 |
static void
|
renatofilho@787
|
107 |
gst_play_bin_maemo_class_init (GstPlayBinMaemoClass * klass)
|
renatofilho@787
|
108 |
{
|
renatofilho@787
|
109 |
GObjectClass *gobject_klass;
|
renatofilho@787
|
110 |
GstElementClass *gstelement_klass;
|
renatofilho@787
|
111 |
GstBinClass *gstbin_klass;
|
renatofilho@787
|
112 |
|
renatofilho@787
|
113 |
gobject_klass = (GObjectClass *) klass;
|
renatofilho@787
|
114 |
gstelement_klass = (GstElementClass *) klass;
|
renatofilho@787
|
115 |
gstbin_klass = (GstBinClass *) klass;
|
renatofilho@787
|
116 |
|
renatofilho@787
|
117 |
parent_class = g_type_class_peek_parent (klass);
|
renatofilho@787
|
118 |
|
renatofilho@787
|
119 |
gobject_klass->set_property = gst_play_bin_maemo_set_property;
|
renatofilho@787
|
120 |
gobject_klass->get_property = gst_play_bin_maemo_get_property;
|
renatofilho@787
|
121 |
|
renatofilho@787
|
122 |
g_object_class_install_property (gobject_klass, ARG_URI,
|
renatofilho@787
|
123 |
g_param_spec_string ("uri", "URI", "URI of the media to play",
|
renatofilho@787
|
124 |
NULL, G_PARAM_READWRITE));
|
renatofilho@787
|
125 |
|
renatofilho@787
|
126 |
g_object_class_install_property (gobject_klass, ARG_VOLUME,
|
renatofilho@793
|
127 |
g_param_spec_double ("volume", "Audio volume", "volume",
|
renatofilho@793
|
128 |
0.0, 10.0, (gdouble) DEFAULT_VOLUME, G_PARAM_READWRITE));
|
renatofilho@787
|
129 |
|
renatofilho@787
|
130 |
g_object_class_install_property (gobject_klass, ARG_XID,
|
renatofilho@787
|
131 |
g_param_spec_long ("xid", "xid", "X windown ID",
|
renatofilho@787
|
132 |
-1, G_MAXLONG, DEFAULT_XID, G_PARAM_READWRITE));
|
renatofilho@787
|
133 |
|
renatofilho@787
|
134 |
g_object_class_install_property (gobject_klass, ARG_SOURCE,
|
renatofilho@787
|
135 |
g_param_spec_object ("source", "Source", "Source element",
|
renatofilho@787
|
136 |
GST_TYPE_ELEMENT, G_PARAM_READABLE));
|
renatofilho@787
|
137 |
|
renatofilho@788
|
138 |
g_object_class_install_property (gobject_klass, ARG_PARSE_METADATA,
|
renatofilho@788
|
139 |
g_param_spec_boolean ("parse-metadata", "Parse Metadata", "Parse metadata info",
|
renatofilho@788
|
140 |
TRUE, G_PARAM_READWRITE));
|
renatofilho@788
|
141 |
|
renatofilho@788
|
142 |
|
renatofilho@787
|
143 |
GST_DEBUG_CATEGORY_INIT (gst_play_bin_maemo_debug, "playbinmaemo", 0,
|
renatofilho@787
|
144 |
"playbinmaemo");
|
renatofilho@787
|
145 |
|
renatofilho@787
|
146 |
gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_play_bin_maemo_dispose);
|
renatofilho@787
|
147 |
gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_play_bin_maemo_finalize);
|
renatofilho@787
|
148 |
|
renatofilho@787
|
149 |
gstelement_klass->change_state =
|
renatofilho@787
|
150 |
GST_DEBUG_FUNCPTR (gst_play_bin_maemo_change_state);
|
renatofilho@787
|
151 |
}
|
renatofilho@787
|
152 |
|
renatofilho@787
|
153 |
static void
|
renatofilho@787
|
154 |
gst_play_bin_maemo_init (GstPlayBinMaemo * play_bin_maemo, GstPlayBinMaemoClass *class)
|
renatofilho@787
|
155 |
{
|
renatofilho@787
|
156 |
GList *factories;
|
renatofilho@787
|
157 |
|
renatofilho@787
|
158 |
play_bin_maemo->uri = NULL;
|
renatofilho@787
|
159 |
play_bin_maemo->source = NULL;
|
renatofilho@787
|
160 |
|
renatofilho@787
|
161 |
play_bin_maemo->volume = DEFAULT_VOLUME * 65535 / 10;
|
renatofilho@787
|
162 |
play_bin_maemo->xid = DEFAULT_XID;
|
renatofilho@788
|
163 |
play_bin_maemo->parse_metadata = TRUE;
|
renatofilho@787
|
164 |
|
renatofilho@787
|
165 |
factories = gst_default_registry_feature_filter ((GstPluginFeatureFilter) factory_filter_sinks,
|
renatofilho@787
|
166 |
FALSE, play_bin_maemo);
|
renatofilho@787
|
167 |
|
renatofilho@787
|
168 |
play_bin_maemo->factories = g_list_sort (factories, (GCompareFunc) compare_ranks);
|
renatofilho@787
|
169 |
}
|
renatofilho@787
|
170 |
|
renatofilho@787
|
171 |
static void
|
renatofilho@787
|
172 |
gst_play_bin_maemo_dispose (GObject * object)
|
renatofilho@787
|
173 |
{
|
renatofilho@787
|
174 |
GstPlayBinMaemo *play_bin_maemo;
|
renatofilho@787
|
175 |
|
renatofilho@787
|
176 |
play_bin_maemo = GST_PLAY_BIN_MAEMO (object);
|
renatofilho@787
|
177 |
g_free (play_bin_maemo->uri);
|
renatofilho@787
|
178 |
play_bin_maemo->uri = NULL;
|
renatofilho@787
|
179 |
|
renatofilho@787
|
180 |
G_OBJECT_CLASS (parent_class)->dispose (object);
|
renatofilho@787
|
181 |
}
|
renatofilho@787
|
182 |
|
renatofilho@787
|
183 |
static void
|
renatofilho@787
|
184 |
gst_play_bin_maemo_finalize (GObject * object)
|
renatofilho@787
|
185 |
{
|
renatofilho@792
|
186 |
clear_elements (GST_PLAY_BIN_MAEMO (object));
|
renatofilho@787
|
187 |
G_OBJECT_CLASS (parent_class)->finalize (object);
|
renatofilho@787
|
188 |
}
|
renatofilho@787
|
189 |
|
renatofilho@787
|
190 |
static gboolean
|
renatofilho@787
|
191 |
array_has_value (const gchar * values[], const gchar * value)
|
renatofilho@787
|
192 |
{
|
renatofilho@787
|
193 |
gint i;
|
renatofilho@787
|
194 |
|
renatofilho@787
|
195 |
for (i = 0; values[i]; i++) {
|
renatofilho@787
|
196 |
if (g_str_has_prefix (value, values[i]))
|
renatofilho@787
|
197 |
return TRUE;
|
renatofilho@787
|
198 |
}
|
renatofilho@787
|
199 |
return FALSE;
|
renatofilho@787
|
200 |
}
|
renatofilho@787
|
201 |
|
renatofilho@787
|
202 |
/* list of URIs that we consider to be streams and that need buffering.
|
renatofilho@787
|
203 |
* We have no mechanism yet to figure this out with a query. */
|
renatofilho@787
|
204 |
static const gchar *stream_uris[] = { "http://", "mms://", "mmsh://",
|
renatofilho@787
|
205 |
"mmsu://", "mmst://", NULL
|
renatofilho@787
|
206 |
};
|
renatofilho@787
|
207 |
|
renatofilho@787
|
208 |
/* blacklisted URIs, we know they will always fail. */
|
renatofilho@787
|
209 |
static const gchar *blacklisted_uris[] = { NULL };
|
renatofilho@787
|
210 |
|
renatofilho@787
|
211 |
/* mime types that we don't consider to be media types */
|
renatofilho@793
|
212 |
/*
|
renatofilho@787
|
213 |
static const gchar *no_media_mimes[] = {
|
renatofilho@787
|
214 |
"application/x-executable", "application/x-bzip", "application/x-gzip",
|
renatofilho@787
|
215 |
"application/zip", "application/x-compress", NULL
|
renatofilho@787
|
216 |
};
|
renatofilho@793
|
217 |
*/
|
renatofilho@787
|
218 |
|
renatofilho@787
|
219 |
/* mime types we consider raw media */
|
renatofilho@787
|
220 |
static const gchar *raw_mimes[] = {
|
renatofilho@787
|
221 |
"audio/x-raw", "video/x-raw", NULL
|
renatofilho@787
|
222 |
};
|
renatofilho@787
|
223 |
|
renatofilho@787
|
224 |
#define IS_STREAM_URI(uri) (array_has_value (stream_uris, uri))
|
renatofilho@787
|
225 |
#define IS_BLACKLISTED_URI(uri) (array_has_value (blacklisted_uris, uri))
|
renatofilho@787
|
226 |
#define IS_NO_MEDIA_MIME(mime) (array_has_value (no_media_mimes, mime))
|
renatofilho@787
|
227 |
#define IS_RAW_MIME(mime) (array_has_value (raw_mimes, mime))
|
renatofilho@787
|
228 |
|
renatofilho@787
|
229 |
/*
|
renatofilho@787
|
230 |
* Generate and configure a source element.
|
renatofilho@787
|
231 |
*/
|
renatofilho@787
|
232 |
static GstElement *
|
renatofilho@787
|
233 |
gen_source_element (GstPlayBinMaemo * play_bin_maemo)
|
renatofilho@787
|
234 |
{
|
renatofilho@787
|
235 |
GstElement *source;
|
renatofilho@787
|
236 |
|
renatofilho@787
|
237 |
if (!play_bin_maemo->uri)
|
renatofilho@787
|
238 |
goto no_uri;
|
renatofilho@787
|
239 |
|
renatofilho@787
|
240 |
if (!gst_uri_is_valid (play_bin_maemo->uri))
|
renatofilho@787
|
241 |
goto invalid_uri;
|
renatofilho@787
|
242 |
|
renatofilho@787
|
243 |
if (IS_BLACKLISTED_URI (play_bin_maemo->uri))
|
renatofilho@787
|
244 |
goto uri_blacklisted;
|
renatofilho@787
|
245 |
|
renatofilho@792
|
246 |
source = gst_element_make_from_uri (GST_URI_SRC, play_bin_maemo->uri, "source");
|
renatofilho@787
|
247 |
if (!source)
|
renatofilho@787
|
248 |
goto no_source;
|
renatofilho@787
|
249 |
|
renatofilho@787
|
250 |
play_bin_maemo->is_stream = IS_STREAM_URI (play_bin_maemo->uri);
|
renatofilho@787
|
251 |
|
renatofilho@787
|
252 |
/* make HTTP sources send extra headers so we get icecast
|
renatofilho@787
|
253 |
* metadata in case the stream is an icecast stream */
|
renatofilho@787
|
254 |
if (!strncmp (play_bin_maemo->uri, "http://", 7) &&
|
renatofilho@787
|
255 |
g_object_class_find_property (G_OBJECT_GET_CLASS (source),
|
renatofilho@787
|
256 |
"iradio-mode")) {
|
renatofilho@787
|
257 |
g_object_set (source, "iradio-mode", TRUE, NULL);
|
renatofilho@787
|
258 |
}
|
renatofilho@787
|
259 |
return source;
|
renatofilho@787
|
260 |
|
renatofilho@787
|
261 |
/* ERRORS */
|
renatofilho@787
|
262 |
no_uri:
|
renatofilho@787
|
263 |
{
|
renatofilho@787
|
264 |
GST_ELEMENT_ERROR (play_bin_maemo, RESOURCE, NOT_FOUND,
|
renatofilho@787
|
265 |
(_("No URI specified to play from.")), (NULL));
|
renatofilho@787
|
266 |
return NULL;
|
renatofilho@787
|
267 |
}
|
renatofilho@787
|
268 |
invalid_uri:
|
renatofilho@787
|
269 |
{
|
renatofilho@787
|
270 |
GST_ELEMENT_ERROR (play_bin_maemo, RESOURCE, NOT_FOUND,
|
renatofilho@787
|
271 |
(_("Invalid URI \"%s\"."), play_bin_maemo->uri), (NULL));
|
renatofilho@787
|
272 |
return NULL;
|
renatofilho@787
|
273 |
}
|
renatofilho@787
|
274 |
uri_blacklisted:
|
renatofilho@787
|
275 |
{
|
renatofilho@787
|
276 |
GST_ELEMENT_ERROR (play_bin_maemo, RESOURCE, FAILED,
|
renatofilho@787
|
277 |
(_("RTSP streams cannot be played yet.")), (NULL));
|
renatofilho@787
|
278 |
return NULL;
|
renatofilho@787
|
279 |
}
|
renatofilho@787
|
280 |
no_source:
|
renatofilho@787
|
281 |
{
|
renatofilho@787
|
282 |
gchar *prot = gst_uri_get_protocol (play_bin_maemo->uri);
|
renatofilho@787
|
283 |
|
renatofilho@787
|
284 |
/* whoops, could not create the source element, dig a little deeper to
|
renatofilho@787
|
285 |
* figure out what might be wrong. */
|
renatofilho@787
|
286 |
if (prot) {
|
renatofilho@793
|
287 |
/*
|
renatofilho@787
|
288 |
gchar *desc;
|
renatofilho@787
|
289 |
|
renatofilho@787
|
290 |
gst_element_post_message (GST_ELEMENT (play_bin_maemo),
|
renatofilho@787
|
291 |
gst_missing_uri_source_message_new (GST_ELEMENT (play_bin_maemo),
|
renatofilho@787
|
292 |
prot));
|
renatofilho@787
|
293 |
|
renatofilho@787
|
294 |
desc = gst_pb_utils_get_source_description (prot);
|
renatofilho@787
|
295 |
GST_ELEMENT_ERROR (play_bin_maemo, CORE, MISSING_PLUGIN,
|
renatofilho@787
|
296 |
(_("A %s plugin is required to play this stream, but not installed."),
|
renatofilho@787
|
297 |
desc), ("No URI handler for %s", prot));
|
renatofilho@787
|
298 |
g_free (desc);
|
renatofilho@793
|
299 |
*/
|
renatofilho@787
|
300 |
g_free (prot);
|
renatofilho@787
|
301 |
} else
|
renatofilho@787
|
302 |
goto invalid_uri;
|
renatofilho@787
|
303 |
|
renatofilho@787
|
304 |
return NULL;
|
renatofilho@787
|
305 |
}
|
renatofilho@787
|
306 |
}
|
renatofilho@787
|
307 |
|
renatofilho@787
|
308 |
static void
|
renatofilho@787
|
309 |
prepare_elements (GstPlayBinMaemo *pbm)
|
renatofilho@787
|
310 |
{
|
leo_sobral@805
|
311 |
GstElement *decoder;
|
leo_sobral@805
|
312 |
GstElement *queue;
|
renatofilho@787
|
313 |
|
leo_sobral@805
|
314 |
decoder = gst_element_factory_make ("decodebin2", "decode");
|
leo_sobral@805
|
315 |
add_element (pbm, decoder);
|
leo_sobral@805
|
316 |
g_signal_connect (G_OBJECT (decoder),
|
leo_sobral@805
|
317 |
"autoplug-continue",
|
leo_sobral@805
|
318 |
G_CALLBACK (autoplug_continue_cb),
|
leo_sobral@805
|
319 |
pbm);
|
renatofilho@787
|
320 |
|
leo_sobral@805
|
321 |
g_signal_connect (G_OBJECT (decoder),
|
leo_sobral@805
|
322 |
"unknown-type",
|
leo_sobral@805
|
323 |
G_CALLBACK (unknown_type_cb),
|
leo_sobral@805
|
324 |
pbm);
|
renatofilho@792
|
325 |
|
leo_sobral@805
|
326 |
g_signal_connect (G_OBJECT (decoder),
|
leo_sobral@805
|
327 |
"new-decoded-pad",
|
leo_sobral@805
|
328 |
G_CALLBACK (new_decoded_pad_cb),
|
leo_sobral@805
|
329 |
pbm);
|
renatofilho@792
|
330 |
|
leo_sobral@805
|
331 |
queue = gst_element_factory_make ("queue", NULL);
|
leo_sobral@805
|
332 |
add_element (pbm, queue);
|
renatofilho@792
|
333 |
|
leo_sobral@805
|
334 |
if (gst_element_link_many (pbm->source, queue, decoder, NULL) == FALSE) {
|
leo_sobral@805
|
335 |
g_warning ("FAIL TO LINK SRC WITH DECODEBIN2");
|
leo_sobral@805
|
336 |
}
|
renatofilho@787
|
337 |
}
|
renatofilho@787
|
338 |
|
renatofilho@787
|
339 |
static gboolean
|
renatofilho@787
|
340 |
setup_source (GstPlayBinMaemo *pbm)
|
renatofilho@787
|
341 |
{
|
leo_sobral@805
|
342 |
if (!pbm->need_rebuild)
|
leo_sobral@805
|
343 |
return TRUE;
|
renatofilho@787
|
344 |
|
leo_sobral@805
|
345 |
clear_elements (pbm);
|
renatofilho@792
|
346 |
|
leo_sobral@805
|
347 |
GST_DEBUG_OBJECT (pbm, "setup source");
|
renatofilho@787
|
348 |
|
leo_sobral@805
|
349 |
pbm->has_metadata = FALSE;
|
renatofilho@788
|
350 |
|
leo_sobral@805
|
351 |
/* create and configure an element that can handle the uri */
|
leo_sobral@805
|
352 |
if (!(pbm->source = gen_source_element (pbm)))
|
leo_sobral@805
|
353 |
goto no_source;
|
renatofilho@787
|
354 |
|
leo_sobral@805
|
355 |
add_element (pbm, pbm->source);
|
renatofilho@787
|
356 |
|
renatofilho@787
|
357 |
|
renatofilho@787
|
358 |
#if 0
|
renatofilho@787
|
359 |
if (verify_src_have_sink (pbm)) {
|
renatofilho@787
|
360 |
/* source can be linked with sinks directly */
|
renatofilho@787
|
361 |
return TRUE;
|
renatofilho@787
|
362 |
}
|
renatofilho@787
|
363 |
#endif
|
renatofilho@787
|
364 |
|
leo_sobral@805
|
365 |
prepare_elements (pbm);
|
renatofilho@787
|
366 |
|
leo_sobral@805
|
367 |
return TRUE;
|
renatofilho@787
|
368 |
|
renatofilho@787
|
369 |
no_source:
|
leo_sobral@805
|
370 |
return FALSE;
|
renatofilho@787
|
371 |
}
|
renatofilho@787
|
372 |
|
renatofilho@787
|
373 |
static void
|
renatofilho@787
|
374 |
gst_play_bin_maemo_set_property (GObject *object,
|
renatofilho@787
|
375 |
guint prop_id,
|
renatofilho@787
|
376 |
const GValue *value,
|
renatofilho@787
|
377 |
GParamSpec *pspec)
|
renatofilho@787
|
378 |
{
|
renatofilho@787
|
379 |
GstPlayBinMaemo *play_bin_maemo;
|
renatofilho@787
|
380 |
|
renatofilho@787
|
381 |
g_return_if_fail (GST_IS_PLAY_BIN_MAEMO (object));
|
renatofilho@787
|
382 |
|
renatofilho@787
|
383 |
play_bin_maemo = GST_PLAY_BIN_MAEMO (object);
|
renatofilho@787
|
384 |
|
renatofilho@787
|
385 |
switch (prop_id) {
|
renatofilho@787
|
386 |
case ARG_URI:
|
renatofilho@787
|
387 |
{
|
renatofilho@787
|
388 |
const gchar *uri = g_value_get_string (value);
|
renatofilho@787
|
389 |
|
renatofilho@787
|
390 |
if (uri == NULL) {
|
renatofilho@787
|
391 |
g_warning ("cannot set NULL uri");
|
renatofilho@787
|
392 |
return;
|
renatofilho@787
|
393 |
}
|
renatofilho@787
|
394 |
/* if we have no previous uri, or the new uri is different from the
|
renatofilho@787
|
395 |
* old one, replug */
|
renatofilho@787
|
396 |
if (play_bin_maemo->uri == NULL || strcmp (play_bin_maemo->uri, uri) != 0) {
|
renatofilho@787
|
397 |
g_free (play_bin_maemo->uri);
|
renatofilho@787
|
398 |
play_bin_maemo->uri = g_strdup (uri);
|
renatofilho@787
|
399 |
|
renatofilho@787
|
400 |
GST_DEBUG ("setting new uri to %s", uri);
|
renatofilho@787
|
401 |
|
renatofilho@787
|
402 |
play_bin_maemo->need_rebuild = TRUE;
|
renatofilho@787
|
403 |
}
|
renatofilho@787
|
404 |
break;
|
renatofilho@787
|
405 |
}
|
renatofilho@787
|
406 |
case ARG_VOLUME:
|
renatofilho@787
|
407 |
{
|
renatofilho@793
|
408 |
gdouble d_volume = 0;
|
renatofilho@793
|
409 |
guint u_volume = 0;
|
renatofilho@793
|
410 |
d_volume = g_value_get_double (value);
|
renatofilho@793
|
411 |
|
renatofilho@793
|
412 |
g_debug ("Getting : %5.2f", d_volume);
|
renatofilho@793
|
413 |
if (d_volume != 0) {
|
renatofilho@793
|
414 |
u_volume = (guint) (65535 * d_volume);
|
renatofilho@787
|
415 |
}
|
renatofilho@787
|
416 |
|
renatofilho@793
|
417 |
g_debug ("Converting : %d", u_volume);
|
renatofilho@793
|
418 |
if (play_bin_maemo->volume != u_volume) {
|
renatofilho@793
|
419 |
play_bin_maemo->volume = u_volume;
|
renatofilho@787
|
420 |
update_volume (play_bin_maemo);
|
renatofilho@787
|
421 |
}
|
renatofilho@787
|
422 |
break;
|
renatofilho@787
|
423 |
}
|
renatofilho@787
|
424 |
case ARG_XID:
|
renatofilho@787
|
425 |
{
|
renatofilho@787
|
426 |
long xid;
|
renatofilho@787
|
427 |
xid = g_value_get_long (value);
|
renatofilho@792
|
428 |
if (play_bin_maemo->xid != xid)
|
renatofilho@792
|
429 |
{
|
renatofilho@787
|
430 |
play_bin_maemo->xid = xid;
|
renatofilho@787
|
431 |
update_xid (play_bin_maemo);
|
renatofilho@787
|
432 |
}
|
renatofilho@787
|
433 |
break;
|
renatofilho@787
|
434 |
}
|
renatofilho@788
|
435 |
case ARG_PARSE_METADATA:
|
renatofilho@788
|
436 |
play_bin_maemo->parse_metadata = g_value_get_boolean (value);
|
renatofilho@788
|
437 |
break;
|
renatofilho@787
|
438 |
default:
|
renatofilho@787
|
439 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
renatofilho@787
|
440 |
break;
|
renatofilho@787
|
441 |
}
|
renatofilho@787
|
442 |
}
|
renatofilho@787
|
443 |
|
renatofilho@787
|
444 |
static void
|
renatofilho@787
|
445 |
gst_play_bin_maemo_get_property (GObject * object, guint prop_id, GValue * value,
|
renatofilho@787
|
446 |
GParamSpec * pspec)
|
renatofilho@787
|
447 |
{
|
renatofilho@787
|
448 |
GstPlayBinMaemo *play_bin_maemo;
|
renatofilho@787
|
449 |
|
renatofilho@787
|
450 |
g_return_if_fail (GST_IS_PLAY_BIN_MAEMO (object));
|
renatofilho@787
|
451 |
|
renatofilho@787
|
452 |
play_bin_maemo = GST_PLAY_BIN_MAEMO (object);
|
renatofilho@787
|
453 |
|
renatofilho@787
|
454 |
switch (prop_id) {
|
renatofilho@787
|
455 |
case ARG_URI:
|
renatofilho@787
|
456 |
g_value_set_string (value, play_bin_maemo->uri);
|
renatofilho@787
|
457 |
break;
|
renatofilho@787
|
458 |
case ARG_SOURCE:
|
renatofilho@787
|
459 |
g_value_set_object (value, play_bin_maemo->source);
|
renatofilho@787
|
460 |
break;
|
renatofilho@787
|
461 |
case ARG_VOLUME:
|
leo_sobral@805
|
462 |
{
|
renatofilho@793
|
463 |
gdouble volume = 0;
|
renatofilho@792
|
464 |
if (play_bin_maemo->volume > 0) {
|
renatofilho@793
|
465 |
volume = play_bin_maemo->volume / 65535;
|
renatofilho@792
|
466 |
}
|
renatofilho@793
|
467 |
g_value_set_double (value, volume);
|
renatofilho@787
|
468 |
break;
|
leo_sobral@805
|
469 |
}
|
renatofilho@787
|
470 |
case ARG_XID:
|
renatofilho@787
|
471 |
g_value_set_long (value, play_bin_maemo->xid);
|
renatofilho@787
|
472 |
break;
|
renatofilho@788
|
473 |
case ARG_PARSE_METADATA:
|
renatofilho@788
|
474 |
g_value_set_boolean (value, play_bin_maemo->parse_metadata);
|
renatofilho@788
|
475 |
break;
|
renatofilho@787
|
476 |
default:
|
renatofilho@787
|
477 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
renatofilho@787
|
478 |
break;
|
renatofilho@787
|
479 |
}
|
renatofilho@787
|
480 |
}
|
renatofilho@787
|
481 |
|
renatofilho@787
|
482 |
static GstStateChangeReturn
|
renatofilho@787
|
483 |
gst_play_bin_maemo_change_state (GstElement * element, GstStateChange transition)
|
renatofilho@787
|
484 |
{
|
renatofilho@787
|
485 |
GstStateChangeReturn ret;
|
renatofilho@787
|
486 |
GstPlayBinMaemo *play_bin_maemo;
|
renatofilho@787
|
487 |
|
renatofilho@787
|
488 |
play_bin_maemo = GST_PLAY_BIN_MAEMO (element);
|
renatofilho@787
|
489 |
|
renatofilho@787
|
490 |
switch (transition) {
|
renatofilho@787
|
491 |
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
renatofilho@787
|
492 |
if (!setup_source (play_bin_maemo))
|
renatofilho@787
|
493 |
goto source_failed;
|
renatofilho@787
|
494 |
break;
|
renatofilho@787
|
495 |
default:
|
renatofilho@787
|
496 |
break;
|
renatofilho@787
|
497 |
}
|
renatofilho@787
|
498 |
|
renatofilho@787
|
499 |
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
renatofilho@787
|
500 |
|
renatofilho@787
|
501 |
switch (transition) {
|
renatofilho@787
|
502 |
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
renatofilho@787
|
503 |
if (ret == GST_STATE_CHANGE_FAILURE) {
|
renatofilho@787
|
504 |
play_bin_maemo->need_rebuild = TRUE;
|
renatofilho@787
|
505 |
return GST_STATE_CHANGE_FAILURE;
|
renatofilho@787
|
506 |
}
|
renatofilho@787
|
507 |
break;
|
renatofilho@787
|
508 |
/* clean-up in both cases, READY=>NULL clean-up is if there was an error */
|
renatofilho@787
|
509 |
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
renatofilho@787
|
510 |
case GST_STATE_CHANGE_READY_TO_NULL:
|
renatofilho@787
|
511 |
play_bin_maemo->need_rebuild = TRUE;
|
renatofilho@792
|
512 |
clear_elements (play_bin_maemo);
|
renatofilho@787
|
513 |
break;
|
renatofilho@787
|
514 |
default:
|
renatofilho@787
|
515 |
break;
|
renatofilho@787
|
516 |
}
|
renatofilho@787
|
517 |
return ret;
|
renatofilho@787
|
518 |
|
renatofilho@787
|
519 |
/* ERRORS */
|
renatofilho@787
|
520 |
source_failed:
|
renatofilho@787
|
521 |
{
|
renatofilho@787
|
522 |
play_bin_maemo->need_rebuild = TRUE;
|
renatofilho@787
|
523 |
|
renatofilho@787
|
524 |
return GST_STATE_CHANGE_FAILURE;
|
renatofilho@787
|
525 |
}
|
renatofilho@787
|
526 |
}
|
renatofilho@787
|
527 |
|
renatofilho@787
|
528 |
static gboolean
|
renatofilho@787
|
529 |
factory_filter_sinks (GstPluginFeature *feature,
|
renatofilho@787
|
530 |
GstPlayBinMaemo *pbm)
|
renatofilho@787
|
531 |
{
|
leo_sobral@805
|
532 |
guint rank;
|
leo_sobral@805
|
533 |
const gchar *klass;
|
renatofilho@787
|
534 |
|
leo_sobral@805
|
535 |
if (!GST_IS_ELEMENT_FACTORY (feature))
|
leo_sobral@805
|
536 |
return FALSE;
|
renatofilho@787
|
537 |
|
leo_sobral@805
|
538 |
klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
|
renatofilho@787
|
539 |
|
leo_sobral@805
|
540 |
if ((strstr (klass, "Sink/Video") == NULL) && (strstr (klass, "Sink/Audio") == NULL))
|
leo_sobral@805
|
541 |
return FALSE;
|
renatofilho@787
|
542 |
|
leo_sobral@805
|
543 |
g_debug ("Filtered: %s", gst_element_factory_get_longname ((GST_ELEMENT_FACTORY (feature))));
|
leo_sobral@805
|
544 |
rank = gst_plugin_feature_get_rank (feature);
|
leo_sobral@805
|
545 |
if (rank < GST_RANK_MARGINAL)
|
leo_sobral@805
|
546 |
return FALSE;
|
renatofilho@787
|
547 |
|
leo_sobral@805
|
548 |
return TRUE;
|
renatofilho@787
|
549 |
}
|
renatofilho@787
|
550 |
|
renatofilho@787
|
551 |
static gint
|
renatofilho@787
|
552 |
compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
|
renatofilho@787
|
553 |
{
|
renatofilho@787
|
554 |
gint diff;
|
renatofilho@787
|
555 |
const gchar *rname1, *rname2;
|
renatofilho@787
|
556 |
|
renatofilho@787
|
557 |
diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
|
renatofilho@787
|
558 |
if (diff != 0)
|
renatofilho@787
|
559 |
return diff;
|
renatofilho@787
|
560 |
|
renatofilho@787
|
561 |
rname1 = gst_plugin_feature_get_name (f1);
|
renatofilho@787
|
562 |
rname2 = gst_plugin_feature_get_name (f2);
|
renatofilho@787
|
563 |
|
renatofilho@787
|
564 |
diff = strcmp (rname2, rname1);
|
renatofilho@787
|
565 |
|
renatofilho@787
|
566 |
return diff;
|
renatofilho@787
|
567 |
}
|
renatofilho@787
|
568 |
|
renatofilho@787
|
569 |
|
renatofilho@787
|
570 |
static GList *
|
renatofilho@787
|
571 |
find_compatibles (GstPlayBinMaemo *pbm, const GstCaps *caps)
|
renatofilho@787
|
572 |
{
|
renatofilho@787
|
573 |
GList *factories;
|
renatofilho@787
|
574 |
GList *to_try = NULL;
|
renatofilho@787
|
575 |
|
renatofilho@787
|
576 |
/* loop over all the factories */
|
renatofilho@787
|
577 |
for (factories = pbm->factories; factories; factories = g_list_next (factories)) {
|
renatofilho@787
|
578 |
GstElementFactory *factory = GST_ELEMENT_FACTORY (factories->data);
|
renatofilho@787
|
579 |
const GList *templates;
|
renatofilho@787
|
580 |
GList *walk;
|
renatofilho@787
|
581 |
|
renatofilho@787
|
582 |
/* get the templates from the element factory */
|
renatofilho@787
|
583 |
templates = gst_element_factory_get_static_pad_templates (factory);
|
renatofilho@787
|
584 |
for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
|
renatofilho@787
|
585 |
GstStaticPadTemplate *templ = walk->data;
|
renatofilho@787
|
586 |
|
renatofilho@787
|
587 |
/* we only care about the sink templates */
|
renatofilho@787
|
588 |
if (templ->direction == GST_PAD_SINK) {
|
renatofilho@787
|
589 |
GstCaps *intersect;
|
renatofilho@787
|
590 |
GstCaps *tmpl_caps;
|
renatofilho@787
|
591 |
|
renatofilho@787
|
592 |
/* try to intersect the caps with the caps of the template */
|
renatofilho@787
|
593 |
tmpl_caps = gst_static_caps_get (&templ->static_caps);
|
renatofilho@787
|
594 |
|
renatofilho@787
|
595 |
intersect = gst_caps_intersect (caps, tmpl_caps);
|
renatofilho@787
|
596 |
gst_caps_unref (tmpl_caps);
|
renatofilho@787
|
597 |
|
renatofilho@787
|
598 |
/* check if the intersection is empty */
|
renatofilho@787
|
599 |
if (!gst_caps_is_empty (intersect)) {
|
renatofilho@787
|
600 |
/* non empty intersection, we can use this element */
|
renatofilho@787
|
601 |
to_try = g_list_prepend (to_try, factory);
|
renatofilho@787
|
602 |
gst_caps_unref (intersect);
|
renatofilho@787
|
603 |
break;
|
renatofilho@787
|
604 |
}
|
renatofilho@787
|
605 |
gst_caps_unref (intersect);
|
renatofilho@787
|
606 |
}
|
renatofilho@787
|
607 |
}
|
renatofilho@787
|
608 |
}
|
renatofilho@787
|
609 |
to_try = g_list_reverse (to_try);
|
renatofilho@787
|
610 |
|
renatofilho@787
|
611 |
return to_try;
|
renatofilho@787
|
612 |
}
|
renatofilho@787
|
613 |
|
renatofilho@787
|
614 |
|
renatofilho@787
|
615 |
static gboolean
|
renatofilho@787
|
616 |
autoplug_continue_cb (GstElement* object,
|
renatofilho@787
|
617 |
GstCaps* caps,
|
renatofilho@787
|
618 |
gpointer user_data)
|
renatofilho@787
|
619 |
{
|
renatofilho@787
|
620 |
GList *comp = NULL;
|
renatofilho@787
|
621 |
gboolean ret = TRUE;
|
renatofilho@788
|
622 |
GstPlayBinMaemo *pbm;
|
renatofilho@788
|
623 |
|
renatofilho@788
|
624 |
pbm = GST_PLAY_BIN_MAEMO (user_data);
|
renatofilho@788
|
625 |
|
renatofilho@788
|
626 |
//TODO: fix this for work with all metada elements
|
renatofilho@788
|
627 |
if (pbm->parse_metadata) {
|
renatofilho@788
|
628 |
gchar *caps_str = gst_caps_to_string (caps);
|
renatofilho@788
|
629 |
if ((strstr (caps_str, "id3") != NULL) &&
|
renatofilho@788
|
630 |
(pbm->has_metadata == FALSE)) {
|
renatofilho@788
|
631 |
|
renatofilho@788
|
632 |
g_free (caps_str);
|
renatofilho@788
|
633 |
pbm->has_metadata = TRUE;
|
renatofilho@788
|
634 |
return ret;
|
renatofilho@788
|
635 |
}
|
renatofilho@788
|
636 |
g_free (caps_str);
|
renatofilho@788
|
637 |
}
|
renatofilho@787
|
638 |
|
renatofilho@787
|
639 |
comp = find_compatibles (GST_PLAY_BIN_MAEMO (user_data), caps);
|
renatofilho@787
|
640 |
if (comp != NULL) {
|
renatofilho@787
|
641 |
g_list_free (comp);
|
renatofilho@787
|
642 |
ret = FALSE;
|
renatofilho@787
|
643 |
}
|
renatofilho@787
|
644 |
|
renatofilho@787
|
645 |
return ret;
|
renatofilho@787
|
646 |
}
|
renatofilho@787
|
647 |
|
renatofilho@787
|
648 |
static void
|
renatofilho@787
|
649 |
unknown_type_cb (GstElement *object,
|
renatofilho@787
|
650 |
GstPad *pad,
|
renatofilho@787
|
651 |
GstCaps *caps,
|
renatofilho@787
|
652 |
gpointer user_data)
|
renatofilho@787
|
653 |
{
|
leo_sobral@805
|
654 |
g_debug ("unknown_type_cb: %s", gst_caps_to_string (caps));
|
renatofilho@787
|
655 |
}
|
renatofilho@787
|
656 |
|
renatofilho@787
|
657 |
static GstPad *
|
renatofilho@787
|
658 |
find_sink_pad (GstElement * element)
|
renatofilho@787
|
659 |
{
|
renatofilho@787
|
660 |
GstIterator *it;
|
renatofilho@787
|
661 |
GstPad *pad = NULL;
|
renatofilho@787
|
662 |
gpointer point;
|
renatofilho@787
|
663 |
|
renatofilho@787
|
664 |
it = gst_element_iterate_sink_pads (element);
|
renatofilho@787
|
665 |
|
renatofilho@787
|
666 |
if ((gst_iterator_next (it, &point)) == GST_ITERATOR_OK)
|
renatofilho@787
|
667 |
pad = (GstPad *) point;
|
renatofilho@787
|
668 |
|
renatofilho@787
|
669 |
gst_iterator_free (it);
|
renatofilho@787
|
670 |
|
renatofilho@787
|
671 |
return pad;
|
renatofilho@787
|
672 |
}
|
renatofilho@787
|
673 |
|
renatofilho@788
|
674 |
static GstElement*
|
renatofilho@788
|
675 |
create_element (GstPlayBinMaemo *pbm, GstElementFactory *factory)
|
renatofilho@788
|
676 |
{
|
leo_sobral@805
|
677 |
GstElement *queue;
|
leo_sobral@805
|
678 |
GstElement *bin = NULL;
|
leo_sobral@805
|
679 |
GstElement *element;
|
leo_sobral@805
|
680 |
GstPad *pad;
|
renatofilho@788
|
681 |
|
leo_sobral@805
|
682 |
element = gst_element_factory_create (factory, NULL);
|
leo_sobral@805
|
683 |
if (element == NULL)
|
leo_sobral@805
|
684 |
return NULL;
|
renatofilho@788
|
685 |
|
renatofilho@792
|
686 |
|
leo_sobral@805
|
687 |
bin = gst_bin_new (NULL);
|
renatofilho@792
|
688 |
|
leo_sobral@805
|
689 |
queue = gst_element_factory_make ("queue", NULL);
|
leo_sobral@805
|
690 |
gst_bin_add (GST_BIN (bin), queue);
|
renatofilho@792
|
691 |
|
leo_sobral@805
|
692 |
if (strstr (gst_element_factory_get_klass (factory), "Sink/Video") != NULL) {
|
leo_sobral@805
|
693 |
GstElement *colorspace;
|
renatofilho@792
|
694 |
|
leo_sobral@805
|
695 |
colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
|
renatofilho@792
|
696 |
|
leo_sobral@805
|
697 |
gst_bin_add (GST_BIN (bin), colorspace);
|
leo_sobral@805
|
698 |
if (gst_element_link (queue, colorspace) == FALSE) {
|
leo_sobral@805
|
699 |
GST_WARNING_OBJECT (pbm, "Fail to link queue and colorspace");
|
leo_sobral@805
|
700 |
gst_element_set_state (colorspace, GST_STATE_NULL);
|
leo_sobral@805
|
701 |
gst_object_unref (colorspace);
|
leo_sobral@805
|
702 |
goto error;
|
renatofilho@788
|
703 |
}
|
renatofilho@788
|
704 |
|
leo_sobral@805
|
705 |
gst_bin_add (GST_BIN (bin), element);
|
leo_sobral@805
|
706 |
if (gst_element_link (colorspace, element) == FALSE) {
|
leo_sobral@805
|
707 |
GST_WARNING_OBJECT (pbm, "Fail to link colorspace and sink video: %s", GST_ELEMENT_NAME (element));
|
leo_sobral@805
|
708 |
gst_element_set_state (colorspace, GST_STATE_NULL);
|
leo_sobral@805
|
709 |
gst_object_unref (colorspace);
|
leo_sobral@805
|
710 |
goto error;
|
leo_sobral@805
|
711 |
}
|
renatofilho@792
|
712 |
|
leo_sobral@805
|
713 |
pbm->video_sink = element;
|
leo_sobral@805
|
714 |
update_xid (pbm);
|
leo_sobral@805
|
715 |
|
leo_sobral@805
|
716 |
} else if (strstr (gst_element_factory_get_klass (factory), "Sink/Audio") != NULL) {
|
leo_sobral@805
|
717 |
GParamSpec *vol_spec;
|
leo_sobral@805
|
718 |
GstElement *prev;
|
leo_sobral@805
|
719 |
|
leo_sobral@805
|
720 |
prev = queue;
|
leo_sobral@805
|
721 |
vol_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (element), "volume");
|
leo_sobral@805
|
722 |
if (vol_spec == NULL) {
|
leo_sobral@805
|
723 |
GstElement *volume;
|
leo_sobral@805
|
724 |
|
leo_sobral@805
|
725 |
bin = gst_bin_new (NULL);
|
leo_sobral@805
|
726 |
volume = gst_element_factory_make ("volume", "volume");
|
leo_sobral@805
|
727 |
gst_bin_add (GST_BIN (bin), volume);
|
leo_sobral@805
|
728 |
if (gst_element_link (queue, volume) == FALSE) {
|
leo_sobral@805
|
729 |
GST_WARNING_OBJECT (pbm, "Fail to link queue and volume");
|
leo_sobral@805
|
730 |
gst_element_set_state (volume, GST_STATE_NULL);
|
leo_sobral@805
|
731 |
gst_object_unref (volume);
|
leo_sobral@805
|
732 |
goto error;
|
leo_sobral@805
|
733 |
}
|
leo_sobral@805
|
734 |
|
leo_sobral@805
|
735 |
prev = volume;
|
leo_sobral@805
|
736 |
g_param_spec_unref (vol_spec);
|
leo_sobral@805
|
737 |
}
|
leo_sobral@805
|
738 |
|
leo_sobral@805
|
739 |
gst_bin_add (GST_BIN (bin), element);
|
leo_sobral@805
|
740 |
if (gst_element_link (prev, element) == FALSE) {
|
leo_sobral@805
|
741 |
GST_WARNING_OBJECT (pbm, "Fail to link volume and sink audio: %s", GST_ELEMENT_NAME (element));
|
leo_sobral@805
|
742 |
if (prev != queue) {
|
leo_sobral@805
|
743 |
gst_element_set_state (prev, GST_STATE_NULL);
|
leo_sobral@805
|
744 |
gst_object_unref (prev);
|
leo_sobral@805
|
745 |
}
|
leo_sobral@805
|
746 |
goto error;
|
leo_sobral@805
|
747 |
}
|
leo_sobral@805
|
748 |
|
leo_sobral@805
|
749 |
pbm->volume_element = (prev != queue) ? prev : element;
|
leo_sobral@805
|
750 |
update_volume (pbm);
|
leo_sobral@805
|
751 |
}
|
leo_sobral@805
|
752 |
|
leo_sobral@805
|
753 |
pad = gst_element_get_pad (queue, "sink");
|
leo_sobral@805
|
754 |
gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
|
leo_sobral@805
|
755 |
gst_object_unref (pad);
|
leo_sobral@805
|
756 |
|
leo_sobral@805
|
757 |
return bin;
|
renatofilho@792
|
758 |
error:
|
renatofilho@792
|
759 |
|
leo_sobral@805
|
760 |
gst_element_set_state (bin, GST_STATE_NULL);
|
leo_sobral@805
|
761 |
gst_object_unref (bin);
|
renatofilho@792
|
762 |
|
leo_sobral@805
|
763 |
return NULL;
|
renatofilho@788
|
764 |
}
|
renatofilho@788
|
765 |
|
renatofilho@787
|
766 |
static void
|
renatofilho@787
|
767 |
new_decoded_pad_cb (GstElement *object,
|
renatofilho@787
|
768 |
GstPad* pad,
|
renatofilho@787
|
769 |
gboolean arg,
|
renatofilho@787
|
770 |
gpointer user_data)
|
renatofilho@787
|
771 |
{
|
leo_sobral@805
|
772 |
GList *comp = NULL;
|
leo_sobral@805
|
773 |
GList *walk;
|
leo_sobral@805
|
774 |
GstCaps *caps;
|
leo_sobral@805
|
775 |
gboolean linked;
|
leo_sobral@805
|
776 |
GstPlayBinMaemo *pbm;
|
renatofilho@787
|
777 |
|
leo_sobral@805
|
778 |
pbm = GST_PLAY_BIN_MAEMO (user_data);
|
leo_sobral@805
|
779 |
caps = gst_pad_get_caps (pad);
|
renatofilho@787
|
780 |
|
leo_sobral@805
|
781 |
g_debug ("new_decoded_pad_cb: %s", gst_caps_to_string (caps));
|
renatofilho@787
|
782 |
|
leo_sobral@805
|
783 |
comp = find_compatibles (GST_PLAY_BIN_MAEMO (user_data), caps);
|
renatofilho@787
|
784 |
|
renatofilho@787
|
785 |
|
leo_sobral@805
|
786 |
if (comp == NULL) {
|
leo_sobral@805
|
787 |
g_warning ("flow error: dont find comaptible");
|
leo_sobral@805
|
788 |
return;
|
leo_sobral@805
|
789 |
}
|
leo_sobral@805
|
790 |
|
leo_sobral@805
|
791 |
GST_PAD_STREAM_LOCK (pad);
|
leo_sobral@805
|
792 |
|
leo_sobral@805
|
793 |
linked = FALSE;
|
leo_sobral@805
|
794 |
for (walk=comp; walk != NULL; walk = walk->next) {
|
leo_sobral@805
|
795 |
GstElementFactory *factory = (GstElementFactory *) walk->data;
|
leo_sobral@805
|
796 |
GstElement *element;
|
leo_sobral@805
|
797 |
GstPad *sinkpad = NULL;
|
leo_sobral@805
|
798 |
|
leo_sobral@805
|
799 |
if ((element = create_element (pbm, factory)) == NULL) {
|
leo_sobral@805
|
800 |
GST_WARNING_OBJECT (pbm, "Could not create an element from %s",
|
leo_sobral@805
|
801 |
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
|
leo_sobral@805
|
802 |
g_debug ("Could not create an element from %s",
|
leo_sobral@805
|
803 |
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
|
leo_sobral@805
|
804 |
|
leo_sobral@805
|
805 |
continue;
|
renatofilho@787
|
806 |
}
|
renatofilho@787
|
807 |
|
leo_sobral@805
|
808 |
if (!(add_element (GST_PLAY_BIN_MAEMO (user_data), element))) {
|
leo_sobral@805
|
809 |
GST_WARNING_OBJECT (pbm, "Couldn't set %s to READY", GST_ELEMENT_NAME (element));
|
leo_sobral@805
|
810 |
gst_object_unref (element);
|
leo_sobral@805
|
811 |
continue;
|
renatofilho@787
|
812 |
}
|
renatofilho@787
|
813 |
|
leo_sobral@805
|
814 |
if ((gst_element_set_state (element, GST_STATE_READY))
|
leo_sobral@805
|
815 |
== GST_STATE_CHANGE_FAILURE) {
|
leo_sobral@805
|
816 |
gst_element_set_state (element, GST_STATE_NULL);
|
leo_sobral@805
|
817 |
gst_object_unref (sinkpad);
|
leo_sobral@805
|
818 |
gst_bin_remove (GST_BIN (user_data), element);
|
leo_sobral@805
|
819 |
continue;
|
renatofilho@787
|
820 |
}
|
leo_sobral@805
|
821 |
|
leo_sobral@805
|
822 |
if (!(sinkpad = find_sink_pad (element))) {
|
leo_sobral@805
|
823 |
GST_WARNING_OBJECT (pbm, "Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
|
leo_sobral@805
|
824 |
g_debug ("Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
|
leo_sobral@805
|
825 |
gst_object_unref (element);
|
leo_sobral@805
|
826 |
continue;
|
leo_sobral@805
|
827 |
}
|
leo_sobral@805
|
828 |
|
leo_sobral@805
|
829 |
|
leo_sobral@805
|
830 |
if ((gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
|
leo_sobral@805
|
831 |
GST_WARNING_OBJECT (pbm, "Link failed on pad %s:%s", GST_DEBUG_PAD_NAME (sinkpad));
|
leo_sobral@805
|
832 |
gst_element_set_state (element, GST_STATE_NULL);
|
leo_sobral@805
|
833 |
gst_object_unref (sinkpad);
|
leo_sobral@805
|
834 |
gst_bin_remove (GST_BIN (user_data), element);
|
leo_sobral@805
|
835 |
continue;
|
leo_sobral@805
|
836 |
}
|
leo_sobral@805
|
837 |
|
leo_sobral@805
|
838 |
gst_object_unref (sinkpad);
|
leo_sobral@805
|
839 |
|
leo_sobral@805
|
840 |
if ((gst_element_set_state (element, GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE) {
|
leo_sobral@805
|
841 |
gst_element_set_state (element, GST_STATE_NULL);
|
leo_sobral@805
|
842 |
gst_bin_remove (GST_BIN (user_data), element);
|
leo_sobral@805
|
843 |
continue;
|
leo_sobral@805
|
844 |
}
|
leo_sobral@805
|
845 |
|
leo_sobral@805
|
846 |
linked = TRUE;
|
leo_sobral@805
|
847 |
break;
|
leo_sobral@805
|
848 |
}
|
leo_sobral@805
|
849 |
|
leo_sobral@805
|
850 |
g_list_free (comp);
|
leo_sobral@805
|
851 |
if (linked == FALSE) {
|
leo_sobral@805
|
852 |
g_warning ("GstFlow ERROR");
|
leo_sobral@805
|
853 |
}
|
leo_sobral@805
|
854 |
GST_PAD_STREAM_UNLOCK (pad);
|
renatofilho@787
|
855 |
}
|
renatofilho@787
|
856 |
|
renatofilho@787
|
857 |
static void
|
renatofilho@787
|
858 |
update_volume (GstPlayBinMaemo *pbm)
|
renatofilho@787
|
859 |
{
|
leo_sobral@805
|
860 |
if (pbm->volume_element != NULL) {
|
leo_sobral@805
|
861 |
if (pbm->volume > 0) {
|
leo_sobral@805
|
862 |
g_object_set (G_OBJECT (pbm->volume_element),
|
leo_sobral@805
|
863 |
"volume", pbm->volume,
|
leo_sobral@805
|
864 |
NULL);
|
leo_sobral@805
|
865 |
} else {
|
leo_sobral@805
|
866 |
g_object_set (G_OBJECT (pbm->volume_element),
|
leo_sobral@805
|
867 |
"mute", TRUE,
|
leo_sobral@805
|
868 |
NULL);
|
renatofilho@787
|
869 |
}
|
leo_sobral@805
|
870 |
}
|
renatofilho@787
|
871 |
}
|
renatofilho@787
|
872 |
|
renatofilho@787
|
873 |
static void
|
renatofilho@787
|
874 |
update_xid (GstPlayBinMaemo *pbm)
|
renatofilho@787
|
875 |
{
|
leo_sobral@805
|
876 |
if ((pbm->video_sink != NULL) &&
|
leo_sobral@805
|
877 |
(pbm->xid != -1) &&
|
leo_sobral@805
|
878 |
(GST_IS_X_OVERLAY (pbm->video_sink))) {
|
leo_sobral@805
|
879 |
Display *display;
|
leo_sobral@805
|
880 |
g_object_set (G_OBJECT (pbm->video_sink),
|
leo_sobral@805
|
881 |
"force-aspect-ratio", TRUE, NULL);
|
leo_sobral@805
|
882 |
display = XOpenDisplay(NULL);
|
leo_sobral@805
|
883 |
XMapRaised(display, pbm->xid);
|
leo_sobral@808
|
884 |
XSetErrorHandler(x_error_handler);
|
leo_sobral@805
|
885 |
XSync (display, FALSE);
|
renatofilho@792
|
886 |
|
leo_sobral@805
|
887 |
gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (pbm->video_sink),
|
leo_sobral@805
|
888 |
pbm->xid);
|
leo_sobral@805
|
889 |
}
|
renatofilho@787
|
890 |
}
|
renatofilho@787
|
891 |
|
leo_sobral@808
|
892 |
static int
|
leo_sobral@808
|
893 |
x_error_handler(Display *display, XErrorEvent *event)
|
leo_sobral@808
|
894 |
{
|
leo_sobral@808
|
895 |
g_debug ("In x error handler:");
|
leo_sobral@808
|
896 |
|
leo_sobral@808
|
897 |
switch (event->error_code) {
|
leo_sobral@808
|
898 |
case BadWindow:
|
leo_sobral@808
|
899 |
g_debug ("got bad window");
|
leo_sobral@808
|
900 |
break;
|
leo_sobral@808
|
901 |
case BadDrawable:
|
leo_sobral@808
|
902 |
g_debug ("got bad drawable");
|
leo_sobral@808
|
903 |
break;
|
leo_sobral@808
|
904 |
case BadGC:
|
leo_sobral@808
|
905 |
g_debug ("got bad gc");
|
leo_sobral@808
|
906 |
break;
|
leo_sobral@808
|
907 |
default:
|
leo_sobral@808
|
908 |
g_debug ("unhandled x error = %d", event->error_code);
|
leo_sobral@808
|
909 |
}
|
leo_sobral@808
|
910 |
|
leo_sobral@808
|
911 |
return 0;
|
leo_sobral@808
|
912 |
}
|
leo_sobral@808
|
913 |
|
renatofilho@787
|
914 |
static gboolean
|
renatofilho@792
|
915 |
add_element (GstPlayBinMaemo *pbm,
|
renatofilho@792
|
916 |
GstElement *child)
|
renatofilho@792
|
917 |
{
|
leo_sobral@805
|
918 |
if (gst_bin_add (GST_BIN (pbm), child)) {
|
leo_sobral@805
|
919 |
pbm->elements = g_list_append (pbm->elements, child);
|
leo_sobral@805
|
920 |
return TRUE;
|
leo_sobral@805
|
921 |
}
|
leo_sobral@805
|
922 |
return FALSE;
|
renatofilho@792
|
923 |
}
|
renatofilho@792
|
924 |
|
renatofilho@792
|
925 |
static void
|
renatofilho@792
|
926 |
clear_elements (GstPlayBinMaemo *pbm)
|
renatofilho@792
|
927 |
{
|
leo_sobral@805
|
928 |
GList *walk;
|
renatofilho@792
|
929 |
|
leo_sobral@805
|
930 |
walk = pbm->elements;
|
renatofilho@792
|
931 |
|
leo_sobral@805
|
932 |
for (; walk != NULL; walk = walk->next) {
|
leo_sobral@805
|
933 |
GstElement *e = GST_ELEMENT (walk->data);
|
renatofilho@792
|
934 |
|
leo_sobral@805
|
935 |
gst_element_set_state (e, GST_STATE_NULL);
|
leo_sobral@805
|
936 |
gst_bin_remove (GST_BIN (pbm), e);
|
leo_sobral@805
|
937 |
}
|
renatofilho@792
|
938 |
|
leo_sobral@805
|
939 |
g_list_free (pbm->elements);
|
leo_sobral@805
|
940 |
pbm->elements = NULL;
|
leo_sobral@805
|
941 |
pbm->source = NULL;
|
leo_sobral@805
|
942 |
pbm->volume_element = NULL;
|
leo_sobral@805
|
943 |
pbm->video_sink = NULL;
|
renatofilho@792
|
944 |
}
|
renatofilho@792
|
945 |
|
renatofilho@792
|
946 |
static gboolean
|
renatofilho@787
|
947 |
plugin_init(GstPlugin * plugin)
|
renatofilho@787
|
948 |
{
|
renatofilho@787
|
949 |
#ifdef ENABLE_NLS
|
leo_sobral@805
|
950 |
setlocale(LC_ALL, "");
|
leo_sobral@805
|
951 |
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
renatofilho@787
|
952 |
#endif /* ENABLE_NLS */
|
renatofilho@787
|
953 |
|
leo_sobral@805
|
954 |
if (!gst_element_register(plugin, "playbinmaemo", GST_RANK_SECONDARY,
|
leo_sobral@805
|
955 |
GST_TYPE_PLAY_BIN_MAEMO)) {
|
leo_sobral@805
|
956 |
return FALSE;
|
leo_sobral@805
|
957 |
}
|
renatofilho@787
|
958 |
|
leo_sobral@805
|
959 |
return TRUE;
|
renatofilho@787
|
960 |
}
|
renatofilho@787
|
961 |
|
renatofilho@787
|
962 |
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
|
renatofilho@787
|
963 |
GST_VERSION_MINOR,
|
renatofilho@787
|
964 |
"playbinmaemo",
|
leo_sobral@796
|
965 |
"A playbin element that uses decodebin2 for automatic playback of audio and video",
|
renatofilho@787
|
966 |
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME,
|
renatofilho@787
|
967 |
GST_PACKAGE_ORIGIN)
|