gst-gmyth/mythsrc/gstmythtvsrc.c
branchtrunk
changeset 839 5930595a2ae5
parent 838 3539377c1807
child 840 5ab6a453da43
     1.1 --- a/gst-gmyth/mythsrc/gstmythtvsrc.c	Mon Sep 03 21:14:14 2007 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1085 +0,0 @@
     1.4 -/*
     1.5 - * GStreamer MythTV Plug-in Copyright (C) <2006> Rosfran Borges
     1.6 - * <rosfran.borges@indt.org.br> This library is free software; you can
     1.7 - * redistribute it and/or modify it under the terms of the GNU Library
     1.8 - * General Public License as published by the Free Software Foundation;
     1.9 - * either version 2 of the License, or (at your option) any later version.
    1.10 - * This library is distributed in the hope that it will be useful, but
    1.11 - * WITHOUT ANY WARRANTY; without even the implied warranty of
    1.12 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library 
    1.13 - * General Public License for more details. You should have received a copy 
    1.14 - * of the GNU Library General Public License along with this library; if
    1.15 - * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 
    1.16 - * 330, Boston, MA 02111-1307, USA. 
    1.17 - */
    1.18 -/**
    1.19 - * SECTION:element-mythtvsrc
    1.20 - *
    1.21 - * <refsect2>
    1.22 - * <para>
    1.23 - * MythTVSrc allows to access a remote MythTV backend streaming Video/Audio server,
    1.24 - * and to render audio and video content through a TCP/IP connection to a specific
    1.25 - * port on this server, and based on a known MythTV protocol that is based on 
    1.26 - * some message passing, such as REQUEST_BLOCK on a specified number of bytes, to get
    1.27 - * some chunk of remote file data.
    1.28 - * You should pass the information aboute the remote MythTV backend server 
    1.29 - * through the <link linkend="GstMythTVSrc--location">location</link> property.
    1.30 - * </para>
    1.31 - * <title>Examples</title>
    1.32 - * <para>
    1.33 - * If you want to get the LiveTV content (set channel, TV tuner, RemoteEncoder, 
    1.34 - * Recorder),
    1.35 - * put the following URI:
    1.36 - * 
    1.37 - * <programlisting> 
    1.38 - *  myth://xxx.xxx.xxx.xxx:6543/livetv?channel=BBC
    1.39 - * </programlisting>
    1.40 - *
    1.41 - * This URI will say to the gmyth library to configure the Recorder instance (used to
    1.42 - * change the channel, start the TV multimedia content transmition, etc.), using
    1.43 - * the IP address (xxx.xxx.xxx.xxx) and port number (6543) of the MythTV backend 
    1.44 - * server, and setting the channel name to "BBC". 
    1.45 - * 
    1.46 - * To get a already recorded the MythTV NUV file, put the following URI:
    1.47 - * 
    1.48 - * <programlisting>
    1.49 - *  myth://xxx.xxx.xxx.xxx:6543/filename.nuv
    1.50 - * </programlisting>
    1.51 - *
    1.52 - * This URI will say to the gmyth library to configure the Recorder instance (used to
    1.53 - * change the channel, start the TV multimedia content transmition, etc.), using
    1.54 - * the IP address (xxx.xxx.xxx.xxx) and port number (6543) of the MythTV backend 
    1.55 - * server, and setting the channel name to "BBC".
    1.56 - * 
    1.57 - * Another possible way to use the LiveTV content, and just in the case you want to 
    1.58 - * use the mysql database, put the location URI in the following format:
    1.59 - * 
    1.60 - * <programlisting> 
    1.61 - *  myth://mythtv:mythtv@xxx.xxx.xxx.xxx:6543/?mythconverg&channel=9
    1.62 - * </programlisting>
    1.63 - * 
    1.64 - * Where the first field is the protocol (myth), the second and third are user 
    1.65 - * name (mythtv) and password (mythtv), then backend host name and port number, 
    1.66 - * and the last field is the database name (mythconverg).
    1.67 - * </para>
    1.68 - * </refsect2>
    1.69 - */
    1.70 -#ifdef HAVE_CONFIG_H
    1.71 -#include "config.h"
    1.72 -#endif
    1.73 -
    1.74 -#include "gstmythtvsrc.h"
    1.75 -#include <gmyth/gmyth_file.h>
    1.76 -#include <gmyth/gmyth_file_transfer.h>
    1.77 -#include <gmyth/gmyth_file_local.h>
    1.78 -#include <gmyth/gmyth_livetv.h>
    1.79 -
    1.80 -#include <gmyth/gmyth_socket.h>
    1.81 -#include <gmyth/gmyth_tvchain.h>
    1.82 -
    1.83 -#include <string.h>
    1.84 -#include <unistd.h>
    1.85 -
    1.86 -GST_DEBUG_CATEGORY_STATIC(mythtvsrc_debug);
    1.87 -#define GST_GMYTHTV_ID_NUM                  1
    1.88 -#define GST_GMYTHTV_CHANNEL_DEFAULT_NUM     (-1)
    1.89 -#define GMYTHTV_VERSION_DEFAULT		    30
    1.90 -#define GMYTHTV_TRANSFER_MAX_WAITS          100
    1.91 -#define GMYTHTV_TRANSFER_MAX_RESENDS        2
    1.92 -#define GMYTHTV_TRANSFER_MAX_BUFFER         (128*1024)
    1.93 -#define READ_SIZE                           (14*1024)
    1.94 -#define READ_SIZE_LIVETV                    (80*1024)
    1.95 -#define GST_FLOW_ERROR_NO_DATA              (-101)
    1.96 -
    1.97 -static const GstElementDetails gst_mythtv_src_details =
    1.98 -GST_ELEMENT_DETAILS("MythTV client source",
    1.99 -                    "Source/Network",
   1.100 -                    "Control and receive data as a client over the network "
   1.101 -                    "via raw socket connections using the MythTV protocol",
   1.102 -                    "Rosfran Borges <rosfran.borges@indt.org.br>");
   1.103 -
   1.104 -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE("src",
   1.105 -                                                                  GST_PAD_SRC,
   1.106 -                                                                  GST_PAD_ALWAYS,
   1.107 -                                                                  GST_STATIC_CAPS_ANY);
   1.108 -    /*
   1.109 -     * GST_STATIC_CAPS ("video/x-nuv")); 
   1.110 -     */
   1.111 -
   1.112 -enum {
   1.113 -    PROP_0,
   1.114 -    PROP_LOCATION,
   1.115 -    PROP_GMYTHTV_VERSION,
   1.116 -    PROP_GMYTHTV_LIVE,
   1.117 -    PROP_GMYTHTV_LIVEID,
   1.118 -    PROP_GMYTHTV_LIVE_CHAINID,
   1.119 -    PROP_GMYTHTV_ENABLE_TIMING_POSITION,
   1.120 -    PROP_GMYTHTV_CHANNEL_NUM
   1.121 -};
   1.122 -
   1.123 -static void     gst_mythtv_src_clear(GstMythtvSrc * mythtv_src);
   1.124 -
   1.125 -static void     gst_mythtv_src_finalize(GObject * gobject);
   1.126 -
   1.127 -static GstFlowReturn gst_mythtv_src_create(GstPushSrc * psrc,
   1.128 -                                           GstBuffer ** outbuf);
   1.129 -
   1.130 -static gboolean gst_mythtv_src_start(GstBaseSrc * bsrc);
   1.131 -static gboolean gst_mythtv_src_stop(GstBaseSrc * bsrc);
   1.132 -static gboolean gst_mythtv_src_get_size(GstBaseSrc * bsrc, guint64 * size);
   1.133 -static gboolean gst_mythtv_src_is_seekable(GstBaseSrc * push_src);
   1.134 -
   1.135 -static gboolean gst_mythtv_src_do_seek(GstBaseSrc * base,
   1.136 -                                       GstSegment * segment);
   1.137 -
   1.138 -static          GstStateChangeReturn
   1.139 -gst_mythtv_src_change_state(GstElement * element,
   1.140 -                            GstStateChange transition);
   1.141 -
   1.142 -static void     gst_mythtv_src_set_property(GObject * object,
   1.143 -                                            guint prop_id,
   1.144 -                                            const GValue * value,
   1.145 -                                            GParamSpec * pspec);
   1.146 -static void     gst_mythtv_src_get_property(GObject * object,
   1.147 -                                            guint prop_id, GValue * value,
   1.148 -                                            GParamSpec * pspec);
   1.149 -
   1.150 -static void     gst_mythtv_src_uri_handler_init(gpointer g_iface,
   1.151 -                                                gpointer iface_data);
   1.152 -
   1.153 -static gboolean gst_mythtv_src_handle_query(GstPad * pad,
   1.154 -                                            GstQuery * query);
   1.155 -
   1.156 -static gboolean gst_mythtv_src_handle_event(GstPad * pad,
   1.157 -                                            GstEvent * event);
   1.158 -
   1.159 -static GMythFileReadResult do_read_request_response(GstMythtvSrc * src,
   1.160 -                                                    guint size,
   1.161 -                                                    GByteArray * data_ptr);
   1.162 -
   1.163 -static void
   1.164 -_urihandler_init(GType type)
   1.165 -{
   1.166 -    static const GInterfaceInfo urihandler_info = {
   1.167 -        gst_mythtv_src_uri_handler_init,
   1.168 -        NULL,
   1.169 -        NULL
   1.170 -    };
   1.171 -
   1.172 -    g_type_add_interface_static(type, GST_TYPE_URI_HANDLER,
   1.173 -                                &urihandler_info);
   1.174 -
   1.175 -    GST_DEBUG_CATEGORY_INIT(mythtvsrc_debug, "mythtvsrc", 0, "MythTV src");
   1.176 -}
   1.177 -
   1.178 -GST_BOILERPLATE_FULL(GstMythtvSrc, gst_mythtv_src, GstPushSrc,
   1.179 -                     GST_TYPE_PUSH_SRC, _urihandler_init)
   1.180 -    static void     gst_mythtv_src_base_init(gpointer g_class)
   1.181 -{
   1.182 -    GstElementClass *element_class = GST_ELEMENT_CLASS(g_class);
   1.183 -
   1.184 -    gst_element_class_add_pad_template(element_class,
   1.185 -                                       gst_static_pad_template_get
   1.186 -                                       (&srctemplate));
   1.187 -
   1.188 -    gst_element_class_set_details(element_class, &gst_mythtv_src_details);
   1.189 -
   1.190 -    element_class->change_state = gst_mythtv_src_change_state;
   1.191 -
   1.192 -}
   1.193 -
   1.194 -static void
   1.195 -gst_mythtv_src_class_init(GstMythtvSrcClass * klass)
   1.196 -{
   1.197 -    GObjectClass   *gobject_class;
   1.198 -    GstPushSrcClass *gstpushsrc_class;
   1.199 -    GstBaseSrcClass *gstbasesrc_class;
   1.200 -
   1.201 -    gobject_class = (GObjectClass *) klass;
   1.202 -    gstbasesrc_class = (GstBaseSrcClass *) klass;
   1.203 -    gstpushsrc_class = (GstPushSrcClass *) klass;
   1.204 -
   1.205 -    gobject_class->set_property = gst_mythtv_src_set_property;
   1.206 -    gobject_class->get_property = gst_mythtv_src_get_property;
   1.207 -    gobject_class->finalize = gst_mythtv_src_finalize;
   1.208 -
   1.209 -    g_object_class_install_property
   1.210 -        (gobject_class, PROP_LOCATION,
   1.211 -         g_param_spec_string("location", "Location",
   1.212 -                             "The location. In the form:"
   1.213 -                             "\n\t\t\tmyth://a.com/file.nuv"
   1.214 -                             "\n\t\t\tmyth://a.com:23223/file.nuv "
   1.215 -                             "\n\t\t\ta.com/file.nuv - default scheme 'myth'",
   1.216 -                             "", G_PARAM_READWRITE));
   1.217 -
   1.218 -    g_object_class_install_property
   1.219 -        (gobject_class, PROP_GMYTHTV_VERSION,
   1.220 -         g_param_spec_int("mythtv-version", "mythtv-version",
   1.221 -                          "Change MythTV version", 26, 30, 26,
   1.222 -                          G_PARAM_READWRITE));
   1.223 -
   1.224 -    g_object_class_install_property
   1.225 -        (gobject_class, PROP_GMYTHTV_LIVEID,
   1.226 -         g_param_spec_int("mythtv-live-id", "mythtv-live-id",
   1.227 -                          "Change MythTV version",
   1.228 -                          0, 200, GST_GMYTHTV_ID_NUM, G_PARAM_READWRITE));
   1.229 -
   1.230 -    g_object_class_install_property
   1.231 -        (gobject_class, PROP_GMYTHTV_LIVE_CHAINID,
   1.232 -         g_param_spec_string("mythtv-live-chainid", "mythtv-live-chainid",
   1.233 -                             "Sets the MythTV chain ID (from TV Chain)",
   1.234 -                             "", G_PARAM_READWRITE));
   1.235 -
   1.236 -    g_object_class_install_property
   1.237 -        (gobject_class, PROP_GMYTHTV_LIVE,
   1.238 -         g_param_spec_boolean("mythtv-live", "mythtv-live",
   1.239 -                              "Enable MythTV Live TV content streaming",
   1.240 -                              FALSE, G_PARAM_READWRITE));
   1.241 -
   1.242 -    g_object_class_install_property
   1.243 -        (gobject_class, PROP_GMYTHTV_ENABLE_TIMING_POSITION,
   1.244 -         g_param_spec_boolean("mythtv-enable-timing-position",
   1.245 -                              "mythtv-enable-timing-position",
   1.246 -                              "Enable MythTV Live TV content size continuous updating",
   1.247 -                              FALSE, G_PARAM_READWRITE));
   1.248 -
   1.249 -    g_object_class_install_property
   1.250 -        (gobject_class, PROP_GMYTHTV_CHANNEL_NUM,
   1.251 -         g_param_spec_string("mythtv-channel", "mythtv-channel",
   1.252 -                             "Change MythTV channel number",
   1.253 -                             "", G_PARAM_READWRITE));
   1.254 -
   1.255 -    gstbasesrc_class->start = gst_mythtv_src_start;
   1.256 -    gstbasesrc_class->stop = gst_mythtv_src_stop;
   1.257 -    gstbasesrc_class->get_size = gst_mythtv_src_get_size;
   1.258 -    gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
   1.259 -    gstbasesrc_class->do_seek = gst_mythtv_src_do_seek;
   1.260 -    gstpushsrc_class->create = gst_mythtv_src_create;
   1.261 -
   1.262 -    GST_DEBUG_CATEGORY_INIT(mythtvsrc_debug, "mythtvsrc", 0,
   1.263 -                            "MythTV Client Source");
   1.264 -}
   1.265 -
   1.266 -static void
   1.267 -gst_mythtv_src_init(GstMythtvSrc * this, GstMythtvSrcClass * g_class)
   1.268 -{
   1.269 -    this->file = NULL;
   1.270 -    this->unique_setup = FALSE;
   1.271 -    this->mythtv_version = GMYTHTV_VERSION_DEFAULT;
   1.272 -    this->state = GST_MYTHTV_SRC_FILE_TRANSFER;
   1.273 -    this->bytes_read = 0;
   1.274 -    this->prev_content_size = 0;
   1.275 -    this->content_size = 0;
   1.276 -    this->read_offset = 0;
   1.277 -    this->content_size_last = 0;
   1.278 -    this->live_tv = FALSE;
   1.279 -    this->enable_timing_position = FALSE;
   1.280 -    this->update_prog_chain = FALSE;
   1.281 -    this->user_agent = g_strdup("mythtvsrc");
   1.282 -    this->update_prog_chain = FALSE;
   1.283 -    this->channel_name = NULL;
   1.284 -    this->eos = FALSE;
   1.285 -    this->wait_to_transfer = 0;
   1.286 -    gst_base_src_set_format(GST_BASE_SRC(this), GST_FORMAT_BYTES);
   1.287 -    gst_pad_set_event_function(GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
   1.288 -                               gst_mythtv_src_handle_event);
   1.289 -    gst_pad_set_query_function(GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
   1.290 -                               gst_mythtv_src_handle_query);
   1.291 -
   1.292 -}
   1.293 -
   1.294 -static void
   1.295 -gst_mythtv_src_clear(GstMythtvSrc * mythtv_src)
   1.296 -{
   1.297 -    mythtv_src->unique_setup = FALSE;
   1.298 -
   1.299 -    if (mythtv_src->spawn_livetv) {
   1.300 -        g_object_unref(mythtv_src->spawn_livetv);
   1.301 -        mythtv_src->spawn_livetv = NULL;
   1.302 -    }
   1.303 -
   1.304 -    if (mythtv_src->file) {
   1.305 -        g_object_unref(mythtv_src->file);
   1.306 -        mythtv_src->file = NULL;
   1.307 -    }
   1.308 -
   1.309 -    if (mythtv_src->backend_info) {
   1.310 -        g_object_unref(mythtv_src->backend_info);
   1.311 -        mythtv_src->backend_info = NULL;
   1.312 -    }
   1.313 -}
   1.314 -
   1.315 -static void
   1.316 -gst_mythtv_src_finalize(GObject * gobject)
   1.317 -{
   1.318 -    GstMythtvSrc   *this = GST_MYTHTV_SRC(gobject);
   1.319 -
   1.320 -    gst_mythtv_src_clear(this);
   1.321 -
   1.322 -    if (this->uri_name) {
   1.323 -        g_free(this->uri_name);
   1.324 -        this->uri_name = NULL;
   1.325 -    }
   1.326 -
   1.327 -    if (this->user_agent) {
   1.328 -        g_free(this->user_agent);
   1.329 -        this->user_agent = NULL;
   1.330 -    }
   1.331 -
   1.332 -    G_OBJECT_CLASS(parent_class)->finalize(gobject);
   1.333 -}
   1.334 -
   1.335 -static GMythFileReadResult
   1.336 -do_read_request_response(GstMythtvSrc * src, guint size,
   1.337 -                         GByteArray * data_ptr)
   1.338 -{
   1.339 -    gint            read = 0;
   1.340 -    guint           sizetoread = size;
   1.341 -    gint            max_iters = GMYTHTV_TRANSFER_MAX_RESENDS;
   1.342 -    GMythFileReadResult result;
   1.343 -
   1.344 -    GST_LOG_OBJECT(src, "Starting: Reading %d bytes...", sizetoread);
   1.345 -
   1.346 -    /*
   1.347 -     * Loop sending the Myth File Transfer request: Retry whilst
   1.348 -     * authentication fails and we supply it. 
   1.349 -     */
   1.350 -
   1.351 -    while (sizetoread == size && --max_iters > 0) {
   1.352 -        /*
   1.353 -         * if ( gmyth_backend_info_is_local_file(src->backend_info) ) 
   1.354 -         */
   1.355 -        if (IS_GMYTH_FILE_LOCAL(src->file))
   1.356 -            result = gmyth_file_local_read(GMYTH_FILE_LOCAL(src->file),
   1.357 -                                           data_ptr, sizetoread,
   1.358 -                                           src->live_tv);
   1.359 -        else if (IS_GMYTH_FILE_TRANSFER(src->file))
   1.360 -            result =
   1.361 -                gmyth_file_transfer_read(GMYTH_FILE_TRANSFER(src->file),
   1.362 -                                         data_ptr, sizetoread,
   1.363 -                                         src->live_tv);
   1.364 -
   1.365 -        if (data_ptr->len > 0) {
   1.366 -            read += data_ptr->len;
   1.367 -            sizetoread -= data_ptr->len;
   1.368 -        } else if (data_ptr->len <= 0) {
   1.369 -            if (src->live_tv == FALSE) {
   1.370 -                result = GMYTH_FILE_READ_EOF;
   1.371 -                goto eos;
   1.372 -            } else {
   1.373 -                if (result == GMYTH_FILE_READ_ERROR) {  /* -314 */
   1.374 -                    GST_INFO_OBJECT(src,
   1.375 -                                    "[LiveTV] FileTransfer READ_ERROR!");
   1.376 -                }
   1.377 -                goto done;
   1.378 -            }
   1.379 -        }
   1.380 -        /*
   1.381 -         * else if (data_ptr->len == 0) goto done; 
   1.382 -         */
   1.383 -        if (read == sizetoread)
   1.384 -            goto done;
   1.385 -    }
   1.386 -
   1.387 -    if ((read < 0 && !src->live_tv) || max_iters == 0) {
   1.388 -        result = GMYTH_FILE_READ_EOF;
   1.389 -        goto eos;
   1.390 -    }
   1.391 -
   1.392 -    goto done;
   1.393 -
   1.394 -  eos:
   1.395 -    src->eos = TRUE;
   1.396 -
   1.397 -  done:
   1.398 -    return result;
   1.399 -}
   1.400 -
   1.401 -static GstFlowReturn
   1.402 -gst_mythtv_src_create(GstPushSrc * psrc, GstBuffer ** outbuf)
   1.403 -{
   1.404 -    GstMythtvSrc  *src;
   1.405 -    GstFlowReturn   ret = GST_FLOW_OK;
   1.406 -    GByteArray *buffer;
   1.407 -    gint buffer_remain = 0;
   1.408 -    GMythFileReadResult result = GMYTH_FILE_READ_OK;
   1.409 -    gboolean buffering = FALSE;
   1.410 -
   1.411 -    src = GST_MYTHTV_SRC(psrc);
   1.412 -
   1.413 -    buffer = g_byte_array_new ();
   1.414 -    if (src->live_tv)
   1.415 -        result = do_read_request_response(src, READ_SIZE_LIVETV, buffer);
   1.416 -    else
   1.417 -        result = do_read_request_response(src, READ_SIZE, buffer);
   1.418 -
   1.419 -    if (result == GMYTH_FILE_READ_ERROR)
   1.420 -        goto read_error;
   1.421 -
   1.422 -
   1.423 -    *outbuf = gst_buffer_new();
   1.424 -    GST_BUFFER_SIZE(*outbuf) = buffer->len;
   1.425 -    GST_BUFFER_MALLOCDATA(*outbuf) = g_malloc0(GST_BUFFER_SIZE(*outbuf));
   1.426 -    GST_BUFFER_DATA(*outbuf) = GST_BUFFER_MALLOCDATA(*outbuf);
   1.427 -    g_memmove(GST_BUFFER_DATA((*outbuf)), buffer->data,
   1.428 -              GST_BUFFER_SIZE(*outbuf));
   1.429 -    GST_BUFFER_OFFSET(*outbuf) = src->read_offset;
   1.430 -    GST_BUFFER_OFFSET_END(*outbuf) =
   1.431 -        src->read_offset + GST_BUFFER_SIZE(*outbuf);
   1.432 -
   1.433 -    src->read_offset += GST_BUFFER_SIZE(*outbuf);
   1.434 -    src->bytes_read += GST_BUFFER_SIZE(*outbuf);
   1.435 -
   1.436 -    g_byte_array_free (buffer, TRUE);
   1.437 -
   1.438 -    if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) {
   1.439 -        GstPad *peer;
   1.440 -
   1.441 -        peer = gst_pad_get_peer (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)));
   1.442 -        gst_pad_send_event (peer,
   1.443 -            gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0));
   1.444 -
   1.445 -        gst_object_unref (peer);
   1.446 -    }
   1.447 -
   1.448 -    if (src->eos  ||
   1.449 -        (!src->live_tv && (src->bytes_read >= src->content_size)))
   1.450 -        ret = GST_FLOW_UNEXPECTED;
   1.451 -
   1.452 -    return ret;
   1.453 -
   1.454 -read_error:
   1.455 -    GST_ELEMENT_ERROR(src, RESOURCE, READ,
   1.456 -        (NULL), ("Could not read any bytes (%i, %s)",
   1.457 -        read, src->uri_name));
   1.458 -    return GST_FLOW_ERROR;
   1.459 -}
   1.460 -
   1.461 -gint64
   1.462 -gst_mythtv_src_get_position(GstMythtvSrc * src)
   1.463 -{
   1.464 -
   1.465 -    gint64          size_tmp = 0;
   1.466 -    guint           max_tries = 2;
   1.467 -
   1.468 -    if (src->live_tv == TRUE && (abs(src->content_size - src->bytes_read) <
   1.469 -                                 GMYTHTV_TRANSFER_MAX_BUFFER)) {
   1.470 -
   1.471 -      get_file_pos:
   1.472 -        g_usleep(10);
   1.473 -        size_tmp =
   1.474 -            gmyth_recorder_get_file_position(src->spawn_livetv->recorder);
   1.475 -        if (size_tmp > (src->content_size + GMYTHTV_TRANSFER_MAX_BUFFER))
   1.476 -            src->content_size = size_tmp;
   1.477 -        else if (size_tmp > 0 && --max_tries > 0)
   1.478 -            goto get_file_pos;
   1.479 -        GST_LOG_OBJECT(src, "GET_POSITION: file_position = %lld",
   1.480 -                       size_tmp);
   1.481 -        /*
   1.482 -         * sets the last content size amount before it can be updated 
   1.483 -         */
   1.484 -        src->prev_content_size = src->content_size;
   1.485 -    }
   1.486 -
   1.487 -    return src->content_size;
   1.488 -
   1.489 -}
   1.490 -
   1.491 -static gboolean
   1.492 -gst_mythtv_src_do_seek(GstBaseSrc * base, GstSegment * segment)
   1.493 -{
   1.494 -    GstMythtvSrc   *src = GST_MYTHTV_SRC(base);
   1.495 -    gint64          new_offset = -1;
   1.496 -    gint64          actual_seek = segment->start;
   1.497 -    gboolean        ret = TRUE;
   1.498 -
   1.499 -    GST_LOG_OBJECT(src, "seek, segment: %" GST_SEGMENT_FORMAT, segment);
   1.500 -
   1.501 -    if (segment->format == GST_FORMAT_TIME) {
   1.502 -        goto done;
   1.503 -    }
   1.504 -    GST_LOG_OBJECT(src,
   1.505 -                   "Trying to seek at the value (actual_seek = %lld, read_offset = %lld)",
   1.506 -                   actual_seek, src->read_offset);
   1.507 -    /*
   1.508 -     * verify if it needs to seek 
   1.509 -     */
   1.510 -    if (src->read_offset != actual_seek) {
   1.511 -
   1.512 -        /*
   1.513 -         * if ( gmyth_backend_info_is_local_file(src->backend_info) ) 
   1.514 -         */
   1.515 -        if (IS_GMYTH_FILE_LOCAL(src->file))
   1.516 -            new_offset =
   1.517 -                gmyth_file_local_seek(GMYTH_FILE_LOCAL(src->file),
   1.518 -                                      segment->start, G_SEEK_SET);
   1.519 -        else if (IS_GMYTH_FILE_TRANSFER(src->file))
   1.520 -            new_offset =
   1.521 -                gmyth_file_transfer_seek(GMYTH_FILE_TRANSFER(src->file),
   1.522 -                                         segment->start, SEEK_SET);
   1.523 -
   1.524 -        GST_LOG_OBJECT(src,
   1.525 -                       "Segment offset start = %lld, SRC Offset = %lld, NEW actual backend SEEK Offset = %lld.",
   1.526 -                       segment->start, src->read_offset, new_offset);
   1.527 -        if (G_UNLIKELY(new_offset < 0)) {
   1.528 -            ret = FALSE;
   1.529 -            if (!src->live_tv)
   1.530 -                goto eos;
   1.531 -        }
   1.532 -
   1.533 -        src->read_offset = new_offset;
   1.534 -
   1.535 -        if (ret == FALSE) {
   1.536 -            GST_INFO_OBJECT(src, "Failed to set the SEEK on segment!");
   1.537 -        }
   1.538 -
   1.539 -    }
   1.540 -
   1.541 -  done:
   1.542 -    return ret;
   1.543 -
   1.544 -  eos:
   1.545 -    {
   1.546 -        GST_DEBUG_OBJECT(src, "EOS found on seeking!!!");
   1.547 -        return FALSE;
   1.548 -    }
   1.549 -
   1.550 -}
   1.551 -
   1.552 -/*
   1.553 - * create a socket for connecting to remote server 
   1.554 - */
   1.555 -static gboolean
   1.556 -gst_mythtv_src_start(GstBaseSrc * bsrc)
   1.557 -{
   1.558 -    GstMythtvSrc   *src = GST_MYTHTV_SRC(bsrc);
   1.559 -
   1.560 -    GString        *chain_id_local = NULL;
   1.561 -    GMythURI       *gmyth_uri = NULL;
   1.562 -    gboolean        ret = TRUE;
   1.563 -    GstMessage     *msg;
   1.564 -
   1.565 -    if (src->unique_setup == FALSE) {
   1.566 -        src->unique_setup = TRUE;
   1.567 -    } else {
   1.568 -        goto done;
   1.569 -    }
   1.570 -
   1.571 -    gmyth_uri = gmyth_uri_new_with_value(src->uri_name);
   1.572 -    src->backend_info = gmyth_backend_info_new_with_uri(src->uri_name);
   1.573 -    src->live_tv = gmyth_uri_is_livetv(gmyth_uri);
   1.574 -
   1.575 -    if (src->live_tv) {
   1.576 -        src->spawn_livetv = gmyth_livetv_new(src->backend_info);
   1.577 -        gchar *ch = gmyth_uri_get_channel_name(gmyth_uri);
   1.578 -        if (ch != NULL)
   1.579 -            src->channel_name = ch;
   1.580 -
   1.581 -        if (src->channel_name != NULL) {
   1.582 -            gboolean        result;
   1.583 -            result =
   1.584 -                gmyth_livetv_channel_name_setup(src->spawn_livetv,
   1.585 -                                                src->channel_name);
   1.586 -            if (result == FALSE) {
   1.587 -                GST_INFO_OBJECT(src, "LiveTV setup felt down on error");
   1.588 -                ret = FALSE;
   1.589 -                goto init_failed;
   1.590 -            }
   1.591 -
   1.592 -        } else {
   1.593 -            if (gmyth_livetv_setup(src->spawn_livetv) == FALSE) {
   1.594 -                GST_INFO_OBJECT(src, "LiveTV setup felt down on error");
   1.595 -                ret = FALSE;
   1.596 -                goto init_failed;
   1.597 -            }
   1.598 -        }
   1.599 -
   1.600 -        /*
   1.601 -         * testing change channel... 
   1.602 -         */
   1.603 -        /*
   1.604 -         * gmyth_recorder_change_channel( src->spawn_livetv->recorder,
   1.605 -         * CHANNEL_DIRECTION_UP ); 
   1.606 -         */
   1.607 -
   1.608 -        src->file =
   1.609 -            GMYTH_FILE(gmyth_livetv_create_file_transfer
   1.610 -                       (src->spawn_livetv));
   1.611 -
   1.612 -
   1.613 -        if (NULL == src->file) {
   1.614 -            GST_INFO_OBJECT(src, "[LiveTV] FileTransfer equals to NULL");
   1.615 -            ret = FALSE;
   1.616 -            goto init_failed;
   1.617 -        }
   1.618 -
   1.619 -        /*
   1.620 -         * Check if the file is local to this specific client renderer 
   1.621 -         */
   1.622 -        if (gmyth_uri_is_local_file(gmyth_uri))
   1.623 -            ret = gmyth_file_local_open(GMYTH_FILE_LOCAL(src->file));
   1.624 -        else
   1.625 -            ret =
   1.626 -                gmyth_file_transfer_open(GMYTH_FILE_TRANSFER(src->file),
   1.627 -                                         src->spawn_livetv->uri !=
   1.628 -                                         NULL ? gmyth_uri_get_path(src->
   1.629 -                                                                   spawn_livetv->
   1.630 -                                                                   uri) :
   1.631 -                                         src->spawn_livetv->proginfo->
   1.632 -                                         pathname->str);
   1.633 -
   1.634 -        /*
   1.635 -         * sets the mythtvsrc "location" property 
   1.636 -         */
   1.637 -        g_object_set(src, "location", gmyth_file_get_uri(src->file), NULL);
   1.638 -
   1.639 -        if (!ret) {
   1.640 -            GST_INFO_OBJECT(src,
   1.641 -                            "Error: couldn't open the FileTransfer from LiveTV source!");
   1.642 -            g_object_unref(src->file);
   1.643 -            src->file = NULL;
   1.644 -            goto init_failed;
   1.645 -        }
   1.646 -    } else {
   1.647 -
   1.648 -        /*
   1.649 -         * Check if the file is local to this specific client renderer,
   1.650 -         * and tries to open a local connection 
   1.651 -         */
   1.652 -        if (gmyth_uri_is_local_file(gmyth_uri)) {
   1.653 -            src->file =
   1.654 -                GMYTH_FILE(gmyth_file_local_new(src->backend_info));
   1.655 -            ret = gmyth_file_local_open(GMYTH_FILE_LOCAL(src->file));
   1.656 -        } else {
   1.657 -            src->file =
   1.658 -                GMYTH_FILE(gmyth_file_transfer_new(src->backend_info));
   1.659 -            ret =
   1.660 -                gmyth_file_transfer_open(GMYTH_FILE_TRANSFER(src->file),
   1.661 -                                         src->uri_name);
   1.662 -        }
   1.663 -
   1.664 -    }                           /* if (else) - recorded FileTransfer */
   1.665 -
   1.666 -    if (NULL == src->file) {
   1.667 -        GST_INFO_OBJECT(src, "FileTransfer is NULL");
   1.668 -        goto init_failed;
   1.669 -    }
   1.670 -    /*
   1.671 -     * GST_INFO_OBJECT( src, "uri = %s", src->spawn_livetv->file); 
   1.672 -     */
   1.673 -
   1.674 -    if (ret == FALSE) {
   1.675 -      GST_INFO_OBJECT(src,
   1.676 -        "MythTV FileTransfer request failed when setting up socket connection!");
   1.677 -      goto begin_req_failed;
   1.678 -    }
   1.679 -
   1.680 -    GST_INFO_OBJECT(src,
   1.681 -                    "MythTV FileTransfer filesize = %lld, content_size = %lld!",
   1.682 -                    gmyth_file_get_filesize(src->file), src->content_size);
   1.683 -
   1.684 -    src->content_size = gmyth_file_get_filesize(src->file);
   1.685 -
   1.686 -    msg =
   1.687 -        gst_message_new_duration(GST_OBJECT(src), GST_FORMAT_BYTES,
   1.688 -                                 src->content_size);
   1.689 -    gst_element_post_message(GST_ELEMENT(src), msg);
   1.690 -
   1.691 -
   1.692 -    src->do_start = FALSE;
   1.693 -
   1.694 -    gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(src)),
   1.695 -                       gst_event_new_new_segment(TRUE, 1.0,
   1.696 -                                                 GST_FORMAT_TIME, 0,
   1.697 -                                                 src->content_size, 0));
   1.698 -
   1.699 -  done:
   1.700 -    if (gmyth_uri != NULL) {
   1.701 -        g_object_unref(gmyth_uri);
   1.702 -        gmyth_uri = NULL;
   1.703 -    }
   1.704 -
   1.705 -    if (chain_id_local != NULL) {
   1.706 -        g_string_free(chain_id_local, TRUE);
   1.707 -        chain_id_local = NULL;
   1.708 -    }
   1.709 -
   1.710 -    return TRUE;
   1.711 -
   1.712 -    /*
   1.713 -     * ERRORS 
   1.714 -     */
   1.715 -  init_failed:
   1.716 -    if (gmyth_uri != NULL) {
   1.717 -        g_object_unref(gmyth_uri);
   1.718 -        gmyth_uri = NULL;
   1.719 -    }
   1.720 -
   1.721 -    if (src->spawn_livetv != NULL) {
   1.722 -        g_object_unref(src->spawn_livetv);
   1.723 -        src->spawn_livetv = NULL;
   1.724 -    }
   1.725 -
   1.726 -    GST_ELEMENT_ERROR(src, LIBRARY, INIT,
   1.727 -                      (NULL),
   1.728 -                      ("Could not initialize MythTV library (%i, %s)", ret,
   1.729 -                       src->uri_name));
   1.730 -
   1.731 -
   1.732 -    gst_mythtv_src_clear(src);
   1.733 -
   1.734 -    return FALSE;
   1.735 -  begin_req_failed:
   1.736 -    if (gmyth_uri != NULL) {
   1.737 -        g_object_unref(gmyth_uri);
   1.738 -        gmyth_uri = NULL;
   1.739 -    }
   1.740 -
   1.741 -    GST_ELEMENT_ERROR(src, LIBRARY, INIT,
   1.742 -                      (NULL),
   1.743 -                      ("Could not begin request sent to MythTV server (%i, %s)",
   1.744 -                       ret, src->uri_name));
   1.745 -    return FALSE;
   1.746 -
   1.747 -}
   1.748 -
   1.749 -static gboolean
   1.750 -gst_mythtv_src_get_size(GstBaseSrc * bsrc, guint64 * size)
   1.751 -{
   1.752 -    GstMythtvSrc   *src = GST_MYTHTV_SRC(bsrc);
   1.753 -    gboolean        ret = TRUE;
   1.754 -
   1.755 -    GST_LOG_OBJECT(src,
   1.756 -                   "Differs from previous content size: %d (max.: %d)",
   1.757 -                   abs(src->content_size - src->prev_content_size),
   1.758 -                   GMYTHTV_TRANSFER_MAX_BUFFER);
   1.759 -
   1.760 -    if (src->live_tv) {
   1.761 -        ret = FALSE;
   1.762 -    } else if (src->live_tv && src->enable_timing_position
   1.763 -               && (abs(src->content_size - src->bytes_read) <
   1.764 -                   GMYTHTV_TRANSFER_MAX_BUFFER)) {
   1.765 -
   1.766 -        gint64          new_offset =
   1.767 -            gmyth_recorder_get_file_position(src->spawn_livetv->recorder);
   1.768 -        if (new_offset > 0 && new_offset > src->content_size) {
   1.769 -            src->content_size = new_offset;
   1.770 -        } else if (new_offset < src->content_size) {
   1.771 -            src->update_prog_chain = TRUE;
   1.772 -        }
   1.773 -
   1.774 -    }
   1.775 -
   1.776 -    *size = src->content_size;
   1.777 -    GST_LOG_OBJECT(src, "Content size = %lld", src->content_size);
   1.778 -
   1.779 -    return ret;
   1.780 -
   1.781 -}
   1.782 -
   1.783 -/*
   1.784 - * close the socket and associated resources used both to recover from
   1.785 - * errors and go to NULL state 
   1.786 - */
   1.787 -static gboolean
   1.788 -gst_mythtv_src_stop(GstBaseSrc * bsrc)
   1.789 -{
   1.790 -    GstMythtvSrc   *src = GST_MYTHTV_SRC(bsrc);
   1.791 -
   1.792 -    gst_mythtv_src_clear(src);
   1.793 -    return TRUE;
   1.794 -}
   1.795 -
   1.796 -static gboolean
   1.797 -gst_mythtv_src_handle_event(GstPad * pad, GstEvent * event)
   1.798 -{
   1.799 -    GstMythtvSrc   *src = GST_MYTHTV_SRC(GST_PAD_PARENT(pad));
   1.800 -    gint64          cont_size = 0;
   1.801 -    gboolean        ret = TRUE;
   1.802 -
   1.803 -    switch (GST_EVENT_TYPE(event)) {
   1.804 -      case GST_EVENT_EOS:
   1.805 -        if (src->live_tv) {
   1.806 -          cont_size = gst_mythtv_src_get_position(src);
   1.807 -          if (cont_size > src->content_size) {
   1.808 -            src->content_size = cont_size;
   1.809 -            src->eos = FALSE;
   1.810 -          } else {
   1.811 -            src->eos = TRUE;
   1.812 -            gst_element_set_state(GST_ELEMENT(src), GST_STATE_NULL);
   1.813 -            gst_element_set_locked_state(GST_ELEMENT(src), FALSE);
   1.814 -          }
   1.815 -        }
   1.816 -        break;
   1.817 -    default:
   1.818 -        ret = gst_pad_event_default(pad, event);
   1.819 -    }
   1.820 -
   1.821 -    GST_DEBUG_OBJECT (src, "HANDLE EVENT %d", ret);
   1.822 -    return ret;
   1.823 -}
   1.824 -
   1.825 -static gboolean
   1.826 -gst_mythtv_src_is_seekable(GstBaseSrc * push_src)
   1.827 -{
   1.828 -    return TRUE;
   1.829 -}
   1.830 -
   1.831 -static gboolean
   1.832 -gst_mythtv_src_handle_query(GstPad * pad, GstQuery * query)
   1.833 -{
   1.834 -    gboolean        res = FALSE;
   1.835 -    GstMythtvSrc   *myth = GST_MYTHTV_SRC(gst_pad_get_parent(pad));
   1.836 -    GstFormat       formt;
   1.837 -
   1.838 -
   1.839 -    switch (GST_QUERY_TYPE(query)) {
   1.840 -      case GST_QUERY_POSITION:
   1.841 -        gst_query_parse_position(query, &formt, NULL);
   1.842 -        if (formt == GST_FORMAT_BYTES) {
   1.843 -          gst_query_set_position(query, formt, myth->read_offset);
   1.844 -          GST_DEBUG_OBJECT(myth, "POS %" G_GINT64_FORMAT,
   1.845 -              myth->read_offset);
   1.846 -          res = TRUE;
   1.847 -        } else if (formt == GST_FORMAT_TIME) {
   1.848 -          res = gst_pad_query_default(pad, query);
   1.849 -        }
   1.850 -        break;
   1.851 -      case GST_QUERY_DURATION:
   1.852 -        gst_query_parse_duration(query, &formt, NULL);
   1.853 -        if (formt == GST_FORMAT_BYTES) {
   1.854 -          gint64 size = myth->content_size;
   1.855 -
   1.856 -          gst_query_set_duration(query, GST_FORMAT_BYTES, 10);
   1.857 -          GST_DEBUG_OBJECT(myth, "SIZE %" G_GINT64_FORMAT, size);
   1.858 -          res = TRUE;
   1.859 -        } else if (formt == GST_FORMAT_TIME) {
   1.860 -          res = gst_pad_query_default(pad, query);
   1.861 -        }
   1.862 -        break;
   1.863 -      default:
   1.864 -        res = gst_pad_query_default(pad, query);
   1.865 -        break;
   1.866 -    }
   1.867 -
   1.868 -    gst_object_unref(myth);
   1.869 -
   1.870 -    return res;
   1.871 -}
   1.872 -
   1.873 -static GstStateChangeReturn
   1.874 -gst_mythtv_src_change_state(GstElement * element,
   1.875 -                            GstStateChange transition)
   1.876 -{
   1.877 -    GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
   1.878 -    GstMythtvSrc  *src = GST_MYTHTV_SRC(element);
   1.879 -
   1.880 -    switch (transition) {
   1.881 -    case GST_STATE_CHANGE_NULL_TO_READY:
   1.882 -        break;
   1.883 -    case GST_STATE_CHANGE_READY_TO_PAUSED:
   1.884 -      if (!src->uri_name) {
   1.885 -        GST_WARNING_OBJECT (src, "Invalid location");
   1.886 -        return ret;
   1.887 -      }
   1.888 -      break;
   1.889 -    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
   1.890 -      if (src->live_tv) {
   1.891 -        if (!gmyth_recorder_send_frontend_ready_command
   1.892 -            (src->spawn_livetv->recorder))
   1.893 -          GST_WARNING_OBJECT(src,
   1.894 -              "Couldn't send the FRONTEND_READY message to the backend!");
   1.895 -        else
   1.896 -          GST_DEBUG_OBJECT(src, "FRONTEND_READY was sent to the backend");
   1.897 -      }
   1.898 -      break;
   1.899 -    default:
   1.900 -        break;
   1.901 -    }
   1.902 -
   1.903 -    ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
   1.904 -    if (ret == GST_STATE_CHANGE_FAILURE) {
   1.905 -        return ret;
   1.906 -    }
   1.907 -
   1.908 -
   1.909 -    switch (transition) {
   1.910 -    case GST_STATE_CHANGE_READY_TO_NULL:
   1.911 -        gst_mythtv_src_clear(src);
   1.912 -        break;
   1.913 -    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
   1.914 -    case GST_STATE_CHANGE_PAUSED_TO_READY:
   1.915 -        break;
   1.916 -    default:
   1.917 -        break;
   1.918 -    }
   1.919 -
   1.920 -    return ret;
   1.921 -}
   1.922 -
   1.923 -static void
   1.924 -gst_mythtv_src_set_property(GObject * object, guint prop_id,
   1.925 -                            const GValue * value, GParamSpec * pspec)
   1.926 -{
   1.927 -    GstMythtvSrc   *mythtvsrc = GST_MYTHTV_SRC(object);
   1.928 -
   1.929 -    GST_OBJECT_LOCK(mythtvsrc);
   1.930 -    switch (prop_id) {
   1.931 -      case PROP_LOCATION:
   1.932 -        if (!g_value_get_string(value)) {
   1.933 -          GST_WARNING("location property cannot be NULL");
   1.934 -          break;
   1.935 -        }
   1.936 -
   1.937 -        if (mythtvsrc->uri_name != NULL) {
   1.938 -          g_free(mythtvsrc->uri_name);
   1.939 -          mythtvsrc->uri_name = NULL;
   1.940 -        }
   1.941 -        mythtvsrc->uri_name = g_value_dup_string(value);
   1.942 -        break;
   1.943 -      case PROP_GMYTHTV_VERSION:
   1.944 -        mythtvsrc->mythtv_version = g_value_get_int(value);
   1.945 -        break;
   1.946 -      case PROP_GMYTHTV_LIVEID:
   1.947 -        mythtvsrc->live_tv_id = g_value_get_int(value);
   1.948 -        break;
   1.949 -      case PROP_GMYTHTV_LIVE:
   1.950 -        mythtvsrc->live_tv = g_value_get_boolean(value);
   1.951 -        break;
   1.952 -      case PROP_GMYTHTV_ENABLE_TIMING_POSITION:
   1.953 -         mythtvsrc->enable_timing_position = g_value_get_boolean(value);
   1.954 -         break;
   1.955 -      case PROP_GMYTHTV_LIVE_CHAINID:
   1.956 -         if (!g_value_get_string(value)) {
   1.957 -            GST_WARNING_OBJECT(object, "MythTV Live chainid property cannot be NULL");
   1.958 -            break;
   1.959 -         }
   1.960 -
   1.961 -         if (mythtvsrc->live_chain_id != NULL) {
   1.962 -           g_free(mythtvsrc->live_chain_id);
   1.963 -           mythtvsrc->live_chain_id = NULL;
   1.964 -         }
   1.965 -         mythtvsrc->live_chain_id = g_value_dup_string(value);
   1.966 -         break;
   1.967 -      case PROP_GMYTHTV_CHANNEL_NUM:
   1.968 -        mythtvsrc->channel_name = g_value_dup_string(value);
   1.969 -        break;
   1.970 -      default:
   1.971 -        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
   1.972 -        break;
   1.973 -    }
   1.974 -
   1.975 -    GST_OBJECT_UNLOCK(mythtvsrc);
   1.976 -}
   1.977 -
   1.978 -static void
   1.979 -gst_mythtv_src_get_property(GObject * object, guint prop_id,
   1.980 -                            GValue * value, GParamSpec * pspec)
   1.981 -{
   1.982 -    GstMythtvSrc   *mythtvsrc = GST_MYTHTV_SRC(object);
   1.983 -
   1.984 -    GST_OBJECT_LOCK(mythtvsrc);
   1.985 -    switch (prop_id) {
   1.986 -      case PROP_LOCATION:
   1.987 -        g_value_set_string(value, mythtvsrc->uri_name);
   1.988 -        break;
   1.989 -      case PROP_GMYTHTV_VERSION:
   1.990 -        g_value_set_int(value, mythtvsrc->mythtv_version);
   1.991 -        break;
   1.992 -      case PROP_GMYTHTV_LIVEID:
   1.993 -        g_value_set_int(value, mythtvsrc->live_tv_id);
   1.994 -        break;
   1.995 -      case PROP_GMYTHTV_LIVE:
   1.996 -        g_value_set_boolean(value, mythtvsrc->live_tv);
   1.997 -        break;
   1.998 -      case PROP_GMYTHTV_ENABLE_TIMING_POSITION:
   1.999 -        g_value_set_boolean(value, mythtvsrc->enable_timing_position);
  1.1000 -        break;
  1.1001 -      case PROP_GMYTHTV_LIVE_CHAINID:
  1.1002 -        g_value_set_string(value, mythtvsrc->live_chain_id);
  1.1003 -        break;
  1.1004 -      case PROP_GMYTHTV_CHANNEL_NUM:
  1.1005 -        g_value_set_string(value, mythtvsrc->channel_name);
  1.1006 -        break;
  1.1007 -    default:
  1.1008 -        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
  1.1009 -        break;
  1.1010 -    }
  1.1011 -    GST_OBJECT_UNLOCK(mythtvsrc);
  1.1012 -}
  1.1013 -
  1.1014 -static gboolean
  1.1015 -plugin_init(GstPlugin * plugin)
  1.1016 -{
  1.1017 -    return gst_element_register(plugin, "mythtvsrc", GST_RANK_NONE,
  1.1018 -                                GST_TYPE_MYTHTV_SRC);
  1.1019 -}
  1.1020 -
  1.1021 -GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
  1.1022 -                  GST_VERSION_MINOR,
  1.1023 -                  "mythtv",
  1.1024 -                  "lib MythTV src",
  1.1025 -                  plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME,
  1.1026 -                  GST_PACKAGE_ORIGIN);
  1.1027 -
  1.1028 -
  1.1029 -/*** GSTURIHANDLER INTERFACE *************************************************/
  1.1030 -static guint
  1.1031 -gst_mythtv_src_uri_get_type(void)
  1.1032 -{
  1.1033 -    return GST_URI_SRC;
  1.1034 -}
  1.1035 -
  1.1036 -static gchar  **
  1.1037 -gst_mythtv_src_uri_get_protocols(void)
  1.1038 -{
  1.1039 -    static gchar   *protocols[] = { "myth", "myths", NULL };
  1.1040 -
  1.1041 -    return protocols;
  1.1042 -}
  1.1043 -
  1.1044 -static const gchar *
  1.1045 -gst_mythtv_src_uri_get_uri(GstURIHandler * handler)
  1.1046 -{
  1.1047 -    GstMythtvSrc   *src = GST_MYTHTV_SRC(handler);
  1.1048 -
  1.1049 -    return src->uri_name;
  1.1050 -}
  1.1051 -
  1.1052 -static gboolean
  1.1053 -gst_mythtv_src_uri_set_uri(GstURIHandler * handler, const gchar * uri)
  1.1054 -{
  1.1055 -    GstMythtvSrc   *src = GST_MYTHTV_SRC(handler);
  1.1056 -
  1.1057 -    gchar          *protocol;
  1.1058 -
  1.1059 -    protocol = gst_uri_get_protocol(uri);
  1.1060 -    if ((strcmp(protocol, "myth") != 0)
  1.1061 -        && (strcmp(protocol, "myths") != 0)) {
  1.1062 -        g_free(protocol);
  1.1063 -        return FALSE;
  1.1064 -    }
  1.1065 -    g_free(protocol);
  1.1066 -    g_object_set(src, "location", uri, NULL);
  1.1067 -
  1.1068 -    return TRUE;
  1.1069 -}
  1.1070 -
  1.1071 -static void
  1.1072 -gst_mythtv_src_uri_handler_init(gpointer g_iface, gpointer iface_data)
  1.1073 -{
  1.1074 -    GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
  1.1075 -
  1.1076 -    iface->get_type = gst_mythtv_src_uri_get_type;
  1.1077 -    iface->get_protocols = gst_mythtv_src_uri_get_protocols;
  1.1078 -    iface->get_uri = gst_mythtv_src_uri_get_uri;
  1.1079 -    iface->set_uri = gst_mythtv_src_uri_set_uri;
  1.1080 -}
  1.1081 -
  1.1082 -void
  1.1083 -size_header_handler(void *userdata, const char *value)
  1.1084 -{
  1.1085 -    GstMythtvSrc   *src = GST_MYTHTV_SRC(userdata);
  1.1086 -
  1.1087 -    GST_DEBUG_OBJECT(src, "content size = %lld bytes", src->content_size);
  1.1088 -}