diff -r cf7e02ee3db4 -r 8b729aff6f81 gst-gmyth/mythsrc/gstmythtvsrc.c --- a/gst-gmyth/mythsrc/gstmythtvsrc.c Mon Aug 20 19:03:06 2007 +0100 +++ b/gst-gmyth/mythsrc/gstmythtvsrc.c Thu Aug 23 14:24:46 2007 +0100 @@ -87,10 +87,8 @@ #define GMYTHTV_TRANSFER_MAX_WAITS 100 #define GMYTHTV_TRANSFER_MAX_RESENDS 2 #define GMYTHTV_TRANSFER_MAX_BUFFER (128*1024) -#define MAX_READ_SIZE (4*1024) +#define READ_SIZE (4*1024) #define GST_FLOW_ERROR_NO_DATA (-101) -#define REQUEST_MAX_SIZE (64*1024) -#define INTERNAL_BUFFER_SIZE (90*1024) static const GstElementDetails gst_mythtv_src_details = GST_ELEMENT_DETAILS("MythTV client source", @@ -254,7 +252,6 @@ 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; - gstbasesrc_class->do_seek = gst_mythtv_src_do_seek; gstpushsrc_class->create = gst_mythtv_src_create; @@ -281,7 +278,6 @@ this->update_prog_chain = FALSE; this->channel_name = NULL; this->eos = FALSE; - this->bytes_queue = NULL; this->wait_to_transfer = 0; 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)), @@ -310,11 +306,6 @@ g_object_unref(mythtv_src->backend_info); mythtv_src->backend_info = NULL; } - - if (mythtv_src->bytes_queue) { - g_byte_array_free(mythtv_src->bytes_queue, TRUE); - mythtv_src->bytes_queue = NULL; - } } static void @@ -378,17 +369,9 @@ if (result == GMYTH_FILE_READ_ERROR) { /* -314 */ GST_INFO_OBJECT(src, "[LiveTV] FileTransfer READ_ERROR!"); - goto done; - } else if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) { /* -315 - */ - GST_INFO_OBJECT(src, - "[LiveTV] FileTransfer - Go to athe next program chain!"); - src->update_prog_chain = TRUE; - continue; } goto done; } - } /* * else if (data_ptr->len == 0) goto done; @@ -414,214 +397,57 @@ static GstFlowReturn gst_mythtv_src_create(GstPushSrc * psrc, GstBuffer ** outbuf) { - GstMythtvSrc *src; + GstMythtvSrc *src; GstFlowReturn ret = GST_FLOW_OK; - guint buffer_size_inter = 0; + GByteArray *buffer; + gint buffer_remain = 0; + GMythFileReadResult result = GMYTH_FILE_READ_OK; + gboolean buffering = FALSE; src = GST_MYTHTV_SRC(psrc); - /* - * The caller should know the number of bytes and not read beyond EOS. - */ - if (G_UNLIKELY(src->eos)) - goto eos; - GST_DEBUG_OBJECT(src, "offset = %" G_GUINT64_FORMAT ", size = %d...", - src->read_offset, MAX_READ_SIZE); + buffer = g_byte_array_new (); + result = do_read_request_response(src, READ_SIZE, buffer); + if (result == GMYTH_FILE_READ_ERROR) + goto read_error; - GST_DEBUG_OBJECT(src, "Create: buffer_remain: %d, buffer_size = %d.", - (gint) src->buffer_remain, src->bytes_queue->len); - - program_chain_changed: - /* - * just get from the byte array, no network effort... - */ - if ((src->buffer_remain = src->bytes_queue->len) < MAX_READ_SIZE) { - GByteArray *buffer; - GMythFileReadResult result = GMYTH_FILE_READ_OK; - - buffer = NULL; - buffer_size_inter = (INTERNAL_BUFFER_SIZE - src->buffer_remain); - - if (buffer_size_inter > REQUEST_MAX_SIZE) - buffer_size_inter = REQUEST_MAX_SIZE; - - buffer = g_byte_array_new(); - - result = do_read_request_response(src, buffer_size_inter, buffer); - - /* - * got the next program info? - */ - if (G_UNLIKELY(src->update_prog_chain) || - (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN)) { - GST_DEBUG_OBJECT(src, - "Update PROGRAM CHAIN!!! buffer_size = %d.", - src->bytes_queue->len); - gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(psrc)), - gst_event_new_custom - (GST_EVENT_CUSTOM_DOWNSTREAM, NULL)); - /* - * gst_pad_push_event (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)), - * gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 0, - * -1, 0)); - */ - src->update_prog_chain = FALSE; - src->eos = FALSE; - - if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) { - /* - * if (buffer != NULL) { g_byte_array_free (buffer, TRUE); - * buffer = NULL; } goto program_chain_changed; - */ - } else if (result == GMYTH_FILE_READ_OK) { - /* - * remove wasteful, NUV file header data - */ - /* - * buffer = g_byte_array_remove_range( buffer, 0, 512 ); - */ - /* - * TODO: need to send a new segment event to NUVDemux? - */ - // gst_pad_push_event (GST_BASE_SRC_PAD (GST_BASE_SRC - // (psrc)), - // gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, - // 0, -1, 0)); - - /* - * goto change_progchain; - */ - } - - } - /* - */ - if (G_UNLIKELY(buffer->len < 0)) { - if (buffer != NULL) { - g_byte_array_free(buffer, TRUE); - buffer = NULL; - } - - if (src->live_tv || - (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN)) - goto change_progchain; - else - goto read_error; - } else if (G_UNLIKELY(buffer->len == 0)) { - - if (buffer != NULL) { - g_byte_array_free(buffer, TRUE); - buffer = NULL; - } - - if (!src->live_tv) { - if (src->eos) - goto eos; - else - goto done; - } - else - goto program_chain_changed; - } - - src->bytes_queue = - g_byte_array_append(src->bytes_queue, buffer->data, - buffer->len); - if (buffer->len > buffer_size_inter) - GST_WARNING_OBJECT(src, - "INCREASED buffer size! Backend sent more than we ask him... (%d)", - abs(buffer->len - buffer_size_inter)); - - src->buffer_remain += buffer->len; - - if (buffer != NULL) { - g_byte_array_free(buffer, TRUE); - buffer = NULL; - } - - /* - * GST_DEBUG_OBJECT (src, "BYTES READ (actual) = %d, BYTES READ - * (cumulative) = %llu, " "OFFSET = %llu, CONTENT SIZE = %llu.", - * read, src->bytes_read, src->read_offset, src->content_size); - */ - } - - guint buffer_size; - buffer_size = (src->buffer_remain < MAX_READ_SIZE) ? - src->buffer_remain : - MAX_READ_SIZE; *outbuf = gst_buffer_new(); - - /* - * GST_DEBUG_OBJECT (src, "read from network? %s!, buffer_remain = - * %d", (buffer_size_inter == 0) ? "NO, got from buffer" : "YES, go - * see the backend's log file", src->buffer_remain); - */ - - GST_BUFFER_SIZE(*outbuf) = buffer_size; + GST_BUFFER_SIZE(*outbuf) = buffer->len; GST_BUFFER_MALLOCDATA(*outbuf) = g_malloc0(GST_BUFFER_SIZE(*outbuf)); GST_BUFFER_DATA(*outbuf) = GST_BUFFER_MALLOCDATA(*outbuf); - g_memmove(GST_BUFFER_DATA((*outbuf)), src->bytes_queue->data, + g_memmove(GST_BUFFER_DATA((*outbuf)), buffer->data, GST_BUFFER_SIZE(*outbuf)); GST_BUFFER_OFFSET(*outbuf) = src->read_offset; GST_BUFFER_OFFSET_END(*outbuf) = src->read_offset + GST_BUFFER_SIZE(*outbuf); - src->buffer_remain -= GST_BUFFER_SIZE(*outbuf); - src->read_offset += GST_BUFFER_SIZE(*outbuf); src->bytes_read += GST_BUFFER_SIZE(*outbuf); - // GST_DEBUG_OBJECT (src, "Buffer output with size: %d", - // GST_BUFFER_SIZE (*outbuf)); - /* - * flushs the newly buffer got from byte array - */ - src->bytes_queue = - g_byte_array_remove_range(src->bytes_queue, 0, buffer_size); + g_byte_array_free (buffer, TRUE); - if (src->eos || - (!src->live_tv && (src->bytes_read >= src->content_size)) - ) - goto eos; + if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) { + GstPad *peer; - done: - { - return ret; - } - eos: - { - return GST_FLOW_UNEXPECTED; - } - /* - * ERRORS - */ - read_error: - { - GST_ELEMENT_ERROR(src, RESOURCE, READ, - (NULL), ("Could not read any bytes (%i, %s)", - read, src->uri_name)); - return GST_FLOW_ERROR; - } - change_progchain: - { - GST_ELEMENT_ERROR(src, RESOURCE, READ, - (NULL), - ("Seek failed, go to the next program info... (%i, %s)", - read, src->uri_name)); + peer = gst_pad_get_peer (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc))); + gst_pad_send_event (peer, + gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0)); - /* - * TODO: need to send a new segment event to NUVDemux? - */ - gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(psrc)), - gst_event_new_new_segment(TRUE, 1.0, - GST_FORMAT_TIME, 0, - -1, 0)); - - goto program_chain_changed; + gst_object_unref (peer); } + if (src->eos || + (!src->live_tv && (src->bytes_read >= src->content_size))) + ret = GST_FLOW_UNEXPECTED; + + return ret; + +read_error: + GST_ELEMENT_ERROR(src, RESOURCE, READ, + (NULL), ("Could not read any bytes (%i, %s)", + read, src->uri_name)); + return GST_FLOW_ERROR; } gint64 @@ -737,16 +563,10 @@ gmyth_uri = gmyth_uri_new_with_value(src->uri_name); src->backend_info = gmyth_backend_info_new_with_uri(src->uri_name); src->live_tv = gmyth_uri_is_livetv(gmyth_uri); - /* - * testing UPnP... - */ - /* - * gmyth_backend_info_set_hostname( src->backend_info, NULL ); - */ + if (src->live_tv) { src->spawn_livetv = gmyth_livetv_new(src->backend_info); - - gchar *ch = gmyth_uri_get_channel_name(gmyth_uri); + gchar *ch = gmyth_uri_get_channel_name(gmyth_uri); if (ch != NULL) src->channel_name = ch; @@ -781,6 +601,7 @@ GMYTH_FILE(gmyth_livetv_create_file_transfer (src->spawn_livetv)); + if (NULL == src->file) { GST_INFO_OBJECT(src, "[LiveTV] FileTransfer equals to NULL"); ret = FALSE; @@ -862,12 +683,6 @@ src->do_start = FALSE; - /* - * this is used for the buffer cache - */ - src->bytes_queue = g_byte_array_sized_new(INTERNAL_BUFFER_SIZE); - src->buffer_remain = 0; - gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(src)), gst_event_new_new_segment(TRUE, 1.0, GST_FORMAT_TIME, 0, @@ -967,11 +782,6 @@ GstMythtvSrc *src = GST_MYTHTV_SRC(bsrc); gst_mythtv_src_clear(src); - - /* - * src->eos = FALSE; - */ - return TRUE; }