diff -r 000000000000 -r cb1c3e2988b9 gmyth-stream/libgnomevfs2/modules/gmythstream-method.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/libgnomevfs2/modules/gmythstream-method.c Thu Apr 12 20:35:08 2007 +0100 @@ -0,0 +1,354 @@ +/* + * @author Artur Duque de Souza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + m * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include /* for socket(), connect(), send(), and recv() */ +#include /* for sockaddr_in and inet_addr() */ +#include /* for atoi() and exit() */ +#include /* for memset() */ +#include /* for close() */ +#include + +#include +#include +#include +#include + +#include +#include + +#define BUFFER_SIZE 4096 + +typedef struct { + gint port; + gchar* hostname; + + GMythStreamClient *stream; + gint fd; +} gmsHandle; + +typedef struct { + gchar *file_name; + gchar *mux; + gchar *vcodec; + guint vbitrate; + gdouble fps; + gchar *acodec; + guint abitrate; + guint width; + guint height; + guint port; + gchar *opt; +} UriArgs; + + +static gmsHandle* gmsHandle_new(GnomeVFSURI *uri); + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context); + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context); + +static GnomeVFSResult +do_close (GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSContext * context); + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod * method, + GnomeVFSURI * uri, + GnomeVFSFileInfo * file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext * context); + + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context); + + +static gboolean +do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri); + + +static gmsHandle* gmsHandle_new(GnomeVFSURI *uri) +{ + gmsHandle* handler = (gmsHandle*)g_malloc0(sizeof(gmsHandle)); + + handler->hostname = (gchar*)gnome_vfs_uri_get_host_name(uri); + handler->port = gnome_vfs_uri_get_host_port(uri); + handler->stream = gmyth_stream_client_new (); + + return handler; +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, /* open */ + NULL, /* create */ + do_close, /* close */ + do_read, /* read */ + NULL, /* write */ + NULL, /* seek */ + NULL, /* tell */ + NULL, /* truncate_handle */ + NULL, /* open_directory */ + NULL, /* close_directory */ + NULL, /* read_directory */ + do_get_file_info, /* get_file_info */ + do_get_file_info_from_handle, /* get_file_info_from_handle */ + do_is_local, /* is_local */ + NULL, /* make_directory */ + NULL, /* remove_directory */ + NULL, /* move */ + NULL, /* unlink */ + NULL, /* check_same_fs */ + NULL, /* set_file_info */ + NULL, /* truncate */ + NULL, /* find_directory */ + NULL, /* create_symbolic_link */ + NULL, /* monitor_add */ + NULL, /* monitor_cancel */ + NULL /* file_control */ +}; + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod* method) +{ + return; +} + +char* _parse_opt(char* opt) +{ + char** list = g_strsplit(opt, "opt=", 2); + char** opts = g_strsplit(list[1], "+", 32); + char* value = ""; + char* aux; + gint i = 0; + + for (aux = opts[0]; aux != NULL; aux = opts[++i]) + value = g_strdup_printf("%s %s", value, aux); + + g_free(aux); + g_strfreev(list); + g_strfreev(opts); + return value; +} + +static UriArgs * +_uri_parse_args (const GnomeVFSURI *uri) +{ + gchar *file = gnome_vfs_unescape_string (uri->text, NULL); + gchar **lst = g_strsplit (file, "?", 0); + UriArgs *info = g_new0 (UriArgs, 1); + gint i = 1; + + gchar** prop = NULL; + prop = g_strsplit_set(lst[0], "/=", 3); + + info->file_name = g_strdup_printf ("%s://%s",\ + prop[1],prop[2]); + g_strfreev(prop); + + gchar* walk; + for (walk = lst[1]; walk != NULL; walk = lst[++i]) + { + prop = g_strsplit(walk, "=", 2); + + if (g_strv_length (prop) == 2) { + if (strcmp (prop[0], "mux") == 0) { + info->mux = g_strdup (prop[1]); + } else if (strcmp (prop[0], "vcodec") == 0) { + info->vcodec = g_strdup (prop[1]); + } else if (strcmp (prop[0], "vbitrate") == 0) { + info->vbitrate = atoi (prop[1]); + } else if (strcmp (prop[0], "fps") == 0) { + info->fps = g_strtod (prop[1], NULL); + } else if (strcmp (prop[0], "acodec") == 0) { + info->acodec = g_strdup (prop[1]); + } else if (strcmp (prop[0], "abitrate") == 0) { + info->abitrate = atoi (prop[1]); + } else if (strcmp (prop[0], "width") == 0) { + info->width = atoi (prop[1]); + } else if (strcmp (prop[0], "height") == 0) { + info->height = atoi (prop[1]); + } else if (strcmp (prop[0], "opt") == 0) { + g_debug("DENTRO DE OPT: %s", walk); + char* v = _parse_opt(walk); + info->opt = g_strdup (v); + } + } + g_strfreev (prop); + } + + g_free (file); + g_strfreev (lst); + return info; +} + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + gmsHandle *handle = gmsHandle_new(uri); + UriArgs *args; + + if (!gmyth_stream_client_connect (handle->stream, + gnome_vfs_uri_get_host_name (uri), + gnome_vfs_uri_get_host_port (uri))) { + + return GNOME_VFS_ERROR_INVALID_FILENAME; + } + + args = _uri_parse_args (uri); + + gint ret = gmyth_stream_client_open_stream (handle->stream, + args->file_name, + args->mux, + args->vcodec, + args->vbitrate, + args->fps, + args->acodec, + args->abitrate, + args->width, + args->height, + args->opt); + + g_free (args); + + if (ret == -1) { + gmyth_stream_client_disconnect (handle->stream); + return GNOME_VFS_ERROR_INVALID_FILENAME; + } + + handle->fd = gmyth_stream_client_play_stream (handle->stream); + + if (handle->fd == -1) { + gmyth_stream_client_disconnect (handle->stream); + return GNOME_VFS_ERROR_INVALID_FILENAME; + } + + *method_handle = (GnomeVFSMethodHandle *) handle; + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + + gint64 total_read = 0; + gmsHandle *handle = (gmsHandle *) method_handle; + + total_read = recv(handle->fd, buffer, BUFFER_SIZE, 0); + *bytes_read = (GnomeVFSFileSize) total_read; + + if (total_read < 0) return GNOME_VFS_ERROR_INTERNAL; + else return GNOME_VFS_OK; + +} + +static GnomeVFSResult +do_close (GnomeVFSMethod * method, + GnomeVFSMethodHandle * method_handle, + GnomeVFSContext * context) +{ + gmsHandle *handle = (gmsHandle *) method_handle; + + gmyth_stream_client_close_stream (handle->stream); + gmyth_stream_client_disconnect (handle->stream); + + g_free(handle); + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod * method, + GnomeVFSURI * uri, + GnomeVFSFileInfo * file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext * context) +{ + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; + + file_info->type = GNOME_VFS_FILE_TYPE_SOCKET; + + file_info->permissions = GNOME_VFS_PERM_USER_READ | + GNOME_VFS_PERM_OTHER_READ | + GNOME_VFS_PERM_GROUP_READ; + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult +do_get_file_info_from_handle (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE | + GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; + + file_info->type = GNOME_VFS_FILE_TYPE_SOCKET; + + file_info->permissions = GNOME_VFS_PERM_USER_READ | + GNOME_VFS_PERM_OTHER_READ | + GNOME_VFS_PERM_GROUP_READ; + + return GNOME_VFS_OK; +} + + +static gboolean +do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri) +{ + return FALSE; +}