gmyth-stream/libgnomevfs2/modules/gmythstream-method.c
author morphbr
Thu Apr 12 23:17:33 2007 +0100 (2007-04-12)
branchtrunk
changeset 542 0c3e3011a942
parent 540 d6f9b0417346
child 544 bf01a0d21980
permissions -rw-r--r--
[svn r547] Debug messages for GMyth-Streamer
     1 /*
     2  * @author Artur Duque de Souza <souza.artur@indt.org.br>
     3  *
     4  * This program is free software; you can redistribute it and/or modify
     5  * it under the terms of the GNU Lesser General Public License as published by
     6  * the Free Software Foundation; either version 2 of the License, or
     7  * (at your option) any later version.
     8  *
     9  * This program 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
    12  * GNU General Public License for more details.
    13  *
    14  m * You should have received a copy of the GNU Lesser General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  */
    18 
    19 #ifdef HAVE_CONFIG_H
    20 #include <config.h>
    21 #endif
    22 
    23 #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
    24 #include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
    25 #include <stdlib.h>     /* for atoi() and exit() */
    26 #include <string.h>     /* for memset() */
    27 #include <unistd.h>     /* for close() */
    28 #include <errno.h>
    29 
    30 #include <glib.h>
    31 #include <glib/gprintf.h>
    32 #include <glib/gstdio.h>
    33 #include <gmyth-stream-client.h>
    34 
    35 #include <libgnomevfs/gnome-vfs-module.h>
    36 #include <libgnomevfs/gnome-vfs-utils.h>
    37 
    38 #define BUFFER_SIZE 4096
    39 
    40 typedef struct {
    41     gint port;
    42     gchar* hostname;
    43 
    44     GMythStreamClient *stream;
    45     gint fd;
    46 } gmsHandle;
    47 
    48 typedef struct {
    49     gchar *file_name;
    50     gchar *mux;
    51     gchar *vcodec;
    52     guint vbitrate;
    53     gdouble fps;
    54     gchar *acodec;
    55     guint abitrate;
    56     guint width;
    57     guint height;
    58     guint port;
    59     gchar *opt;
    60 } UriArgs;
    61 
    62 
    63 static gmsHandle* gmsHandle_new(GnomeVFSURI *uri);
    64 
    65 static GnomeVFSResult
    66 do_open (GnomeVFSMethod        *method,
    67 	 GnomeVFSMethodHandle **method_handle,
    68 	 GnomeVFSURI           *uri,
    69 	 GnomeVFSOpenMode       mode,
    70 	 GnomeVFSContext       *context);
    71 
    72 static GnomeVFSResult
    73 do_read (GnomeVFSMethod       *method,
    74 	 GnomeVFSMethodHandle *method_handle,
    75 	 gpointer              buffer,
    76 	 GnomeVFSFileSize      bytes,
    77 	 GnomeVFSFileSize     *bytes_read,
    78 	 GnomeVFSContext      *context);
    79 
    80 static GnomeVFSResult
    81 do_close (GnomeVFSMethod * method,
    82           GnomeVFSMethodHandle * method_handle,
    83           GnomeVFSContext * context);
    84 
    85 static GnomeVFSResult
    86 do_get_file_info (GnomeVFSMethod * method,
    87 		  GnomeVFSURI * uri,
    88 		  GnomeVFSFileInfo * file_info,
    89 		  GnomeVFSFileInfoOptions options,
    90 		  GnomeVFSContext * context);
    91 
    92 
    93 static GnomeVFSResult
    94 do_get_file_info_from_handle (GnomeVFSMethod 		*method,
    95                               GnomeVFSMethodHandle 	*method_handle,
    96                               GnomeVFSFileInfo 		*file_info,
    97                               GnomeVFSFileInfoOptions    options,
    98                               GnomeVFSContext 		*context);
    99 
   100 
   101 static gboolean
   102 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri);
   103 
   104 
   105 static gmsHandle* gmsHandle_new(GnomeVFSURI *uri)
   106 {
   107     gmsHandle* handler = (gmsHandle*)g_malloc0(sizeof(gmsHandle));
   108 
   109     handler->hostname = (gchar*)gnome_vfs_uri_get_host_name(uri);
   110     handler->port = gnome_vfs_uri_get_host_port(uri);
   111     handler->stream = gmyth_stream_client_new ();
   112 
   113     return handler;
   114 }
   115 
   116 static GnomeVFSMethod method = {
   117     sizeof (GnomeVFSMethod),
   118     do_open,                       /* open */
   119     NULL,                          /* create */
   120     do_close,                      /* close */
   121     do_read,                       /* read */
   122     NULL,                          /* write */
   123     NULL,                          /* seek */
   124     NULL,                          /* tell */
   125     NULL,                          /* truncate_handle */
   126     NULL,                          /* open_directory */
   127     NULL,                          /* close_directory */
   128     NULL,                          /* read_directory */
   129     do_get_file_info,              /* get_file_info */
   130     do_get_file_info_from_handle,  /* get_file_info_from_handle */
   131     do_is_local,                   /* is_local */
   132     NULL,                          /* make_directory */
   133     NULL,                          /* remove_directory */
   134     NULL,                          /* move */
   135     NULL,                          /* unlink */
   136     NULL,                          /* check_same_fs */
   137     NULL,                          /* set_file_info */
   138     NULL,                          /* truncate */
   139     NULL,                          /* find_directory */
   140     NULL,                          /* create_symbolic_link */
   141     NULL,                          /* monitor_add */
   142     NULL,                          /* monitor_cancel */
   143     NULL                           /* file_control */
   144 };
   145 
   146 GnomeVFSMethod *
   147 vfs_module_init (const char *method_name, const char *args)
   148 {
   149     return &method;
   150 }
   151 
   152 void
   153 vfs_module_shutdown (GnomeVFSMethod* method)
   154 {
   155     return;
   156 }
   157 
   158 static UriArgs *
   159 _uri_parse_args (const GnomeVFSURI *uri)
   160 {
   161 
   162     gchar *file;
   163     UriArgs *info = g_new0 (UriArgs, 1);
   164 	GSList *args = NULL;
   165 	gchar *c;
   166 	GString *entry;
   167 	gboolean open = FALSE;
   168 	gchar **prop;
   169     GSList* walk;
   170 	gchar *uri_str = gnome_vfs_uri_to_string (uri,
   171 			GNOME_VFS_URI_HIDE_USER_NAME |
   172 			GNOME_VFS_URI_HIDE_PASSWORD |
   173 			GNOME_VFS_URI_HIDE_HOST_NAME |
   174 			GNOME_VFS_URI_HIDE_HOST_PORT |
   175 			GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD);
   176 
   177 	file = gnome_vfs_unescape_string (uri_str, "");
   178 	c = file;
   179 	entry = g_string_new ("");
   180 	c = c + 1;
   181 	do {
   182 		if ((*c == '\"') || (*c == '\'')) {
   183 			open = !open;
   184 		}
   185 
   186 		if (((*c == '?') || (c[1] == '\0')) && !open) {
   187 			if (*c != '?')
   188 				g_string_append_c (entry, *c);
   189 			args = g_slist_append (args, g_strdup (entry->str));
   190 			entry = g_string_assign (entry, "");
   191 		} else {
   192 			if (*c == '+')
   193 				g_string_append_c (entry, "//");
   194 			else
   195 				g_string_append_c (entry, *c);
   196 		}
   197 		c = c + 1;
   198 	} while (*c != '\0');
   199 
   200 	g_string_free (entry, TRUE);
   201 
   202     for (walk = args; walk != NULL; walk = walk->next)
   203     {
   204 		gchar *arg = (gchar *) walk->data;
   205         prop = g_strsplit(arg, "=", 2);
   206 		g_debug ("arg = %s", arg);
   207 
   208         if (g_strv_length (prop) == 2) {
   209 			if (strcmp (prop[0], "file") == 0) {
   210 				info->file_name = g_strdup (prop[1]);
   211 			} else if (strcmp (prop[0], "mux") == 0) {
   212                 info->mux = g_strdup (prop[1]);
   213             } else if (strcmp (prop[0], "vcodec") == 0) {
   214                 info->vcodec = g_strdup (prop[1]);
   215             } else if (strcmp (prop[0], "vbitrate") == 0) {
   216                 info->vbitrate = atoi (prop[1]);
   217             } else if (strcmp (prop[0], "fps") == 0) {
   218                 info->fps = g_strtod (prop[1], NULL);
   219             } else if (strcmp (prop[0], "acodec") == 0) {
   220                 info->acodec = g_strdup (prop[1]);
   221             } else if (strcmp (prop[0], "abitrate") == 0) {
   222                 info->abitrate = atoi (prop[1]);
   223             } else if (strcmp (prop[0], "width") == 0) {
   224                 info->width = atoi (prop[1]);
   225             } else if (strcmp (prop[0], "height") == 0) {
   226                 info->height = atoi (prop[1]);
   227             } else if (strcmp (prop[0], "opt") == 0) {
   228                 g_debug("DENTRO DE OPT: %s", arg);
   229                 //char* v = _parse_opt(walk);
   230                 info->opt = g_strdup (arg);
   231             }
   232         }
   233         g_strfreev (prop);
   234 		g_free (arg);
   235     }
   236     g_free (file);
   237 	g_slist_free (args);
   238     return info;
   239 }
   240 
   241 static GnomeVFSResult
   242 do_open (GnomeVFSMethod        *method,
   243 	 GnomeVFSMethodHandle **method_handle,
   244 	 GnomeVFSURI           *uri,
   245 	 GnomeVFSOpenMode       mode,
   246 	 GnomeVFSContext       *context)
   247 {
   248     gmsHandle *handle = gmsHandle_new(uri);
   249     UriArgs *args;
   250 
   251     args = _uri_parse_args (uri);
   252 
   253     if (!gmyth_stream_client_connect (handle->stream,
   254                                       gnome_vfs_uri_get_host_name  (uri),
   255                                       gnome_vfs_uri_get_host_port  (uri))) {
   256 
   257         return GNOME_VFS_ERROR_INVALID_FILENAME;
   258     }
   259 
   260     args = _uri_parse_args (uri);
   261 
   262     gint ret = gmyth_stream_client_open_stream (handle->stream,
   263                                                 args->file_name,
   264                                                 args->mux,
   265                                                 args->vcodec,
   266                                                 args->vbitrate,
   267                                                 args->fps,
   268                                                 args->acodec,
   269                                                 args->abitrate,
   270                                                 args->width,
   271                                                 args->height,
   272                                                 args->opt);
   273 
   274     g_free (args);
   275 
   276     if (ret == -1) {
   277         gmyth_stream_client_disconnect (handle->stream);
   278         return GNOME_VFS_ERROR_INVALID_FILENAME;
   279     }
   280 
   281     handle->fd = gmyth_stream_client_play_stream (handle->stream);
   282 
   283     if (handle->fd == -1) {
   284         gmyth_stream_client_disconnect (handle->stream);
   285         return GNOME_VFS_ERROR_INVALID_FILENAME;
   286     }
   287 
   288     *method_handle = (GnomeVFSMethodHandle *) handle;
   289     return GNOME_VFS_OK;
   290 }
   291 
   292 static GnomeVFSResult
   293 do_read (GnomeVFSMethod       *method,
   294 	 GnomeVFSMethodHandle *method_handle,
   295 	 gpointer              buffer,
   296 	 GnomeVFSFileSize      bytes,
   297 	 GnomeVFSFileSize     *bytes_read,
   298 	 GnomeVFSContext      *context)
   299 {
   300 
   301     gint64 total_read = 0;
   302     gmsHandle *handle = (gmsHandle *) method_handle;
   303 
   304     total_read = recv(handle->fd, buffer, BUFFER_SIZE, 0);
   305     *bytes_read = (GnomeVFSFileSize) total_read;
   306 
   307     if (total_read < 0) return GNOME_VFS_ERROR_INTERNAL;
   308     else return GNOME_VFS_OK;
   309 
   310 }
   311 
   312 static GnomeVFSResult
   313 do_close (GnomeVFSMethod * method,
   314           GnomeVFSMethodHandle * method_handle,
   315           GnomeVFSContext * context)
   316 {
   317     gmsHandle *handle = (gmsHandle *) method_handle;
   318 
   319     gmyth_stream_client_close_stream (handle->stream);
   320     gmyth_stream_client_disconnect (handle->stream);
   321 
   322     g_free(handle);
   323     return GNOME_VFS_OK;
   324 }
   325 
   326 
   327 static GnomeVFSResult
   328 do_get_file_info (GnomeVFSMethod * method,
   329 		  GnomeVFSURI * uri,
   330 		  GnomeVFSFileInfo * file_info,
   331 		  GnomeVFSFileInfoOptions options,
   332 		  GnomeVFSContext * context)
   333 {
   334     file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
   335         GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
   336 
   337     file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
   338 
   339     file_info->permissions = GNOME_VFS_PERM_USER_READ |
   340         GNOME_VFS_PERM_OTHER_READ |
   341         GNOME_VFS_PERM_GROUP_READ;
   342 
   343     return GNOME_VFS_OK;
   344 }
   345 
   346 
   347 static GnomeVFSResult
   348 do_get_file_info_from_handle (GnomeVFSMethod 		*method,
   349                               GnomeVFSMethodHandle 	*method_handle,
   350                               GnomeVFSFileInfo 		*file_info,
   351                               GnomeVFSFileInfoOptions    options,
   352                               GnomeVFSContext 		*context)
   353 {
   354     file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
   355         GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
   356 
   357     file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
   358 
   359     file_info->permissions = GNOME_VFS_PERM_USER_READ |
   360         GNOME_VFS_PERM_OTHER_READ |
   361         GNOME_VFS_PERM_GROUP_READ;
   362 
   363     return GNOME_VFS_OK;
   364 }
   365 
   366 
   367 static gboolean
   368 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)
   369 {
   370     return FALSE;
   371 }