[svn r14] new source tree.
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 +}