[svn r14] new source tree. trunk
authorabnerf
Tue Sep 26 15:58:37 2006 +0100 (2006-09-26)
branchtrunk
changeset 13f3cdc7844178
parent 12 343d4e3c03ab
child 14 29720bf82e86
[svn r14] new source tree.
gst-plugins-mythtv/Makefile.am
gst-plugins-mythtv/configure.ac
gst-plugins-mythtv/gstmythtvsrc.c
gst-plugins-mythtv/gstmythtvsrc.c.new
gst-plugins-mythtv/gstmythtvsrc.h
gst-plugins-mythtv/myth_file_transfer.c
gst-plugins-mythtv/myth_file_transfer.h
gst-plugins-mythtv/myth_livetv.c
gst-plugins-mythtv/myth_livetv.h
gst-plugins-mythtv/myth_uri.c
gst-plugins-mythtv/myth_uri.h
gst-plugins-mythtv/mythtvsrc-test.c
gst-plugins-mythtv/src/Makefile.am
gst-plugins-mythtv/src/Makefile.in
gst-plugins-mythtv/src/gstmythtvsrc.c
gst-plugins-mythtv/src/gstmythtvsrc.c.new
gst-plugins-mythtv/src/gstmythtvsrc.h
gst-plugins-mythtv/src/myth_file_transfer.c
gst-plugins-mythtv/src/myth_file_transfer.h
gst-plugins-mythtv/src/myth_livetv.c
gst-plugins-mythtv/src/myth_livetv.h
gst-plugins-mythtv/src/myth_uri.c
gst-plugins-mythtv/src/myth_uri.h
gst-plugins-mythtv/src/mythtvsrc-test.c
     1.1 --- a/gst-plugins-mythtv/Makefile.am	Tue Sep 26 15:30:52 2006 +0100
     1.2 +++ b/gst-plugins-mythtv/Makefile.am	Tue Sep 26 15:58:37 2006 +0100
     1.3 @@ -1,27 +1,3 @@
     1.4 -plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
     1.5 +SUBDIRS = src
     1.6  
     1.7 -plugin_LTLIBRARIES =	libgstmythtvsrc.la
     1.8 -
     1.9 -libgstmythtvsrc_la_SOURCES =	\
    1.10 -		gstmythtvsrc.c \
    1.11 -		myth_uri.c \
    1.12 -		myth_file_transfer.c \
    1.13 -		myth_livetv.c
    1.14 -
    1.15 -libgstmythtvsrc_la_CFLAGS = \
    1.16 -	$(GST_CFLAGS) \
    1.17 -	$(GMYTH_CFLAGS)
    1.18 -
    1.19 -libgstmythtvsrc_la_LDFLAGS = \
    1.20 -	$(GST_PLUGIN_LDFLAGS)
    1.21 -
    1.22 -libgstmythtvsrc_la_LIBADD = \
    1.23 -	$(GST_BASE_LIBS) \
    1.24 -	$(GMYTH_LIBS)
    1.25 -
    1.26 -noinst_HEADERS = \
    1.27 -	gstmythtvsrc.h \
    1.28 -	myth_uri.h \
    1.29 -	myth_file_transfer.h \
    1.30 -	myth_livetv.h
    1.31 -
    1.32 +DIST_SUBDIRS = src
     2.1 --- a/gst-plugins-mythtv/configure.ac	Tue Sep 26 15:30:52 2006 +0100
     2.2 +++ b/gst-plugins-mythtv/configure.ac	Tue Sep 26 15:58:37 2006 +0100
     2.3 @@ -5,7 +5,7 @@
     2.4  
     2.5  AC_INIT([mythtvsrc],[0.1])
     2.6  
     2.7 -dnl AC_CONFIG_SRCDIR([src/mmyth_main.c])
     2.8 +dnl AC_CONFIG_SRCDIR([src])
     2.9  AC_CONFIG_HEADER(config.h)
    2.10  
    2.11  dnl when going to/from release please set the nano (fourth number) right !
    2.12 @@ -176,6 +176,9 @@
    2.13  # make GST_MAJORMINOR available in Makefile.am
    2.14  AC_SUBST(GST_MAJORMINOR)
    2.15  
    2.16 -AC_CONFIG_FILES([Makefile])
    2.17 +AC_CONFIG_FILES([
    2.18 +Makefile
    2.19 +src/Makefile
    2.20 +])
    2.21  
    2.22  AC_OUTPUT
     3.1 --- a/gst-plugins-mythtv/gstmythtvsrc.c	Tue Sep 26 15:30:52 2006 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,901 +0,0 @@
     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 -/* GStreamer MythTV Plug-in
     3.6 - * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
     3.7 - *
     3.8 - * This library is free software; you can redistribute it and/or
     3.9 - * modify it under the terms of the GNU Library General Public
    3.10 - * License as published by the Free Software Foundation; either
    3.11 - * version 2 of the License, or (at your option) any later version.
    3.12 - *
    3.13 - * This library is distributed in the hope that it will be useful,
    3.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.16 - * Library General Public License for more 
    3.17 - */
    3.18 -
    3.19 -#ifdef HAVE_CONFIG_H
    3.20 -#include "config.h"
    3.21 -#endif
    3.22 -
    3.23 -#include "gstmythtvsrc.h"
    3.24 -#include "myth_file_transfer.h"
    3.25 -#include "myth_livetv.h"
    3.26 -
    3.27 -#include <gmyth/gmyth_socket.h>
    3.28 -#include <gmyth/gmyth_tvchain.h>
    3.29 -
    3.30 -#include <string.h>
    3.31 -#include <unistd.h>
    3.32 -
    3.33 -GST_DEBUG_CATEGORY_STATIC (mythtvsrc_debug);
    3.34 -#define GST_CAT_DEFAULT mythtvsrc_debug
    3.35 -
    3.36 -#define GST_MYTHTV_ID_NUM		1
    3.37 -
    3.38 -#define MYTHTV_VERSION_DEFAULT		30
    3.39 -
    3.40 -#define MYTHTV_TRANSFER_MAX_WAITS	100
    3.41 -
    3.42 -#define MYTHTV_TRANSFER_MAX_BUFFER	( 32*1024  )
    3.43 -
    3.44 -/* 4*1024 ??? */
    3.45 -#define MAX_READ_SIZE                   ( 16*1024 )
    3.46 -
    3.47 -#define ENABLE_TIMING_POSITION		1
    3.48 -
    3.49 -/* stablish a maximum iteration value to the IS_RECORDING message */
    3.50 -static guint wait_to_transfer = 0;
    3.51 -
    3.52 -static const GstElementDetails gst_mythtv_src_details =
    3.53 -GST_ELEMENT_DETAILS ("MythTV client source",
    3.54 -    "Source/Network",
    3.55 -    "Control and receive data as a client over the network via raw socket connections using the MythTV protocol",
    3.56 -    "Rosfran Borges <rosfran.borges@indt.org.br>");
    3.57 -
    3.58 -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    3.59 -    GST_PAD_SRC,
    3.60 -    GST_PAD_ALWAYS,
    3.61 -    GST_STATIC_CAPS_ANY);
    3.62 -
    3.63 -enum
    3.64 -{
    3.65 -  PROP_0,
    3.66 -  PROP_LOCATION,
    3.67 -  PROP_URI,
    3.68 -#ifndef GST_DISABLE_GST_DEBUG
    3.69 -  PROP_MYTHTV_DBG,
    3.70 -#endif
    3.71 -  PROP_MYTHTV_VERSION,
    3.72 -  PROP_MYTHTV_LIVE,
    3.73 -  PROP_MYTHTV_LIVEID,
    3.74 -  PROP_MYTHTV_LIVE_CHAINID
    3.75 -};
    3.76 -
    3.77 -static void gst_mythtv_src_finalize (GObject * gobject);
    3.78 -
    3.79 -static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc,
    3.80 -    guint64 offset, guint size, GstBuffer ** outbuf);
    3.81 -static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
    3.82 -static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
    3.83 -static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
    3.84 -static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *base_src );
    3.85 -
    3.86 -static void gst_mythtv_src_set_property (GObject * object, guint prop_id,
    3.87 -    const GValue * value, GParamSpec * pspec);
    3.88 -static void gst_mythtv_src_get_property (GObject * object, guint prop_id,
    3.89 -    GValue * value, GParamSpec * pspec);
    3.90 -
    3.91 -static void
    3.92 -gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
    3.93 -
    3.94 -static gboolean
    3.95 -gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
    3.96 -
    3.97 -  static void
    3.98 -_urihandler_init (GType type)
    3.99 -{
   3.100 -  static const GInterfaceInfo urihandler_info = {
   3.101 -    gst_mythtv_src_uri_handler_init,
   3.102 -    NULL,
   3.103 -    NULL
   3.104 -  };
   3.105 -
   3.106 -  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
   3.107 -
   3.108 -  GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
   3.109 -      "MythTV src");
   3.110 -}
   3.111 -
   3.112 -GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstBaseSrc,
   3.113 -    GST_TYPE_BASE_SRC, _urihandler_init);
   3.114 -
   3.115 -  static void
   3.116 -gst_mythtv_src_base_init (gpointer g_class)
   3.117 -{
   3.118 -  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
   3.119 -
   3.120 -  gst_element_class_add_pad_template (element_class,
   3.121 -      gst_static_pad_template_get (&srctemplate));
   3.122 -
   3.123 -  gst_element_class_set_details (element_class, &gst_mythtv_src_details);
   3.124 -}
   3.125 -
   3.126 -  static void
   3.127 -gst_mythtv_src_class_init (GstMythtvSrcClass * klass)
   3.128 -{
   3.129 -  GObjectClass *gobject_class;
   3.130 -  GstBaseSrcClass *gstbasesrc_class;
   3.131 -
   3.132 -  gobject_class = (GObjectClass *) klass;
   3.133 -  gstbasesrc_class = (GstBaseSrcClass *) klass;
   3.134 -
   3.135 -  gobject_class->set_property = gst_mythtv_src_set_property;
   3.136 -  gobject_class->get_property = gst_mythtv_src_get_property;
   3.137 -  gobject_class->finalize = gst_mythtv_src_finalize;
   3.138 -
   3.139 -  g_object_class_install_property
   3.140 -    (gobject_class, PROP_LOCATION,
   3.141 -     g_param_spec_string ("location", "Location",
   3.142 -       "The location. In the form:"
   3.143 -       "\n\t\t\tmyth://a.com/file.nuv"
   3.144 -       "\n\t\t\tmyth://a.com:23223/file.nuv "
   3.145 -       "\n\t\t\ta.com/file.nuv - default scheme 'myth'",
   3.146 -       "", G_PARAM_READWRITE));
   3.147 -
   3.148 -  g_object_class_install_property
   3.149 -    (gobject_class, PROP_URI,
   3.150 -     g_param_spec_string ("uri", "Uri",
   3.151 -       "The location in form of a URI (deprecated; use location)",
   3.152 -       "", G_PARAM_READWRITE));
   3.153 -
   3.154 -  g_object_class_install_property
   3.155 -    (gobject_class, PROP_MYTHTV_VERSION,
   3.156 -     g_param_spec_int ("mythtv-version", "mythtv-version",
   3.157 -       "Change Myth TV version",
   3.158 -       26, 30, 26, G_PARAM_READWRITE));
   3.159 -
   3.160 -  g_object_class_install_property
   3.161 -    (gobject_class, PROP_MYTHTV_LIVEID,
   3.162 -     g_param_spec_int ("mythtv-live-id", "mythtv-live-id",
   3.163 -       "Change Myth TV version",
   3.164 -       0, 200, GST_MYTHTV_ID_NUM, G_PARAM_READWRITE));
   3.165 -
   3.166 -  g_object_class_install_property
   3.167 -    (gobject_class, PROP_MYTHTV_LIVE_CHAINID,
   3.168 -     g_param_spec_string ("mythtv-live-chainid", "mythtv-live-chainid",
   3.169 -       "Sets the Myth TV chain ID (from TV Chain)",
   3.170 -       "", G_PARAM_READWRITE));
   3.171 -
   3.172 -  g_object_class_install_property
   3.173 -    (gobject_class, PROP_MYTHTV_LIVE,
   3.174 -     g_param_spec_boolean ("mythtv-live", "mythtv-live",
   3.175 -       "Enable MythTV Live TV content streaming",
   3.176 -       FALSE, G_PARAM_READWRITE));
   3.177 -
   3.178 -#ifndef GST_DISABLE_GST_DEBUG
   3.179 -  g_object_class_install_property
   3.180 -    (gobject_class, PROP_MYTHTV_DBG,
   3.181 -     g_param_spec_boolean ("mythtv-debug", "mythtv-debug",
   3.182 -       "Enable MythTV debug messages",
   3.183 -       FALSE, G_PARAM_READWRITE));
   3.184 -#endif
   3.185 -
   3.186 -  gstbasesrc_class->start = gst_mythtv_src_start;
   3.187 -  gstbasesrc_class->stop = gst_mythtv_src_stop;
   3.188 -  gstbasesrc_class->get_size = gst_mythtv_src_get_size;
   3.189 -  gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
   3.190 -
   3.191 -  gstbasesrc_class->create = gst_mythtv_src_create;
   3.192 -
   3.193 -
   3.194 -  GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
   3.195 -      "MythTV Client Source");
   3.196 -}
   3.197 -
   3.198 -  static void
   3.199 -gst_mythtv_src_init (GstMythtvSrc * this, GstMythtvSrcClass * g_class)
   3.200 -{
   3.201 -  this->file_transfer = NULL;
   3.202 -
   3.203 -  this->unique_setup = FALSE;
   3.204 -
   3.205 -  this->mythtv_version = MYTHTV_VERSION_DEFAULT;
   3.206 -
   3.207 -  this->bytes_read = 0;
   3.208 -
   3.209 -  this->content_size = -1;
   3.210 -  this->read_offset = 0;
   3.211 -
   3.212 -  this->live_tv = FALSE;
   3.213 -
   3.214 -  this->user_agent = g_strdup ("mythtvsrc");
   3.215 -  this->mythtv_caps = NULL;    
   3.216 -
   3.217 -  gst_pad_set_event_function (GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
   3.218 -      GST_DEBUG_FUNCPTR (gst_mythtv_src_handle_event));
   3.219 -
   3.220 -}
   3.221 -
   3.222 -  static void
   3.223 -gst_mythtv_src_finalize (GObject * gobject)
   3.224 -{
   3.225 -  GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
   3.226 -
   3.227 -  g_free (this->user_agent);
   3.228 -
   3.229 -  if (this->mythtv_caps) {
   3.230 -    gst_caps_unref (this->mythtv_caps);
   3.231 -    this->mythtv_caps = NULL;
   3.232 -  }
   3.233 -
   3.234 -  if (this->file_transfer) {
   3.235 -    g_object_unref (this->file_transfer);
   3.236 -    this->file_transfer = NULL;
   3.237 -  }
   3.238 -
   3.239 -  if (this->uri_name) {
   3.240 -    g_free (this->uri_name);
   3.241 -  }
   3.242 -
   3.243 -  if (this->user_agent) {
   3.244 -    g_free (this->user_agent);
   3.245 -  }
   3.246 -
   3.247 -  G_OBJECT_CLASS (parent_class)->finalize (gobject);
   3.248 -}
   3.249 -
   3.250 -#if 0
   3.251 -  static guint
   3.252 -do_seek( GstMythtvSrc *src, guint64 offset, guint size, GstBuffer *outbuf )
   3.253 -{
   3.254 -  guint64 off_uint64 = myth_file_transfer_seek(src->file_transfer, offset, 1);
   3.255 -
   3.256 -  g_print( "[%s] Call MythTV SEEK with offset %llu, got a new one %llu...\n", __FUNCTION__, 
   3.257 -      offset, off_uint64 );
   3.258 -
   3.259 -  return off_uint64;
   3.260 -
   3.261 -}
   3.262 -#endif
   3.263 -
   3.264 -  static guint
   3.265 -do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer * outbuf)
   3.266 -{
   3.267 -  guint read = 0;
   3.268 -  guint sizetoread = size; //GST_BUFFER_SIZE (outbuf);
   3.269 -
   3.270 -  g_print( "[%s] Reading %d bytes...\n", __FUNCTION__, sizetoread ); 
   3.271 -
   3.272 -  /* Loop sending the request:
   3.273 -   * Retry whilst authentication fails and we supply it. */
   3.274 -
   3.275 -  ssize_t len = 0;
   3.276 -
   3.277 -  GST_OBJECT_LOCK(src);
   3.278 -
   3.279 -  while ( sizetoread > 0 ) {
   3.280 -
   3.281 -    len = myth_file_transfer_read( src->file_transfer,
   3.282 -	GST_BUFFER_DATA (outbuf) + read, sizetoread, TRUE );
   3.283 -
   3.284 -    if ( len > 0 ) {
   3.285 -      read += len;
   3.286 -      src->read_offset += read;
   3.287 -      sizetoread -= len;
   3.288 -    } else if ( len < 0 ) {
   3.289 -      goto done;
   3.290 -    }
   3.291 -    /*else if ( len == 0 ) {
   3.292 -      goto eos;
   3.293 -    }*/
   3.294 -
   3.295 -    if ( len == sizetoread )
   3.296 -      break;
   3.297 -
   3.298 -  }
   3.299 -
   3.300 -  if ( read > 0 ) {
   3.301 -    src->bytes_read += read;
   3.302 -
   3.303 -    GST_BUFFER_SIZE (outbuf) = read;
   3.304 -  } else if ( read <= 0 || len <= 0 ) {
   3.305 -    if ( src->live_tv == FALSE )
   3.306 -      goto eos;
   3.307 -    else
   3.308 -      goto done;
   3.309 -  }
   3.310 -  //GST_BUFFER_OFFSET (outbuf) = src->read_offset;
   3.311 -
   3.312 -  g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
   3.313 -      "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read, 
   3.314 -      src->read_offset, src->content_size );
   3.315 -
   3.316 -  GST_OBJECT_UNLOCK(src);
   3.317 -
   3.318 -  if ( len < 0 ) {
   3.319 -    read = len;
   3.320 -    if ( src->live_tv == FALSE ) 
   3.321 -      goto eos;
   3.322 -    else
   3.323 -      goto done;
   3.324 -  }
   3.325 -
   3.326 -  if ( src->bytes_read < src->content_size )
   3.327 -    goto done;
   3.328 -
   3.329 -eos:
   3.330 -  GST_OBJECT_UNLOCK(src);
   3.331 -
   3.332 -  src->eos = TRUE;
   3.333 -done:
   3.334 -  GST_OBJECT_UNLOCK(src);
   3.335 -
   3.336 -  return read;
   3.337 -}
   3.338 -
   3.339 -  static GstFlowReturn
   3.340 -gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset, 
   3.341 -    guint size, GstBuffer **outbuf )
   3.342 -{
   3.343 -  GstMythtvSrc *src;
   3.344 -  GstFlowReturn ret = GST_FLOW_OK;
   3.345 -  guint read;
   3.346 -  guint64 size_tmp = 0;
   3.347 -
   3.348 -  src = GST_MYTHTV_SRC (psrc);
   3.349 -
   3.350 -  g_print( "[%s]\tBUFFER OFFSET = %llu, BUFFER SIZE = %d.\n", __FUNCTION__, offset, 
   3.351 -      size );
   3.352 -
   3.353 -
   3.354 -  /* The caller should know the number of bytes and not read beyond EOS. */
   3.355 -  if (G_UNLIKELY (src->eos))
   3.356 -    goto eos;
   3.357 -
   3.358 -  /* Create the buffer. */
   3.359 -  ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
   3.360 -      //      GST_BUFFER_OFFSET_NONE, GST_BASE_SRC (psrc)->blocksize,
   3.361 -      offset, size,
   3.362 -      src->mythtv_caps ? src->mythtv_caps :
   3.363 -      GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
   3.364 -
   3.365 -  if (G_UNLIKELY (ret == GST_FLOW_UNEXPECTED))
   3.366 -    goto eos;
   3.367 -
   3.368 -  if (G_UNLIKELY (ret != GST_FLOW_OK))
   3.369 -    goto done;
   3.370 -
   3.371 -  read = do_read_request_response ( src, offset, size, *outbuf );
   3.372 -
   3.373 -#if ENABLE_TIMING_POSITION == 1
   3.374 -  if (src->live_tv == TRUE) {
   3.375 -    //g_usleep( 1000 );
   3.376 -get_file_pos:
   3.377 -    //g_usleep( 100 );
   3.378 -    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
   3.379 -    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
   3.380 -      src->content_size = size_tmp;
   3.381 -    else
   3.382 -      goto get_file_pos;
   3.383 -    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
   3.384 -	__FUNCTION__, size_tmp);
   3.385 -
   3.386 -  }
   3.387 -#endif
   3.388 -
   3.389 -  if (G_UNLIKELY (read < 0))
   3.390 -    goto read_error;
   3.391 -
   3.392 -  if (G_UNLIKELY(src->eos))
   3.393 -    goto eos;
   3.394 -
   3.395 -done:
   3.396 -  return ret;
   3.397 -eos:
   3.398 -#if ENABLE_TIMING_POSITION == 1
   3.399 -  if ( src->live_tv == TRUE ) {
   3.400 -    //g_usleep( 1000 );
   3.401 -    guint64 size_tmp = 0;
   3.402 -get_file_pos_eos:
   3.403 -    //g_usleep( 100 );
   3.404 -    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
   3.405 -    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
   3.406 -      src->content_size = size_tmp;
   3.407 -    else
   3.408 -      goto get_file_pos_eos;
   3.409 -    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
   3.410 -	__FUNCTION__, size_tmp);
   3.411 -    goto done;
   3.412 -  } else 
   3.413 -#endif
   3.414 -  {
   3.415 -    GST_DEBUG_OBJECT (src, "EOS reached");
   3.416 -    return GST_FLOW_UNEXPECTED;
   3.417 -  }
   3.418 -  /* ERRORS */
   3.419 -read_error:
   3.420 -  {
   3.421 -    GST_ELEMENT_ERROR (src, RESOURCE, READ,
   3.422 -	(NULL), ("Could not read any bytes (%i, %s)", read,
   3.423 -	  src->uri_name));
   3.424 -    return GST_FLOW_ERROR;
   3.425 -  }
   3.426 -}
   3.427 -
   3.428 -#if 0
   3.429 -/* The following two charset mangling functions were copied from gnomevfssrc.
   3.430 - * Preserve them under the unverified assumption that they do something vaguely
   3.431 - * worthwhile.
   3.432 - */
   3.433 -  static char *
   3.434 -unicodify (const char *str, int len, ...)
   3.435 -{
   3.436 -  char *ret = NULL, *cset;
   3.437 -  va_list args;
   3.438 -  gsize bytes_read, bytes_written;
   3.439 -
   3.440 -  if (g_utf8_validate (str, len, NULL))
   3.441 -    return g_strndup (str, len >= 0 ? len : strlen (str));
   3.442 -
   3.443 -  va_start (args, len);
   3.444 -  while ((cset = va_arg (args, char *)) != NULL)
   3.445 -  {
   3.446 -    if (!strcmp (cset, "locale"))
   3.447 -      ret = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, NULL);
   3.448 -    else
   3.449 -      ret = g_convert (str, len, "UTF-8", cset,
   3.450 -	  &bytes_read, &bytes_written, NULL);
   3.451 -    if (ret)
   3.452 -      break;
   3.453 -  }
   3.454 -  va_end (args);
   3.455 -
   3.456 -  return ret;
   3.457 -}
   3.458 -
   3.459 -  static char *
   3.460 -gst_mythtv_src_unicodify (const char *str)
   3.461 -{
   3.462 -  return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
   3.463 -}
   3.464 -#endif
   3.465 -
   3.466 -/* create a socket for connecting to remote server */
   3.467 -  static gboolean
   3.468 -gst_mythtv_src_start ( GstBaseSrc * bsrc )
   3.469 -{
   3.470 -  GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc);
   3.471 -
   3.472 -  GString *chain_id_local = NULL;
   3.473 -
   3.474 -  gboolean ret = TRUE;
   3.475 -#if 0
   3.476 -  if (src->live_tv == TRUE && src->file_transfer != NULL) {
   3.477 -    guint64 size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
   3.478 -    if (size_tmp > src->content_size)
   3.479 -      src->content_size = size_tmp;
   3.480 -    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
   3.481 -	__FUNCTION__, size_tmp);
   3.482 -  }
   3.483 -#endif
   3.484 -  if (src->unique_setup == FALSE) {
   3.485 -    src->unique_setup = TRUE;
   3.486 -  } else {
   3.487 -    goto done;
   3.488 -  }
   3.489 -
   3.490 -  GST_OBJECT_LOCK(src);
   3.491 -
   3.492 -  if ( src->live_tv ) {
   3.493 -    src->spawn_livetv = myth_livetv_new( );
   3.494 -    if ( myth_livetv_setup( src->spawn_livetv ) == FALSE ) {
   3.495 -    	ret = FALSE;
   3.496 -    	goto init_failed;
   3.497 -    }
   3.498 -    /* set up the uri variable */
   3.499 -    src->uri_name = g_strdup( src->spawn_livetv->proginfo->pathname->str );
   3.500 -    chain_id_local = gmyth_tvchain_get_id( src->spawn_livetv->tvchain );
   3.501 -    if ( chain_id_local != NULL ) {
   3.502 -      src->live_chain_id = g_strdup( chain_id_local->str );
   3.503 -      g_print( "\t[%s]\tLocal chain ID = %s.\n", __FUNCTION__, src->live_chain_id );
   3.504 -    }
   3.505 -    src->live_tv_id = src->spawn_livetv->remote_encoder->recorder_num;
   3.506 -    g_print ( "[%s] LiveTV id = %d, URI path = %s.\n", __FUNCTION__, src->live_tv_id, src->uri_name );
   3.507 -  }
   3.508 -
   3.509 -  src->file_transfer = myth_file_transfer_new( src->live_tv_id, 
   3.510 -      g_string_new( src->uri_name ), -1, src->mythtv_version );
   3.511 -
   3.512 -  if ( src->file_transfer == NULL ) {
   3.513 -    GST_OBJECT_UNLOCK(src);
   3.514 -
   3.515 -    goto init_failed;
   3.516 -  }
   3.517 -
   3.518 -  if ( src->live_tv ) {
   3.519 -    g_print ( "[%s] GST MYTHTVSRC: live_chain_id = %s\n", __FUNCTION__, src->live_chain_id );
   3.520 -    /* sets the MythSocket to the FileTransfer */
   3.521 -    //ret = myth_file_transfer_livetv_setup( &(src->file_transfer), src->spawn_livetv->remote_encoder->myth_socket );
   3.522 -  }
   3.523 -  /* sets the Playback monitor connection */
   3.524 -  ret = myth_file_transfer_playback_setup( &(src->file_transfer), src->live_tv );
   3.525 -
   3.526 -  if ( src->live_tv == TRUE && ret == TRUE ) {
   3.527 -    /* loop finished, set the max tries variable to zero again... */
   3.528 -    wait_to_transfer = 0;
   3.529 -
   3.530 -    while ( wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS && ( myth_file_transfer_is_recording( src->file_transfer ) == FALSE 
   3.531 -	  /*|| ( myth_file_transfer_get_file_position( src->file_transfer ) < ( src->content_size + 327680 ) )*/ ) )
   3.532 -      g_usleep( 100 );
   3.533 -  }
   3.534 -
   3.535 -  /* sets the FileTransfer instance connection (video/audio download) */
   3.536 -  ret = myth_file_transfer_setup( &(src->file_transfer), src->live_tv );
   3.537 -
   3.538 -  if ( ret == FALSE ) {
   3.539 -    GST_OBJECT_UNLOCK(src);
   3.540 -#ifndef GST_DISABLE_GST_DEBUG  
   3.541 -    if ( src->mythtv_msgs_dbg )
   3.542 -      g_printerr( "MythTV FileTransfer request failed when setting up socket connection!\n" );  	  
   3.543 -#endif
   3.544 -    goto begin_req_failed;
   3.545 -  }
   3.546 -
   3.547 -  src->content_size = src->file_transfer->filesize;
   3.548 -
   3.549 -  GST_OBJECT_UNLOCK(src);
   3.550 -
   3.551 -#if 0
   3.552 -  const char *str_value;
   3.553 -  gint gint_value;
   3.554 -
   3.555 -  str_value = ne_get_response_header (src->request, "myth-metaint");
   3.556 -  if (str_value) {
   3.557 -    if ( sscanf (str_value, "%d", &gint_value) == 1 ) {
   3.558 -      if (src->myth_caps) {
   3.559 -	gst_caps_unref (src->myth_caps);
   3.560 -	src->myth_caps = NULL;
   3.561 -      }
   3.562 -      src->myth_metaint = gint_value;
   3.563 -#endif
   3.564 -      //src->mythtv_caps = gst_caps_new_simple ("application/x-gst_ff-nuv", NULL);
   3.565 -      //   }
   3.566 -      // }
   3.567 -done:
   3.568 -      return TRUE;
   3.569 -
   3.570 -      /* ERRORS */
   3.571 -init_failed:
   3.572 -      {
   3.573 -      	if (src->spawn_livetv != NULL )
   3.574 -	  g_object_unref( src->spawn_livetv );
   3.575 -
   3.576 -	GST_ELEMENT_ERROR (src, LIBRARY, INIT,
   3.577 -	    (NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name));
   3.578 -	return FALSE;
   3.579 -      }
   3.580 -begin_req_failed:
   3.581 -      {
   3.582 -	GST_ELEMENT_ERROR (src, LIBRARY, INIT,
   3.583 -	    (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name));
   3.584 -	return FALSE;
   3.585 -      }
   3.586 -}
   3.587 -
   3.588 -  static gboolean
   3.589 -gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
   3.590 -{
   3.591 -  GstMythtvSrc *src;
   3.592 -
   3.593 -  src = GST_MYTHTV_SRC (bsrc);
   3.594 -#if ENABLE_TIMING_POSITION == 1
   3.595 -  guint64 size_tmp = 0; 
   3.596 -  if (src->live_tv == TRUE) {
   3.597 -get_file_pos:
   3.598 -    //g_usleep( 100 );
   3.599 -    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
   3.600 -    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
   3.601 -      src->content_size = size_tmp;
   3.602 -    else
   3.603 -      goto get_file_pos;
   3.604 -    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
   3.605 -	__FUNCTION__, size_tmp);
   3.606 -  }
   3.607 -#endif
   3.608 -  if (src->content_size <= 0)
   3.609 -    return FALSE;
   3.610 -
   3.611 -  *size = src->content_size;
   3.612 -
   3.613 -  return TRUE;
   3.614 -}
   3.615 -
   3.616 -/* close the socket and associated resources
   3.617 - * used both to recover from errors and go to NULL state */
   3.618 -  static gboolean
   3.619 -gst_mythtv_src_stop (GstBaseSrc * bsrc)
   3.620 -{
   3.621 -  GstMythtvSrc *src;
   3.622 -
   3.623 -  src = GST_MYTHTV_SRC (bsrc);
   3.624 -
   3.625 -  if (src->uri_name) {
   3.626 -    g_free (src->uri_name);
   3.627 -    src->uri_name = NULL;
   3.628 -  }
   3.629 -
   3.630 -  if (src->mythtv_caps) {
   3.631 -    gst_caps_unref (src->mythtv_caps);
   3.632 -    src->mythtv_caps = NULL;
   3.633 -  }
   3.634 -
   3.635 -  src->eos = FALSE;
   3.636 -
   3.637 -  return TRUE;
   3.638 -}
   3.639 -
   3.640 -  static gboolean
   3.641 -gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event)
   3.642 -{
   3.643 -  GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
   3.644 -
   3.645 -  switch (GST_EVENT_TYPE (event)) {
   3.646 -    case GST_EVENT_FLUSH_START:
   3.647 -      src->eos = FALSE;
   3.648 -      break;
   3.649 -      //return TRUE;
   3.650 -    case GST_EVENT_FLUSH_STOP:
   3.651 -      src->do_start = TRUE;
   3.652 -      src->eos = FALSE;
   3.653 -      gst_element_set_state (GST_ELEMENT(src), GST_STATE_NULL);
   3.654 -      gst_element_set_locked_state (GST_ELEMENT(src), TRUE);
   3.655 -      break;
   3.656 -    case GST_EVENT_SEEK:  	  
   3.657 -      {
   3.658 -	gdouble rate;
   3.659 -	//gboolean update = TRUE;
   3.660 -	GstFormat format;
   3.661 -	GstSeekType cur_type, stop_type;
   3.662 -	GstSeekFlags flags;
   3.663 -	gint64 cur = 0, stop = 0;
   3.664 -	gst_event_parse_seek ( event, &rate, &format,
   3.665 -	    &flags, &cur_type, &cur,
   3.666 -	    &stop_type, &stop );
   3.667 -
   3.668 -	g_print( "[%s] Got EVENT_SEEK.\n", __FUNCTION__ );
   3.669 -	if ( !( flags & GST_SEEK_FLAG_FLUSH ) ) {
   3.670 -	  g_print( "[%s] Could get the FLAG_FLUSH message.\n", __FUNCTION__ );
   3.671 -	}
   3.672 -	//gboolean ret = gst_event_parse_new_segment ( event,
   3.673 -	//    &update, &rate, &format, &start, &stop,
   3.674 -	//    &position );
   3.675 -	//GstFlowReturn flow_ret = gst_mythtv_src_create (GST_BASE_SRC( GST_PAD_PARENT( psrc ) ), 
   3.676 -	//			cur, stop - cur + 1, GstBuffer)
   3.677 -
   3.678 -      } 
   3.679 -    default:
   3.680 -      return gst_pad_event_default (pad, event);
   3.681 -  }
   3.682 -
   3.683 -  return gst_pad_event_default (pad, event);
   3.684 -}
   3.685 -
   3.686 -  static gboolean
   3.687 -gst_mythtv_src_is_seekable( GstBaseSrc *base_src )
   3.688 -{
   3.689 -  return TRUE;
   3.690 -}
   3.691 -
   3.692 -  static void
   3.693 -gst_mythtv_src_set_property (GObject * object, guint prop_id,
   3.694 -    const GValue * value, GParamSpec * pspec)
   3.695 -{
   3.696 -  GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
   3.697 -
   3.698 -  GST_OBJECT_LOCK (mythtvsrc);
   3.699 -  switch (prop_id) {
   3.700 -    case PROP_URI:
   3.701 -    case PROP_LOCATION:
   3.702 -      {
   3.703 -	if (!g_value_get_string (value)) {
   3.704 -	  GST_WARNING ("location property cannot be NULL");
   3.705 -	  goto done;
   3.706 -	}
   3.707 -
   3.708 -	if (mythtvsrc->uri_name != NULL) {
   3.709 -	  g_free (mythtvsrc->uri_name);
   3.710 -	  mythtvsrc->uri_name = NULL;
   3.711 -	}
   3.712 -	mythtvsrc->uri_name = g_value_dup_string (value);
   3.713 -
   3.714 -	break;
   3.715 -      }
   3.716 -#ifndef GST_DISABLE_GST_DEBUG
   3.717 -    case PROP_MYTHTV_DBG:
   3.718 -      {
   3.719 -	mythtvsrc->mythtv_msgs_dbg = g_value_get_boolean (value);
   3.720 -	break;
   3.721 -      }
   3.722 -#endif
   3.723 -    case PROP_MYTHTV_VERSION:
   3.724 -      {
   3.725 -	mythtvsrc->mythtv_version = g_value_get_int (value);
   3.726 -	break;
   3.727 -      }
   3.728 -    case PROP_MYTHTV_LIVEID:
   3.729 -      {
   3.730 -	mythtvsrc->live_tv_id = g_value_get_int (value);
   3.731 -	break;
   3.732 -      }
   3.733 -    case PROP_MYTHTV_LIVE:
   3.734 -      {
   3.735 -	mythtvsrc->live_tv = g_value_get_boolean (value);
   3.736 -	break;
   3.737 -      }
   3.738 -    case PROP_MYTHTV_LIVE_CHAINID:
   3.739 -      {
   3.740 -	if (!g_value_get_string (value)) {
   3.741 -	  GST_WARNING ("MythTV Live chainid property cannot be NULL");
   3.742 -	  goto done;
   3.743 -	}
   3.744 -
   3.745 -	if (mythtvsrc->live_chain_id != NULL) {
   3.746 -	  g_free (mythtvsrc->live_chain_id);
   3.747 -	  mythtvsrc->live_chain_id = NULL;
   3.748 -	}
   3.749 -	mythtvsrc->live_chain_id = g_value_dup_string (value);
   3.750 -
   3.751 -	break;
   3.752 -      }
   3.753 -
   3.754 -    default:
   3.755 -      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   3.756 -      break;
   3.757 -  }
   3.758 -  GST_OBJECT_UNLOCK (mythtvsrc);
   3.759 -done:
   3.760 -  return;
   3.761 -}
   3.762 -
   3.763 -  static void
   3.764 -gst_mythtv_src_get_property (GObject * object, guint prop_id,
   3.765 -    GValue * value, GParamSpec * pspec)
   3.766 -{
   3.767 -  GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
   3.768 -
   3.769 -  GST_OBJECT_LOCK (mythtvsrc);
   3.770 -  switch (prop_id) {
   3.771 -    case PROP_URI:
   3.772 -    case PROP_LOCATION:
   3.773 -      {
   3.774 -	gchar *str = g_strdup( "" );
   3.775 -
   3.776 -	if ( mythtvsrc->uri_name == NULL ) {
   3.777 -	  g_free (mythtvsrc->uri_name);
   3.778 -	  mythtvsrc->uri_name = NULL;
   3.779 -	} else {
   3.780 -	  str = g_strdup( mythtvsrc->uri_name );
   3.781 -	}
   3.782 -	g_value_set_string ( value, str );
   3.783 -	break;
   3.784 -      }
   3.785 -#ifndef GST_DISABLE_GST_DEBUG
   3.786 -    case PROP_MYTHTV_DBG:
   3.787 -      g_value_set_boolean ( value, mythtvsrc->mythtv_msgs_dbg );
   3.788 -      break;
   3.789 -#endif
   3.790 -    case PROP_MYTHTV_VERSION:
   3.791 -      {
   3.792 -	g_value_set_int ( value, mythtvsrc->mythtv_version );
   3.793 -	break;
   3.794 -      }
   3.795 -    case PROP_MYTHTV_LIVEID:
   3.796 -      {
   3.797 -	g_value_set_int ( value, mythtvsrc->live_tv_id );
   3.798 -	break;
   3.799 -      }
   3.800 -    case PROP_MYTHTV_LIVE:
   3.801 -      g_value_set_boolean ( value, mythtvsrc->live_tv );
   3.802 -      break;
   3.803 -    case PROP_MYTHTV_LIVE_CHAINID:
   3.804 -      {
   3.805 -	gchar *str = g_strdup( "" );
   3.806 -
   3.807 -	if ( mythtvsrc->live_chain_id == NULL ) {
   3.808 -	  g_free (mythtvsrc->live_chain_id);
   3.809 -	  mythtvsrc->live_chain_id = NULL;
   3.810 -	} else {
   3.811 -	  str = g_strdup( mythtvsrc->live_chain_id );
   3.812 -	}
   3.813 -	g_value_set_string ( value, str );
   3.814 -	break;
   3.815 -      }
   3.816 -    default:
   3.817 -      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   3.818 -      break;
   3.819 -  }
   3.820 -  GST_OBJECT_UNLOCK (mythtvsrc);
   3.821 -}
   3.822 -
   3.823 -/* entry point to initialize the plug-in
   3.824 - * initialize the plug-in itself
   3.825 - * register the element factories and pad templates
   3.826 - * register the features
   3.827 - */
   3.828 -  static gboolean
   3.829 -plugin_init (GstPlugin * plugin)
   3.830 -{
   3.831 -  return gst_element_register (plugin, "mythtvsrc", GST_RANK_NONE,
   3.832 -      GST_TYPE_MYTHTV_SRC);
   3.833 -}
   3.834 -
   3.835 -/* this is the structure that gst-register looks for
   3.836 - * so keep the name plugin_desc, or you cannot get your plug-in registered */
   3.837 -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
   3.838 -    GST_VERSION_MINOR,
   3.839 -    "mythtv",
   3.840 -    "lib MythTV src",
   3.841 -    plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
   3.842 -
   3.843 -
   3.844 -/*** GSTURIHANDLER INTERFACE *************************************************/
   3.845 -  static guint 
   3.846 -gst_mythtv_src_uri_get_type (void)
   3.847 -{
   3.848 -  return GST_URI_SRC;
   3.849 -}
   3.850 -
   3.851 -  static gchar **
   3.852 -gst_mythtv_src_uri_get_protocols (void)
   3.853 -{
   3.854 -  static gchar *protocols[] = { "myth", "myths", NULL };
   3.855 -
   3.856 -  return protocols;
   3.857 -}
   3.858 -
   3.859 -  static const gchar *
   3.860 -gst_mythtv_src_uri_get_uri (GstURIHandler * handler)
   3.861 -{
   3.862 -  GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
   3.863 -
   3.864 -  return src->uri_name;
   3.865 -}
   3.866 -
   3.867 -  static gboolean
   3.868 -gst_mythtv_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
   3.869 -{
   3.870 -  GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
   3.871 -
   3.872 -  gchar *protocol;
   3.873 -
   3.874 -  protocol = gst_uri_get_protocol (uri);
   3.875 -  if ((strcmp (protocol, "myth") != 0) && (strcmp (protocol, "myths") != 0)) {
   3.876 -    g_free (protocol);
   3.877 -    return FALSE;
   3.878 -  }
   3.879 -  g_free (protocol);
   3.880 -  g_object_set (src, "location", uri, NULL);
   3.881 -
   3.882 -  return TRUE;
   3.883 -}
   3.884 -
   3.885 -  static void
   3.886 -gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
   3.887 -{
   3.888 -  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
   3.889 -
   3.890 -  iface->get_type = gst_mythtv_src_uri_get_type;
   3.891 -  iface->get_protocols = gst_mythtv_src_uri_get_protocols;
   3.892 -  iface->get_uri = gst_mythtv_src_uri_get_uri;
   3.893 -  iface->set_uri = gst_mythtv_src_uri_set_uri;
   3.894 -}
   3.895 -
   3.896 -  void
   3.897 -size_header_handler (void *userdata, const char *value)
   3.898 -{
   3.899 -  GstMythtvSrc *src = GST_MYTHTV_SRC (userdata);
   3.900 -
   3.901 -  //src->content_size = g_ascii_strtoull (value, NULL, 10);
   3.902 -
   3.903 -  GST_DEBUG_OBJECT (src, "content size = %lld bytes", src->content_size);
   3.904 -}
     4.1 --- a/gst-plugins-mythtv/gstmythtvsrc.c.new	Tue Sep 26 15:30:52 2006 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,1033 +0,0 @@
     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 -/* GStreamer MythTV Plug-in
     4.6 - * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
     4.7 - *
     4.8 - * This library is free software; you can redistribute it and/or
     4.9 - * modify it under the terms of the GNU Library General Public
    4.10 - * License as published by the Free Software Foundation; either
    4.11 - * version 2 of the License, or (at your option) any later version.
    4.12 - *
    4.13 - * This library is distributed in the hope that it will be useful,
    4.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.16 - * Library General Public License for more 
    4.17 - */
    4.18 -
    4.19 -#ifdef HAVE_CONFIG_H
    4.20 -#include "config.h"
    4.21 -#endif
    4.22 -
    4.23 -#include "gstmythtvsrc.h"
    4.24 -#include "myth_file_transfer.h"
    4.25 -#include "myth_livetv.h"
    4.26 -
    4.27 -#include <gmyth/gmyth_socket.h>
    4.28 -#include <gmyth/gmyth_tvchain.h>
    4.29 -
    4.30 -#include <string.h>
    4.31 -#include <unistd.h>
    4.32 -
    4.33 -GST_DEBUG_CATEGORY_STATIC (mythtvsrc_debug);
    4.34 -#define GST_CAT_DEFAULT mythtvsrc_debug
    4.35 -
    4.36 -#define GST_MYTHTV_ID_NUM		1
    4.37 -
    4.38 -#define MYTHTV_VERSION_DEFAULT		30
    4.39 -
    4.40 -#define MYTHTV_TRANSFER_MAX_WAITS	100
    4.41 -
    4.42 -#define MYTHTV_TRANSFER_MAX_BUFFER	( 32*1024  )
    4.43 -
    4.44 -/* 4*1024 ??? */
    4.45 -#define MAX_READ_SIZE                   ( 16*1024 )
    4.46 -
    4.47 -#define ENABLE_TIMING_POSITION		1
    4.48 -
    4.49 -/* stablish a maximum iteration value to the IS_RECORDING message */
    4.50 -static guint wait_to_transfer = 0;
    4.51 -
    4.52 -static const GstElementDetails gst_mythtv_src_details =
    4.53 -GST_ELEMENT_DETAILS ("MythTV client source",
    4.54 -    "Source/Network",
    4.55 -    "Control and receive data as a client over the network via raw socket connections using the MythTV protocol",
    4.56 -    "Rosfran Borges <rosfran.borges@indt.org.br>");
    4.57 -
    4.58 -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    4.59 -    GST_PAD_SRC,
    4.60 -    GST_PAD_ALWAYS,
    4.61 -    GST_STATIC_CAPS_ANY);
    4.62 -
    4.63 -static GstTask *update_size_task = NULL;
    4.64 -
    4.65 -static GStaticRecMutex update_size_mutex = G_STATIC_REC_MUTEX_INIT;
    4.66 -
    4.67 -enum
    4.68 -{
    4.69 -  PROP_0,
    4.70 -  PROP_LOCATION,
    4.71 -  PROP_URI,
    4.72 -#ifndef GST_DISABLE_GST_DEBUG
    4.73 -  PROP_MYTHTV_DBG,
    4.74 -#endif
    4.75 -  PROP_MYTHTV_VERSION,
    4.76 -  PROP_MYTHTV_LIVE,
    4.77 -  PROP_MYTHTV_LIVEID,
    4.78 -  PROP_MYTHTV_LIVE_CHAINID
    4.79 -};
    4.80 -
    4.81 -static void gst_mythtv_src_finalize (GObject * gobject);
    4.82 -
    4.83 -static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc,
    4.84 -    guint64 offset, guint size, GstBuffer ** outbuf);
    4.85 -static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
    4.86 -static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
    4.87 -static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
    4.88 -static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *base_src );
    4.89 -
    4.90 -static void gst_mythtv_src_set_property (GObject * object, guint prop_id,
    4.91 -    const GValue * value, GParamSpec * pspec);
    4.92 -static void gst_mythtv_src_get_property (GObject * object, guint prop_id,
    4.93 -    GValue * value, GParamSpec * pspec);
    4.94 -
    4.95 -static void
    4.96 -gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
    4.97 -
    4.98 -static gboolean
    4.99 -gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
   4.100 -
   4.101 -  static void
   4.102 -_urihandler_init (GType type)
   4.103 -{
   4.104 -  static const GInterfaceInfo urihandler_info = {
   4.105 -    gst_mythtv_src_uri_handler_init,
   4.106 -    NULL,
   4.107 -    NULL
   4.108 -  };
   4.109 -
   4.110 -  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
   4.111 -
   4.112 -  GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
   4.113 -      "MythTV src");
   4.114 -}
   4.115 -
   4.116 -GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstBaseSrc,
   4.117 -    GST_TYPE_BASE_SRC, _urihandler_init);
   4.118 -
   4.119 -  static void
   4.120 -gst_mythtv_src_base_init (gpointer g_class)
   4.121 -{
   4.122 -  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
   4.123 -
   4.124 -  gst_element_class_add_pad_template (element_class,
   4.125 -      gst_static_pad_template_get (&srctemplate));
   4.126 -
   4.127 -  gst_element_class_set_details (element_class, &gst_mythtv_src_details);
   4.128 -}
   4.129 -
   4.130 -  static void
   4.131 -gst_mythtv_src_class_init (GstMythtvSrcClass * klass)
   4.132 -{
   4.133 -  GObjectClass *gobject_class;
   4.134 -  GstBaseSrcClass *gstbasesrc_class;
   4.135 -
   4.136 -  gobject_class = (GObjectClass *) klass;
   4.137 -  gstbasesrc_class = (GstBaseSrcClass *) klass;
   4.138 -
   4.139 -  gobject_class->set_property = gst_mythtv_src_set_property;
   4.140 -  gobject_class->get_property = gst_mythtv_src_get_property;
   4.141 -  gobject_class->finalize = gst_mythtv_src_finalize;
   4.142 -
   4.143 -  g_object_class_install_property
   4.144 -    (gobject_class, PROP_LOCATION,
   4.145 -     g_param_spec_string ("location", "Location",
   4.146 -       "The location. In the form:"
   4.147 -       "\n\t\t\tmyth://a.com/file.nuv"
   4.148 -       "\n\t\t\tmyth://a.com:23223/file.nuv "
   4.149 -       "\n\t\t\ta.com/file.nuv - default scheme 'myth'",
   4.150 -       "", G_PARAM_READWRITE));
   4.151 -
   4.152 -  g_object_class_install_property
   4.153 -    (gobject_class, PROP_URI,
   4.154 -     g_param_spec_string ("uri", "Uri",
   4.155 -       "The location in form of a URI (deprecated; use location)",
   4.156 -       "", G_PARAM_READWRITE));
   4.157 -
   4.158 -  g_object_class_install_property
   4.159 -    (gobject_class, PROP_MYTHTV_VERSION,
   4.160 -     g_param_spec_int ("mythtv-version", "mythtv-version",
   4.161 -       "Change Myth TV version",
   4.162 -       26, 30, 26, G_PARAM_READWRITE));
   4.163 -
   4.164 -  g_object_class_install_property
   4.165 -    (gobject_class, PROP_MYTHTV_LIVEID,
   4.166 -     g_param_spec_int ("mythtv-live-id", "mythtv-live-id",
   4.167 -       "Change Myth TV version",
   4.168 -       0, 200, GST_MYTHTV_ID_NUM, G_PARAM_READWRITE));
   4.169 -
   4.170 -  g_object_class_install_property
   4.171 -    (gobject_class, PROP_MYTHTV_LIVE_CHAINID,
   4.172 -     g_param_spec_string ("mythtv-live-chainid", "mythtv-live-chainid",
   4.173 -       "Sets the Myth TV chain ID (from TV Chain)",
   4.174 -       "", G_PARAM_READWRITE));
   4.175 -
   4.176 -  g_object_class_install_property
   4.177 -    (gobject_class, PROP_MYTHTV_LIVE,
   4.178 -     g_param_spec_boolean ("mythtv-live", "mythtv-live",
   4.179 -       "Enable MythTV Live TV content streaming",
   4.180 -       FALSE, G_PARAM_READWRITE));
   4.181 -
   4.182 -#ifndef GST_DISABLE_GST_DEBUG
   4.183 -  g_object_class_install_property
   4.184 -    (gobject_class, PROP_MYTHTV_DBG,
   4.185 -     g_param_spec_boolean ("mythtv-debug", "mythtv-debug",
   4.186 -       "Enable MythTV debug messages",
   4.187 -       FALSE, G_PARAM_READWRITE));
   4.188 -#endif
   4.189 -
   4.190 -  gstbasesrc_class->start = gst_mythtv_src_start;
   4.191 -  gstbasesrc_class->stop = gst_mythtv_src_stop;
   4.192 -  gstbasesrc_class->get_size = gst_mythtv_src_get_size;
   4.193 -  gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
   4.194 -
   4.195 -  gstbasesrc_class->create = gst_mythtv_src_create;
   4.196 -
   4.197 -  GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
   4.198 -      "MythTV Client Source");
   4.199 -}
   4.200 -
   4.201 -  static void
   4.202 -gst_mythtv_src_init (GstMythtvSrc * this, GstMythtvSrcClass * g_class)
   4.203 -{
   4.204 -  this->file_transfer = NULL;
   4.205 -
   4.206 -  this->unique_setup = FALSE;
   4.207 -
   4.208 -  this->mythtv_version = MYTHTV_VERSION_DEFAULT;
   4.209 -
   4.210 -  this->bytes_read = 0;
   4.211 -
   4.212 -  this->content_size = -1;
   4.213 -  this->read_offset = 0;
   4.214 -
   4.215 -  this->live_tv = FALSE;
   4.216 -
   4.217 -  this->user_agent = g_strdup ("mythtvsrc");
   4.218 -  this->mythtv_caps = NULL;    
   4.219 -
   4.220 -  gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE );
   4.221 -
   4.222 -  gst_pad_set_event_function (GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
   4.223 -      GST_DEBUG_FUNCPTR (gst_mythtv_src_handle_event));
   4.224 -
   4.225 -}
   4.226 -
   4.227 -  static void
   4.228 -gst_mythtv_src_finalize (GObject * gobject)
   4.229 -{
   4.230 -  GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
   4.231 -
   4.232 -  g_free (this->user_agent);
   4.233 -
   4.234 -  if (this->mythtv_caps) {
   4.235 -    gst_caps_unref (this->mythtv_caps);
   4.236 -    this->mythtv_caps = NULL;
   4.237 -  }
   4.238 -
   4.239 -  if (this->file_transfer) {
   4.240 -    g_object_unref (this->file_transfer);
   4.241 -    this->file_transfer = NULL;
   4.242 -  }
   4.243 -
   4.244 -  if (this->uri_name) {
   4.245 -    g_free (this->uri_name);
   4.246 -  }
   4.247 -
   4.248 -  if (this->user_agent) {
   4.249 -    g_free (this->user_agent);
   4.250 -  }
   4.251 -
   4.252 -  if ( update_size_task != NULL ) {
   4.253 -
   4.254 -    if ( GST_TASK_STATE( update_size_task ) != GST_TASK_STOPPED )
   4.255 -    	gst_task_stop( update_size_task );
   4.256 -
   4.257 -    gst_object_unref( update_size_task );
   4.258 -
   4.259 -    update_size_task = NULL;
   4.260 -
   4.261 -  }
   4.262 -
   4.263 -  G_OBJECT_CLASS (parent_class)->finalize (gobject);
   4.264 -}
   4.265 -
   4.266 -#if 0
   4.267 -  static guint
   4.268 -do_seek( GstMythtvSrc *src, guint64 offset, guint size, GstBuffer *outbuf )
   4.269 -{
   4.270 -  guint64 off_uint64 = myth_file_transfer_seek(src->file_transfer, offset, 1);
   4.271 -
   4.272 -  g_print( "[%s] Call MythTV SEEK with offset %llu, got a new one %llu...\n", __FUNCTION__, 
   4.273 -      offset, off_uint64 );
   4.274 -
   4.275 -  return off_uint64;
   4.276 -
   4.277 -}
   4.278 -#endif
   4.279 -
   4.280 -  static guint
   4.281 -do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer * outbuf)
   4.282 -{
   4.283 -  guint read = 0;
   4.284 -  guint sizetoread = size; //GST_BUFFER_SIZE (outbuf);
   4.285 -
   4.286 -  g_print( "[%s] Reading %d bytes...\n", __FUNCTION__, sizetoread ); 
   4.287 -
   4.288 -  /* Loop sending the request:
   4.289 -   * Retry whilst authentication fails and we supply it. */
   4.290 -
   4.291 -  ssize_t len = 0;
   4.292 -
   4.293 -  //GST_OBJECT_LOCK(src);
   4.294 -
   4.295 -  while ( sizetoread > 0 ) {
   4.296 -
   4.297 -    len = myth_file_transfer_read( src->file_transfer,
   4.298 -	GST_BUFFER_DATA (outbuf) + read, sizetoread, TRUE );
   4.299 -
   4.300 -    if ( len > 0 ) {
   4.301 -      read += len;
   4.302 -      src->read_offset += read;
   4.303 -      sizetoread -= len;
   4.304 -    } else if ( len < 0 ) {
   4.305 -      goto done;
   4.306 -    }
   4.307 -    else if ( len == 0 ) {
   4.308 -      if ( src->live_tv == FALSE )
   4.309 -	goto done;
   4.310 -      else
   4.311 -	goto eos;
   4.312 -
   4.313 -    }
   4.314 -
   4.315 -    if ( len == sizetoread )
   4.316 -      break;
   4.317 -
   4.318 -  }
   4.319 -
   4.320 -  if ( read > 0 ) {
   4.321 -    src->bytes_read += read;
   4.322 -
   4.323 -    GST_BUFFER_SIZE (outbuf) = read;
   4.324 -  } else if ( read <= 0 || len <= 0 ) {
   4.325 -    if ( src->live_tv == FALSE )
   4.326 -      goto eos;
   4.327 -    else
   4.328 -      goto done;
   4.329 -  }
   4.330 -  //GST_BUFFER_OFFSET (outbuf) = src->read_offset;
   4.331 -
   4.332 -  g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
   4.333 -      "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read, 
   4.334 -      src->read_offset, src->content_size );
   4.335 -
   4.336 -  //GST_OBJECT_UNLOCK(src);
   4.337 -
   4.338 -  if ( len < 0 ) {
   4.339 -    read = len;
   4.340 -    if ( src->live_tv == FALSE ) 
   4.341 -      goto eos;
   4.342 -    else
   4.343 -      goto done;
   4.344 -  }
   4.345 -
   4.346 -  if ( src->bytes_read < src->content_size )
   4.347 -    goto done;
   4.348 -
   4.349 -eos:
   4.350 -  //GST_OBJECT_UNLOCK(src);
   4.351 -
   4.352 -  src->eos = TRUE;
   4.353 -done:
   4.354 -  //GST_OBJECT_UNLOCK(src);
   4.355 -
   4.356 -  return read;
   4.357 -}
   4.358 -
   4.359 -  static GstFlowReturn
   4.360 -gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset, 
   4.361 -    guint size, GstBuffer **outbuf )
   4.362 -{
   4.363 -  GstMythtvSrc *src;
   4.364 -  GstFlowReturn ret = GST_FLOW_OK;
   4.365 -  guint read = 0;
   4.366 -
   4.367 -  src = GST_MYTHTV_SRC (psrc);
   4.368 -
   4.369 -  //src->do_start = FALSE;
   4.370 -  src->do_start = FALSE;
   4.371 -  gst_task_join ( update_size_task );
   4.372 -
   4.373 -  g_print( "[%s]\tBUFFER OFFSET = %llu, BUFFER SIZE = %d.\n", __FUNCTION__, offset, 
   4.374 -      size );
   4.375 -
   4.376 -  /* The caller should know the number of bytes and not read beyond EOS. */
   4.377 -  //if (G_UNLIKELY (src->eos))
   4.378 -  //  goto eos;
   4.379 -  //g_static_rec_mutex_lock( &update_size_mutex );
   4.380 -
   4.381 -  /* Create the buffer. */
   4.382 -  ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
   4.383 -      //      GST_BUFFER_OFFSET_NONE, GST_BASE_SRC (psrc)->blocksize,
   4.384 -      offset, size,
   4.385 -      src->mythtv_caps ? src->mythtv_caps :
   4.386 -      GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
   4.387 -
   4.388 -  //if (G_UNLIKELY (ret == GST_FLOW_UNEXPECTED))
   4.389 -  //  goto eos;
   4.390 -
   4.391 -  if (G_UNLIKELY (ret != GST_FLOW_OK))
   4.392 -    goto eos;
   4.393 -
   4.394 -  if (G_UNLIKELY (ret == GST_FLOW_ERROR))
   4.395 -    goto read_error;
   4.396 -
   4.397 -  read = do_read_request_response ( src, offset, size, *outbuf );
   4.398 -
   4.399 -  //g_static_rec_mutex_unlock( &update_size_mutex );
   4.400 -
   4.401 -  src->do_start = TRUE;
   4.402 -  gst_task_start ( update_size_task );
   4.403 -
   4.404 -#if 0
   4.405 -  g_static_rec_mutex_lock( &update_size_mutex );
   4.406 -  src->do_start = FALSE;  
   4.407 -  g_static_rec_mutex_unlock( &update_size_mutex );
   4.408 -  GST_TASK_SIGNAL( update_size_task );
   4.409 -#endif
   4.410 -
   4.411 -  //g_static_rec_mutex_unlock( &update_size_mutex );
   4.412 -
   4.413 -#if 0
   4.414 -#if ENABLE_TIMING_POSITION == 1
   4.415 -  guint64 size_tmp = 0;
   4.416 -  if (src->live_tv == TRUE) {
   4.417 -    //g_usleep( 1000 );
   4.418 -get_file_pos:
   4.419 -    //g_usleep( 100 );
   4.420 -    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
   4.421 -    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
   4.422 -      src->content_size = size_tmp;
   4.423 -    else
   4.424 -      goto get_file_pos;
   4.425 -    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
   4.426 -	__FUNCTION__, size_tmp);
   4.427 -
   4.428 -  }
   4.429 -#endif
   4.430 -#endif
   4.431 -
   4.432 -  //if (G_UNLIKELY (read < 0))
   4.433 -  //  goto read_error;
   4.434 -
   4.435 -  if (G_UNLIKELY(src->eos))
   4.436 -    goto eos;
   4.437 -  else
   4.438 -    goto done;
   4.439 -
   4.440 -done:
   4.441 -  return ret;
   4.442 -eos:
   4.443 -#if 0
   4.444 -#if ENABLE_TIMING_POSITION == 1
   4.445 -  if ( src->live_tv == TRUE ) {
   4.446 -    //g_usleep( 1000 );
   4.447 -    guint64 size_tmp = 0;
   4.448 -get_file_pos_eos:
   4.449 -    //g_usleep( 100 );
   4.450 -    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
   4.451 -    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
   4.452 -      src->content_size = size_tmp;
   4.453 -    else
   4.454 -      goto get_file_pos_eos;
   4.455 -    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
   4.456 -	__FUNCTION__, size_tmp);
   4.457 -    goto done;
   4.458 -  } else 
   4.459 -#endif
   4.460 -#endif
   4.461 -  {
   4.462 -    GST_DEBUG_OBJECT (src, "EOS reached");
   4.463 -    return GST_FLOW_UNEXPECTED;
   4.464 -  }
   4.465 -  /* ERRORS */
   4.466 -read_error:
   4.467 -  {
   4.468 -    GST_ELEMENT_ERROR (src, RESOURCE, READ,
   4.469 -	(NULL), ("Could not read any bytes (%i, %s)", read,
   4.470 -	  src->uri_name));
   4.471 -    return GST_FLOW_ERROR;
   4.472 -  }
   4.473 -  #if 0
   4.474 -need_pause:
   4.475 -  {
   4.476 -    const gchar *reason = gst_flow_get_name (ret);
   4.477 -
   4.478 -    GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
   4.479 -    return GST_FLOW_UNEXPECTED;
   4.480 -  }
   4.481 -  #endif
   4.482 -
   4.483 -}
   4.484 -
   4.485 -#if 0
   4.486 -/* The following two charset mangling functions were copied from gnomevfssrc.
   4.487 - * Preserve them under the unverified assumption that they do something vaguely
   4.488 - * worthwhile.
   4.489 - */
   4.490 -  static char *
   4.491 -unicodify (const char *str, int len, ...)
   4.492 -{
   4.493 -  char *ret = NULL, *cset;
   4.494 -  va_list args;
   4.495 -  gsize bytes_read, bytes_written;
   4.496 -
   4.497 -  if (g_utf8_validate (str, len, NULL))
   4.498 -    return g_strndup (str, len >= 0 ? len : strlen (str));
   4.499 -
   4.500 -  va_start (args, len);
   4.501 -  while ((cset = va_arg (args, char *)) != NULL)
   4.502 -  {
   4.503 -    if (!strcmp (cset, "locale"))
   4.504 -      ret = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, NULL);
   4.505 -    else
   4.506 -      ret = g_convert (str, len, "UTF-8", cset,
   4.507 -	  &bytes_read, &bytes_written, NULL);
   4.508 -    if (ret)
   4.509 -      break;
   4.510 -  }
   4.511 -  va_end (args);
   4.512 -
   4.513 -  return ret;
   4.514 -}
   4.515 -
   4.516 -  static char *
   4.517 -gst_mythtv_src_unicodify (const char *str)
   4.518 -{
   4.519 -  return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
   4.520 -}
   4.521 -#endif
   4.522 -
   4.523 -void
   4.524 -update_size_func( void *mythtv_data ) 
   4.525 -{
   4.526 -  GstMythtvSrc *src;
   4.527 -
   4.528 -  g_return_if_fail( mythtv_data != NULL );
   4.529 -
   4.530 -  src = GST_MYTHTV_SRC ( mythtv_data );
   4.531 -  if ( src->do_start ) {
   4.532 - #if ENABLE_TIMING_POSITION == 1
   4.533 -  guint64 size_tmp = 0;
   4.534 -  if (src->live_tv == TRUE) {
   4.535 -get_file_pos:
   4.536 -    //g_usleep( 50 );
   4.537 -    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
   4.538 -    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
   4.539 -      src->content_size = size_tmp;
   4.540 -    else
   4.541 -      goto get_file_pos;
   4.542 -    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
   4.543 -	__FUNCTION__, size_tmp );
   4.544 -  }
   4.545 -#endif
   4.546 -}
   4.547 -  gst_task_pause( update_size_task );
   4.548 - // src->do_start = FALSE;
   4.549 -  //GST_TASK_SIGNAL( update_size_task );
   4.550 -
   4.551 -}
   4.552 -
   4.553 -/* create a socket for connecting to remote server */
   4.554 -  static gboolean
   4.555 -gst_mythtv_src_start ( GstBaseSrc * bsrc )
   4.556 -{
   4.557 -  GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc);
   4.558 -
   4.559 -  GString *chain_id_local = NULL;
   4.560 -
   4.561 -  gboolean ret = TRUE;
   4.562 -#if 0
   4.563 -  if (src->live_tv == TRUE && src->file_transfer != NULL) {
   4.564 -    guint64 size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
   4.565 -    if (size_tmp > src->content_size)
   4.566 -      src->content_size = size_tmp;
   4.567 -    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
   4.568 -	__FUNCTION__, size_tmp);
   4.569 -  }
   4.570 -#endif
   4.571 -  if (src->unique_setup == FALSE) {
   4.572 -    src->unique_setup = TRUE;
   4.573 -  } else {
   4.574 -    goto done;
   4.575 -  }
   4.576 -
   4.577 -  //GST_OBJECT_LOCK(src);
   4.578 -
   4.579 -  if ( src->live_tv ) {
   4.580 -    src->spawn_livetv = myth_livetv_new( );
   4.581 -    if ( myth_livetv_setup( src->spawn_livetv ) == FALSE ) {
   4.582 -    	ret = FALSE;
   4.583 -    	goto init_failed;
   4.584 -    }
   4.585 -    /* set up the uri variable */
   4.586 -    src->uri_name = g_strdup( src->spawn_livetv->proginfo->pathname->str );
   4.587 -    chain_id_local = gmyth_tvchain_get_id( src->spawn_livetv->tvchain );
   4.588 -    if ( chain_id_local != NULL ) {
   4.589 -      src->live_chain_id = g_strdup( chain_id_local->str );
   4.590 -      g_print( "\t[%s]\tLocal chain ID = %s.\n", __FUNCTION__, src->live_chain_id );
   4.591 -    }
   4.592 -    src->live_tv_id = src->spawn_livetv->remote_encoder->recorder_num;
   4.593 -    g_print ( "[%s] LiveTV id = %d, URI path = %s.\n", __FUNCTION__, src->live_tv_id, src->uri_name );
   4.594 -  }
   4.595 -
   4.596 -  src->file_transfer = myth_file_transfer_new( src->live_tv_id, 
   4.597 -      g_string_new( src->uri_name ), -1, src->mythtv_version );
   4.598 -
   4.599 -  if ( src->file_transfer == NULL ) {
   4.600 -    //GST_OBJECT_UNLOCK(src);
   4.601 -
   4.602 -    goto init_failed;
   4.603 -  }
   4.604 -
   4.605 -  if ( src->live_tv ) {
   4.606 -    g_print ( "[%s] GST MYTHTVSRC: live_chain_id = %s\n", __FUNCTION__, src->live_chain_id );
   4.607 -    /* sets the MythSocket to the FileTransfer */
   4.608 -    //ret = myth_file_transfer_livetv_setup( &(src->file_transfer), src->spawn_livetv->remote_encoder->myth_socket );
   4.609 -  }
   4.610 -  /* sets the Playback monitor connection */
   4.611 -  ret = myth_file_transfer_playback_setup( &(src->file_transfer), src->live_tv );
   4.612 -
   4.613 -  if ( src->live_tv == TRUE && ret == TRUE ) {
   4.614 -    /* loop finished, set the max tries variable to zero again... */
   4.615 -    wait_to_transfer = 0;
   4.616 -
   4.617 -    while ( wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS && ( myth_file_transfer_is_recording( src->file_transfer ) == FALSE 
   4.618 -	  /*|| ( myth_file_transfer_get_file_position( src->file_transfer ) < ( src->content_size + 327680 ) )*/ ) )
   4.619 -      g_usleep( 100 );
   4.620 -  }
   4.621 -
   4.622 -  /* sets the FileTransfer instance connection (video/audio download) */
   4.623 -  ret = myth_file_transfer_setup( &(src->file_transfer), src->live_tv );
   4.624 -
   4.625 -  if ( ret == FALSE ) {
   4.626 -    //GST_OBJECT_UNLOCK(src);
   4.627 -#ifndef GST_DISABLE_GST_DEBUG  
   4.628 -    if ( src->mythtv_msgs_dbg )
   4.629 -      g_printerr( "MythTV FileTransfer request failed when setting up socket connection!\n" );  	  
   4.630 -#endif
   4.631 -    goto begin_req_failed;
   4.632 -  }
   4.633 -
   4.634 -  src->content_size = src->file_transfer->filesize;
   4.635 -
   4.636 -  //GST_OBJECT_UNLOCK(src);
   4.637 -
   4.638 -  update_size_task = gst_task_create( update_size_func, src );
   4.639 -
   4.640 -  gst_task_set_lock( update_size_task, &update_size_mutex );
   4.641 -
   4.642 -  g_print( "[%s] Update Size task = %s\n", __FUNCTION__, gst_task_start( update_size_task ) && 
   4.643 -  		GST_TASK_STATE( update_size_task ) == GST_TASK_STARTED ? "OK !" : "ERROR!!!" );
   4.644 -
   4.645 -  src->do_start = TRUE;
   4.646 -
   4.647 -#if 0
   4.648 -  const char *str_value;
   4.649 -  gint gint_value;
   4.650 -
   4.651 -  str_value = ne_get_response_header (src->request, "myth-metaint");
   4.652 -  if (str_value) {
   4.653 -    if ( sscanf (str_value, "%d", &gint_value) == 1 ) {
   4.654 -      if (src->myth_caps) {
   4.655 -	gst_caps_unref (src->myth_caps);
   4.656 -	src->myth_caps = NULL;
   4.657 -      }
   4.658 -      src->myth_metaint = gint_value;
   4.659 -#endif
   4.660 -      //src->mythtv_caps = gst_caps_new_simple ("application/x-gst_ff-nuv", NULL);
   4.661 -      //   }
   4.662 -      // }
   4.663 -done:
   4.664 -      return TRUE;
   4.665 -
   4.666 -      /* ERRORS */
   4.667 -init_failed:
   4.668 -      {
   4.669 -      	if (src->spawn_livetv != NULL )
   4.670 -	  g_object_unref( src->spawn_livetv );
   4.671 -
   4.672 -	GST_ELEMENT_ERROR (src, LIBRARY, INIT,
   4.673 -	    (NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name));
   4.674 -	return FALSE;
   4.675 -      }
   4.676 -begin_req_failed:
   4.677 -      {
   4.678 -	GST_ELEMENT_ERROR (src, LIBRARY, INIT,
   4.679 -	    (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name));
   4.680 -	return FALSE;
   4.681 -      }
   4.682 -}
   4.683 -
   4.684 -#if 0
   4.685 -static gboolean
   4.686 -gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
   4.687 -{
   4.688 -  GstMythtvSrc *src;
   4.689 -  gboolean ret = FALSE;
   4.690 -
   4.691 -  src = GST_MYTHTV_SRC (bsrc);
   4.692 -
   4.693 -  g_static_rec_mutex_lock( &update_size_mutex );
   4.694 -  src->do_start = FALSE;  
   4.695 -  g_static_rec_mutex_unlock( &update_size_mutex );
   4.696 -  GST_TASK_SIGNAL( update_size_task );
   4.697 - 
   4.698 -
   4.699 -  while (1) {
   4.700 -
   4.701 -    g_static_rec_mutex_lock( &update_size_mutex );
   4.702 -    if ( !src->do_start ) {
   4.703 -
   4.704 -      g_print( "[%s] GET SIZE: do_start? == %s\n", __FUNCTION__, src->do_start ? "YES" : "NO" );
   4.705 -
   4.706 -      GST_TASK_WAIT( update_size_task );
   4.707 -    } else {
   4.708 -      if (src->content_size <= 0) {
   4.709 -	g_static_rec_mutex_unlock( &update_size_mutex );
   4.710 -	goto done;
   4.711 -      }
   4.712 -
   4.713 -      *size = src->content_size;
   4.714 -      src->do_start = FALSE;
   4.715 -
   4.716 -      g_static_rec_mutex_unlock( &update_size_mutex );
   4.717 -
   4.718 -      break;
   4.719 -    }
   4.720 -    g_static_rec_mutex_unlock( &update_size_mutex );
   4.721 -
   4.722 -  } // while (1) 
   4.723 -
   4.724 -done:
   4.725 -  return ret;
   4.726 -
   4.727 -}
   4.728 -#endif
   4.729 -
   4.730 -static gboolean
   4.731 -gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
   4.732 -{
   4.733 -  GstMythtvSrc *src;
   4.734 -  gboolean ret = TRUE;
   4.735 -
   4.736 -  src = GST_MYTHTV_SRC (bsrc);
   4.737 -
   4.738 -  if (src->content_size <= 0)
   4.739 -    ret= FALSE;
   4.740 -
   4.741 -  *size = src->content_size;
   4.742 -
   4.743 -  return ret;
   4.744 -
   4.745 -}
   4.746 -/* close the socket and associated resources
   4.747 - * used both to recover from errors and go to NULL state */
   4.748 -  static gboolean
   4.749 -gst_mythtv_src_stop (GstBaseSrc * bsrc)
   4.750 -{
   4.751 -  GstMythtvSrc *src;
   4.752 -
   4.753 -  src = GST_MYTHTV_SRC (bsrc);
   4.754 -
   4.755 -  if (src->uri_name) {
   4.756 -    g_free (src->uri_name);
   4.757 -    src->uri_name = NULL;
   4.758 -  }
   4.759 -
   4.760 -  if (src->mythtv_caps) {
   4.761 -    gst_caps_unref (src->mythtv_caps);
   4.762 -    src->mythtv_caps = NULL;
   4.763 -  }
   4.764 -
   4.765 -  src->eos = FALSE;
   4.766 -
   4.767 -  return TRUE;
   4.768 -}
   4.769 -
   4.770 -  static gboolean
   4.771 -gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event)
   4.772 -{
   4.773 -  GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
   4.774 -
   4.775 -  switch (GST_EVENT_TYPE (event)) {
   4.776 -    case GST_EVENT_FLUSH_START:
   4.777 -      src->eos = FALSE;
   4.778 -      break;
   4.779 -      //return TRUE;
   4.780 -#if 0
   4.781 -case GST_EVENT_FLUSH_STOP:
   4.782 -      src->do_start = TRUE;
   4.783 -      src->eos = FALSE;
   4.784 -      gst_element_set_state (GST_ELEMENT(src), GST_STATE_NULL);
   4.785 -      //gst_element_set_locked_state (GST_ELEMENT(src), TRUE);
   4.786 -      break;
   4.787 -#endif
   4.788 -    case GST_EVENT_SEEK:  	  
   4.789 -      {
   4.790 -	gdouble rate;
   4.791 -	//gboolean update = TRUE;
   4.792 -	GstFormat format;
   4.793 -	GstSeekType cur_type, stop_type;
   4.794 -	GstSeekFlags flags;
   4.795 -	gint64 cur = 0, stop = 0;
   4.796 -	gst_event_parse_seek ( event, &rate, &format,
   4.797 -	    &flags, &cur_type, &cur,
   4.798 -	    &stop_type, &stop );
   4.799 -
   4.800 -	g_print( "[%s] Got EVENT_SEEK.\n", __FUNCTION__ );
   4.801 -	if ( !( flags & GST_SEEK_FLAG_FLUSH ) ) {
   4.802 -	  g_print( "[%s] Could get the FLAG_FLUSH message.\n", __FUNCTION__ );
   4.803 -	}
   4.804 -	//gboolean ret = gst_event_parse_new_segment ( event,
   4.805 -	//    &update, &rate, &format, &start, &stop,
   4.806 -	//    &position );
   4.807 -	//GstFlowReturn flow_ret = gst_mythtv_src_create (GST_BASE_SRC( GST_PAD_PARENT( psrc ) ), 
   4.808 -	//			cur, stop - cur + 1, GstBuffer)
   4.809 -
   4.810 -      } 
   4.811 -    default:
   4.812 -      return gst_pad_event_default (pad, event);
   4.813 -  }
   4.814 -
   4.815 -  return gst_pad_event_default (pad, event);
   4.816 -}
   4.817 -
   4.818 -  static gboolean
   4.819 -gst_mythtv_src_is_seekable( GstBaseSrc *base_src )
   4.820 -{
   4.821 -  return TRUE;
   4.822 -}
   4.823 -
   4.824 -  static void
   4.825 -gst_mythtv_src_set_property (GObject * object, guint prop_id,
   4.826 -    const GValue * value, GParamSpec * pspec)
   4.827 -{
   4.828 -  GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
   4.829 -
   4.830 -  GST_OBJECT_LOCK (mythtvsrc);
   4.831 -  switch (prop_id) {
   4.832 -    case PROP_URI:
   4.833 -    case PROP_LOCATION:
   4.834 -      {
   4.835 -	if (!g_value_get_string (value)) {
   4.836 -	  GST_WARNING ("location property cannot be NULL");
   4.837 -	  goto done;
   4.838 -	}
   4.839 -
   4.840 -	if (mythtvsrc->uri_name != NULL) {
   4.841 -	  g_free (mythtvsrc->uri_name);
   4.842 -	  mythtvsrc->uri_name = NULL;
   4.843 -	}
   4.844 -	mythtvsrc->uri_name = g_value_dup_string (value);
   4.845 -
   4.846 -	break;
   4.847 -      }
   4.848 -#ifndef GST_DISABLE_GST_DEBUG
   4.849 -    case PROP_MYTHTV_DBG:
   4.850 -      {
   4.851 -	mythtvsrc->mythtv_msgs_dbg = g_value_get_boolean (value);
   4.852 -	break;
   4.853 -      }
   4.854 -#endif
   4.855 -    case PROP_MYTHTV_VERSION:
   4.856 -      {
   4.857 -	mythtvsrc->mythtv_version = g_value_get_int (value);
   4.858 -	break;
   4.859 -      }
   4.860 -    case PROP_MYTHTV_LIVEID:
   4.861 -      {
   4.862 -	mythtvsrc->live_tv_id = g_value_get_int (value);
   4.863 -	break;
   4.864 -      }
   4.865 -    case PROP_MYTHTV_LIVE:
   4.866 -      {
   4.867 -	mythtvsrc->live_tv = g_value_get_boolean (value);
   4.868 -	break;
   4.869 -      }
   4.870 -    case PROP_MYTHTV_LIVE_CHAINID:
   4.871 -      {
   4.872 -	if (!g_value_get_string (value)) {
   4.873 -	  GST_WARNING ("MythTV Live chainid property cannot be NULL");
   4.874 -	  goto done;
   4.875 -	}
   4.876 -
   4.877 -	if (mythtvsrc->live_chain_id != NULL) {
   4.878 -	  g_free (mythtvsrc->live_chain_id);
   4.879 -	  mythtvsrc->live_chain_id = NULL;
   4.880 -	}
   4.881 -	mythtvsrc->live_chain_id = g_value_dup_string (value);
   4.882 -
   4.883 -	break;
   4.884 -      }
   4.885 -
   4.886 -    default:
   4.887 -      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   4.888 -      break;
   4.889 -  }
   4.890 -  GST_OBJECT_UNLOCK (mythtvsrc);
   4.891 -done:
   4.892 -  return;
   4.893 -}
   4.894 -
   4.895 -  static void
   4.896 -gst_mythtv_src_get_property (GObject * object, guint prop_id,
   4.897 -    GValue * value, GParamSpec * pspec)
   4.898 -{
   4.899 -  GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
   4.900 -
   4.901 -  GST_OBJECT_LOCK (mythtvsrc);
   4.902 -  switch (prop_id) {
   4.903 -    case PROP_URI:
   4.904 -    case PROP_LOCATION:
   4.905 -      {
   4.906 -	gchar *str = g_strdup( "" );
   4.907 -
   4.908 -	if ( mythtvsrc->uri_name == NULL ) {
   4.909 -	  g_free (mythtvsrc->uri_name);
   4.910 -	  mythtvsrc->uri_name = NULL;
   4.911 -	} else {
   4.912 -	  str = g_strdup( mythtvsrc->uri_name );
   4.913 -	}
   4.914 -	g_value_set_string ( value, str );
   4.915 -	break;
   4.916 -      }
   4.917 -#ifndef GST_DISABLE_GST_DEBUG
   4.918 -    case PROP_MYTHTV_DBG:
   4.919 -      g_value_set_boolean ( value, mythtvsrc->mythtv_msgs_dbg );
   4.920 -      break;
   4.921 -#endif
   4.922 -    case PROP_MYTHTV_VERSION:
   4.923 -      {
   4.924 -	g_value_set_int ( value, mythtvsrc->mythtv_version );
   4.925 -	break;
   4.926 -      }
   4.927 -    case PROP_MYTHTV_LIVEID:
   4.928 -      {
   4.929 -	g_value_set_int ( value, mythtvsrc->live_tv_id );
   4.930 -	break;
   4.931 -      }
   4.932 -    case PROP_MYTHTV_LIVE:
   4.933 -      g_value_set_boolean ( value, mythtvsrc->live_tv );
   4.934 -      break;
   4.935 -    case PROP_MYTHTV_LIVE_CHAINID:
   4.936 -      {
   4.937 -	gchar *str = g_strdup( "" );
   4.938 -
   4.939 -	if ( mythtvsrc->live_chain_id == NULL ) {
   4.940 -	  g_free (mythtvsrc->live_chain_id);
   4.941 -	  mythtvsrc->live_chain_id = NULL;
   4.942 -	} else {
   4.943 -	  str = g_strdup( mythtvsrc->live_chain_id );
   4.944 -	}
   4.945 -	g_value_set_string ( value, str );
   4.946 -	break;
   4.947 -      }
   4.948 -    default:
   4.949 -      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   4.950 -      break;
   4.951 -  }
   4.952 -  GST_OBJECT_UNLOCK (mythtvsrc);
   4.953 -}
   4.954 -
   4.955 -/* entry point to initialize the plug-in
   4.956 - * initialize the plug-in itself
   4.957 - * register the element factories and pad templates
   4.958 - * register the features
   4.959 - */
   4.960 -  static gboolean
   4.961 -plugin_init (GstPlugin * plugin)
   4.962 -{
   4.963 -  return gst_element_register (plugin, "mythtvsrc", GST_RANK_NONE,
   4.964 -      GST_TYPE_MYTHTV_SRC);
   4.965 -}
   4.966 -
   4.967 -/* this is the structure that gst-register looks for
   4.968 - * so keep the name plugin_desc, or you cannot get your plug-in registered */
   4.969 -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
   4.970 -    GST_VERSION_MINOR,
   4.971 -    "mythtv",
   4.972 -    "lib MythTV src",
   4.973 -    plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
   4.974 -
   4.975 -
   4.976 -/*** GSTURIHANDLER INTERFACE *************************************************/
   4.977 -  static guint 
   4.978 -gst_mythtv_src_uri_get_type (void)
   4.979 -{
   4.980 -  return GST_URI_SRC;
   4.981 -}
   4.982 -
   4.983 -  static gchar **
   4.984 -gst_mythtv_src_uri_get_protocols (void)
   4.985 -{
   4.986 -  static gchar *protocols[] = { "myth", "myths", NULL };
   4.987 -
   4.988 -  return protocols;
   4.989 -}
   4.990 -
   4.991 -  static const gchar *
   4.992 -gst_mythtv_src_uri_get_uri (GstURIHandler * handler)
   4.993 -{
   4.994 -  GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
   4.995 -
   4.996 -  return src->uri_name;
   4.997 -}
   4.998 -
   4.999 -  static gboolean
  4.1000 -gst_mythtv_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
  4.1001 -{
  4.1002 -  GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
  4.1003 -
  4.1004 -  gchar *protocol;
  4.1005 -
  4.1006 -  protocol = gst_uri_get_protocol (uri);
  4.1007 -  if ((strcmp (protocol, "myth") != 0) && (strcmp (protocol, "myths") != 0)) {
  4.1008 -    g_free (protocol);
  4.1009 -    return FALSE;
  4.1010 -  }
  4.1011 -  g_free (protocol);
  4.1012 -  g_object_set (src, "location", uri, NULL);
  4.1013 -
  4.1014 -  return TRUE;
  4.1015 -}
  4.1016 -
  4.1017 -  static void
  4.1018 -gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
  4.1019 -{
  4.1020 -  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
  4.1021 -
  4.1022 -  iface->get_type = gst_mythtv_src_uri_get_type;
  4.1023 -  iface->get_protocols = gst_mythtv_src_uri_get_protocols;
  4.1024 -  iface->get_uri = gst_mythtv_src_uri_get_uri;
  4.1025 -  iface->set_uri = gst_mythtv_src_uri_set_uri;
  4.1026 -}
  4.1027 -
  4.1028 -  void
  4.1029 -size_header_handler (void *userdata, const char *value)
  4.1030 -{
  4.1031 -  GstMythtvSrc *src = GST_MYTHTV_SRC (userdata);
  4.1032 -
  4.1033 -  //src->content_size = g_ascii_strtoull (value, NULL, 10);
  4.1034 -
  4.1035 -  GST_DEBUG_OBJECT (src, "content size = %lld bytes", src->content_size);
  4.1036 -}
     5.1 --- a/gst-plugins-mythtv/gstmythtvsrc.h	Tue Sep 26 15:30:52 2006 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,89 +0,0 @@
     5.4 -/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2 -*- */
     5.5 -/* GStreamer
     5.6 - * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
     5.7 - *
     5.8 - * This library is free software; you can redistribute it and/or
     5.9 - * modify it under the terms of the GNU Library General Public
    5.10 - * License as published by the Free Software Foundation; either
    5.11 - * version 2 of the License, or (at your option) any later version.
    5.12 - *
    5.13 - * This library is distributed in the hope that it will be useful,
    5.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.16 - * Library General Public License for more 
    5.17 - */
    5.18 -
    5.19 -#ifndef __GST_MYTHTV_SRC_H__
    5.20 -#define __GST_MYTHTV_SRC_H__
    5.21 -
    5.22 -#include <gst/gst.h>
    5.23 -#include <gst/base/gstpushsrc.h>
    5.24 -#include <stdio.h>
    5.25 -
    5.26 -#include <gmyth/gmyth_socket.h>
    5.27 -#include "myth_file_transfer.h"
    5.28 -#include "myth_livetv.h"
    5.29 -
    5.30 -G_BEGIN_DECLS
    5.31 -
    5.32 -#define GST_TYPE_MYTHTV_SRC \
    5.33 -  (gst_mythtv_src_get_type())
    5.34 -#define GST_MYTHTV_SRC(obj) \
    5.35 -  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MYTHTV_SRC,GstMythtvSrc))
    5.36 -#define GST_MYTHTV_SRC_CLASS(klass) \
    5.37 -  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MYTHTV_SRC,GstMythtvSrcClass))
    5.38 -#define GST_IS_MYTHTV_SRC(obj) \
    5.39 -  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MYTHTV_SRC))
    5.40 -#define GST_IS_MYTHTV_SRC_CLASS(klass) \
    5.41 -  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MYTHTV_SRC))
    5.42 -
    5.43 -typedef struct _GstMythtvSrc GstMythtvSrc;
    5.44 -typedef struct _GstMythtvSrcClass GstMythtvSrcClass;
    5.45 -
    5.46 -struct _GstMythtvSrc {
    5.47 -  GstBaseSrc element;
    5.48 -
    5.49 -  /* MythFileTransfer */
    5.50 -  MythFileTransfer *file_transfer;
    5.51 -
    5.52 -  MythLiveTV *spawn_livetv;
    5.53 -
    5.54 -  gchar *uri_name;
    5.55 -  gchar *user_agent;
    5.56 -
    5.57 -  gchar *live_chain_id;
    5.58 -  
    5.59 -  gint mythtv_version;
    5.60 -
    5.61 -  guint64 content_size;
    5.62 -
    5.63 -  guint64 bytes_read;
    5.64 -
    5.65 -  guint64 read_offset;
    5.66 -
    5.67 -  gboolean eos;
    5.68 -  
    5.69 -  gboolean do_start;
    5.70 -
    5.71 -  gboolean unique_setup;
    5.72 -
    5.73 -  gboolean live_tv;
    5.74 -
    5.75 -  gint live_tv_id;
    5.76 -
    5.77 -  /* MythTV capabilities */
    5.78 -  GstCaps *mythtv_caps;
    5.79 -
    5.80 -  /* enable Myth TV debug messages */
    5.81 -  gboolean mythtv_msgs_dbg;
    5.82 -};
    5.83 -
    5.84 -struct _GstMythtvSrcClass {
    5.85 -  GstBaseSrcClass parent_class;
    5.86 -};
    5.87 -
    5.88 -GType gst_mythtv_src_get_type (void);
    5.89 -
    5.90 -G_END_DECLS
    5.91 -
    5.92 -#endif /* __GST_MYTHTV_SRC_H__ */
     6.1 --- a/gst-plugins-mythtv/myth_file_transfer.c	Tue Sep 26 15:30:52 2006 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,960 +0,0 @@
     6.4 -/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
     6.5 -/**
     6.6 - * GStreamer plug-in properties:
     6.7 - * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
     6.8 - * - path (qurl - remote file to be opened)
     6.9 - * - port number
    6.10 - *   @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
    6.11 - */
    6.12 -
    6.13 -#include "myth_file_transfer.h"
    6.14 -#include "myth_uri.h"
    6.15 -#include "myth_livetv.h"
    6.16 -#include <gmyth/gmyth_util.h>
    6.17 -#include <gmyth/gmyth_socket.h>
    6.18 -#include <gmyth/gmyth_stringlist.h>
    6.19 -
    6.20 -#include <unistd.h>
    6.21 -#include <glib.h>
    6.22 -
    6.23 -#include <arpa/inet.h>
    6.24 -#include <sys/types.h>
    6.25 -#include <sys/socket.h>
    6.26 -#include <netdb.h>
    6.27 -#include <errno.h>
    6.28 -#include <stdlib.h>
    6.29 -
    6.30 -#define MYTHTV_QUERY_HEADER "QUERY_FILETRANSFER"
    6.31 -#define MYTHTV_RECORDER_HEADER "QUERY_RECORDER"
    6.32 -
    6.33 -/* default values to the file transfer parameters */
    6.34 -#define MYTHTV_USER_READ_AHEAD	FALSE
    6.35 -#define MYTHTV_RETRIES			1
    6.36 -#define MYTHTV_FILE_SIZE		-1
    6.37 -
    6.38 -#define MYTHTV_BUFFER_SIZE		2048
    6.39 -
    6.40 -#define MYTHTV_VERSION			30
    6.41 -
    6.42 -#define MYTHTV_TRANSFER_MAX_WAITS	700
    6.43 -
    6.44 -#ifdef MYTHTV_ENABLE_DEBUG
    6.45 -#define MYTHTV_ENABLE_DEBUG	1
    6.46 -#else
    6.47 -#undef MYTHTV_ENABLE_DEBUG
    6.48 -#endif
    6.49 -
    6.50 -/* this NDEBUG is to maintain compatibility with GMyth library */
    6.51 -#ifndef NDEBUG
    6.52 -#define MYTHTV_ENABLE_DEBUG	1
    6.53 -#endif
    6.54 -
    6.55 -static guint wait_to_transfer = 0;
    6.56 -
    6.57 -enum myth_sock_types {
    6.58 -  MYTH_PLAYBACK_TYPE = 0,
    6.59 -  MYTH_MONITOR_TYPE,
    6.60 -  MYTH_FILETRANSFER_TYPE,
    6.61 -  MYTH_RINGBUFFER_TYPE
    6.62 -};
    6.63 -
    6.64 -static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
    6.65 -
    6.66 -static void myth_file_transfer_class_init          (MythFileTransferClass *klass);
    6.67 -static void myth_file_transfer_init                (MythFileTransfer *object);
    6.68 -
    6.69 -static void myth_file_transfer_dispose  (GObject *object);
    6.70 -static void myth_file_transfer_finalize (GObject *object);
    6.71 -
    6.72 -static GMythSocket *myth_connect_to_transfer_backend( MythFileTransfer **transfer, guint sock_type );
    6.73 -static void* myth_init_io_watchers( void *data );
    6.74 -
    6.75 -void myth_file_transfer_close( MythFileTransfer *transfer );
    6.76 -
    6.77 -G_DEFINE_TYPE(MythFileTransfer, myth_file_transfer, G_TYPE_OBJECT)
    6.78 -
    6.79 -static guint64
    6.80 -mmyth_util_decode_long_long( GMythStringList *strlist, guint offset  )
    6.81 -{
    6.82 -
    6.83 -  guint64 ret_value = 0LL;
    6.84 -
    6.85 -  g_return_val_if_fail( strlist != NULL, ret_value );
    6.86 -
    6.87 -  if ( offset < gmyth_string_list_length( strlist ))
    6.88 -    g_printerr( "[%s] Offset is lower than the GMythStringList (offset = %d)!\n", __FUNCTION__, offset );
    6.89 -  g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
    6.90 -
    6.91 -  gint l1 = gmyth_string_list_get_int( strlist, offset );
    6.92 -  gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
    6.93 -
    6.94 -  ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
    6.95 -
    6.96 -  return ret_value;
    6.97 -
    6.98 -}
    6.99 -
   6.100 -static void
   6.101 -myth_file_transfer_class_init (MythFileTransferClass *klass)
   6.102 -{
   6.103 -  GObjectClass *gobject_class;
   6.104 -
   6.105 -  gobject_class = (GObjectClass *) klass;
   6.106 -
   6.107 -  gobject_class->dispose  = myth_file_transfer_dispose;
   6.108 -  gobject_class->finalize = myth_file_transfer_finalize;
   6.109 -}
   6.110 -
   6.111 -  static void
   6.112 -myth_file_transfer_init (MythFileTransfer *myth_file_transfer)
   6.113 -{ 
   6.114 -  g_return_if_fail( myth_file_transfer != NULL );
   6.115 -  myth_file_transfer->mythtv_version = MYTHTV_VERSION;
   6.116 -}
   6.117 -
   6.118 -static void
   6.119 -myth_file_transfer_dispose  (GObject *object)
   6.120 -{
   6.121 -  MythFileTransfer *myth_file_transfer = MYTH_FILE_TRANSFER(object);
   6.122 -
   6.123 -  myth_file_transfer_close( myth_file_transfer );
   6.124 -
   6.125 -  G_OBJECT_CLASS (myth_file_transfer_parent_class)->dispose (object);
   6.126 -}
   6.127 -
   6.128 -  static void
   6.129 -myth_file_transfer_finalize (GObject *object)
   6.130 -{
   6.131 -  g_signal_handlers_destroy (object);
   6.132 -
   6.133 -  G_OBJECT_CLASS (myth_file_transfer_parent_class)->finalize (object);
   6.134 -}
   6.135 -
   6.136 -  MythFileTransfer*
   6.137 -myth_file_transfer_new (gint num, GString *uri_str, gshort port, gint mythtv_version)
   6.138 -{
   6.139 -  MythFileTransfer *transfer = MYTH_FILE_TRANSFER ( g_object_new (
   6.140 -	MYTH_FILE_TRANSFER_TYPE, FALSE ));
   6.141 -
   6.142 -  if ( mythtv_version > 0 )
   6.143 -    transfer->mythtv_version = mythtv_version;
   6.144 -
   6.145 -  transfer->card_id = num;
   6.146 -
   6.147 -  transfer->rec_id = -1;
   6.148 -
   6.149 -  transfer->recordernum = 0;
   6.150 -  transfer->uri = myth_uri_new ( uri_str->str );
   6.151 -
   6.152 -  transfer->hostname = g_string_new( myth_uri_gethost(transfer->uri) );
   6.153 -  g_print( "\t--> transfer->hostname = %s\n", transfer->hostname->str );
   6.154 -
   6.155 -  if ( port >= 0 )
   6.156 -    transfer->port = port;
   6.157 -  else
   6.158 -    transfer->port = myth_uri_getport( transfer->uri );
   6.159 -
   6.160 -  g_print( "\t--> transfer->port = %d\n", transfer->port );
   6.161 -
   6.162 -  transfer->readposition = 0;
   6.163 -  transfer->filesize = MYTHTV_FILE_SIZE;
   6.164 -  transfer->timeoutisfast = FALSE;
   6.165 -
   6.166 -  transfer->userreadahead = MYTHTV_USER_READ_AHEAD;
   6.167 -  transfer->retries = MYTHTV_RETRIES;  
   6.168 -
   6.169 -  transfer->live_tv = FALSE;
   6.170 -
   6.171 -  transfer->query = g_string_new( MYTHTV_QUERY_HEADER );
   6.172 -  g_string_append_printf ( transfer->query, " %d", transfer->recordernum );
   6.173 -  g_print( "\t--> transfer->query = %s\n", transfer->query->str );
   6.174 -
   6.175 -  transfer->control_sock = NULL;
   6.176 -  transfer->event_sock = NULL;
   6.177 -  transfer->sock = NULL;
   6.178 -
   6.179 -  return transfer;
   6.180 -}
   6.181 -
   6.182 -gboolean
   6.183 -myth_file_transfer_livetv_setup( MythFileTransfer **transfer, GMythSocket *live_socket )
   6.184 -{
   6.185 -	(*transfer)->sock = live_socket;
   6.186 -	g_object_ref( live_socket );
   6.187 -
   6.188 -	return TRUE;
   6.189 -}
   6.190 -
   6.191 -gboolean
   6.192 -myth_file_transfer_playback_setup( MythFileTransfer **transfer, gboolean live_tv )
   6.193 -{
   6.194 -
   6.195 -  gboolean ret = TRUE;
   6.196 -
   6.197 -  (*transfer)->live_tv = live_tv;
   6.198 -
   6.199 -  printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
   6.200 -
   6.201 -  /* configure the control socket */
   6.202 -  if ((*transfer)->control_sock == NULL) { 
   6.203 -
   6.204 -    if ( myth_connect_to_transfer_backend ( transfer, MYTH_PLAYBACK_TYPE ) == NULL ) {
   6.205 -      g_printerr( "Connection to backend failed (Control Socket).\n" );
   6.206 -      ret = FALSE;
   6.207 -    }
   6.208 -
   6.209 -  } else {
   6.210 -    g_warning("Remote transfer control socket already created.\n");
   6.211 -  }
   6.212 -
   6.213 -  return ret;
   6.214 -
   6.215 -}
   6.216 -
   6.217 -gboolean
   6.218 -myth_file_transfer_setup( MythFileTransfer **transfer, gboolean live_tv )
   6.219 -{
   6.220 -  GMythStringList *strlist = NULL;
   6.221 -
   6.222 -  gboolean ret = TRUE;
   6.223 -
   6.224 -  (*transfer)->live_tv = live_tv;
   6.225 -
   6.226 -  printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
   6.227 -
   6.228 -#if 0
   6.229 -  /* configure the event socket */
   6.230 -  if ((*transfer)->event_sock == NULL) { 
   6.231 -
   6.232 -    if ( myth_connect_to_transfer_backend ( transfer, MYTH_MONITOR_TYPE ) == NULL ) {
   6.233 -      g_printerr( "Connection to backend failed (Event Socket).\n" );
   6.234 -      ret = FALSE;
   6.235 -    }
   6.236 -
   6.237 -  } else {
   6.238 -    g_warning("Remote transfer control socket already created.\n");
   6.239 -  }
   6.240 -#endif
   6.241 -
   6.242 -  /* configure the socket */
   6.243 -  if ( (*transfer)->sock == NULL ) { 
   6.244 -
   6.245 -    //if ( live_tv == FALSE ) {
   6.246 -
   6.247 -    if ( myth_connect_to_transfer_backend ( transfer, MYTH_FILETRANSFER_TYPE ) == NULL ) {
   6.248 -      g_printerr ("Connection to backend failed (Raw Transfer Socket).\n");
   6.249 -      ret = FALSE;
   6.250 -    }
   6.251 -
   6.252 -    if ( !(*transfer)->live_tv && (*transfer)->control_sock != NULL) {
   6.253 -      strlist = gmyth_string_list_new();
   6.254 -      g_string_printf ( (*transfer)->query, "%s %d", MYTHTV_QUERY_HEADER, (*transfer)->recordernum );
   6.255 -
   6.256 -      gmyth_string_list_append_string( strlist, (*transfer)->query );
   6.257 -      gmyth_string_list_append_char_array( strlist, "IS_OPEN" );
   6.258 -
   6.259 -      gmyth_socket_write_stringlist( (*transfer)->control_sock, strlist );
   6.260 -      gmyth_socket_read_stringlist( (*transfer)->control_sock, strlist );
   6.261 -
   6.262 -      if ( strlist!=NULL && gmyth_string_list_get_int( strlist, 0 ) == 1 ) {
   6.263 -	g_print( "[%s] Remote Myth FileTransfer socket is open!\n", __FUNCTION__ );
   6.264 -      } else {
   6.265 -	g_print( "[%s] Remote Myth FileTransfer socket is CLOSED! See the MythTV Server Backend for configuration details...\n", __FUNCTION__ );
   6.266 -	ret = FALSE;
   6.267 -      }
   6.268 -    }
   6.269 -
   6.270 -  } else {
   6.271 -    g_warning("Remote transfer (raw) socket already created.\n");
   6.272 -  }
   6.273 -
   6.274 -  return ret;
   6.275 -}
   6.276 -
   6.277 -static GMythSocket *
   6.278 -myth_connect_to_transfer_backend( MythFileTransfer **transfer, guint sock_type )
   6.279 -{
   6.280 -  GMythSocket *sock = NULL;
   6.281 -
   6.282 -  g_return_val_if_fail( transfer != NULL && *transfer != NULL, NULL );
   6.283 -  g_return_val_if_fail( (*transfer)->uri != NULL, NULL );
   6.284 -
   6.285 -  g_static_mutex_lock (&mutex);
   6.286 -
   6.287 -  gchar *path_dir = myth_uri_getpath( (*transfer)->uri );
   6.288 -  //g_print( "\t--> %s: path_dir = %s\n", __FUNCTION__, path_dir );
   6.289 -
   6.290 -  gchar *stype = g_strdup( "" );
   6.291 -
   6.292 -  //  if ( (*transfer)->live_tv == FALSE ) {
   6.293 -
   6.294 -  sock = gmyth_socket_new();
   6.295 -
   6.296 -  gmyth_socket_connect( &sock, (*transfer)->hostname->str, (*transfer)->port );
   6.297 -
   6.298 -  /*
   6.299 -     } else {
   6.300 -     sock = (*transfer)->sock;
   6.301 -     }
   6.302 -     */
   6.303 -#ifdef MYTHTV_ENABLE_DEBUG
   6.304 -
   6.305 -  g_print( "[%s] --> Creating socket... (%s, %d)\n", __FUNCTION__, (*transfer)->hostname->str, (*transfer)->port );
   6.306 -#endif
   6.307 -
   6.308 -  GMythStringList *strlist = NULL;
   6.309 -
   6.310 -  GString *hostname = g_string_new( myth_uri_gethost( (*transfer)->uri ) );
   6.311 -  GString *base_str = g_string_new( "" );
   6.312 -
   6.313 -  if ( gmyth_socket_check_protocol_version_number (sock, (*transfer)->mythtv_version) ) {
   6.314 -
   6.315 -    if (sock == NULL) {
   6.316 -      stype = (sock_type==MYTH_PLAYBACK_TYPE) ? "control socket" : "file data socket";
   6.317 -      g_printerr( "FileTransfer, open_socket(%s): \n"
   6.318 -	  "\t\t\tCould not connect to server \"%s\" @ port %d\n", stype, 
   6.319 -	  (*transfer)->hostname->str, (*transfer)->port );
   6.320 -      g_object_unref(sock);
   6.321 -      g_static_mutex_unlock (&mutex);
   6.322 -      return NULL;
   6.323 -    }
   6.324 -
   6.325 -    hostname = gmyth_socket_get_local_hostname();
   6.326 -
   6.327 -    g_print( "[%s] local hostname = %s\n", __FUNCTION__, hostname->str  );
   6.328 -
   6.329 -    if ( sock_type == MYTH_PLAYBACK_TYPE )
   6.330 -    {
   6.331 -      (*transfer)->control_sock = sock;
   6.332 -      g_string_printf( base_str, "ANN Playback %s %d", hostname->str, FALSE );
   6.333 -
   6.334 -      gmyth_socket_send_command( (*transfer)->control_sock, base_str );
   6.335 -      GString *resp = gmyth_socket_receive_response( (*transfer)->control_sock );
   6.336 -      g_print( "[%s] Got Playback response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
   6.337 -    }
   6.338 -    else if ( sock_type == MYTH_MONITOR_TYPE )
   6.339 -    {
   6.340 -      (*transfer)->event_sock = sock;
   6.341 -      g_string_printf( base_str, "ANN Monitor %s %d", hostname->str, TRUE );
   6.342 -
   6.343 -      gmyth_socket_send_command( (*transfer)->event_sock, base_str );
   6.344 -      GString *resp = gmyth_socket_receive_response( (*transfer)->event_sock );
   6.345 -      g_print( "[%s] Got Monitor response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
   6.346 -      g_thread_create( myth_init_io_watchers, (void*)(*transfer), FALSE, NULL );
   6.347 -
   6.348 -      g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
   6.349 -
   6.350 -    }
   6.351 -    else if ( sock_type == MYTH_FILETRANSFER_TYPE )
   6.352 -    {
   6.353 -      (*transfer)->sock = sock;
   6.354 -      strlist = gmyth_string_list_new();
   6.355 -      //g_string_printf( base_str, "ANN FileTransfer %s %d %d", hostname->str,
   6.356 -      //  		transfer->userreadahead, transfer->retries );
   6.357 -      g_string_printf( base_str, "ANN FileTransfer %s", hostname->str );
   6.358 -
   6.359 -      gmyth_string_list_append_string( strlist, base_str );
   6.360 -      gmyth_string_list_append_char_array( strlist, path_dir );
   6.361 -
   6.362 -      gmyth_socket_write_stringlist( (*transfer)->sock, strlist );
   6.363 -      gmyth_socket_read_stringlist( (*transfer)->sock, strlist );
   6.364 -
   6.365 -      /* socket number, where all the stream data comes from - got from the MythTV remote backend */
   6.366 -      (*transfer)->recordernum = gmyth_string_list_get_int( strlist, 1 );
   6.367 -
   6.368 -      /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */
   6.369 -      (*transfer)->filesize = mmyth_util_decode_long_long( strlist, 2 );
   6.370 -
   6.371 -      printf( "[%s] ***** Received: recordernum = %d, filesize = %" G_GUINT64_FORMAT "\n", __FUNCTION__,
   6.372 -	  (*transfer)->recordernum, (*transfer)->filesize );
   6.373 -
   6.374 -      if ( (*transfer)->filesize <= 0 ) {
   6.375 -	g_print( "[%s] Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", __FUNCTION__, (*transfer)->filesize );
   6.376 -	g_object_unref(sock);
   6.377 -	sock = NULL; 
   6.378 -      }
   6.379 -    }
   6.380 -    else if ( sock_type == MYTH_RINGBUFFER_TYPE )
   6.381 -    {
   6.382 -      (*transfer)->sock = sock;
   6.383 -      //myth_file_transfer_spawntv( (*transfer), NULL );      
   6.384 -
   6.385 -      strlist = gmyth_string_list_new();
   6.386 -      g_string_printf( base_str, "ANN RingBuffer %s %d", hostname->str, (*transfer)->card_id );
   6.387 -
   6.388 -      gmyth_socket_send_command( (*transfer)->sock, base_str );
   6.389 -      GString *resp = gmyth_socket_receive_response( (*transfer)->sock );
   6.390 -      g_print( "[%s] Got RingBuffer response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
   6.391 -
   6.392 -    }
   6.393 -
   6.394 -  }
   6.395 -
   6.396 -  printf("[%s] ANN %s sent: %s\n", (sock_type==MYTH_PLAYBACK_TYPE) ? "Playback" : (sock_type==MYTH_FILETRANSFER_TYPE) ? "FileTransfer" : "Monitor", __FUNCTION__, base_str->str);
   6.397 -
   6.398 -  if ( strlist != NULL )
   6.399 -    g_object_unref( strlist );
   6.400 -
   6.401 -  g_static_mutex_unlock (&mutex);
   6.402 -
   6.403 -  return sock;
   6.404 -}    
   6.405 -
   6.406 -void
   6.407 -myth_file_transfer_spawntv ( MythFileTransfer *file_transfer, 
   6.408 -    GString *tvchain_id )
   6.409 -{
   6.410 -  GMythStringList *str_list;
   6.411 -
   6.412 -  g_debug ("myth_file_transfer_spawntv.\n");
   6.413 -
   6.414 -  str_list = gmyth_string_list_new ();
   6.415 -
   6.416 -  g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER, 
   6.417 -      file_transfer->card_id );
   6.418 -  gmyth_string_list_append_string (str_list, file_transfer->query);
   6.419 -  gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
   6.420 -  if (tvchain_id!=NULL) {
   6.421 -    gmyth_string_list_append_string (str_list, tvchain_id);
   6.422 -    gmyth_string_list_append_int (str_list, FALSE); // PIP = FALSE (0)
   6.423 -  }
   6.424 -
   6.425 -  gmyth_socket_sendreceive_stringlist ( file_transfer->sock, str_list );
   6.426 -
   6.427 -  //GString *str = NULL;
   6.428 -
   6.429 -  //if (str_list!=NULL && (str = gmyth_string_list_get_string( str_list, 0 )) != NULL && strcasecmp( str->str, "ok" ) != 0 ) {
   6.430 -  //  g_print( "[%s]\t\tSpawnLiveTV is OK!\n", __FUNCTION__ );
   6.431 -  //}
   6.432 -  if (str_list!=NULL)
   6.433 -    g_object_unref (str_list);
   6.434 -
   6.435 -}
   6.436 -
   6.437 -gboolean
   6.438 -myth_file_transfer_is_recording ( MythFileTransfer *file_transfer )
   6.439 -{
   6.440 -  gboolean ret = TRUE;
   6.441 -  
   6.442 -  GMythStringList *str_list = gmyth_string_list_new ();
   6.443 -
   6.444 -  g_debug ( "[%s]\n", __FUNCTION__ );
   6.445 -  g_static_mutex_lock (&mutex);
   6.446 -
   6.447 -  g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER, 
   6.448 -      file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id );
   6.449 -  gmyth_string_list_append_string (str_list, file_transfer->query);
   6.450 -  gmyth_string_list_append_string (str_list, g_string_new ("IS_RECORDING"));
   6.451 -
   6.452 -  gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list );
   6.453 -
   6.454 -  if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 ) 
   6.455 -  {
   6.456 -    GString *str = NULL;
   6.457 -    if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp( str->str, "bad" )!= 0 ) {
   6.458 -      gint is_rec = gmyth_string_list_get_int( str_list, 0 );
   6.459 -      if ( is_rec != 0 )
   6.460 -	ret = TRUE;
   6.461 -      else
   6.462 -	ret = FALSE;
   6.463 -    }
   6.464 -  }  
   6.465 -  g_print( "[%s] %s, stream is %s being recorded!\n", __FUNCTION__, ret ? "YES" : "NO", ret ? "" : "NOT" );
   6.466 -  g_static_mutex_unlock (&mutex);
   6.467 -
   6.468 -  if ( str_list != NULL )
   6.469 -    g_object_unref (str_list);
   6.470 -
   6.471 -  return ret;
   6.472 -
   6.473 -}
   6.474 -
   6.475 -guint64
   6.476 -myth_file_transfer_get_file_position ( MythFileTransfer *file_transfer )
   6.477 -{
   6.478 -  guint64 pos = 0;
   6.479 -
   6.480 -  GMythStringList *str_list = gmyth_string_list_new ();
   6.481 -
   6.482 -  g_debug ( "[%s]\n", __FUNCTION__ );
   6.483 -  g_static_mutex_lock (&mutex);
   6.484 -
   6.485 -  g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER, 
   6.486 -      file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id );
   6.487 -
   6.488 -  gmyth_string_list_append_string (str_list, file_transfer->query);
   6.489 -  gmyth_string_list_append_string (str_list, g_string_new ("GET_FILE_POSITION"));
   6.490 -
   6.491 -  gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list );
   6.492 -
   6.493 -  if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 ) 
   6.494 -  {
   6.495 -    GString *str = NULL;
   6.496 -    if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp ( str->str, "bad" ) != 0 )
   6.497 -      pos = gmyth_util_decode_long_long( str_list, 0 );
   6.498 -  } 
   6.499 -  g_static_mutex_unlock (&mutex);
   6.500 -
   6.501 -#ifndef MYTHTV_ENABLE_DEBUG
   6.502 -
   6.503 -  g_print( "[%s] Got file position = %llu\n", __FUNCTION__, pos );
   6.504 -#endif
   6.505 -  if (str_list!=NULL)
   6.506 -    g_object_unref (str_list);
   6.507 -
   6.508 -  return pos;
   6.509 -
   6.510 -}
   6.511 -
   6.512 -  glong
   6.513 -myth_file_transfer_get_recordernum( MythFileTransfer *transfer )
   6.514 -{
   6.515 -  return transfer->recordernum;
   6.516 -}
   6.517 -
   6.518 -  glong
   6.519 -myth_file_transfer_get_filesize( MythFileTransfer *transfer )
   6.520 -{
   6.521 -  return transfer->filesize;
   6.522 -}
   6.523 -
   6.524 -  gboolean
   6.525 -myth_file_transfer_isopen( MythFileTransfer *transfer )
   6.526 -{
   6.527 -  return (transfer->sock != NULL && transfer->control_sock != NULL);
   6.528 -}
   6.529 -
   6.530 -  void
   6.531 -myth_file_transfer_close( MythFileTransfer *transfer )
   6.532 -{
   6.533 -  GMythStringList *strlist;
   6.534 -
   6.535 -  if (transfer->control_sock == NULL)
   6.536 -    return;
   6.537 -
   6.538 -  strlist = gmyth_string_list_new( );
   6.539 -
   6.540 -  g_string_printf( transfer->query, "%s %d", MYTHTV_QUERY_HEADER, 
   6.541 -      transfer->recordernum );
   6.542 -  gmyth_string_list_append_string( strlist, transfer->query );
   6.543 -  gmyth_string_list_append_char_array( strlist, "DONE" );
   6.544 -
   6.545 -
   6.546 -  if ( gmyth_socket_sendreceive_stringlist(transfer->control_sock, strlist) <= 0 )
   6.547 -  {
   6.548 -    g_printerr( "Remote file timeout.\n" );
   6.549 -  }
   6.550 -
   6.551 -  if (transfer->sock)
   6.552 -  {
   6.553 -    g_object_unref( transfer->sock );
   6.554 -    transfer->sock = NULL;
   6.555 -  }
   6.556 -
   6.557 -  if (transfer->control_sock)
   6.558 -  {
   6.559 -    g_object_unref( transfer->control_sock );
   6.560 -    transfer->control_sock = NULL;
   6.561 -  } 
   6.562 -
   6.563 -}
   6.564 -
   6.565 -  void
   6.566 -myth_file_transfer_reset_controlsock( MythFileTransfer *transfer )
   6.567 -{
   6.568 -  if (transfer->control_sock == NULL)
   6.569 -  {
   6.570 -    g_printerr( "myth_file_transfer_reset_controlsock(): Called with no control socket" );
   6.571 -    return;
   6.572 -  }
   6.573 -
   6.574 -  GString *str = gmyth_socket_receive_response( transfer->control_sock );
   6.575 -
   6.576 -  g_string_free( str, TRUE );
   6.577 -}
   6.578 -
   6.579 -void
   6.580 -myth_file_transfer_reset_sock( MythFileTransfer *transfer )
   6.581 -{
   6.582 -  if ( transfer->sock == NULL )
   6.583 -  {
   6.584 -    g_printerr( "myth_file_transfer_reset_sock(): Called with no raw socket" );
   6.585 -    return;
   6.586 -  }
   6.587 -
   6.588 -  GString *str = gmyth_socket_receive_response( transfer->sock );
   6.589 -
   6.590 -  g_string_free( str, TRUE );
   6.591 -}
   6.592 -
   6.593 -void
   6.594 -myth_file_transfer_reset( MythFileTransfer *transfer )
   6.595 -{
   6.596 -  myth_file_transfer_reset_controlsock( transfer );
   6.597 -  myth_file_transfer_reset_sock( transfer );
   6.598 -}
   6.599 -
   6.600 -guint64
   6.601 -myth_file_transfer_seek(MythFileTransfer *transfer, guint64 pos, gint whence)
   6.602 -{
   6.603 -  if (transfer->sock == NULL)
   6.604 -  {
   6.605 -    g_printerr( "[%s] myth_file_transfer_seek(): Called with no socket", __FUNCTION__ );
   6.606 -    return 0;
   6.607 -  }
   6.608 -
   6.609 -  if (transfer->control_sock == NULL)
   6.610 -    return 0;
   6.611 -
   6.612 -  // if (!controlSock->isOpen() || controlSock->error())
   6.613 -  //   return 0;
   6.614 -
   6.615 -  GMythStringList *strlist = gmyth_string_list_new();
   6.616 -  g_string_printf (transfer->query, "%s %d", MYTHTV_QUERY_HEADER, transfer->recordernum);
   6.617 -  gmyth_string_list_append_string( strlist, transfer->query );  
   6.618 -  gmyth_string_list_append_char_array( strlist, "SEEK" );
   6.619 -  gmyth_string_list_append_uint64( strlist, pos );
   6.620 -  //  gmyth_string_list_append_int( strlist, whence );
   6.621 -
   6.622 -  if (pos > 0 )
   6.623 -    gmyth_string_list_append_uint64( strlist, pos );
   6.624 -  else
   6.625 -    gmyth_string_list_append_uint64( strlist, transfer->readposition );
   6.626 -
   6.627 -  gmyth_socket_sendreceive_stringlist( transfer->control_sock, strlist );
   6.628 -
   6.629 -  guint64 retval = gmyth_string_list_get_uint64(strlist, 0);
   6.630 -  transfer->readposition = retval;
   6.631 -  g_print( "[%s] got reading position pointer from the streaming = %llu\n", 
   6.632 -      __FUNCTION__, retval );
   6.633 -
   6.634 -  //myth_file_transfer_reset( transfer );
   6.635 -
   6.636 -  return retval;
   6.637 -}
   6.638 -
   6.639 -static gboolean
   6.640 -myth_control_sock_listener( GIOChannel *source, GIOCondition condition, gpointer data )
   6.641 -{
   6.642 -
   6.643 -  GIOStatus ret;
   6.644 -  GError *err = NULL;
   6.645 -  gchar *msg = g_strdup("");
   6.646 -
   6.647 -  gsize len;
   6.648 -  if (condition & G_IO_HUP)
   6.649 -    g_error ("Read end of pipe died!\n");
   6.650 -  ret = g_io_channel_read_line ( source, &msg, &len, NULL, &err);
   6.651 -  if ( ret == G_IO_STATUS_ERROR )
   6.652 -    g_error ("[%s] Error reading: %s\n", __FUNCTION__, err != NULL ? err->message : "" );
   6.653 -  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 : "" );
   6.654 -  if ( msg != NULL )
   6.655 -    g_free (msg);
   6.656 -
   6.657 -  return TRUE;
   6.658 -
   6.659 -}
   6.660 -
   6.661 -static void*
   6.662 -myth_init_io_watchers( void *data )
   6.663 -{
   6.664 -  MythFileTransfer *transfer = (MythFileTransfer*)data;
   6.665 -  GMainContext *context = g_main_context_new();
   6.666 -  GMainLoop *loop = g_main_loop_new( NULL, FALSE );
   6.667 -
   6.668 -  GSource *source = NULL;
   6.669 -
   6.670 -  if ( transfer->event_sock->sd_io_ch != NULL )
   6.671 -    source = g_io_create_watch( transfer->event_sock->sd_io_ch, G_IO_IN | G_IO_HUP );
   6.672 -
   6.673 -  g_source_set_callback ( source, (GSourceFunc)myth_control_sock_listener, NULL, NULL );
   6.674 -
   6.675 -  g_source_attach( source, context );
   6.676 -
   6.677 -  if (source==NULL)
   6.678 -    g_printerr( "[%s] Error adding watch listener function to the IO control channel!\n", __FUNCTION__ );
   6.679 -
   6.680 -  g_main_loop_run( loop );
   6.681 -
   6.682 -  g_source_unref( source );
   6.683 -
   6.684 -  g_main_loop_unref( loop );
   6.685 -
   6.686 -  g_main_context_unref( context );
   6.687 -
   6.688 -  return NULL;
   6.689 -}
   6.690 -
   6.691 -  gint 
   6.692 -myth_file_transfer_read(MythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited)
   6.693 -{
   6.694 -  gint recv = 0;
   6.695 -  gsize bytes_read = 0;
   6.696 -
   6.697 -  gint sent = 0;
   6.698 -  //guint zerocnt = 0;
   6.699 -  gboolean response = FALSE;
   6.700 -
   6.701 -  GIOChannel *io_channel;
   6.702 -  GIOChannel *io_channel_control;
   6.703 -
   6.704 -  GIOCondition io_cond;
   6.705 -  GIOCondition io_cond_control;
   6.706 -  GIOStatus io_status = G_IO_STATUS_NORMAL, io_status_control = G_IO_STATUS_NORMAL;   
   6.707 -
   6.708 -  gint buf_len = MYTHTV_BUFFER_SIZE;
   6.709 -
   6.710 -  GMythStringList *strlist = NULL;
   6.711 -  GError *error = NULL;
   6.712 -
   6.713 -  gchar *trash = g_strdup("");
   6.714 -
   6.715 -  g_return_val_if_fail ( data != NULL, -2 );
   6.716 -
   6.717 -  /* gets the size of the entire file, if the size requested is lesser than 0 */
   6.718 -  if ( size <= 0 )
   6.719 -    size = transfer->filesize;
   6.720 -
   6.721 -  io_channel = transfer->sock->sd_io_ch;
   6.722 -  io_channel_control = transfer->control_sock->sd_io_ch;
   6.723 -
   6.724 -  //g_io_channel_set_flags( io_channel, G_IO_FLAG_APPEND | 
   6.725 -  //    G_IO_STATUS_AGAIN | G_IO_FLAG_IS_READABLE | G_IO_FLAG_IS_WRITEABLE | 
   6.726 -  //    G_IO_FLAG_IS_SEEKABLE, NULL );
   6.727 -
   6.728 -  io_status = g_io_channel_set_encoding( io_channel, NULL, &error );
   6.729 -  if ( io_status == G_IO_STATUS_NORMAL )
   6.730 -    g_print( "[%s] Setting encoding to binary data socket).\n", __FUNCTION__ );
   6.731 -
   6.732 -  io_cond = g_io_channel_get_buffer_condition( io_channel );  
   6.733 -
   6.734 -  io_cond_control = g_io_channel_get_buffer_condition( io_channel );
   6.735 -
   6.736 -  if ( transfer->sock == NULL || ( io_status == G_IO_STATUS_ERROR ) )
   6.737 -  {
   6.738 -    g_printerr( "myth_file_transfer_read(): Called with no raw socket.\n" );
   6.739 -    recv = -1;
   6.740 -    goto cleanup;
   6.741 -  }
   6.742 -
   6.743 -  if ( transfer->control_sock == NULL || ( io_status_control == G_IO_STATUS_ERROR ) )
   6.744 -  {
   6.745 -    g_printerr( "myth_file_transfer_read(): Called with no control socket.\n" );
   6.746 -    recv = -1;
   6.747 -    goto cleanup;
   6.748 -  }
   6.749 -
   6.750 -  /*
   6.751 -     if (!controlSock->isOpen() || controlSock->error())
   6.752 -     return -1;
   6.753 -     */
   6.754 -
   6.755 -  if ( ( io_cond & G_IO_IN ) != 0 ) {
   6.756 -    do 
   6.757 -    {
   6.758 -
   6.759 -      io_status = g_io_channel_read_line( io_channel, &trash, &bytes_read, NULL, &error);
   6.760 -
   6.761 -      g_print( "[%s] cleaning buffer on IO binary channel... (%s)\n", __FUNCTION__, trash );
   6.762 -      io_cond = g_io_channel_get_buffer_condition( io_channel );
   6.763 -
   6.764 -    } while ( ( io_cond & G_IO_IN ) != 0 && ( io_status != G_IO_STATUS_ERROR ) );
   6.765 -
   6.766 -    if ( trash!= NULL )
   6.767 -      g_free( trash );
   6.768 -  }
   6.769 -
   6.770 -  if ( ( io_cond_control & G_IO_IN ) != 0 ) {
   6.771 -    GMythStringList *strlist_tmp = gmyth_string_list_new();
   6.772 -    gmyth_socket_read_stringlist( transfer->control_sock, strlist_tmp );
   6.773 -    g_object_unref( strlist_tmp );
   6.774 -  }
   6.775 -
   6.776 -  wait_to_transfer = 0;
   6.777 -
   6.778 -  while ( transfer->live_tv && ( myth_file_transfer_get_file_position( transfer ) < 4096 ) &&
   6.779 -  		wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS )
   6.780 -  	g_usleep( 1000*50 ); /* waits just for 2/10 second */
   6.781 -
   6.782 -  //g_thread_create( myth_init_io_watchers, (void*)transfer, FALSE, NULL );
   6.783 -  //g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
   6.784 -
   6.785 -  g_static_mutex_lock (&mutex);
   6.786 -  strlist = gmyth_string_list_new();
   6.787 -
   6.788 -  g_string_printf ( transfer->query, "%s %d", /*transfer->live_tv ? MYTHTV_RECORDER_HEADER :*/  MYTHTV_QUERY_HEADER, 
   6.789 -      /* transfer->live_tv ? transfer->card_id :*/ transfer->recordernum ); // transfer->recordernum
   6.790 -  g_print( "\t[%s] Transfer_query = %s\n", __FUNCTION__, transfer->query->str );
   6.791 -  strlist = gmyth_string_list_new();
   6.792 -
   6.793 -  gmyth_string_list_append_string( strlist, transfer->query );
   6.794 -  gmyth_string_list_append_char_array( strlist, /*transfer->live_tv ? "REQUEST_BLOCK_RINGBUF" :*/ "REQUEST_BLOCK" );
   6.795 -  gmyth_string_list_append_int( strlist, size );
   6.796 -
   6.797 -  gmyth_socket_write_stringlist( transfer->control_sock, strlist );
   6.798 -  sent = size;
   6.799 -
   6.800 -  //data = (void*)g_new0( gchar, size );
   6.801 -
   6.802 -  g_io_channel_flush( io_channel_control, NULL );
   6.803 -//  g_io_channel_flush( io_channel, NULL );
   6.804 -
   6.805 -  io_cond = g_io_channel_get_buffer_condition( io_channel );
   6.806 -
   6.807 -  while ( ( recv < sent ) )//&& ( io_cond & G_IO_IN ) != 0 )
   6.808 -  {
   6.809 -    do
   6.810 -    {
   6.811 -      //while ( ( io_cond & G_IO_IN ) == 0 ) {
   6.812 -      //usleep(200);
   6.813 -      //
   6.814 -      //io_cond = g_io_channel_get_buffer_condition( io_channel );
   6.815 -      //
   6.816 -
   6.817 -      buf_len = ( sent - recv ) > MYTHTV_BUFFER_SIZE ? MYTHTV_BUFFER_SIZE : ( sent - recv );
   6.818 -
   6.819 -      io_status = g_io_channel_read_chars( io_channel, data + recv, 
   6.820 -	  buf_len, &bytes_read, &error );
   6.821 -      /*
   6.822 -	 GString *sss = g_string_new("");
   6.823 -	 sss = g_string_append_len( sss, (gchar*)data+recv, bytes_read );
   6.824 -
   6.825 -	 g_print( "[%s] Reading buffer (length = %d)\n", __FUNCTION__, bytes_read);
   6.826 -	 */
   6.827 -      if ( bytes_read > 0 )
   6.828 -      {
   6.829 -	if ( bytes_read <= buf_len )
   6.830 -	  recv += bytes_read;
   6.831 -      } 
   6.832 -
   6.833 -      if ( io_status == G_IO_STATUS_EOF ) {
   6.834 -	g_printerr( "[%s] got EOS!", __FUNCTION__ );
   6.835 -	break;
   6.836 -      } else if ( io_status == G_IO_STATUS_ERROR ) {
   6.837 -	g_printerr( "[%s] myth_file_transfer_read(): socket error.\n", __FUNCTION__ );
   6.838 -	break;
   6.839 -      }
   6.840 -
   6.841 -      /* increase buffer size, to allow get more data (do not obey to the buffer size) */
   6.842 -      if ( read_unlimited == TRUE ) {
   6.843 -	//if ( recv > buf_len )
   6.844 -	// sent += (bytes_read - buf_len) + 1;
   6.845 -      }
   6.846 -      if ( bytes_read == buf_len )
   6.847 -	break;
   6.848 -
   6.849 -      /* verify if the input (read) buffer is ready to receive data */
   6.850 -      io_cond = g_io_channel_get_buffer_condition( io_channel );
   6.851 -
   6.852 -      g_print( "[%s]\t io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, 
   6.853 -      		( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
   6.854 -
   6.855 -    } while ( recv < sent && ( ( io_cond & G_IO_IN ) != 0 ) && ( io_status == G_IO_STATUS_NORMAL ) );
   6.856 -
   6.857 -    io_cond_control = g_io_channel_get_buffer_condition( io_channel_control );
   6.858 -    if ( ( io_status == G_IO_STATUS_EOF ) || ( ( io_cond_control & G_IO_IN ) != 0 ) )
   6.859 -    {
   6.860 -      gmyth_socket_read_stringlist( transfer->control_sock, strlist );
   6.861 -      sent = gmyth_string_list_get_int( strlist,  0 ); // -1 on backend error      
   6.862 -      g_print( "[%s]\t sent = %d, io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, 
   6.863 -	  sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
   6.864 -      response = TRUE;
   6.865 -    }
   6.866 -  }
   6.867 -
   6.868 -  if ( ( ( error == NULL ) && ( response == FALSE ) ) || 
   6.869 -  		( io_status == G_IO_STATUS_EOF ) || ( ( io_cond & G_IO_IN ) == 0 ) )
   6.870 -  {
   6.871 -    if ( gmyth_socket_read_stringlist( transfer->control_sock, strlist ) > 0 )
   6.872 -    {
   6.873 -      if ( strlist != NULL && gmyth_string_list_length(strlist) > 0 ) {
   6.874 -	sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error
   6.875 -	g_print( "[%s]\t sent = %d, io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, 
   6.876 -	    sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
   6.877 -      }
   6.878 -    }
   6.879 -    else
   6.880 -    {
   6.881 -      g_printerr ( "myth_file_transfer_read(): No response from control socket.");
   6.882 -      sent = -1;
   6.883 -    }
   6.884 -
   6.885 -    if ( error!=NULL ) {
   6.886 -      g_printerr( "[%s] Error occurred: (%d, %s)\n", __FUNCTION__, error->code, error->message );
   6.887 -      g_error_free( error );
   6.888 -    }
   6.889 -  }
   6.890 -
   6.891 -cleanup:
   6.892 -
   6.893 -  if ( trash != NULL )
   6.894 -    g_free( trash );
   6.895 -
   6.896 -  if ( strlist != NULL )
   6.897 -    g_object_unref( strlist );
   6.898 -
   6.899 -  g_static_mutex_unlock (&mutex);
   6.900 -  g_print( "myth_file_transfer_read(): reqd=%d, rcvd=%d, rept=%d, "\
   6.901 -      "(rcvd and rept MUST be the same!)\n", size, 
   6.902 -      recv, sent );
   6.903 -
   6.904 -  //if ( sent != recv ) {
   6.905 -  //  recv = -1;
   6.906 -  //}
   6.907 -
   6.908 -  if ( error != NULL )
   6.909 -    g_printerr( "ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message, 
   6.910 -	error->code );
   6.911 -
   6.912 -  return recv;
   6.913 -}
   6.914 -
   6.915 -  void 
   6.916 -myth_file_transfer_settimeout( MythFileTransfer *transfer, gboolean fast )
   6.917 -{
   6.918 -
   6.919 -  GMythStringList *strlist = NULL;
   6.920 -
   6.921 -  if ( transfer->timeoutisfast == fast )
   6.922 -    return;
   6.923 -
   6.924 -  if ( transfer->sock == NULL )
   6.925 -  {
   6.926 -    g_printerr( "myth_file_transfer_settimeout(): Called with no socket" );
   6.927 -    return;
   6.928 -  }
   6.929 -
   6.930 -  if ( transfer->control_sock == NULL )
   6.931 -    return;
   6.932 -
   6.933 -  strlist = gmyth_string_list_new(); 
   6.934 -  gmyth_string_list_append_string( strlist, transfer->query );
   6.935 -  gmyth_string_list_append_char_array( strlist, "SET_TIMEOUT" );
   6.936 -  gmyth_string_list_append_int( strlist, fast ); 
   6.937 -
   6.938 -  gmyth_socket_write_stringlist( transfer->control_sock, strlist );
   6.939 -  gmyth_socket_read_stringlist( transfer->control_sock, strlist );
   6.940 -
   6.941 -  transfer->timeoutisfast = fast;
   6.942 -
   6.943 -}
   6.944 -
   6.945 -#ifdef DO_TESTING
   6.946 -
   6.947 -  int
   6.948 -main( int argc, char *argv[] )
   6.949 -{
   6.950 -  g_type_init();
   6.951 -
   6.952 -  MythFileTransfer *file_transfer = myth_file_transfer_new( 1, 
   6.953 -      g_string_new("myth://192.168.1.109:6543/jshks.nuv"), -1, MYTHTV_VERSION );
   6.954 -  myth_file_transfer_setup( &file_transfer );
   6.955 -  gchar *data = g_strdup("");
   6.956 -
   6.957 -  gint num = myth_file_transfer_read( file_transfer, data, -1 );
   6.958 -
   6.959 -  return 0;
   6.960 -
   6.961 -}
   6.962 -
   6.963 -#endif
     7.1 --- a/gst-plugins-mythtv/myth_file_transfer.h	Tue Sep 26 15:30:52 2006 +0100
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,93 +0,0 @@
     7.4 -/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
     7.5 -
     7.6 -#ifndef __MYTH_FILE_TRANSFER_H__
     7.7 -#define __MYTH_FILE_TRANSFER_H__
     7.8 -
     7.9 -#include <glib-object.h>
    7.10 -
    7.11 -#include <gmyth/gmyth_socket.h>
    7.12 -#include "myth_uri.h"
    7.13 -#include "myth_livetv.h"
    7.14 -
    7.15 -#include <stdio.h>
    7.16 -#include <stdlib.h>
    7.17 -#include <string.h>
    7.18 -#include <netdb.h>
    7.19 -#include <sys/socket.h>
    7.20 -#include <unistd.h>
    7.21 -
    7.22 -#define G_BEGIN_DECLS
    7.23 -
    7.24 -#define MYTH_FILE_TRANSFER_TYPE               (myth_file_transfer_get_type ())
    7.25 -#define MYTH_FILE_TRANSFER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_FILE_TRANSFER_TYPE, MythFileTransfer))
    7.26 -#define MYTH_FILE_TRANSFER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_FILE_TRANSFER_TYPE, MythFileTransferClass))
    7.27 -#define IS_MYTH_FILE_TRANSFER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_FILE_TRANSFER_TYPE))
    7.28 -#define IS_MYTH_FILE_TRANSFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_FILE_TRANSFER_TYPE))
    7.29 -#define MYTH_FILE_TRANSFER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), MYTH_FILE_TRANSFER_TYPE, MythFileTransferClass))
    7.30 -
    7.31 -
    7.32 -typedef struct _MythFileTransfer         MythFileTransfer;
    7.33 -typedef struct _MythFileTransferClass    MythFileTransferClass;
    7.34 -
    7.35 -struct _MythFileTransferClass
    7.36 -{
    7.37 -	GObjectClass parent_class;
    7.38 -
    7.39 -	/* callbacks */
    7.40 -	/* no one for now */
    7.41 -};
    7.42 -
    7.43 -struct _MythFileTransfer
    7.44 -{
    7.45 -	GObject parent;
    7.46 -
    7.47 -	/* Myth URI structure */
    7.48 -	const MythURI *uri;
    7.49 -	
    7.50 -	/* MythTV version number */	
    7.51 -	gint mythtv_version;
    7.52 -
    7.53 -	/* socket descriptors */
    7.54 -	GMythSocket *control_sock;
    7.55 -	GMythSocket *event_sock;
    7.56 -	GMythSocket *sock;
    7.57 -
    7.58 -	guint64 readposition;
    7.59 -	guint64 filesize;
    7.60 -	gboolean timeoutisfast;
    7.61 -	gboolean userreadahead;
    7.62 -	gboolean live_tv;
    7.63 -	gint retries;
    7.64 -
    7.65 -	GString *query;
    7.66 -
    7.67 -	gint rec_id;
    7.68 -	gint recordernum;
    7.69 -	gint card_id;
    7.70 -	GString *hostname;
    7.71 -	gint port;
    7.72 -};
    7.73 -
    7.74 -GType          myth_file_transfer_get_type        (void);
    7.75 -
    7.76 -MythFileTransfer* myth_file_transfer_new (gint num, GString *hostname, gshort port, gint mythtv_version );
    7.77 -
    7.78 -gint myth_file_transfer_read(MythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited);
    7.79 -
    7.80 -guint64 myth_file_transfer_seek(MythFileTransfer *transfer, guint64 pos, gint whence);
    7.81 -
    7.82 -gboolean myth_file_transfer_playback_setup( MythFileTransfer **transfer, gboolean live_tv );
    7.83 -
    7.84 -gboolean myth_file_transfer_setup( MythFileTransfer **transfer, gboolean live_tv );
    7.85 -
    7.86 -gboolean myth_file_transfer_livetv_setup( MythFileTransfer **transfer, GMythSocket *live_sock );
    7.87 -
    7.88 -void myth_file_transfer_spawntv ( MythFileTransfer *file_transfer, GString *tvchain_id );
    7.89 -
    7.90 -gboolean myth_file_transfer_is_recording( MythFileTransfer *file_transfer );
    7.91 -
    7.92 -guint64  myth_file_transfer_get_file_position( MythFileTransfer *file_transfer );
    7.93 -
    7.94 -#define G_END_DECLS
    7.95 -
    7.96 -#endif /* __MYTH_FILE_TRANSFER_H__ */
     8.1 --- a/gst-plugins-mythtv/myth_livetv.c	Tue Sep 26 15:30:52 2006 +0100
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,220 +0,0 @@
     8.4 -
     8.5 -#include <gmyth/gmyth_context.h>
     8.6 -#include <gmyth/gmyth_remote_util.h>
     8.7 -#include <gmyth/gmyth_tvchain.h>
     8.8 -
     8.9 -#include "myth_livetv.h"
    8.10 -#include "myth_file_transfer.h"
    8.11 -
    8.12 -static void myth_livetv_class_init          (MythLiveTVClass *klass);
    8.13 -static void myth_livetv_init                (MythLiveTV *object);
    8.14 -
    8.15 -static void myth_livetv_dispose  (GObject *object);
    8.16 -static void myth_livetv_finalize (GObject *object);
    8.17 -
    8.18 -G_DEFINE_TYPE(MythLiveTV, myth_livetv, G_TYPE_OBJECT)
    8.19 -
    8.20 -static void
    8.21 -myth_livetv_class_init (MythLiveTVClass *klass)
    8.22 -{
    8.23 -	GObjectClass *gobject_class;
    8.24 -
    8.25 -	gobject_class = (GObjectClass *) klass;
    8.26 -
    8.27 -	gobject_class->dispose  = myth_livetv_dispose;
    8.28 -	gobject_class->finalize = myth_livetv_finalize;	
    8.29 -}
    8.30 -
    8.31 -static void
    8.32 -myth_livetv_init (MythLiveTV *livetv)
    8.33 -{
    8.34 -	livetv->backend_hostname = NULL;
    8.35 -	livetv->backend_port = 0;
    8.36 -	livetv->local_hostname = NULL;
    8.37 -
    8.38 -	livetv->remote_encoder = NULL;
    8.39 -	livetv->tvchain = NULL;
    8.40 -	livetv->proginfo = NULL;
    8.41 -}
    8.42 -
    8.43 -static void
    8.44 -myth_livetv_dispose  (GObject *object)
    8.45 -{
    8.46 -
    8.47 -	G_OBJECT_CLASS (myth_livetv_parent_class)->dispose (object);
    8.48 -}
    8.49 -
    8.50 -static void
    8.51 -myth_livetv_finalize (GObject *object)
    8.52 -{
    8.53 -	g_signal_handlers_destroy (object);
    8.54 -
    8.55 -	MythLiveTV *livetv = MYTH_LIVETV (object);
    8.56 -
    8.57 -	g_debug ("[%s] Finalizing livetv", __FUNCTION__);
    8.58 -
    8.59 -	if ( livetv->remote_encoder != NULL ) {
    8.60 -		g_object_unref (livetv->remote_encoder);
    8.61 -		livetv->remote_encoder = NULL;
    8.62 -	}
    8.63 -
    8.64 -	if ( livetv->tvchain != NULL ) {
    8.65 -		g_object_unref (livetv->tvchain);
    8.66 -		livetv->tvchain = NULL;
    8.67 -	}
    8.68 -
    8.69 -	if ( livetv->proginfo != NULL ) {
    8.70 -		g_object_unref (livetv->proginfo);
    8.71 -		livetv->proginfo = NULL;
    8.72 -	}
    8.73 -
    8.74 -	G_OBJECT_CLASS ( myth_livetv_parent_class )->finalize ( object );
    8.75 -}
    8.76 -
    8.77 -MythLiveTV*
    8.78 -myth_livetv_new ()
    8.79 -{
    8.80 -	MythLiveTV *livetv = MYTH_LIVETV ( g_object_new( MYTH_LIVETV_TYPE, NULL ) );
    8.81 -
    8.82 -	return livetv;
    8.83 -}
    8.84 -
    8.85 -gboolean
    8.86 -myth_livetv_setup ( MythLiveTV *livetv )
    8.87 -{
    8.88 -
    8.89 -	// FIXME: Get from the settings
    8.90 -	GMythSettings *msettings = gmyth_context_get_settings ();
    8.91 -	gboolean res = TRUE;
    8.92 -
    8.93 -	livetv->is_livetv = TRUE;
    8.94 -
    8.95 -	res = gmyth_context_check_connection();
    8.96 -	if (!res) {
    8.97 -		g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);	
    8.98 -		res = FALSE;
    8.99 -		goto error;
   8.100 -	}
   8.101 -
   8.102 -	livetv->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
   8.103 -	livetv->backend_port = gmyth_settings_get_backend_port (msettings);
   8.104 -
   8.105 -	livetv->local_hostname  = g_string_new("");    
   8.106 -	gmyth_context_get_local_hostname (livetv->local_hostname);
   8.107 -
   8.108 -	if ( livetv->local_hostname == NULL ) {
   8.109 -		res = FALSE;
   8.110 -		goto error;
   8.111 -	}
   8.112 -
   8.113 -	// Gets the remote encoder num
   8.114 -	livetv->remote_encoder = remote_request_next_free_recorder (-1);
   8.115 -
   8.116 -	if ( livetv->remote_encoder == NULL ) {
   8.117 -		g_warning ("[%s] None remote encoder available", __FUNCTION__);
   8.118 -		res = FALSE;
   8.119 -		goto error;
   8.120 -	}
   8.121 -
   8.122 -	// Creates livetv chain handler
   8.123 -	livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
   8.124 -	gmyth_tvchain_initialize ( livetv->tvchain, livetv->local_hostname );
   8.125 -
   8.126 -	if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
   8.127 -		res = FALSE;
   8.128 -		goto error;
   8.129 -	}
   8.130 -
   8.131 -	// Init remote encoder. Opens its control socket.
   8.132 -	res = gmyth_remote_encoder_setup(livetv->remote_encoder);
   8.133 -	if ( !res ) {
   8.134 -		g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
   8.135 -		res = FALSE;
   8.136 -		goto error;
   8.137 -	}
   8.138 -	// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
   8.139 -	res = gmyth_remote_encoder_spawntv ( livetv->remote_encoder,
   8.140 -			gmyth_tvchain_get_id(livetv->tvchain) );
   8.141 -	if (!res) {
   8.142 -		g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
   8.143 -		res = FALSE;
   8.144 -		goto error;
   8.145 -	}
   8.146 -
   8.147 -	// Reload all TV chain from Mysql database.
   8.148 -	gmyth_tvchain_reload_all (livetv->tvchain);
   8.149 -
   8.150 -	if ( livetv->tvchain == NULL ) {
   8.151 -		res = FALSE;
   8.152 -		goto error;
   8.153 -	}
   8.154 -
   8.155 -	// Get program info from database using chanid and starttime
   8.156 -	livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, -1);
   8.157 -	if ( livetv->proginfo == NULL ) {
   8.158 -		g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
   8.159 -		res = FALSE;
   8.160 -		goto error;
   8.161 -	} else {
   8.162 -		g_debug ("[%s] MythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
   8.163 -	}
   8.164 -
   8.165 -	return res;
   8.166 -
   8.167 -error:
   8.168 -	if ( livetv->backend_hostname != NULL ) {
   8.169 -		g_string_free( livetv->backend_hostname, TRUE );
   8.170 -		res = FALSE;
   8.171 -	}
   8.172 -
   8.173 -	if ( livetv->local_hostname != NULL ) {
   8.174 -		g_string_free( livetv->local_hostname, TRUE );
   8.175 -		res = FALSE;
   8.176 -	}
   8.177 -
   8.178 -	if ( livetv->remote_encoder != NULL ) {
   8.179 -		g_object_unref (livetv->remote_encoder);
   8.180 -		livetv->remote_encoder = NULL;
   8.181 -	}
   8.182 -
   8.183 -	if ( livetv->tvchain != NULL ) {
   8.184 -		g_object_unref (livetv->tvchain);
   8.185 -		livetv->tvchain = NULL;
   8.186 -	}
   8.187 -
   8.188 -	if ( livetv->proginfo != NULL ) {
   8.189 -		g_object_unref (livetv->proginfo);
   8.190 -		livetv->proginfo = NULL;
   8.191 -	}
   8.192 -
   8.193 -	return res;
   8.194 -
   8.195 -}
   8.196 -
   8.197 -// FIXME: How to proceed differently between livetv and recorded content
   8.198 -void
   8.199 -myth_livetv_stop_playing (MythLiveTV *livetv) 
   8.200 -{
   8.201 -	g_debug ("[%s] Stopping the LiveTV...\n", __FUNCTION__);
   8.202 -
   8.203 -	if (livetv->is_livetv) {
   8.204 -		if (!gmyth_remote_encoder_stop_livetv (livetv->remote_encoder)) {
   8.205 -			g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);	
   8.206 -		}
   8.207 -	}
   8.208 -}
   8.209 -
   8.210 -gboolean
   8.211 -myth_livetv_is_playing (MythLiveTV *livetv)
   8.212 -{
   8.213 -	return TRUE;
   8.214 -}
   8.215 -
   8.216 -void
   8.217 -myth_livetv_start_playing (MythLiveTV *livetv)
   8.218 -{
   8.219 -
   8.220 -	// TODO
   8.221 -
   8.222 -}
   8.223 -
     9.1 --- a/gst-plugins-mythtv/myth_livetv.h	Tue Sep 26 15:30:52 2006 +0100
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,59 +0,0 @@
     9.4 -#ifndef MYTH_LIVETV_H_
     9.5 -#define MYTH_LIVETV_H_
     9.6 -
     9.7 -#include <glib-object.h>
     9.8 -
     9.9 -#include <gmyth/gmyth_remote_encoder.h>
    9.10 -#include <gmyth/gmyth_tvchain.h>
    9.11 -#include <gmyth/gmyth_common.h>
    9.12 -
    9.13 -#include "myth_file_transfer.h"
    9.14 -
    9.15 -#define G_BEGIN_DECLS
    9.16 -
    9.17 -#define MYTH_LIVETV_TYPE               (myth_livetv_get_type ())
    9.18 -#define MYTH_LIVETV(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_LIVETV_TYPE, MythLiveTV))
    9.19 -#define MYTH_LIVETV_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_LIVETV_TYPE, MythLiveTVClass))
    9.20 -#define IS_MYTH_LIVETV(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_LIVETV_TYPE))
    9.21 -#define IS_MYTH_LIVETV_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_LIVETV_TYPE))
    9.22 -#define MYTH_LIVETV_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), MYTH_LIVETV_TYPE, MythLiveTVClass))
    9.23 -
    9.24 -typedef struct _MythLiveTV         MythLiveTV;
    9.25 -typedef struct _MythLiveTVClass    MythLiveTVClass;
    9.26 -
    9.27 -struct _MythLiveTVClass
    9.28 -{
    9.29 -  GObjectClass parent_class;
    9.30 -
    9.31 -  /* callbacks */
    9.32 -};
    9.33 -
    9.34 -struct _MythLiveTV
    9.35 -{
    9.36 -	GObject parent;
    9.37 -
    9.38 -	// Backend connection related variables
    9.39 -	GString *backend_hostname;
    9.40 -	gint backend_port;
    9.41 -	GString *local_hostname;
    9.42 -
    9.43 -	GMythRemoteEncoder *remote_encoder;
    9.44 -	GMythTVChain *tvchain;
    9.45 -	GMythProgramInfo *proginfo;
    9.46 -
    9.47 -	gboolean is_livetv;
    9.48 -
    9.49 -};
    9.50 -
    9.51 -GType          myth_livetv_get_type (void);
    9.52 -
    9.53 -MythLiveTV* myth_livetv_new ();
    9.54 -
    9.55 -void myth_livetv_start_playing (MythLiveTV *livetv);
    9.56 -void myth_livetv_stop_playing (MythLiveTV *livetv);
    9.57 -
    9.58 -gboolean myth_livetv_setup (MythLiveTV *livetv);
    9.59 -
    9.60 -#define G_END_DECLS
    9.61 -
    9.62 -#endif /*MYTH_LIVETV_H_*/
    10.1 --- a/gst-plugins-mythtv/myth_uri.c	Tue Sep 26 15:30:52 2006 +0100
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,208 +0,0 @@
    10.4 -/**
    10.5 - *
    10.6 - *    MythURI utils
    10.7 - *  - Extracts and parses a URI char string, in according with the RFC 2396
    10.8 - *    [http://www.ietf.org/rfc/rfc2396.txt]
    10.9 - *
   10.10 - *   @author Rosfran Borges (rosfran.borges@indt.org.br)
   10.11 - *
   10.12 - */
   10.13 -
   10.14 -#include "myth_uri.h"
   10.15 -#include <glib.h>
   10.16 -#include <string.h>
   10.17 -#include <stdlib.h>
   10.18 -
   10.19 -static gint 
   10.20 -myth_strstr( const gchar *haystack, const gchar *needle )
   10.21 -{
   10.22 -	
   10.23 -	gchar *strPos;
   10.24 -	
   10.25 -	if (haystack == NULL || needle == NULL)
   10.26 -		return -1;
   10.27 -	strPos = strstr(haystack, needle);
   10.28 -	if (strPos == NULL)
   10.29 -		return -1;
   10.30 -		
   10.31 -	return (strPos - haystack);
   10.32 -
   10.33 -}
   10.34 -
   10.35 -static gboolean
   10.36 -myth_uri_isabsolute( const MythURI *uri )
   10.37 -{
   10.38 -	gboolean ret = FALSE;
   10.39 -	
   10.40 -	g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE );
   10.41 -	
   10.42 -	if ( myth_strstr( uri->uri->str, MYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 )
   10.43 -		ret = TRUE;
   10.44 -		
   10.45 -	return ret;	
   10.46 -}
   10.47 -
   10.48 -static gint
   10.49 -myth_strrchr( const gchar *str, const gchar *chars, const gint nchars )
   10.50 -{
   10.51 -
   10.52 -	gint strLen;
   10.53 -	gint i, j;
   10.54 -	
   10.55 -	if ( str == NULL || chars == NULL )
   10.56 -		return -1;
   10.57 -		
   10.58 -	strLen = strlen( str );
   10.59 -	for ( i= (strLen-1); 0 <= i; i-- ) {
   10.60 -		for ( j=0; j<nchars; j++ ) {
   10.61 -			if ( str[i] == chars[j] )
   10.62 -				return i;
   10.63 -		}
   10.64 -	}
   10.65 -
   10.66 -	return -1;
   10.67 -
   10.68 -}
   10.69 -
   10.70 -static MythURI *
   10.71 -myth_uri_init( )
   10.72 -{
   10.73 -	MythURI *uri = g_new0( MythURI, 1 );
   10.74 -	uri->host = g_string_new("");
   10.75 -	uri->fragment = g_string_new("");
   10.76 -	uri->password = g_string_new("");
   10.77 -	uri->path = g_string_new("");
   10.78 -	uri->protocol = g_string_new("");
   10.79 -	uri->query = g_string_new("");
   10.80 -	uri->uri = g_string_new("");
   10.81 -	uri->user = g_string_new("");
   10.82 -	return uri;
   10.83 -}
   10.84 -
   10.85 -const MythURI *
   10.86 -myth_uri_new( gchar *value )
   10.87 -{
   10.88 -	
   10.89 -	MythURI *uri = myth_uri_init();
   10.90 -
   10.91 -	gchar *protocol;
   10.92 -	gint uriLen;
   10.93 -	gint currIdx;
   10.94 -	gint protoIdx;
   10.95 -	gint atIdx;
   10.96 -	gint colonIdx;
   10.97 -	gint shashIdx;
   10.98 -	gchar *host;
   10.99 -	gint eblacketIdx;
  10.100 -	GString *hostStr;
  10.101 -	GString *portStr;
  10.102 -	gint hostLen;
  10.103 -	gint sharpIdx;
  10.104 -	gint questionIdx;
  10.105 -	gint queryLen;
  10.106 -	
  10.107 -	uriLen = strlen(value);
  10.108 -	uri->uri = g_string_new( value );
  10.109 -		
  10.110 -	currIdx = 0;
  10.111 -	
  10.112 -	/*** Protocol ****/
  10.113 -	protoIdx = myth_strstr( value, MYTH_URI_PROTOCOL_DELIM );
  10.114 -	if (0 < protoIdx) {
  10.115 -		uri->protocol = g_string_append_len( uri->protocol, value, protoIdx );
  10.116 -		currIdx += protoIdx + strlen( MYTH_URI_PROTOCOL_DELIM );
  10.117 -	}
  10.118 -
  10.119 -	/*** User (Password) ****/
  10.120 -	atIdx = myth_strstr( value+currIdx, MYTH_URI_USER_DELIM );
  10.121 -	if ( 0 < atIdx ) {
  10.122 -		colonIdx = myth_strstr( value+currIdx, MYTH_URI_COLON_DELIM );
  10.123 -
  10.124 -		if (0 < colonIdx && colonIdx < atIdx) {
  10.125 -			uri->user = g_string_append_len( uri->user, value+currIdx,  colonIdx );
  10.126 -			uri->password = g_string_append_len( uri->password, value+currIdx+colonIdx+1, atIdx-(colonIdx+1) );
  10.127 -		}
  10.128 -		else 
  10.129 -			uri->user = g_string_append_len( uri->user, value+currIdx, atIdx - currIdx );
  10.130 -		currIdx += atIdx + 1;
  10.131 -	}
  10.132 -
  10.133 -	/*** Host (Port) ****/
  10.134 -	shashIdx = myth_strstr( value+currIdx, MYTH_URI_SLASH_DELIM );
  10.135 -	if ( 0 < shashIdx )
  10.136 -		uri->host = g_string_append_len( uri->host, value+currIdx, shashIdx );
  10.137 -	else if ( myth_uri_isabsolute(uri) == TRUE )
  10.138 -		uri->host = g_string_append_len( uri->host, value+currIdx, strlen(value) - currIdx );
  10.139 -	host = g_strdup( myth_uri_gethost(uri) );
  10.140 -	colonIdx = myth_strrchr( host, MYTH_URI_COLON_DELIM, 1 );
  10.141 -	eblacketIdx = myth_strrchr( host, MYTH_URI_EBLACET_DELIM, 1 );
  10.142 -	if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) {
  10.143 -		hostStr = g_string_new( host );
  10.144 -
  10.145 -		hostLen = hostStr->len;
  10.146 -		/**** host ****/
  10.147 -		uri->host = g_string_erase( uri->host, 0, hostLen );
  10.148 -		uri->host = g_string_insert_len( uri->host, 0, hostStr->str, colonIdx );
  10.149 -		//host = myth_uri_gethost( uri );
  10.150 -		if (0 < hostLen) {
  10.151 -			if (host[0] == '[' && host[hostLen-1] == ']')
  10.152 -				uri->host = g_string_append_len( uri->host, hostStr->str+1,  colonIdx-2 );
  10.153 -		}
  10.154 -		/**** port ****/
  10.155 -		portStr = g_string_new("");
  10.156 -		portStr = g_string_append_len( portStr, hostStr->str+colonIdx+1, hostLen-colonIdx-1 );
  10.157 -		uri->port = atoi( portStr->str );
  10.158 -		g_string_free( portStr, TRUE );
  10.159 -		g_string_free( hostStr, FALSE );
  10.160 -	}
  10.161 -	else {
  10.162 -		uri->port = MYTH_URI_KNKOWN_PORT;
  10.163 -		protocol = myth_uri_getprotocol(uri);
  10.164 -		if ( strcmp(protocol, MYTH_URI_PROTOCOL_HTTP) == 0 )
  10.165 -			uri->port = MYTH_URI_DEFAULT_HTTP_PORT;
  10.166 -		if ( strcmp(protocol, MYTH_URI_PROTOCOL_FTP) == 0 )
  10.167 -			uri->port = MYTH_URI_DEFAULT_FTP_PORT;
  10.168 -	}
  10.169 -	
  10.170 -	if (shashIdx > 0) currIdx += shashIdx;
  10.171 -	
  10.172 -	/*
  10.173 -		Handle relative URL
  10.174 -	*/
  10.175 -	if (myth_uri_isabsolute(uri) == FALSE)
  10.176 -	{
  10.177 -
  10.178 -		if (shashIdx != 0)
  10.179 -		{
  10.180 -			/* Add slash delimiter at the beginning of the URL,
  10.181 -			   if it doesn't exist 
  10.182 -			*/
  10.183 -			uri->path = g_string_new( MYTH_URI_SLASH_DELIM );
  10.184 -		}
  10.185 -		uri->path = g_string_append( uri->path, value );
  10.186 -		
  10.187 -	} else {
  10.188 -		/* First set path simply to the rest of URI */
  10.189 -		g_string_append_len( uri->path, value+currIdx,  uriLen-currIdx );
  10.190 -	}
  10.191 -		
  10.192 -	/**** Path (Query/Fragment) ****/
  10.193 -	sharpIdx = myth_strstr(value+currIdx, MYTH_URI_SHARP_DELIM);
  10.194 -	if (0 < sharpIdx) {
  10.195 -		uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx);
  10.196 -		uri->fragment = g_string_append_len( uri->fragment, 
  10.197 -			value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1));
  10.198 -	}
  10.199 -	
  10.200 -	questionIdx = myth_strstr( value+currIdx, MYTH_URI_QUESTION_DELIM );
  10.201 -	if ( 0 < questionIdx ) {
  10.202 -		uri->path = g_string_append_len( uri->path, value+currIdx, questionIdx );
  10.203 -		queryLen = uriLen-(currIdx+questionIdx+1);
  10.204 -		if ( 0 < sharpIdx )
  10.205 -			queryLen -= uriLen - (currIdx+sharpIdx+1);
  10.206 -		uri->query = g_string_append_len( uri->query, value+currIdx+questionIdx+1, queryLen );
  10.207 -	}
  10.208 -	
  10.209 -	return uri;
  10.210 -
  10.211 -}
    11.1 --- a/gst-plugins-mythtv/myth_uri.h	Tue Sep 26 15:30:52 2006 +0100
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,63 +0,0 @@
    11.4 -/**
    11.5 - *
    11.6 - *	MythURI utils
    11.7 - *  - Extracts and parses a URI char string, in according with the RFC 2396 
    11.8 - *    [http://www.ietf.org/rfc/rfc2396.txt]
    11.9 - *
   11.10 - * @author Rosfran Borges (rosfran.borges@indt.org.br)
   11.11 - * 
   11.12 - */
   11.13 -
   11.14 -#ifndef _MYTH_URI_H_
   11.15 -#define _MYTH_URI_H_
   11.16 -
   11.17 -#include <glib.h>
   11.18 -
   11.19 -/****************************************
   11.20 -* Define
   11.21 -****************************************/
   11.22 -
   11.23 -#define MYTH_URI_KNKOWN_PORT (-1)
   11.24 -#define MYTH_URI_DEFAULT_HTTP_PORT 80
   11.25 -#define MYTH_URI_DEFAULT_FTP_PORT 21
   11.26 -#define MYTH_URI_DEFAULT_PATH "/"
   11.27 -#define MYTH_URI_MAXLEN 256
   11.28 -
   11.29 -#define MYTH_URI_PROTOCOL_DELIM "://"
   11.30 -#define MYTH_URI_USER_DELIM "@"
   11.31 -#define MYTH_URI_COLON_DELIM ":"
   11.32 -#define MYTH_URI_SLASH_DELIM "/"
   11.33 -#define MYTH_URI_SBLACET_DELIM "["
   11.34 -#define MYTH_URI_EBLACET_DELIM "]"
   11.35 -#define MYTH_URI_SHARP_DELIM "#"
   11.36 -#define MYTH_URI_QUESTION_DELIM "?"
   11.37 -#define MYTH_URI_ESCAPING_CHAR "%"
   11.38 -
   11.39 -#define MYTH_URI_PROTOCOL_MYTH "myth"
   11.40 -#define MYTH_URI_PROTOCOL_HTTP "http"
   11.41 -#define MYTH_URI_PROTOCOL_FTP "ftp"
   11.42 -
   11.43 -/****************************************
   11.44 -* Data Type
   11.45 -****************************************/
   11.46 -
   11.47 -typedef struct _MythURI {
   11.48 -	GString *uri;
   11.49 -	GString *host;
   11.50 -	gint port;
   11.51 -	GString *protocol;
   11.52 -	GString *path;
   11.53 -	GString *fragment;
   11.54 -	GString *user;
   11.55 -	GString *password;
   11.56 -	GString *query;
   11.57 -} MythURI;
   11.58 -
   11.59 -const MythURI *myth_uri_new( gchar *value );
   11.60 -
   11.61 -#define myth_uri_gethost(urip) (urip->host->str)
   11.62 -#define myth_uri_getport(urip) (urip->port)
   11.63 -#define myth_uri_getprotocol(urip) (urip->protocol->str)
   11.64 -#define myth_uri_getpath(urip) (urip->path->str)
   11.65 -
   11.66 -#endif
    12.1 --- a/gst-plugins-mythtv/mythtvsrc-test.c	Tue Sep 26 15:30:52 2006 +0100
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,85 +0,0 @@
    12.4 -#include <gst/gst.h>
    12.5 -
    12.6 -static gboolean
    12.7 -bus_call (GstBus     *bus,
    12.8 -	  GstMessage *msg,
    12.9 -	  gpointer    data)
   12.10 -{
   12.11 -  GMainLoop *loop = data;
   12.12 -
   12.13 -  switch (GST_MESSAGE_TYPE (msg)) {
   12.14 -    case GST_MESSAGE_EOS:
   12.15 -      g_print ("End-of-stream\n");
   12.16 -      g_main_loop_quit (loop);
   12.17 -      break;
   12.18 -    case GST_MESSAGE_ERROR: {
   12.19 -      gchar *debug;
   12.20 -      GError *err;
   12.21 -
   12.22 -      gst_message_parse_error (msg, &err, &debug);
   12.23 -      g_free (debug);
   12.24 -
   12.25 -      g_print ("Error: %s\n", err->message);
   12.26 -      g_error_free (err);
   12.27 -
   12.28 -      g_main_loop_quit (loop);
   12.29 -      break;
   12.30 -    }
   12.31 -    default:
   12.32 -      break;
   12.33 -  }
   12.34 -
   12.35 -  return TRUE;
   12.36 -}
   12.37 -
   12.38 -gint
   12.39 -main (gint   argc,
   12.40 -      gchar *argv[])
   12.41 -{
   12.42 -  GstElement *pipeline, *filesrc, *decoder, *filter, *sink;
   12.43 -  GMainLoop *loop;
   12.44 -
   12.45 -  /* initialization */
   12.46 -  gst_init (&argc, &argv);
   12.47 -  loop = g_main_loop_new (NULL, FALSE);
   12.48 -  if (argc != 2) {
   12.49 -    g_print ("Usage: %s <myth uri>\n", argv[0]);
   12.50 -    return 01;
   12.51 -  }
   12.52 -
   12.53 -  /* create elements */
   12.54 -  pipeline = gst_pipeline_new ("mythtvsrc_pipeline");
   12.55 -  gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
   12.56 -		     bus_call, loop);
   12.57 -
   12.58 -  filesrc  = gst_element_factory_make ("mythtvsrc", "mythtvsrc");
   12.59 -  decoder  = gst_element_factory_make ("mad", "my_decoder");
   12.60 -  filter   = gst_element_factory_make ("my_filter", "my_filter");
   12.61 -  sink     = gst_element_factory_make ("osssink", "audiosink");
   12.62 -  if (!sink || !decoder) {
   12.63 -    g_print ("Decoder or output could not be found - check your install\n");
   12.64 -    return -1;
   12.65 -  } else if (!filter) {
   12.66 -    g_print ("Your self-written filter could not be found. Make sure it "
   12.67 -             "is installed correctly in $(libdir)/gstreamer-0.9/ and that "
   12.68 -             "you've ran gst-register-0.9 to register it. Check availability "
   12.69 -             "of the plugin afterwards using \"gst-inspect-0.9 my_filter\"");
   12.70 -    return -1;
   12.71 -  }
   12.72 -
   12.73 -  g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
   12.74 -
   12.75 -  /* link everything together */
   12.76 -  gst_element_link_many (filesrc, decoder, filter, sink, NULL);
   12.77 -  gst_bin_add_many (GST_BIN (pipeline), filesrc, decoder, filter, sink, NULL);
   12.78 -
   12.79 -  /* run */
   12.80 -  gst_element_set_state (pipeline, GST_STATE_PLAYING);
   12.81 -  g_main_loop_run (loop);
   12.82 -
   12.83 -  /* clean up */
   12.84 -  gst_element_set_state (pipeline, GST_STATE_NULL);
   12.85 -  gst_object_unref (GST_OBJECT (pipeline));
   12.86 -
   12.87 -  return 0;
   12.88 -}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/gst-plugins-mythtv/src/Makefile.am	Tue Sep 26 15:58:37 2006 +0100
    13.3 @@ -0,0 +1,27 @@
    13.4 +plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
    13.5 +
    13.6 +plugin_LTLIBRARIES =	libgstmythtvsrc.la
    13.7 +
    13.8 +libgstmythtvsrc_la_SOURCES =	\
    13.9 +		gstmythtvsrc.c \
   13.10 +		myth_uri.c \
   13.11 +		myth_file_transfer.c \
   13.12 +		myth_livetv.c
   13.13 +
   13.14 +libgstmythtvsrc_la_CFLAGS = \
   13.15 +	$(GST_CFLAGS) \
   13.16 +	$(GMYTH_CFLAGS)
   13.17 +
   13.18 +libgstmythtvsrc_la_LDFLAGS = \
   13.19 +	$(GST_PLUGIN_LDFLAGS)
   13.20 +
   13.21 +libgstmythtvsrc_la_LIBADD = \
   13.22 +	$(GST_BASE_LIBS) \
   13.23 +	$(GMYTH_LIBS)
   13.24 +
   13.25 +noinst_HEADERS = \
   13.26 +	gstmythtvsrc.h \
   13.27 +	myth_uri.h \
   13.28 +	myth_file_transfer.h \
   13.29 +	myth_livetv.h
   13.30 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/gst-plugins-mythtv/src/Makefile.in	Tue Sep 26 15:58:37 2006 +0100
    14.3 @@ -0,0 +1,543 @@
    14.4 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
    14.5 +# @configure_input@
    14.6 +
    14.7 +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
    14.8 +# 2003, 2004, 2005  Free Software Foundation, Inc.
    14.9 +# This Makefile.in is free software; the Free Software Foundation
   14.10 +# gives unlimited permission to copy and/or distribute it,
   14.11 +# with or without modifications, as long as this notice is preserved.
   14.12 +
   14.13 +# This program is distributed in the hope that it will be useful,
   14.14 +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
   14.15 +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
   14.16 +# PARTICULAR PURPOSE.
   14.17 +
   14.18 +@SET_MAKE@
   14.19 +
   14.20 +
   14.21 +srcdir = @srcdir@
   14.22 +top_srcdir = @top_srcdir@
   14.23 +VPATH = @srcdir@
   14.24 +pkgdatadir = $(datadir)/@PACKAGE@
   14.25 +pkglibdir = $(libdir)/@PACKAGE@
   14.26 +pkgincludedir = $(includedir)/@PACKAGE@
   14.27 +top_builddir = ..
   14.28 +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
   14.29 +INSTALL = @INSTALL@
   14.30 +install_sh_DATA = $(install_sh) -c -m 644
   14.31 +install_sh_PROGRAM = $(install_sh) -c
   14.32 +install_sh_SCRIPT = $(install_sh) -c
   14.33 +INSTALL_HEADER = $(INSTALL_DATA)
   14.34 +transform = $(program_transform_name)
   14.35 +NORMAL_INSTALL = :
   14.36 +PRE_INSTALL = :
   14.37 +POST_INSTALL = :
   14.38 +NORMAL_UNINSTALL = :
   14.39 +PRE_UNINSTALL = :
   14.40 +POST_UNINSTALL = :
   14.41 +build_triplet = @build@
   14.42 +host_triplet = @host@
   14.43 +subdir = src
   14.44 +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
   14.45 +	$(srcdir)/Makefile.in
   14.46 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
   14.47 +am__aclocal_m4_deps = $(top_srcdir)/m4/as-version.m4 \
   14.48 +	$(top_srcdir)/configure.ac
   14.49 +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
   14.50 +	$(ACLOCAL_M4)
   14.51 +mkinstalldirs = $(install_sh) -d
   14.52 +CONFIG_HEADER = $(top_builddir)/config.h
   14.53 +CONFIG_CLEAN_FILES =
   14.54 +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
   14.55 +am__vpath_adj = case $$p in \
   14.56 +    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
   14.57 +    *) f=$$p;; \
   14.58 +  esac;
   14.59 +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
   14.60 +am__installdirs = "$(DESTDIR)$(plugindir)"
   14.61 +pluginLTLIBRARIES_INSTALL = $(INSTALL)
   14.62 +LTLIBRARIES = $(plugin_LTLIBRARIES)
   14.63 +am__DEPENDENCIES_1 =
   14.64 +libgstmythtvsrc_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
   14.65 +am_libgstmythtvsrc_la_OBJECTS = libgstmythtvsrc_la-gstmythtvsrc.lo \
   14.66 +	libgstmythtvsrc_la-myth_uri.lo \
   14.67 +	libgstmythtvsrc_la-myth_file_transfer.lo \
   14.68 +	libgstmythtvsrc_la-myth_livetv.lo
   14.69 +libgstmythtvsrc_la_OBJECTS = $(am_libgstmythtvsrc_la_OBJECTS)
   14.70 +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
   14.71 +depcomp = $(SHELL) $(top_srcdir)/depcomp
   14.72 +am__depfiles_maybe = depfiles
   14.73 +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
   14.74 +	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
   14.75 +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
   14.76 +	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
   14.77 +	$(AM_CFLAGS) $(CFLAGS)
   14.78 +CCLD = $(CC)
   14.79 +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
   14.80 +	$(AM_LDFLAGS) $(LDFLAGS) -o $@
   14.81 +SOURCES = $(libgstmythtvsrc_la_SOURCES)
   14.82 +DIST_SOURCES = $(libgstmythtvsrc_la_SOURCES)
   14.83 +HEADERS = $(noinst_HEADERS)
   14.84 +ETAGS = etags
   14.85 +CTAGS = ctags
   14.86 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
   14.87 +ACLOCAL = @ACLOCAL@
   14.88 +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
   14.89 +AMDEP_FALSE = @AMDEP_FALSE@
   14.90 +AMDEP_TRUE = @AMDEP_TRUE@
   14.91 +AMTAR = @AMTAR@
   14.92 +AR = @AR@
   14.93 +AUTOCONF = @AUTOCONF@
   14.94 +AUTOHEADER = @AUTOHEADER@
   14.95 +AUTOMAKE = @AUTOMAKE@
   14.96 +AWK = @AWK@
   14.97 +CC = @CC@
   14.98 +CCDEPMODE = @CCDEPMODE@
   14.99 +CFLAGS = @CFLAGS@
  14.100 +CPP = @CPP@
  14.101 +CPPFLAGS = @CPPFLAGS@
  14.102 +CXX = @CXX@
  14.103 +CXXCPP = @CXXCPP@
  14.104 +CXXDEPMODE = @CXXDEPMODE@
  14.105 +CXXFLAGS = @CXXFLAGS@
  14.106 +CYGPATH_W = @CYGPATH_W@
  14.107 +DEFS = @DEFS@
  14.108 +DEPDIR = @DEPDIR@
  14.109 +ECHO = @ECHO@
  14.110 +ECHO_C = @ECHO_C@
  14.111 +ECHO_N = @ECHO_N@
  14.112 +ECHO_T = @ECHO_T@
  14.113 +EGREP = @EGREP@
  14.114 +EXEEXT = @EXEEXT@
  14.115 +F77 = @F77@
  14.116 +FFLAGS = @FFLAGS@
  14.117 +GLIB_CFLAGS = @GLIB_CFLAGS@
  14.118 +GLIB_LIBS = @GLIB_LIBS@
  14.119 +GMYTH_CFLAGS = @GMYTH_CFLAGS@
  14.120 +GMYTH_LIBS = @GMYTH_LIBS@
  14.121 +GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
  14.122 +GOBJECT_LIBS = @GOBJECT_LIBS@
  14.123 +GSTBASE_CFLAGS = @GSTBASE_CFLAGS@
  14.124 +GSTBASE_LIBS = @GSTBASE_LIBS@
  14.125 +GST_CFLAGS = @GST_CFLAGS@
  14.126 +GST_LIBS = @GST_LIBS@
  14.127 +GST_MAJORMINOR = @GST_MAJORMINOR@
  14.128 +GST_PLUGINS_DIR = @GST_PLUGINS_DIR@
  14.129 +GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
  14.130 +HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
  14.131 +HILDON_CFLAGS = @HILDON_CFLAGS@
  14.132 +HILDON_LIBS = @HILDON_LIBS@
  14.133 +INSTALL_DATA = @INSTALL_DATA@
  14.134 +INSTALL_PROGRAM = @INSTALL_PROGRAM@
  14.135 +INSTALL_SCRIPT = @INSTALL_SCRIPT@
  14.136 +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
  14.137 +LDFLAGS = @LDFLAGS@
  14.138 +LIBOBJS = @LIBOBJS@
  14.139 +LIBS = @LIBS@
  14.140 +LIBTOOL = @LIBTOOL@
  14.141 +LN_S = @LN_S@
  14.142 +LTLIBOBJS = @LTLIBOBJS@
  14.143 +MAEMO_PLATFORM_FALSE = @MAEMO_PLATFORM_FALSE@
  14.144 +MAEMO_PLATFORM_TRUE = @MAEMO_PLATFORM_TRUE@
  14.145 +MAINT = @MAINT@
  14.146 +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
  14.147 +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
  14.148 +MAKEINFO = @MAKEINFO@
  14.149 +MYTHTVSRC_MAJORMINOR = @MYTHTVSRC_MAJORMINOR@
  14.150 +MYTHTVSRC_MAJOR_VERSION = @MYTHTVSRC_MAJOR_VERSION@
  14.151 +MYTHTVSRC_MICRO_VERSION = @MYTHTVSRC_MICRO_VERSION@
  14.152 +MYTHTVSRC_MINOR_VERSION = @MYTHTVSRC_MINOR_VERSION@
  14.153 +MYTHTVSRC_NANO_VERSION = @MYTHTVSRC_NANO_VERSION@
  14.154 +MYTHTVSRC_RELEASE = @MYTHTVSRC_RELEASE@
  14.155 +MYTHTVSRC_VERSION = @MYTHTVSRC_VERSION@
  14.156 +NDEBUG_FALSE = @NDEBUG_FALSE@
  14.157 +NDEBUG_TRUE = @NDEBUG_TRUE@
  14.158 +OBJEXT = @OBJEXT@
  14.159 +PACKAGE = @PACKAGE@
  14.160 +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
  14.161 +PACKAGE_NAME = @PACKAGE_NAME@
  14.162 +PACKAGE_STRING = @PACKAGE_STRING@
  14.163 +PACKAGE_TARNAME = @PACKAGE_TARNAME@
  14.164 +PACKAGE_VERSION = @PACKAGE_VERSION@
  14.165 +PATH_SEPARATOR = @PATH_SEPARATOR@
  14.166 +PKG_CONFIG = @PKG_CONFIG@
  14.167 +RANLIB = @RANLIB@
  14.168 +SET_MAKE = @SET_MAKE@
  14.169 +SHELL = @SHELL@
  14.170 +STRIP = @STRIP@
  14.171 +VERSION = @VERSION@
  14.172 +ac_ct_AR = @ac_ct_AR@
  14.173 +ac_ct_CC = @ac_ct_CC@
  14.174 +ac_ct_CXX = @ac_ct_CXX@
  14.175 +ac_ct_F77 = @ac_ct_F77@
  14.176 +ac_ct_RANLIB = @ac_ct_RANLIB@
  14.177 +ac_ct_STRIP = @ac_ct_STRIP@
  14.178 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
  14.179 +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
  14.180 +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
  14.181 +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
  14.182 +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
  14.183 +am__include = @am__include@
  14.184 +am__leading_dot = @am__leading_dot@
  14.185 +am__quote = @am__quote@
  14.186 +am__tar = @am__tar@
  14.187 +am__untar = @am__untar@
  14.188 +bindir = @bindir@
  14.189 +build = @build@
  14.190 +build_alias = @build_alias@
  14.191 +build_cpu = @build_cpu@
  14.192 +build_os = @build_os@
  14.193 +build_vendor = @build_vendor@
  14.194 +datadir = @datadir@
  14.195 +exec_prefix = @exec_prefix@
  14.196 +host = @host@
  14.197 +host_alias = @host_alias@
  14.198 +host_cpu = @host_cpu@
  14.199 +host_os = @host_os@
  14.200 +host_vendor = @host_vendor@
  14.201 +includedir = @includedir@
  14.202 +infodir = @infodir@
  14.203 +install_sh = @install_sh@
  14.204 +libdir = @libdir@
  14.205 +libexecdir = @libexecdir@
  14.206 +localstatedir = @localstatedir@
  14.207 +mandir = @mandir@
  14.208 +mkdir_p = @mkdir_p@
  14.209 +oldincludedir = @oldincludedir@
  14.210 +prefix = @prefix@
  14.211 +program_transform_name = @program_transform_name@
  14.212 +sbindir = @sbindir@
  14.213 +sharedstatedir = @sharedstatedir@
  14.214 +sysconfdir = @sysconfdir@
  14.215 +target_alias = @target_alias@
  14.216 +plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
  14.217 +plugin_LTLIBRARIES = libgstmythtvsrc.la
  14.218 +libgstmythtvsrc_la_SOURCES = \
  14.219 +		gstmythtvsrc.c \
  14.220 +		myth_uri.c \
  14.221 +		myth_file_transfer.c \
  14.222 +		myth_livetv.c
  14.223 +
  14.224 +libgstmythtvsrc_la_CFLAGS = \
  14.225 +	$(GST_CFLAGS) \
  14.226 +	$(GMYTH_CFLAGS)
  14.227 +
  14.228 +libgstmythtvsrc_la_LDFLAGS = \
  14.229 +	$(GST_PLUGIN_LDFLAGS)
  14.230 +
  14.231 +libgstmythtvsrc_la_LIBADD = \
  14.232 +	$(GST_BASE_LIBS) \
  14.233 +	$(GMYTH_LIBS)
  14.234 +
  14.235 +noinst_HEADERS = \
  14.236 +	gstmythtvsrc.h \
  14.237 +	myth_uri.h \
  14.238 +	myth_file_transfer.h \
  14.239 +	myth_livetv.h
  14.240 +
  14.241 +all: all-am
  14.242 +
  14.243 +.SUFFIXES:
  14.244 +.SUFFIXES: .c .lo .o .obj
  14.245 +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
  14.246 +	@for dep in $?; do \
  14.247 +	  case '$(am__configure_deps)' in \
  14.248 +	    *$$dep*) \
  14.249 +	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
  14.250 +		&& exit 0; \
  14.251 +	      exit 1;; \
  14.252 +	  esac; \
  14.253 +	done; \
  14.254 +	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  src/Makefile'; \
  14.255 +	cd $(top_srcdir) && \
  14.256 +	  $(AUTOMAKE) --gnu  src/Makefile
  14.257 +.PRECIOUS: Makefile
  14.258 +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
  14.259 +	@case '$?' in \
  14.260 +	  *config.status*) \
  14.261 +	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
  14.262 +	  *) \
  14.263 +	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
  14.264 +	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
  14.265 +	esac;
  14.266 +
  14.267 +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
  14.268 +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
  14.269 +
  14.270 +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
  14.271 +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
  14.272 +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
  14.273 +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
  14.274 +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
  14.275 +	@$(NORMAL_INSTALL)
  14.276 +	test -z "$(plugindir)" || $(mkdir_p) "$(DESTDIR)$(plugindir)"
  14.277 +	@list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
  14.278 +	  if test -f $$p; then \
  14.279 +	    f=$(am__strip_dir) \
  14.280 +	    echo " $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
  14.281 +	    $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
  14.282 +	  else :; fi; \
  14.283 +	done
  14.284 +
  14.285 +uninstall-pluginLTLIBRARIES:
  14.286 +	@$(NORMAL_UNINSTALL)
  14.287 +	@set -x; list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
  14.288 +	  p=$(am__strip_dir) \
  14.289 +	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
  14.290 +	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
  14.291 +	done
  14.292 +
  14.293 +clean-pluginLTLIBRARIES:
  14.294 +	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
  14.295 +	@list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
  14.296 +	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
  14.297 +	  test "$$dir" != "$$p" || dir=.; \
  14.298 +	  echo "rm -f \"$${dir}/so_locations\""; \
  14.299 +	  rm -f "$${dir}/so_locations"; \
  14.300 +	done
  14.301 +libgstmythtvsrc.la: $(libgstmythtvsrc_la_OBJECTS) $(libgstmythtvsrc_la_DEPENDENCIES) 
  14.302 +	$(LINK) -rpath $(plugindir) $(libgstmythtvsrc_la_LDFLAGS) $(libgstmythtvsrc_la_OBJECTS) $(libgstmythtvsrc_la_LIBADD) $(LIBS)
  14.303 +
  14.304 +mostlyclean-compile:
  14.305 +	-rm -f *.$(OBJEXT)
  14.306 +
  14.307 +distclean-compile:
  14.308 +	-rm -f *.tab.c
  14.309 +
  14.310 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-gstmythtvsrc.Plo@am__quote@
  14.311 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-myth_file_transfer.Plo@am__quote@
  14.312 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-myth_livetv.Plo@am__quote@
  14.313 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstmythtvsrc_la-myth_uri.Plo@am__quote@
  14.314 +
  14.315 +.c.o:
  14.316 +@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
  14.317 +@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
  14.318 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
  14.319 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
  14.320 +@am__fastdepCC_FALSE@	$(COMPILE) -c $<
  14.321 +
  14.322 +.c.obj:
  14.323 +@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
  14.324 +@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
  14.325 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
  14.326 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
  14.327 +@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
  14.328 +
  14.329 +.c.lo:
  14.330 +@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
  14.331 +@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
  14.332 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
  14.333 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
  14.334 +@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
  14.335 +
  14.336 +libgstmythtvsrc_la-gstmythtvsrc.lo: gstmythtvsrc.c
  14.337 +@am__fastdepCC_TRUE@	if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstmythtvsrc_la_CFLAGS) $(CFLAGS) -MT libgstmythtvsrc_la-gstmythtvsrc.lo -MD -MP -MF "$(DEPDIR)/libgstmythtvsrc_la-gstmythtvsrc.Tpo" -c -o libgstmythtvsrc_la-gstmythtvsrc.lo `test -f 'gstmythtvsrc.c' || echo '$(srcdir)/'`gstmythtvsrc.c; \
  14.338 +@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgstmythtvsrc_la-gstmythtvsrc.Tpo" "$(DEPDIR)/libgstmythtvsrc_la-gstmythtvsrc.Plo"; else rm -f "$(DEPDIR)/libgstmythtvsrc_la-gstmythtvsrc.Tpo"; exit 1; fi
  14.339 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gstmythtvsrc.c' object='libgstmythtvsrc_la-gstmythtvsrc.lo' libtool=yes @AMDEPBACKSLASH@
  14.340 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
  14.341 +@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
  14.342 +
  14.343 +libgstmythtvsrc_la-myth_uri.lo: myth_uri.c
  14.344 +@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; \
  14.345 +@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
  14.346 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='myth_uri.c' object='libgstmythtvsrc_la-myth_uri.lo' libtool=yes @AMDEPBACKSLASH@
  14.347 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
  14.348 +@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
  14.349 +
  14.350 +libgstmythtvsrc_la-myth_file_transfer.lo: myth_file_transfer.c
  14.351 +@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; \
  14.352 +@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
  14.353 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='myth_file_transfer.c' object='libgstmythtvsrc_la-myth_file_transfer.lo' libtool=yes @AMDEPBACKSLASH@
  14.354 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
  14.355 +@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
  14.356 +
  14.357 +libgstmythtvsrc_la-myth_livetv.lo: myth_livetv.c
  14.358 +@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; \
  14.359 +@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
  14.360 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='myth_livetv.c' object='libgstmythtvsrc_la-myth_livetv.lo' libtool=yes @AMDEPBACKSLASH@
  14.361 +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
  14.362 +@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
  14.363 +
  14.364 +mostlyclean-libtool:
  14.365 +	-rm -f *.lo
  14.366 +
  14.367 +clean-libtool:
  14.368 +	-rm -rf .libs _libs
  14.369 +
  14.370 +distclean-libtool:
  14.371 +	-rm -f libtool
  14.372 +uninstall-info-am:
  14.373 +
  14.374 +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
  14.375 +	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
  14.376 +	unique=`for i in $$list; do \
  14.377 +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  14.378 +	  done | \
  14.379 +	  $(AWK) '    { files[$$0] = 1; } \
  14.380 +	       END { for (i in files) print i; }'`; \
  14.381 +	mkid -fID $$unique
  14.382 +tags: TAGS
  14.383 +
  14.384 +TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
  14.385 +		$(TAGS_FILES) $(LISP)
  14.386 +	tags=; \
  14.387 +	here=`pwd`; \
  14.388 +	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
  14.389 +	unique=`for i in $$list; do \
  14.390 +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  14.391 +	  done | \
  14.392 +	  $(AWK) '    { files[$$0] = 1; } \
  14.393 +	       END { for (i in files) print i; }'`; \
  14.394 +	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
  14.395 +	  test -n "$$unique" || unique=$$empty_fix; \
  14.396 +	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
  14.397 +	    $$tags $$unique; \
  14.398 +	fi
  14.399 +ctags: CTAGS
  14.400 +CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
  14.401 +		$(TAGS_FILES) $(LISP)
  14.402 +	tags=; \
  14.403 +	here=`pwd`; \
  14.404 +	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
  14.405 +	unique=`for i in $$list; do \
  14.406 +	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  14.407 +	  done | \
  14.408 +	  $(AWK) '    { files[$$0] = 1; } \
  14.409 +	       END { for (i in files) print i; }'`; \
  14.410 +	test -z "$(CTAGS_ARGS)$$tags$$unique" \
  14.411 +	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
  14.412 +	     $$tags $$unique
  14.413 +
  14.414 +GTAGS:
  14.415 +	here=`$(am__cd) $(top_builddir) && pwd` \
  14.416 +	  && cd $(top_srcdir) \
  14.417 +	  && gtags -i $(GTAGS_ARGS) $$here
  14.418 +
  14.419 +distclean-tags:
  14.420 +	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
  14.421 +
  14.422 +distdir: $(DISTFILES)
  14.423 +	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
  14.424 +	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
  14.425 +	list='$(DISTFILES)'; for file in $$list; do \
  14.426 +	  case $$file in \
  14.427 +	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
  14.428 +	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
  14.429 +	  esac; \
  14.430 +	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
  14.431 +	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
  14.432 +	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
  14.433 +	    dir="/$$dir"; \
  14.434 +	    $(mkdir_p) "$(distdir)$$dir"; \
  14.435 +	  else \
  14.436 +	    dir=''; \
  14.437 +	  fi; \
  14.438 +	  if test -d $$d/$$file; then \
  14.439 +	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
  14.440 +	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
  14.441 +	    fi; \
  14.442 +	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
  14.443 +	  else \
  14.444 +	    test -f $(distdir)/$$file \
  14.445 +	    || cp -p $$d/$$file $(distdir)/$$file \
  14.446 +	    || exit 1; \
  14.447 +	  fi; \
  14.448 +	done
  14.449 +check-am: all-am
  14.450 +check: check-am
  14.451 +all-am: Makefile $(LTLIBRARIES) $(HEADERS)
  14.452 +installdirs:
  14.453 +	for dir in "$(DESTDIR)$(plugindir)"; do \
  14.454 +	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
  14.455 +	done
  14.456 +install: install-am
  14.457 +install-exec: install-exec-am
  14.458 +install-data: install-data-am
  14.459 +uninstall: uninstall-am
  14.460 +
  14.461 +install-am: all-am
  14.462 +	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
  14.463 +
  14.464 +installcheck: installcheck-am
  14.465 +install-strip:
  14.466 +	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
  14.467 +	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
  14.468 +	  `test -z '$(STRIP)' || \
  14.469 +	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
  14.470 +mostlyclean-generic:
  14.471 +
  14.472 +clean-generic:
  14.473 +
  14.474 +distclean-generic:
  14.475 +	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
  14.476 +
  14.477 +maintainer-clean-generic:
  14.478 +	@echo "This command is intended for maintainers to use"
  14.479 +	@echo "it deletes files that may require special tools to rebuild."
  14.480 +clean: clean-am
  14.481 +
  14.482 +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
  14.483 +	mostlyclean-am
  14.484 +
  14.485 +distclean: distclean-am
  14.486 +	-rm -rf ./$(DEPDIR)
  14.487 +	-rm -f Makefile
  14.488 +distclean-am: clean-am distclean-compile distclean-generic \
  14.489 +	distclean-libtool distclean-tags
  14.490 +
  14.491 +dvi: dvi-am
  14.492 +
  14.493 +dvi-am:
  14.494 +
  14.495 +html: html-am
  14.496 +
  14.497 +info: info-am
  14.498 +
  14.499 +info-am:
  14.500 +
  14.501 +install-data-am: install-pluginLTLIBRARIES
  14.502 +
  14.503 +install-exec-am:
  14.504 +
  14.505 +install-info: install-info-am
  14.506 +
  14.507 +install-man:
  14.508 +
  14.509 +installcheck-am:
  14.510 +
  14.511 +maintainer-clean: maintainer-clean-am
  14.512 +	-rm -rf ./$(DEPDIR)
  14.513 +	-rm -f Makefile
  14.514 +maintainer-clean-am: distclean-am maintainer-clean-generic
  14.515 +
  14.516 +mostlyclean: mostlyclean-am
  14.517 +
  14.518 +mostlyclean-am: mostlyclean-compile mostlyclean-generic \
  14.519 +	mostlyclean-libtool
  14.520 +
  14.521 +pdf: pdf-am
  14.522 +
  14.523 +pdf-am:
  14.524 +
  14.525 +ps: ps-am
  14.526 +
  14.527 +ps-am:
  14.528 +
  14.529 +uninstall-am: uninstall-info-am uninstall-pluginLTLIBRARIES
  14.530 +
  14.531 +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
  14.532 +	clean-libtool clean-pluginLTLIBRARIES ctags distclean \
  14.533 +	distclean-compile distclean-generic distclean-libtool \
  14.534 +	distclean-tags distdir dvi dvi-am html html-am info info-am \
  14.535 +	install install-am install-data install-data-am install-exec \
  14.536 +	install-exec-am install-info install-info-am install-man \
  14.537 +	install-pluginLTLIBRARIES install-strip installcheck \
  14.538 +	installcheck-am installdirs maintainer-clean \
  14.539 +	maintainer-clean-generic mostlyclean mostlyclean-compile \
  14.540 +	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
  14.541 +	tags uninstall uninstall-am uninstall-info-am \
  14.542 +	uninstall-pluginLTLIBRARIES
  14.543 +
  14.544 +# Tell versions [3.59,3.63) of GNU make to not export all variables.
  14.545 +# Otherwise a system limit (for SysV at least) may be exceeded.
  14.546 +.NOEXPORT:
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c	Tue Sep 26 15:58:37 2006 +0100
    15.3 @@ -0,0 +1,901 @@
    15.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2 -*- */
    15.5 +/* GStreamer MythTV Plug-in
    15.6 + * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
    15.7 + *
    15.8 + * This library is free software; you can redistribute it and/or
    15.9 + * modify it under the terms of the GNU Library General Public
   15.10 + * License as published by the Free Software Foundation; either
   15.11 + * version 2 of the License, or (at your option) any later version.
   15.12 + *
   15.13 + * This library is distributed in the hope that it will be useful,
   15.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15.16 + * Library General Public License for more 
   15.17 + */
   15.18 +
   15.19 +#ifdef HAVE_CONFIG_H
   15.20 +#include "config.h"
   15.21 +#endif
   15.22 +
   15.23 +#include "gstmythtvsrc.h"
   15.24 +#include "myth_file_transfer.h"
   15.25 +#include "myth_livetv.h"
   15.26 +
   15.27 +#include <gmyth/gmyth_socket.h>
   15.28 +#include <gmyth/gmyth_tvchain.h>
   15.29 +
   15.30 +#include <string.h>
   15.31 +#include <unistd.h>
   15.32 +
   15.33 +GST_DEBUG_CATEGORY_STATIC (mythtvsrc_debug);
   15.34 +#define GST_CAT_DEFAULT mythtvsrc_debug
   15.35 +
   15.36 +#define GST_MYTHTV_ID_NUM		1
   15.37 +
   15.38 +#define MYTHTV_VERSION_DEFAULT		30
   15.39 +
   15.40 +#define MYTHTV_TRANSFER_MAX_WAITS	100
   15.41 +
   15.42 +#define MYTHTV_TRANSFER_MAX_BUFFER	( 32*1024  )
   15.43 +
   15.44 +/* 4*1024 ??? */
   15.45 +#define MAX_READ_SIZE                   ( 16*1024 )
   15.46 +
   15.47 +#define ENABLE_TIMING_POSITION		1
   15.48 +
   15.49 +/* stablish a maximum iteration value to the IS_RECORDING message */
   15.50 +static guint wait_to_transfer = 0;
   15.51 +
   15.52 +static const GstElementDetails gst_mythtv_src_details =
   15.53 +GST_ELEMENT_DETAILS ("MythTV client source",
   15.54 +    "Source/Network",
   15.55 +    "Control and receive data as a client over the network via raw socket connections using the MythTV protocol",
   15.56 +    "Rosfran Borges <rosfran.borges@indt.org.br>");
   15.57 +
   15.58 +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
   15.59 +    GST_PAD_SRC,
   15.60 +    GST_PAD_ALWAYS,
   15.61 +    GST_STATIC_CAPS_ANY);
   15.62 +
   15.63 +enum
   15.64 +{
   15.65 +  PROP_0,
   15.66 +  PROP_LOCATION,
   15.67 +  PROP_URI,
   15.68 +#ifndef GST_DISABLE_GST_DEBUG
   15.69 +  PROP_MYTHTV_DBG,
   15.70 +#endif
   15.71 +  PROP_MYTHTV_VERSION,
   15.72 +  PROP_MYTHTV_LIVE,
   15.73 +  PROP_MYTHTV_LIVEID,
   15.74 +  PROP_MYTHTV_LIVE_CHAINID
   15.75 +};
   15.76 +
   15.77 +static void gst_mythtv_src_finalize (GObject * gobject);
   15.78 +
   15.79 +static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc,
   15.80 +    guint64 offset, guint size, GstBuffer ** outbuf);
   15.81 +static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
   15.82 +static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
   15.83 +static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
   15.84 +static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *base_src );
   15.85 +
   15.86 +static void gst_mythtv_src_set_property (GObject * object, guint prop_id,
   15.87 +    const GValue * value, GParamSpec * pspec);
   15.88 +static void gst_mythtv_src_get_property (GObject * object, guint prop_id,
   15.89 +    GValue * value, GParamSpec * pspec);
   15.90 +
   15.91 +static void
   15.92 +gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
   15.93 +
   15.94 +static gboolean
   15.95 +gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
   15.96 +
   15.97 +  static void
   15.98 +_urihandler_init (GType type)
   15.99 +{
  15.100 +  static const GInterfaceInfo urihandler_info = {
  15.101 +    gst_mythtv_src_uri_handler_init,
  15.102 +    NULL,
  15.103 +    NULL
  15.104 +  };
  15.105 +
  15.106 +  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
  15.107 +
  15.108 +  GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
  15.109 +      "MythTV src");
  15.110 +}
  15.111 +
  15.112 +GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstBaseSrc,
  15.113 +    GST_TYPE_BASE_SRC, _urihandler_init);
  15.114 +
  15.115 +  static void
  15.116 +gst_mythtv_src_base_init (gpointer g_class)
  15.117 +{
  15.118 +  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
  15.119 +
  15.120 +  gst_element_class_add_pad_template (element_class,
  15.121 +      gst_static_pad_template_get (&srctemplate));
  15.122 +
  15.123 +  gst_element_class_set_details (element_class, &gst_mythtv_src_details);
  15.124 +}
  15.125 +
  15.126 +  static void
  15.127 +gst_mythtv_src_class_init (GstMythtvSrcClass * klass)
  15.128 +{
  15.129 +  GObjectClass *gobject_class;
  15.130 +  GstBaseSrcClass *gstbasesrc_class;
  15.131 +
  15.132 +  gobject_class = (GObjectClass *) klass;
  15.133 +  gstbasesrc_class = (GstBaseSrcClass *) klass;
  15.134 +
  15.135 +  gobject_class->set_property = gst_mythtv_src_set_property;
  15.136 +  gobject_class->get_property = gst_mythtv_src_get_property;
  15.137 +  gobject_class->finalize = gst_mythtv_src_finalize;
  15.138 +
  15.139 +  g_object_class_install_property
  15.140 +    (gobject_class, PROP_LOCATION,
  15.141 +     g_param_spec_string ("location", "Location",
  15.142 +       "The location. In the form:"
  15.143 +       "\n\t\t\tmyth://a.com/file.nuv"
  15.144 +       "\n\t\t\tmyth://a.com:23223/file.nuv "
  15.145 +       "\n\t\t\ta.com/file.nuv - default scheme 'myth'",
  15.146 +       "", G_PARAM_READWRITE));
  15.147 +
  15.148 +  g_object_class_install_property
  15.149 +    (gobject_class, PROP_URI,
  15.150 +     g_param_spec_string ("uri", "Uri",
  15.151 +       "The location in form of a URI (deprecated; use location)",
  15.152 +       "", G_PARAM_READWRITE));
  15.153 +
  15.154 +  g_object_class_install_property
  15.155 +    (gobject_class, PROP_MYTHTV_VERSION,
  15.156 +     g_param_spec_int ("mythtv-version", "mythtv-version",
  15.157 +       "Change Myth TV version",
  15.158 +       26, 30, 26, G_PARAM_READWRITE));
  15.159 +
  15.160 +  g_object_class_install_property
  15.161 +    (gobject_class, PROP_MYTHTV_LIVEID,
  15.162 +     g_param_spec_int ("mythtv-live-id", "mythtv-live-id",
  15.163 +       "Change Myth TV version",
  15.164 +       0, 200, GST_MYTHTV_ID_NUM, G_PARAM_READWRITE));
  15.165 +
  15.166 +  g_object_class_install_property
  15.167 +    (gobject_class, PROP_MYTHTV_LIVE_CHAINID,
  15.168 +     g_param_spec_string ("mythtv-live-chainid", "mythtv-live-chainid",
  15.169 +       "Sets the Myth TV chain ID (from TV Chain)",
  15.170 +       "", G_PARAM_READWRITE));
  15.171 +
  15.172 +  g_object_class_install_property
  15.173 +    (gobject_class, PROP_MYTHTV_LIVE,
  15.174 +     g_param_spec_boolean ("mythtv-live", "mythtv-live",
  15.175 +       "Enable MythTV Live TV content streaming",
  15.176 +       FALSE, G_PARAM_READWRITE));
  15.177 +
  15.178 +#ifndef GST_DISABLE_GST_DEBUG
  15.179 +  g_object_class_install_property
  15.180 +    (gobject_class, PROP_MYTHTV_DBG,
  15.181 +     g_param_spec_boolean ("mythtv-debug", "mythtv-debug",
  15.182 +       "Enable MythTV debug messages",
  15.183 +       FALSE, G_PARAM_READWRITE));
  15.184 +#endif
  15.185 +
  15.186 +  gstbasesrc_class->start = gst_mythtv_src_start;
  15.187 +  gstbasesrc_class->stop = gst_mythtv_src_stop;
  15.188 +  gstbasesrc_class->get_size = gst_mythtv_src_get_size;
  15.189 +  gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
  15.190 +
  15.191 +  gstbasesrc_class->create = gst_mythtv_src_create;
  15.192 +
  15.193 +
  15.194 +  GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
  15.195 +      "MythTV Client Source");
  15.196 +}
  15.197 +
  15.198 +  static void
  15.199 +gst_mythtv_src_init (GstMythtvSrc * this, GstMythtvSrcClass * g_class)
  15.200 +{
  15.201 +  this->file_transfer = NULL;
  15.202 +
  15.203 +  this->unique_setup = FALSE;
  15.204 +
  15.205 +  this->mythtv_version = MYTHTV_VERSION_DEFAULT;
  15.206 +
  15.207 +  this->bytes_read = 0;
  15.208 +
  15.209 +  this->content_size = -1;
  15.210 +  this->read_offset = 0;
  15.211 +
  15.212 +  this->live_tv = FALSE;
  15.213 +
  15.214 +  this->user_agent = g_strdup ("mythtvsrc");
  15.215 +  this->mythtv_caps = NULL;    
  15.216 +
  15.217 +  gst_pad_set_event_function (GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
  15.218 +      GST_DEBUG_FUNCPTR (gst_mythtv_src_handle_event));
  15.219 +
  15.220 +}
  15.221 +
  15.222 +  static void
  15.223 +gst_mythtv_src_finalize (GObject * gobject)
  15.224 +{
  15.225 +  GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
  15.226 +
  15.227 +  g_free (this->user_agent);
  15.228 +
  15.229 +  if (this->mythtv_caps) {
  15.230 +    gst_caps_unref (this->mythtv_caps);
  15.231 +    this->mythtv_caps = NULL;
  15.232 +  }
  15.233 +
  15.234 +  if (this->file_transfer) {
  15.235 +    g_object_unref (this->file_transfer);
  15.236 +    this->file_transfer = NULL;
  15.237 +  }
  15.238 +
  15.239 +  if (this->uri_name) {
  15.240 +    g_free (this->uri_name);
  15.241 +  }
  15.242 +
  15.243 +  if (this->user_agent) {
  15.244 +    g_free (this->user_agent);
  15.245 +  }
  15.246 +
  15.247 +  G_OBJECT_CLASS (parent_class)->finalize (gobject);
  15.248 +}
  15.249 +
  15.250 +#if 0
  15.251 +  static guint
  15.252 +do_seek( GstMythtvSrc *src, guint64 offset, guint size, GstBuffer *outbuf )
  15.253 +{
  15.254 +  guint64 off_uint64 = myth_file_transfer_seek(src->file_transfer, offset, 1);
  15.255 +
  15.256 +  g_print( "[%s] Call MythTV SEEK with offset %llu, got a new one %llu...\n", __FUNCTION__, 
  15.257 +      offset, off_uint64 );
  15.258 +
  15.259 +  return off_uint64;
  15.260 +
  15.261 +}
  15.262 +#endif
  15.263 +
  15.264 +  static guint
  15.265 +do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer * outbuf)
  15.266 +{
  15.267 +  guint read = 0;
  15.268 +  guint sizetoread = size; //GST_BUFFER_SIZE (outbuf);
  15.269 +
  15.270 +  g_print( "[%s] Reading %d bytes...\n", __FUNCTION__, sizetoread ); 
  15.271 +
  15.272 +  /* Loop sending the request:
  15.273 +   * Retry whilst authentication fails and we supply it. */
  15.274 +
  15.275 +  ssize_t len = 0;
  15.276 +
  15.277 +  GST_OBJECT_LOCK(src);
  15.278 +
  15.279 +  while ( sizetoread > 0 ) {
  15.280 +
  15.281 +    len = myth_file_transfer_read( src->file_transfer,
  15.282 +	GST_BUFFER_DATA (outbuf) + read, sizetoread, TRUE );
  15.283 +
  15.284 +    if ( len > 0 ) {
  15.285 +      read += len;
  15.286 +      src->read_offset += read;
  15.287 +      sizetoread -= len;
  15.288 +    } else if ( len < 0 ) {
  15.289 +      goto done;
  15.290 +    }
  15.291 +    /*else if ( len == 0 ) {
  15.292 +      goto eos;
  15.293 +    }*/
  15.294 +
  15.295 +    if ( len == sizetoread )
  15.296 +      break;
  15.297 +
  15.298 +  }
  15.299 +
  15.300 +  if ( read > 0 ) {
  15.301 +    src->bytes_read += read;
  15.302 +
  15.303 +    GST_BUFFER_SIZE (outbuf) = read;
  15.304 +  } else if ( read <= 0 || len <= 0 ) {
  15.305 +    if ( src->live_tv == FALSE )
  15.306 +      goto eos;
  15.307 +    else
  15.308 +      goto done;
  15.309 +  }
  15.310 +  //GST_BUFFER_OFFSET (outbuf) = src->read_offset;
  15.311 +
  15.312 +  g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
  15.313 +      "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read, 
  15.314 +      src->read_offset, src->content_size );
  15.315 +
  15.316 +  GST_OBJECT_UNLOCK(src);
  15.317 +
  15.318 +  if ( len < 0 ) {
  15.319 +    read = len;
  15.320 +    if ( src->live_tv == FALSE ) 
  15.321 +      goto eos;
  15.322 +    else
  15.323 +      goto done;
  15.324 +  }
  15.325 +
  15.326 +  if ( src->bytes_read < src->content_size )
  15.327 +    goto done;
  15.328 +
  15.329 +eos:
  15.330 +  GST_OBJECT_UNLOCK(src);
  15.331 +
  15.332 +  src->eos = TRUE;
  15.333 +done:
  15.334 +  GST_OBJECT_UNLOCK(src);
  15.335 +
  15.336 +  return read;
  15.337 +}
  15.338 +
  15.339 +  static GstFlowReturn
  15.340 +gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset, 
  15.341 +    guint size, GstBuffer **outbuf )
  15.342 +{
  15.343 +  GstMythtvSrc *src;
  15.344 +  GstFlowReturn ret = GST_FLOW_OK;
  15.345 +  guint read;
  15.346 +  guint64 size_tmp = 0;
  15.347 +
  15.348 +  src = GST_MYTHTV_SRC (psrc);
  15.349 +
  15.350 +  g_print( "[%s]\tBUFFER OFFSET = %llu, BUFFER SIZE = %d.\n", __FUNCTION__, offset, 
  15.351 +      size );
  15.352 +
  15.353 +
  15.354 +  /* The caller should know the number of bytes and not read beyond EOS. */
  15.355 +  if (G_UNLIKELY (src->eos))
  15.356 +    goto eos;
  15.357 +
  15.358 +  /* Create the buffer. */
  15.359 +  ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
  15.360 +      //      GST_BUFFER_OFFSET_NONE, GST_BASE_SRC (psrc)->blocksize,
  15.361 +      offset, size,
  15.362 +      src->mythtv_caps ? src->mythtv_caps :
  15.363 +      GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
  15.364 +
  15.365 +  if (G_UNLIKELY (ret == GST_FLOW_UNEXPECTED))
  15.366 +    goto eos;
  15.367 +
  15.368 +  if (G_UNLIKELY (ret != GST_FLOW_OK))
  15.369 +    goto done;
  15.370 +
  15.371 +  read = do_read_request_response ( src, offset, size, *outbuf );
  15.372 +
  15.373 +#if ENABLE_TIMING_POSITION == 1
  15.374 +  if (src->live_tv == TRUE) {
  15.375 +    //g_usleep( 1000 );
  15.376 +get_file_pos:
  15.377 +    //g_usleep( 100 );
  15.378 +    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
  15.379 +    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
  15.380 +      src->content_size = size_tmp;
  15.381 +    else
  15.382 +      goto get_file_pos;
  15.383 +    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
  15.384 +	__FUNCTION__, size_tmp);
  15.385 +
  15.386 +  }
  15.387 +#endif
  15.388 +
  15.389 +  if (G_UNLIKELY (read < 0))
  15.390 +    goto read_error;
  15.391 +
  15.392 +  if (G_UNLIKELY(src->eos))
  15.393 +    goto eos;
  15.394 +
  15.395 +done:
  15.396 +  return ret;
  15.397 +eos:
  15.398 +#if ENABLE_TIMING_POSITION == 1
  15.399 +  if ( src->live_tv == TRUE ) {
  15.400 +    //g_usleep( 1000 );
  15.401 +    guint64 size_tmp = 0;
  15.402 +get_file_pos_eos:
  15.403 +    //g_usleep( 100 );
  15.404 +    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
  15.405 +    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
  15.406 +      src->content_size = size_tmp;
  15.407 +    else
  15.408 +      goto get_file_pos_eos;
  15.409 +    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
  15.410 +	__FUNCTION__, size_tmp);
  15.411 +    goto done;
  15.412 +  } else 
  15.413 +#endif
  15.414 +  {
  15.415 +    GST_DEBUG_OBJECT (src, "EOS reached");
  15.416 +    return GST_FLOW_UNEXPECTED;
  15.417 +  }
  15.418 +  /* ERRORS */
  15.419 +read_error:
  15.420 +  {
  15.421 +    GST_ELEMENT_ERROR (src, RESOURCE, READ,
  15.422 +	(NULL), ("Could not read any bytes (%i, %s)", read,
  15.423 +	  src->uri_name));
  15.424 +    return GST_FLOW_ERROR;
  15.425 +  }
  15.426 +}
  15.427 +
  15.428 +#if 0
  15.429 +/* The following two charset mangling functions were copied from gnomevfssrc.
  15.430 + * Preserve them under the unverified assumption that they do something vaguely
  15.431 + * worthwhile.
  15.432 + */
  15.433 +  static char *
  15.434 +unicodify (const char *str, int len, ...)
  15.435 +{
  15.436 +  char *ret = NULL, *cset;
  15.437 +  va_list args;
  15.438 +  gsize bytes_read, bytes_written;
  15.439 +
  15.440 +  if (g_utf8_validate (str, len, NULL))
  15.441 +    return g_strndup (str, len >= 0 ? len : strlen (str));
  15.442 +
  15.443 +  va_start (args, len);
  15.444 +  while ((cset = va_arg (args, char *)) != NULL)
  15.445 +  {
  15.446 +    if (!strcmp (cset, "locale"))
  15.447 +      ret = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, NULL);
  15.448 +    else
  15.449 +      ret = g_convert (str, len, "UTF-8", cset,
  15.450 +	  &bytes_read, &bytes_written, NULL);
  15.451 +    if (ret)
  15.452 +      break;
  15.453 +  }
  15.454 +  va_end (args);
  15.455 +
  15.456 +  return ret;
  15.457 +}
  15.458 +
  15.459 +  static char *
  15.460 +gst_mythtv_src_unicodify (const char *str)
  15.461 +{
  15.462 +  return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
  15.463 +}
  15.464 +#endif
  15.465 +
  15.466 +/* create a socket for connecting to remote server */
  15.467 +  static gboolean
  15.468 +gst_mythtv_src_start ( GstBaseSrc * bsrc )
  15.469 +{
  15.470 +  GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc);
  15.471 +
  15.472 +  GString *chain_id_local = NULL;
  15.473 +
  15.474 +  gboolean ret = TRUE;
  15.475 +#if 0
  15.476 +  if (src->live_tv == TRUE && src->file_transfer != NULL) {
  15.477 +    guint64 size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
  15.478 +    if (size_tmp > src->content_size)
  15.479 +      src->content_size = size_tmp;
  15.480 +    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
  15.481 +	__FUNCTION__, size_tmp);
  15.482 +  }
  15.483 +#endif
  15.484 +  if (src->unique_setup == FALSE) {
  15.485 +    src->unique_setup = TRUE;
  15.486 +  } else {
  15.487 +    goto done;
  15.488 +  }
  15.489 +
  15.490 +  GST_OBJECT_LOCK(src);
  15.491 +
  15.492 +  if ( src->live_tv ) {
  15.493 +    src->spawn_livetv = myth_livetv_new( );
  15.494 +    if ( myth_livetv_setup( src->spawn_livetv ) == FALSE ) {
  15.495 +    	ret = FALSE;
  15.496 +    	goto init_failed;
  15.497 +    }
  15.498 +    /* set up the uri variable */
  15.499 +    src->uri_name = g_strdup( src->spawn_livetv->proginfo->pathname->str );
  15.500 +    chain_id_local = gmyth_tvchain_get_id( src->spawn_livetv->tvchain );
  15.501 +    if ( chain_id_local != NULL ) {
  15.502 +      src->live_chain_id = g_strdup( chain_id_local->str );
  15.503 +      g_print( "\t[%s]\tLocal chain ID = %s.\n", __FUNCTION__, src->live_chain_id );
  15.504 +    }
  15.505 +    src->live_tv_id = src->spawn_livetv->remote_encoder->recorder_num;
  15.506 +    g_print ( "[%s] LiveTV id = %d, URI path = %s.\n", __FUNCTION__, src->live_tv_id, src->uri_name );
  15.507 +  }
  15.508 +
  15.509 +  src->file_transfer = myth_file_transfer_new( src->live_tv_id, 
  15.510 +      g_string_new( src->uri_name ), -1, src->mythtv_version );
  15.511 +
  15.512 +  if ( src->file_transfer == NULL ) {
  15.513 +    GST_OBJECT_UNLOCK(src);
  15.514 +
  15.515 +    goto init_failed;
  15.516 +  }
  15.517 +
  15.518 +  if ( src->live_tv ) {
  15.519 +    g_print ( "[%s] GST MYTHTVSRC: live_chain_id = %s\n", __FUNCTION__, src->live_chain_id );
  15.520 +    /* sets the MythSocket to the FileTransfer */
  15.521 +    //ret = myth_file_transfer_livetv_setup( &(src->file_transfer), src->spawn_livetv->remote_encoder->myth_socket );
  15.522 +  }
  15.523 +  /* sets the Playback monitor connection */
  15.524 +  ret = myth_file_transfer_playback_setup( &(src->file_transfer), src->live_tv );
  15.525 +
  15.526 +  if ( src->live_tv == TRUE && ret == TRUE ) {
  15.527 +    /* loop finished, set the max tries variable to zero again... */
  15.528 +    wait_to_transfer = 0;
  15.529 +
  15.530 +    while ( wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS && ( myth_file_transfer_is_recording( src->file_transfer ) == FALSE 
  15.531 +	  /*|| ( myth_file_transfer_get_file_position( src->file_transfer ) < ( src->content_size + 327680 ) )*/ ) )
  15.532 +      g_usleep( 100 );
  15.533 +  }
  15.534 +
  15.535 +  /* sets the FileTransfer instance connection (video/audio download) */
  15.536 +  ret = myth_file_transfer_setup( &(src->file_transfer), src->live_tv );
  15.537 +
  15.538 +  if ( ret == FALSE ) {
  15.539 +    GST_OBJECT_UNLOCK(src);
  15.540 +#ifndef GST_DISABLE_GST_DEBUG  
  15.541 +    if ( src->mythtv_msgs_dbg )
  15.542 +      g_printerr( "MythTV FileTransfer request failed when setting up socket connection!\n" );  	  
  15.543 +#endif
  15.544 +    goto begin_req_failed;
  15.545 +  }
  15.546 +
  15.547 +  src->content_size = src->file_transfer->filesize;
  15.548 +
  15.549 +  GST_OBJECT_UNLOCK(src);
  15.550 +
  15.551 +#if 0
  15.552 +  const char *str_value;
  15.553 +  gint gint_value;
  15.554 +
  15.555 +  str_value = ne_get_response_header (src->request, "myth-metaint");
  15.556 +  if (str_value) {
  15.557 +    if ( sscanf (str_value, "%d", &gint_value) == 1 ) {
  15.558 +      if (src->myth_caps) {
  15.559 +	gst_caps_unref (src->myth_caps);
  15.560 +	src->myth_caps = NULL;
  15.561 +      }
  15.562 +      src->myth_metaint = gint_value;
  15.563 +#endif
  15.564 +      //src->mythtv_caps = gst_caps_new_simple ("application/x-gst_ff-nuv", NULL);
  15.565 +      //   }
  15.566 +      // }
  15.567 +done:
  15.568 +      return TRUE;
  15.569 +
  15.570 +      /* ERRORS */
  15.571 +init_failed:
  15.572 +      {
  15.573 +      	if (src->spawn_livetv != NULL )
  15.574 +	  g_object_unref( src->spawn_livetv );
  15.575 +
  15.576 +	GST_ELEMENT_ERROR (src, LIBRARY, INIT,
  15.577 +	    (NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name));
  15.578 +	return FALSE;
  15.579 +      }
  15.580 +begin_req_failed:
  15.581 +      {
  15.582 +	GST_ELEMENT_ERROR (src, LIBRARY, INIT,
  15.583 +	    (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name));
  15.584 +	return FALSE;
  15.585 +      }
  15.586 +}
  15.587 +
  15.588 +  static gboolean
  15.589 +gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
  15.590 +{
  15.591 +  GstMythtvSrc *src;
  15.592 +
  15.593 +  src = GST_MYTHTV_SRC (bsrc);
  15.594 +#if ENABLE_TIMING_POSITION == 1
  15.595 +  guint64 size_tmp = 0; 
  15.596 +  if (src->live_tv == TRUE) {
  15.597 +get_file_pos:
  15.598 +    //g_usleep( 100 );
  15.599 +    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
  15.600 +    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
  15.601 +      src->content_size = size_tmp;
  15.602 +    else
  15.603 +      goto get_file_pos;
  15.604 +    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
  15.605 +	__FUNCTION__, size_tmp);
  15.606 +  }
  15.607 +#endif
  15.608 +  if (src->content_size <= 0)
  15.609 +    return FALSE;
  15.610 +
  15.611 +  *size = src->content_size;
  15.612 +
  15.613 +  return TRUE;
  15.614 +}
  15.615 +
  15.616 +/* close the socket and associated resources
  15.617 + * used both to recover from errors and go to NULL state */
  15.618 +  static gboolean
  15.619 +gst_mythtv_src_stop (GstBaseSrc * bsrc)
  15.620 +{
  15.621 +  GstMythtvSrc *src;
  15.622 +
  15.623 +  src = GST_MYTHTV_SRC (bsrc);
  15.624 +
  15.625 +  if (src->uri_name) {
  15.626 +    g_free (src->uri_name);
  15.627 +    src->uri_name = NULL;
  15.628 +  }
  15.629 +
  15.630 +  if (src->mythtv_caps) {
  15.631 +    gst_caps_unref (src->mythtv_caps);
  15.632 +    src->mythtv_caps = NULL;
  15.633 +  }
  15.634 +
  15.635 +  src->eos = FALSE;
  15.636 +
  15.637 +  return TRUE;
  15.638 +}
  15.639 +
  15.640 +  static gboolean
  15.641 +gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event)
  15.642 +{
  15.643 +  GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
  15.644 +
  15.645 +  switch (GST_EVENT_TYPE (event)) {
  15.646 +    case GST_EVENT_FLUSH_START:
  15.647 +      src->eos = FALSE;
  15.648 +      break;
  15.649 +      //return TRUE;
  15.650 +    case GST_EVENT_FLUSH_STOP:
  15.651 +      src->do_start = TRUE;
  15.652 +      src->eos = FALSE;
  15.653 +      gst_element_set_state (GST_ELEMENT(src), GST_STATE_NULL);
  15.654 +      gst_element_set_locked_state (GST_ELEMENT(src), TRUE);
  15.655 +      break;
  15.656 +    case GST_EVENT_SEEK:  	  
  15.657 +      {
  15.658 +	gdouble rate;
  15.659 +	//gboolean update = TRUE;
  15.660 +	GstFormat format;
  15.661 +	GstSeekType cur_type, stop_type;
  15.662 +	GstSeekFlags flags;
  15.663 +	gint64 cur = 0, stop = 0;
  15.664 +	gst_event_parse_seek ( event, &rate, &format,
  15.665 +	    &flags, &cur_type, &cur,
  15.666 +	    &stop_type, &stop );
  15.667 +
  15.668 +	g_print( "[%s] Got EVENT_SEEK.\n", __FUNCTION__ );
  15.669 +	if ( !( flags & GST_SEEK_FLAG_FLUSH ) ) {
  15.670 +	  g_print( "[%s] Could get the FLAG_FLUSH message.\n", __FUNCTION__ );
  15.671 +	}
  15.672 +	//gboolean ret = gst_event_parse_new_segment ( event,
  15.673 +	//    &update, &rate, &format, &start, &stop,
  15.674 +	//    &position );
  15.675 +	//GstFlowReturn flow_ret = gst_mythtv_src_create (GST_BASE_SRC( GST_PAD_PARENT( psrc ) ), 
  15.676 +	//			cur, stop - cur + 1, GstBuffer)
  15.677 +
  15.678 +      } 
  15.679 +    default:
  15.680 +      return gst_pad_event_default (pad, event);
  15.681 +  }
  15.682 +
  15.683 +  return gst_pad_event_default (pad, event);
  15.684 +}
  15.685 +
  15.686 +  static gboolean
  15.687 +gst_mythtv_src_is_seekable( GstBaseSrc *base_src )
  15.688 +{
  15.689 +  return TRUE;
  15.690 +}
  15.691 +
  15.692 +  static void
  15.693 +gst_mythtv_src_set_property (GObject * object, guint prop_id,
  15.694 +    const GValue * value, GParamSpec * pspec)
  15.695 +{
  15.696 +  GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
  15.697 +
  15.698 +  GST_OBJECT_LOCK (mythtvsrc);
  15.699 +  switch (prop_id) {
  15.700 +    case PROP_URI:
  15.701 +    case PROP_LOCATION:
  15.702 +      {
  15.703 +	if (!g_value_get_string (value)) {
  15.704 +	  GST_WARNING ("location property cannot be NULL");
  15.705 +	  goto done;
  15.706 +	}
  15.707 +
  15.708 +	if (mythtvsrc->uri_name != NULL) {
  15.709 +	  g_free (mythtvsrc->uri_name);
  15.710 +	  mythtvsrc->uri_name = NULL;
  15.711 +	}
  15.712 +	mythtvsrc->uri_name = g_value_dup_string (value);
  15.713 +
  15.714 +	break;
  15.715 +      }
  15.716 +#ifndef GST_DISABLE_GST_DEBUG
  15.717 +    case PROP_MYTHTV_DBG:
  15.718 +      {
  15.719 +	mythtvsrc->mythtv_msgs_dbg = g_value_get_boolean (value);
  15.720 +	break;
  15.721 +      }
  15.722 +#endif
  15.723 +    case PROP_MYTHTV_VERSION:
  15.724 +      {
  15.725 +	mythtvsrc->mythtv_version = g_value_get_int (value);
  15.726 +	break;
  15.727 +      }
  15.728 +    case PROP_MYTHTV_LIVEID:
  15.729 +      {
  15.730 +	mythtvsrc->live_tv_id = g_value_get_int (value);
  15.731 +	break;
  15.732 +      }
  15.733 +    case PROP_MYTHTV_LIVE:
  15.734 +      {
  15.735 +	mythtvsrc->live_tv = g_value_get_boolean (value);
  15.736 +	break;
  15.737 +      }
  15.738 +    case PROP_MYTHTV_LIVE_CHAINID:
  15.739 +      {
  15.740 +	if (!g_value_get_string (value)) {
  15.741 +	  GST_WARNING ("MythTV Live chainid property cannot be NULL");
  15.742 +	  goto done;
  15.743 +	}
  15.744 +
  15.745 +	if (mythtvsrc->live_chain_id != NULL) {
  15.746 +	  g_free (mythtvsrc->live_chain_id);
  15.747 +	  mythtvsrc->live_chain_id = NULL;
  15.748 +	}
  15.749 +	mythtvsrc->live_chain_id = g_value_dup_string (value);
  15.750 +
  15.751 +	break;
  15.752 +      }
  15.753 +
  15.754 +    default:
  15.755 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  15.756 +      break;
  15.757 +  }
  15.758 +  GST_OBJECT_UNLOCK (mythtvsrc);
  15.759 +done:
  15.760 +  return;
  15.761 +}
  15.762 +
  15.763 +  static void
  15.764 +gst_mythtv_src_get_property (GObject * object, guint prop_id,
  15.765 +    GValue * value, GParamSpec * pspec)
  15.766 +{
  15.767 +  GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
  15.768 +
  15.769 +  GST_OBJECT_LOCK (mythtvsrc);
  15.770 +  switch (prop_id) {
  15.771 +    case PROP_URI:
  15.772 +    case PROP_LOCATION:
  15.773 +      {
  15.774 +	gchar *str = g_strdup( "" );
  15.775 +
  15.776 +	if ( mythtvsrc->uri_name == NULL ) {
  15.777 +	  g_free (mythtvsrc->uri_name);
  15.778 +	  mythtvsrc->uri_name = NULL;
  15.779 +	} else {
  15.780 +	  str = g_strdup( mythtvsrc->uri_name );
  15.781 +	}
  15.782 +	g_value_set_string ( value, str );
  15.783 +	break;
  15.784 +      }
  15.785 +#ifndef GST_DISABLE_GST_DEBUG
  15.786 +    case PROP_MYTHTV_DBG:
  15.787 +      g_value_set_boolean ( value, mythtvsrc->mythtv_msgs_dbg );
  15.788 +      break;
  15.789 +#endif
  15.790 +    case PROP_MYTHTV_VERSION:
  15.791 +      {
  15.792 +	g_value_set_int ( value, mythtvsrc->mythtv_version );
  15.793 +	break;
  15.794 +      }
  15.795 +    case PROP_MYTHTV_LIVEID:
  15.796 +      {
  15.797 +	g_value_set_int ( value, mythtvsrc->live_tv_id );
  15.798 +	break;
  15.799 +      }
  15.800 +    case PROP_MYTHTV_LIVE:
  15.801 +      g_value_set_boolean ( value, mythtvsrc->live_tv );
  15.802 +      break;
  15.803 +    case PROP_MYTHTV_LIVE_CHAINID:
  15.804 +      {
  15.805 +	gchar *str = g_strdup( "" );
  15.806 +
  15.807 +	if ( mythtvsrc->live_chain_id == NULL ) {
  15.808 +	  g_free (mythtvsrc->live_chain_id);
  15.809 +	  mythtvsrc->live_chain_id = NULL;
  15.810 +	} else {
  15.811 +	  str = g_strdup( mythtvsrc->live_chain_id );
  15.812 +	}
  15.813 +	g_value_set_string ( value, str );
  15.814 +	break;
  15.815 +      }
  15.816 +    default:
  15.817 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  15.818 +      break;
  15.819 +  }
  15.820 +  GST_OBJECT_UNLOCK (mythtvsrc);
  15.821 +}
  15.822 +
  15.823 +/* entry point to initialize the plug-in
  15.824 + * initialize the plug-in itself
  15.825 + * register the element factories and pad templates
  15.826 + * register the features
  15.827 + */
  15.828 +  static gboolean
  15.829 +plugin_init (GstPlugin * plugin)
  15.830 +{
  15.831 +  return gst_element_register (plugin, "mythtvsrc", GST_RANK_NONE,
  15.832 +      GST_TYPE_MYTHTV_SRC);
  15.833 +}
  15.834 +
  15.835 +/* this is the structure that gst-register looks for
  15.836 + * so keep the name plugin_desc, or you cannot get your plug-in registered */
  15.837 +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
  15.838 +    GST_VERSION_MINOR,
  15.839 +    "mythtv",
  15.840 +    "lib MythTV src",
  15.841 +    plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
  15.842 +
  15.843 +
  15.844 +/*** GSTURIHANDLER INTERFACE *************************************************/
  15.845 +  static guint 
  15.846 +gst_mythtv_src_uri_get_type (void)
  15.847 +{
  15.848 +  return GST_URI_SRC;
  15.849 +}
  15.850 +
  15.851 +  static gchar **
  15.852 +gst_mythtv_src_uri_get_protocols (void)
  15.853 +{
  15.854 +  static gchar *protocols[] = { "myth", "myths", NULL };
  15.855 +
  15.856 +  return protocols;
  15.857 +}
  15.858 +
  15.859 +  static const gchar *
  15.860 +gst_mythtv_src_uri_get_uri (GstURIHandler * handler)
  15.861 +{
  15.862 +  GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
  15.863 +
  15.864 +  return src->uri_name;
  15.865 +}
  15.866 +
  15.867 +  static gboolean
  15.868 +gst_mythtv_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
  15.869 +{
  15.870 +  GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
  15.871 +
  15.872 +  gchar *protocol;
  15.873 +
  15.874 +  protocol = gst_uri_get_protocol (uri);
  15.875 +  if ((strcmp (protocol, "myth") != 0) && (strcmp (protocol, "myths") != 0)) {
  15.876 +    g_free (protocol);
  15.877 +    return FALSE;
  15.878 +  }
  15.879 +  g_free (protocol);
  15.880 +  g_object_set (src, "location", uri, NULL);
  15.881 +
  15.882 +  return TRUE;
  15.883 +}
  15.884 +
  15.885 +  static void
  15.886 +gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
  15.887 +{
  15.888 +  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
  15.889 +
  15.890 +  iface->get_type = gst_mythtv_src_uri_get_type;
  15.891 +  iface->get_protocols = gst_mythtv_src_uri_get_protocols;
  15.892 +  iface->get_uri = gst_mythtv_src_uri_get_uri;
  15.893 +  iface->set_uri = gst_mythtv_src_uri_set_uri;
  15.894 +}
  15.895 +
  15.896 +  void
  15.897 +size_header_handler (void *userdata, const char *value)
  15.898 +{
  15.899 +  GstMythtvSrc *src = GST_MYTHTV_SRC (userdata);
  15.900 +
  15.901 +  //src->content_size = g_ascii_strtoull (value, NULL, 10);
  15.902 +
  15.903 +  GST_DEBUG_OBJECT (src, "content size = %lld bytes", src->content_size);
  15.904 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c.new	Tue Sep 26 15:58:37 2006 +0100
    16.3 @@ -0,0 +1,1033 @@
    16.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2 -*- */
    16.5 +/* GStreamer MythTV Plug-in
    16.6 + * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
    16.7 + *
    16.8 + * This library is free software; you can redistribute it and/or
    16.9 + * modify it under the terms of the GNU Library General Public
   16.10 + * License as published by the Free Software Foundation; either
   16.11 + * version 2 of the License, or (at your option) any later version.
   16.12 + *
   16.13 + * This library is distributed in the hope that it will be useful,
   16.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   16.16 + * Library General Public License for more 
   16.17 + */
   16.18 +
   16.19 +#ifdef HAVE_CONFIG_H
   16.20 +#include "config.h"
   16.21 +#endif
   16.22 +
   16.23 +#include "gstmythtvsrc.h"
   16.24 +#include "myth_file_transfer.h"
   16.25 +#include "myth_livetv.h"
   16.26 +
   16.27 +#include <gmyth/gmyth_socket.h>
   16.28 +#include <gmyth/gmyth_tvchain.h>
   16.29 +
   16.30 +#include <string.h>
   16.31 +#include <unistd.h>
   16.32 +
   16.33 +GST_DEBUG_CATEGORY_STATIC (mythtvsrc_debug);
   16.34 +#define GST_CAT_DEFAULT mythtvsrc_debug
   16.35 +
   16.36 +#define GST_MYTHTV_ID_NUM		1
   16.37 +
   16.38 +#define MYTHTV_VERSION_DEFAULT		30
   16.39 +
   16.40 +#define MYTHTV_TRANSFER_MAX_WAITS	100
   16.41 +
   16.42 +#define MYTHTV_TRANSFER_MAX_BUFFER	( 32*1024  )
   16.43 +
   16.44 +/* 4*1024 ??? */
   16.45 +#define MAX_READ_SIZE                   ( 16*1024 )
   16.46 +
   16.47 +#define ENABLE_TIMING_POSITION		1
   16.48 +
   16.49 +/* stablish a maximum iteration value to the IS_RECORDING message */
   16.50 +static guint wait_to_transfer = 0;
   16.51 +
   16.52 +static const GstElementDetails gst_mythtv_src_details =
   16.53 +GST_ELEMENT_DETAILS ("MythTV client source",
   16.54 +    "Source/Network",
   16.55 +    "Control and receive data as a client over the network via raw socket connections using the MythTV protocol",
   16.56 +    "Rosfran Borges <rosfran.borges@indt.org.br>");
   16.57 +
   16.58 +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
   16.59 +    GST_PAD_SRC,
   16.60 +    GST_PAD_ALWAYS,
   16.61 +    GST_STATIC_CAPS_ANY);
   16.62 +
   16.63 +static GstTask *update_size_task = NULL;
   16.64 +
   16.65 +static GStaticRecMutex update_size_mutex = G_STATIC_REC_MUTEX_INIT;
   16.66 +
   16.67 +enum
   16.68 +{
   16.69 +  PROP_0,
   16.70 +  PROP_LOCATION,
   16.71 +  PROP_URI,
   16.72 +#ifndef GST_DISABLE_GST_DEBUG
   16.73 +  PROP_MYTHTV_DBG,
   16.74 +#endif
   16.75 +  PROP_MYTHTV_VERSION,
   16.76 +  PROP_MYTHTV_LIVE,
   16.77 +  PROP_MYTHTV_LIVEID,
   16.78 +  PROP_MYTHTV_LIVE_CHAINID
   16.79 +};
   16.80 +
   16.81 +static void gst_mythtv_src_finalize (GObject * gobject);
   16.82 +
   16.83 +static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc,
   16.84 +    guint64 offset, guint size, GstBuffer ** outbuf);
   16.85 +static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc);
   16.86 +static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc);
   16.87 +static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size);
   16.88 +static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *base_src );
   16.89 +
   16.90 +static void gst_mythtv_src_set_property (GObject * object, guint prop_id,
   16.91 +    const GValue * value, GParamSpec * pspec);
   16.92 +static void gst_mythtv_src_get_property (GObject * object, guint prop_id,
   16.93 +    GValue * value, GParamSpec * pspec);
   16.94 +
   16.95 +static void
   16.96 +gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
   16.97 +
   16.98 +static gboolean
   16.99 +gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event);
  16.100 +
  16.101 +  static void
  16.102 +_urihandler_init (GType type)
  16.103 +{
  16.104 +  static const GInterfaceInfo urihandler_info = {
  16.105 +    gst_mythtv_src_uri_handler_init,
  16.106 +    NULL,
  16.107 +    NULL
  16.108 +  };
  16.109 +
  16.110 +  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
  16.111 +
  16.112 +  GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
  16.113 +      "MythTV src");
  16.114 +}
  16.115 +
  16.116 +GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstBaseSrc,
  16.117 +    GST_TYPE_BASE_SRC, _urihandler_init);
  16.118 +
  16.119 +  static void
  16.120 +gst_mythtv_src_base_init (gpointer g_class)
  16.121 +{
  16.122 +  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
  16.123 +
  16.124 +  gst_element_class_add_pad_template (element_class,
  16.125 +      gst_static_pad_template_get (&srctemplate));
  16.126 +
  16.127 +  gst_element_class_set_details (element_class, &gst_mythtv_src_details);
  16.128 +}
  16.129 +
  16.130 +  static void
  16.131 +gst_mythtv_src_class_init (GstMythtvSrcClass * klass)
  16.132 +{
  16.133 +  GObjectClass *gobject_class;
  16.134 +  GstBaseSrcClass *gstbasesrc_class;
  16.135 +
  16.136 +  gobject_class = (GObjectClass *) klass;
  16.137 +  gstbasesrc_class = (GstBaseSrcClass *) klass;
  16.138 +
  16.139 +  gobject_class->set_property = gst_mythtv_src_set_property;
  16.140 +  gobject_class->get_property = gst_mythtv_src_get_property;
  16.141 +  gobject_class->finalize = gst_mythtv_src_finalize;
  16.142 +
  16.143 +  g_object_class_install_property
  16.144 +    (gobject_class, PROP_LOCATION,
  16.145 +     g_param_spec_string ("location", "Location",
  16.146 +       "The location. In the form:"
  16.147 +       "\n\t\t\tmyth://a.com/file.nuv"
  16.148 +       "\n\t\t\tmyth://a.com:23223/file.nuv "
  16.149 +       "\n\t\t\ta.com/file.nuv - default scheme 'myth'",
  16.150 +       "", G_PARAM_READWRITE));
  16.151 +
  16.152 +  g_object_class_install_property
  16.153 +    (gobject_class, PROP_URI,
  16.154 +     g_param_spec_string ("uri", "Uri",
  16.155 +       "The location in form of a URI (deprecated; use location)",
  16.156 +       "", G_PARAM_READWRITE));
  16.157 +
  16.158 +  g_object_class_install_property
  16.159 +    (gobject_class, PROP_MYTHTV_VERSION,
  16.160 +     g_param_spec_int ("mythtv-version", "mythtv-version",
  16.161 +       "Change Myth TV version",
  16.162 +       26, 30, 26, G_PARAM_READWRITE));
  16.163 +
  16.164 +  g_object_class_install_property
  16.165 +    (gobject_class, PROP_MYTHTV_LIVEID,
  16.166 +     g_param_spec_int ("mythtv-live-id", "mythtv-live-id",
  16.167 +       "Change Myth TV version",
  16.168 +       0, 200, GST_MYTHTV_ID_NUM, G_PARAM_READWRITE));
  16.169 +
  16.170 +  g_object_class_install_property
  16.171 +    (gobject_class, PROP_MYTHTV_LIVE_CHAINID,
  16.172 +     g_param_spec_string ("mythtv-live-chainid", "mythtv-live-chainid",
  16.173 +       "Sets the Myth TV chain ID (from TV Chain)",
  16.174 +       "", G_PARAM_READWRITE));
  16.175 +
  16.176 +  g_object_class_install_property
  16.177 +    (gobject_class, PROP_MYTHTV_LIVE,
  16.178 +     g_param_spec_boolean ("mythtv-live", "mythtv-live",
  16.179 +       "Enable MythTV Live TV content streaming",
  16.180 +       FALSE, G_PARAM_READWRITE));
  16.181 +
  16.182 +#ifndef GST_DISABLE_GST_DEBUG
  16.183 +  g_object_class_install_property
  16.184 +    (gobject_class, PROP_MYTHTV_DBG,
  16.185 +     g_param_spec_boolean ("mythtv-debug", "mythtv-debug",
  16.186 +       "Enable MythTV debug messages",
  16.187 +       FALSE, G_PARAM_READWRITE));
  16.188 +#endif
  16.189 +
  16.190 +  gstbasesrc_class->start = gst_mythtv_src_start;
  16.191 +  gstbasesrc_class->stop = gst_mythtv_src_stop;
  16.192 +  gstbasesrc_class->get_size = gst_mythtv_src_get_size;
  16.193 +  gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
  16.194 +
  16.195 +  gstbasesrc_class->create = gst_mythtv_src_create;
  16.196 +
  16.197 +  GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0,
  16.198 +      "MythTV Client Source");
  16.199 +}
  16.200 +
  16.201 +  static void
  16.202 +gst_mythtv_src_init (GstMythtvSrc * this, GstMythtvSrcClass * g_class)
  16.203 +{
  16.204 +  this->file_transfer = NULL;
  16.205 +
  16.206 +  this->unique_setup = FALSE;
  16.207 +
  16.208 +  this->mythtv_version = MYTHTV_VERSION_DEFAULT;
  16.209 +
  16.210 +  this->bytes_read = 0;
  16.211 +
  16.212 +  this->content_size = -1;
  16.213 +  this->read_offset = 0;
  16.214 +
  16.215 +  this->live_tv = FALSE;
  16.216 +
  16.217 +  this->user_agent = g_strdup ("mythtvsrc");
  16.218 +  this->mythtv_caps = NULL;    
  16.219 +
  16.220 +  gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE );
  16.221 +
  16.222 +  gst_pad_set_event_function (GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
  16.223 +      GST_DEBUG_FUNCPTR (gst_mythtv_src_handle_event));
  16.224 +
  16.225 +}
  16.226 +
  16.227 +  static void
  16.228 +gst_mythtv_src_finalize (GObject * gobject)
  16.229 +{
  16.230 +  GstMythtvSrc *this = GST_MYTHTV_SRC (gobject);
  16.231 +
  16.232 +  g_free (this->user_agent);
  16.233 +
  16.234 +  if (this->mythtv_caps) {
  16.235 +    gst_caps_unref (this->mythtv_caps);
  16.236 +    this->mythtv_caps = NULL;
  16.237 +  }
  16.238 +
  16.239 +  if (this->file_transfer) {
  16.240 +    g_object_unref (this->file_transfer);
  16.241 +    this->file_transfer = NULL;
  16.242 +  }
  16.243 +
  16.244 +  if (this->uri_name) {
  16.245 +    g_free (this->uri_name);
  16.246 +  }
  16.247 +
  16.248 +  if (this->user_agent) {
  16.249 +    g_free (this->user_agent);
  16.250 +  }
  16.251 +
  16.252 +  if ( update_size_task != NULL ) {
  16.253 +
  16.254 +    if ( GST_TASK_STATE( update_size_task ) != GST_TASK_STOPPED )
  16.255 +    	gst_task_stop( update_size_task );
  16.256 +
  16.257 +    gst_object_unref( update_size_task );
  16.258 +
  16.259 +    update_size_task = NULL;
  16.260 +
  16.261 +  }
  16.262 +
  16.263 +  G_OBJECT_CLASS (parent_class)->finalize (gobject);
  16.264 +}
  16.265 +
  16.266 +#if 0
  16.267 +  static guint
  16.268 +do_seek( GstMythtvSrc *src, guint64 offset, guint size, GstBuffer *outbuf )
  16.269 +{
  16.270 +  guint64 off_uint64 = myth_file_transfer_seek(src->file_transfer, offset, 1);
  16.271 +
  16.272 +  g_print( "[%s] Call MythTV SEEK with offset %llu, got a new one %llu...\n", __FUNCTION__, 
  16.273 +      offset, off_uint64 );
  16.274 +
  16.275 +  return off_uint64;
  16.276 +
  16.277 +}
  16.278 +#endif
  16.279 +
  16.280 +  static guint
  16.281 +do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer * outbuf)
  16.282 +{
  16.283 +  guint read = 0;
  16.284 +  guint sizetoread = size; //GST_BUFFER_SIZE (outbuf);
  16.285 +
  16.286 +  g_print( "[%s] Reading %d bytes...\n", __FUNCTION__, sizetoread ); 
  16.287 +
  16.288 +  /* Loop sending the request:
  16.289 +   * Retry whilst authentication fails and we supply it. */
  16.290 +
  16.291 +  ssize_t len = 0;
  16.292 +
  16.293 +  //GST_OBJECT_LOCK(src);
  16.294 +
  16.295 +  while ( sizetoread > 0 ) {
  16.296 +
  16.297 +    len = myth_file_transfer_read( src->file_transfer,
  16.298 +	GST_BUFFER_DATA (outbuf) + read, sizetoread, TRUE );
  16.299 +
  16.300 +    if ( len > 0 ) {
  16.301 +      read += len;
  16.302 +      src->read_offset += read;
  16.303 +      sizetoread -= len;
  16.304 +    } else if ( len < 0 ) {
  16.305 +      goto done;
  16.306 +    }
  16.307 +    else if ( len == 0 ) {
  16.308 +      if ( src->live_tv == FALSE )
  16.309 +	goto done;
  16.310 +      else
  16.311 +	goto eos;
  16.312 +
  16.313 +    }
  16.314 +
  16.315 +    if ( len == sizetoread )
  16.316 +      break;
  16.317 +
  16.318 +  }
  16.319 +
  16.320 +  if ( read > 0 ) {
  16.321 +    src->bytes_read += read;
  16.322 +
  16.323 +    GST_BUFFER_SIZE (outbuf) = read;
  16.324 +  } else if ( read <= 0 || len <= 0 ) {
  16.325 +    if ( src->live_tv == FALSE )
  16.326 +      goto eos;
  16.327 +    else
  16.328 +      goto done;
  16.329 +  }
  16.330 +  //GST_BUFFER_OFFSET (outbuf) = src->read_offset;
  16.331 +
  16.332 +  g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\
  16.333 +      "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read, 
  16.334 +      src->read_offset, src->content_size );
  16.335 +
  16.336 +  //GST_OBJECT_UNLOCK(src);
  16.337 +
  16.338 +  if ( len < 0 ) {
  16.339 +    read = len;
  16.340 +    if ( src->live_tv == FALSE ) 
  16.341 +      goto eos;
  16.342 +    else
  16.343 +      goto done;
  16.344 +  }
  16.345 +
  16.346 +  if ( src->bytes_read < src->content_size )
  16.347 +    goto done;
  16.348 +
  16.349 +eos:
  16.350 +  //GST_OBJECT_UNLOCK(src);
  16.351 +
  16.352 +  src->eos = TRUE;
  16.353 +done:
  16.354 +  //GST_OBJECT_UNLOCK(src);
  16.355 +
  16.356 +  return read;
  16.357 +}
  16.358 +
  16.359 +  static GstFlowReturn
  16.360 +gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset, 
  16.361 +    guint size, GstBuffer **outbuf )
  16.362 +{
  16.363 +  GstMythtvSrc *src;
  16.364 +  GstFlowReturn ret = GST_FLOW_OK;
  16.365 +  guint read = 0;
  16.366 +
  16.367 +  src = GST_MYTHTV_SRC (psrc);
  16.368 +
  16.369 +  //src->do_start = FALSE;
  16.370 +  src->do_start = FALSE;
  16.371 +  gst_task_join ( update_size_task );
  16.372 +
  16.373 +  g_print( "[%s]\tBUFFER OFFSET = %llu, BUFFER SIZE = %d.\n", __FUNCTION__, offset, 
  16.374 +      size );
  16.375 +
  16.376 +  /* The caller should know the number of bytes and not read beyond EOS. */
  16.377 +  //if (G_UNLIKELY (src->eos))
  16.378 +  //  goto eos;
  16.379 +  //g_static_rec_mutex_lock( &update_size_mutex );
  16.380 +
  16.381 +  /* Create the buffer. */
  16.382 +  ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
  16.383 +      //      GST_BUFFER_OFFSET_NONE, GST_BASE_SRC (psrc)->blocksize,
  16.384 +      offset, size,
  16.385 +      src->mythtv_caps ? src->mythtv_caps :
  16.386 +      GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf );
  16.387 +
  16.388 +  //if (G_UNLIKELY (ret == GST_FLOW_UNEXPECTED))
  16.389 +  //  goto eos;
  16.390 +
  16.391 +  if (G_UNLIKELY (ret != GST_FLOW_OK))
  16.392 +    goto eos;
  16.393 +
  16.394 +  if (G_UNLIKELY (ret == GST_FLOW_ERROR))
  16.395 +    goto read_error;
  16.396 +
  16.397 +  read = do_read_request_response ( src, offset, size, *outbuf );
  16.398 +
  16.399 +  //g_static_rec_mutex_unlock( &update_size_mutex );
  16.400 +
  16.401 +  src->do_start = TRUE;
  16.402 +  gst_task_start ( update_size_task );
  16.403 +
  16.404 +#if 0
  16.405 +  g_static_rec_mutex_lock( &update_size_mutex );
  16.406 +  src->do_start = FALSE;  
  16.407 +  g_static_rec_mutex_unlock( &update_size_mutex );
  16.408 +  GST_TASK_SIGNAL( update_size_task );
  16.409 +#endif
  16.410 +
  16.411 +  //g_static_rec_mutex_unlock( &update_size_mutex );
  16.412 +
  16.413 +#if 0
  16.414 +#if ENABLE_TIMING_POSITION == 1
  16.415 +  guint64 size_tmp = 0;
  16.416 +  if (src->live_tv == TRUE) {
  16.417 +    //g_usleep( 1000 );
  16.418 +get_file_pos:
  16.419 +    //g_usleep( 100 );
  16.420 +    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
  16.421 +    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
  16.422 +      src->content_size = size_tmp;
  16.423 +    else
  16.424 +      goto get_file_pos;
  16.425 +    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
  16.426 +	__FUNCTION__, size_tmp);
  16.427 +
  16.428 +  }
  16.429 +#endif
  16.430 +#endif
  16.431 +
  16.432 +  //if (G_UNLIKELY (read < 0))
  16.433 +  //  goto read_error;
  16.434 +
  16.435 +  if (G_UNLIKELY(src->eos))
  16.436 +    goto eos;
  16.437 +  else
  16.438 +    goto done;
  16.439 +
  16.440 +done:
  16.441 +  return ret;
  16.442 +eos:
  16.443 +#if 0
  16.444 +#if ENABLE_TIMING_POSITION == 1
  16.445 +  if ( src->live_tv == TRUE ) {
  16.446 +    //g_usleep( 1000 );
  16.447 +    guint64 size_tmp = 0;
  16.448 +get_file_pos_eos:
  16.449 +    //g_usleep( 100 );
  16.450 +    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
  16.451 +    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
  16.452 +      src->content_size = size_tmp;
  16.453 +    else
  16.454 +      goto get_file_pos_eos;
  16.455 +    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
  16.456 +	__FUNCTION__, size_tmp);
  16.457 +    goto done;
  16.458 +  } else 
  16.459 +#endif
  16.460 +#endif
  16.461 +  {
  16.462 +    GST_DEBUG_OBJECT (src, "EOS reached");
  16.463 +    return GST_FLOW_UNEXPECTED;
  16.464 +  }
  16.465 +  /* ERRORS */
  16.466 +read_error:
  16.467 +  {
  16.468 +    GST_ELEMENT_ERROR (src, RESOURCE, READ,
  16.469 +	(NULL), ("Could not read any bytes (%i, %s)", read,
  16.470 +	  src->uri_name));
  16.471 +    return GST_FLOW_ERROR;
  16.472 +  }
  16.473 +  #if 0
  16.474 +need_pause:
  16.475 +  {
  16.476 +    const gchar *reason = gst_flow_get_name (ret);
  16.477 +
  16.478 +    GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
  16.479 +    return GST_FLOW_UNEXPECTED;
  16.480 +  }
  16.481 +  #endif
  16.482 +
  16.483 +}
  16.484 +
  16.485 +#if 0
  16.486 +/* The following two charset mangling functions were copied from gnomevfssrc.
  16.487 + * Preserve them under the unverified assumption that they do something vaguely
  16.488 + * worthwhile.
  16.489 + */
  16.490 +  static char *
  16.491 +unicodify (const char *str, int len, ...)
  16.492 +{
  16.493 +  char *ret = NULL, *cset;
  16.494 +  va_list args;
  16.495 +  gsize bytes_read, bytes_written;
  16.496 +
  16.497 +  if (g_utf8_validate (str, len, NULL))
  16.498 +    return g_strndup (str, len >= 0 ? len : strlen (str));
  16.499 +
  16.500 +  va_start (args, len);
  16.501 +  while ((cset = va_arg (args, char *)) != NULL)
  16.502 +  {
  16.503 +    if (!strcmp (cset, "locale"))
  16.504 +      ret = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, NULL);
  16.505 +    else
  16.506 +      ret = g_convert (str, len, "UTF-8", cset,
  16.507 +	  &bytes_read, &bytes_written, NULL);
  16.508 +    if (ret)
  16.509 +      break;
  16.510 +  }
  16.511 +  va_end (args);
  16.512 +
  16.513 +  return ret;
  16.514 +}
  16.515 +
  16.516 +  static char *
  16.517 +gst_mythtv_src_unicodify (const char *str)
  16.518 +{
  16.519 +  return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
  16.520 +}
  16.521 +#endif
  16.522 +
  16.523 +void
  16.524 +update_size_func( void *mythtv_data ) 
  16.525 +{
  16.526 +  GstMythtvSrc *src;
  16.527 +
  16.528 +  g_return_if_fail( mythtv_data != NULL );
  16.529 +
  16.530 +  src = GST_MYTHTV_SRC ( mythtv_data );
  16.531 +  if ( src->do_start ) {
  16.532 + #if ENABLE_TIMING_POSITION == 1
  16.533 +  guint64 size_tmp = 0;
  16.534 +  if (src->live_tv == TRUE) {
  16.535 +get_file_pos:
  16.536 +    //g_usleep( 50 );
  16.537 +    size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
  16.538 +    if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) )
  16.539 +      src->content_size = size_tmp;
  16.540 +    else
  16.541 +      goto get_file_pos;
  16.542 +    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n",
  16.543 +	__FUNCTION__, size_tmp );
  16.544 +  }
  16.545 +#endif
  16.546 +}
  16.547 +  gst_task_pause( update_size_task );
  16.548 + // src->do_start = FALSE;
  16.549 +  //GST_TASK_SIGNAL( update_size_task );
  16.550 +
  16.551 +}
  16.552 +
  16.553 +/* create a socket for connecting to remote server */
  16.554 +  static gboolean
  16.555 +gst_mythtv_src_start ( GstBaseSrc * bsrc )
  16.556 +{
  16.557 +  GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc);
  16.558 +
  16.559 +  GString *chain_id_local = NULL;
  16.560 +
  16.561 +  gboolean ret = TRUE;
  16.562 +#if 0
  16.563 +  if (src->live_tv == TRUE && src->file_transfer != NULL) {
  16.564 +    guint64 size_tmp = myth_file_transfer_get_file_position( src->file_transfer );
  16.565 +    if (size_tmp > src->content_size)
  16.566 +      src->content_size = size_tmp;
  16.567 +    g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", 
  16.568 +	__FUNCTION__, size_tmp);
  16.569 +  }
  16.570 +#endif
  16.571 +  if (src->unique_setup == FALSE) {
  16.572 +    src->unique_setup = TRUE;
  16.573 +  } else {
  16.574 +    goto done;
  16.575 +  }
  16.576 +
  16.577 +  //GST_OBJECT_LOCK(src);
  16.578 +
  16.579 +  if ( src->live_tv ) {
  16.580 +    src->spawn_livetv = myth_livetv_new( );
  16.581 +    if ( myth_livetv_setup( src->spawn_livetv ) == FALSE ) {
  16.582 +    	ret = FALSE;
  16.583 +    	goto init_failed;
  16.584 +    }
  16.585 +    /* set up the uri variable */
  16.586 +    src->uri_name = g_strdup( src->spawn_livetv->proginfo->pathname->str );
  16.587 +    chain_id_local = gmyth_tvchain_get_id( src->spawn_livetv->tvchain );
  16.588 +    if ( chain_id_local != NULL ) {
  16.589 +      src->live_chain_id = g_strdup( chain_id_local->str );
  16.590 +      g_print( "\t[%s]\tLocal chain ID = %s.\n", __FUNCTION__, src->live_chain_id );
  16.591 +    }
  16.592 +    src->live_tv_id = src->spawn_livetv->remote_encoder->recorder_num;
  16.593 +    g_print ( "[%s] LiveTV id = %d, URI path = %s.\n", __FUNCTION__, src->live_tv_id, src->uri_name );
  16.594 +  }
  16.595 +
  16.596 +  src->file_transfer = myth_file_transfer_new( src->live_tv_id, 
  16.597 +      g_string_new( src->uri_name ), -1, src->mythtv_version );
  16.598 +
  16.599 +  if ( src->file_transfer == NULL ) {
  16.600 +    //GST_OBJECT_UNLOCK(src);
  16.601 +
  16.602 +    goto init_failed;
  16.603 +  }
  16.604 +
  16.605 +  if ( src->live_tv ) {
  16.606 +    g_print ( "[%s] GST MYTHTVSRC: live_chain_id = %s\n", __FUNCTION__, src->live_chain_id );
  16.607 +    /* sets the MythSocket to the FileTransfer */
  16.608 +    //ret = myth_file_transfer_livetv_setup( &(src->file_transfer), src->spawn_livetv->remote_encoder->myth_socket );
  16.609 +  }
  16.610 +  /* sets the Playback monitor connection */
  16.611 +  ret = myth_file_transfer_playback_setup( &(src->file_transfer), src->live_tv );
  16.612 +
  16.613 +  if ( src->live_tv == TRUE && ret == TRUE ) {
  16.614 +    /* loop finished, set the max tries variable to zero again... */
  16.615 +    wait_to_transfer = 0;
  16.616 +
  16.617 +    while ( wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS && ( myth_file_transfer_is_recording( src->file_transfer ) == FALSE 
  16.618 +	  /*|| ( myth_file_transfer_get_file_position( src->file_transfer ) < ( src->content_size + 327680 ) )*/ ) )
  16.619 +      g_usleep( 100 );
  16.620 +  }
  16.621 +
  16.622 +  /* sets the FileTransfer instance connection (video/audio download) */
  16.623 +  ret = myth_file_transfer_setup( &(src->file_transfer), src->live_tv );
  16.624 +
  16.625 +  if ( ret == FALSE ) {
  16.626 +    //GST_OBJECT_UNLOCK(src);
  16.627 +#ifndef GST_DISABLE_GST_DEBUG  
  16.628 +    if ( src->mythtv_msgs_dbg )
  16.629 +      g_printerr( "MythTV FileTransfer request failed when setting up socket connection!\n" );  	  
  16.630 +#endif
  16.631 +    goto begin_req_failed;
  16.632 +  }
  16.633 +
  16.634 +  src->content_size = src->file_transfer->filesize;
  16.635 +
  16.636 +  //GST_OBJECT_UNLOCK(src);
  16.637 +
  16.638 +  update_size_task = gst_task_create( update_size_func, src );
  16.639 +
  16.640 +  gst_task_set_lock( update_size_task, &update_size_mutex );
  16.641 +
  16.642 +  g_print( "[%s] Update Size task = %s\n", __FUNCTION__, gst_task_start( update_size_task ) && 
  16.643 +  		GST_TASK_STATE( update_size_task ) == GST_TASK_STARTED ? "OK !" : "ERROR!!!" );
  16.644 +
  16.645 +  src->do_start = TRUE;
  16.646 +
  16.647 +#if 0
  16.648 +  const char *str_value;
  16.649 +  gint gint_value;
  16.650 +
  16.651 +  str_value = ne_get_response_header (src->request, "myth-metaint");
  16.652 +  if (str_value) {
  16.653 +    if ( sscanf (str_value, "%d", &gint_value) == 1 ) {
  16.654 +      if (src->myth_caps) {
  16.655 +	gst_caps_unref (src->myth_caps);
  16.656 +	src->myth_caps = NULL;
  16.657 +      }
  16.658 +      src->myth_metaint = gint_value;
  16.659 +#endif
  16.660 +      //src->mythtv_caps = gst_caps_new_simple ("application/x-gst_ff-nuv", NULL);
  16.661 +      //   }
  16.662 +      // }
  16.663 +done:
  16.664 +      return TRUE;
  16.665 +
  16.666 +      /* ERRORS */
  16.667 +init_failed:
  16.668 +      {
  16.669 +      	if (src->spawn_livetv != NULL )
  16.670 +	  g_object_unref( src->spawn_livetv );
  16.671 +
  16.672 +	GST_ELEMENT_ERROR (src, LIBRARY, INIT,
  16.673 +	    (NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name));
  16.674 +	return FALSE;
  16.675 +      }
  16.676 +begin_req_failed:
  16.677 +      {
  16.678 +	GST_ELEMENT_ERROR (src, LIBRARY, INIT,
  16.679 +	    (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name));
  16.680 +	return FALSE;
  16.681 +      }
  16.682 +}
  16.683 +
  16.684 +#if 0
  16.685 +static gboolean
  16.686 +gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
  16.687 +{
  16.688 +  GstMythtvSrc *src;
  16.689 +  gboolean ret = FALSE;
  16.690 +
  16.691 +  src = GST_MYTHTV_SRC (bsrc);
  16.692 +
  16.693 +  g_static_rec_mutex_lock( &update_size_mutex );
  16.694 +  src->do_start = FALSE;  
  16.695 +  g_static_rec_mutex_unlock( &update_size_mutex );
  16.696 +  GST_TASK_SIGNAL( update_size_task );
  16.697 + 
  16.698 +
  16.699 +  while (1) {
  16.700 +
  16.701 +    g_static_rec_mutex_lock( &update_size_mutex );
  16.702 +    if ( !src->do_start ) {
  16.703 +
  16.704 +      g_print( "[%s] GET SIZE: do_start? == %s\n", __FUNCTION__, src->do_start ? "YES" : "NO" );
  16.705 +
  16.706 +      GST_TASK_WAIT( update_size_task );
  16.707 +    } else {
  16.708 +      if (src->content_size <= 0) {
  16.709 +	g_static_rec_mutex_unlock( &update_size_mutex );
  16.710 +	goto done;
  16.711 +      }
  16.712 +
  16.713 +      *size = src->content_size;
  16.714 +      src->do_start = FALSE;
  16.715 +
  16.716 +      g_static_rec_mutex_unlock( &update_size_mutex );
  16.717 +
  16.718 +      break;
  16.719 +    }
  16.720 +    g_static_rec_mutex_unlock( &update_size_mutex );
  16.721 +
  16.722 +  } // while (1) 
  16.723 +
  16.724 +done:
  16.725 +  return ret;
  16.726 +
  16.727 +}
  16.728 +#endif
  16.729 +
  16.730 +static gboolean
  16.731 +gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size)
  16.732 +{
  16.733 +  GstMythtvSrc *src;
  16.734 +  gboolean ret = TRUE;
  16.735 +
  16.736 +  src = GST_MYTHTV_SRC (bsrc);
  16.737 +
  16.738 +  if (src->content_size <= 0)
  16.739 +    ret= FALSE;
  16.740 +
  16.741 +  *size = src->content_size;
  16.742 +
  16.743 +  return ret;
  16.744 +
  16.745 +}
  16.746 +/* close the socket and associated resources
  16.747 + * used both to recover from errors and go to NULL state */
  16.748 +  static gboolean
  16.749 +gst_mythtv_src_stop (GstBaseSrc * bsrc)
  16.750 +{
  16.751 +  GstMythtvSrc *src;
  16.752 +
  16.753 +  src = GST_MYTHTV_SRC (bsrc);
  16.754 +
  16.755 +  if (src->uri_name) {
  16.756 +    g_free (src->uri_name);
  16.757 +    src->uri_name = NULL;
  16.758 +  }
  16.759 +
  16.760 +  if (src->mythtv_caps) {
  16.761 +    gst_caps_unref (src->mythtv_caps);
  16.762 +    src->mythtv_caps = NULL;
  16.763 +  }
  16.764 +
  16.765 +  src->eos = FALSE;
  16.766 +
  16.767 +  return TRUE;
  16.768 +}
  16.769 +
  16.770 +  static gboolean
  16.771 +gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event)
  16.772 +{
  16.773 +  GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad));
  16.774 +
  16.775 +  switch (GST_EVENT_TYPE (event)) {
  16.776 +    case GST_EVENT_FLUSH_START:
  16.777 +      src->eos = FALSE;
  16.778 +      break;
  16.779 +      //return TRUE;
  16.780 +#if 0
  16.781 +case GST_EVENT_FLUSH_STOP:
  16.782 +      src->do_start = TRUE;
  16.783 +      src->eos = FALSE;
  16.784 +      gst_element_set_state (GST_ELEMENT(src), GST_STATE_NULL);
  16.785 +      //gst_element_set_locked_state (GST_ELEMENT(src), TRUE);
  16.786 +      break;
  16.787 +#endif
  16.788 +    case GST_EVENT_SEEK:  	  
  16.789 +      {
  16.790 +	gdouble rate;
  16.791 +	//gboolean update = TRUE;
  16.792 +	GstFormat format;
  16.793 +	GstSeekType cur_type, stop_type;
  16.794 +	GstSeekFlags flags;
  16.795 +	gint64 cur = 0, stop = 0;
  16.796 +	gst_event_parse_seek ( event, &rate, &format,
  16.797 +	    &flags, &cur_type, &cur,
  16.798 +	    &stop_type, &stop );
  16.799 +
  16.800 +	g_print( "[%s] Got EVENT_SEEK.\n", __FUNCTION__ );
  16.801 +	if ( !( flags & GST_SEEK_FLAG_FLUSH ) ) {
  16.802 +	  g_print( "[%s] Could get the FLAG_FLUSH message.\n", __FUNCTION__ );
  16.803 +	}
  16.804 +	//gboolean ret = gst_event_parse_new_segment ( event,
  16.805 +	//    &update, &rate, &format, &start, &stop,
  16.806 +	//    &position );
  16.807 +	//GstFlowReturn flow_ret = gst_mythtv_src_create (GST_BASE_SRC( GST_PAD_PARENT( psrc ) ), 
  16.808 +	//			cur, stop - cur + 1, GstBuffer)
  16.809 +
  16.810 +      } 
  16.811 +    default:
  16.812 +      return gst_pad_event_default (pad, event);
  16.813 +  }
  16.814 +
  16.815 +  return gst_pad_event_default (pad, event);
  16.816 +}
  16.817 +
  16.818 +  static gboolean
  16.819 +gst_mythtv_src_is_seekable( GstBaseSrc *base_src )
  16.820 +{
  16.821 +  return TRUE;
  16.822 +}
  16.823 +
  16.824 +  static void
  16.825 +gst_mythtv_src_set_property (GObject * object, guint prop_id,
  16.826 +    const GValue * value, GParamSpec * pspec)
  16.827 +{
  16.828 +  GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
  16.829 +
  16.830 +  GST_OBJECT_LOCK (mythtvsrc);
  16.831 +  switch (prop_id) {
  16.832 +    case PROP_URI:
  16.833 +    case PROP_LOCATION:
  16.834 +      {
  16.835 +	if (!g_value_get_string (value)) {
  16.836 +	  GST_WARNING ("location property cannot be NULL");
  16.837 +	  goto done;
  16.838 +	}
  16.839 +
  16.840 +	if (mythtvsrc->uri_name != NULL) {
  16.841 +	  g_free (mythtvsrc->uri_name);
  16.842 +	  mythtvsrc->uri_name = NULL;
  16.843 +	}
  16.844 +	mythtvsrc->uri_name = g_value_dup_string (value);
  16.845 +
  16.846 +	break;
  16.847 +      }
  16.848 +#ifndef GST_DISABLE_GST_DEBUG
  16.849 +    case PROP_MYTHTV_DBG:
  16.850 +      {
  16.851 +	mythtvsrc->mythtv_msgs_dbg = g_value_get_boolean (value);
  16.852 +	break;
  16.853 +      }
  16.854 +#endif
  16.855 +    case PROP_MYTHTV_VERSION:
  16.856 +      {
  16.857 +	mythtvsrc->mythtv_version = g_value_get_int (value);
  16.858 +	break;
  16.859 +      }
  16.860 +    case PROP_MYTHTV_LIVEID:
  16.861 +      {
  16.862 +	mythtvsrc->live_tv_id = g_value_get_int (value);
  16.863 +	break;
  16.864 +      }
  16.865 +    case PROP_MYTHTV_LIVE:
  16.866 +      {
  16.867 +	mythtvsrc->live_tv = g_value_get_boolean (value);
  16.868 +	break;
  16.869 +      }
  16.870 +    case PROP_MYTHTV_LIVE_CHAINID:
  16.871 +      {
  16.872 +	if (!g_value_get_string (value)) {
  16.873 +	  GST_WARNING ("MythTV Live chainid property cannot be NULL");
  16.874 +	  goto done;
  16.875 +	}
  16.876 +
  16.877 +	if (mythtvsrc->live_chain_id != NULL) {
  16.878 +	  g_free (mythtvsrc->live_chain_id);
  16.879 +	  mythtvsrc->live_chain_id = NULL;
  16.880 +	}
  16.881 +	mythtvsrc->live_chain_id = g_value_dup_string (value);
  16.882 +
  16.883 +	break;
  16.884 +      }
  16.885 +
  16.886 +    default:
  16.887 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  16.888 +      break;
  16.889 +  }
  16.890 +  GST_OBJECT_UNLOCK (mythtvsrc);
  16.891 +done:
  16.892 +  return;
  16.893 +}
  16.894 +
  16.895 +  static void
  16.896 +gst_mythtv_src_get_property (GObject * object, guint prop_id,
  16.897 +    GValue * value, GParamSpec * pspec)
  16.898 +{
  16.899 +  GstMythtvSrc *mythtvsrc = GST_MYTHTV_SRC (object);
  16.900 +
  16.901 +  GST_OBJECT_LOCK (mythtvsrc);
  16.902 +  switch (prop_id) {
  16.903 +    case PROP_URI:
  16.904 +    case PROP_LOCATION:
  16.905 +      {
  16.906 +	gchar *str = g_strdup( "" );
  16.907 +
  16.908 +	if ( mythtvsrc->uri_name == NULL ) {
  16.909 +	  g_free (mythtvsrc->uri_name);
  16.910 +	  mythtvsrc->uri_name = NULL;
  16.911 +	} else {
  16.912 +	  str = g_strdup( mythtvsrc->uri_name );
  16.913 +	}
  16.914 +	g_value_set_string ( value, str );
  16.915 +	break;
  16.916 +      }
  16.917 +#ifndef GST_DISABLE_GST_DEBUG
  16.918 +    case PROP_MYTHTV_DBG:
  16.919 +      g_value_set_boolean ( value, mythtvsrc->mythtv_msgs_dbg );
  16.920 +      break;
  16.921 +#endif
  16.922 +    case PROP_MYTHTV_VERSION:
  16.923 +      {
  16.924 +	g_value_set_int ( value, mythtvsrc->mythtv_version );
  16.925 +	break;
  16.926 +      }
  16.927 +    case PROP_MYTHTV_LIVEID:
  16.928 +      {
  16.929 +	g_value_set_int ( value, mythtvsrc->live_tv_id );
  16.930 +	break;
  16.931 +      }
  16.932 +    case PROP_MYTHTV_LIVE:
  16.933 +      g_value_set_boolean ( value, mythtvsrc->live_tv );
  16.934 +      break;
  16.935 +    case PROP_MYTHTV_LIVE_CHAINID:
  16.936 +      {
  16.937 +	gchar *str = g_strdup( "" );
  16.938 +
  16.939 +	if ( mythtvsrc->live_chain_id == NULL ) {
  16.940 +	  g_free (mythtvsrc->live_chain_id);
  16.941 +	  mythtvsrc->live_chain_id = NULL;
  16.942 +	} else {
  16.943 +	  str = g_strdup( mythtvsrc->live_chain_id );
  16.944 +	}
  16.945 +	g_value_set_string ( value, str );
  16.946 +	break;
  16.947 +      }
  16.948 +    default:
  16.949 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  16.950 +      break;
  16.951 +  }
  16.952 +  GST_OBJECT_UNLOCK (mythtvsrc);
  16.953 +}
  16.954 +
  16.955 +/* entry point to initialize the plug-in
  16.956 + * initialize the plug-in itself
  16.957 + * register the element factories and pad templates
  16.958 + * register the features
  16.959 + */
  16.960 +  static gboolean
  16.961 +plugin_init (GstPlugin * plugin)
  16.962 +{
  16.963 +  return gst_element_register (plugin, "mythtvsrc", GST_RANK_NONE,
  16.964 +      GST_TYPE_MYTHTV_SRC);
  16.965 +}
  16.966 +
  16.967 +/* this is the structure that gst-register looks for
  16.968 + * so keep the name plugin_desc, or you cannot get your plug-in registered */
  16.969 +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
  16.970 +    GST_VERSION_MINOR,
  16.971 +    "mythtv",
  16.972 +    "lib MythTV src",
  16.973 +    plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
  16.974 +
  16.975 +
  16.976 +/*** GSTURIHANDLER INTERFACE *************************************************/
  16.977 +  static guint 
  16.978 +gst_mythtv_src_uri_get_type (void)
  16.979 +{
  16.980 +  return GST_URI_SRC;
  16.981 +}
  16.982 +
  16.983 +  static gchar **
  16.984 +gst_mythtv_src_uri_get_protocols (void)
  16.985 +{
  16.986 +  static gchar *protocols[] = { "myth", "myths", NULL };
  16.987 +
  16.988 +  return protocols;
  16.989 +}
  16.990 +
  16.991 +  static const gchar *
  16.992 +gst_mythtv_src_uri_get_uri (GstURIHandler * handler)
  16.993 +{
  16.994 +  GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
  16.995 +
  16.996 +  return src->uri_name;
  16.997 +}
  16.998 +
  16.999 +  static gboolean
 16.1000 +gst_mythtv_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
 16.1001 +{
 16.1002 +  GstMythtvSrc *src = GST_MYTHTV_SRC (handler);
 16.1003 +
 16.1004 +  gchar *protocol;
 16.1005 +
 16.1006 +  protocol = gst_uri_get_protocol (uri);
 16.1007 +  if ((strcmp (protocol, "myth") != 0) && (strcmp (protocol, "myths") != 0)) {
 16.1008 +    g_free (protocol);
 16.1009 +    return FALSE;
 16.1010 +  }
 16.1011 +  g_free (protocol);
 16.1012 +  g_object_set (src, "location", uri, NULL);
 16.1013 +
 16.1014 +  return TRUE;
 16.1015 +}
 16.1016 +
 16.1017 +  static void
 16.1018 +gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
 16.1019 +{
 16.1020 +  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
 16.1021 +
 16.1022 +  iface->get_type = gst_mythtv_src_uri_get_type;
 16.1023 +  iface->get_protocols = gst_mythtv_src_uri_get_protocols;
 16.1024 +  iface->get_uri = gst_mythtv_src_uri_get_uri;
 16.1025 +  iface->set_uri = gst_mythtv_src_uri_set_uri;
 16.1026 +}
 16.1027 +
 16.1028 +  void
 16.1029 +size_header_handler (void *userdata, const char *value)
 16.1030 +{
 16.1031 +  GstMythtvSrc *src = GST_MYTHTV_SRC (userdata);
 16.1032 +
 16.1033 +  //src->content_size = g_ascii_strtoull (value, NULL, 10);
 16.1034 +
 16.1035 +  GST_DEBUG_OBJECT (src, "content size = %lld bytes", src->content_size);
 16.1036 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.h	Tue Sep 26 15:58:37 2006 +0100
    17.3 @@ -0,0 +1,89 @@
    17.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2 -*- */
    17.5 +/* GStreamer
    17.6 + * Copyright (C) <2006> Rosfran Borges <rosfran.borges@indt.org.br>
    17.7 + *
    17.8 + * This library is free software; you can redistribute it and/or
    17.9 + * modify it under the terms of the GNU Library General Public
   17.10 + * License as published by the Free Software Foundation; either
   17.11 + * version 2 of the License, or (at your option) any later version.
   17.12 + *
   17.13 + * This library is distributed in the hope that it will be useful,
   17.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   17.16 + * Library General Public License for more 
   17.17 + */
   17.18 +
   17.19 +#ifndef __GST_MYTHTV_SRC_H__
   17.20 +#define __GST_MYTHTV_SRC_H__
   17.21 +
   17.22 +#include <gst/gst.h>
   17.23 +#include <gst/base/gstpushsrc.h>
   17.24 +#include <stdio.h>
   17.25 +
   17.26 +#include <gmyth/gmyth_socket.h>
   17.27 +#include "myth_file_transfer.h"
   17.28 +#include "myth_livetv.h"
   17.29 +
   17.30 +G_BEGIN_DECLS
   17.31 +
   17.32 +#define GST_TYPE_MYTHTV_SRC \
   17.33 +  (gst_mythtv_src_get_type())
   17.34 +#define GST_MYTHTV_SRC(obj) \
   17.35 +  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MYTHTV_SRC,GstMythtvSrc))
   17.36 +#define GST_MYTHTV_SRC_CLASS(klass) \
   17.37 +  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MYTHTV_SRC,GstMythtvSrcClass))
   17.38 +#define GST_IS_MYTHTV_SRC(obj) \
   17.39 +  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MYTHTV_SRC))
   17.40 +#define GST_IS_MYTHTV_SRC_CLASS(klass) \
   17.41 +  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MYTHTV_SRC))
   17.42 +
   17.43 +typedef struct _GstMythtvSrc GstMythtvSrc;
   17.44 +typedef struct _GstMythtvSrcClass GstMythtvSrcClass;
   17.45 +
   17.46 +struct _GstMythtvSrc {
   17.47 +  GstBaseSrc element;
   17.48 +
   17.49 +  /* MythFileTransfer */
   17.50 +  MythFileTransfer *file_transfer;
   17.51 +
   17.52 +  MythLiveTV *spawn_livetv;
   17.53 +
   17.54 +  gchar *uri_name;
   17.55 +  gchar *user_agent;
   17.56 +
   17.57 +  gchar *live_chain_id;
   17.58 +  
   17.59 +  gint mythtv_version;
   17.60 +
   17.61 +  guint64 content_size;
   17.62 +
   17.63 +  guint64 bytes_read;
   17.64 +
   17.65 +  guint64 read_offset;
   17.66 +
   17.67 +  gboolean eos;
   17.68 +  
   17.69 +  gboolean do_start;
   17.70 +
   17.71 +  gboolean unique_setup;
   17.72 +
   17.73 +  gboolean live_tv;
   17.74 +
   17.75 +  gint live_tv_id;
   17.76 +
   17.77 +  /* MythTV capabilities */
   17.78 +  GstCaps *mythtv_caps;
   17.79 +
   17.80 +  /* enable Myth TV debug messages */
   17.81 +  gboolean mythtv_msgs_dbg;
   17.82 +};
   17.83 +
   17.84 +struct _GstMythtvSrcClass {
   17.85 +  GstBaseSrcClass parent_class;
   17.86 +};
   17.87 +
   17.88 +GType gst_mythtv_src_get_type (void);
   17.89 +
   17.90 +G_END_DECLS
   17.91 +
   17.92 +#endif /* __GST_MYTHTV_SRC_H__ */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/gst-plugins-mythtv/src/myth_file_transfer.c	Tue Sep 26 15:58:37 2006 +0100
    18.3 @@ -0,0 +1,960 @@
    18.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
    18.5 +/**
    18.6 + * GStreamer plug-in properties:
    18.7 + * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
    18.8 + * - path (qurl - remote file to be opened)
    18.9 + * - port number
   18.10 + *   @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   18.11 + */
   18.12 +
   18.13 +#include "myth_file_transfer.h"
   18.14 +#include "myth_uri.h"
   18.15 +#include "myth_livetv.h"
   18.16 +#include <gmyth/gmyth_util.h>
   18.17 +#include <gmyth/gmyth_socket.h>
   18.18 +#include <gmyth/gmyth_stringlist.h>
   18.19 +
   18.20 +#include <unistd.h>
   18.21 +#include <glib.h>
   18.22 +
   18.23 +#include <arpa/inet.h>
   18.24 +#include <sys/types.h>
   18.25 +#include <sys/socket.h>
   18.26 +#include <netdb.h>
   18.27 +#include <errno.h>
   18.28 +#include <stdlib.h>
   18.29 +
   18.30 +#define MYTHTV_QUERY_HEADER "QUERY_FILETRANSFER"
   18.31 +#define MYTHTV_RECORDER_HEADER "QUERY_RECORDER"
   18.32 +
   18.33 +/* default values to the file transfer parameters */
   18.34 +#define MYTHTV_USER_READ_AHEAD	FALSE
   18.35 +#define MYTHTV_RETRIES			1
   18.36 +#define MYTHTV_FILE_SIZE		-1
   18.37 +
   18.38 +#define MYTHTV_BUFFER_SIZE		2048
   18.39 +
   18.40 +#define MYTHTV_VERSION			30
   18.41 +
   18.42 +#define MYTHTV_TRANSFER_MAX_WAITS	700
   18.43 +
   18.44 +#ifdef MYTHTV_ENABLE_DEBUG
   18.45 +#define MYTHTV_ENABLE_DEBUG	1
   18.46 +#else
   18.47 +#undef MYTHTV_ENABLE_DEBUG
   18.48 +#endif
   18.49 +
   18.50 +/* this NDEBUG is to maintain compatibility with GMyth library */
   18.51 +#ifndef NDEBUG
   18.52 +#define MYTHTV_ENABLE_DEBUG	1
   18.53 +#endif
   18.54 +
   18.55 +static guint wait_to_transfer = 0;
   18.56 +
   18.57 +enum myth_sock_types {
   18.58 +  MYTH_PLAYBACK_TYPE = 0,
   18.59 +  MYTH_MONITOR_TYPE,
   18.60 +  MYTH_FILETRANSFER_TYPE,
   18.61 +  MYTH_RINGBUFFER_TYPE
   18.62 +};
   18.63 +
   18.64 +static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
   18.65 +
   18.66 +static void myth_file_transfer_class_init          (MythFileTransferClass *klass);
   18.67 +static void myth_file_transfer_init                (MythFileTransfer *object);
   18.68 +
   18.69 +static void myth_file_transfer_dispose  (GObject *object);
   18.70 +static void myth_file_transfer_finalize (GObject *object);
   18.71 +
   18.72 +static GMythSocket *myth_connect_to_transfer_backend( MythFileTransfer **transfer, guint sock_type );
   18.73 +static void* myth_init_io_watchers( void *data );
   18.74 +
   18.75 +void myth_file_transfer_close( MythFileTransfer *transfer );
   18.76 +
   18.77 +G_DEFINE_TYPE(MythFileTransfer, myth_file_transfer, G_TYPE_OBJECT)
   18.78 +
   18.79 +static guint64
   18.80 +mmyth_util_decode_long_long( GMythStringList *strlist, guint offset  )
   18.81 +{
   18.82 +
   18.83 +  guint64 ret_value = 0LL;
   18.84 +
   18.85 +  g_return_val_if_fail( strlist != NULL, ret_value );
   18.86 +
   18.87 +  if ( offset < gmyth_string_list_length( strlist ))
   18.88 +    g_printerr( "[%s] Offset is lower than the GMythStringList (offset = %d)!\n", __FUNCTION__, offset );
   18.89 +  g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value );
   18.90 +
   18.91 +  gint l1 = gmyth_string_list_get_int( strlist, offset );
   18.92 +  gint l2 = gmyth_string_list_get_int( strlist, offset + 1 );
   18.93 +
   18.94 +  ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32);
   18.95 +
   18.96 +  return ret_value;
   18.97 +
   18.98 +}
   18.99 +
  18.100 +static void
  18.101 +myth_file_transfer_class_init (MythFileTransferClass *klass)
  18.102 +{
  18.103 +  GObjectClass *gobject_class;
  18.104 +
  18.105 +  gobject_class = (GObjectClass *) klass;
  18.106 +
  18.107 +  gobject_class->dispose  = myth_file_transfer_dispose;
  18.108 +  gobject_class->finalize = myth_file_transfer_finalize;
  18.109 +}
  18.110 +
  18.111 +  static void
  18.112 +myth_file_transfer_init (MythFileTransfer *myth_file_transfer)
  18.113 +{ 
  18.114 +  g_return_if_fail( myth_file_transfer != NULL );
  18.115 +  myth_file_transfer->mythtv_version = MYTHTV_VERSION;
  18.116 +}
  18.117 +
  18.118 +static void
  18.119 +myth_file_transfer_dispose  (GObject *object)
  18.120 +{
  18.121 +  MythFileTransfer *myth_file_transfer = MYTH_FILE_TRANSFER(object);
  18.122 +
  18.123 +  myth_file_transfer_close( myth_file_transfer );
  18.124 +
  18.125 +  G_OBJECT_CLASS (myth_file_transfer_parent_class)->dispose (object);
  18.126 +}
  18.127 +
  18.128 +  static void
  18.129 +myth_file_transfer_finalize (GObject *object)
  18.130 +{
  18.131 +  g_signal_handlers_destroy (object);
  18.132 +
  18.133 +  G_OBJECT_CLASS (myth_file_transfer_parent_class)->finalize (object);
  18.134 +}
  18.135 +
  18.136 +  MythFileTransfer*
  18.137 +myth_file_transfer_new (gint num, GString *uri_str, gshort port, gint mythtv_version)
  18.138 +{
  18.139 +  MythFileTransfer *transfer = MYTH_FILE_TRANSFER ( g_object_new (
  18.140 +	MYTH_FILE_TRANSFER_TYPE, FALSE ));
  18.141 +
  18.142 +  if ( mythtv_version > 0 )
  18.143 +    transfer->mythtv_version = mythtv_version;
  18.144 +
  18.145 +  transfer->card_id = num;
  18.146 +
  18.147 +  transfer->rec_id = -1;
  18.148 +
  18.149 +  transfer->recordernum = 0;
  18.150 +  transfer->uri = myth_uri_new ( uri_str->str );
  18.151 +
  18.152 +  transfer->hostname = g_string_new( myth_uri_gethost(transfer->uri) );
  18.153 +  g_print( "\t--> transfer->hostname = %s\n", transfer->hostname->str );
  18.154 +
  18.155 +  if ( port >= 0 )
  18.156 +    transfer->port = port;
  18.157 +  else
  18.158 +    transfer->port = myth_uri_getport( transfer->uri );
  18.159 +
  18.160 +  g_print( "\t--> transfer->port = %d\n", transfer->port );
  18.161 +
  18.162 +  transfer->readposition = 0;
  18.163 +  transfer->filesize = MYTHTV_FILE_SIZE;
  18.164 +  transfer->timeoutisfast = FALSE;
  18.165 +
  18.166 +  transfer->userreadahead = MYTHTV_USER_READ_AHEAD;
  18.167 +  transfer->retries = MYTHTV_RETRIES;  
  18.168 +
  18.169 +  transfer->live_tv = FALSE;
  18.170 +
  18.171 +  transfer->query = g_string_new( MYTHTV_QUERY_HEADER );
  18.172 +  g_string_append_printf ( transfer->query, " %d", transfer->recordernum );
  18.173 +  g_print( "\t--> transfer->query = %s\n", transfer->query->str );
  18.174 +
  18.175 +  transfer->control_sock = NULL;
  18.176 +  transfer->event_sock = NULL;
  18.177 +  transfer->sock = NULL;
  18.178 +
  18.179 +  return transfer;
  18.180 +}
  18.181 +
  18.182 +gboolean
  18.183 +myth_file_transfer_livetv_setup( MythFileTransfer **transfer, GMythSocket *live_socket )
  18.184 +{
  18.185 +	(*transfer)->sock = live_socket;
  18.186 +	g_object_ref( live_socket );
  18.187 +
  18.188 +	return TRUE;
  18.189 +}
  18.190 +
  18.191 +gboolean
  18.192 +myth_file_transfer_playback_setup( MythFileTransfer **transfer, gboolean live_tv )
  18.193 +{
  18.194 +
  18.195 +  gboolean ret = TRUE;
  18.196 +
  18.197 +  (*transfer)->live_tv = live_tv;
  18.198 +
  18.199 +  printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
  18.200 +
  18.201 +  /* configure the control socket */
  18.202 +  if ((*transfer)->control_sock == NULL) { 
  18.203 +
  18.204 +    if ( myth_connect_to_transfer_backend ( transfer, MYTH_PLAYBACK_TYPE ) == NULL ) {
  18.205 +      g_printerr( "Connection to backend failed (Control Socket).\n" );
  18.206 +      ret = FALSE;
  18.207 +    }
  18.208 +
  18.209 +  } else {
  18.210 +    g_warning("Remote transfer control socket already created.\n");
  18.211 +  }
  18.212 +
  18.213 +  return ret;
  18.214 +
  18.215 +}
  18.216 +
  18.217 +gboolean
  18.218 +myth_file_transfer_setup( MythFileTransfer **transfer, gboolean live_tv )
  18.219 +{
  18.220 +  GMythStringList *strlist = NULL;
  18.221 +
  18.222 +  gboolean ret = TRUE;
  18.223 +
  18.224 +  (*transfer)->live_tv = live_tv;
  18.225 +
  18.226 +  printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" );
  18.227 +
  18.228 +#if 0
  18.229 +  /* configure the event socket */
  18.230 +  if ((*transfer)->event_sock == NULL) { 
  18.231 +
  18.232 +    if ( myth_connect_to_transfer_backend ( transfer, MYTH_MONITOR_TYPE ) == NULL ) {
  18.233 +      g_printerr( "Connection to backend failed (Event Socket).\n" );
  18.234 +      ret = FALSE;
  18.235 +    }
  18.236 +
  18.237 +  } else {
  18.238 +    g_warning("Remote transfer control socket already created.\n");
  18.239 +  }
  18.240 +#endif
  18.241 +
  18.242 +  /* configure the socket */
  18.243 +  if ( (*transfer)->sock == NULL ) { 
  18.244 +
  18.245 +    //if ( live_tv == FALSE ) {
  18.246 +
  18.247 +    if ( myth_connect_to_transfer_backend ( transfer, MYTH_FILETRANSFER_TYPE ) == NULL ) {
  18.248 +      g_printerr ("Connection to backend failed (Raw Transfer Socket).\n");
  18.249 +      ret = FALSE;
  18.250 +    }
  18.251 +
  18.252 +    if ( !(*transfer)->live_tv && (*transfer)->control_sock != NULL) {
  18.253 +      strlist = gmyth_string_list_new();
  18.254 +      g_string_printf ( (*transfer)->query, "%s %d", MYTHTV_QUERY_HEADER, (*transfer)->recordernum );
  18.255 +
  18.256 +      gmyth_string_list_append_string( strlist, (*transfer)->query );
  18.257 +      gmyth_string_list_append_char_array( strlist, "IS_OPEN" );
  18.258 +
  18.259 +      gmyth_socket_write_stringlist( (*transfer)->control_sock, strlist );
  18.260 +      gmyth_socket_read_stringlist( (*transfer)->control_sock, strlist );
  18.261 +
  18.262 +      if ( strlist!=NULL && gmyth_string_list_get_int( strlist, 0 ) == 1 ) {
  18.263 +	g_print( "[%s] Remote Myth FileTransfer socket is open!\n", __FUNCTION__ );
  18.264 +      } else {
  18.265 +	g_print( "[%s] Remote Myth FileTransfer socket is CLOSED! See the MythTV Server Backend for configuration details...\n", __FUNCTION__ );
  18.266 +	ret = FALSE;
  18.267 +      }
  18.268 +    }
  18.269 +
  18.270 +  } else {
  18.271 +    g_warning("Remote transfer (raw) socket already created.\n");
  18.272 +  }
  18.273 +
  18.274 +  return ret;
  18.275 +}
  18.276 +
  18.277 +static GMythSocket *
  18.278 +myth_connect_to_transfer_backend( MythFileTransfer **transfer, guint sock_type )
  18.279 +{
  18.280 +  GMythSocket *sock = NULL;
  18.281 +
  18.282 +  g_return_val_if_fail( transfer != NULL && *transfer != NULL, NULL );
  18.283 +  g_return_val_if_fail( (*transfer)->uri != NULL, NULL );
  18.284 +
  18.285 +  g_static_mutex_lock (&mutex);
  18.286 +
  18.287 +  gchar *path_dir = myth_uri_getpath( (*transfer)->uri );
  18.288 +  //g_print( "\t--> %s: path_dir = %s\n", __FUNCTION__, path_dir );
  18.289 +
  18.290 +  gchar *stype = g_strdup( "" );
  18.291 +
  18.292 +  //  if ( (*transfer)->live_tv == FALSE ) {
  18.293 +
  18.294 +  sock = gmyth_socket_new();
  18.295 +
  18.296 +  gmyth_socket_connect( &sock, (*transfer)->hostname->str, (*transfer)->port );
  18.297 +
  18.298 +  /*
  18.299 +     } else {
  18.300 +     sock = (*transfer)->sock;
  18.301 +     }
  18.302 +     */
  18.303 +#ifdef MYTHTV_ENABLE_DEBUG
  18.304 +
  18.305 +  g_print( "[%s] --> Creating socket... (%s, %d)\n", __FUNCTION__, (*transfer)->hostname->str, (*transfer)->port );
  18.306 +#endif
  18.307 +
  18.308 +  GMythStringList *strlist = NULL;
  18.309 +
  18.310 +  GString *hostname = g_string_new( myth_uri_gethost( (*transfer)->uri ) );
  18.311 +  GString *base_str = g_string_new( "" );
  18.312 +
  18.313 +  if ( gmyth_socket_check_protocol_version_number (sock, (*transfer)->mythtv_version) ) {
  18.314 +
  18.315 +    if (sock == NULL) {
  18.316 +      stype = (sock_type==MYTH_PLAYBACK_TYPE) ? "control socket" : "file data socket";
  18.317 +      g_printerr( "FileTransfer, open_socket(%s): \n"
  18.318 +	  "\t\t\tCould not connect to server \"%s\" @ port %d\n", stype, 
  18.319 +	  (*transfer)->hostname->str, (*transfer)->port );
  18.320 +      g_object_unref(sock);
  18.321 +      g_static_mutex_unlock (&mutex);
  18.322 +      return NULL;
  18.323 +    }
  18.324 +
  18.325 +    hostname = gmyth_socket_get_local_hostname();
  18.326 +
  18.327 +    g_print( "[%s] local hostname = %s\n", __FUNCTION__, hostname->str  );
  18.328 +
  18.329 +    if ( sock_type == MYTH_PLAYBACK_TYPE )
  18.330 +    {
  18.331 +      (*transfer)->control_sock = sock;
  18.332 +      g_string_printf( base_str, "ANN Playback %s %d", hostname->str, FALSE );
  18.333 +
  18.334 +      gmyth_socket_send_command( (*transfer)->control_sock, base_str );
  18.335 +      GString *resp = gmyth_socket_receive_response( (*transfer)->control_sock );
  18.336 +      g_print( "[%s] Got Playback response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
  18.337 +    }
  18.338 +    else if ( sock_type == MYTH_MONITOR_TYPE )
  18.339 +    {
  18.340 +      (*transfer)->event_sock = sock;
  18.341 +      g_string_printf( base_str, "ANN Monitor %s %d", hostname->str, TRUE );
  18.342 +
  18.343 +      gmyth_socket_send_command( (*transfer)->event_sock, base_str );
  18.344 +      GString *resp = gmyth_socket_receive_response( (*transfer)->event_sock );
  18.345 +      g_print( "[%s] Got Monitor response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
  18.346 +      g_thread_create( myth_init_io_watchers, (void*)(*transfer), FALSE, NULL );
  18.347 +
  18.348 +      g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
  18.349 +
  18.350 +    }
  18.351 +    else if ( sock_type == MYTH_FILETRANSFER_TYPE )
  18.352 +    {
  18.353 +      (*transfer)->sock = sock;
  18.354 +      strlist = gmyth_string_list_new();
  18.355 +      //g_string_printf( base_str, "ANN FileTransfer %s %d %d", hostname->str,
  18.356 +      //  		transfer->userreadahead, transfer->retries );
  18.357 +      g_string_printf( base_str, "ANN FileTransfer %s", hostname->str );
  18.358 +
  18.359 +      gmyth_string_list_append_string( strlist, base_str );
  18.360 +      gmyth_string_list_append_char_array( strlist, path_dir );
  18.361 +
  18.362 +      gmyth_socket_write_stringlist( (*transfer)->sock, strlist );
  18.363 +      gmyth_socket_read_stringlist( (*transfer)->sock, strlist );
  18.364 +
  18.365 +      /* socket number, where all the stream data comes from - got from the MythTV remote backend */
  18.366 +      (*transfer)->recordernum = gmyth_string_list_get_int( strlist, 1 );
  18.367 +
  18.368 +      /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */
  18.369 +      (*transfer)->filesize = mmyth_util_decode_long_long( strlist, 2 );
  18.370 +
  18.371 +      printf( "[%s] ***** Received: recordernum = %d, filesize = %" G_GUINT64_FORMAT "\n", __FUNCTION__,
  18.372 +	  (*transfer)->recordernum, (*transfer)->filesize );
  18.373 +
  18.374 +      if ( (*transfer)->filesize <= 0 ) {
  18.375 +	g_print( "[%s] Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", __FUNCTION__, (*transfer)->filesize );
  18.376 +	g_object_unref(sock);
  18.377 +	sock = NULL; 
  18.378 +      }
  18.379 +    }
  18.380 +    else if ( sock_type == MYTH_RINGBUFFER_TYPE )
  18.381 +    {
  18.382 +      (*transfer)->sock = sock;
  18.383 +      //myth_file_transfer_spawntv( (*transfer), NULL );      
  18.384 +
  18.385 +      strlist = gmyth_string_list_new();
  18.386 +      g_string_printf( base_str, "ANN RingBuffer %s %d", hostname->str, (*transfer)->card_id );
  18.387 +
  18.388 +      gmyth_socket_send_command( (*transfer)->sock, base_str );
  18.389 +      GString *resp = gmyth_socket_receive_response( (*transfer)->sock );
  18.390 +      g_print( "[%s] Got RingBuffer response from %s: %s\n", __FUNCTION__, base_str->str, resp->str );
  18.391 +
  18.392 +    }
  18.393 +
  18.394 +  }
  18.395 +
  18.396 +  printf("[%s] ANN %s sent: %s\n", (sock_type==MYTH_PLAYBACK_TYPE) ? "Playback" : (sock_type==MYTH_FILETRANSFER_TYPE) ? "FileTransfer" : "Monitor", __FUNCTION__, base_str->str);
  18.397 +
  18.398 +  if ( strlist != NULL )
  18.399 +    g_object_unref( strlist );
  18.400 +
  18.401 +  g_static_mutex_unlock (&mutex);
  18.402 +
  18.403 +  return sock;
  18.404 +}    
  18.405 +
  18.406 +void
  18.407 +myth_file_transfer_spawntv ( MythFileTransfer *file_transfer, 
  18.408 +    GString *tvchain_id )
  18.409 +{
  18.410 +  GMythStringList *str_list;
  18.411 +
  18.412 +  g_debug ("myth_file_transfer_spawntv.\n");
  18.413 +
  18.414 +  str_list = gmyth_string_list_new ();
  18.415 +
  18.416 +  g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER, 
  18.417 +      file_transfer->card_id );
  18.418 +  gmyth_string_list_append_string (str_list, file_transfer->query);
  18.419 +  gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV"));
  18.420 +  if (tvchain_id!=NULL) {
  18.421 +    gmyth_string_list_append_string (str_list, tvchain_id);
  18.422 +    gmyth_string_list_append_int (str_list, FALSE); // PIP = FALSE (0)
  18.423 +  }
  18.424 +
  18.425 +  gmyth_socket_sendreceive_stringlist ( file_transfer->sock, str_list );
  18.426 +
  18.427 +  //GString *str = NULL;
  18.428 +
  18.429 +  //if (str_list!=NULL && (str = gmyth_string_list_get_string( str_list, 0 )) != NULL && strcasecmp( str->str, "ok" ) != 0 ) {
  18.430 +  //  g_print( "[%s]\t\tSpawnLiveTV is OK!\n", __FUNCTION__ );
  18.431 +  //}
  18.432 +  if (str_list!=NULL)
  18.433 +    g_object_unref (str_list);
  18.434 +
  18.435 +}
  18.436 +
  18.437 +gboolean
  18.438 +myth_file_transfer_is_recording ( MythFileTransfer *file_transfer )
  18.439 +{
  18.440 +  gboolean ret = TRUE;
  18.441 +  
  18.442 +  GMythStringList *str_list = gmyth_string_list_new ();
  18.443 +
  18.444 +  g_debug ( "[%s]\n", __FUNCTION__ );
  18.445 +  g_static_mutex_lock (&mutex);
  18.446 +
  18.447 +  g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER, 
  18.448 +      file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id );
  18.449 +  gmyth_string_list_append_string (str_list, file_transfer->query);
  18.450 +  gmyth_string_list_append_string (str_list, g_string_new ("IS_RECORDING"));
  18.451 +
  18.452 +  gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list );
  18.453 +
  18.454 +  if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 ) 
  18.455 +  {
  18.456 +    GString *str = NULL;
  18.457 +    if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp( str->str, "bad" )!= 0 ) {
  18.458 +      gint is_rec = gmyth_string_list_get_int( str_list, 0 );
  18.459 +      if ( is_rec != 0 )
  18.460 +	ret = TRUE;
  18.461 +      else
  18.462 +	ret = FALSE;
  18.463 +    }
  18.464 +  }  
  18.465 +  g_print( "[%s] %s, stream is %s being recorded!\n", __FUNCTION__, ret ? "YES" : "NO", ret ? "" : "NOT" );
  18.466 +  g_static_mutex_unlock (&mutex);
  18.467 +
  18.468 +  if ( str_list != NULL )
  18.469 +    g_object_unref (str_list);
  18.470 +
  18.471 +  return ret;
  18.472 +
  18.473 +}
  18.474 +
  18.475 +guint64
  18.476 +myth_file_transfer_get_file_position ( MythFileTransfer *file_transfer )
  18.477 +{
  18.478 +  guint64 pos = 0;
  18.479 +
  18.480 +  GMythStringList *str_list = gmyth_string_list_new ();
  18.481 +
  18.482 +  g_debug ( "[%s]\n", __FUNCTION__ );
  18.483 +  g_static_mutex_lock (&mutex);
  18.484 +
  18.485 +  g_string_printf( file_transfer->query, "%s %d", MYTHTV_RECORDER_HEADER, 
  18.486 +      file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id );
  18.487 +
  18.488 +  gmyth_string_list_append_string (str_list, file_transfer->query);
  18.489 +  gmyth_string_list_append_string (str_list, g_string_new ("GET_FILE_POSITION"));
  18.490 +
  18.491 +  gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list );
  18.492 +
  18.493 +  if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 ) 
  18.494 +  {
  18.495 +    GString *str = NULL;
  18.496 +    if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strcmp ( str->str, "bad" ) != 0 )
  18.497 +      pos = gmyth_util_decode_long_long( str_list, 0 );
  18.498 +  } 
  18.499 +  g_static_mutex_unlock (&mutex);
  18.500 +
  18.501 +#ifndef MYTHTV_ENABLE_DEBUG
  18.502 +
  18.503 +  g_print( "[%s] Got file position = %llu\n", __FUNCTION__, pos );
  18.504 +#endif
  18.505 +  if (str_list!=NULL)
  18.506 +    g_object_unref (str_list);
  18.507 +
  18.508 +  return pos;
  18.509 +
  18.510 +}
  18.511 +
  18.512 +  glong
  18.513 +myth_file_transfer_get_recordernum( MythFileTransfer *transfer )
  18.514 +{
  18.515 +  return transfer->recordernum;
  18.516 +}
  18.517 +
  18.518 +  glong
  18.519 +myth_file_transfer_get_filesize( MythFileTransfer *transfer )
  18.520 +{
  18.521 +  return transfer->filesize;
  18.522 +}
  18.523 +
  18.524 +  gboolean
  18.525 +myth_file_transfer_isopen( MythFileTransfer *transfer )
  18.526 +{
  18.527 +  return (transfer->sock != NULL && transfer->control_sock != NULL);
  18.528 +}
  18.529 +
  18.530 +  void
  18.531 +myth_file_transfer_close( MythFileTransfer *transfer )
  18.532 +{
  18.533 +  GMythStringList *strlist;
  18.534 +
  18.535 +  if (transfer->control_sock == NULL)
  18.536 +    return;
  18.537 +
  18.538 +  strlist = gmyth_string_list_new( );
  18.539 +
  18.540 +  g_string_printf( transfer->query, "%s %d", MYTHTV_QUERY_HEADER, 
  18.541 +      transfer->recordernum );
  18.542 +  gmyth_string_list_append_string( strlist, transfer->query );
  18.543 +  gmyth_string_list_append_char_array( strlist, "DONE" );
  18.544 +
  18.545 +
  18.546 +  if ( gmyth_socket_sendreceive_stringlist(transfer->control_sock, strlist) <= 0 )
  18.547 +  {
  18.548 +    g_printerr( "Remote file timeout.\n" );
  18.549 +  }
  18.550 +
  18.551 +  if (transfer->sock)
  18.552 +  {
  18.553 +    g_object_unref( transfer->sock );
  18.554 +    transfer->sock = NULL;
  18.555 +  }
  18.556 +
  18.557 +  if (transfer->control_sock)
  18.558 +  {
  18.559 +    g_object_unref( transfer->control_sock );
  18.560 +    transfer->control_sock = NULL;
  18.561 +  } 
  18.562 +
  18.563 +}
  18.564 +
  18.565 +  void
  18.566 +myth_file_transfer_reset_controlsock( MythFileTransfer *transfer )
  18.567 +{
  18.568 +  if (transfer->control_sock == NULL)
  18.569 +  {
  18.570 +    g_printerr( "myth_file_transfer_reset_controlsock(): Called with no control socket" );
  18.571 +    return;
  18.572 +  }
  18.573 +
  18.574 +  GString *str = gmyth_socket_receive_response( transfer->control_sock );
  18.575 +
  18.576 +  g_string_free( str, TRUE );
  18.577 +}
  18.578 +
  18.579 +void
  18.580 +myth_file_transfer_reset_sock( MythFileTransfer *transfer )
  18.581 +{
  18.582 +  if ( transfer->sock == NULL )
  18.583 +  {
  18.584 +    g_printerr( "myth_file_transfer_reset_sock(): Called with no raw socket" );
  18.585 +    return;
  18.586 +  }
  18.587 +
  18.588 +  GString *str = gmyth_socket_receive_response( transfer->sock );
  18.589 +
  18.590 +  g_string_free( str, TRUE );
  18.591 +}
  18.592 +
  18.593 +void
  18.594 +myth_file_transfer_reset( MythFileTransfer *transfer )
  18.595 +{
  18.596 +  myth_file_transfer_reset_controlsock( transfer );
  18.597 +  myth_file_transfer_reset_sock( transfer );
  18.598 +}
  18.599 +
  18.600 +guint64
  18.601 +myth_file_transfer_seek(MythFileTransfer *transfer, guint64 pos, gint whence)
  18.602 +{
  18.603 +  if (transfer->sock == NULL)
  18.604 +  {
  18.605 +    g_printerr( "[%s] myth_file_transfer_seek(): Called with no socket", __FUNCTION__ );
  18.606 +    return 0;
  18.607 +  }
  18.608 +
  18.609 +  if (transfer->control_sock == NULL)
  18.610 +    return 0;
  18.611 +
  18.612 +  // if (!controlSock->isOpen() || controlSock->error())
  18.613 +  //   return 0;
  18.614 +
  18.615 +  GMythStringList *strlist = gmyth_string_list_new();
  18.616 +  g_string_printf (transfer->query, "%s %d", MYTHTV_QUERY_HEADER, transfer->recordernum);
  18.617 +  gmyth_string_list_append_string( strlist, transfer->query );  
  18.618 +  gmyth_string_list_append_char_array( strlist, "SEEK" );
  18.619 +  gmyth_string_list_append_uint64( strlist, pos );
  18.620 +  //  gmyth_string_list_append_int( strlist, whence );
  18.621 +
  18.622 +  if (pos > 0 )
  18.623 +    gmyth_string_list_append_uint64( strlist, pos );
  18.624 +  else
  18.625 +    gmyth_string_list_append_uint64( strlist, transfer->readposition );
  18.626 +
  18.627 +  gmyth_socket_sendreceive_stringlist( transfer->control_sock, strlist );
  18.628 +
  18.629 +  guint64 retval = gmyth_string_list_get_uint64(strlist, 0);
  18.630 +  transfer->readposition = retval;
  18.631 +  g_print( "[%s] got reading position pointer from the streaming = %llu\n", 
  18.632 +      __FUNCTION__, retval );
  18.633 +
  18.634 +  //myth_file_transfer_reset( transfer );
  18.635 +
  18.636 +  return retval;
  18.637 +}
  18.638 +
  18.639 +static gboolean
  18.640 +myth_control_sock_listener( GIOChannel *source, GIOCondition condition, gpointer data )
  18.641 +{
  18.642 +
  18.643 +  GIOStatus ret;
  18.644 +  GError *err = NULL;
  18.645 +  gchar *msg = g_strdup("");
  18.646 +
  18.647 +  gsize len;
  18.648 +  if (condition & G_IO_HUP)
  18.649 +    g_error ("Read end of pipe died!\n");
  18.650 +  ret = g_io_channel_read_line ( source, &msg, &len, NULL, &err);
  18.651 +  if ( ret == G_IO_STATUS_ERROR )
  18.652 +    g_error ("[%s] Error reading: %s\n", __FUNCTION__, err != NULL ? err->message : "" );
  18.653 +  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 : "" );
  18.654 +  if ( msg != NULL )
  18.655 +    g_free (msg);
  18.656 +
  18.657 +  return TRUE;
  18.658 +
  18.659 +}
  18.660 +
  18.661 +static void*
  18.662 +myth_init_io_watchers( void *data )
  18.663 +{
  18.664 +  MythFileTransfer *transfer = (MythFileTransfer*)data;
  18.665 +  GMainContext *context = g_main_context_new();
  18.666 +  GMainLoop *loop = g_main_loop_new( NULL, FALSE );
  18.667 +
  18.668 +  GSource *source = NULL;
  18.669 +
  18.670 +  if ( transfer->event_sock->sd_io_ch != NULL )
  18.671 +    source = g_io_create_watch( transfer->event_sock->sd_io_ch, G_IO_IN | G_IO_HUP );
  18.672 +
  18.673 +  g_source_set_callback ( source, (GSourceFunc)myth_control_sock_listener, NULL, NULL );
  18.674 +
  18.675 +  g_source_attach( source, context );
  18.676 +
  18.677 +  if (source==NULL)
  18.678 +    g_printerr( "[%s] Error adding watch listener function to the IO control channel!\n", __FUNCTION__ );
  18.679 +
  18.680 +  g_main_loop_run( loop );
  18.681 +
  18.682 +  g_source_unref( source );
  18.683 +
  18.684 +  g_main_loop_unref( loop );
  18.685 +
  18.686 +  g_main_context_unref( context );
  18.687 +
  18.688 +  return NULL;
  18.689 +}
  18.690 +
  18.691 +  gint 
  18.692 +myth_file_transfer_read(MythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited)
  18.693 +{
  18.694 +  gint recv = 0;
  18.695 +  gsize bytes_read = 0;
  18.696 +
  18.697 +  gint sent = 0;
  18.698 +  //guint zerocnt = 0;
  18.699 +  gboolean response = FALSE;
  18.700 +
  18.701 +  GIOChannel *io_channel;
  18.702 +  GIOChannel *io_channel_control;
  18.703 +
  18.704 +  GIOCondition io_cond;
  18.705 +  GIOCondition io_cond_control;
  18.706 +  GIOStatus io_status = G_IO_STATUS_NORMAL, io_status_control = G_IO_STATUS_NORMAL;   
  18.707 +
  18.708 +  gint buf_len = MYTHTV_BUFFER_SIZE;
  18.709 +
  18.710 +  GMythStringList *strlist = NULL;
  18.711 +  GError *error = NULL;
  18.712 +
  18.713 +  gchar *trash = g_strdup("");
  18.714 +
  18.715 +  g_return_val_if_fail ( data != NULL, -2 );
  18.716 +
  18.717 +  /* gets the size of the entire file, if the size requested is lesser than 0 */
  18.718 +  if ( size <= 0 )
  18.719 +    size = transfer->filesize;
  18.720 +
  18.721 +  io_channel = transfer->sock->sd_io_ch;
  18.722 +  io_channel_control = transfer->control_sock->sd_io_ch;
  18.723 +
  18.724 +  //g_io_channel_set_flags( io_channel, G_IO_FLAG_APPEND | 
  18.725 +  //    G_IO_STATUS_AGAIN | G_IO_FLAG_IS_READABLE | G_IO_FLAG_IS_WRITEABLE | 
  18.726 +  //    G_IO_FLAG_IS_SEEKABLE, NULL );
  18.727 +
  18.728 +  io_status = g_io_channel_set_encoding( io_channel, NULL, &error );
  18.729 +  if ( io_status == G_IO_STATUS_NORMAL )
  18.730 +    g_print( "[%s] Setting encoding to binary data socket).\n", __FUNCTION__ );
  18.731 +
  18.732 +  io_cond = g_io_channel_get_buffer_condition( io_channel );  
  18.733 +
  18.734 +  io_cond_control = g_io_channel_get_buffer_condition( io_channel );
  18.735 +
  18.736 +  if ( transfer->sock == NULL || ( io_status == G_IO_STATUS_ERROR ) )
  18.737 +  {
  18.738 +    g_printerr( "myth_file_transfer_read(): Called with no raw socket.\n" );
  18.739 +    recv = -1;
  18.740 +    goto cleanup;
  18.741 +  }
  18.742 +
  18.743 +  if ( transfer->control_sock == NULL || ( io_status_control == G_IO_STATUS_ERROR ) )
  18.744 +  {
  18.745 +    g_printerr( "myth_file_transfer_read(): Called with no control socket.\n" );
  18.746 +    recv = -1;
  18.747 +    goto cleanup;
  18.748 +  }
  18.749 +
  18.750 +  /*
  18.751 +     if (!controlSock->isOpen() || controlSock->error())
  18.752 +     return -1;
  18.753 +     */
  18.754 +
  18.755 +  if ( ( io_cond & G_IO_IN ) != 0 ) {
  18.756 +    do 
  18.757 +    {
  18.758 +
  18.759 +      io_status = g_io_channel_read_line( io_channel, &trash, &bytes_read, NULL, &error);
  18.760 +
  18.761 +      g_print( "[%s] cleaning buffer on IO binary channel... (%s)\n", __FUNCTION__, trash );
  18.762 +      io_cond = g_io_channel_get_buffer_condition( io_channel );
  18.763 +
  18.764 +    } while ( ( io_cond & G_IO_IN ) != 0 && ( io_status != G_IO_STATUS_ERROR ) );
  18.765 +
  18.766 +    if ( trash!= NULL )
  18.767 +      g_free( trash );
  18.768 +  }
  18.769 +
  18.770 +  if ( ( io_cond_control & G_IO_IN ) != 0 ) {
  18.771 +    GMythStringList *strlist_tmp = gmyth_string_list_new();
  18.772 +    gmyth_socket_read_stringlist( transfer->control_sock, strlist_tmp );
  18.773 +    g_object_unref( strlist_tmp );
  18.774 +  }
  18.775 +
  18.776 +  wait_to_transfer = 0;
  18.777 +
  18.778 +  while ( transfer->live_tv && ( myth_file_transfer_get_file_position( transfer ) < 4096 ) &&
  18.779 +  		wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS )
  18.780 +  	g_usleep( 1000*50 ); /* waits just for 2/10 second */
  18.781 +
  18.782 +  //g_thread_create( myth_init_io_watchers, (void*)transfer, FALSE, NULL );
  18.783 +  //g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() );
  18.784 +
  18.785 +  g_static_mutex_lock (&mutex);
  18.786 +  strlist = gmyth_string_list_new();
  18.787 +
  18.788 +  g_string_printf ( transfer->query, "%s %d", /*transfer->live_tv ? MYTHTV_RECORDER_HEADER :*/  MYTHTV_QUERY_HEADER, 
  18.789 +      /* transfer->live_tv ? transfer->card_id :*/ transfer->recordernum ); // transfer->recordernum
  18.790 +  g_print( "\t[%s] Transfer_query = %s\n", __FUNCTION__, transfer->query->str );
  18.791 +  strlist = gmyth_string_list_new();
  18.792 +
  18.793 +  gmyth_string_list_append_string( strlist, transfer->query );
  18.794 +  gmyth_string_list_append_char_array( strlist, /*transfer->live_tv ? "REQUEST_BLOCK_RINGBUF" :*/ "REQUEST_BLOCK" );
  18.795 +  gmyth_string_list_append_int( strlist, size );
  18.796 +
  18.797 +  gmyth_socket_write_stringlist( transfer->control_sock, strlist );
  18.798 +  sent = size;
  18.799 +
  18.800 +  //data = (void*)g_new0( gchar, size );
  18.801 +
  18.802 +  g_io_channel_flush( io_channel_control, NULL );
  18.803 +//  g_io_channel_flush( io_channel, NULL );
  18.804 +
  18.805 +  io_cond = g_io_channel_get_buffer_condition( io_channel );
  18.806 +
  18.807 +  while ( ( recv < sent ) )//&& ( io_cond & G_IO_IN ) != 0 )
  18.808 +  {
  18.809 +    do
  18.810 +    {
  18.811 +      //while ( ( io_cond & G_IO_IN ) == 0 ) {
  18.812 +      //usleep(200);
  18.813 +      //
  18.814 +      //io_cond = g_io_channel_get_buffer_condition( io_channel );
  18.815 +      //
  18.816 +
  18.817 +      buf_len = ( sent - recv ) > MYTHTV_BUFFER_SIZE ? MYTHTV_BUFFER_SIZE : ( sent - recv );
  18.818 +
  18.819 +      io_status = g_io_channel_read_chars( io_channel, data + recv, 
  18.820 +	  buf_len, &bytes_read, &error );
  18.821 +      /*
  18.822 +	 GString *sss = g_string_new("");
  18.823 +	 sss = g_string_append_len( sss, (gchar*)data+recv, bytes_read );
  18.824 +
  18.825 +	 g_print( "[%s] Reading buffer (length = %d)\n", __FUNCTION__, bytes_read);
  18.826 +	 */
  18.827 +      if ( bytes_read > 0 )
  18.828 +      {
  18.829 +	if ( bytes_read <= buf_len )
  18.830 +	  recv += bytes_read;
  18.831 +      } 
  18.832 +
  18.833 +      if ( io_status == G_IO_STATUS_EOF ) {
  18.834 +	g_printerr( "[%s] got EOS!", __FUNCTION__ );
  18.835 +	break;
  18.836 +      } else if ( io_status == G_IO_STATUS_ERROR ) {
  18.837 +	g_printerr( "[%s] myth_file_transfer_read(): socket error.\n", __FUNCTION__ );
  18.838 +	break;
  18.839 +      }
  18.840 +
  18.841 +      /* increase buffer size, to allow get more data (do not obey to the buffer size) */
  18.842 +      if ( read_unlimited == TRUE ) {
  18.843 +	//if ( recv > buf_len )
  18.844 +	// sent += (bytes_read - buf_len) + 1;
  18.845 +      }
  18.846 +      if ( bytes_read == buf_len )
  18.847 +	break;
  18.848 +
  18.849 +      /* verify if the input (read) buffer is ready to receive data */
  18.850 +      io_cond = g_io_channel_get_buffer_condition( io_channel );
  18.851 +
  18.852 +      g_print( "[%s]\t io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, 
  18.853 +      		( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
  18.854 +
  18.855 +    } while ( recv < sent && ( ( io_cond & G_IO_IN ) != 0 ) && ( io_status == G_IO_STATUS_NORMAL ) );
  18.856 +
  18.857 +    io_cond_control = g_io_channel_get_buffer_condition( io_channel_control );
  18.858 +    if ( ( io_status == G_IO_STATUS_EOF ) || ( ( io_cond_control & G_IO_IN ) != 0 ) )
  18.859 +    {
  18.860 +      gmyth_socket_read_stringlist( transfer->control_sock, strlist );
  18.861 +      sent = gmyth_string_list_get_int( strlist,  0 ); // -1 on backend error      
  18.862 +      g_print( "[%s]\t sent = %d, io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, 
  18.863 +	  sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
  18.864 +      response = TRUE;
  18.865 +    }
  18.866 +  }
  18.867 +
  18.868 +  if ( ( ( error == NULL ) && ( response == FALSE ) ) || 
  18.869 +  		( io_status == G_IO_STATUS_EOF ) || ( ( io_cond & G_IO_IN ) == 0 ) )
  18.870 +  {
  18.871 +    if ( gmyth_socket_read_stringlist( transfer->control_sock, strlist ) > 0 )
  18.872 +    {
  18.873 +      if ( strlist != NULL && gmyth_string_list_length(strlist) > 0 ) {
  18.874 +	sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error
  18.875 +	g_print( "[%s]\t sent = %d, io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, 
  18.876 +	    sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" );
  18.877 +      }
  18.878 +    }
  18.879 +    else
  18.880 +    {
  18.881 +      g_printerr ( "myth_file_transfer_read(): No response from control socket.");
  18.882 +      sent = -1;
  18.883 +    }
  18.884 +
  18.885 +    if ( error!=NULL ) {
  18.886 +      g_printerr( "[%s] Error occurred: (%d, %s)\n", __FUNCTION__, error->code, error->message );
  18.887 +      g_error_free( error );
  18.888 +    }
  18.889 +  }
  18.890 +
  18.891 +cleanup:
  18.892 +
  18.893 +  if ( trash != NULL )
  18.894 +    g_free( trash );
  18.895 +
  18.896 +  if ( strlist != NULL )
  18.897 +    g_object_unref( strlist );
  18.898 +
  18.899 +  g_static_mutex_unlock (&mutex);
  18.900 +  g_print( "myth_file_transfer_read(): reqd=%d, rcvd=%d, rept=%d, "\
  18.901 +      "(rcvd and rept MUST be the same!)\n", size, 
  18.902 +      recv, sent );
  18.903 +
  18.904 +  //if ( sent != recv ) {
  18.905 +  //  recv = -1;
  18.906 +  //}
  18.907 +
  18.908 +  if ( error != NULL )
  18.909 +    g_printerr( "ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message, 
  18.910 +	error->code );
  18.911 +
  18.912 +  return recv;
  18.913 +}
  18.914 +
  18.915 +  void 
  18.916 +myth_file_transfer_settimeout( MythFileTransfer *transfer, gboolean fast )
  18.917 +{
  18.918 +
  18.919 +  GMythStringList *strlist = NULL;
  18.920 +
  18.921 +  if ( transfer->timeoutisfast == fast )
  18.922 +    return;
  18.923 +
  18.924 +  if ( transfer->sock == NULL )
  18.925 +  {
  18.926 +    g_printerr( "myth_file_transfer_settimeout(): Called with no socket" );
  18.927 +    return;
  18.928 +  }
  18.929 +
  18.930 +  if ( transfer->control_sock == NULL )
  18.931 +    return;
  18.932 +
  18.933 +  strlist = gmyth_string_list_new(); 
  18.934 +  gmyth_string_list_append_string( strlist, transfer->query );
  18.935 +  gmyth_string_list_append_char_array( strlist, "SET_TIMEOUT" );
  18.936 +  gmyth_string_list_append_int( strlist, fast ); 
  18.937 +
  18.938 +  gmyth_socket_write_stringlist( transfer->control_sock, strlist );
  18.939 +  gmyth_socket_read_stringlist( transfer->control_sock, strlist );
  18.940 +
  18.941 +  transfer->timeoutisfast = fast;
  18.942 +
  18.943 +}
  18.944 +
  18.945 +#ifdef DO_TESTING
  18.946 +
  18.947 +  int
  18.948 +main( int argc, char *argv[] )
  18.949 +{
  18.950 +  g_type_init();
  18.951 +
  18.952 +  MythFileTransfer *file_transfer = myth_file_transfer_new( 1, 
  18.953 +      g_string_new("myth://192.168.1.109:6543/jshks.nuv"), -1, MYTHTV_VERSION );
  18.954 +  myth_file_transfer_setup( &file_transfer );
  18.955 +  gchar *data = g_strdup("");
  18.956 +
  18.957 +  gint num = myth_file_transfer_read( file_transfer, data, -1 );
  18.958 +
  18.959 +  return 0;
  18.960 +
  18.961 +}
  18.962 +
  18.963 +#endif
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/gst-plugins-mythtv/src/myth_file_transfer.h	Tue Sep 26 15:58:37 2006 +0100
    19.3 @@ -0,0 +1,93 @@
    19.4 +/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2-*- */
    19.5 +
    19.6 +#ifndef __MYTH_FILE_TRANSFER_H__
    19.7 +#define __MYTH_FILE_TRANSFER_H__
    19.8 +
    19.9 +#include <glib-object.h>
   19.10 +
   19.11 +#include <gmyth/gmyth_socket.h>
   19.12 +#include "myth_uri.h"
   19.13 +#include "myth_livetv.h"
   19.14 +
   19.15 +#include <stdio.h>
   19.16 +#include <stdlib.h>
   19.17 +#include <string.h>
   19.18 +#include <netdb.h>
   19.19 +#include <sys/socket.h>
   19.20 +#include <unistd.h>
   19.21 +
   19.22 +#define G_BEGIN_DECLS
   19.23 +
   19.24 +#define MYTH_FILE_TRANSFER_TYPE               (myth_file_transfer_get_type ())
   19.25 +#define MYTH_FILE_TRANSFER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_FILE_TRANSFER_TYPE, MythFileTransfer))
   19.26 +#define MYTH_FILE_TRANSFER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_FILE_TRANSFER_TYPE, MythFileTransferClass))
   19.27 +#define IS_MYTH_FILE_TRANSFER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_FILE_TRANSFER_TYPE))
   19.28 +#define IS_MYTH_FILE_TRANSFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_FILE_TRANSFER_TYPE))
   19.29 +#define MYTH_FILE_TRANSFER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), MYTH_FILE_TRANSFER_TYPE, MythFileTransferClass))
   19.30 +
   19.31 +
   19.32 +typedef struct _MythFileTransfer         MythFileTransfer;
   19.33 +typedef struct _MythFileTransferClass    MythFileTransferClass;
   19.34 +
   19.35 +struct _MythFileTransferClass
   19.36 +{
   19.37 +	GObjectClass parent_class;
   19.38 +
   19.39 +	/* callbacks */
   19.40 +	/* no one for now */
   19.41 +};
   19.42 +
   19.43 +struct _MythFileTransfer
   19.44 +{
   19.45 +	GObject parent;
   19.46 +
   19.47 +	/* Myth URI structure */
   19.48 +	const MythURI *uri;
   19.49 +	
   19.50 +	/* MythTV version number */	
   19.51 +	gint mythtv_version;
   19.52 +
   19.53 +	/* socket descriptors */
   19.54 +	GMythSocket *control_sock;
   19.55 +	GMythSocket *event_sock;
   19.56 +	GMythSocket *sock;
   19.57 +
   19.58 +	guint64 readposition;
   19.59 +	guint64 filesize;
   19.60 +	gboolean timeoutisfast;
   19.61 +	gboolean userreadahead;
   19.62 +	gboolean live_tv;
   19.63 +	gint retries;
   19.64 +
   19.65 +	GString *query;
   19.66 +
   19.67 +	gint rec_id;
   19.68 +	gint recordernum;
   19.69 +	gint card_id;
   19.70 +	GString *hostname;
   19.71 +	gint port;
   19.72 +};
   19.73 +
   19.74 +GType          myth_file_transfer_get_type        (void);
   19.75 +
   19.76 +MythFileTransfer* myth_file_transfer_new (gint num, GString *hostname, gshort port, gint mythtv_version );
   19.77 +
   19.78 +gint myth_file_transfer_read(MythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited);
   19.79 +
   19.80 +guint64 myth_file_transfer_seek(MythFileTransfer *transfer, guint64 pos, gint whence);
   19.81 +
   19.82 +gboolean myth_file_transfer_playback_setup( MythFileTransfer **transfer, gboolean live_tv );
   19.83 +
   19.84 +gboolean myth_file_transfer_setup( MythFileTransfer **transfer, gboolean live_tv );
   19.85 +
   19.86 +gboolean myth_file_transfer_livetv_setup( MythFileTransfer **transfer, GMythSocket *live_sock );
   19.87 +
   19.88 +void myth_file_transfer_spawntv ( MythFileTransfer *file_transfer, GString *tvchain_id );
   19.89 +
   19.90 +gboolean myth_file_transfer_is_recording( MythFileTransfer *file_transfer );
   19.91 +
   19.92 +guint64  myth_file_transfer_get_file_position( MythFileTransfer *file_transfer );
   19.93 +
   19.94 +#define G_END_DECLS
   19.95 +
   19.96 +#endif /* __MYTH_FILE_TRANSFER_H__ */
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/gst-plugins-mythtv/src/myth_livetv.c	Tue Sep 26 15:58:37 2006 +0100
    20.3 @@ -0,0 +1,220 @@
    20.4 +
    20.5 +#include <gmyth/gmyth_context.h>
    20.6 +#include <gmyth/gmyth_remote_util.h>
    20.7 +#include <gmyth/gmyth_tvchain.h>
    20.8 +
    20.9 +#include "myth_livetv.h"
   20.10 +#include "myth_file_transfer.h"
   20.11 +
   20.12 +static void myth_livetv_class_init          (MythLiveTVClass *klass);
   20.13 +static void myth_livetv_init                (MythLiveTV *object);
   20.14 +
   20.15 +static void myth_livetv_dispose  (GObject *object);
   20.16 +static void myth_livetv_finalize (GObject *object);
   20.17 +
   20.18 +G_DEFINE_TYPE(MythLiveTV, myth_livetv, G_TYPE_OBJECT)
   20.19 +
   20.20 +static void
   20.21 +myth_livetv_class_init (MythLiveTVClass *klass)
   20.22 +{
   20.23 +	GObjectClass *gobject_class;
   20.24 +
   20.25 +	gobject_class = (GObjectClass *) klass;
   20.26 +
   20.27 +	gobject_class->dispose  = myth_livetv_dispose;
   20.28 +	gobject_class->finalize = myth_livetv_finalize;	
   20.29 +}
   20.30 +
   20.31 +static void
   20.32 +myth_livetv_init (MythLiveTV *livetv)
   20.33 +{
   20.34 +	livetv->backend_hostname = NULL;
   20.35 +	livetv->backend_port = 0;
   20.36 +	livetv->local_hostname = NULL;
   20.37 +
   20.38 +	livetv->remote_encoder = NULL;
   20.39 +	livetv->tvchain = NULL;
   20.40 +	livetv->proginfo = NULL;
   20.41 +}
   20.42 +
   20.43 +static void
   20.44 +myth_livetv_dispose  (GObject *object)
   20.45 +{
   20.46 +
   20.47 +	G_OBJECT_CLASS (myth_livetv_parent_class)->dispose (object);
   20.48 +}
   20.49 +
   20.50 +static void
   20.51 +myth_livetv_finalize (GObject *object)
   20.52 +{
   20.53 +	g_signal_handlers_destroy (object);
   20.54 +
   20.55 +	MythLiveTV *livetv = MYTH_LIVETV (object);
   20.56 +
   20.57 +	g_debug ("[%s] Finalizing livetv", __FUNCTION__);
   20.58 +
   20.59 +	if ( livetv->remote_encoder != NULL ) {
   20.60 +		g_object_unref (livetv->remote_encoder);
   20.61 +		livetv->remote_encoder = NULL;
   20.62 +	}
   20.63 +
   20.64 +	if ( livetv->tvchain != NULL ) {
   20.65 +		g_object_unref (livetv->tvchain);
   20.66 +		livetv->tvchain = NULL;
   20.67 +	}
   20.68 +
   20.69 +	if ( livetv->proginfo != NULL ) {
   20.70 +		g_object_unref (livetv->proginfo);
   20.71 +		livetv->proginfo = NULL;
   20.72 +	}
   20.73 +
   20.74 +	G_OBJECT_CLASS ( myth_livetv_parent_class )->finalize ( object );
   20.75 +}
   20.76 +
   20.77 +MythLiveTV*
   20.78 +myth_livetv_new ()
   20.79 +{
   20.80 +	MythLiveTV *livetv = MYTH_LIVETV ( g_object_new( MYTH_LIVETV_TYPE, NULL ) );
   20.81 +
   20.82 +	return livetv;
   20.83 +}
   20.84 +
   20.85 +gboolean
   20.86 +myth_livetv_setup ( MythLiveTV *livetv )
   20.87 +{
   20.88 +
   20.89 +	// FIXME: Get from the settings
   20.90 +	GMythSettings *msettings = gmyth_context_get_settings ();
   20.91 +	gboolean res = TRUE;
   20.92 +
   20.93 +	livetv->is_livetv = TRUE;
   20.94 +
   20.95 +	res = gmyth_context_check_connection();
   20.96 +	if (!res) {
   20.97 +		g_warning ("[%s] LiveTV can not connect to backend", __FUNCTION__);	
   20.98 +		res = FALSE;
   20.99 +		goto error;
  20.100 +	}
  20.101 +
  20.102 +	livetv->backend_hostname = gmyth_settings_get_backend_hostname(msettings);
  20.103 +	livetv->backend_port = gmyth_settings_get_backend_port (msettings);
  20.104 +
  20.105 +	livetv->local_hostname  = g_string_new("");    
  20.106 +	gmyth_context_get_local_hostname (livetv->local_hostname);
  20.107 +
  20.108 +	if ( livetv->local_hostname == NULL ) {
  20.109 +		res = FALSE;
  20.110 +		goto error;
  20.111 +	}
  20.112 +
  20.113 +	// Gets the remote encoder num
  20.114 +	livetv->remote_encoder = remote_request_next_free_recorder (-1);
  20.115 +
  20.116 +	if ( livetv->remote_encoder == NULL ) {
  20.117 +		g_warning ("[%s] None remote encoder available", __FUNCTION__);
  20.118 +		res = FALSE;
  20.119 +		goto error;
  20.120 +	}
  20.121 +
  20.122 +	// Creates livetv chain handler
  20.123 +	livetv->tvchain = GMYTH_TVCHAIN ( g_object_new(GMYTH_TVCHAIN_TYPE, NULL) );
  20.124 +	gmyth_tvchain_initialize ( livetv->tvchain, livetv->local_hostname );
  20.125 +
  20.126 +	if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) {
  20.127 +		res = FALSE;
  20.128 +		goto error;
  20.129 +	}
  20.130 +
  20.131 +	// Init remote encoder. Opens its control socket.
  20.132 +	res = gmyth_remote_encoder_setup(livetv->remote_encoder);
  20.133 +	if ( !res ) {
  20.134 +		g_warning ("[%s] Fail while setting remote encoder\n", __FUNCTION__);
  20.135 +		res = FALSE;
  20.136 +		goto error;
  20.137 +	}
  20.138 +	// Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly)
  20.139 +	res = gmyth_remote_encoder_spawntv ( livetv->remote_encoder,
  20.140 +			gmyth_tvchain_get_id(livetv->tvchain) );
  20.141 +	if (!res) {
  20.142 +		g_warning ("[%s] Fail while spawn tv\n", __FUNCTION__);
  20.143 +		res = FALSE;
  20.144 +		goto error;
  20.145 +	}
  20.146 +
  20.147 +	// Reload all TV chain from Mysql database.
  20.148 +	gmyth_tvchain_reload_all (livetv->tvchain);
  20.149 +
  20.150 +	if ( livetv->tvchain == NULL ) {
  20.151 +		res = FALSE;
  20.152 +		goto error;
  20.153 +	}
  20.154 +
  20.155 +	// Get program info from database using chanid and starttime
  20.156 +	livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, -1);
  20.157 +	if ( livetv->proginfo == NULL ) {
  20.158 +		g_warning ("[%s] LiveTV not successfully started.\n", __FUNCTION__ );
  20.159 +		res = FALSE;
  20.160 +		goto error;
  20.161 +	} else {
  20.162 +		g_debug ("[%s] MythLiveTV: All requests to backend to start TV were OK.\n", __FUNCTION__ );
  20.163 +	}
  20.164 +
  20.165 +	return res;
  20.166 +
  20.167 +error:
  20.168 +	if ( livetv->backend_hostname != NULL ) {
  20.169 +		g_string_free( livetv->backend_hostname, TRUE );
  20.170 +		res = FALSE;
  20.171 +	}
  20.172 +
  20.173 +	if ( livetv->local_hostname != NULL ) {
  20.174 +		g_string_free( livetv->local_hostname, TRUE );
  20.175 +		res = FALSE;
  20.176 +	}
  20.177 +
  20.178 +	if ( livetv->remote_encoder != NULL ) {
  20.179 +		g_object_unref (livetv->remote_encoder);
  20.180 +		livetv->remote_encoder = NULL;
  20.181 +	}
  20.182 +
  20.183 +	if ( livetv->tvchain != NULL ) {
  20.184 +		g_object_unref (livetv->tvchain);
  20.185 +		livetv->tvchain = NULL;
  20.186 +	}
  20.187 +
  20.188 +	if ( livetv->proginfo != NULL ) {
  20.189 +		g_object_unref (livetv->proginfo);
  20.190 +		livetv->proginfo = NULL;
  20.191 +	}
  20.192 +
  20.193 +	return res;
  20.194 +
  20.195 +}
  20.196 +
  20.197 +// FIXME: How to proceed differently between livetv and recorded content
  20.198 +void
  20.199 +myth_livetv_stop_playing (MythLiveTV *livetv) 
  20.200 +{
  20.201 +	g_debug ("[%s] Stopping the LiveTV...\n", __FUNCTION__);
  20.202 +
  20.203 +	if (livetv->is_livetv) {
  20.204 +		if (!gmyth_remote_encoder_stop_livetv (livetv->remote_encoder)) {
  20.205 +			g_warning ("[%s] Error while stoping remote encoder", __FUNCTION__);	
  20.206 +		}
  20.207 +	}
  20.208 +}
  20.209 +
  20.210 +gboolean
  20.211 +myth_livetv_is_playing (MythLiveTV *livetv)
  20.212 +{
  20.213 +	return TRUE;
  20.214 +}
  20.215 +
  20.216 +void
  20.217 +myth_livetv_start_playing (MythLiveTV *livetv)
  20.218 +{
  20.219 +
  20.220 +	// TODO
  20.221 +
  20.222 +}
  20.223 +
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/gst-plugins-mythtv/src/myth_livetv.h	Tue Sep 26 15:58:37 2006 +0100
    21.3 @@ -0,0 +1,59 @@
    21.4 +#ifndef MYTH_LIVETV_H_
    21.5 +#define MYTH_LIVETV_H_
    21.6 +
    21.7 +#include <glib-object.h>
    21.8 +
    21.9 +#include <gmyth/gmyth_remote_encoder.h>
   21.10 +#include <gmyth/gmyth_tvchain.h>
   21.11 +#include <gmyth/gmyth_common.h>
   21.12 +
   21.13 +#include "myth_file_transfer.h"
   21.14 +
   21.15 +#define G_BEGIN_DECLS
   21.16 +
   21.17 +#define MYTH_LIVETV_TYPE               (myth_livetv_get_type ())
   21.18 +#define MYTH_LIVETV(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_LIVETV_TYPE, MythLiveTV))
   21.19 +#define MYTH_LIVETV_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_LIVETV_TYPE, MythLiveTVClass))
   21.20 +#define IS_MYTH_LIVETV(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MYTH_LIVETV_TYPE))
   21.21 +#define IS_MYTH_LIVETV_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MYTH_LIVETV_TYPE))
   21.22 +#define MYTH_LIVETV_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), MYTH_LIVETV_TYPE, MythLiveTVClass))
   21.23 +
   21.24 +typedef struct _MythLiveTV         MythLiveTV;
   21.25 +typedef struct _MythLiveTVClass    MythLiveTVClass;
   21.26 +
   21.27 +struct _MythLiveTVClass
   21.28 +{
   21.29 +  GObjectClass parent_class;
   21.30 +
   21.31 +  /* callbacks */
   21.32 +};
   21.33 +
   21.34 +struct _MythLiveTV
   21.35 +{
   21.36 +	GObject parent;
   21.37 +
   21.38 +	// Backend connection related variables
   21.39 +	GString *backend_hostname;
   21.40 +	gint backend_port;
   21.41 +	GString *local_hostname;
   21.42 +
   21.43 +	GMythRemoteEncoder *remote_encoder;
   21.44 +	GMythTVChain *tvchain;
   21.45 +	GMythProgramInfo *proginfo;
   21.46 +
   21.47 +	gboolean is_livetv;
   21.48 +
   21.49 +};
   21.50 +
   21.51 +GType          myth_livetv_get_type (void);
   21.52 +
   21.53 +MythLiveTV* myth_livetv_new ();
   21.54 +
   21.55 +void myth_livetv_start_playing (MythLiveTV *livetv);
   21.56 +void myth_livetv_stop_playing (MythLiveTV *livetv);
   21.57 +
   21.58 +gboolean myth_livetv_setup (MythLiveTV *livetv);
   21.59 +
   21.60 +#define G_END_DECLS
   21.61 +
   21.62 +#endif /*MYTH_LIVETV_H_*/
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/gst-plugins-mythtv/src/myth_uri.c	Tue Sep 26 15:58:37 2006 +0100
    22.3 @@ -0,0 +1,208 @@
    22.4 +/**
    22.5 + *
    22.6 + *    MythURI utils
    22.7 + *  - Extracts and parses a URI char string, in according with the RFC 2396
    22.8 + *    [http://www.ietf.org/rfc/rfc2396.txt]
    22.9 + *
   22.10 + *   @author Rosfran Borges (rosfran.borges@indt.org.br)
   22.11 + *
   22.12 + */
   22.13 +
   22.14 +#include "myth_uri.h"
   22.15 +#include <glib.h>
   22.16 +#include <string.h>
   22.17 +#include <stdlib.h>
   22.18 +
   22.19 +static gint 
   22.20 +myth_strstr( const gchar *haystack, const gchar *needle )
   22.21 +{
   22.22 +	
   22.23 +	gchar *strPos;
   22.24 +	
   22.25 +	if (haystack == NULL || needle == NULL)
   22.26 +		return -1;
   22.27 +	strPos = strstr(haystack, needle);
   22.28 +	if (strPos == NULL)
   22.29 +		return -1;
   22.30 +		
   22.31 +	return (strPos - haystack);
   22.32 +
   22.33 +}
   22.34 +
   22.35 +static gboolean
   22.36 +myth_uri_isabsolute( const MythURI *uri )
   22.37 +{
   22.38 +	gboolean ret = FALSE;
   22.39 +	
   22.40 +	g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE );
   22.41 +	
   22.42 +	if ( myth_strstr( uri->uri->str, MYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 )
   22.43 +		ret = TRUE;
   22.44 +		
   22.45 +	return ret;	
   22.46 +}
   22.47 +
   22.48 +static gint
   22.49 +myth_strrchr( const gchar *str, const gchar *chars, const gint nchars )
   22.50 +{
   22.51 +
   22.52 +	gint strLen;
   22.53 +	gint i, j;
   22.54 +	
   22.55 +	if ( str == NULL || chars == NULL )
   22.56 +		return -1;
   22.57 +		
   22.58 +	strLen = strlen( str );
   22.59 +	for ( i= (strLen-1); 0 <= i; i-- ) {
   22.60 +		for ( j=0; j<nchars; j++ ) {
   22.61 +			if ( str[i] == chars[j] )
   22.62 +				return i;
   22.63 +		}
   22.64 +	}
   22.65 +
   22.66 +	return -1;
   22.67 +
   22.68 +}
   22.69 +
   22.70 +static MythURI *
   22.71 +myth_uri_init( )
   22.72 +{
   22.73 +	MythURI *uri = g_new0( MythURI, 1 );
   22.74 +	uri->host = g_string_new("");
   22.75 +	uri->fragment = g_string_new("");
   22.76 +	uri->password = g_string_new("");
   22.77 +	uri->path = g_string_new("");
   22.78 +	uri->protocol = g_string_new("");
   22.79 +	uri->query = g_string_new("");
   22.80 +	uri->uri = g_string_new("");
   22.81 +	uri->user = g_string_new("");
   22.82 +	return uri;
   22.83 +}
   22.84 +
   22.85 +const MythURI *
   22.86 +myth_uri_new( gchar *value )
   22.87 +{
   22.88 +	
   22.89 +	MythURI *uri = myth_uri_init();
   22.90 +
   22.91 +	gchar *protocol;
   22.92 +	gint uriLen;
   22.93 +	gint currIdx;
   22.94 +	gint protoIdx;
   22.95 +	gint atIdx;
   22.96 +	gint colonIdx;
   22.97 +	gint shashIdx;
   22.98 +	gchar *host;
   22.99 +	gint eblacketIdx;
  22.100 +	GString *hostStr;
  22.101 +	GString *portStr;
  22.102 +	gint hostLen;
  22.103 +	gint sharpIdx;
  22.104 +	gint questionIdx;
  22.105 +	gint queryLen;
  22.106 +	
  22.107 +	uriLen = strlen(value);
  22.108 +	uri->uri = g_string_new( value );
  22.109 +		
  22.110 +	currIdx = 0;
  22.111 +	
  22.112 +	/*** Protocol ****/
  22.113 +	protoIdx = myth_strstr( value, MYTH_URI_PROTOCOL_DELIM );
  22.114 +	if (0 < protoIdx) {
  22.115 +		uri->protocol = g_string_append_len( uri->protocol, value, protoIdx );
  22.116 +		currIdx += protoIdx + strlen( MYTH_URI_PROTOCOL_DELIM );
  22.117 +	}
  22.118 +
  22.119 +	/*** User (Password) ****/
  22.120 +	atIdx = myth_strstr( value+currIdx, MYTH_URI_USER_DELIM );
  22.121 +	if ( 0 < atIdx ) {
  22.122 +		colonIdx = myth_strstr( value+currIdx, MYTH_URI_COLON_DELIM );
  22.123 +
  22.124 +		if (0 < colonIdx && colonIdx < atIdx) {
  22.125 +			uri->user = g_string_append_len( uri->user, value+currIdx,  colonIdx );
  22.126 +			uri->password = g_string_append_len( uri->password, value+currIdx+colonIdx+1, atIdx-(colonIdx+1) );
  22.127 +		}
  22.128 +		else 
  22.129 +			uri->user = g_string_append_len( uri->user, value+currIdx, atIdx - currIdx );
  22.130 +		currIdx += atIdx + 1;
  22.131 +	}
  22.132 +
  22.133 +	/*** Host (Port) ****/
  22.134 +	shashIdx = myth_strstr( value+currIdx, MYTH_URI_SLASH_DELIM );
  22.135 +	if ( 0 < shashIdx )
  22.136 +		uri->host = g_string_append_len( uri->host, value+currIdx, shashIdx );
  22.137 +	else if ( myth_uri_isabsolute(uri) == TRUE )
  22.138 +		uri->host = g_string_append_len( uri->host, value+currIdx, strlen(value) - currIdx );
  22.139 +	host = g_strdup( myth_uri_gethost(uri) );
  22.140 +	colonIdx = myth_strrchr( host, MYTH_URI_COLON_DELIM, 1 );
  22.141 +	eblacketIdx = myth_strrchr( host, MYTH_URI_EBLACET_DELIM, 1 );
  22.142 +	if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) {
  22.143 +		hostStr = g_string_new( host );
  22.144 +
  22.145 +		hostLen = hostStr->len;
  22.146 +		/**** host ****/
  22.147 +		uri->host = g_string_erase( uri->host, 0, hostLen );
  22.148 +		uri->host = g_string_insert_len( uri->host, 0, hostStr->str, colonIdx );
  22.149 +		//host = myth_uri_gethost( uri );
  22.150 +		if (0 < hostLen) {
  22.151 +			if (host[0] == '[' && host[hostLen-1] == ']')
  22.152 +				uri->host = g_string_append_len( uri->host, hostStr->str+1,  colonIdx-2 );
  22.153 +		}
  22.154 +		/**** port ****/
  22.155 +		portStr = g_string_new("");
  22.156 +		portStr = g_string_append_len( portStr, hostStr->str+colonIdx+1, hostLen-colonIdx-1 );
  22.157 +		uri->port = atoi( portStr->str );
  22.158 +		g_string_free( portStr, TRUE );
  22.159 +		g_string_free( hostStr, FALSE );
  22.160 +	}
  22.161 +	else {
  22.162 +		uri->port = MYTH_URI_KNKOWN_PORT;
  22.163 +		protocol = myth_uri_getprotocol(uri);
  22.164 +		if ( strcmp(protocol, MYTH_URI_PROTOCOL_HTTP) == 0 )
  22.165 +			uri->port = MYTH_URI_DEFAULT_HTTP_PORT;
  22.166 +		if ( strcmp(protocol, MYTH_URI_PROTOCOL_FTP) == 0 )
  22.167 +			uri->port = MYTH_URI_DEFAULT_FTP_PORT;
  22.168 +	}
  22.169 +	
  22.170 +	if (shashIdx > 0) currIdx += shashIdx;
  22.171 +	
  22.172 +	/*
  22.173 +		Handle relative URL
  22.174 +	*/
  22.175 +	if (myth_uri_isabsolute(uri) == FALSE)
  22.176 +	{
  22.177 +
  22.178 +		if (shashIdx != 0)
  22.179 +		{
  22.180 +			/* Add slash delimiter at the beginning of the URL,
  22.181 +			   if it doesn't exist 
  22.182 +			*/
  22.183 +			uri->path = g_string_new( MYTH_URI_SLASH_DELIM );
  22.184 +		}
  22.185 +		uri->path = g_string_append( uri->path, value );
  22.186 +		
  22.187 +	} else {
  22.188 +		/* First set path simply to the rest of URI */
  22.189 +		g_string_append_len( uri->path, value+currIdx,  uriLen-currIdx );
  22.190 +	}
  22.191 +		
  22.192 +	/**** Path (Query/Fragment) ****/
  22.193 +	sharpIdx = myth_strstr(value+currIdx, MYTH_URI_SHARP_DELIM);
  22.194 +	if (0 < sharpIdx) {
  22.195 +		uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx);
  22.196 +		uri->fragment = g_string_append_len( uri->fragment, 
  22.197 +			value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1));
  22.198 +	}
  22.199 +	
  22.200 +	questionIdx = myth_strstr( value+currIdx, MYTH_URI_QUESTION_DELIM );
  22.201 +	if ( 0 < questionIdx ) {
  22.202 +		uri->path = g_string_append_len( uri->path, value+currIdx, questionIdx );
  22.203 +		queryLen = uriLen-(currIdx+questionIdx+1);
  22.204 +		if ( 0 < sharpIdx )
  22.205 +			queryLen -= uriLen - (currIdx+sharpIdx+1);
  22.206 +		uri->query = g_string_append_len( uri->query, value+currIdx+questionIdx+1, queryLen );
  22.207 +	}
  22.208 +	
  22.209 +	return uri;
  22.210 +
  22.211 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/gst-plugins-mythtv/src/myth_uri.h	Tue Sep 26 15:58:37 2006 +0100
    23.3 @@ -0,0 +1,63 @@
    23.4 +/**
    23.5 + *
    23.6 + *	MythURI utils
    23.7 + *  - Extracts and parses a URI char string, in according with the RFC 2396 
    23.8 + *    [http://www.ietf.org/rfc/rfc2396.txt]
    23.9 + *
   23.10 + * @author Rosfran Borges (rosfran.borges@indt.org.br)
   23.11 + * 
   23.12 + */
   23.13 +
   23.14 +#ifndef _MYTH_URI_H_
   23.15 +#define _MYTH_URI_H_
   23.16 +
   23.17 +#include <glib.h>
   23.18 +
   23.19 +/****************************************
   23.20 +* Define
   23.21 +****************************************/
   23.22 +
   23.23 +#define MYTH_URI_KNKOWN_PORT (-1)
   23.24 +#define MYTH_URI_DEFAULT_HTTP_PORT 80
   23.25 +#define MYTH_URI_DEFAULT_FTP_PORT 21
   23.26 +#define MYTH_URI_DEFAULT_PATH "/"
   23.27 +#define MYTH_URI_MAXLEN 256
   23.28 +
   23.29 +#define MYTH_URI_PROTOCOL_DELIM "://"
   23.30 +#define MYTH_URI_USER_DELIM "@"
   23.31 +#define MYTH_URI_COLON_DELIM ":"
   23.32 +#define MYTH_URI_SLASH_DELIM "/"
   23.33 +#define MYTH_URI_SBLACET_DELIM "["
   23.34 +#define MYTH_URI_EBLACET_DELIM "]"
   23.35 +#define MYTH_URI_SHARP_DELIM "#"
   23.36 +#define MYTH_URI_QUESTION_DELIM "?"
   23.37 +#define MYTH_URI_ESCAPING_CHAR "%"
   23.38 +
   23.39 +#define MYTH_URI_PROTOCOL_MYTH "myth"
   23.40 +#define MYTH_URI_PROTOCOL_HTTP "http"
   23.41 +#define MYTH_URI_PROTOCOL_FTP "ftp"
   23.42 +
   23.43 +/****************************************
   23.44 +* Data Type
   23.45 +****************************************/
   23.46 +
   23.47 +typedef struct _MythURI {
   23.48 +	GString *uri;
   23.49 +	GString *host;
   23.50 +	gint port;
   23.51 +	GString *protocol;
   23.52 +	GString *path;
   23.53 +	GString *fragment;
   23.54 +	GString *user;
   23.55 +	GString *password;
   23.56 +	GString *query;
   23.57 +} MythURI;
   23.58 +
   23.59 +const MythURI *myth_uri_new( gchar *value );
   23.60 +
   23.61 +#define myth_uri_gethost(urip) (urip->host->str)
   23.62 +#define myth_uri_getport(urip) (urip->port)
   23.63 +#define myth_uri_getprotocol(urip) (urip->protocol->str)
   23.64 +#define myth_uri_getpath(urip) (urip->path->str)
   23.65 +
   23.66 +#endif
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/gst-plugins-mythtv/src/mythtvsrc-test.c	Tue Sep 26 15:58:37 2006 +0100
    24.3 @@ -0,0 +1,85 @@
    24.4 +#include <gst/gst.h>
    24.5 +
    24.6 +static gboolean
    24.7 +bus_call (GstBus     *bus,
    24.8 +	  GstMessage *msg,
    24.9 +	  gpointer    data)
   24.10 +{
   24.11 +  GMainLoop *loop = data;
   24.12 +
   24.13 +  switch (GST_MESSAGE_TYPE (msg)) {
   24.14 +    case GST_MESSAGE_EOS:
   24.15 +      g_print ("End-of-stream\n");
   24.16 +      g_main_loop_quit (loop);
   24.17 +      break;
   24.18 +    case GST_MESSAGE_ERROR: {
   24.19 +      gchar *debug;
   24.20 +      GError *err;
   24.21 +
   24.22 +      gst_message_parse_error (msg, &err, &debug);
   24.23 +      g_free (debug);
   24.24 +
   24.25 +      g_print ("Error: %s\n", err->message);
   24.26 +      g_error_free (err);
   24.27 +
   24.28 +      g_main_loop_quit (loop);
   24.29 +      break;
   24.30 +    }
   24.31 +    default:
   24.32 +      break;
   24.33 +  }
   24.34 +
   24.35 +  return TRUE;
   24.36 +}
   24.37 +
   24.38 +gint
   24.39 +main (gint   argc,
   24.40 +      gchar *argv[])
   24.41 +{
   24.42 +  GstElement *pipeline, *filesrc, *decoder, *filter, *sink;
   24.43 +  GMainLoop *loop;
   24.44 +
   24.45 +  /* initialization */
   24.46 +  gst_init (&argc, &argv);
   24.47 +  loop = g_main_loop_new (NULL, FALSE);
   24.48 +  if (argc != 2) {
   24.49 +    g_print ("Usage: %s <myth uri>\n", argv[0]);
   24.50 +    return 01;
   24.51 +  }
   24.52 +
   24.53 +  /* create elements */
   24.54 +  pipeline = gst_pipeline_new ("mythtvsrc_pipeline");
   24.55 +  gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
   24.56 +		     bus_call, loop);
   24.57 +
   24.58 +  filesrc  = gst_element_factory_make ("mythtvsrc", "mythtvsrc");
   24.59 +  decoder  = gst_element_factory_make ("mad", "my_decoder");
   24.60 +  filter   = gst_element_factory_make ("my_filter", "my_filter");
   24.61 +  sink     = gst_element_factory_make ("osssink", "audiosink");
   24.62 +  if (!sink || !decoder) {
   24.63 +    g_print ("Decoder or output could not be found - check your install\n");
   24.64 +    return -1;
   24.65 +  } else if (!filter) {
   24.66 +    g_print ("Your self-written filter could not be found. Make sure it "
   24.67 +             "is installed correctly in $(libdir)/gstreamer-0.9/ and that "
   24.68 +             "you've ran gst-register-0.9 to register it. Check availability "
   24.69 +             "of the plugin afterwards using \"gst-inspect-0.9 my_filter\"");
   24.70 +    return -1;
   24.71 +  }
   24.72 +
   24.73 +  g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
   24.74 +
   24.75 +  /* link everything together */
   24.76 +  gst_element_link_many (filesrc, decoder, filter, sink, NULL);
   24.77 +  gst_bin_add_many (GST_BIN (pipeline), filesrc, decoder, filter, sink, NULL);
   24.78 +
   24.79 +  /* run */
   24.80 +  gst_element_set_state (pipeline, GST_STATE_PLAYING);
   24.81 +  g_main_loop_run (loop);
   24.82 +
   24.83 +  /* clean up */
   24.84 +  gst_element_set_state (pipeline, GST_STATE_NULL);
   24.85 +  gst_object_unref (GST_OBJECT (pipeline));
   24.86 +
   24.87 +  return 0;
   24.88 +}