[svn r41] Changes prior to move some MythTV depedencies to the GMyth library.
1.1 --- a/gst-plugins-mythtv/src/Makefile.am Mon Oct 23 14:43:18 2006 +0100
1.2 +++ b/gst-plugins-mythtv/src/Makefile.am Mon Oct 23 15:42:46 2006 +0100
1.3 @@ -4,9 +4,9 @@
1.4
1.5 libgstmythtvsrc_la_SOURCES = \
1.6 gstmythtvsrc.c \
1.7 - myth_uri.c \
1.8 - myth_file_transfer.c \
1.9 - myth_livetv.c
1.10 + gmyth_uri.c \
1.11 + gmyth_file_transfer.c \
1.12 + gmyth_livetv.c
1.13
1.14 libgstmythtvsrc_la_CFLAGS = \
1.15 $(GST_CFLAGS) \
1.16 @@ -21,7 +21,7 @@
1.17
1.18 noinst_HEADERS = \
1.19 gstmythtvsrc.h \
1.20 - myth_uri.h \
1.21 - myth_file_transfer.h \
1.22 - myth_livetv.h
1.23 + gmyth_uri.h \
1.24 + gmyth_file_transfer.h \
1.25 + gmyth_livetv.h
1.26
2.1 --- a/gst-plugins-mythtv/src/Makefile.in Mon Oct 23 14:43:18 2006 +0100
2.2 +++ b/gst-plugins-mythtv/src/Makefile.in Mon Oct 23 15:42:46 2006 +0100
2.3 @@ -60,9 +60,9 @@
2.4 am__DEPENDENCIES_1 =
2.5 libgstmythtvsrc_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
2.6 am_libgstmythtvsrc_la_OBJECTS = libgstmythtvsrc_la-gstmythtvsrc.lo \
2.7 - libgstmythtvsrc_la-myth_uri.lo \
2.8 - libgstmythtvsrc_la-myth_file_transfer.lo \
2.9 - libgstmythtvsrc_la-myth_livetv.lo
2.10 + libgstmythtvsrc_la-gmyth_uri.lo \
2.11 + libgstmythtvsrc_la-gmyth_file_transfer.lo \
2.12 + libgstmythtvsrc_la-gmyth_livetv.lo
2.13 libgstmythtvsrc_la_OBJECTS = $(am_libgstmythtvsrc_la_OBJECTS)
2.14 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
2.15 depcomp = $(SHELL) $(top_srcdir)/depcomp
2.16 @@ -117,6 +117,7 @@
2.17 GMYTH_LIBS = @GMYTH_LIBS@
2.18 GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
2.19 GOBJECT_LIBS = @GOBJECT_LIBS@
2.20 +GREP = @GREP@
2.21 GSTBASE_CFLAGS = @GSTBASE_CFLAGS@
2.22 GSTBASE_LIBS = @GSTBASE_LIBS@
2.23 GST_CFLAGS = @GST_CFLAGS@
2.24 @@ -166,13 +167,9 @@
2.25 SHELL = @SHELL@
2.26 STRIP = @STRIP@
2.27 VERSION = @VERSION@
2.28 -ac_ct_AR = @ac_ct_AR@
2.29 ac_ct_CC = @ac_ct_CC@
2.30 ac_ct_CXX = @ac_ct_CXX@
2.31 ac_ct_F77 = @ac_ct_F77@
2.32 -ac_ct_RANLIB = @ac_ct_RANLIB@
2.33 -ac_ct_STRIP = @ac_ct_STRIP@
2.34 -ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
2.35 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
2.36 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
2.37 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
2.38 @@ -189,23 +186,30 @@
2.39 build_os = @build_os@
2.40 build_vendor = @build_vendor@
2.41 datadir = @datadir@
2.42 +datarootdir = @datarootdir@
2.43 +docdir = @docdir@
2.44 +dvidir = @dvidir@
2.45 exec_prefix = @exec_prefix@
2.46 host = @host@
2.47 host_alias = @host_alias@
2.48 host_cpu = @host_cpu@
2.49 host_os = @host_os@
2.50 host_vendor = @host_vendor@
2.51 +htmldir = @htmldir@
2.52 includedir = @includedir@
2.53 infodir = @infodir@
2.54 install_sh = @install_sh@
2.55 libdir = @libdir@
2.56 libexecdir = @libexecdir@
2.57 +localedir = @localedir@
2.58 localstatedir = @localstatedir@
2.59 mandir = @mandir@
2.60 mkdir_p = @mkdir_p@
2.61 oldincludedir = @oldincludedir@
2.62 +pdfdir = @pdfdir@
2.63 prefix = @prefix@
2.64 program_transform_name = @program_transform_name@
2.65 +psdir = @psdir@
2.66 sbindir = @sbindir@
2.67 sharedstatedir = @sharedstatedir@
2.68 sysconfdir = @sysconfdir@
2.69 @@ -214,9 +218,9 @@
2.70 plugin_LTLIBRARIES = libgstmythtvsrc.la
2.71 libgstmythtvsrc_la_SOURCES = \
2.72 gstmythtvsrc.c \
2.73 - myth_uri.c \
2.74 - myth_file_transfer.c \
2.75 - myth_livetv.c
2.76 + gmyth_uri.c \
2.77 + gmyth_file_transfer.c \
2.78 + gmyth_livetv.c
2.79
2.80 libgstmythtvsrc_la_CFLAGS = \
2.81 $(GST_CFLAGS) \
2.82 @@ -231,9 +235,9 @@
2.83
2.84 noinst_HEADERS = \
2.85 gstmythtvsrc.h \
2.86 - myth_uri.h \
2.87 - myth_file_transfer.h \
2.88 - myth_livetv.h
2.89 + gmyth_uri.h \
2.90 + gmyth_file_transfer.h \
2.91 + gmyth_livetv.h
2.92
2.93 all: all-am
2.94
2.95 @@ -304,10 +308,10 @@
2.96 distclean-compile:
2.97 -rm -f *.tab.c
2.98
2.99 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-gmyth_file_transfer.Plo@am__quote@
2.100 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-gmyth_livetv.Plo@am__quote@
2.101 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-gmyth_uri.Plo@am__quote@
2.102 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-gstmythtvsrc.Plo@am__quote@
2.103 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-myth_file_transfer.Plo@am__quote@
2.104 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-myth_livetv.Plo@am__quote@
2.105 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-myth_uri.Plo@am__quote@
2.106
2.107 .c.o:
2.108 @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
2.109 @@ -337,26 +341,26 @@
2.110 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.111 @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -c -o libgstmythtvsrc_la-gstmythtvsrc.lo `test -f 'gstmythtvsrc.c' || echo '$(srcdir)/'`gstmythtvsrc.c
2.112
2.113 -libgstmythtvsrc_la-myth_uri.lo: myth_uri.c
2.114 -@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -MT libgstmythtvsrc_la-myth_uri.lo -MD -MP -MF "$(DEPDIR)/libgstmythtvsrc_la-myth_uri.Tpo" -c -o libgstmythtvsrc_la-myth_uri.lo `test -f 'myth_uri.c' || echo '$(srcdir)/'`myth_uri.c; \
2.115 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgstmythtvsrc_la-myth_uri.Tpo" "$(DEPDIR)/libgstmythtvsrc_la-myth_uri.Plo"; else rm -f "$(DEPDIR)/libgstmythtvsrc_la-myth_uri.Tpo"; exit 1; fi
2.116 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='myth_uri.c' object='libgstmythtvsrc_la-myth_uri.lo' libtool=yes @AMDEPBACKSLASH@
2.117 +libgstmythtvsrc_la-gmyth_uri.lo: gmyth_uri.c
2.118 +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -MT libgstmythtvsrc_la-gmyth_uri.lo -MD -MP -MF "$(DEPDIR)/libgstmythtvsrc_la-gmyth_uri.Tpo" -c -o libgstmythtvsrc_la-gmyth_uri.lo `test -f 'gmyth_uri.c' || echo '$(srcdir)/'`gmyth_uri.c; \
2.119 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgstmythtvsrc_la-gmyth_uri.Tpo" "$(DEPDIR)/libgstmythtvsrc_la-gmyth_uri.Plo"; else rm -f "$(DEPDIR)/libgstmythtvsrc_la-gmyth_uri.Tpo"; exit 1; fi
2.120 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gmyth_uri.c' object='libgstmythtvsrc_la-gmyth_uri.lo' libtool=yes @AMDEPBACKSLASH@
2.121 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.122 -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -c -o libgstmythtvsrc_la-myth_uri.lo `test -f 'myth_uri.c' || echo '$(srcdir)/'`myth_uri.c
2.123 +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -c -o libgstmythtvsrc_la-gmyth_uri.lo `test -f 'gmyth_uri.c' || echo '$(srcdir)/'`gmyth_uri.c
2.124
2.125 -libgstmythtvsrc_la-myth_file_transfer.lo: myth_file_transfer.c
2.126 -@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -MT libgstmythtvsrc_la-myth_file_transfer.lo -MD -MP -MF "$(DEPDIR)/libgstmythtvsrc_la-myth_file_transfer.Tpo" -c -o libgstmythtvsrc_la-myth_file_transfer.lo `test -f 'myth_file_transfer.c' || echo '$(srcdir)/'`myth_file_transfer.c; \
2.127 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgstmythtvsrc_la-myth_file_transfer.Tpo" "$(DEPDIR)/libgstmythtvsrc_la-myth_file_transfer.Plo"; else rm -f "$(DEPDIR)/libgstmythtvsrc_la-myth_file_transfer.Tpo"; exit 1; fi
2.128 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='myth_file_transfer.c' object='libgstmythtvsrc_la-myth_file_transfer.lo' libtool=yes @AMDEPBACKSLASH@
2.129 +libgstmythtvsrc_la-gmyth_file_transfer.lo: gmyth_file_transfer.c
2.130 +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -MT libgstmythtvsrc_la-gmyth_file_transfer.lo -MD -MP -MF "$(DEPDIR)/libgstmythtvsrc_la-gmyth_file_transfer.Tpo" -c -o libgstmythtvsrc_la-gmyth_file_transfer.lo `test -f 'gmyth_file_transfer.c' || echo '$(srcdir)/'`gmyth_file_transfer.c; \
2.131 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgstmythtvsrc_la-gmyth_file_transfer.Tpo" "$(DEPDIR)/libgstmythtvsrc_la-gmyth_file_transfer.Plo"; else rm -f "$(DEPDIR)/libgstmythtvsrc_la-gmyth_file_transfer.Tpo"; exit 1; fi
2.132 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gmyth_file_transfer.c' object='libgstmythtvsrc_la-gmyth_file_transfer.lo' libtool=yes @AMDEPBACKSLASH@
2.133 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.134 -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -c -o libgstmythtvsrc_la-myth_file_transfer.lo `test -f 'myth_file_transfer.c' || echo '$(srcdir)/'`myth_file_transfer.c
2.135 +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -c -o libgstmythtvsrc_la-gmyth_file_transfer.lo `test -f 'gmyth_file_transfer.c' || echo '$(srcdir)/'`gmyth_file_transfer.c
2.136
2.137 -libgstmythtvsrc_la-myth_livetv.lo: myth_livetv.c
2.138 -@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -MT libgstmythtvsrc_la-myth_livetv.lo -MD -MP -MF "$(DEPDIR)/libgstmythtvsrc_la-myth_livetv.Tpo" -c -o libgstmythtvsrc_la-myth_livetv.lo `test -f 'myth_livetv.c' || echo '$(srcdir)/'`myth_livetv.c; \
2.139 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgstmythtvsrc_la-myth_livetv.Tpo" "$(DEPDIR)/libgstmythtvsrc_la-myth_livetv.Plo"; else rm -f "$(DEPDIR)/libgstmythtvsrc_la-myth_livetv.Tpo"; exit 1; fi
2.140 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='myth_livetv.c' object='libgstmythtvsrc_la-myth_livetv.lo' libtool=yes @AMDEPBACKSLASH@
2.141 +libgstmythtvsrc_la-gmyth_livetv.lo: gmyth_livetv.c
2.142 +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -MT libgstmythtvsrc_la-gmyth_livetv.lo -MD -MP -MF "$(DEPDIR)/libgstmythtvsrc_la-gmyth_livetv.Tpo" -c -o libgstmythtvsrc_la-gmyth_livetv.lo `test -f 'gmyth_livetv.c' || echo '$(srcdir)/'`gmyth_livetv.c; \
2.143 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgstmythtvsrc_la-gmyth_livetv.Tpo" "$(DEPDIR)/libgstmythtvsrc_la-gmyth_livetv.Plo"; else rm -f "$(DEPDIR)/libgstmythtvsrc_la-gmyth_livetv.Tpo"; exit 1; fi
2.144 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gmyth_livetv.c' object='libgstmythtvsrc_la-gmyth_livetv.lo' libtool=yes @AMDEPBACKSLASH@
2.145 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.146 -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -c -o libgstmythtvsrc_la-myth_livetv.lo `test -f 'myth_livetv.c' || echo '$(srcdir)/'`myth_livetv.c
2.147 +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -c -o libgstmythtvsrc_la-gmyth_livetv.lo `test -f 'gmyth_livetv.c' || echo '$(srcdir)/'`gmyth_livetv.c
2.148
2.149 mostlyclean-libtool:
2.150 -rm -f *.lo
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/gst-plugins-mythtv/src/gmyth_file_transfer.c Mon Oct 23 15:42:46 2006 +0100
3.3 @@ -0,0 +1,1050 @@
3.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
3.5 +/**
3.6 + * GStreamer plug-in properties:
3.7 + * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
3.8 + * - path (qurl - remote file to be opened)
3.9 + * - port number
3.10 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
3.11 + */
3.12 +
3.13 +#include "gmyth_file_transfer.h"
3.14 +#include "gmyth_uri.h"
3.15 +#include "gmyth_livetv.h"
3.16 +#include <gmyth/gmyth_util.h>
3.17 +#include <gmyth/gmyth_socket.h>
3.18 +#include <gmyth/gmyth_stringlist.h>
3.19 +
3.20 +#include <unistd.h>
3.21 +#include <glib.h>
3.22 +
3.23 +#include <arpa/inet.h>
3.24 +#include <sys/types.h>
3.25 +#include <sys/socket.h>
3.26 +#include <netdb.h>
3.27 +#include <errno.h>
3.28 +#include <stdlib.h>
3.29 +
3.30 +#define GMYTHTV_QUERY_HEADER "QUERY_FILETRANSFER"
3.31 +#define GMYTHTV_RECORDER_HEADER "QUERY_RECORDER"
3.32 +
3.33 +/* default values to the file transfer parameters */
3.34 +#define GMYTHTV_USER_READ_AHEAD FALSE
3.35 +#define GMYTHTV_RETRIES 1
3.36 +#define GMYTHTV_FILE_SIZE -1
3.37 +
3.38 +#define GMYTHTV_BUFFER_SIZE 8*1024
3.39 +
3.40 +#define GMYTHTV_VERSION 30
3.41 +
3.42 +#define GMYTHTV_TRANSFER_MAX_WAITS 700
3.43 +
3.44 +#ifdef GMYTHTV_ENABLE_DEBUG
3.45 +#define GMYTHTV_ENABLE_DEBUG 1
3.46 +#else
3.47 +#undef GMYTHTV_ENABLE_DEBUG
3.48 +#endif
3.49 +
3.50 +/* this NDEBUG is to maintain compatibility with GMyth library */
3.51 +#ifndef NDEBUG
3.52 +#define GMYTHTV_ENABLE_DEBUG 1
3.53 +#endif
3.54 +
3.55 +static guint wait_to_transfer = 0;
3.56 +
3.57 +enum myth_sock_types {
3.58 + GMYTH_PLAYBACK_TYPE = 0,
3.59 + GMYTH_MONITOR_TYPE,
3.60 + GMYTH_FILETRANSFER_TYPE,
3.61 + GMYTH_RINGBUFFER_TYPE
3.62 +};
3.63 +
3.64 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
3.65 +
3.66 +static GMainContext *io_watcher_context = NULL;
3.67 +
3.68 +static void gmyth_file_transfer_class_init (GMythFileTransferClass *klass);
3.69 +static void gmyth_file_transfer_init (GMythFileTransfer *object);
3.70 +
3.71 +static void gmyth_file_transfer_dispose (GObject *object);
3.72 +static void gmyth_file_transfer_finalize (GObject *object);
3.73 +
3.74 +static GMythSocket *myth_connect_to_transfer_backend( GMythFileTransfer **transfer, guint sock_type );
3.75 +static void* myth_init_io_watchers( void *data );
3.76 +
3.77 +void gmyth_file_transfer_close( GMythFileTransfer *transfer );
3.78 +
3.79 +G_DEFINE_TYPE(GMythFileTransfer, gmyth_file_transfer, G_TYPE_OBJECT)
3.80 +
3.81 +#if 0
3.82 +static guint64
3.83 +mmyth_util_decode_long_long( GMythStringList *strlist, guint offset )
3.84 +{
3.85 +
3.86 + guint64 ret_value = 0LL;
3.87 +
3.88 + g_return_val_if_fail( strlist != NULL, ret_value );
3.89 +
3.90 + if ( offset < gmyth_string_list_length( strlist ))
3.91 + g_printerr( "[%s] Offset is lower than the GMythStringList (offset = %d)!\n", __FUNCTION__, offset );
3.92 + g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
3.93 +
3.94 + gint l1 = gmyth_string_list_get_int( strlist, offset );
3.95 + gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
3.96 +
3.97 + ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
3.98 +
3.99 + return ret_value;
3.100 +
3.101 +}
3.102 +#endif
3.103 +
3.104 +static void
3.105 +gmyth_file_transfer_class_init (GMythFileTransferClass *klass)
3.106 +{
3.107 + GObjectClass *gobject_class;
3.108 +
3.109 + gobject_class = (GObjectClass *) klass;
3.110 +
3.111 + gobject_class->dispose = gmyth_file_transfer_dispose;
3.112 + gobject_class->finalize = gmyth_file_transfer_finalize;
3.113 +}
3.114 +
3.115 + static void
3.116 +gmyth_file_transfer_init (GMythFileTransfer *gmyth_file_transfer)
3.117 +{
3.118 + g_return_if_fail( gmyth_file_transfer != NULL );
3.119 + gmyth_file_transfer->mythtv_version = GMYTHTV_VERSION;
3.120 +}
3.121 +
3.122 +static void
3.123 +gmyth_file_transfer_dispose (GObject *object)
3.124 +{
3.125 + GMythFileTransfer *gmyth_file_transfer = GMYTH_FILE_TRANSFER(object);
3.126 +
3.127 + gmyth_file_transfer_close( gmyth_file_transfer );
3.128 +
3.129 + G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->dispose (object);
3.130 +}
3.131 +
3.132 + static void
3.133 +gmyth_file_transfer_finalize (GObject *object)
3.134 +{
3.135 + g_signal_handlers_destroy (object);
3.136 +
3.137 + G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->finalize (object);
3.138 +}
3.139 +
3.140 + GMythFileTransfer*
3.141 +gmyth_file_transfer_new (gint num, GString *uri_str, gshort port, gint mythtv_version)
3.142 +{
3.143 + GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER ( g_object_new (
3.144 + GMYTH_FILE_TRANSFER_TYPE, FALSE ));
3.145 +
3.146 + if ( mythtv_version > 0 )
3.147 + transfer->mythtv_version = mythtv_version;
3.148 +
3.149 + transfer->card_id = num;
3.150 +
3.151 + transfer->rec_id = -1;
3.152 +
3.153 + transfer->recordernum = num;
3.154 + transfer->uri = gmyth_uri_new ( uri_str->str );
3.155 +
3.156 + transfer->hostname = g_string_new( gmyth_uri_gethost(transfer->uri) );
3.157 + g_print( "\t--> transfer->hostname = %s\n", transfer->hostname->str );
3.158 +
3.159 + if ( port >= 0 )
3.160 + transfer->port = port;
3.161 + else
3.162 + transfer->port = gmyth_uri_getport( transfer->uri );
3.163 +
3.164 + g_print( "\t--> transfer->port = %d\n", transfer->port );
3.165 +
3.166 + transfer->readposition = 0;
3.167 + transfer->filesize = GMYTHTV_FILE_SIZE;
3.168 + transfer->timeoutisfast = FALSE;
3.169 +
3.170 + transfer->userreadahead = GMYTHTV_USER_READ_AHEAD;
3.171 + transfer->retries = GMYTHTV_RETRIES;
3.172 +
3.173 + transfer->live_tv = FALSE;
3.174 +
3.175 + transfer->query = g_string_new( GMYTHTV_QUERY_HEADER );
3.176 + g_string_append_printf ( transfer->query, " %d", transfer->recordernum );
3.177 + g_print( "\t--> transfer->query = %s\n", transfer->query->str );
3.178 +
3.179 + transfer->control_sock = NULL;
3.180 + transfer->event_sock = NULL;
3.181 + transfer->sock = NULL;
3.182 +
3.183 + return transfer;
3.184 +}
3.185 +
3.186 +gboolean
3.187 +gmyth_file_transfer_livetv_setup( GMythFileTransfer **transfer, GMythSocket *live_socket )
3.188 +{
3.189 + (*transfer)->sock = live_socket;
3.190 + g_object_ref( live_socket );
3.191 +
3.192 + return TRUE;
3.193 +}
3.194 +
3.195 +gboolean
3.196 +gmyth_file_transfer_playback_setup( GMythFileTransfer **transfer, gboolean live_tv )
3.197 +{
3.198 +
3.199 + gboolean ret = TRUE;
3.200 +
3.201 + (*transfer)->live_tv = live_tv;
3.202 +
3.203 + printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
3.204 +
3.205 + /* configure the control socket */
3.206 + if ((*transfer)->control_sock == NULL) {
3.207 +
3.208 + if ( myth_connect_to_transfer_backend ( transfer, GMYTH_PLAYBACK_TYPE ) == NULL ) {
3.209 + g_printerr( "Connection to backend failed (Control Socket).\n" );
3.210 + ret = FALSE;
3.211 + }
3.212 +
3.213 + } else {
3.214 + g_warning("Remote transfer control socket already created.\n");
3.215 + }
3.216 +
3.217 + return ret;
3.218 +
3.219 +}
3.220 +
3.221 +gboolean
3.222 +gmyth_file_transfer_setup( GMythFileTransfer **transfer, gboolean live_tv )
3.223 +{
3.224 + GMythStringList *strlist = NULL;
3.225 +
3.226 + gboolean ret = TRUE;
3.227 +
3.228 + (*transfer)->live_tv = live_tv;
3.229 +
3.230 + printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
3.231 +
3.232 +#if 0
3.233 + /* configure the control socket */
3.234 + if ((*transfer)->event_sock == NULL) {
3.235 +
3.236 + if ( myth_connect_to_transfer_backend ( transfer, GMYTH_MONITOR_TYPE ) == NULL ) {
3.237 + g_printerr( "Connection to backend failed (Event Socket).\n" );
3.238 + ret = FALSE;
3.239 + }
3.240 +
3.241 + } else {
3.242 + g_warning("Remote transfer control socket already created.\n");
3.243 + }
3.244 +#endif
3.245 +
3.246 + /* configure the socket */
3.247 + if ( (*transfer)->sock == NULL ) {
3.248 +
3.249 + //if ( live_tv == FALSE ) {
3.250 +
3.251 + if ( myth_connect_to_transfer_backend ( transfer, GMYTH_FILETRANSFER_TYPE ) == NULL ) {
3.252 + g_printerr ("Connection to backend failed (Raw Transfer Socket).\n");
3.253 + ret = FALSE;
3.254 + }
3.255 +
3.256 + if ( !(*transfer)->live_tv && (*transfer)->control_sock != NULL) {
3.257 + strlist = gmyth_string_list_new();
3.258 + g_string_printf ( (*transfer)->query, "%s %d", GMYTHTV_QUERY_HEADER, (*transfer)->recordernum );
3.259 +
3.260 + gmyth_string_list_append_string( strlist, (*transfer)->query );
3.261 + gmyth_string_list_append_char_array( strlist, "IS_OPEN" );
3.262 +
3.263 + gmyth_socket_write_stringlist( (*transfer)->control_sock, strlist );
3.264 + gmyth_socket_read_stringlist( (*transfer)->control_sock, strlist );
3.265 +
3.266 + if ( strlist!=NULL && gmyth_string_list_get_int( strlist, 0 ) == 1 ) {
3.267 + g_print( "[%s] Remote Myth FileTransfer socket is open!\n", __FUNCTION__ );
3.268 + } else {
3.269 + g_print( "[%s] Remote Myth FileTransfer socket is CLOSED! See the MythTV Server Backend for configuration details...\n", __FUNCTION__ );
3.270 + ret = FALSE;
3.271 + }
3.272 + }
3.273 +
3.274 + } else {
3.275 + g_warning("Remote transfer (raw) socket already created.\n");
3.276 + }
3.277 +
3.278 + return ret;
3.279 +}
3.280 +
3.281 +static GMythSocket *
3.282 +myth_connect_to_transfer_backend( GMythFileTransfer **transfer, guint sock_type )
3.283 +{
3.284 + GMythSocket *sock = NULL;
3.285 +
3.286 + g_return_val_if_fail( transfer != NULL && *transfer != NULL, NULL );
3.287 + g_return_val_if_fail( (*transfer)->uri != NULL, NULL );
3.288 +
3.289 + g_static_mutex_lock (&mutex);
3.290 +
3.291 + gchar *path_dir = gmyth_uri_getpath( (*transfer)->uri );
3.292 + //g_print( "\t--> %s: path_dir = %s\n", __FUNCTION__, path_dir );
3.293 +
3.294 + gchar *stype = g_strdup( "" );
3.295 +
3.296 + // if ( (*transfer)->live_tv == FALSE ) {
3.297 +
3.298 + sock = gmyth_socket_new();
3.299 +
3.300 + gmyth_socket_connect( &sock, (*transfer)->hostname->str, (*transfer)->port );
3.301 +
3.302 + /*
3.303 + } else {
3.304 + sock = (*transfer)->sock;
3.305 + }
3.306 + */
3.307 +#ifdef GMYTHTV_ENABLE_DEBUG
3.308 +
3.309 + g_print( "[%s] --> Creating socket... (%s, %d)\n", __FUNCTION__, (*transfer)->hostname->str, (*transfer)->port );
3.310 +#endif
3.311 +
3.312 + GMythStringList *strlist = NULL;
3.313 +
3.314 + GString *hostname = g_string_new( gmyth_uri_gethost( (*transfer)->uri ) );
3.315 + GString *base_str = g_string_new( "" );
3.316 +
3.317 + if ( gmyth_socket_check_protocol_version_number (sock, (*transfer)->mythtv_version) ) {
3.318 +
3.319 + if (sock == NULL) {
3.320 + stype = (sock_type==GMYTH_PLAYBACK_TYPE) ? "control socket" : "file data socket";
3.321 + g_printerr( "FileTransfer, open_socket(%s): \n"
3.322 + "\t\t\tCould not connect to server \"%s\" @ port %d\n", stype,
3.323 + (*transfer)->hostname->str, (*transfer)->port );
3.324 + g_object_unref(sock);
3.325 + g_static_mutex_unlock (&mutex);
3.326 + return NULL;
3.327 + }
3.328 +
3.329 + hostname = gmyth_socket_get_local_hostname();
3.330 +
3.331 + g_print( "[%s] local hostname = %s\n", __FUNCTION__, hostname->str );
3.332 +
3.333 + if ( sock_type == GMYTH_PLAYBACK_TYPE )
3.334 + {
3.335 + (*transfer)->control_sock = sock;
3.336 + g_string_printf( base_str, "ANN Playback %s %d", hostname->str, TRUE );
3.337 +
3.338 + gmyth_socket_send_command( (*transfer)->control_sock, base_str );
3.339 + GString *resp = gmyth_socket_receive_response( (*transfer)->control_sock );
3.340 + g_print( "[%s] Got Playback response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
3.341 + }
3.342 + else if ( sock_type == GMYTH_MONITOR_TYPE )
3.343 + {
3.344 + (*transfer)->event_sock = sock;
3.345 + g_string_printf( base_str, "ANN Monitor %s %d", hostname->str, TRUE );
3.346 +
3.347 + gmyth_socket_send_command( (*transfer)->event_sock, base_str );
3.348 + GString *resp = gmyth_socket_receive_response( (*transfer)->event_sock );
3.349 + g_print( "[%s] Got Monitor response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
3.350 + //g_thread_create( myth_init_io_watchers, (void*)(*transfer), FALSE, NULL );
3.351 + myth_init_io_watchers ( (void*)(*transfer) );
3.352 +
3.353 + g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
3.354 +
3.355 + }
3.356 + else if ( sock_type == GMYTH_FILETRANSFER_TYPE )
3.357 + {
3.358 + (*transfer)->sock = sock;
3.359 + strlist = gmyth_string_list_new();
3.360 + //g_string_printf( base_str, "ANN FileTransfer %s %d %d", hostname->str,
3.361 + // transfer->userreadahead, transfer->retries );
3.362 + g_string_printf( base_str, "ANN FileTransfer %s", hostname->str );
3.363 +
3.364 + gmyth_string_list_append_string( strlist, base_str );
3.365 + gmyth_string_list_append_char_array( strlist, path_dir );
3.366 +
3.367 + gmyth_socket_write_stringlist( (*transfer)->sock, strlist );
3.368 + gmyth_socket_read_stringlist( (*transfer)->sock, strlist );
3.369 +
3.370 + /* socket number, where all the stream data comes from - got from the MythTV remote backend */
3.371 + (*transfer)->recordernum = gmyth_string_list_get_int( strlist, 1 );
3.372 +
3.373 + /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */
3.374 + (*transfer)->filesize = gmyth_util_decode_long_long( strlist, 2 );
3.375 +
3.376 + printf( "[%s] ***** Received: recordernum = %d, filesize = %" G_GUINT64_FORMAT "\n", __FUNCTION__,
3.377 + (*transfer)->recordernum, (*transfer)->filesize );
3.378 +
3.379 + if ( (*transfer)->filesize <= 0 ) {
3.380 + g_print( "[%s] Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", __FUNCTION__, (*transfer)->filesize );
3.381 + g_object_unref(sock);
3.382 + sock = NULL;
3.383 + }
3.384 + }
3.385 + else if ( sock_type == GMYTH_RINGBUFFER_TYPE )
3.386 + {
3.387 + (*transfer)->sock = sock;
3.388 + //gmyth_file_transfer_spawntv( (*transfer), NULL );
3.389 +
3.390 + strlist = gmyth_string_list_new();
3.391 + g_string_printf( base_str, "ANN RingBuffer %s %d", hostname->str, (*transfer)->card_id );
3.392 +
3.393 + gmyth_socket_send_command( (*transfer)->sock, base_str );
3.394 + GString *resp = gmyth_socket_receive_response( (*transfer)->sock );
3.395 + g_print( "[%s] Got RingBuffer response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
3.396 +
3.397 + }
3.398 +
3.399 + }
3.400 +
3.401 + printf("[%s] ANN %s sent: %s\n", (sock_type==GMYTH_PLAYBACK_TYPE) ? "Playback" : (sock_type==GMYTH_FILETRANSFER_TYPE) ? "FileTransfer" : "Monitor", __FUNCTION__, base_str->str);
3.402 +
3.403 + if ( strlist != NULL )
3.404 + g_object_unref( strlist );
3.405 +
3.406 + g_static_mutex_unlock (&mutex);
3.407 +
3.408 + return sock;
3.409 +}
3.410 +
3.411 +void
3.412 +gmyth_file_transfer_spawntv ( GMythFileTransfer *file_transfer,
3.413 + GString *tvchain_id )
3.414 +{
3.415 + GMythStringList *str_list;
3.416 +
3.417 + g_debug ("gmyth_file_transfer_spawntv.\n");
3.418 +
3.419 + str_list = gmyth_string_list_new ();
3.420 +
3.421 + g_string_printf( file_transfer->query, "%s %d", GMYTHTV_RECORDER_HEADER,
3.422 + file_transfer->card_id );
3.423 + gmyth_string_list_append_string (str_list, file_transfer->query);
3.424 + gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
3.425 + if (tvchain_id!=NULL) {
3.426 + gmyth_string_list_append_string (str_list, tvchain_id);
3.427 + gmyth_string_list_append_int (str_list, FALSE); // PIP = FALSE (0)
3.428 + }
3.429 +
3.430 + gmyth_socket_sendreceive_stringlist ( file_transfer->sock, str_list );
3.431 +
3.432 + //GString *str = NULL;
3.433 +
3.434 + //if (str_list!=NULL && (str = gmyth_string_list_get_string( str_list, 0 )) != NULL && strcasecmp( str->str, "ok" ) != 0 ) {
3.435 + // g_print( "[%s]\t\tSpawnLiveTV is OK!\n", __FUNCTION__ );
3.436 + //}
3.437 + if (str_list!=NULL)
3.438 + g_object_unref (str_list);
3.439 +
3.440 +}
3.441 +
3.442 +gboolean
3.443 +gmyth_file_transfer_is_recording ( GMythFileTransfer *file_transfer )
3.444 +{
3.445 + gboolean ret = TRUE;
3.446 +
3.447 + GMythStringList *str_list = gmyth_string_list_new ();
3.448 +
3.449 + g_debug ( "[%s]\n", __FUNCTION__ );
3.450 + g_static_mutex_lock (&mutex);
3.451 +
3.452 + g_string_printf( file_transfer->query, "%s %d", GMYTHTV_RECORDER_HEADER,
3.453 + file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id );
3.454 + gmyth_string_list_append_string (str_list, file_transfer->query);
3.455 + gmyth_string_list_append_string (str_list, g_string_new ("IS_RECORDING"));
3.456 +
3.457 + gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list );
3.458 +
3.459 + if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 )
3.460 + {
3.461 + GString *str = NULL;
3.462 + if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp( str->str, "bad" )!= 0 ) {
3.463 + gint is_rec = gmyth_string_list_get_int( str_list, 0 );
3.464 + if ( is_rec != 0 )
3.465 + ret = TRUE;
3.466 + else
3.467 + ret = FALSE;
3.468 + }
3.469 + }
3.470 + g_print( "[%s] %s, stream is %s being recorded!\n", __FUNCTION__, ret ? "YES" : "NO", ret ? "" : "NOT" );
3.471 + g_static_mutex_unlock (&mutex);
3.472 +
3.473 + if ( str_list != NULL )
3.474 + g_object_unref (str_list);
3.475 +
3.476 + return ret;
3.477 +
3.478 +}
3.479 +
3.480 +gint64
3.481 +gmyth_file_transfer_get_file_position ( GMythFileTransfer *file_transfer )
3.482 +{
3.483 + gint64 pos = 0;
3.484 +
3.485 + GMythStringList *str_list = gmyth_string_list_new ();
3.486 +
3.487 + g_debug ( "[%s]\n", __FUNCTION__ );
3.488 + g_static_mutex_lock (&mutex);
3.489 +
3.490 + g_string_printf( file_transfer->query, "%s %d", GMYTHTV_RECORDER_HEADER,
3.491 + file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id );
3.492 +
3.493 + gmyth_string_list_append_string (str_list, file_transfer->query);
3.494 + gmyth_string_list_append_string (str_list, g_string_new ("GET_FILE_POSITION"));
3.495 +
3.496 + gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list );
3.497 +
3.498 + if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 )
3.499 + {
3.500 + GString *str = NULL;
3.501 + if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strstr ( str->str, "bad" ) == NULL )
3.502 + pos = gmyth_util_decode_long_long( str_list, 0 );
3.503 + }
3.504 + g_static_mutex_unlock (&mutex);
3.505 +
3.506 +#ifndef GMYTHTV_ENABLE_DEBUG
3.507 +
3.508 + g_print( "[%s] Got file position = %lld\n", __FUNCTION__, pos );
3.509 +#endif
3.510 + if (str_list!=NULL)
3.511 + g_object_unref (str_list);
3.512 +
3.513 + return pos;
3.514 +
3.515 +}
3.516 +
3.517 + glong
3.518 +gmyth_file_transfer_get_recordernum( GMythFileTransfer *transfer )
3.519 +{
3.520 + return transfer->recordernum;
3.521 +}
3.522 +
3.523 + glong
3.524 +gmyth_file_transfer_get_filesize( GMythFileTransfer *transfer )
3.525 +{
3.526 + return transfer->filesize;
3.527 +}
3.528 +
3.529 + gboolean
3.530 +gmyth_file_transfer_isopen( GMythFileTransfer *transfer )
3.531 +{
3.532 + return (transfer->sock != NULL && transfer->control_sock != NULL);
3.533 +}
3.534 +
3.535 + void
3.536 +gmyth_file_transfer_close( GMythFileTransfer *transfer )
3.537 +{
3.538 + GMythStringList *strlist;
3.539 +
3.540 + if (transfer->control_sock == NULL)
3.541 + return;
3.542 +
3.543 + strlist = gmyth_string_list_new( );
3.544 +
3.545 + g_string_printf( transfer->query, "%s %d", GMYTHTV_QUERY_HEADER,
3.546 + transfer->recordernum );
3.547 + gmyth_string_list_append_string( strlist, transfer->query );
3.548 + gmyth_string_list_append_char_array( strlist, "DONE" );
3.549 +
3.550 +
3.551 + if ( gmyth_socket_sendreceive_stringlist(transfer->control_sock, strlist) <= 0 )
3.552 + {
3.553 + g_printerr( "Remote file timeout.\n" );
3.554 + }
3.555 +
3.556 + if (transfer->sock)
3.557 + {
3.558 + g_object_unref( transfer->sock );
3.559 + transfer->sock = NULL;
3.560 + }
3.561 +
3.562 + if (transfer->control_sock)
3.563 + {
3.564 + g_object_unref( transfer->control_sock );
3.565 + transfer->control_sock = NULL;
3.566 + }
3.567 +
3.568 +}
3.569 +
3.570 + void
3.571 +gmyth_file_transfer_reset_controlsock( GMythFileTransfer *transfer )
3.572 +{
3.573 + if (transfer->control_sock == NULL)
3.574 + {
3.575 + g_printerr( "gmyth_file_transfer_reset_controlsock(): Called with no control socket" );
3.576 + return;
3.577 + }
3.578 +
3.579 + GString *str = gmyth_socket_receive_response( transfer->control_sock );
3.580 +
3.581 + g_string_free( str, TRUE );
3.582 +}
3.583 +
3.584 +void
3.585 +gmyth_file_transfer_reset_sock( GMythFileTransfer *transfer )
3.586 +{
3.587 + if ( transfer->sock == NULL )
3.588 + {
3.589 + g_printerr( "gmyth_file_transfer_reset_sock(): Called with no raw socket" );
3.590 + return;
3.591 + }
3.592 +
3.593 + GString *str = gmyth_socket_receive_response( transfer->sock );
3.594 +
3.595 + g_string_free( str, TRUE );
3.596 +}
3.597 +
3.598 +void
3.599 +gmyth_file_transfer_reset( GMythFileTransfer *transfer )
3.600 +{
3.601 + gmyth_file_transfer_reset_controlsock( transfer );
3.602 + gmyth_file_transfer_reset_sock( transfer );
3.603 +}
3.604 +
3.605 +gint64
3.606 +gmyth_file_transfer_seek(GMythFileTransfer *transfer, guint64 pos, gint whence)
3.607 +{
3.608 + if (transfer->sock == NULL)
3.609 + {
3.610 + g_printerr( "[%s] gmyth_file_transfer_seek(): Called with no socket", __FUNCTION__ );
3.611 + return 0;
3.612 + }
3.613 +
3.614 + if (transfer->control_sock == NULL)
3.615 + return 0;
3.616 +
3.617 + // if (!controlSock->isOpen() || controlSock->error())
3.618 + // return 0;
3.619 +
3.620 + GMythStringList *strlist = gmyth_string_list_new();
3.621 + g_string_printf (transfer->query, "%s %d", GMYTHTV_QUERY_HEADER, transfer->recordernum);
3.622 + gmyth_string_list_append_string( strlist, transfer->query );
3.623 + gmyth_string_list_append_char_array( strlist, "SEEK" );
3.624 + gmyth_string_list_append_uint64( strlist, pos );
3.625 +
3.626 + gmyth_string_list_append_int( strlist, whence );
3.627 +
3.628 + if (pos > 0 )
3.629 + gmyth_string_list_append_uint64( strlist, pos );
3.630 + else
3.631 + gmyth_string_list_append_uint64( strlist, transfer->readposition );
3.632 +
3.633 + gmyth_socket_sendreceive_stringlist( transfer->control_sock, strlist );
3.634 +
3.635 + gint64 retval = gmyth_string_list_get_int64(strlist, 0);
3.636 + transfer->readposition = retval;
3.637 + g_print( "[%s] got reading position pointer from the streaming = %lld\n",
3.638 + __FUNCTION__, retval );
3.639 +
3.640 + //gmyth_file_transfer_reset( transfer );
3.641 +
3.642 + return retval;
3.643 +}
3.644 +
3.645 +static gboolean
3.646 +myth_control_sock_listener( GIOChannel *source, GIOCondition condition, gpointer data )
3.647 +{
3.648 +
3.649 + GIOStatus ret;
3.650 + GError *err = NULL;
3.651 + gchar *msg = g_strdup("");
3.652 +
3.653 + g_static_mutex_lock( &mutex );
3.654 +
3.655 + gsize len;
3.656 + if (condition & G_IO_HUP)
3.657 + g_error ("Read end of pipe died!\n");
3.658 + ret = g_io_channel_read_line ( source, &msg, &len, NULL, &err);
3.659 + if ( ret == G_IO_STATUS_ERROR )
3.660 + g_error ("[%s] Error reading: %s\n", __FUNCTION__, err != NULL ? err->message : "" );
3.661 + g_print ("\n\n\n\n\n\n[%s]\t\tEVENT: Read %u bytes: %s\n\n\n\n\n", __FUNCTION__, len, msg != NULL ? msg : "" );
3.662 + if ( msg != NULL )
3.663 + g_free (msg);
3.664 +
3.665 + g_static_mutex_unlock( &mutex );
3.666 +
3.667 + return TRUE;
3.668 +
3.669 +}
3.670 +
3.671 +static void*
3.672 +myth_init_io_watchers( void *data )
3.673 +{
3.674 + GMythFileTransfer *transfer = (GMythFileTransfer*)data;
3.675 + io_watcher_context = g_main_context_new();
3.676 + GMainLoop *loop = g_main_loop_new( NULL, FALSE );
3.677 +
3.678 + GSource *source = NULL;
3.679 +
3.680 + if ( transfer->event_sock->sd_io_ch != NULL )
3.681 + source = g_io_create_watch( transfer->event_sock->sd_io_ch, G_IO_IN | G_IO_HUP );
3.682 + else
3.683 + goto cleanup;
3.684 +
3.685 + g_source_set_callback ( source, (GSourceFunc)myth_control_sock_listener, NULL, NULL );
3.686 +
3.687 + g_source_attach( source, io_watcher_context );
3.688 +
3.689 + if (source==NULL) {
3.690 + g_printerr( "[%s] Error adding watch listener function to the IO control channel!\n", __FUNCTION__ );
3.691 + goto cleanup;
3.692 + }
3.693 +
3.694 + g_print( "[%s]\tOK! Starting listener on the MONITOR event socket...\n", __FUNCTION__ );
3.695 +
3.696 + g_main_loop_run( loop );
3.697 +
3.698 +cleanup:
3.699 + if ( source != NULL )
3.700 + g_source_unref( source );
3.701 +
3.702 + g_main_loop_unref( loop );
3.703 +
3.704 + g_main_context_unref( io_watcher_context );
3.705 +
3.706 + return NULL;
3.707 +}
3.708 +
3.709 +
3.710 +gint
3.711 +gmyth_file_transfer_read(GMythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited)
3.712 +{
3.713 + gint recv = 0;
3.714 + gsize bytes_read = 0;
3.715 + gint sent = 0;
3.716 + guint remaining = 0;
3.717 + gboolean response = FALSE;
3.718 +
3.719 + GIOChannel *io_channel;
3.720 + GIOChannel *io_channel_control;
3.721 +
3.722 + GIOCondition io_cond;
3.723 + GIOCondition io_cond_control;
3.724 + GIOStatus io_status = G_IO_STATUS_NORMAL, io_status_control = G_IO_STATUS_NORMAL;
3.725 +
3.726 + gint buf_len = GMYTHTV_BUFFER_SIZE;
3.727 +
3.728 + GMythStringList *strlist = NULL;
3.729 + GError *error = NULL;
3.730 +
3.731 + gchar *trash = g_strdup("");
3.732 +
3.733 + g_return_val_if_fail ( data != NULL, -2 );
3.734 +
3.735 + /* gets the size of the entire file, if the size requested is lesser than 0 */
3.736 + if ( size <= 0 )
3.737 + size = transfer->filesize;
3.738 +
3.739 + io_channel = transfer->sock->sd_io_ch;
3.740 + io_channel_control = transfer->control_sock->sd_io_ch;
3.741 +
3.742 + //g_io_channel_set_flags( io_channel, G_IO_FLAG_APPEND |
3.743 + // G_IO_STATUS_AGAIN | G_IO_FLAG_IS_READABLE | G_IO_FLAG_IS_WRITEABLE |
3.744 + // G_IO_FLAG_IS_SEEKABLE, NULL );
3.745 +
3.746 + io_status = g_io_channel_set_encoding( io_channel, NULL, &error );
3.747 + if ( io_status == G_IO_STATUS_NORMAL )
3.748 + g_print( "[%s] Setting encoding to binary data socket).\n", __FUNCTION__ );
3.749 +
3.750 + io_cond = g_io_channel_get_buffer_condition( io_channel );
3.751 +
3.752 + io_cond_control = g_io_channel_get_buffer_condition( io_channel );
3.753 +
3.754 + if ( transfer->sock == NULL || ( io_status == G_IO_STATUS_ERROR ) )
3.755 + {
3.756 + g_printerr( "gmyth_file_transfer_read(): Called with no raw socket.\n" );
3.757 + recv = -1;
3.758 + goto cleanup;
3.759 + }
3.760 +
3.761 + if ( transfer->control_sock == NULL || ( io_status_control == G_IO_STATUS_ERROR ) )
3.762 + {
3.763 + g_printerr( "gmyth_file_transfer_read(): Called with no control socket.\n" );
3.764 + recv = -1;
3.765 + goto cleanup;
3.766 + }
3.767 +
3.768 + /*
3.769 + if (!controlSock->isOpen() || controlSock->error())
3.770 + return -1;
3.771 + */
3.772 +
3.773 + if ( ( io_cond & G_IO_IN ) != 0 ) {
3.774 + do
3.775 + {
3.776 + trash = g_new0( gchar, GMYTHTV_BUFFER_SIZE );
3.777 +
3.778 + io_status = g_io_channel_read_chars( io_channel, trash,
3.779 + GMYTHTV_BUFFER_SIZE, &bytes_read, &error);
3.780 +
3.781 + g_print( "[%s] cleaning buffer on IO binary channel... %d bytes gone!\n",
3.782 + __FUNCTION__, bytes_read );
3.783 +
3.784 + if ( trash != NULL )
3.785 + g_free( trash );
3.786 +
3.787 + io_cond = g_io_channel_get_buffer_condition( io_channel );
3.788 +
3.789 + } while ( ( io_cond & G_IO_IN ) != 0 && ( io_status != G_IO_STATUS_ERROR ) && (error == NULL) );
3.790 +
3.791 + //if ( trash!= NULL )
3.792 + // g_free( trash );
3.793 + }
3.794 +
3.795 + if ( ( io_cond_control & G_IO_IN ) != 0 ) {
3.796 + GMythStringList *strlist_tmp = gmyth_string_list_new();
3.797 + gmyth_socket_read_stringlist( transfer->control_sock, strlist_tmp );
3.798 + g_object_unref( strlist_tmp );
3.799 + }
3.800 +
3.801 + wait_to_transfer = 0;
3.802 +
3.803 + //while ( transfer->live_tv && ( gmyth_file_transfer_get_file_position( transfer ) < 4096 ) &&
3.804 + // wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS )
3.805 + // g_usleep( 1000*50 ); /* waits just for 2/10 second */
3.806 +
3.807 + //g_thread_create( myth_init_io_watchers, (void*)transfer, FALSE, NULL );
3.808 + //g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
3.809 +
3.810 + //g_static_mutex_lock (&mutex);
3.811 + //strlist = gmyth_string_list_new();
3.812 +
3.813 + g_string_printf ( transfer->query, "%s %d",
3.814 + /*transfer->live_tv ? GMYTHTV_RECORDER_HEADER :*/ GMYTHTV_QUERY_HEADER,
3.815 + /* transfer->live_tv ? transfer->card_id :*/ transfer->recordernum ); // transfer->recordernum
3.816 + g_print( "\t[%s] Transfer_query = %s\n", __FUNCTION__, transfer->query->str );
3.817 +
3.818 + sent = size;
3.819 + remaining = size - recv;
3.820 + //g_static_mutex_unlock( &mutex );
3.821 + //data = (void*)g_new0( gchar, size );
3.822 +
3.823 + //g_io_channel_flush( io_channel, NULL );
3.824 +
3.825 + //g_static_mutex_lock( &mutex );
3.826 +
3.827 + io_cond = g_io_channel_get_buffer_condition( io_channel );
3.828 +
3.829 + while ( recv < size && !response )//&& ( io_cond & G_IO_IN ) != 0 )
3.830 + {
3.831 + g_io_channel_flush( io_channel_control, NULL );
3.832 +
3.833 + strlist = gmyth_string_list_new();
3.834 + gmyth_string_list_append_char_array( strlist, transfer->query->str );
3.835 + gmyth_string_list_append_char_array( strlist,
3.836 + /*transfer->live_tv ? "REQUEST_BLOCK_RINGBUF" :*/ "REQUEST_BLOCK" );
3.837 + gmyth_string_list_append_int( strlist, remaining );
3.838 + gmyth_socket_write_stringlist( transfer->control_sock, strlist );
3.839 +
3.840 + guint count_bytes = 0;
3.841 +
3.842 + do
3.843 + {
3.844 + //buf_len = ( sent - recv ) > GMYTHTV_BUFFER_SIZE ? GMYTHTV_BUFFER_SIZE : ( sent - recv );
3.845 + if ( remaining > GMYTHTV_BUFFER_SIZE ) {
3.846 + buf_len = GMYTHTV_BUFFER_SIZE;
3.847 + } else {
3.848 + buf_len = remaining;
3.849 + }
3.850 +
3.851 + bytes_read = 0;
3.852 +
3.853 + io_status = g_io_channel_read_chars( io_channel, data + recv,
3.854 + buf_len, &bytes_read, &error );
3.855 +
3.856 + //g_static_mutex_unlock( &mutex );
3.857 + /*
3.858 + GString *sss = g_string_new("");
3.859 + sss = g_string_append_len( sss, (gchar*)data+recv, bytes_read );
3.860 +
3.861 + g_print( "[%s] Reading buffer (length = %d)\n", __FUNCTION__, bytes_read);
3.862 + */
3.863 + if ( bytes_read > 0 )
3.864 + {
3.865 + //if ( bytes_read <= buf_len )
3.866 + recv += bytes_read;
3.867 + count_bytes += bytes_read;
3.868 + remaining -= bytes_read;
3.869 + g_print( "[%s] Reading buffer (bytes read = %d, remaining = %d)\n", __FUNCTION__, bytes_read, remaining );
3.870 + if ( remaining == 0 ) {
3.871 + break;
3.872 + }
3.873 + } else {
3.874 + break;
3.875 + }
3.876 +
3.877 + //if ( remaining > 0 ) {
3.878 +
3.879 + if ( io_status == G_IO_STATUS_EOF ) {
3.880 + g_print( "[%s] got EOS!", __FUNCTION__ );
3.881 + break;
3.882 + } else if ( io_status == G_IO_STATUS_ERROR ) {
3.883 + g_print( "[%s] gmyth_file_transfer_read(): socket error.\n", __FUNCTION__ );
3.884 + break;
3.885 + }
3.886 + //}
3.887 +
3.888 + /* increase buffer size, to allow get more data (do not obey to the buffer size) */
3.889 + if ( read_unlimited == TRUE ) {
3.890 + // FOR NOW, DO NOTHING!!!
3.891 + //if ( recv > buf_len )
3.892 + // sent += (bytes_read - buf_len) + 1;
3.893 + }
3.894 +
3.895 + /* verify if the input (read) buffer is ready to receive data */
3.896 + io_cond = g_io_channel_get_buffer_condition( io_channel );
3.897 +
3.898 + g_print( "[%s]\t io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__,
3.899 + ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
3.900 +
3.901 + //if ( recv == size )
3.902 + //break;
3.903 +
3.904 + } while ( remaining > 0 );//&& ( io_status == G_IO_STATUS_NORMAL ) );
3.905 +
3.906 + // if ( ( recv < size ) ) {
3.907 + // finish_read = FALSE;
3.908 + //}
3.909 +
3.910 + io_cond_control = g_io_channel_get_buffer_condition( io_channel_control );
3.911 + if ( remaining == 0 )//( io_cond_control & G_IO_IN ) != 0 )
3.912 + {
3.913 + gmyth_socket_read_stringlist( transfer->control_sock, strlist );
3.914 + if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 )
3.915 + {
3.916 + sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error
3.917 + g_print( "[%s] got SENT buffer message = %d\n", __FUNCTION__, sent );
3.918 + if ( sent != 0 )
3.919 + {
3.920 + g_print( "[%s]\t received = %d bytes, backend says %d bytes sent, "\
3.921 + "io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__,
3.922 + recv, sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
3.923 +
3.924 + if ( sent == count_bytes )
3.925 + {
3.926 + response = ( recv == size );
3.927 + g_print( "[%s]\t\tsent %d, which is equals to bytes_read = %d\n\n",
3.928 + __FUNCTION__, sent, count_bytes );
3.929 + if ( response == TRUE )
3.930 + break;
3.931 + }
3.932 + else
3.933 + {
3.934 + g_print( "[%s]\t\tsent %d, which is NOT equals to bytes_read = %d\n\n",
3.935 + __FUNCTION__, sent, count_bytes );
3.936 + goto cleanup;
3.937 + //response = FALSE;
3.938 + //break;
3.939 + }
3.940 + } else {
3.941 + break;
3.942 + //goto cleanup;
3.943 + } // if
3.944 + } // if - reading control response from backend
3.945 + } else {
3.946 + response = FALSE;
3.947 + } // if - stringlist response
3.948 +
3.949 + } // while
3.950 +
3.951 + io_cond_control = g_io_channel_get_buffer_condition( io_channel_control );
3.952 + // io_cond = g_io_channel_get_buffer_condition( io_channel );
3.953 +
3.954 + if ( ( ( io_cond_control & G_IO_IN ) != 0 ) &&
3.955 + ( response || ( recv == size ) ) )
3.956 + {
3.957 + if ( gmyth_socket_read_stringlist( transfer->control_sock, strlist ) > 0 )
3.958 + {
3.959 + if ( strlist != NULL && gmyth_string_list_length(strlist) > 0 )
3.960 + {
3.961 + sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error
3.962 + g_print( "[%s]\t received = %d bytes -\tNOW returning from reading buffer I/O socket "\
3.963 + "[%s prepared for reading]! (G_IO_IN) !!!\n\n", __FUNCTION__,
3.964 + sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
3.965 + }
3.966 + }
3.967 + else
3.968 + {
3.969 + g_printerr ( "gmyth_file_transfer_read(): No response from control socket.");
3.970 + recv = -1;
3.971 + }
3.972 +
3.973 + }
3.974 + else if ( error != NULL )
3.975 + {
3.976 + g_printerr( "[%s] Error occurred: (%d, %s)\n", __FUNCTION__, error->code, error->message );
3.977 + }
3.978 +
3.979 +cleanup:
3.980 + //g_static_mutex_unlock (&mutex);
3.981 +
3.982 + if ( trash != NULL )
3.983 + g_free( trash );
3.984 +
3.985 + if ( strlist != NULL )
3.986 + g_object_unref( strlist );
3.987 +
3.988 + g_print( "gmyth_file_transfer_read(): reqd=%d, rcvd=%d, rept=%d, "\
3.989 + "(rcvd and rept MUST be the same!)\n", size,
3.990 + recv, sent );
3.991 +
3.992 + //if ( ( recv != size ) || ( sent != size ) ) {
3.993 + //recv = size;
3.994 + //}
3.995 +
3.996 + if ( error != NULL ) {
3.997 + g_printerr( "Cleaning-up ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message,
3.998 + error->code );
3.999 + g_error_free( error );
3.1000 + }
3.1001 +
3.1002 + return recv;
3.1003 +}
3.1004 +
3.1005 +void
3.1006 +gmyth_file_transfer_settimeout( GMythFileTransfer *transfer, gboolean fast )
3.1007 +{
3.1008 +
3.1009 + GMythStringList *strlist = NULL;
3.1010 +
3.1011 + if ( transfer->timeoutisfast == fast )
3.1012 + return;
3.1013 +
3.1014 + if ( transfer->sock == NULL )
3.1015 + {
3.1016 + g_printerr( "gmyth_file_transfer_settimeout(): Called with no socket" );
3.1017 + return;
3.1018 + }
3.1019 +
3.1020 + if ( transfer->control_sock == NULL )
3.1021 + return;
3.1022 +
3.1023 + strlist = gmyth_string_list_new();
3.1024 + gmyth_string_list_append_string( strlist, transfer->query );
3.1025 + gmyth_string_list_append_char_array( strlist, "SET_TIMEOUT" );
3.1026 + gmyth_string_list_append_int( strlist, fast );
3.1027 +
3.1028 + gmyth_socket_write_stringlist( transfer->control_sock, strlist );
3.1029 + gmyth_socket_read_stringlist( transfer->control_sock, strlist );
3.1030 +
3.1031 + transfer->timeoutisfast = fast;
3.1032 +
3.1033 +}
3.1034 +
3.1035 +#ifdef DO_TESTING
3.1036 +
3.1037 + int
3.1038 +main( int argc, char *argv[] )
3.1039 +{
3.1040 + g_type_init();
3.1041 +
3.1042 + GMythFileTransfer *file_transfer = gmyth_file_transfer_new( 1,
3.1043 + g_string_new("myth://192.168.1.109:6543/jshks.nuv"), -1, GMYTHTV_VERSION );
3.1044 + gmyth_file_transfer_setup( &file_transfer );
3.1045 + gchar *data = g_strdup("");
3.1046 +
3.1047 + gint num = gmyth_file_transfer_read( file_transfer, data, -1 );
3.1048 +
3.1049 + return 0;
3.1050 +
3.1051 +}
3.1052 +
3.1053 +#endif
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/gst-plugins-mythtv/src/gmyth_file_transfer.h Mon Oct 23 15:42:46 2006 +0100
4.3 @@ -0,0 +1,93 @@
4.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
4.5 +
4.6 +#ifndef __GMYTH_FILE_TRANSFER_H__
4.7 +#define __GMYTH_FILE_TRANSFER_H__
4.8 +
4.9 +#include <glib-object.h>
4.10 +
4.11 +#include <gmyth/gmyth_socket.h>
4.12 +#include "gmyth_uri.h"
4.13 +#include "gmyth_livetv.h"
4.14 +
4.15 +#include <stdio.h>
4.16 +#include <stdlib.h>
4.17 +#include <string.h>
4.18 +#include <netdb.h>
4.19 +#include <sys/socket.h>
4.20 +#include <unistd.h>
4.21 +
4.22 +#define G_BEGIN_DECLS
4.23 +
4.24 +#define GMYTH_FILE_TRANSFER_TYPE (gmyth_file_transfer_get_type ())
4.25 +#define GMYTH_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransfer))
4.26 +#define GMYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass))
4.27 +#define IS_GMYTH_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TRANSFER_TYPE))
4.28 +#define IS_GMYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE))
4.29 +#define GMYTH_FILE_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass))
4.30 +
4.31 +
4.32 +typedef struct _GMythFileTransfer GMythFileTransfer;
4.33 +typedef struct _GMythFileTransferClass GMythFileTransferClass;
4.34 +
4.35 +struct _GMythFileTransferClass
4.36 +{
4.37 + GObjectClass parent_class;
4.38 +
4.39 + /* callbacks */
4.40 + /* no one for now */
4.41 +};
4.42 +
4.43 +struct _GMythFileTransfer
4.44 +{
4.45 + GObject parent;
4.46 +
4.47 + /* Myth URI structure */
4.48 + const GMythURI *uri;
4.49 +
4.50 + /* MythTV version number */
4.51 + gint mythtv_version;
4.52 +
4.53 + /* socket descriptors */
4.54 + GMythSocket *control_sock;
4.55 + GMythSocket *event_sock;
4.56 + GMythSocket *sock;
4.57 +
4.58 + guint64 readposition;
4.59 + guint64 filesize;
4.60 + gboolean timeoutisfast;
4.61 + gboolean userreadahead;
4.62 + gboolean live_tv;
4.63 + gint retries;
4.64 +
4.65 + GString *query;
4.66 +
4.67 + gint rec_id;
4.68 + gint recordernum;
4.69 + gint card_id;
4.70 + GString *hostname;
4.71 + gint port;
4.72 +};
4.73 +
4.74 +GType gmyth_file_transfer_get_type (void);
4.75 +
4.76 +GMythFileTransfer* gmyth_file_transfer_new (gint num, GString *hostname, gshort port, gint mythtv_version );
4.77 +
4.78 +gint gmyth_file_transfer_read(GMythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited);
4.79 +
4.80 +gint64 gmyth_file_transfer_seek(GMythFileTransfer *transfer, guint64 pos, gint whence);
4.81 +
4.82 +gboolean gmyth_file_transfer_playback_setup( GMythFileTransfer **transfer, gboolean live_tv );
4.83 +
4.84 +gboolean gmyth_file_transfer_setup( GMythFileTransfer **transfer, gboolean live_tv );
4.85 +
4.86 +gboolean gmyth_file_transfer_livetv_setup( GMythFileTransfer **transfer, GMythSocket *live_sock );
4.87 +
4.88 +void gmyth_file_transfer_spawntv ( GMythFileTransfer *file_transfer, GString *tvchain_id );
4.89 +
4.90 +gboolean gmyth_file_transfer_is_recording( GMythFileTransfer *file_transfer );
4.91 +
4.92 +gint64 gmyth_file_transfer_get_file_position( GMythFileTransfer *file_transfer );
4.93 +
4.94 +#define G_END_DECLS
4.95 +
4.96 +#endif /* __GMYTH_FILE_TRANSFER_H__ */
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/gst-plugins-mythtv/src/gmyth_livetv.c Mon Oct 23 15:42:46 2006 +0100
5.3 @@ -0,0 +1,220 @@
5.4 +
5.5 +#include <gmyth/gmyth_context.h>
5.6 +#include <gmyth/gmyth_remote_util.h>
5.7 +#include <gmyth/gmyth_tvchain.h>
5.8 +
5.9 +#include "gmyth_livetv.h"
5.10 +#include "gmyth_file_transfer.h"
5.11 +
5.12 +static void gmyth_livetv_class_init (GMythLiveTVClass *klass);
5.13 +static void gmyth_livetv_init (GMythLiveTV *object);
5.14 +
5.15 +static void gmyth_livetv_dispose (GObject *object);
5.16 +static void gmyth_livetv_finalize (GObject *object);
5.17 +
5.18 +static gint tvchain_curr_index = -1;
5.19 +
5.20 +G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT)
5.21 +
5.22 +static void
5.23 +gmyth_livetv_class_init (GMythLiveTVClass *klass)
5.24 +{
5.25 + GObjectClass *gobject_class;
5.26 +
5.27 + gobject_class = (GObjectClass *) klass;
5.28 +
5.29 + gobject_class->dispose = gmyth_livetv_dispose;
5.30 + gobject_class->finalize = gmyth_livetv_finalize;
5.31 +}
5.32 +
5.33 +static void
5.34 +gmyth_livetv_init (GMythLiveTV *livetv)
5.35 +{
5.36 + livetv->backend_hostname = NULL;
5.37 + livetv->backend_port = 0;
5.38 + livetv->local_hostname = NULL;
5.39 +
5.40 + livetv->remote_encoder = NULL;
5.41 + livetv->tvchain = NULL;
5.42 + livetv->proginfo = NULL;
5.43 +}
5.44 +
5.45 +static void
5.46 +gmyth_livetv_dispose (GObject *object)
5.47 +{
5.48 +
5.49 + G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object);
5.50 +}
5.51 +
5.52 +static void
5.53 +gmyth_livetv_finalize (GObject *object)
5.54 +{
5.55 + g_signal_handlers_destroy (object);
5.56 +
5.57 + GMythLiveTV *livetv = GMYTH_LIVETV (object);
5.58 +
5.59 + g_debug ("[%s] Finalizing livetv", __FUNCTION__);
5.60 +
5.61 + if ( livetv->remote_encoder != NULL ) {
5.62 + g_object_unref (livetv->remote_encoder);
5.63 + livetv->remote_encoder = NULL;
5.64 + }
5.65 +
5.66 + if ( livetv->tvchain != NULL ) {
5.67 + g_object_unref (livetv->tvchain);
5.68 + livetv->tvchain = NULL;
5.69 + }
5.70 +
5.71 + if ( livetv->proginfo != NULL ) {
5.72 + g_object_unref (livetv->proginfo);
5.73 + livetv->proginfo = NULL;
5.74 + }
5.75 +
5.76 + G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object );
5.77 +}
5.78 +
5.79 +GMythLiveTV*
5.80 +gmyth_livetv_new ()
5.81 +{
5.82 + GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) );
5.83 +
5.84 + return livetv;
5.85 +}
5.86 +
5.87 +gboolean
5.88 +gmyth_livetv_setup ( GMythLiveTV *livetv )
5.89 +{
5.90 + GMythSettings *msettings = gmyth_context_get_settings ();
5.91 + gboolean res = TRUE;
5.92 +
5.93 + livetv->is_livetv = TRUE;
5.94 +
5.95 + res = gmyth_context_check_connection();
5.96 + if (!res) {
5.97 + g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);
5.98 + res = FALSE;
5.99 + goto error;
5.100 + }
5.101 +
5.102 + livetv->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
5.103 + livetv->backend_port = gmyth_settings_get_backend_port (msettings);
5.104 +
5.105 + livetv->local_hostname = g_string_new("");
5.106 + gmyth_context_get_local_hostname (livetv->local_hostname);
5.107 +
5.108 + if ( livetv->local_hostname == NULL ) {
5.109 + res = FALSE;
5.110 + goto error;
5.111 + }
5.112 +
5.113 + // Gets the remote encoder num
5.114 + livetv->remote_encoder = remote_request_next_free_recorder (-1);
5.115 +
5.116 + if ( livetv->remote_encoder == NULL ) {
5.117 + g_warning ("[%s] None remote encoder available", __FUNCTION__);
5.118 + res = FALSE;
5.119 + goto error;
5.120 + }
5.121 +
5.122 + // Creates livetv chain handler
5.123 + livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
5.124 + gmyth_tvchain_initialize ( livetv->tvchain, livetv->local_hostname );
5.125 +
5.126 + if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
5.127 + res = FALSE;
5.128 + goto error;
5.129 + }
5.130 +
5.131 + // Init remote encoder. Opens its control socket.
5.132 + res = gmyth_remote_encoder_setup(livetv->remote_encoder);
5.133 + if ( !res ) {
5.134 + g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
5.135 + res = FALSE;
5.136 + goto error;
5.137 + }
5.138 + // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
5.139 + res = gmyth_remote_encoder_spawntv ( livetv->remote_encoder,
5.140 + gmyth_tvchain_get_id(livetv->tvchain) );
5.141 + if (!res) {
5.142 + g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
5.143 + res = FALSE;
5.144 + goto error;
5.145 + }
5.146 +
5.147 + // Reload all TV chain from Mysql database.
5.148 + gmyth_tvchain_reload_all (livetv->tvchain);
5.149 +
5.150 + if ( livetv->tvchain == NULL ) {
5.151 + res = FALSE;
5.152 + goto error;
5.153 + }
5.154 +
5.155 + // Get program info from database using chanid and starttime
5.156 + livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
5.157 + if ( livetv->proginfo == NULL ) {
5.158 + g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
5.159 + res = FALSE;
5.160 + goto error;
5.161 + } else {
5.162 + g_debug ("[%s] GMythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
5.163 + }
5.164 +
5.165 + return res;
5.166 +
5.167 +error:
5.168 + if ( livetv->backend_hostname != NULL ) {
5.169 + g_string_free( livetv->backend_hostname, TRUE );
5.170 + res = FALSE;
5.171 + }
5.172 +
5.173 + if ( livetv->local_hostname != NULL ) {
5.174 + g_string_free( livetv->local_hostname, TRUE );
5.175 + res = FALSE;
5.176 + }
5.177 +
5.178 + if ( livetv->remote_encoder != NULL ) {
5.179 + g_object_unref (livetv->remote_encoder);
5.180 + livetv->remote_encoder = NULL;
5.181 + }
5.182 +
5.183 + if ( livetv->tvchain != NULL ) {
5.184 + g_object_unref (livetv->tvchain);
5.185 + livetv->tvchain = NULL;
5.186 + }
5.187 +
5.188 + if ( livetv->proginfo != NULL ) {
5.189 + g_object_unref (livetv->proginfo);
5.190 + livetv->proginfo = NULL;
5.191 + }
5.192 +
5.193 + return res;
5.194 +
5.195 +}
5.196 +
5.197 +// FIXME: How to proceed differently between livetv and recorded content
5.198 +void
5.199 +gmyth_livetv_stop_playing (GMythLiveTV *livetv)
5.200 +{
5.201 + g_debug ("[%s] Stopping the LiveTV...\n", __FUNCTION__);
5.202 +
5.203 + if (livetv->is_livetv) {
5.204 + if (!gmyth_remote_encoder_stop_livetv (livetv->remote_encoder)) {
5.205 + g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);
5.206 + }
5.207 + }
5.208 +}
5.209 +
5.210 +gboolean
5.211 +gmyth_livetv_is_playing (GMythLiveTV *livetv)
5.212 +{
5.213 + return TRUE;
5.214 +}
5.215 +
5.216 +void
5.217 +gmyth_livetv_start_playing (GMythLiveTV *livetv)
5.218 +{
5.219 +
5.220 + // TODO
5.221 +
5.222 +}
5.223 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/gst-plugins-mythtv/src/gmyth_livetv.h Mon Oct 23 15:42:46 2006 +0100
6.3 @@ -0,0 +1,59 @@
6.4 +#ifndef GMYTH_LIVETV_H_
6.5 +#define GMYTH_LIVETV_H_
6.6 +
6.7 +#include <glib-object.h>
6.8 +
6.9 +#include <gmyth/gmyth_remote_encoder.h>
6.10 +#include <gmyth/gmyth_tvchain.h>
6.11 +#include <gmyth/gmyth_common.h>
6.12 +
6.13 +#include "gmyth_file_transfer.h"
6.14 +
6.15 +#define G_BEGIN_DECLS
6.16 +
6.17 +#define GMYTH_LIVETV_TYPE (gmyth_livetv_get_type ())
6.18 +#define GMYTH_LIVETV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_LIVETV_TYPE, GMythLiveTV))
6.19 +#define GMYTH_LIVETV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE, GMythLiveTVClass))
6.20 +#define IS_GMYTH_LIVETV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_LIVETV_TYPE))
6.21 +#define IS_GMYTH_LIVETV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE))
6.22 +#define GMYTH_LIVETV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_LIVETV_TYPE, GMythLiveTVClass))
6.23 +
6.24 +typedef struct _GMythLiveTV GMythLiveTV;
6.25 +typedef struct _GMythLiveTVClass GMythLiveTVClass;
6.26 +
6.27 +struct _GMythLiveTVClass
6.28 +{
6.29 + GObjectClass parent_class;
6.30 +
6.31 + /* callbacks */
6.32 +};
6.33 +
6.34 +struct _GMythLiveTV
6.35 +{
6.36 + GObject parent;
6.37 +
6.38 + // Backend connection related variables
6.39 + GString *backend_hostname;
6.40 + gint backend_port;
6.41 + GString *local_hostname;
6.42 +
6.43 + GMythRemoteEncoder *remote_encoder;
6.44 + GMythTVChain *tvchain;
6.45 + GMythProgramInfo *proginfo;
6.46 +
6.47 + gboolean is_livetv;
6.48 +
6.49 +};
6.50 +
6.51 +GType gmyth_livetv_get_type (void);
6.52 +
6.53 +GMythLiveTV* gmyth_livetv_new ();
6.54 +
6.55 +void gmyth_livetv_start_playing (GMythLiveTV *livetv);
6.56 +void gmyth_livetv_stop_playing (GMythLiveTV *livetv);
6.57 +
6.58 +gboolean gmyth_livetv_setup (GMythLiveTV *livetv);
6.59 +
6.60 +#define G_END_DECLS
6.61 +
6.62 +#endif /*GMYTH_LIVETV_H_*/
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/gst-plugins-mythtv/src/gmyth_uri.c Mon Oct 23 15:42:46 2006 +0100
7.3 @@ -0,0 +1,208 @@
7.4 +/**
7.5 + *
7.6 + * GMythURI utils
7.7 + * - Extracts and parses a URI char string, in according with the RFC 2396
7.8 + * [http://www.ietf.org/rfc/rfc2396.txt]
7.9 + *
7.10 + * @author Rosfran Borges (rosfran.borges@indt.org.br)
7.11 + *
7.12 + */
7.13 +
7.14 +#include "gmyth_uri.h"
7.15 +#include <glib.h>
7.16 +#include <string.h>
7.17 +#include <stdlib.h>
7.18 +
7.19 +static gint
7.20 +gmyth_strstr( const gchar *haystack, const gchar *needle )
7.21 +{
7.22 +
7.23 + gchar *strPos;
7.24 +
7.25 + if (haystack == NULL || needle == NULL)
7.26 + return -1;
7.27 + strPos = strstr(haystack, needle);
7.28 + if (strPos == NULL)
7.29 + return -1;
7.30 +
7.31 + return (strPos - haystack);
7.32 +
7.33 +}
7.34 +
7.35 +static gboolean
7.36 +gmyth_uri_isabsolute( const GMythURI *uri )
7.37 +{
7.38 + gboolean ret = FALSE;
7.39 +
7.40 + g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE );
7.41 +
7.42 + if ( gmyth_strstr( uri->uri->str, GMYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 )
7.43 + ret = TRUE;
7.44 +
7.45 + return ret;
7.46 +}
7.47 +
7.48 +static gint
7.49 +gmyth_strrchr( const gchar *str, const gchar *chars, const gint nchars )
7.50 +{
7.51 +
7.52 + gint strLen;
7.53 + gint i, j;
7.54 +
7.55 + if ( str == NULL || chars == NULL )
7.56 + return -1;
7.57 +
7.58 + strLen = strlen( str );
7.59 + for ( i= (strLen-1); 0 <= i; i-- ) {
7.60 + for ( j=0; j<nchars; j++ ) {
7.61 + if ( str[i] == chars[j] )
7.62 + return i;
7.63 + }
7.64 + }
7.65 +
7.66 + return -1;
7.67 +
7.68 +}
7.69 +
7.70 +static GMythURI *
7.71 +gmyth_uri_init( )
7.72 +{
7.73 + GMythURI *uri = g_new0( GMythURI, 1 );
7.74 + uri->host = g_string_new("");
7.75 + uri->fragment = g_string_new("");
7.76 + uri->password = g_string_new("");
7.77 + uri->path = g_string_new("");
7.78 + uri->protocol = g_string_new("");
7.79 + uri->query = g_string_new("");
7.80 + uri->uri = g_string_new("");
7.81 + uri->user = g_string_new("");
7.82 + return uri;
7.83 +}
7.84 +
7.85 +const GMythURI *
7.86 +gmyth_uri_new( gchar *value )
7.87 +{
7.88 +
7.89 + GMythURI *uri = gmyth_uri_init();
7.90 +
7.91 + gchar *protocol;
7.92 + gint uriLen;
7.93 + gint currIdx;
7.94 + gint protoIdx;
7.95 + gint atIdx;
7.96 + gint colonIdx;
7.97 + gint shashIdx;
7.98 + gchar *host;
7.99 + gint eblacketIdx;
7.100 + GString *hostStr;
7.101 + GString *portStr;
7.102 + gint hostLen;
7.103 + gint sharpIdx;
7.104 + gint questionIdx;
7.105 + gint queryLen;
7.106 +
7.107 + uriLen = strlen(value);
7.108 + uri->uri = g_string_new( value );
7.109 +
7.110 + currIdx = 0;
7.111 +
7.112 + /*** Protocol ****/
7.113 + protoIdx = gmyth_strstr( value, GMYTH_URI_PROTOCOL_DELIM );
7.114 + if (0 < protoIdx) {
7.115 + uri->protocol = g_string_append_len( uri->protocol, value, protoIdx );
7.116 + currIdx += protoIdx + strlen( GMYTH_URI_PROTOCOL_DELIM );
7.117 + }
7.118 +
7.119 + /*** User (Password) ****/
7.120 + atIdx = gmyth_strstr( value+currIdx, GMYTH_URI_USER_DELIM );
7.121 + if ( 0 < atIdx ) {
7.122 + colonIdx = gmyth_strstr( value+currIdx, GMYTH_URI_COLON_DELIM );
7.123 +
7.124 + if (0 < colonIdx && colonIdx < atIdx) {
7.125 + uri->user = g_string_append_len( uri->user, value+currIdx, colonIdx );
7.126 + uri->password = g_string_append_len( uri->password, value+currIdx+colonIdx+1, atIdx-(colonIdx+1) );
7.127 + }
7.128 + else
7.129 + uri->user = g_string_append_len( uri->user, value+currIdx, atIdx - currIdx );
7.130 + currIdx += atIdx + 1;
7.131 + }
7.132 +
7.133 + /*** Host (Port) ****/
7.134 + shashIdx = gmyth_strstr( value+currIdx, GMYTH_URI_SLASH_DELIM );
7.135 + if ( 0 < shashIdx )
7.136 + uri->host = g_string_append_len( uri->host, value+currIdx, shashIdx );
7.137 + else if ( gmyth_uri_isabsolute(uri) == TRUE )
7.138 + uri->host = g_string_append_len( uri->host, value+currIdx, strlen(value) - currIdx );
7.139 + host = g_strdup( gmyth_uri_gethost(uri) );
7.140 + colonIdx = gmyth_strrchr( host, GMYTH_URI_COLON_DELIM, 1 );
7.141 + eblacketIdx = gmyth_strrchr( host, GMYTH_URI_EBLACET_DELIM, 1 );
7.142 + if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) {
7.143 + hostStr = g_string_new( host );
7.144 +
7.145 + hostLen = hostStr->len;
7.146 + /**** host ****/
7.147 + uri->host = g_string_erase( uri->host, 0, hostLen );
7.148 + uri->host = g_string_insert_len( uri->host, 0, hostStr->str, colonIdx );
7.149 + //host = gmyth_uri_gethost( uri );
7.150 + if (0 < hostLen) {
7.151 + if (host[0] == '[' && host[hostLen-1] == ']')
7.152 + uri->host = g_string_append_len( uri->host, hostStr->str+1, colonIdx-2 );
7.153 + }
7.154 + /**** port ****/
7.155 + portStr = g_string_new("");
7.156 + portStr = g_string_append_len( portStr, hostStr->str+colonIdx+1, hostLen-colonIdx-1 );
7.157 + uri->port = atoi( portStr->str );
7.158 + g_string_free( portStr, TRUE );
7.159 + g_string_free( hostStr, FALSE );
7.160 + }
7.161 + else {
7.162 + uri->port = GMYTH_URI_KNKOWN_PORT;
7.163 + protocol = gmyth_uri_getprotocol(uri);
7.164 + if ( strcmp(protocol, GMYTH_URI_PROTOCOL_HTTP) == 0 )
7.165 + uri->port = GMYTH_URI_DEFAULT_HTTP_PORT;
7.166 + if ( strcmp(protocol, GMYTH_URI_PROTOCOL_FTP) == 0 )
7.167 + uri->port = GMYTH_URI_DEFAULT_FTP_PORT;
7.168 + }
7.169 +
7.170 + if (shashIdx > 0) currIdx += shashIdx;
7.171 +
7.172 + /*
7.173 + Handle relative URL
7.174 + */
7.175 + if (gmyth_uri_isabsolute(uri) == FALSE)
7.176 + {
7.177 +
7.178 + if (shashIdx != 0)
7.179 + {
7.180 + /* Add slash delimiter at the beginning of the URL,
7.181 + if it doesn't exist
7.182 + */
7.183 + uri->path = g_string_new( GMYTH_URI_SLASH_DELIM );
7.184 + }
7.185 + uri->path = g_string_append( uri->path, value );
7.186 +
7.187 + } else {
7.188 + /* First set path simply to the rest of URI */
7.189 + g_string_append_len( uri->path, value+currIdx, uriLen-currIdx );
7.190 + }
7.191 +
7.192 + /**** Path (Query/Fragment) ****/
7.193 + sharpIdx = gmyth_strstr(value+currIdx, GMYTH_URI_SHARP_DELIM);
7.194 + if (0 < sharpIdx) {
7.195 + uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx);
7.196 + uri->fragment = g_string_append_len( uri->fragment,
7.197 + value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1));
7.198 + }
7.199 +
7.200 + questionIdx = gmyth_strstr( value+currIdx, GMYTH_URI_QUESTION_DELIM );
7.201 + if ( 0 < questionIdx ) {
7.202 + uri->path = g_string_append_len( uri->path, value+currIdx, questionIdx );
7.203 + queryLen = uriLen-(currIdx+questionIdx+1);
7.204 + if ( 0 < sharpIdx )
7.205 + queryLen -= uriLen - (currIdx+sharpIdx+1);
7.206 + uri->query = g_string_append_len( uri->query, value+currIdx+questionIdx+1, queryLen );
7.207 + }
7.208 +
7.209 + return uri;
7.210 +
7.211 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/gst-plugins-mythtv/src/gmyth_uri.h Mon Oct 23 15:42:46 2006 +0100
8.3 @@ -0,0 +1,63 @@
8.4 +/**
8.5 + *
8.6 + * GMythURI utils
8.7 + * - Extracts and parses a URI char string, in according with the RFC 2396
8.8 + * [http://www.ietf.org/rfc/rfc2396.txt]
8.9 + *
8.10 + * @author Rosfran Borges (rosfran.borges@indt.org.br)
8.11 + *
8.12 + */
8.13 +
8.14 +#ifndef _GMYTH_URI_H_
8.15 +#define _GMYTH_URI_H_
8.16 +
8.17 +#include <glib.h>
8.18 +
8.19 +/****************************************
8.20 +* Define
8.21 +****************************************/
8.22 +
8.23 +#define GMYTH_URI_KNKOWN_PORT (-1)
8.24 +#define GMYTH_URI_DEFAULT_HTTP_PORT 80
8.25 +#define GMYTH_URI_DEFAULT_FTP_PORT 21
8.26 +#define GMYTH_URI_DEFAULT_PATH "/"
8.27 +#define GMYTH_URI_MAXLEN 256
8.28 +
8.29 +#define GMYTH_URI_PROTOCOL_DELIM "://"
8.30 +#define GMYTH_URI_USER_DELIM "@"
8.31 +#define GMYTH_URI_COLON_DELIM ":"
8.32 +#define GMYTH_URI_SLASH_DELIM "/"
8.33 +#define GMYTH_URI_SBLACET_DELIM "["
8.34 +#define GMYTH_URI_EBLACET_DELIM "]"
8.35 +#define GMYTH_URI_SHARP_DELIM "#"
8.36 +#define GMYTH_URI_QUESTION_DELIM "?"
8.37 +#define GMYTH_URI_ESCAPING_CHAR "%"
8.38 +
8.39 +#define GMYTH_URI_PROTOCOL_MYTH "myth"
8.40 +#define GMYTH_URI_PROTOCOL_HTTP "http"
8.41 +#define GMYTH_URI_PROTOCOL_FTP "ftp"
8.42 +
8.43 +/****************************************
8.44 +* Data Type
8.45 +****************************************/
8.46 +
8.47 +typedef struct _GMythURI {
8.48 + GString *uri;
8.49 + GString *host;
8.50 + gint port;
8.51 + GString *protocol;
8.52 + GString *path;
8.53 + GString *fragment;
8.54 + GString *user;
8.55 + GString *password;
8.56 + GString *query;
8.57 +} GMythURI;
8.58 +
8.59 +const GMythURI *gmyth_uri_new( gchar *value );
8.60 +
8.61 +#define gmyth_uri_gethost(urip) (urip->host->str)
8.62 +#define gmyth_uri_getport(urip) (urip->port)
8.63 +#define gmyth_uri_getprotocol(urip) (urip->protocol->str)
8.64 +#define gmyth_uri_getpath(urip) (urip->path->str)
8.65 +
8.66 +#endif
9.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.c Mon Oct 23 14:43:18 2006 +0100
9.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c Mon Oct 23 15:42:46 2006 +0100
9.3 @@ -18,8 +18,8 @@
9.4 #endif
9.5
9.6 #include "gstmythtvsrc.h"
9.7 -#include "myth_file_transfer.h"
9.8 -#include "myth_livetv.h"
9.9 +#include "gmyth_file_transfer.h"
9.10 +#include "gmyth_livetv.h"
9.11
9.12 #include <gmyth/gmyth_socket.h>
9.13 #include <gmyth/gmyth_tvchain.h>
9.14 @@ -30,13 +30,13 @@
9.15 GST_DEBUG_CATEGORY_STATIC (mythtvsrc_debug);
9.16 #define GST_CAT_DEFAULT mythtvsrc_debug
9.17
9.18 -#define GST_MYTHTV_ID_NUM 1
9.19 +#define GST_GMYTHTV_ID_NUM 1
9.20
9.21 -#define MYTHTV_VERSION_DEFAULT 30
9.22 +#define GMYTHTV_VERSION_DEFAULT 30
9.23
9.24 -#define MYTHTV_TRANSFER_MAX_WAITS 100
9.25 +#define GMYTHTV_TRANSFER_MAX_WAITS 100
9.26
9.27 -#define MYTHTV_TRANSFER_MAX_BUFFER 1024*1024
9.28 +#define GMYTHTV_TRANSFER_MAX_BUFFER 1024*1024
9.29 //( 32*1024 )
9.30
9.31 /* 4*1024 ??? */
9.32 @@ -70,12 +70,12 @@
9.33 PROP_LOCATION,
9.34 PROP_URI,
9.35 #ifndef GST_DISABLE_GST_DEBUG
9.36 - PROP_MYTHTV_DBG,
9.37 + PROP_GMYTHTV_DBG,
9.38 #endif
9.39 - PROP_MYTHTV_VERSION,
9.40 - PROP_MYTHTV_LIVE,
9.41 - PROP_MYTHTV_LIVEID,
9.42 - PROP_MYTHTV_LIVE_CHAINID
9.43 + PROP_GMYTHTV_VERSION,
9.44 + PROP_GMYTHTV_LIVE,
9.45 + PROP_GMYTHTV_LIVEID,
9.46 + PROP_GMYTHTV_LIVE_CHAINID
9.47 };
9.48
9.49 static void gst_mythtv_src_finalize (GObject * gobject);
9.50 @@ -168,32 +168,32 @@
9.51 "", G_PARAM_READWRITE));
9.52
9.53 g_object_class_install_property
9.54 - (gobject_class, PROP_MYTHTV_VERSION,
9.55 + (gobject_class, PROP_GMYTHTV_VERSION,
9.56 g_param_spec_int ("mythtv-version", "mythtv-version",
9.57 "Change Myth TV version",
9.58 26, 30, 26, G_PARAM_READWRITE));
9.59
9.60 g_object_class_install_property
9.61 - (gobject_class, PROP_MYTHTV_LIVEID,
9.62 + (gobject_class, PROP_GMYTHTV_LIVEID,
9.63 g_param_spec_int ("mythtv-live-id", "mythtv-live-id",
9.64 "Change Myth TV version",
9.65 - 0, 200, GST_MYTHTV_ID_NUM, G_PARAM_READWRITE));
9.66 + 0, 200, GST_GMYTHTV_ID_NUM, G_PARAM_READWRITE));
9.67
9.68 g_object_class_install_property
9.69 - (gobject_class, PROP_MYTHTV_LIVE_CHAINID,
9.70 + (gobject_class, PROP_GMYTHTV_LIVE_CHAINID,
9.71 g_param_spec_string ("mythtv-live-chainid", "mythtv-live-chainid",
9.72 "Sets the Myth TV chain ID (from TV Chain)",
9.73 "", G_PARAM_READWRITE));
9.74
9.75 g_object_class_install_property
9.76 - (gobject_class, PROP_MYTHTV_LIVE,
9.77 + (gobject_class, PROP_GMYTHTV_LIVE,
9.78 g_param_spec_boolean ("mythtv-live", "mythtv-live",
9.79 "Enable MythTV Live TV content streaming",
9.80 FALSE, G_PARAM_READWRITE));
9.81
9.82 #ifndef GST_DISABLE_GST_DEBUG
9.83 g_object_class_install_property
9.84 - (gobject_class, PROP_MYTHTV_DBG,
9.85 + (gobject_class, PROP_GMYTHTV_DBG,
9.86 g_param_spec_boolean ("mythtv-debug", "mythtv-debug",
9.87 "Enable MythTV debug messages",
9.88 FALSE, G_PARAM_READWRITE));
9.89 @@ -218,7 +218,7 @@
9.90
9.91 this->unique_setup = FALSE;
9.92
9.93 - this->mythtv_version = MYTHTV_VERSION_DEFAULT;
9.94 + this->mythtv_version = GMYTHTV_VERSION_DEFAULT;
9.95
9.96 this->bytes_read = 0;
9.97
9.98 @@ -293,7 +293,7 @@
9.99
9.100 while ( sizetoread > 0 ) {
9.101
9.102 - len = myth_file_transfer_read( src->file_transfer,
9.103 + len = gmyth_file_transfer_read( src->file_transfer,
9.104 GST_BUFFER_DATA( *outbuf ) + read, sizetoread, TRUE );
9.105
9.106 if ( len > 0 ) {
9.107 @@ -305,25 +305,29 @@
9.108 goto done;
9.109 } else if ( /*src->content_size >= src->read_offset &&
9.110 abs ( src->content_size - src->read_offset ) <= 1024 ) ||*/
9.111 - ( src->content_size <= ( src->read_offset + size + MYTHTV_TRANSFER_MAX_BUFFER ) ) )
9.112 + ( src->content_size <= ( src->read_offset + size + GMYTHTV_TRANSFER_MAX_BUFFER ) ) )
9.113 {
9.114 #if ENABLE_TIMING_POSITION == 1
9.115 - guint64 size_tmp = 0;
9.116 + gint64 size_tmp = 0;
9.117 if (src->live_tv == TRUE) {
9.118 get_file_pos:
9.119 - size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
9.120 - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
9.121 + size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
9.122 + if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
9.123 src->content_size = size_tmp;
9.124 - else
9.125 + else if ( size_tmp > 0 )
9.126 goto get_file_pos;
9.127 - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
9.128 + g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
9.129 __FUNCTION__, size_tmp );
9.130 }
9.131 #else
9.132 - guint64 new_offset = myth_file_transfer_get_file_position( src->file_transfer );
9.133 - if ( src->content_size < new_offset ) {
9.134 - src->content_size = new_offset;
9.135 - }
9.136 + gint64 new_offset = gmyth_file_transfer_get_file_position( src->file_transfer );
9.137 + if ( new_offset > 0 ) {
9.138 + if ( src->content_size < new_offset ) {
9.139 + src->content_size = new_offset;
9.140 + }
9.141 + } else {
9.142 + src->update_prog_chain = TRUE;
9.143 + }
9.144 #endif
9.145 goto done;
9.146 }
9.147 @@ -377,17 +381,19 @@
9.148 /* The caller should know the number of bytes and not read beyond EOS. */
9.149 if (G_UNLIKELY (src->eos))
9.150 goto eos;
9.151 + if ( G_UNLIKELY (src->update_prog_chain) )
9.152 + goto change_progchain;
9.153
9.154 //GST_OBJECT_LOCK(src);
9.155
9.156 if (G_UNLIKELY (src->read_offset != offset)) {
9.157 - guint64 new_offset = myth_file_transfer_seek(src->file_transfer, offset, SEEK_SET);
9.158 - g_print( "[%s] SRC Offset = %llu, NEW actual backend SEEK Offset = %llu.\n",
9.159 + gint64 new_offset = gmyth_file_transfer_seek(src->file_transfer, offset, SEEK_SET);
9.160 + g_print( "[%s] SRC Offset = %lld, NEW actual backend SEEK Offset = %lld.\n",
9.161 __FUNCTION__, src->read_offset, new_offset );
9.162 if (G_UNLIKELY (new_offset < 0 ) )//|| new_offset != src->read_offset)) {
9.163 {
9.164 //GST_OBJECT_UNLOCK(src);
9.165 - goto seek_failed;
9.166 + goto change_progchain;
9.167 }
9.168
9.169 src->read_offset = offset;
9.170 @@ -407,6 +413,9 @@
9.171 read = do_read_request_response ( src, src->read_offset, size, outbuf );
9.172 //g_static_mutex_unlock( &update_size_mutex );
9.173
9.174 + if (G_UNLIKELY (src->update_prog_chain) )
9.175 + goto change_progchain;
9.176 +
9.177 if (G_UNLIKELY (read < 0) || *outbuf == NULL) {
9.178 //if ( src->live_tv )
9.179 // goto done;
9.180 @@ -443,7 +452,7 @@
9.181 src->uri_name));
9.182 return GST_FLOW_ERROR;
9.183 }
9.184 -seek_failed:
9.185 +change_progchain:
9.186 {
9.187 GST_ELEMENT_ERROR (src, RESOURCE, READ,
9.188 (NULL), ("Seek failed, go to the next program info... (%i, %s)", read,
9.189 @@ -470,16 +479,16 @@
9.190
9.191 if ( src->do_start ) {
9.192 #if ENABLE_TIMING_POSITION == 1
9.193 - guint64 size_tmp = 0;
9.194 + gint64 size_tmp = 0;
9.195 if (src->live_tv == TRUE) {
9.196 get_file_pos:
9.197 g_usleep( 50 );
9.198 - size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
9.199 - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
9.200 + size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
9.201 + if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
9.202 src->content_size = size_tmp;
9.203 - else
9.204 + else if ( size_tmp > 0 )
9.205 goto get_file_pos;
9.206 - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
9.207 + g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
9.208 __FUNCTION__, size_tmp );
9.209 }
9.210 #endif
9.211 @@ -494,16 +503,16 @@
9.212
9.213 if ( src->do_start ) {
9.214 #if ENABLE_TIMING_POSITION == 1
9.215 - guint64 size_tmp = 0;
9.216 + gint64 size_tmp = 0;
9.217 if (src->live_tv == TRUE) {
9.218 get_file_pos:
9.219 g_usleep( 50 );
9.220 - size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
9.221 - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
9.222 + size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
9.223 + if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
9.224 src->content_size = size_tmp;
9.225 - else
9.226 + else if ( size_tmp > 0 )
9.227 goto get_file_pos;
9.228 - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
9.229 + g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
9.230 __FUNCTION__, size_tmp );
9.231 }
9.232 #endif
9.233 @@ -532,8 +541,8 @@
9.234 GST_OBJECT_LOCK(src);
9.235
9.236 if ( src->live_tv ) {
9.237 - src->spawn_livetv = myth_livetv_new( );
9.238 - if ( myth_livetv_setup( src->spawn_livetv ) == FALSE ) {
9.239 + src->spawn_livetv = gmyth_livetv_new( );
9.240 + if ( gmyth_livetv_setup( src->spawn_livetv ) == FALSE ) {
9.241 ret = FALSE;
9.242 goto init_failed;
9.243 }
9.244 @@ -548,7 +557,7 @@
9.245 g_print ( "[%s] LiveTV id = %d, URI path = %s.\n", __FUNCTION__, src->live_tv_id, src->uri_name );
9.246 }
9.247
9.248 - src->file_transfer = myth_file_transfer_new( src->live_tv_id,
9.249 + src->file_transfer = gmyth_file_transfer_new( src->live_tv_id,
9.250 g_string_new( src->uri_name ), -1, src->mythtv_version );
9.251
9.252 if ( src->file_transfer == NULL ) {
9.253 @@ -558,19 +567,19 @@
9.254 }
9.255
9.256 /* sets the Playback monitor connection */
9.257 - ret = myth_file_transfer_playback_setup( &(src->file_transfer), src->live_tv );
9.258 + ret = gmyth_file_transfer_playback_setup( &(src->file_transfer), src->live_tv );
9.259
9.260 if ( src->live_tv == TRUE && ret == TRUE ) {
9.261 /* loop finished, set the max tries variable to zero again... */
9.262 wait_to_transfer = 0;
9.263
9.264 - while ( wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS && ( myth_file_transfer_is_recording( src->file_transfer ) == FALSE
9.265 - /*|| ( myth_file_transfer_get_file_position( src->file_transfer ) < ( src->content_size + 327680 ) )*/ ) )
9.266 + while ( wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS && ( gmyth_file_transfer_is_recording( src->file_transfer ) == FALSE
9.267 + /*|| ( gmyth_file_transfer_get_file_position( src->file_transfer ) < ( src->content_size + 327680 ) )*/ ) )
9.268 g_usleep( 100 );
9.269 }
9.270
9.271 /* sets the FileTransfer instance connection (video/audio download) */
9.272 - ret = myth_file_transfer_setup( &(src->file_transfer), src->live_tv );
9.273 + ret = gmyth_file_transfer_setup( &(src->file_transfer), src->live_tv );
9.274
9.275 if ( ret == FALSE ) {
9.276 GST_OBJECT_UNLOCK(src);
9.277 @@ -624,7 +633,7 @@
9.278
9.279 guint64 size = 0;
9.280
9.281 - mythtv = GST_MYTHTV_SRC( GST_PAD_PARENT (pad) );
9.282 + mythtv = GST_GMYTHTV_SRC( GST_PAD_PARENT (pad) );
9.283
9.284 size = gst_mythtv_src_get_position (mythtv);
9.285
9.286 @@ -690,26 +699,31 @@
9.287
9.288 if (src->content_size <= 0) {
9.289 ret= FALSE;
9.290 - } else if ( abs ( src->content_size - src->read_offset ) <= MYTHTV_TRANSFER_MAX_BUFFER ) {
9.291 + } else if ( abs ( src->content_size - src->read_offset ) <= GMYTHTV_TRANSFER_MAX_BUFFER ) {
9.292 //g_static_mutex_lock( &update_size_mutex );
9.293 GST_OBJECT_LOCK(src);
9.294
9.295 - guint64 new_offset = myth_file_transfer_get_file_position( src->file_transfer );
9.296 - if ( src->content_size < new_offset ) {
9.297 - src->content_size = new_offset;
9.298 - }
9.299 + gint64 new_offset = gmyth_file_transfer_get_file_position( src->file_transfer );
9.300 + if ( new_offset > 0 ) {
9.301 + if ( src->content_size < new_offset ) {
9.302 + src->content_size = new_offset;
9.303 + }
9.304 + } else {
9.305 + src->update_prog_chain = TRUE;
9.306 + src->content_size = 0;
9.307 + }
9.308
9.309 #if ENABLE_TIMING_POSITION == 1
9.310 - guint64 size_tmp = 0;
9.311 + gint64 size_tmp = 0;
9.312 if (src->live_tv == TRUE) {
9.313 get_file_pos:
9.314 g_usleep( 5 );
9.315 - size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
9.316 - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
9.317 + size_tmp = gmyth_file_transfer_get_file_position( src->file_transfer );
9.318 + if ( size_tmp > ( src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER ) )
9.319 src->content_size = size_tmp;
9.320 - else
9.321 + else if ( size_tmp > 0 )
9.322 goto get_file_pos;
9.323 - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
9.324 + g_print( "\t[%s]\tGET_POSITION: file_position = %lld\n",
9.325 __FUNCTION__, size_tmp );
9.326 }
9.327 #endif
9.328 @@ -849,28 +863,28 @@
9.329 break;
9.330 }
9.331 #ifndef GST_DISABLE_GST_DEBUG
9.332 - case PROP_MYTHTV_DBG:
9.333 + case PROP_GMYTHTV_DBG:
9.334 {
9.335 mythtvsrc->mythtv_msgs_dbg = g_value_get_boolean (value);
9.336 break;
9.337 }
9.338 #endif
9.339 - case PROP_MYTHTV_VERSION:
9.340 + case PROP_GMYTHTV_VERSION:
9.341 {
9.342 mythtvsrc->mythtv_version = g_value_get_int (value);
9.343 break;
9.344 }
9.345 - case PROP_MYTHTV_LIVEID:
9.346 + case PROP_GMYTHTV_LIVEID:
9.347 {
9.348 mythtvsrc->live_tv_id = g_value_get_int (value);
9.349 break;
9.350 }
9.351 - case PROP_MYTHTV_LIVE:
9.352 + case PROP_GMYTHTV_LIVE:
9.353 {
9.354 mythtvsrc->live_tv = g_value_get_boolean (value);
9.355 break;
9.356 }
9.357 - case PROP_MYTHTV_LIVE_CHAINID:
9.358 + case PROP_GMYTHTV_LIVE_CHAINID:
9.359 {
9.360 if (!g_value_get_string (value)) {
9.361 GST_WARNING ("MythTV Live chainid property cannot be NULL");
9.362 @@ -918,24 +932,24 @@
9.363 break;
9.364 }
9.365 #ifndef GST_DISABLE_GST_DEBUG
9.366 - case PROP_MYTHTV_DBG:
9.367 + case PROP_GMYTHTV_DBG:
9.368 g_value_set_boolean ( value, mythtvsrc->mythtv_msgs_dbg );
9.369 break;
9.370 #endif
9.371 - case PROP_MYTHTV_VERSION:
9.372 + case PROP_GMYTHTV_VERSION:
9.373 {
9.374 g_value_set_int ( value, mythtvsrc->mythtv_version );
9.375 break;
9.376 }
9.377 - case PROP_MYTHTV_LIVEID:
9.378 + case PROP_GMYTHTV_LIVEID:
9.379 {
9.380 g_value_set_int ( value, mythtvsrc->live_tv_id );
9.381 break;
9.382 }
9.383 - case PROP_MYTHTV_LIVE:
9.384 + case PROP_GMYTHTV_LIVE:
9.385 g_value_set_boolean ( value, mythtvsrc->live_tv );
9.386 break;
9.387 - case PROP_MYTHTV_LIVE_CHAINID:
9.388 + case PROP_GMYTHTV_LIVE_CHAINID:
9.389 {
9.390 gchar *str = g_strdup( "" );
9.391
9.392 @@ -960,7 +974,7 @@
9.393 * register the element factories and pad templates
9.394 * register the features
9.395 */
9.396 - static gboolean
9.397 +static gboolean
9.398 plugin_init (GstPlugin * plugin)
9.399 {
9.400 return gst_element_register (plugin, "mythtvsrc", GST_RANK_NONE,
10.1 --- a/gst-plugins-mythtv/src/gstmythtvsrc.h Mon Oct 23 14:43:18 2006 +0100
10.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.h Mon Oct 23 15:42:46 2006 +0100
10.3 @@ -21,8 +21,8 @@
10.4 #include <stdio.h>
10.5
10.6 #include <gmyth/gmyth_socket.h>
10.7 -#include "myth_file_transfer.h"
10.8 -#include "myth_livetv.h"
10.9 +#include "gmyth_file_transfer.h"
10.10 +#include "gmyth_livetv.h"
10.11
10.12 G_BEGIN_DECLS
10.13
10.14 @@ -44,9 +44,9 @@
10.15 GstBaseSrc element;
10.16
10.17 /* MythFileTransfer */
10.18 - MythFileTransfer *file_transfer;
10.19 + GMythFileTransfer *file_transfer;
10.20
10.21 - MythLiveTV *spawn_livetv;
10.22 + GMythLiveTV *spawn_livetv;
10.23
10.24 gchar *uri_name;
10.25 gchar *user_agent;
10.26 @@ -76,6 +76,8 @@
10.27
10.28 /* enable Myth TV debug messages */
10.29 gboolean mythtv_msgs_dbg;
10.30 +
10.31 + gboolean update_prog_chain;
10.32 };
10.33
10.34 struct _GstMythtvSrcClass {
11.1 --- a/gst-plugins-mythtv/src/myth_file_transfer.c Mon Oct 23 14:43:18 2006 +0100
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,1050 +0,0 @@
11.4 -/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
11.5 -/**
11.6 - * GStreamer plug-in properties:
11.7 - * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
11.8 - * - path (qurl - remote file to be opened)
11.9 - * - port number
11.10 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
11.11 - */
11.12 -
11.13 -#include "myth_file_transfer.h"
11.14 -#include "myth_uri.h"
11.15 -#include "myth_livetv.h"
11.16 -#include <gmyth/gmyth_util.h>
11.17 -#include <gmyth/gmyth_socket.h>
11.18 -#include <gmyth/gmyth_stringlist.h>
11.19 -
11.20 -#include <unistd.h>
11.21 -#include <glib.h>
11.22 -
11.23 -#include <arpa/inet.h>
11.24 -#include <sys/types.h>
11.25 -#include <sys/socket.h>
11.26 -#include <netdb.h>
11.27 -#include <errno.h>
11.28 -#include <stdlib.h>
11.29 -
11.30 -#define MYTHTV_QUERY_HEADER "QUERY_FILETRANSFER"
11.31 -#define MYTHTV_RECORDER_HEADER "QUERY_RECORDER"
11.32 -
11.33 -/* default values to the file transfer parameters */
11.34 -#define MYTHTV_USER_READ_AHEAD FALSE
11.35 -#define MYTHTV_RETRIES 1
11.36 -#define MYTHTV_FILE_SIZE -1
11.37 -
11.38 -#define MYTHTV_BUFFER_SIZE 8*1024
11.39 -
11.40 -#define MYTHTV_VERSION 30
11.41 -
11.42 -#define MYTHTV_TRANSFER_MAX_WAITS 700
11.43 -
11.44 -#ifdef MYTHTV_ENABLE_DEBUG
11.45 -#define MYTHTV_ENABLE_DEBUG 1
11.46 -#else
11.47 -#undef MYTHTV_ENABLE_DEBUG
11.48 -#endif
11.49 -
11.50 -/* this NDEBUG is to maintain compatibility with GMyth library */
11.51 -#ifndef NDEBUG
11.52 -#define MYTHTV_ENABLE_DEBUG 1
11.53 -#endif
11.54 -
11.55 -static guint wait_to_transfer = 0;
11.56 -
11.57 -enum myth_sock_types {
11.58 - MYTH_PLAYBACK_TYPE = 0,
11.59 - MYTH_MONITOR_TYPE,
11.60 - MYTH_FILETRANSFER_TYPE,
11.61 - MYTH_RINGBUFFER_TYPE
11.62 -};
11.63 -
11.64 -static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
11.65 -
11.66 -static GMainContext *io_watcher_context = NULL;
11.67 -
11.68 -static void myth_file_transfer_class_init (MythFileTransferClass *klass);
11.69 -static void myth_file_transfer_init (MythFileTransfer *object);
11.70 -
11.71 -static void myth_file_transfer_dispose (GObject *object);
11.72 -static void myth_file_transfer_finalize (GObject *object);
11.73 -
11.74 -static GMythSocket *myth_connect_to_transfer_backend( MythFileTransfer **transfer, guint sock_type );
11.75 -static void* myth_init_io_watchers( void *data );
11.76 -
11.77 -void myth_file_transfer_close( MythFileTransfer *transfer );
11.78 -
11.79 -G_DEFINE_TYPE(MythFileTransfer, myth_file_transfer, G_TYPE_OBJECT)
11.80 -
11.81 -#if 0
11.82 -static guint64
11.83 -mmyth_util_decode_long_long( GMythStringList *strlist, guint offset )
11.84 -{
11.85 -
11.86 - guint64 ret_value = 0LL;
11.87 -
11.88 - g_return_val_if_fail( strlist != NULL, ret_value );
11.89 -
11.90 - if ( offset < gmyth_string_list_length( strlist ))
11.91 - g_printerr( "[%s] Offset is lower than the GMythStringList (offset = %d)!\n", __FUNCTION__, offset );
11.92 - g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
11.93 -
11.94 - gint l1 = gmyth_string_list_get_int( strlist, offset );
11.95 - gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
11.96 -
11.97 - ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
11.98 -
11.99 - return ret_value;
11.100 -
11.101 -}
11.102 -#endif
11.103 -
11.104 -static void
11.105 -myth_file_transfer_class_init (MythFileTransferClass *klass)
11.106 -{
11.107 - GObjectClass *gobject_class;
11.108 -
11.109 - gobject_class = (GObjectClass *) klass;
11.110 -
11.111 - gobject_class->dispose = myth_file_transfer_dispose;
11.112 - gobject_class->finalize = myth_file_transfer_finalize;
11.113 -}
11.114 -
11.115 - static void
11.116 -myth_file_transfer_init (MythFileTransfer *myth_file_transfer)
11.117 -{
11.118 - g_return_if_fail( myth_file_transfer != NULL );
11.119 - myth_file_transfer->mythtv_version = MYTHTV_VERSION;
11.120 -}
11.121 -
11.122 -static void
11.123 -myth_file_transfer_dispose (GObject *object)
11.124 -{
11.125 - MythFileTransfer *myth_file_transfer = MYTH_FILE_TRANSFER(object);
11.126 -
11.127 - myth_file_transfer_close( myth_file_transfer );
11.128 -
11.129 - G_OBJECT_CLASS (myth_file_transfer_parent_class)->dispose (object);
11.130 -}
11.131 -
11.132 - static void
11.133 -myth_file_transfer_finalize (GObject *object)
11.134 -{
11.135 - g_signal_handlers_destroy (object);
11.136 -
11.137 - G_OBJECT_CLASS (myth_file_transfer_parent_class)->finalize (object);
11.138 -}
11.139 -
11.140 - MythFileTransfer*
11.141 -myth_file_transfer_new (gint num, GString *uri_str, gshort port, gint mythtv_version)
11.142 -{
11.143 - MythFileTransfer *transfer = MYTH_FILE_TRANSFER ( g_object_new (
11.144 - MYTH_FILE_TRANSFER_TYPE, FALSE ));
11.145 -
11.146 - if ( mythtv_version > 0 )
11.147 - transfer->mythtv_version = mythtv_version;
11.148 -
11.149 - transfer->card_id = num;
11.150 -
11.151 - transfer->rec_id = -1;
11.152 -
11.153 - transfer->recordernum = num;
11.154 - transfer->uri = myth_uri_new ( uri_str->str );
11.155 -
11.156 - transfer->hostname = g_string_new( myth_uri_gethost(transfer->uri) );
11.157 - g_print( "\t--> transfer->hostname = %s\n", transfer->hostname->str );
11.158 -
11.159 - if ( port >= 0 )
11.160 - transfer->port = port;
11.161 - else
11.162 - transfer->port = myth_uri_getport( transfer->uri );
11.163 -
11.164 - g_print( "\t--> transfer->port = %d\n", transfer->port );
11.165 -
11.166 - transfer->readposition = 0;
11.167 - transfer->filesize = MYTHTV_FILE_SIZE;
11.168 - transfer->timeoutisfast = FALSE;
11.169 -
11.170 - transfer->userreadahead = MYTHTV_USER_READ_AHEAD;
11.171 - transfer->retries = MYTHTV_RETRIES;
11.172 -
11.173 - transfer->live_tv = FALSE;
11.174 -
11.175 - transfer->query = g_string_new( MYTHTV_QUERY_HEADER );
11.176 - g_string_append_printf ( transfer->query, " %d", transfer->recordernum );
11.177 - g_print( "\t--> transfer->query = %s\n", transfer->query->str );
11.178 -
11.179 - transfer->control_sock = NULL;
11.180 - transfer->event_sock = NULL;
11.181 - transfer->sock = NULL;
11.182 -
11.183 - return transfer;
11.184 -}
11.185 -
11.186 -gboolean
11.187 -myth_file_transfer_livetv_setup( MythFileTransfer **transfer, GMythSocket *live_socket )
11.188 -{
11.189 - (*transfer)->sock = live_socket;
11.190 - g_object_ref( live_socket );
11.191 -
11.192 - return TRUE;
11.193 -}
11.194 -
11.195 -gboolean
11.196 -myth_file_transfer_playback_setup( MythFileTransfer **transfer, gboolean live_tv )
11.197 -{
11.198 -
11.199 - gboolean ret = TRUE;
11.200 -
11.201 - (*transfer)->live_tv = live_tv;
11.202 -
11.203 - printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
11.204 -
11.205 - /* configure the control socket */
11.206 - if ((*transfer)->control_sock == NULL) {
11.207 -
11.208 - if ( myth_connect_to_transfer_backend ( transfer, MYTH_PLAYBACK_TYPE ) == NULL ) {
11.209 - g_printerr( "Connection to backend failed (Control Socket).\n" );
11.210 - ret = FALSE;
11.211 - }
11.212 -
11.213 - } else {
11.214 - g_warning("Remote transfer control socket already created.\n");
11.215 - }
11.216 -
11.217 - return ret;
11.218 -
11.219 -}
11.220 -
11.221 -gboolean
11.222 -myth_file_transfer_setup( MythFileTransfer **transfer, gboolean live_tv )
11.223 -{
11.224 - GMythStringList *strlist = NULL;
11.225 -
11.226 - gboolean ret = TRUE;
11.227 -
11.228 - (*transfer)->live_tv = live_tv;
11.229 -
11.230 - printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
11.231 -
11.232 -#if 0
11.233 - /* configure the control socket */
11.234 - if ((*transfer)->event_sock == NULL) {
11.235 -
11.236 - if ( myth_connect_to_transfer_backend ( transfer, MYTH_MONITOR_TYPE ) == NULL ) {
11.237 - g_printerr( "Connection to backend failed (Event Socket).\n" );
11.238 - ret = FALSE;
11.239 - }
11.240 -
11.241 - } else {
11.242 - g_warning("Remote transfer control socket already created.\n");
11.243 - }
11.244 -#endif
11.245 -
11.246 - /* configure the socket */
11.247 - if ( (*transfer)->sock == NULL ) {
11.248 -
11.249 - //if ( live_tv == FALSE ) {
11.250 -
11.251 - if ( myth_connect_to_transfer_backend ( transfer, MYTH_FILETRANSFER_TYPE ) == NULL ) {
11.252 - g_printerr ("Connection to backend failed (Raw Transfer Socket).\n");
11.253 - ret = FALSE;
11.254 - }
11.255 -
11.256 - if ( !(*transfer)->live_tv && (*transfer)->control_sock != NULL) {
11.257 - strlist = gmyth_string_list_new();
11.258 - g_string_printf ( (*transfer)->query, "%s %d", MYTHTV_QUERY_HEADER, (*transfer)->recordernum );
11.259 -
11.260 - gmyth_string_list_append_string( strlist, (*transfer)->query );
11.261 - gmyth_string_list_append_char_array( strlist, "IS_OPEN" );
11.262 -
11.263 - gmyth_socket_write_stringlist( (*transfer)->control_sock, strlist );
11.264 - gmyth_socket_read_stringlist( (*transfer)->control_sock, strlist );
11.265 -
11.266 - if ( strlist!=NULL && gmyth_string_list_get_int( strlist, 0 ) == 1 ) {
11.267 - g_print( "[%s] Remote Myth FileTransfer socket is open!\n", __FUNCTION__ );
11.268 - } else {
11.269 - g_print( "[%s] Remote Myth FileTransfer socket is CLOSED! See the MythTV Server Backend for configuration details...\n", __FUNCTION__ );
11.270 - ret = FALSE;
11.271 - }
11.272 - }
11.273 -
11.274 - } else {
11.275 - g_warning("Remote transfer (raw) socket already created.\n");
11.276 - }
11.277 -
11.278 - return ret;
11.279 -}
11.280 -
11.281 -static GMythSocket *
11.282 -myth_connect_to_transfer_backend( MythFileTransfer **transfer, guint sock_type )
11.283 -{
11.284 - GMythSocket *sock = NULL;
11.285 -
11.286 - g_return_val_if_fail( transfer != NULL && *transfer != NULL, NULL );
11.287 - g_return_val_if_fail( (*transfer)->uri != NULL, NULL );
11.288 -
11.289 - g_static_mutex_lock (&mutex);
11.290 -
11.291 - gchar *path_dir = myth_uri_getpath( (*transfer)->uri );
11.292 - //g_print( "\t--> %s: path_dir = %s\n", __FUNCTION__, path_dir );
11.293 -
11.294 - gchar *stype = g_strdup( "" );
11.295 -
11.296 - // if ( (*transfer)->live_tv == FALSE ) {
11.297 -
11.298 - sock = gmyth_socket_new();
11.299 -
11.300 - gmyth_socket_connect( &sock, (*transfer)->hostname->str, (*transfer)->port );
11.301 -
11.302 - /*
11.303 - } else {
11.304 - sock = (*transfer)->sock;
11.305 - }
11.306 - */
11.307 -#ifdef MYTHTV_ENABLE_DEBUG
11.308 -
11.309 - g_print( "[%s] --> Creating socket... (%s, %d)\n", __FUNCTION__, (*transfer)->hostname->str, (*transfer)->port );
11.310 -#endif
11.311 -
11.312 - GMythStringList *strlist = NULL;
11.313 -
11.314 - GString *hostname = g_string_new( myth_uri_gethost( (*transfer)->uri ) );
11.315 - GString *base_str = g_string_new( "" );
11.316 -
11.317 - if ( gmyth_socket_check_protocol_version_number (sock, (*transfer)->mythtv_version) ) {
11.318 -
11.319 - if (sock == NULL) {
11.320 - stype = (sock_type==MYTH_PLAYBACK_TYPE) ? "control socket" : "file data socket";
11.321 - g_printerr( "FileTransfer, open_socket(%s): \n"
11.322 - "\t\t\tCould not connect to server \"%s\" @ port %d\n", stype,
11.323 - (*transfer)->hostname->str, (*transfer)->port );
11.324 - g_object_unref(sock);
11.325 - g_static_mutex_unlock (&mutex);
11.326 - return NULL;
11.327 - }
11.328 -
11.329 - hostname = gmyth_socket_get_local_hostname();
11.330 -
11.331 - g_print( "[%s] local hostname = %s\n", __FUNCTION__, hostname->str );
11.332 -
11.333 - if ( sock_type == MYTH_PLAYBACK_TYPE )
11.334 - {
11.335 - (*transfer)->control_sock = sock;
11.336 - g_string_printf( base_str, "ANN Playback %s %d", hostname->str, TRUE );
11.337 -
11.338 - gmyth_socket_send_command( (*transfer)->control_sock, base_str );
11.339 - GString *resp = gmyth_socket_receive_response( (*transfer)->control_sock );
11.340 - g_print( "[%s] Got Playback response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
11.341 - }
11.342 - else if ( sock_type == MYTH_MONITOR_TYPE )
11.343 - {
11.344 - (*transfer)->event_sock = sock;
11.345 - g_string_printf( base_str, "ANN Monitor %s %d", hostname->str, TRUE );
11.346 -
11.347 - gmyth_socket_send_command( (*transfer)->event_sock, base_str );
11.348 - GString *resp = gmyth_socket_receive_response( (*transfer)->event_sock );
11.349 - g_print( "[%s] Got Monitor response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
11.350 - //g_thread_create( myth_init_io_watchers, (void*)(*transfer), FALSE, NULL );
11.351 - myth_init_io_watchers ( (void*)(*transfer) );
11.352 -
11.353 - g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
11.354 -
11.355 - }
11.356 - else if ( sock_type == MYTH_FILETRANSFER_TYPE )
11.357 - {
11.358 - (*transfer)->sock = sock;
11.359 - strlist = gmyth_string_list_new();
11.360 - //g_string_printf( base_str, "ANN FileTransfer %s %d %d", hostname->str,
11.361 - // transfer->userreadahead, transfer->retries );
11.362 - g_string_printf( base_str, "ANN FileTransfer %s", hostname->str );
11.363 -
11.364 - gmyth_string_list_append_string( strlist, base_str );
11.365 - gmyth_string_list_append_char_array( strlist, path_dir );
11.366 -
11.367 - gmyth_socket_write_stringlist( (*transfer)->sock, strlist );
11.368 - gmyth_socket_read_stringlist( (*transfer)->sock, strlist );
11.369 -
11.370 - /* socket number, where all the stream data comes from - got from the MythTV remote backend */
11.371 - (*transfer)->recordernum = gmyth_string_list_get_int( strlist, 1 );
11.372 -
11.373 - /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */
11.374 - (*transfer)->filesize = gmyth_util_decode_long_long( strlist, 2 );
11.375 -
11.376 - printf( "[%s] ***** Received: recordernum = %d, filesize = %" G_GUINT64_FORMAT "\n", __FUNCTION__,
11.377 - (*transfer)->recordernum, (*transfer)->filesize );
11.378 -
11.379 - if ( (*transfer)->filesize <= 0 ) {
11.380 - g_print( "[%s] Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", __FUNCTION__, (*transfer)->filesize );
11.381 - g_object_unref(sock);
11.382 - sock = NULL;
11.383 - }
11.384 - }
11.385 - else if ( sock_type == MYTH_RINGBUFFER_TYPE )
11.386 - {
11.387 - (*transfer)->sock = sock;
11.388 - //myth_file_transfer_spawntv( (*transfer), NULL );
11.389 -
11.390 - strlist = gmyth_string_list_new();
11.391 - g_string_printf( base_str, "ANN RingBuffer %s %d", hostname->str, (*transfer)->card_id );
11.392 -
11.393 - gmyth_socket_send_command( (*transfer)->sock, base_str );
11.394 - GString *resp = gmyth_socket_receive_response( (*transfer)->sock );
11.395 - g_print( "[%s] Got RingBuffer response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
11.396 -
11.397 - }
11.398 -
11.399 - }
11.400 -
11.401 - printf("[%s] ANN %s sent: %s\n", (sock_type==MYTH_PLAYBACK_TYPE) ? "Playback" : (sock_type==MYTH_FILETRANSFER_TYPE) ? "FileTransfer" : "Monitor", __FUNCTION__, base_str->str);
11.402 -
11.403 - if ( strlist != NULL )
11.404 - g_object_unref( strlist );
11.405 -
11.406 - g_static_mutex_unlock (&mutex);
11.407 -
11.408 - return sock;
11.409 -}
11.410 -
11.411 -void
11.412 -myth_file_transfer_spawntv ( MythFileTransfer *file_transfer,
11.413 - GString *tvchain_id )
11.414 -{
11.415 - GMythStringList *str_list;
11.416 -
11.417 - g_debug ("myth_file_transfer_spawntv.\n");
11.418 -
11.419 - str_list = gmyth_string_list_new ();
11.420 -
11.421 - g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER,
11.422 - file_transfer->card_id );
11.423 - gmyth_string_list_append_string (str_list, file_transfer->query);
11.424 - gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
11.425 - if (tvchain_id!=NULL) {
11.426 - gmyth_string_list_append_string (str_list, tvchain_id);
11.427 - gmyth_string_list_append_int (str_list, FALSE); // PIP = FALSE (0)
11.428 - }
11.429 -
11.430 - gmyth_socket_sendreceive_stringlist ( file_transfer->sock, str_list );
11.431 -
11.432 - //GString *str = NULL;
11.433 -
11.434 - //if (str_list!=NULL && (str = gmyth_string_list_get_string( str_list, 0 )) != NULL && strcasecmp( str->str, "ok" ) != 0 ) {
11.435 - // g_print( "[%s]\t\tSpawnLiveTV is OK!\n", __FUNCTION__ );
11.436 - //}
11.437 - if (str_list!=NULL)
11.438 - g_object_unref (str_list);
11.439 -
11.440 -}
11.441 -
11.442 -gboolean
11.443 -myth_file_transfer_is_recording ( MythFileTransfer *file_transfer )
11.444 -{
11.445 - gboolean ret = TRUE;
11.446 -
11.447 - GMythStringList *str_list = gmyth_string_list_new ();
11.448 -
11.449 - g_debug ( "[%s]\n", __FUNCTION__ );
11.450 - g_static_mutex_lock (&mutex);
11.451 -
11.452 - g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER,
11.453 - file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id );
11.454 - gmyth_string_list_append_string (str_list, file_transfer->query);
11.455 - gmyth_string_list_append_string (str_list, g_string_new ("IS_RECORDING"));
11.456 -
11.457 - gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list );
11.458 -
11.459 - if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 )
11.460 - {
11.461 - GString *str = NULL;
11.462 - if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp( str->str, "bad" )!= 0 ) {
11.463 - gint is_rec = gmyth_string_list_get_int( str_list, 0 );
11.464 - if ( is_rec != 0 )
11.465 - ret = TRUE;
11.466 - else
11.467 - ret = FALSE;
11.468 - }
11.469 - }
11.470 - g_print( "[%s] %s, stream is %s being recorded!\n", __FUNCTION__, ret ? "YES" : "NO", ret ? "" : "NOT" );
11.471 - g_static_mutex_unlock (&mutex);
11.472 -
11.473 - if ( str_list != NULL )
11.474 - g_object_unref (str_list);
11.475 -
11.476 - return ret;
11.477 -
11.478 -}
11.479 -
11.480 -guint64
11.481 -myth_file_transfer_get_file_position ( MythFileTransfer *file_transfer )
11.482 -{
11.483 - gint64 pos = 0;
11.484 -
11.485 - GMythStringList *str_list = gmyth_string_list_new ();
11.486 -
11.487 - g_debug ( "[%s]\n", __FUNCTION__ );
11.488 - g_static_mutex_lock (&mutex);
11.489 -
11.490 - g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER,
11.491 - file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id );
11.492 -
11.493 - gmyth_string_list_append_string (str_list, file_transfer->query);
11.494 - gmyth_string_list_append_string (str_list, g_string_new ("GET_FILE_POSITION"));
11.495 -
11.496 - gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list );
11.497 -
11.498 - if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 )
11.499 - {
11.500 - GString *str = NULL;
11.501 - if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp ( str->str, "bad" ) != 0 )
11.502 - pos = gmyth_util_decode_long_long( str_list, 0 );
11.503 - }
11.504 - g_static_mutex_unlock (&mutex);
11.505 -
11.506 -#ifndef MYTHTV_ENABLE_DEBUG
11.507 -
11.508 - g_print( "[%s] Got file position = %llu\n", __FUNCTION__, pos );
11.509 -#endif
11.510 - if (str_list!=NULL)
11.511 - g_object_unref (str_list);
11.512 -
11.513 - return pos;
11.514 -
11.515 -}
11.516 -
11.517 - glong
11.518 -myth_file_transfer_get_recordernum( MythFileTransfer *transfer )
11.519 -{
11.520 - return transfer->recordernum;
11.521 -}
11.522 -
11.523 - glong
11.524 -myth_file_transfer_get_filesize( MythFileTransfer *transfer )
11.525 -{
11.526 - return transfer->filesize;
11.527 -}
11.528 -
11.529 - gboolean
11.530 -myth_file_transfer_isopen( MythFileTransfer *transfer )
11.531 -{
11.532 - return (transfer->sock != NULL && transfer->control_sock != NULL);
11.533 -}
11.534 -
11.535 - void
11.536 -myth_file_transfer_close( MythFileTransfer *transfer )
11.537 -{
11.538 - GMythStringList *strlist;
11.539 -
11.540 - if (transfer->control_sock == NULL)
11.541 - return;
11.542 -
11.543 - strlist = gmyth_string_list_new( );
11.544 -
11.545 - g_string_printf( transfer->query, "%s %d", MYTHTV_QUERY_HEADER,
11.546 - transfer->recordernum );
11.547 - gmyth_string_list_append_string( strlist, transfer->query );
11.548 - gmyth_string_list_append_char_array( strlist, "DONE" );
11.549 -
11.550 -
11.551 - if ( gmyth_socket_sendreceive_stringlist(transfer->control_sock, strlist) <= 0 )
11.552 - {
11.553 - g_printerr( "Remote file timeout.\n" );
11.554 - }
11.555 -
11.556 - if (transfer->sock)
11.557 - {
11.558 - g_object_unref( transfer->sock );
11.559 - transfer->sock = NULL;
11.560 - }
11.561 -
11.562 - if (transfer->control_sock)
11.563 - {
11.564 - g_object_unref( transfer->control_sock );
11.565 - transfer->control_sock = NULL;
11.566 - }
11.567 -
11.568 -}
11.569 -
11.570 - void
11.571 -myth_file_transfer_reset_controlsock( MythFileTransfer *transfer )
11.572 -{
11.573 - if (transfer->control_sock == NULL)
11.574 - {
11.575 - g_printerr( "myth_file_transfer_reset_controlsock(): Called with no control socket" );
11.576 - return;
11.577 - }
11.578 -
11.579 - GString *str = gmyth_socket_receive_response( transfer->control_sock );
11.580 -
11.581 - g_string_free( str, TRUE );
11.582 -}
11.583 -
11.584 -void
11.585 -myth_file_transfer_reset_sock( MythFileTransfer *transfer )
11.586 -{
11.587 - if ( transfer->sock == NULL )
11.588 - {
11.589 - g_printerr( "myth_file_transfer_reset_sock(): Called with no raw socket" );
11.590 - return;
11.591 - }
11.592 -
11.593 - GString *str = gmyth_socket_receive_response( transfer->sock );
11.594 -
11.595 - g_string_free( str, TRUE );
11.596 -}
11.597 -
11.598 -void
11.599 -myth_file_transfer_reset( MythFileTransfer *transfer )
11.600 -{
11.601 - myth_file_transfer_reset_controlsock( transfer );
11.602 - myth_file_transfer_reset_sock( transfer );
11.603 -}
11.604 -
11.605 -guint64
11.606 -myth_file_transfer_seek(MythFileTransfer *transfer, guint64 pos, gint whence)
11.607 -{
11.608 - if (transfer->sock == NULL)
11.609 - {
11.610 - g_printerr( "[%s] myth_file_transfer_seek(): Called with no socket", __FUNCTION__ );
11.611 - return 0;
11.612 - }
11.613 -
11.614 - if (transfer->control_sock == NULL)
11.615 - return 0;
11.616 -
11.617 - // if (!controlSock->isOpen() || controlSock->error())
11.618 - // return 0;
11.619 -
11.620 - GMythStringList *strlist = gmyth_string_list_new();
11.621 - g_string_printf (transfer->query, "%s %d", MYTHTV_QUERY_HEADER, transfer->recordernum);
11.622 - gmyth_string_list_append_string( strlist, transfer->query );
11.623 - gmyth_string_list_append_char_array( strlist, "SEEK" );
11.624 - gmyth_string_list_append_uint64( strlist, pos );
11.625 -
11.626 - gmyth_string_list_append_int( strlist, whence );
11.627 -
11.628 - if (pos > 0 )
11.629 - gmyth_string_list_append_uint64( strlist, pos );
11.630 - else
11.631 - gmyth_string_list_append_uint64( strlist, transfer->readposition );
11.632 -
11.633 - gmyth_socket_sendreceive_stringlist( transfer->control_sock, strlist );
11.634 -
11.635 - guint64 retval = gmyth_string_list_get_uint64(strlist, 0);
11.636 - transfer->readposition = retval;
11.637 - g_print( "[%s] got reading position pointer from the streaming = %llu\n",
11.638 - __FUNCTION__, retval );
11.639 -
11.640 - //myth_file_transfer_reset( transfer );
11.641 -
11.642 - return retval;
11.643 -}
11.644 -
11.645 -static gboolean
11.646 -myth_control_sock_listener( GIOChannel *source, GIOCondition condition, gpointer data )
11.647 -{
11.648 -
11.649 - GIOStatus ret;
11.650 - GError *err = NULL;
11.651 - gchar *msg = g_strdup("");
11.652 -
11.653 - g_static_mutex_lock( &mutex );
11.654 -
11.655 - gsize len;
11.656 - if (condition & G_IO_HUP)
11.657 - g_error ("Read end of pipe died!\n");
11.658 - ret = g_io_channel_read_line ( source, &msg, &len, NULL, &err);
11.659 - if ( ret == G_IO_STATUS_ERROR )
11.660 - g_error ("[%s] Error reading: %s\n", __FUNCTION__, err != NULL ? err->message : "" );
11.661 - g_print ("\n\n\n\n\n\n[%s]\t\tEVENT: Read %u bytes: %s\n\n\n\n\n", __FUNCTION__, len, msg != NULL ? msg : "" );
11.662 - if ( msg != NULL )
11.663 - g_free (msg);
11.664 -
11.665 - g_static_mutex_unlock( &mutex );
11.666 -
11.667 - return TRUE;
11.668 -
11.669 -}
11.670 -
11.671 -static void*
11.672 -myth_init_io_watchers( void *data )
11.673 -{
11.674 - MythFileTransfer *transfer = (MythFileTransfer*)data;
11.675 - io_watcher_context = g_main_context_new();
11.676 - GMainLoop *loop = g_main_loop_new( NULL, FALSE );
11.677 -
11.678 - GSource *source = NULL;
11.679 -
11.680 - if ( transfer->event_sock->sd_io_ch != NULL )
11.681 - source = g_io_create_watch( transfer->event_sock->sd_io_ch, G_IO_IN | G_IO_HUP );
11.682 - else
11.683 - goto cleanup;
11.684 -
11.685 - g_source_set_callback ( source, (GSourceFunc)myth_control_sock_listener, NULL, NULL );
11.686 -
11.687 - g_source_attach( source, io_watcher_context );
11.688 -
11.689 - if (source==NULL) {
11.690 - g_printerr( "[%s] Error adding watch listener function to the IO control channel!\n", __FUNCTION__ );
11.691 - goto cleanup;
11.692 - }
11.693 -
11.694 - g_print( "[%s]\tOK! Starting listener on the MONITOR event socket...\n", __FUNCTION__ );
11.695 -
11.696 - g_main_loop_run( loop );
11.697 -
11.698 -cleanup:
11.699 - if ( source != NULL )
11.700 - g_source_unref( source );
11.701 -
11.702 - g_main_loop_unref( loop );
11.703 -
11.704 - g_main_context_unref( io_watcher_context );
11.705 -
11.706 - return NULL;
11.707 -}
11.708 -
11.709 -
11.710 -gint
11.711 -myth_file_transfer_read(MythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited)
11.712 -{
11.713 - gint recv = 0;
11.714 - gsize bytes_read = 0;
11.715 - gint sent = 0;
11.716 - guint remaining = 0;
11.717 - gboolean response = FALSE;
11.718 -
11.719 - GIOChannel *io_channel;
11.720 - GIOChannel *io_channel_control;
11.721 -
11.722 - GIOCondition io_cond;
11.723 - GIOCondition io_cond_control;
11.724 - GIOStatus io_status = G_IO_STATUS_NORMAL, io_status_control = G_IO_STATUS_NORMAL;
11.725 -
11.726 - gint buf_len = MYTHTV_BUFFER_SIZE;
11.727 -
11.728 - GMythStringList *strlist = NULL;
11.729 - GError *error = NULL;
11.730 -
11.731 - gchar *trash = g_strdup("");
11.732 -
11.733 - g_return_val_if_fail ( data != NULL, -2 );
11.734 -
11.735 - /* gets the size of the entire file, if the size requested is lesser than 0 */
11.736 - if ( size <= 0 )
11.737 - size = transfer->filesize;
11.738 -
11.739 - io_channel = transfer->sock->sd_io_ch;
11.740 - io_channel_control = transfer->control_sock->sd_io_ch;
11.741 -
11.742 - //g_io_channel_set_flags( io_channel, G_IO_FLAG_APPEND |
11.743 - // G_IO_STATUS_AGAIN | G_IO_FLAG_IS_READABLE | G_IO_FLAG_IS_WRITEABLE |
11.744 - // G_IO_FLAG_IS_SEEKABLE, NULL );
11.745 -
11.746 - io_status = g_io_channel_set_encoding( io_channel, NULL, &error );
11.747 - if ( io_status == G_IO_STATUS_NORMAL )
11.748 - g_print( "[%s] Setting encoding to binary data socket).\n", __FUNCTION__ );
11.749 -
11.750 - io_cond = g_io_channel_get_buffer_condition( io_channel );
11.751 -
11.752 - io_cond_control = g_io_channel_get_buffer_condition( io_channel );
11.753 -
11.754 - if ( transfer->sock == NULL || ( io_status == G_IO_STATUS_ERROR ) )
11.755 - {
11.756 - g_printerr( "myth_file_transfer_read(): Called with no raw socket.\n" );
11.757 - recv = -1;
11.758 - goto cleanup;
11.759 - }
11.760 -
11.761 - if ( transfer->control_sock == NULL || ( io_status_control == G_IO_STATUS_ERROR ) )
11.762 - {
11.763 - g_printerr( "myth_file_transfer_read(): Called with no control socket.\n" );
11.764 - recv = -1;
11.765 - goto cleanup;
11.766 - }
11.767 -
11.768 - /*
11.769 - if (!controlSock->isOpen() || controlSock->error())
11.770 - return -1;
11.771 - */
11.772 -
11.773 - if ( ( io_cond & G_IO_IN ) != 0 ) {
11.774 - do
11.775 - {
11.776 - trash = g_new0( gchar, MYTHTV_BUFFER_SIZE );
11.777 -
11.778 - io_status = g_io_channel_read_chars( io_channel, trash,
11.779 - MYTHTV_BUFFER_SIZE, &bytes_read, &error);
11.780 -
11.781 - g_print( "[%s] cleaning buffer on IO binary channel... %d bytes gone!\n",
11.782 - __FUNCTION__, bytes_read );
11.783 -
11.784 - if ( trash != NULL )
11.785 - g_free( trash );
11.786 -
11.787 - io_cond = g_io_channel_get_buffer_condition( io_channel );
11.788 -
11.789 - } while ( ( io_cond & G_IO_IN ) != 0 && ( io_status != G_IO_STATUS_ERROR ) && (error == NULL) );
11.790 -
11.791 - //if ( trash!= NULL )
11.792 - // g_free( trash );
11.793 - }
11.794 -
11.795 - if ( ( io_cond_control & G_IO_IN ) != 0 ) {
11.796 - GMythStringList *strlist_tmp = gmyth_string_list_new();
11.797 - gmyth_socket_read_stringlist( transfer->control_sock, strlist_tmp );
11.798 - g_object_unref( strlist_tmp );
11.799 - }
11.800 -
11.801 - wait_to_transfer = 0;
11.802 -
11.803 - //while ( transfer->live_tv && ( myth_file_transfer_get_file_position( transfer ) < 4096 ) &&
11.804 - // wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS )
11.805 - // g_usleep( 1000*50 ); /* waits just for 2/10 second */
11.806 -
11.807 - //g_thread_create( myth_init_io_watchers, (void*)transfer, FALSE, NULL );
11.808 - //g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
11.809 -
11.810 - //g_static_mutex_lock (&mutex);
11.811 - //strlist = gmyth_string_list_new();
11.812 -
11.813 - g_string_printf ( transfer->query, "%s %d",
11.814 - /*transfer->live_tv ? MYTHTV_RECORDER_HEADER :*/ MYTHTV_QUERY_HEADER,
11.815 - /* transfer->live_tv ? transfer->card_id :*/ transfer->recordernum ); // transfer->recordernum
11.816 - g_print( "\t[%s] Transfer_query = %s\n", __FUNCTION__, transfer->query->str );
11.817 -
11.818 - sent = size;
11.819 - remaining = size - recv;
11.820 - //g_static_mutex_unlock( &mutex );
11.821 - //data = (void*)g_new0( gchar, size );
11.822 -
11.823 - //g_io_channel_flush( io_channel, NULL );
11.824 -
11.825 - //g_static_mutex_lock( &mutex );
11.826 -
11.827 - io_cond = g_io_channel_get_buffer_condition( io_channel );
11.828 -
11.829 - while ( recv < size && !response )//&& ( io_cond & G_IO_IN ) != 0 )
11.830 - {
11.831 - g_io_channel_flush( io_channel_control, NULL );
11.832 -
11.833 - strlist = gmyth_string_list_new();
11.834 - gmyth_string_list_append_char_array( strlist, transfer->query->str );
11.835 - gmyth_string_list_append_char_array( strlist,
11.836 - /*transfer->live_tv ? "REQUEST_BLOCK_RINGBUF" :*/ "REQUEST_BLOCK" );
11.837 - gmyth_string_list_append_int( strlist, remaining );
11.838 - gmyth_socket_write_stringlist( transfer->control_sock, strlist );
11.839 -
11.840 - guint count_bytes = 0;
11.841 -
11.842 - do
11.843 - {
11.844 - //buf_len = ( sent - recv ) > MYTHTV_BUFFER_SIZE ? MYTHTV_BUFFER_SIZE : ( sent - recv );
11.845 - if ( remaining > MYTHTV_BUFFER_SIZE ) {
11.846 - buf_len = MYTHTV_BUFFER_SIZE;
11.847 - } else {
11.848 - buf_len = remaining;
11.849 - }
11.850 -
11.851 - bytes_read = 0;
11.852 -
11.853 - io_status = g_io_channel_read_chars( io_channel, data + recv,
11.854 - buf_len, &bytes_read, &error );
11.855 -
11.856 - //g_static_mutex_unlock( &mutex );
11.857 - /*
11.858 - GString *sss = g_string_new("");
11.859 - sss = g_string_append_len( sss, (gchar*)data+recv, bytes_read );
11.860 -
11.861 - g_print( "[%s] Reading buffer (length = %d)\n", __FUNCTION__, bytes_read);
11.862 - */
11.863 - if ( bytes_read > 0 )
11.864 - {
11.865 - //if ( bytes_read <= buf_len )
11.866 - recv += bytes_read;
11.867 - count_bytes += bytes_read;
11.868 - remaining -= bytes_read;
11.869 - g_print( "[%s] Reading buffer (bytes read = %d, remaining = %d)\n", __FUNCTION__, bytes_read, remaining );
11.870 - if ( remaining == 0 ) {
11.871 - break;
11.872 - }
11.873 - } else {
11.874 - break;
11.875 - }
11.876 -
11.877 - //if ( remaining > 0 ) {
11.878 -
11.879 - if ( io_status == G_IO_STATUS_EOF ) {
11.880 - g_print( "[%s] got EOS!", __FUNCTION__ );
11.881 - break;
11.882 - } else if ( io_status == G_IO_STATUS_ERROR ) {
11.883 - g_print( "[%s] myth_file_transfer_read(): socket error.\n", __FUNCTION__ );
11.884 - break;
11.885 - }
11.886 - //}
11.887 -
11.888 - /* increase buffer size, to allow get more data (do not obey to the buffer size) */
11.889 - if ( read_unlimited == TRUE ) {
11.890 - // FOR NOW, DO NOTHING!!!
11.891 - //if ( recv > buf_len )
11.892 - // sent += (bytes_read - buf_len) + 1;
11.893 - }
11.894 -
11.895 - /* verify if the input (read) buffer is ready to receive data */
11.896 - io_cond = g_io_channel_get_buffer_condition( io_channel );
11.897 -
11.898 - g_print( "[%s]\t io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__,
11.899 - ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
11.900 -
11.901 - //if ( recv == size )
11.902 - //break;
11.903 -
11.904 - } while ( remaining > 0 );//&& ( io_status == G_IO_STATUS_NORMAL ) );
11.905 -
11.906 - // if ( ( recv < size ) ) {
11.907 - // finish_read = FALSE;
11.908 - //}
11.909 -
11.910 - io_cond_control = g_io_channel_get_buffer_condition( io_channel_control );
11.911 - if ( remaining == 0 )//( io_cond_control & G_IO_IN ) != 0 )
11.912 - {
11.913 - gmyth_socket_read_stringlist( transfer->control_sock, strlist );
11.914 - if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 )
11.915 - {
11.916 - sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error
11.917 - g_print( "[%s] got SENT buffer message = %d\n", __FUNCTION__, sent );
11.918 - if ( sent != 0 )
11.919 - {
11.920 - g_print( "[%s]\t received = %d bytes, backend says %d bytes sent, "\
11.921 - "io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__,
11.922 - recv, sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
11.923 -
11.924 - if ( sent == count_bytes )
11.925 - {
11.926 - response = ( recv == size );
11.927 - g_print( "[%s]\t\tsent %d, which is equals to bytes_read = %d\n\n",
11.928 - __FUNCTION__, sent, count_bytes );
11.929 - if ( response == TRUE )
11.930 - break;
11.931 - }
11.932 - else
11.933 - {
11.934 - g_print( "[%s]\t\tsent %d, which is NOT equals to bytes_read = %d\n\n",
11.935 - __FUNCTION__, sent, count_bytes );
11.936 - goto cleanup;
11.937 - //response = FALSE;
11.938 - //break;
11.939 - }
11.940 - } else {
11.941 - break;
11.942 - //goto cleanup;
11.943 - } // if
11.944 - } // if - reading control response from backend
11.945 - } else {
11.946 - response = FALSE;
11.947 - } // if - stringlist response
11.948 -
11.949 - } // while
11.950 -
11.951 - io_cond_control = g_io_channel_get_buffer_condition( io_channel_control );
11.952 - // io_cond = g_io_channel_get_buffer_condition( io_channel );
11.953 -
11.954 - if ( ( ( io_cond_control & G_IO_IN ) != 0 ) &&
11.955 - ( response || ( recv == size ) ) )
11.956 - {
11.957 - if ( gmyth_socket_read_stringlist( transfer->control_sock, strlist ) > 0 )
11.958 - {
11.959 - if ( strlist != NULL && gmyth_string_list_length(strlist) > 0 )
11.960 - {
11.961 - sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error
11.962 - g_print( "[%s]\t received = %d bytes -\tNOW returning from reading buffer I/O socket "\
11.963 - "[%s prepared for reading]! (G_IO_IN) !!!\n\n", __FUNCTION__,
11.964 - sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
11.965 - }
11.966 - }
11.967 - else
11.968 - {
11.969 - g_printerr ( "myth_file_transfer_read(): No response from control socket.");
11.970 - recv = -1;
11.971 - }
11.972 -
11.973 - }
11.974 - else if ( error != NULL )
11.975 - {
11.976 - g_printerr( "[%s] Error occurred: (%d, %s)\n", __FUNCTION__, error->code, error->message );
11.977 - }
11.978 -
11.979 -cleanup:
11.980 - //g_static_mutex_unlock (&mutex);
11.981 -
11.982 - if ( trash != NULL )
11.983 - g_free( trash );
11.984 -
11.985 - if ( strlist != NULL )
11.986 - g_object_unref( strlist );
11.987 -
11.988 - g_print( "myth_file_transfer_read(): reqd=%d, rcvd=%d, rept=%d, "\
11.989 - "(rcvd and rept MUST be the same!)\n", size,
11.990 - recv, sent );
11.991 -
11.992 - //if ( ( recv != size ) || ( sent != size ) ) {
11.993 - //recv = size;
11.994 - //}
11.995 -
11.996 - if ( error != NULL ) {
11.997 - g_printerr( "Cleaning-up ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message,
11.998 - error->code );
11.999 - g_error_free( error );
11.1000 - }
11.1001 -
11.1002 - return recv;
11.1003 -}
11.1004 -
11.1005 -void
11.1006 -myth_file_transfer_settimeout( MythFileTransfer *transfer, gboolean fast )
11.1007 -{
11.1008 -
11.1009 - GMythStringList *strlist = NULL;
11.1010 -
11.1011 - if ( transfer->timeoutisfast == fast )
11.1012 - return;
11.1013 -
11.1014 - if ( transfer->sock == NULL )
11.1015 - {
11.1016 - g_printerr( "myth_file_transfer_settimeout(): Called with no socket" );
11.1017 - return;
11.1018 - }
11.1019 -
11.1020 - if ( transfer->control_sock == NULL )
11.1021 - return;
11.1022 -
11.1023 - strlist = gmyth_string_list_new();
11.1024 - gmyth_string_list_append_string( strlist, transfer->query );
11.1025 - gmyth_string_list_append_char_array( strlist, "SET_TIMEOUT" );
11.1026 - gmyth_string_list_append_int( strlist, fast );
11.1027 -
11.1028 - gmyth_socket_write_stringlist( transfer->control_sock, strlist );
11.1029 - gmyth_socket_read_stringlist( transfer->control_sock, strlist );
11.1030 -
11.1031 - transfer->timeoutisfast = fast;
11.1032 -
11.1033 -}
11.1034 -
11.1035 -#ifdef DO_TESTING
11.1036 -
11.1037 - int
11.1038 -main( int argc, char *argv[] )
11.1039 -{
11.1040 - g_type_init();
11.1041 -
11.1042 - MythFileTransfer *file_transfer = myth_file_transfer_new( 1,
11.1043 - g_string_new("myth://192.168.1.109:6543/jshks.nuv"), -1, MYTHTV_VERSION );
11.1044 - myth_file_transfer_setup( &file_transfer );
11.1045 - gchar *data = g_strdup("");
11.1046 -
11.1047 - gint num = myth_file_transfer_read( file_transfer, data, -1 );
11.1048 -
11.1049 - return 0;
11.1050 -
11.1051 -}
11.1052 -
11.1053 -#endif
12.1 --- a/gst-plugins-mythtv/src/myth_file_transfer.h Mon Oct 23 14:43:18 2006 +0100
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,93 +0,0 @@
12.4 -/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
12.5 -
12.6 -#ifndef __MYTH_FILE_TRANSFER_H__
12.7 -#define __MYTH_FILE_TRANSFER_H__
12.8 -
12.9 -#include <glib-object.h>
12.10 -
12.11 -#include <gmyth/gmyth_socket.h>
12.12 -#include "myth_uri.h"
12.13 -#include "myth_livetv.h"
12.14 -
12.15 -#include <stdio.h>
12.16 -#include <stdlib.h>
12.17 -#include <string.h>
12.18 -#include <netdb.h>
12.19 -#include <sys/socket.h>
12.20 -#include <unistd.h>
12.21 -
12.22 -#define G_BEGIN_DECLS
12.23 -
12.24 -#define MYTH_FILE_TRANSFER_TYPE (myth_file_transfer_get_type ())
12.25 -#define MYTH_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_FILE_TRANSFER_TYPE, MythFileTransfer))
12.26 -#define MYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_FILE_TRANSFER_TYPE, MythFileTransferClass))
12.27 -#define IS_MYTH_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_FILE_TRANSFER_TYPE))
12.28 -#define IS_MYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_FILE_TRANSFER_TYPE))
12.29 -#define MYTH_FILE_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MYTH_FILE_TRANSFER_TYPE, MythFileTransferClass))
12.30 -
12.31 -
12.32 -typedef struct _MythFileTransfer MythFileTransfer;
12.33 -typedef struct _MythFileTransferClass MythFileTransferClass;
12.34 -
12.35 -struct _MythFileTransferClass
12.36 -{
12.37 - GObjectClass parent_class;
12.38 -
12.39 - /* callbacks */
12.40 - /* no one for now */
12.41 -};
12.42 -
12.43 -struct _MythFileTransfer
12.44 -{
12.45 - GObject parent;
12.46 -
12.47 - /* Myth URI structure */
12.48 - const MythURI *uri;
12.49 -
12.50 - /* MythTV version number */
12.51 - gint mythtv_version;
12.52 -
12.53 - /* socket descriptors */
12.54 - GMythSocket *control_sock;
12.55 - GMythSocket *event_sock;
12.56 - GMythSocket *sock;
12.57 -
12.58 - guint64 readposition;
12.59 - guint64 filesize;
12.60 - gboolean timeoutisfast;
12.61 - gboolean userreadahead;
12.62 - gboolean live_tv;
12.63 - gint retries;
12.64 -
12.65 - GString *query;
12.66 -
12.67 - gint rec_id;
12.68 - gint recordernum;
12.69 - gint card_id;
12.70 - GString *hostname;
12.71 - gint port;
12.72 -};
12.73 -
12.74 -GType myth_file_transfer_get_type (void);
12.75 -
12.76 -MythFileTransfer* myth_file_transfer_new (gint num, GString *hostname, gshort port, gint mythtv_version );
12.77 -
12.78 -gint myth_file_transfer_read(MythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited);
12.79 -
12.80 -guint64 myth_file_transfer_seek(MythFileTransfer *transfer, guint64 pos, gint whence);
12.81 -
12.82 -gboolean myth_file_transfer_playback_setup( MythFileTransfer **transfer, gboolean live_tv );
12.83 -
12.84 -gboolean myth_file_transfer_setup( MythFileTransfer **transfer, gboolean live_tv );
12.85 -
12.86 -gboolean myth_file_transfer_livetv_setup( MythFileTransfer **transfer, GMythSocket *live_sock );
12.87 -
12.88 -void myth_file_transfer_spawntv ( MythFileTransfer *file_transfer, GString *tvchain_id );
12.89 -
12.90 -gboolean myth_file_transfer_is_recording( MythFileTransfer *file_transfer );
12.91 -
12.92 -guint64 myth_file_transfer_get_file_position( MythFileTransfer *file_transfer );
12.93 -
12.94 -#define G_END_DECLS
12.95 -
12.96 -#endif /* __MYTH_FILE_TRANSFER_H__ */
13.1 --- a/gst-plugins-mythtv/src/myth_livetv.c Mon Oct 23 14:43:18 2006 +0100
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,220 +0,0 @@
13.4 -
13.5 -#include <gmyth/gmyth_context.h>
13.6 -#include <gmyth/gmyth_remote_util.h>
13.7 -#include <gmyth/gmyth_tvchain.h>
13.8 -
13.9 -#include "myth_livetv.h"
13.10 -#include "myth_file_transfer.h"
13.11 -
13.12 -static void myth_livetv_class_init (MythLiveTVClass *klass);
13.13 -static void myth_livetv_init (MythLiveTV *object);
13.14 -
13.15 -static void myth_livetv_dispose (GObject *object);
13.16 -static void myth_livetv_finalize (GObject *object);
13.17 -
13.18 -static gint tvchain_curr_index = -1;
13.19 -
13.20 -G_DEFINE_TYPE(MythLiveTV, myth_livetv, G_TYPE_OBJECT)
13.21 -
13.22 -static void
13.23 -myth_livetv_class_init (MythLiveTVClass *klass)
13.24 -{
13.25 - GObjectClass *gobject_class;
13.26 -
13.27 - gobject_class = (GObjectClass *) klass;
13.28 -
13.29 - gobject_class->dispose = myth_livetv_dispose;
13.30 - gobject_class->finalize = myth_livetv_finalize;
13.31 -}
13.32 -
13.33 -static void
13.34 -myth_livetv_init (MythLiveTV *livetv)
13.35 -{
13.36 - livetv->backend_hostname = NULL;
13.37 - livetv->backend_port = 0;
13.38 - livetv->local_hostname = NULL;
13.39 -
13.40 - livetv->remote_encoder = NULL;
13.41 - livetv->tvchain = NULL;
13.42 - livetv->proginfo = NULL;
13.43 -}
13.44 -
13.45 -static void
13.46 -myth_livetv_dispose (GObject *object)
13.47 -{
13.48 -
13.49 - G_OBJECT_CLASS (myth_livetv_parent_class)->dispose (object);
13.50 -}
13.51 -
13.52 -static void
13.53 -myth_livetv_finalize (GObject *object)
13.54 -{
13.55 - g_signal_handlers_destroy (object);
13.56 -
13.57 - MythLiveTV *livetv = MYTH_LIVETV (object);
13.58 -
13.59 - g_debug ("[%s] Finalizing livetv", __FUNCTION__);
13.60 -
13.61 - if ( livetv->remote_encoder != NULL ) {
13.62 - g_object_unref (livetv->remote_encoder);
13.63 - livetv->remote_encoder = NULL;
13.64 - }
13.65 -
13.66 - if ( livetv->tvchain != NULL ) {
13.67 - g_object_unref (livetv->tvchain);
13.68 - livetv->tvchain = NULL;
13.69 - }
13.70 -
13.71 - if ( livetv->proginfo != NULL ) {
13.72 - g_object_unref (livetv->proginfo);
13.73 - livetv->proginfo = NULL;
13.74 - }
13.75 -
13.76 - G_OBJECT_CLASS ( myth_livetv_parent_class )->finalize ( object );
13.77 -}
13.78 -
13.79 -MythLiveTV*
13.80 -myth_livetv_new ()
13.81 -{
13.82 - MythLiveTV *livetv = MYTH_LIVETV ( g_object_new( MYTH_LIVETV_TYPE, NULL ) );
13.83 -
13.84 - return livetv;
13.85 -}
13.86 -
13.87 -gboolean
13.88 -myth_livetv_setup ( MythLiveTV *livetv )
13.89 -{
13.90 - GMythSettings *msettings = gmyth_context_get_settings ();
13.91 - gboolean res = TRUE;
13.92 -
13.93 - livetv->is_livetv = TRUE;
13.94 -
13.95 - res = gmyth_context_check_connection();
13.96 - if (!res) {
13.97 - g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);
13.98 - res = FALSE;
13.99 - goto error;
13.100 - }
13.101 -
13.102 - livetv->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
13.103 - livetv->backend_port = gmyth_settings_get_backend_port (msettings);
13.104 -
13.105 - livetv->local_hostname = g_string_new("");
13.106 - gmyth_context_get_local_hostname (livetv->local_hostname);
13.107 -
13.108 - if ( livetv->local_hostname == NULL ) {
13.109 - res = FALSE;
13.110 - goto error;
13.111 - }
13.112 -
13.113 - // Gets the remote encoder num
13.114 - livetv->remote_encoder = remote_request_next_free_recorder (-1);
13.115 -
13.116 - if ( livetv->remote_encoder == NULL ) {
13.117 - g_warning ("[%s] None remote encoder available", __FUNCTION__);
13.118 - res = FALSE;
13.119 - goto error;
13.120 - }
13.121 -
13.122 - // Creates livetv chain handler
13.123 - livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
13.124 - gmyth_tvchain_initialize ( livetv->tvchain, livetv->local_hostname );
13.125 -
13.126 - if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
13.127 - res = FALSE;
13.128 - goto error;
13.129 - }
13.130 -
13.131 - // Init remote encoder. Opens its control socket.
13.132 - res = gmyth_remote_encoder_setup(livetv->remote_encoder);
13.133 - if ( !res ) {
13.134 - g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
13.135 - res = FALSE;
13.136 - goto error;
13.137 - }
13.138 - // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
13.139 - res = gmyth_remote_encoder_spawntv ( livetv->remote_encoder,
13.140 - gmyth_tvchain_get_id(livetv->tvchain) );
13.141 - if (!res) {
13.142 - g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
13.143 - res = FALSE;
13.144 - goto error;
13.145 - }
13.146 -
13.147 - // Reload all TV chain from Mysql database.
13.148 - gmyth_tvchain_reload_all (livetv->tvchain);
13.149 -
13.150 - if ( livetv->tvchain == NULL ) {
13.151 - res = FALSE;
13.152 - goto error;
13.153 - }
13.154 -
13.155 - // Get program info from database using chanid and starttime
13.156 - livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ );
13.157 - if ( livetv->proginfo == NULL ) {
13.158 - g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
13.159 - res = FALSE;
13.160 - goto error;
13.161 - } else {
13.162 - g_debug ("[%s] MythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
13.163 - }
13.164 -
13.165 - return res;
13.166 -
13.167 -error:
13.168 - if ( livetv->backend_hostname != NULL ) {
13.169 - g_string_free( livetv->backend_hostname, TRUE );
13.170 - res = FALSE;
13.171 - }
13.172 -
13.173 - if ( livetv->local_hostname != NULL ) {
13.174 - g_string_free( livetv->local_hostname, TRUE );
13.175 - res = FALSE;
13.176 - }
13.177 -
13.178 - if ( livetv->remote_encoder != NULL ) {
13.179 - g_object_unref (livetv->remote_encoder);
13.180 - livetv->remote_encoder = NULL;
13.181 - }
13.182 -
13.183 - if ( livetv->tvchain != NULL ) {
13.184 - g_object_unref (livetv->tvchain);
13.185 - livetv->tvchain = NULL;
13.186 - }
13.187 -
13.188 - if ( livetv->proginfo != NULL ) {
13.189 - g_object_unref (livetv->proginfo);
13.190 - livetv->proginfo = NULL;
13.191 - }
13.192 -
13.193 - return res;
13.194 -
13.195 -}
13.196 -
13.197 -// FIXME: How to proceed differently between livetv and recorded content
13.198 -void
13.199 -myth_livetv_stop_playing (MythLiveTV *livetv)
13.200 -{
13.201 - g_debug ("[%s] Stopping the LiveTV...\n", __FUNCTION__);
13.202 -
13.203 - if (livetv->is_livetv) {
13.204 - if (!gmyth_remote_encoder_stop_livetv (livetv->remote_encoder)) {
13.205 - g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);
13.206 - }
13.207 - }
13.208 -}
13.209 -
13.210 -gboolean
13.211 -myth_livetv_is_playing (MythLiveTV *livetv)
13.212 -{
13.213 - return TRUE;
13.214 -}
13.215 -
13.216 -void
13.217 -myth_livetv_start_playing (MythLiveTV *livetv)
13.218 -{
13.219 -
13.220 - // TODO
13.221 -
13.222 -}
13.223 -
14.1 --- a/gst-plugins-mythtv/src/myth_livetv.h Mon Oct 23 14:43:18 2006 +0100
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,59 +0,0 @@
14.4 -#ifndef MYTH_LIVETV_H_
14.5 -#define MYTH_LIVETV_H_
14.6 -
14.7 -#include <glib-object.h>
14.8 -
14.9 -#include <gmyth/gmyth_remote_encoder.h>
14.10 -#include <gmyth/gmyth_tvchain.h>
14.11 -#include <gmyth/gmyth_common.h>
14.12 -
14.13 -#include "myth_file_transfer.h"
14.14 -
14.15 -#define G_BEGIN_DECLS
14.16 -
14.17 -#define MYTH_LIVETV_TYPE (myth_livetv_get_type ())
14.18 -#define MYTH_LIVETV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_LIVETV_TYPE, MythLiveTV))
14.19 -#define MYTH_LIVETV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_LIVETV_TYPE, MythLiveTVClass))
14.20 -#define IS_MYTH_LIVETV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_LIVETV_TYPE))
14.21 -#define IS_MYTH_LIVETV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_LIVETV_TYPE))
14.22 -#define MYTH_LIVETV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MYTH_LIVETV_TYPE, MythLiveTVClass))
14.23 -
14.24 -typedef struct _MythLiveTV MythLiveTV;
14.25 -typedef struct _MythLiveTVClass MythLiveTVClass;
14.26 -
14.27 -struct _MythLiveTVClass
14.28 -{
14.29 - GObjectClass parent_class;
14.30 -
14.31 - /* callbacks */
14.32 -};
14.33 -
14.34 -struct _MythLiveTV
14.35 -{
14.36 - GObject parent;
14.37 -
14.38 - // Backend connection related variables
14.39 - GString *backend_hostname;
14.40 - gint backend_port;
14.41 - GString *local_hostname;
14.42 -
14.43 - GMythRemoteEncoder *remote_encoder;
14.44 - GMythTVChain *tvchain;
14.45 - GMythProgramInfo *proginfo;
14.46 -
14.47 - gboolean is_livetv;
14.48 -
14.49 -};
14.50 -
14.51 -GType myth_livetv_get_type (void);
14.52 -
14.53 -MythLiveTV* myth_livetv_new ();
14.54 -
14.55 -void myth_livetv_start_playing (MythLiveTV *livetv);
14.56 -void myth_livetv_stop_playing (MythLiveTV *livetv);
14.57 -
14.58 -gboolean myth_livetv_setup (MythLiveTV *livetv);
14.59 -
14.60 -#define G_END_DECLS
14.61 -
14.62 -#endif /*MYTH_LIVETV_H_*/
15.1 --- a/gst-plugins-mythtv/src/myth_uri.c Mon Oct 23 14:43:18 2006 +0100
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,208 +0,0 @@
15.4 -/**
15.5 - *
15.6 - * MythURI utils
15.7 - * - Extracts and parses a URI char string, in according with the RFC 2396
15.8 - * [http://www.ietf.org/rfc/rfc2396.txt]
15.9 - *
15.10 - * @author Rosfran Borges (rosfran.borges@indt.org.br)
15.11 - *
15.12 - */
15.13 -
15.14 -#include "myth_uri.h"
15.15 -#include <glib.h>
15.16 -#include <string.h>
15.17 -#include <stdlib.h>
15.18 -
15.19 -static gint
15.20 -myth_strstr( const gchar *haystack, const gchar *needle )
15.21 -{
15.22 -
15.23 - gchar *strPos;
15.24 -
15.25 - if (haystack == NULL || needle == NULL)
15.26 - return -1;
15.27 - strPos = strstr(haystack, needle);
15.28 - if (strPos == NULL)
15.29 - return -1;
15.30 -
15.31 - return (strPos - haystack);
15.32 -
15.33 -}
15.34 -
15.35 -static gboolean
15.36 -myth_uri_isabsolute( const MythURI *uri )
15.37 -{
15.38 - gboolean ret = FALSE;
15.39 -
15.40 - g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE );
15.41 -
15.42 - if ( myth_strstr( uri->uri->str, MYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 )
15.43 - ret = TRUE;
15.44 -
15.45 - return ret;
15.46 -}
15.47 -
15.48 -static gint
15.49 -myth_strrchr( const gchar *str, const gchar *chars, const gint nchars )
15.50 -{
15.51 -
15.52 - gint strLen;
15.53 - gint i, j;
15.54 -
15.55 - if ( str == NULL || chars == NULL )
15.56 - return -1;
15.57 -
15.58 - strLen = strlen( str );
15.59 - for ( i= (strLen-1); 0 <= i; i-- ) {
15.60 - for ( j=0; j<nchars; j++ ) {
15.61 - if ( str[i] == chars[j] )
15.62 - return i;
15.63 - }
15.64 - }
15.65 -
15.66 - return -1;
15.67 -
15.68 -}
15.69 -
15.70 -static MythURI *
15.71 -myth_uri_init( )
15.72 -{
15.73 - MythURI *uri = g_new0( MythURI, 1 );
15.74 - uri->host = g_string_new("");
15.75 - uri->fragment = g_string_new("");
15.76 - uri->password = g_string_new("");
15.77 - uri->path = g_string_new("");
15.78 - uri->protocol = g_string_new("");
15.79 - uri->query = g_string_new("");
15.80 - uri->uri = g_string_new("");
15.81 - uri->user = g_string_new("");
15.82 - return uri;
15.83 -}
15.84 -
15.85 -const MythURI *
15.86 -myth_uri_new( gchar *value )
15.87 -{
15.88 -
15.89 - MythURI *uri = myth_uri_init();
15.90 -
15.91 - gchar *protocol;
15.92 - gint uriLen;
15.93 - gint currIdx;
15.94 - gint protoIdx;
15.95 - gint atIdx;
15.96 - gint colonIdx;
15.97 - gint shashIdx;
15.98 - gchar *host;
15.99 - gint eblacketIdx;
15.100 - GString *hostStr;
15.101 - GString *portStr;
15.102 - gint hostLen;
15.103 - gint sharpIdx;
15.104 - gint questionIdx;
15.105 - gint queryLen;
15.106 -
15.107 - uriLen = strlen(value);
15.108 - uri->uri = g_string_new( value );
15.109 -
15.110 - currIdx = 0;
15.111 -
15.112 - /*** Protocol ****/
15.113 - protoIdx = myth_strstr( value, MYTH_URI_PROTOCOL_DELIM );
15.114 - if (0 < protoIdx) {
15.115 - uri->protocol = g_string_append_len( uri->protocol, value, protoIdx );
15.116 - currIdx += protoIdx + strlen( MYTH_URI_PROTOCOL_DELIM );
15.117 - }
15.118 -
15.119 - /*** User (Password) ****/
15.120 - atIdx = myth_strstr( value+currIdx, MYTH_URI_USER_DELIM );
15.121 - if ( 0 < atIdx ) {
15.122 - colonIdx = myth_strstr( value+currIdx, MYTH_URI_COLON_DELIM );
15.123 -
15.124 - if (0 < colonIdx && colonIdx < atIdx) {
15.125 - uri->user = g_string_append_len( uri->user, value+currIdx, colonIdx );
15.126 - uri->password = g_string_append_len( uri->password, value+currIdx+colonIdx+1, atIdx-(colonIdx+1) );
15.127 - }
15.128 - else
15.129 - uri->user = g_string_append_len( uri->user, value+currIdx, atIdx - currIdx );
15.130 - currIdx += atIdx + 1;
15.131 - }
15.132 -
15.133 - /*** Host (Port) ****/
15.134 - shashIdx = myth_strstr( value+currIdx, MYTH_URI_SLASH_DELIM );
15.135 - if ( 0 < shashIdx )
15.136 - uri->host = g_string_append_len( uri->host, value+currIdx, shashIdx );
15.137 - else if ( myth_uri_isabsolute(uri) == TRUE )
15.138 - uri->host = g_string_append_len( uri->host, value+currIdx, strlen(value) - currIdx );
15.139 - host = g_strdup( myth_uri_gethost(uri) );
15.140 - colonIdx = myth_strrchr( host, MYTH_URI_COLON_DELIM, 1 );
15.141 - eblacketIdx = myth_strrchr( host, MYTH_URI_EBLACET_DELIM, 1 );
15.142 - if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) {
15.143 - hostStr = g_string_new( host );
15.144 -
15.145 - hostLen = hostStr->len;
15.146 - /**** host ****/
15.147 - uri->host = g_string_erase( uri->host, 0, hostLen );
15.148 - uri->host = g_string_insert_len( uri->host, 0, hostStr->str, colonIdx );
15.149 - //host = myth_uri_gethost( uri );
15.150 - if (0 < hostLen) {
15.151 - if (host[0] == '[' && host[hostLen-1] == ']')
15.152 - uri->host = g_string_append_len( uri->host, hostStr->str+1, colonIdx-2 );
15.153 - }
15.154 - /**** port ****/
15.155 - portStr = g_string_new("");
15.156 - portStr = g_string_append_len( portStr, hostStr->str+colonIdx+1, hostLen-colonIdx-1 );
15.157 - uri->port = atoi( portStr->str );
15.158 - g_string_free( portStr, TRUE );
15.159 - g_string_free( hostStr, FALSE );
15.160 - }
15.161 - else {
15.162 - uri->port = MYTH_URI_KNKOWN_PORT;
15.163 - protocol = myth_uri_getprotocol(uri);
15.164 - if ( strcmp(protocol, MYTH_URI_PROTOCOL_HTTP) == 0 )
15.165 - uri->port = MYTH_URI_DEFAULT_HTTP_PORT;
15.166 - if ( strcmp(protocol, MYTH_URI_PROTOCOL_FTP) == 0 )
15.167 - uri->port = MYTH_URI_DEFAULT_FTP_PORT;
15.168 - }
15.169 -
15.170 - if (shashIdx > 0) currIdx += shashIdx;
15.171 -
15.172 - /*
15.173 - Handle relative URL
15.174 - */
15.175 - if (myth_uri_isabsolute(uri) == FALSE)
15.176 - {
15.177 -
15.178 - if (shashIdx != 0)
15.179 - {
15.180 - /* Add slash delimiter at the beginning of the URL,
15.181 - if it doesn't exist
15.182 - */
15.183 - uri->path = g_string_new( MYTH_URI_SLASH_DELIM );
15.184 - }
15.185 - uri->path = g_string_append( uri->path, value );
15.186 -
15.187 - } else {
15.188 - /* First set path simply to the rest of URI */
15.189 - g_string_append_len( uri->path, value+currIdx, uriLen-currIdx );
15.190 - }
15.191 -
15.192 - /**** Path (Query/Fragment) ****/
15.193 - sharpIdx = myth_strstr(value+currIdx, MYTH_URI_SHARP_DELIM);
15.194 - if (0 < sharpIdx) {
15.195 - uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx);
15.196 - uri->fragment = g_string_append_len( uri->fragment,
15.197 - value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1));
15.198 - }
15.199 -
15.200 - questionIdx = myth_strstr( value+currIdx, MYTH_URI_QUESTION_DELIM );
15.201 - if ( 0 < questionIdx ) {
15.202 - uri->path = g_string_append_len( uri->path, value+currIdx, questionIdx );
15.203 - queryLen = uriLen-(currIdx+questionIdx+1);
15.204 - if ( 0 < sharpIdx )
15.205 - queryLen -= uriLen - (currIdx+sharpIdx+1);
15.206 - uri->query = g_string_append_len( uri->query, value+currIdx+questionIdx+1, queryLen );
15.207 - }
15.208 -
15.209 - return uri;
15.210 -
15.211 -}
16.1 --- a/gst-plugins-mythtv/src/myth_uri.h Mon Oct 23 14:43:18 2006 +0100
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,63 +0,0 @@
16.4 -/**
16.5 - *
16.6 - * MythURI utils
16.7 - * - Extracts and parses a URI char string, in according with the RFC 2396
16.8 - * [http://www.ietf.org/rfc/rfc2396.txt]
16.9 - *
16.10 - * @author Rosfran Borges (rosfran.borges@indt.org.br)
16.11 - *
16.12 - */
16.13 -
16.14 -#ifndef _MYTH_URI_H_
16.15 -#define _MYTH_URI_H_
16.16 -
16.17 -#include <glib.h>
16.18 -
16.19 -/****************************************
16.20 -* Define
16.21 -****************************************/
16.22 -
16.23 -#define MYTH_URI_KNKOWN_PORT (-1)
16.24 -#define MYTH_URI_DEFAULT_HTTP_PORT 80
16.25 -#define MYTH_URI_DEFAULT_FTP_PORT 21
16.26 -#define MYTH_URI_DEFAULT_PATH "/"
16.27 -#define MYTH_URI_MAXLEN 256
16.28 -
16.29 -#define MYTH_URI_PROTOCOL_DELIM "://"
16.30 -#define MYTH_URI_USER_DELIM "@"
16.31 -#define MYTH_URI_COLON_DELIM ":"
16.32 -#define MYTH_URI_SLASH_DELIM "/"
16.33 -#define MYTH_URI_SBLACET_DELIM "["
16.34 -#define MYTH_URI_EBLACET_DELIM "]"
16.35 -#define MYTH_URI_SHARP_DELIM "#"
16.36 -#define MYTH_URI_QUESTION_DELIM "?"
16.37 -#define MYTH_URI_ESCAPING_CHAR "%"
16.38 -
16.39 -#define MYTH_URI_PROTOCOL_MYTH "myth"
16.40 -#define MYTH_URI_PROTOCOL_HTTP "http"
16.41 -#define MYTH_URI_PROTOCOL_FTP "ftp"
16.42 -
16.43 -/****************************************
16.44 -* Data Type
16.45 -****************************************/
16.46 -
16.47 -typedef struct _MythURI {
16.48 - GString *uri;
16.49 - GString *host;
16.50 - gint port;
16.51 - GString *protocol;
16.52 - GString *path;
16.53 - GString *fragment;
16.54 - GString *user;
16.55 - GString *password;
16.56 - GString *query;
16.57 -} MythURI;
16.58 -
16.59 -const MythURI *myth_uri_new( gchar *value );
16.60 -
16.61 -#define myth_uri_gethost(urip) (urip->host->str)
16.62 -#define myth_uri_getport(urip) (urip->port)
16.63 -#define myth_uri_getprotocol(urip) (urip->protocol->str)
16.64 -#define myth_uri_getpath(urip) (urip->path->str)
16.65 -
16.66 -#endif