2 * This file is a part of MAFW
4 * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
6 * Contact: Visa Smolander <visa.smolander@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
36 #include "mafw-gst-renderer-utils.h"
39 #define G_LOG_DOMAIN "mafw-gst-renderer-utils"
44 * @dst: location for utf8 version of @src.
46 * Tries to convert @src into UTF-8, placing it into @dst.
48 * Returns: TRUE on success.
50 gboolean convert_utf8(const gchar *src, gchar **dst)
56 if (g_utf8_validate(src, -1, NULL)) {
61 *dst = g_locale_to_utf8(src, -1, NULL, NULL, &error);
63 g_warning("utf8 conversion failed '%s' (%d: %s)",
64 src, error->code, error->message);
73 * @uri: the URI to be checked.
75 * Check if given URI is a stream (not a local resource). To not depend on
76 * gnomevfs for this, we assume everything that doesn't start with "file://" is
79 * Returns: TRUE if the URI is not local.
81 gboolean uri_is_stream(const gchar *uri)
86 return !g_str_has_prefix(uri, "file://");
90 /** remap_gst_error_code:
92 * @error: pointer to error
94 * Maps a Gst error to worker errror code,
95 * mapping follows roughly the one from FMAFW gst-renderer.
97 * Returns: possibly remapped ecode if the domain was certain Gst domain.
99 gint remap_gst_error_code(const GError *error)
104 if (error->domain == GST_RESOURCE_ERROR)
106 /* handle RESOURCE errors */
109 case GST_RESOURCE_ERROR_READ:
110 new_err_code = WORKER_ERROR_STREAM_DISCONNECTED;
112 case GST_RESOURCE_ERROR_NOT_FOUND:
113 case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
114 case GST_RESOURCE_ERROR_OPEN_READ:
115 new_err_code = WORKER_ERROR_MEDIA_NOT_FOUND;
117 case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
118 new_err_code = WORKER_ERROR_UNABLE_TO_PERFORM;
120 case GST_RESOURCE_ERROR_WRITE:
121 /* DSP renderers send ERROR_WRITE when they find
123 new_err_code = WORKER_ERROR_CORRUPTED_FILE;
125 case GST_RESOURCE_ERROR_SEEK:
126 new_err_code = WORKER_ERROR_CANNOT_SET_POSITION;
129 /* Unknown RESOURCE error */
130 new_err_code = WORKER_ERROR_UNABLE_TO_PERFORM;
134 else if (error->domain == GST_STREAM_ERROR)
136 /* handle STREAM errors */
137 switch (error->code) {
138 case GST_STREAM_ERROR_TYPE_NOT_FOUND:
139 new_err_code = WORKER_ERROR_TYPE_NOT_AVAILABLE;
141 case GST_STREAM_ERROR_FORMAT:
142 case GST_STREAM_ERROR_WRONG_TYPE:
143 case GST_STREAM_ERROR_FAILED:
144 new_err_code = WORKER_ERROR_UNSUPPORTED_TYPE;
146 case GST_STREAM_ERROR_DECODE:
147 case GST_STREAM_ERROR_DEMUX:
148 new_err_code = WORKER_ERROR_CORRUPTED_FILE;
150 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
151 new_err_code = WORKER_ERROR_CODEC_NOT_FOUND;
153 case GST_STREAM_ERROR_DECRYPT:
154 case GST_STREAM_ERROR_DECRYPT_NOKEY:
155 new_err_code = WORKER_ERROR_DRM_NOT_ALLOWED;
157 case WORKER_ERROR_POSSIBLY_PLAYLIST_TYPE:
158 new_err_code = WORKER_ERROR_POSSIBLY_PLAYLIST_TYPE;
161 /* Unknown STREAM error */
162 new_err_code = WORKER_ERROR_UNABLE_TO_PERFORM;
166 else if( error->domain == GST_CORE_ERROR )
168 switch( error->code ) {
169 case GST_CORE_ERROR_MISSING_PLUGIN:
170 new_err_code = WORKER_ERROR_UNSUPPORTED_TYPE;
173 new_err_code = error->code;
178 /* by default return the original code */
179 new_err_code = error->code;
187 * Imported from totem-uri.c
188 * Copyright (C) 2004 Bastien Nocera
191 /* List from xine-lib's demux_sputext.c */
192 static const char subtitle_ext[][4] = {
201 static inline gboolean
202 uri_exists (const char *uri)
204 GFile *file = g_file_new_for_uri (uri);
206 if (g_file_query_exists (file, NULL)) {
207 g_object_unref (file);
210 g_object_unref (file);
216 uri_get_subtitle_for_uri (const char *uri)
222 /* Find the filename suffix delimiter */
224 for (suffix = len - 1; suffix > 0; suffix--) {
225 if (uri[suffix] == G_DIR_SEPARATOR ||
226 (uri[suffix] == '/')) {
227 /* This filename has no extension; we'll need to
232 if (uri[suffix] == '.') {
233 /* Found our extension marker */
240 /* Generate a subtitle string with room at the end to store the
241 * 3 character extensions for which we want to search */
242 subtitle = g_malloc0 (suffix + 4 + 1);
243 g_return_val_if_fail (subtitle != NULL, NULL);
244 g_strlcpy (subtitle, uri, suffix + 4 + 1);
245 g_strlcpy (subtitle + suffix, ".???", 5);
247 /* Search for any files with one of our known subtitle extensions */
248 for (i = 0; i < G_N_ELEMENTS (subtitle_ext) ; i++) {
249 char *subtitle_ext_upper;
250 memcpy (subtitle + suffix + 1, subtitle_ext[i], 3);
252 if (uri_exists (subtitle))
255 /* Check with upper-cased extension */
256 subtitle_ext_upper = g_ascii_strup (subtitle_ext[i], -1);
257 memcpy (subtitle + suffix + 1, subtitle_ext_upper, 3);
258 g_free (subtitle_ext_upper);
260 if (uri_exists (subtitle))
268 uri_get_subtitle_in_subdir (GFile *file, const char *subdir)
270 char *filename, *subtitle, *full_path_str;
271 GFile *parent, *full_path, *directory;
273 /* Get the sibling directory @subdir of the file @file */
274 parent = g_file_get_parent (file);
275 directory = g_file_get_child (parent, subdir);
276 g_object_unref (parent);
278 /* Get the file of the same name as @file in the @subdir directory */
279 filename = g_file_get_basename (file);
280 full_path = g_file_get_child (directory, filename);
281 g_object_unref (directory);
284 /* Get the subtitles from that URI */
285 full_path_str = g_file_get_uri (full_path);
286 g_object_unref (full_path);
287 subtitle = uri_get_subtitle_for_uri (full_path_str);
288 g_free (full_path_str);
294 uri_get_subtitle_uri (const char *uri)
299 if (g_str_has_prefix (uri, "http") != FALSE)
302 /* Has the user specified a subtitle file manually? */
303 if (strstr (uri, "#subtitle:") != NULL)
306 /* Does the file exist? */
307 file = g_file_new_for_uri (uri);
308 if (g_file_query_exists (file, NULL) != TRUE) {
309 g_object_unref (file);
313 /* Try in the current directory */
314 subtitle = uri_get_subtitle_for_uri (uri);
315 if (subtitle != NULL) {
316 g_object_unref (file);
320 subtitle = uri_get_subtitle_in_subdir (file, "subtitles");
321 g_object_unref (file);