# HG changeset patch # User rosfran # Date 1160614227 -3600 # Node ID abe0ee48d78b4380c200e6337b54f60f08311317 # Parent 081274382473b4ff09fd77d9f7526e9a7f803e74 [svn r31] Some changes, in order to use the newly added nuvdemux features. diff -r 081274382473 -r abe0ee48d78b gst-plugins-mythtv/src/gstmythtvsrc.c --- a/gst-plugins-mythtv/src/gstmythtvsrc.c Wed Oct 11 22:46:27 2006 +0100 +++ b/gst-plugins-mythtv/src/gstmythtvsrc.c Thu Oct 12 01:50:27 2006 +0100 @@ -3,8 +3,8 @@ * Copyright (C) <2006> Rosfran Borges * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either + * modify it under the terms of the GNU Library Lesser General + * Public License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, @@ -36,10 +36,12 @@ #define MYTHTV_TRANSFER_MAX_WAITS 100 -#define MYTHTV_TRANSFER_MAX_BUFFER ( 32*1024 ) +#define MYTHTV_TRANSFER_MAX_BUFFER 32*1024 +//( 32*1024 ) /* 4*1024 ??? */ -#define MAX_READ_SIZE ( 16*1024 ) +#define MAX_READ_SIZE 12*1024 +//( 32*1024 ) #define ENABLE_TIMING_POSITION 1 @@ -47,15 +49,20 @@ static guint wait_to_transfer = 0; static const GstElementDetails gst_mythtv_src_details = -GST_ELEMENT_DETAILS ("MythTV client source", +GST_ELEMENT_DETAILS ( "MythTV client source", "Source/Network", "Control and receive data as a client over the network via raw socket connections using the MythTV protocol", - "Rosfran Borges "); + "Rosfran Borges " ); static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); + GST_STATIC_CAPS ("video/x-nuv") ); + //GST_STATIC_CAPS_ANY); + +static GThread *update_size_task = NULL; + +static GStaticMutex update_size_mutex = G_STATIC_MUTEX_INIT; enum { @@ -73,23 +80,30 @@ static void gst_mythtv_src_finalize (GObject * gobject); -static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc, - guint64 offset, guint size, GstBuffer ** outbuf); +static GstFlowReturn gst_mythtv_src_create (GstBaseSrc * psrc, guint64 offset, + guint size, GstBuffer ** outbuf); +//static GstFlowReturn gst_mythtv_src_create (GstPushSrc * psrc, GstBuffer ** outbuf); static gboolean gst_mythtv_src_start (GstBaseSrc * bsrc); static gboolean gst_mythtv_src_stop (GstBaseSrc * bsrc); static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size); -static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *base_src ); +static gboolean gst_mythtv_src_is_seekable( GstBaseSrc *push_src ); +//static gboolean gst_mythtv_new_segment ( GstBaseSrc * psrc ); static void gst_mythtv_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_mythtv_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void -gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data); +//static GstFlowReturn gst_mythtv_src_chain (GstPad * pad, GstBuffer * buf); -static gboolean -gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event); +static void gst_mythtv_src_uri_handler_init (gpointer g_iface, gpointer iface_data); + +//static gboolean gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event); +//static gboolean gst_mythtv_src_query ( GstPad * pad, GstQuery * query ); + +static guint do_read_request_response (GstMythtvSrc *src, guint64 offset, + guint size, GstBuffer **outbuf); +//static gboolean gst_mythtv_src_sink_activate_pull (GstPad * srcpad, gboolean active); static void _urihandler_init (GType type) @@ -107,8 +121,11 @@ } GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstBaseSrc, - GST_TYPE_BASE_SRC, _urihandler_init); - + GST_TYPE_BASE_SRC, _urihandler_init) + +//GST_BOILERPLATE_FULL (GstMythtvSrc, gst_mythtv_src, GstPushSrc, +// GST_TYPE_PUSH_SRC, _urihandler_init) + static void gst_mythtv_src_base_init (gpointer g_class) { @@ -120,14 +137,16 @@ gst_element_class_set_details (element_class, &gst_mythtv_src_details); } - static void +static void gst_mythtv_src_class_init (GstMythtvSrcClass * klass) { GObjectClass *gobject_class; + //GstPushSrcClass *gstpushsrc_class; GstBaseSrcClass *gstbasesrc_class; gobject_class = (GObjectClass *) klass; gstbasesrc_class = (GstBaseSrcClass *) klass; + //gstpushsrc_class = (GstPushSrcClass *) klass; gobject_class->set_property = gst_mythtv_src_set_property; gobject_class->get_property = gst_mythtv_src_get_property; @@ -184,15 +203,15 @@ gstbasesrc_class->stop = gst_mythtv_src_stop; gstbasesrc_class->get_size = gst_mythtv_src_get_size; gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable; + //gstpushsrc_class->newsegment = gst_mythtv_src_new_segment; gstbasesrc_class->create = gst_mythtv_src_create; - - + GST_DEBUG_CATEGORY_INIT (mythtvsrc_debug, "mythtvsrc", 0, "MythTV Client Source"); } - static void +static void gst_mythtv_src_init (GstMythtvSrc * this, GstMythtvSrcClass * g_class) { this->file_transfer = NULL; @@ -209,14 +228,29 @@ this->live_tv = FALSE; this->user_agent = g_strdup ("mythtvsrc"); - this->mythtv_caps = NULL; + this->mythtv_caps = NULL; + + gst_base_src_set_format( GST_BASE_SRC( this ), GST_FORMAT_BYTES ); - gst_pad_set_event_function (GST_BASE_SRC_PAD(GST_BASE_SRC(this)), - GST_DEBUG_FUNCPTR (gst_mythtv_src_handle_event)); + gst_base_src_set_live ( GST_BASE_SRC( this ), TRUE ); + + //gst_pad_set_chain_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)), + // gst_mythtv_src_chain ); + +/* + gst_pad_set_event_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)), + gst_mythtv_src_handle_event ); + + gst_pad_set_query_function ( GST_BASE_SRC_PAD(GST_BASE_SRC(this)), + gst_mythtv_src_query ); +*/ + //gst_pad_set_activatepull_function( GST_BASE_SRC_PAD(GST_BASE_SRC(this)), + // gst_mythtv_src_sink_activate_pull ); + } - static void +static void gst_mythtv_src_finalize (GObject * gobject) { GstMythtvSrc *this = GST_MYTHTV_SRC (gobject); @@ -244,172 +278,146 @@ G_OBJECT_CLASS (parent_class)->finalize (gobject); } -#if 0 - static guint -do_seek( GstMythtvSrc *src, guint64 offset, guint size, GstBuffer *outbuf ) -{ - guint64 off_uint64 = myth_file_transfer_seek(src->file_transfer, offset, 1); - - g_print( "[%s] Call MythTV SEEK with offset %llu, got a new one %llu...\n", __FUNCTION__, - offset, off_uint64 ); - - return off_uint64; - -} -#endif - - static guint -do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer * outbuf) +static guint +do_read_request_response (GstMythtvSrc * src, guint64 offset, guint size, GstBuffer **outbuf) { guint read = 0; guint sizetoread = size; //GST_BUFFER_SIZE (outbuf); + GstBuffer *buffer = gst_buffer_new_and_alloc( size ); - g_print( "[%s] Reading %d bytes...\n", __FUNCTION__, sizetoread ); + g_print( "Starting: [%s] Reading %d bytes...\n", __FUNCTION__, sizetoread ); - /* Loop sending the request: + /* Loop sending the Myth File Transfer request: * Retry whilst authentication fails and we supply it. */ + guint len = 0; - ssize_t len = 0; - - GST_OBJECT_LOCK(src); + //GST_OBJECT_LOCK(src); while ( sizetoread > 0 ) { len = myth_file_transfer_read( src->file_transfer, - GST_BUFFER_DATA (outbuf) + read, sizetoread, TRUE ); + GST_BUFFER_DATA( buffer ) + read, sizetoread, TRUE ); if ( len > 0 ) { read += len; src->read_offset += read; sizetoread -= len; - } else if ( len < 0 ) { - goto done; + } else if ( len <= 0 ) { + + if ( src->live_tv == FALSE ) { + goto done; + } else if ( src->content_size >= src->read_offset && + abs ( src->content_size - src->read_offset ) <= MYTHTV_TRANSFER_MAX_BUFFER ) { + guint64 new_offset = myth_file_transfer_get_file_position( src->file_transfer ); + if ( src->content_size < new_offset ) { + src->content_size = new_offset; + goto done; + } else + goto eos; + } else + goto eos; + } - /*else if ( len == 0 ) { - goto eos; - }*/ - if ( len == sizetoread ) + if ( read == sizetoread ) break; - } - + if ( read > 0 ) { src->bytes_read += read; - - GST_BUFFER_SIZE (outbuf) = read; - } else if ( read <= 0 || len <= 0 ) { - if ( src->live_tv == FALSE ) - goto eos; - else - goto done; } - //GST_BUFFER_OFFSET (outbuf) = src->read_offset; g_print( "[%s]\tBYTES READ (actual) = %d, BYTES READ (cumulative) = %llu, "\ "OFFSET = %llu, CONTENT SIZE = %llu.\n", __FUNCTION__, read, src->bytes_read, src->read_offset, src->content_size ); - GST_OBJECT_UNLOCK(src); - - if ( len < 0 ) { - read = len; - if ( src->live_tv == FALSE ) - goto eos; - else - goto done; - } - - if ( src->bytes_read < src->content_size ) - goto done; + *outbuf = buffer; + memcpy( GST_BUFFER_DATA( *outbuf ), GST_BUFFER_DATA( buffer ), read ); + GST_BUFFER_SIZE (buffer) = read; + GST_BUFFER_OFFSET (buffer) = offset; + GST_BUFFER_OFFSET_END (buffer) = offset + read; + + g_print( "Stopping: [%s]\t\tBUFFER --->SIZE = %d, OFFSET = %llu, "\ + "OFFSET_END = %llu.\n\n", __FUNCTION__, GST_BUFFER_SIZE (*outbuf), + GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf) ); + //GST_OBJECT_UNLOCK(src); + goto done; eos: - GST_OBJECT_UNLOCK(src); + //GST_OBJECT_UNLOCK(src); src->eos = TRUE; + done: - GST_OBJECT_UNLOCK(src); return read; } - static GstFlowReturn -gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset, - guint size, GstBuffer **outbuf ) +static GstFlowReturn +gst_mythtv_src_create ( GstBaseSrc * psrc, guint64 offset, guint size, GstBuffer **outbuf) { GstMythtvSrc *src; GstFlowReturn ret = GST_FLOW_OK; - guint read; - guint64 size_tmp = 0; + guint read = 0; + //GstBuffer *buffer = NULL; + //guint size = MAX_READ_SIZE; + + src = GST_MYTHTV_SRC (psrc); + + if ( src->content_size >= src->read_offset && + abs ( src->content_size - src->read_offset ) <= MYTHTV_TRANSFER_MAX_BUFFER ) { + guint64 new_offset = myth_file_transfer_get_file_position( src->file_transfer ); + if ( src->content_size < new_offset ) { + src->content_size = new_offset; + } + } - src = GST_MYTHTV_SRC (psrc); + if (G_UNLIKELY (src->read_offset != offset)) { + guint64 new_offset = myth_file_transfer_seek(src->file_transfer, offset, SEEK_SET); - g_print( "[%s]\tBUFFER OFFSET = %llu, BUFFER SIZE = %d.\n", __FUNCTION__, offset, - size ); + if (G_UNLIKELY (new_offset < 0 || new_offset != offset)) + goto read_error; - + src->read_offset = offset; + } + /* The caller should know the number of bytes and not read beyond EOS. */ if (G_UNLIKELY (src->eos)) goto eos; /* Create the buffer. */ - ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)), - // GST_BUFFER_OFFSET_NONE, GST_BASE_SRC (psrc)->blocksize, - offset, size, - src->mythtv_caps ? src->mythtv_caps : - GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf ); + //ret = gst_pad_alloc_buffer ( GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)), + // GST_BUFFER_OFFSET_NONE, size, src->mythtv_caps ? src->mythtv_caps : + // GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))), outbuf ); + + //if (G_UNLIKELY (ret != GST_FLOW_OK)) + // goto eos; + //if (G_UNLIKELY (ret == GST_FLOW_ERROR)) + // goto read_error; + + g_static_mutex_lock( &update_size_mutex ); + read = do_read_request_response ( src, 0, size, outbuf ); + g_static_mutex_unlock( &update_size_mutex ); - if (G_UNLIKELY (ret == GST_FLOW_UNEXPECTED)) - goto eos; - - if (G_UNLIKELY (ret != GST_FLOW_OK)) - goto done; - - read = do_read_request_response ( src, offset, size, *outbuf ); - -#if ENABLE_TIMING_POSITION == 1 - if (src->live_tv == TRUE) { - //g_usleep( 1000 ); -get_file_pos: - //g_usleep( 100 ); - size_tmp = myth_file_transfer_get_file_position( src->file_transfer ); - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) ) - src->content_size = size_tmp; - else - goto get_file_pos; - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", - __FUNCTION__, size_tmp); - - } -#endif - - if (G_UNLIKELY (read < 0)) + if (G_UNLIKELY (read < 0) || *outbuf == NULL) goto read_error; + gst_buffer_set_caps( *outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))) ); + + //*outbuf = buffer; + if (G_UNLIKELY(src->eos)) goto eos; + else + goto done; done: return ret; eos: -#if ENABLE_TIMING_POSITION == 1 - if ( src->live_tv == TRUE ) { - //g_usleep( 1000 ); - guint64 size_tmp = 0; -get_file_pos_eos: - //g_usleep( 100 ); - size_tmp = myth_file_transfer_get_file_position( src->file_transfer ); - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) ) - src->content_size = size_tmp; - else - goto get_file_pos_eos; - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", - __FUNCTION__, size_tmp); - goto done; - } else -#endif { - GST_DEBUG_OBJECT (src, "EOS reached"); + const gchar *reason = gst_flow_get_name (ret); + + GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason); return GST_FLOW_UNEXPECTED; } /* ERRORS */ @@ -420,48 +428,76 @@ src->uri_name)); return GST_FLOW_ERROR; } + +#if 0 +need_pause: + { + const gchar *reason = gst_flow_get_name (ret); + + GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason); + return GST_FLOW_UNEXPECTED; + } +#endif } -#if 0 -/* The following two charset mangling functions were copied from gnomevfssrc. - * Preserve them under the unverified assumption that they do something vaguely - * worthwhile. - */ - static char * -unicodify (const char *str, int len, ...) +void +update_size_func( void *mythtv_data ) { - char *ret = NULL, *cset; - va_list args; - gsize bytes_read, bytes_written; + GstMythtvSrc *src; - if (g_utf8_validate (str, len, NULL)) - return g_strndup (str, len >= 0 ? len : strlen (str)); + g_return_if_fail( mythtv_data != NULL ); - va_start (args, len); - while ((cset = va_arg (args, char *)) != NULL) - { - if (!strcmp (cset, "locale")) - ret = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, NULL); - else - ret = g_convert (str, len, "UTF-8", cset, - &bytes_read, &bytes_written, NULL); - if (ret) - break; + src = GST_MYTHTV_SRC ( mythtv_data ); + + g_static_mutex_lock( &update_size_mutex ); + + if ( src->do_start ) { +#if ENABLE_TIMING_POSITION == 1 + guint64 size_tmp = 0; + if (src->live_tv == TRUE) { +get_file_pos: + g_usleep( 50 ); + size_tmp = myth_file_transfer_get_file_position( src->file_transfer ); + if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) ) + src->content_size = size_tmp; + else + goto get_file_pos; + g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", + __FUNCTION__, size_tmp ); + } +#endif } - va_end (args); + g_static_mutex_unlock( &update_size_mutex ); - return ret; } - static char * -gst_mythtv_src_unicodify (const char *str) +guint64 +gst_mythtv_src_get_position ( GstMythtvSrc* src ) { - return unicodify (str, -1, "locale", "ISO-8859-1", NULL); + + if ( src->do_start ) { +#if ENABLE_TIMING_POSITION == 1 + guint64 size_tmp = 0; + if (src->live_tv == TRUE) { +get_file_pos: + g_usleep( 50 ); + size_tmp = myth_file_transfer_get_file_position( src->file_transfer ); + if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) ) + src->content_size = size_tmp; + else + goto get_file_pos; + g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", + __FUNCTION__, size_tmp ); + } +#endif + } + + return src->content_size; + } -#endif /* create a socket for connecting to remote server */ - static gboolean +static gboolean gst_mythtv_src_start ( GstBaseSrc * bsrc ) { GstMythtvSrc *src = GST_MYTHTV_SRC (bsrc); @@ -469,15 +505,7 @@ GString *chain_id_local = NULL; gboolean ret = TRUE; -#if 0 - if (src->live_tv == TRUE && src->file_transfer != NULL) { - guint64 size_tmp = myth_file_transfer_get_file_position( src->file_transfer ); - if (size_tmp > src->content_size) - src->content_size = size_tmp; - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", - __FUNCTION__, size_tmp); - } -#endif + if (src->unique_setup == FALSE) { src->unique_setup = TRUE; } else { @@ -489,8 +517,8 @@ if ( src->live_tv ) { src->spawn_livetv = myth_livetv_new( ); if ( myth_livetv_setup( src->spawn_livetv ) == FALSE ) { - ret = FALSE; - goto init_failed; + ret = FALSE; + goto init_failed; } /* set up the uri variable */ src->uri_name = g_strdup( src->spawn_livetv->proginfo->pathname->str ); @@ -544,70 +572,143 @@ src->content_size = src->file_transfer->filesize; GST_OBJECT_UNLOCK(src); + if ( src->live_tv ) { + + //GError* error; + + //update_size_task = g_thread_create( (GThreadFunc)update_size_func, src, FALSE, &error ); + + g_print( "[%s] Update Size task = %s\n", __FUNCTION__, update_size_task != NULL ? "OK !" : "ERROR!!!" ); + + } + src->do_start = TRUE; + +done: + return TRUE; + + /* ERRORS */ +init_failed: + { + if (src->spawn_livetv != NULL ) + g_object_unref( src->spawn_livetv ); + + GST_ELEMENT_ERROR (src, LIBRARY, INIT, + (NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name)); + return FALSE; + } +begin_req_failed: + { + GST_ELEMENT_ERROR (src, LIBRARY, INIT, + (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name)); + return FALSE; + } +} #if 0 - const char *str_value; - gint gint_value; +/* handles queries for location in the stream in the requested format */ +static gboolean +gst_mythtv_src_query ( GstPad * pad, GstQuery * query ) +{ + gboolean res = TRUE; + GstMythtvSrc *mythtv; - str_value = ne_get_response_header (src->request, "myth-metaint"); - if (str_value) { - if ( sscanf (str_value, "%d", &gint_value) == 1 ) { - if (src->myth_caps) { - gst_caps_unref (src->myth_caps); - src->myth_caps = NULL; + guint64 size = 0; + + mythtv = GST_MYTHTV_SRC( GST_PAD_PARENT (pad) ); + + size = gst_mythtv_src_get_position (mythtv); + + switch (GST_QUERY_TYPE (query)) { + + case GST_QUERY_POSITION: + { + + //GstFormat format; + gint64 cur = 0; + + /* save requested format */ + gst_query_parse_position (query, NULL, &cur); + + /* query peer for current position in time */ + g_print( "[%s] Actual size is %s than current size from sink. [ %lld, %lld ]\n", __FUNCTION__, + ( size > cur ) ? "greater" : "lower", size, cur ); + gst_query_set_position (query, GST_FORMAT_BYTES, size); + if ( size < cur ) + goto error; + + break; } - src->myth_metaint = gint_value; + #if 0 + case GST_QUERY_DURATION: + { + //GstFormat format; + gint64 cur = 0; + + /* save requested format */ + gst_query_parse_position (query, NULL, &cur); + + /* query peer for current position in time */ + g_print( "[%s] Actual size is %s than current size from sink. [ %lld, %lld ]\n", __FUNCTION__, + ( size * GST_SECOND > cur * GST_SECOND ) ? "greater" : "lower", size * GST_SECOND, + cur * GST_SECOND ); + gst_query_set_position (query, GST_FORMAT_TIME, size * GST_SECOND ); + + if ( size * GST_SECOND < cur * GST_SECOND ) + goto error; + + break; + } + #endif + default: + res = FALSE; + break; + } + + return res; + +error: + + return FALSE; +} #endif - //src->mythtv_caps = gst_caps_new_simple ("application/x-gst_ff-nuv", NULL); - // } - // } -done: - return TRUE; - /* ERRORS */ -init_failed: - { - if (src->spawn_livetv != NULL ) - g_object_unref( src->spawn_livetv ); - - GST_ELEMENT_ERROR (src, LIBRARY, INIT, - (NULL), ("Could not initialize MythTV library (%i, %s)", ret, src->uri_name)); - return FALSE; - } -begin_req_failed: - { - GST_ELEMENT_ERROR (src, LIBRARY, INIT, - (NULL), ("Could not begin request sent to MythTV server (%i, %s)", ret, src->uri_name)); - return FALSE; - } -} - - static gboolean +static gboolean gst_mythtv_src_get_size (GstBaseSrc * bsrc, guint64 * size) { GstMythtvSrc *src; + gboolean ret = TRUE; src = GST_MYTHTV_SRC (bsrc); + + if (src->content_size <= 0) { + ret= FALSE; + + } else if ( src->live_tv && src->content_size < MYTHTV_TRANSFER_MAX_BUFFER ) { + g_static_mutex_lock( &update_size_mutex ); + #if ENABLE_TIMING_POSITION == 1 - guint64 size_tmp = 0; - if (src->live_tv == TRUE) { + guint64 size_tmp = 0; + if (src->live_tv == TRUE) { get_file_pos: - //g_usleep( 100 ); - size_tmp = myth_file_transfer_get_file_position( src->file_transfer ); - if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) ) - src->content_size = size_tmp; - else - goto get_file_pos; - g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", - __FUNCTION__, size_tmp); + g_usleep( 50 ); + size_tmp = myth_file_transfer_get_file_position( src->file_transfer ); + if ( size_tmp > ( src->content_size + MYTHTV_TRANSFER_MAX_BUFFER ) ) + src->content_size = size_tmp; + else + goto get_file_pos; + g_print( "\t[%s]\tGET_POSITION: file_position = %llu\n", + __FUNCTION__, size_tmp ); + } +#endif + g_static_mutex_unlock( &update_size_mutex ); + } -#endif - if (src->content_size <= 0) - return FALSE; *size = src->content_size; + g_print( "[%s] Content size = %llu\n", __FUNCTION__, src->content_size ); - return TRUE; + return ret; + } /* close the socket and associated resources @@ -634,12 +735,14 @@ return TRUE; } - static gboolean +#if 0 +static gboolean gst_mythtv_src_handle_event (GstPad * pad, GstEvent * event) { GstMythtvSrc *src = GST_MYTHTV_SRC (GST_PAD_PARENT (pad)); switch (GST_EVENT_TYPE (event)) { +#if 0 case GST_EVENT_FLUSH_START: src->eos = FALSE; break; @@ -648,10 +751,28 @@ src->do_start = TRUE; src->eos = FALSE; gst_element_set_state (GST_ELEMENT(src), GST_STATE_NULL); - gst_element_set_locked_state (GST_ELEMENT(src), TRUE); + //gst_element_set_locked_state (GST_ELEMENT(src), TRUE); + break; +#endif + case GST_EVENT_EOS: + g_print( "[%s] Got EOS event!!!\n", __FUNCTION__ ); + src->content_size = gst_mythtv_src_get_position (src); + if ( cont_size > src->content_size ) { + src->content_size = cont_size; + } else { + src->eos = TRUE; + gst_element_set_state ( GST_ELEMENT (src), GST_STATE_NULL ); + gst_element_set_locked_state ( GST_ELEMENT (src), FALSE ); + } + break; +#if 0 + case GST_EVENT_NEWSEGMENT: + g_print( "[%s] Got NEWSEGMENT!!!\n", __FUNCTION__ ); + src->eos = FALSE; break; case GST_EVENT_SEEK: { + g_print( "[%s] Got EVENT_SEEK!!!\n", __FUNCTION__ ); gdouble rate; //gboolean update = TRUE; GstFormat format; @@ -671,22 +792,23 @@ // &position ); //GstFlowReturn flow_ret = gst_mythtv_src_create (GST_BASE_SRC( GST_PAD_PARENT( psrc ) ), // cur, stop - cur + 1, GstBuffer) - - } + } +#endif default: return gst_pad_event_default (pad, event); } return gst_pad_event_default (pad, event); } +#endif - static gboolean -gst_mythtv_src_is_seekable( GstBaseSrc *base_src ) +static gboolean +gst_mythtv_src_is_seekable( GstBaseSrc *push_src ) { return TRUE; } - static void +static void gst_mythtv_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { diff -r 081274382473 -r abe0ee48d78b gst-plugins-mythtv/src/myth_file_transfer.c --- a/gst-plugins-mythtv/src/myth_file_transfer.c Wed Oct 11 22:46:27 2006 +0100 +++ b/gst-plugins-mythtv/src/myth_file_transfer.c Thu Oct 12 01:50:27 2006 +0100 @@ -143,7 +143,7 @@ transfer->rec_id = -1; - transfer->recordernum = 0; + transfer->recordernum = num; transfer->uri = myth_uri_new ( uri_str->str ); transfer->hostname = g_string_new( myth_uri_gethost(transfer->uri) ); @@ -223,10 +223,10 @@ printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" ); #if 0 - /* configure the event socket */ - if ((*transfer)->event_sock == NULL) { + /* configure the control socket */ + if ((*transfer)->control_sock == NULL) { - if ( myth_connect_to_transfer_backend ( transfer, MYTH_MONITOR_TYPE ) == NULL ) { + if ( myth_connect_to_transfer_backend ( transfer, MYTH_PLAYBACK_TYPE ) == NULL ) { g_printerr( "Connection to backend failed (Event Socket).\n" ); ret = FALSE; } @@ -611,16 +611,17 @@ GMythStringList *strlist = gmyth_string_list_new(); g_string_printf (transfer->query, "%s %d", MYTHTV_QUERY_HEADER, transfer->recordernum); - gmyth_string_list_append_string( strlist, transfer->query ); + gmyth_string_list_append_string( strlist, transfer->query ); gmyth_string_list_append_char_array( strlist, "SEEK" ); gmyth_string_list_append_uint64( strlist, pos ); - // gmyth_string_list_append_int( strlist, whence ); + + gmyth_string_list_append_int( strlist, whence ); if (pos > 0 ) gmyth_string_list_append_uint64( strlist, pos ); else gmyth_string_list_append_uint64( strlist, transfer->readposition ); - + gmyth_socket_sendreceive_stringlist( transfer->control_sock, strlist ); guint64 retval = gmyth_string_list_get_uint64(strlist, 0); @@ -726,6 +727,7 @@ if ( io_status == G_IO_STATUS_NORMAL ) g_print( "[%s] Setting encoding to binary data socket).\n", __FUNCTION__ ); + io_cond = g_io_channel_get_buffer_condition( io_channel ); io_cond_control = g_io_channel_get_buffer_condition( io_channel ); @@ -772,32 +774,36 @@ wait_to_transfer = 0; - while ( transfer->live_tv && ( myth_file_transfer_get_file_position( transfer ) < 4096 ) && - wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS ) - g_usleep( 1000*50 ); /* waits just for 2/10 second */ + //while ( transfer->live_tv && ( myth_file_transfer_get_file_position( transfer ) < 4096 ) && + // wait_to_transfer++ < MYTHTV_TRANSFER_MAX_WAITS ) + // g_usleep( 1000*50 ); /* waits just for 2/10 second */ //g_thread_create( myth_init_io_watchers, (void*)transfer, FALSE, NULL ); //g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", __FUNCTION__, g_thread_self() ); - g_static_mutex_lock (&mutex); - strlist = gmyth_string_list_new(); + //g_static_mutex_lock (&mutex); + //strlist = gmyth_string_list_new(); g_string_printf ( transfer->query, "%s %d", /*transfer->live_tv ? MYTHTV_RECORDER_HEADER :*/ MYTHTV_QUERY_HEADER, /* transfer->live_tv ? transfer->card_id :*/ transfer->recordernum ); // transfer->recordernum g_print( "\t[%s] Transfer_query = %s\n", __FUNCTION__, transfer->query->str ); + strlist = gmyth_string_list_new(); - gmyth_string_list_append_string( strlist, transfer->query ); + gmyth_string_list_append_char_array( strlist, transfer->query->str ); gmyth_string_list_append_char_array( strlist, /*transfer->live_tv ? "REQUEST_BLOCK_RINGBUF" :*/ "REQUEST_BLOCK" ); gmyth_string_list_append_int( strlist, size ); gmyth_socket_write_stringlist( transfer->control_sock, strlist ); sent = size; + //g_static_mutex_unlock( &mutex ); //data = (void*)g_new0( gchar, size ); g_io_channel_flush( io_channel_control, NULL ); -// g_io_channel_flush( io_channel, NULL ); + //g_io_channel_flush( io_channel, NULL ); + + g_static_mutex_lock( &mutex ); io_cond = g_io_channel_get_buffer_condition( io_channel ); @@ -814,7 +820,7 @@ buf_len = ( sent - recv ) > MYTHTV_BUFFER_SIZE ? MYTHTV_BUFFER_SIZE : ( sent - recv ); io_status = g_io_channel_read_chars( io_channel, data + recv, - buf_len, &bytes_read, &error ); + buf_len, &bytes_read, &error ); /* GString *sss = g_string_new(""); sss = g_string_append_len( sss, (gchar*)data+recv, bytes_read ); @@ -884,6 +890,7 @@ g_error_free( error ); } } + //g_static_mutex_unlock( &mutex ); cleanup: @@ -894,6 +901,7 @@ g_object_unref( strlist ); g_static_mutex_unlock (&mutex); + g_print( "myth_file_transfer_read(): reqd=%d, rcvd=%d, rept=%d, "\ "(rcvd and rept MUST be the same!)\n", size, recv, sent ); @@ -902,9 +910,11 @@ // recv = -1; //} - if ( error != NULL ) + if ( error != NULL ) { g_printerr( "ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message, error->code ); + g_error_free( error ); + } return recv; }