1.1 --- a/gst-gmyth/mythsrc/gstmythtvsrc.c Mon Aug 20 19:03:06 2007 +0100
1.2 +++ b/gst-gmyth/mythsrc/gstmythtvsrc.c Thu Aug 23 20:24:11 2007 +0100
1.3 @@ -87,10 +87,8 @@
1.4 #define GMYTHTV_TRANSFER_MAX_WAITS 100
1.5 #define GMYTHTV_TRANSFER_MAX_RESENDS 2
1.6 #define GMYTHTV_TRANSFER_MAX_BUFFER (128*1024)
1.7 -#define MAX_READ_SIZE (4*1024)
1.8 +#define READ_SIZE (4*1024)
1.9 #define GST_FLOW_ERROR_NO_DATA (-101)
1.10 -#define REQUEST_MAX_SIZE (64*1024)
1.11 -#define INTERNAL_BUFFER_SIZE (90*1024)
1.12
1.13 static const GstElementDetails gst_mythtv_src_details =
1.14 GST_ELEMENT_DETAILS("MythTV client source",
1.15 @@ -254,7 +252,6 @@
1.16 gstbasesrc_class->stop = gst_mythtv_src_stop;
1.17 gstbasesrc_class->get_size = gst_mythtv_src_get_size;
1.18 gstbasesrc_class->is_seekable = gst_mythtv_src_is_seekable;
1.19 -
1.20 gstbasesrc_class->do_seek = gst_mythtv_src_do_seek;
1.21 gstpushsrc_class->create = gst_mythtv_src_create;
1.22
1.23 @@ -281,7 +278,6 @@
1.24 this->update_prog_chain = FALSE;
1.25 this->channel_name = NULL;
1.26 this->eos = FALSE;
1.27 - this->bytes_queue = NULL;
1.28 this->wait_to_transfer = 0;
1.29 gst_base_src_set_format(GST_BASE_SRC(this), GST_FORMAT_BYTES);
1.30 gst_pad_set_event_function(GST_BASE_SRC_PAD(GST_BASE_SRC(this)),
1.31 @@ -310,11 +306,6 @@
1.32 g_object_unref(mythtv_src->backend_info);
1.33 mythtv_src->backend_info = NULL;
1.34 }
1.35 -
1.36 - if (mythtv_src->bytes_queue) {
1.37 - g_byte_array_free(mythtv_src->bytes_queue, TRUE);
1.38 - mythtv_src->bytes_queue = NULL;
1.39 - }
1.40 }
1.41
1.42 static void
1.43 @@ -378,17 +369,9 @@
1.44 if (result == GMYTH_FILE_READ_ERROR) { /* -314 */
1.45 GST_INFO_OBJECT(src,
1.46 "[LiveTV] FileTransfer READ_ERROR!");
1.47 - goto done;
1.48 - } else if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) { /* -315
1.49 - */
1.50 - GST_INFO_OBJECT(src,
1.51 - "[LiveTV] FileTransfer - Go to athe next program chain!");
1.52 - src->update_prog_chain = TRUE;
1.53 - continue;
1.54 }
1.55 goto done;
1.56 }
1.57 -
1.58 }
1.59 /*
1.60 * else if (data_ptr->len == 0) goto done;
1.61 @@ -414,214 +397,57 @@
1.62 static GstFlowReturn
1.63 gst_mythtv_src_create(GstPushSrc * psrc, GstBuffer ** outbuf)
1.64 {
1.65 - GstMythtvSrc *src;
1.66 + GstMythtvSrc *src;
1.67 GstFlowReturn ret = GST_FLOW_OK;
1.68 - guint buffer_size_inter = 0;
1.69 + GByteArray *buffer;
1.70 + gint buffer_remain = 0;
1.71 + GMythFileReadResult result = GMYTH_FILE_READ_OK;
1.72 + gboolean buffering = FALSE;
1.73
1.74 src = GST_MYTHTV_SRC(psrc);
1.75
1.76 - /*
1.77 - * The caller should know the number of bytes and not read beyond EOS.
1.78 - */
1.79 - if (G_UNLIKELY(src->eos))
1.80 - goto eos;
1.81 - GST_DEBUG_OBJECT(src, "offset = %" G_GUINT64_FORMAT ", size = %d...",
1.82 - src->read_offset, MAX_READ_SIZE);
1.83 + buffer = g_byte_array_new ();
1.84 + result = do_read_request_response(src, READ_SIZE, buffer);
1.85 + if (result == GMYTH_FILE_READ_ERROR)
1.86 + goto read_error;
1.87
1.88 - GST_DEBUG_OBJECT(src, "Create: buffer_remain: %d, buffer_size = %d.",
1.89 - (gint) src->buffer_remain, src->bytes_queue->len);
1.90 -
1.91 - program_chain_changed:
1.92 - /*
1.93 - * just get from the byte array, no network effort...
1.94 - */
1.95 - if ((src->buffer_remain = src->bytes_queue->len) < MAX_READ_SIZE) {
1.96 - GByteArray *buffer;
1.97 - GMythFileReadResult result = GMYTH_FILE_READ_OK;
1.98 -
1.99 - buffer = NULL;
1.100 - buffer_size_inter = (INTERNAL_BUFFER_SIZE - src->buffer_remain);
1.101 -
1.102 - if (buffer_size_inter > REQUEST_MAX_SIZE)
1.103 - buffer_size_inter = REQUEST_MAX_SIZE;
1.104 -
1.105 - buffer = g_byte_array_new();
1.106 -
1.107 - result = do_read_request_response(src, buffer_size_inter, buffer);
1.108 -
1.109 - /*
1.110 - * got the next program info?
1.111 - */
1.112 - if (G_UNLIKELY(src->update_prog_chain) ||
1.113 - (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN)) {
1.114 - GST_DEBUG_OBJECT(src,
1.115 - "Update PROGRAM CHAIN!!! buffer_size = %d.",
1.116 - src->bytes_queue->len);
1.117 - gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(psrc)),
1.118 - gst_event_new_custom
1.119 - (GST_EVENT_CUSTOM_DOWNSTREAM, NULL));
1.120 - /*
1.121 - * gst_pad_push_event (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)),
1.122 - * gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 0,
1.123 - * -1, 0));
1.124 - */
1.125 - src->update_prog_chain = FALSE;
1.126 - src->eos = FALSE;
1.127 -
1.128 - if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) {
1.129 - /*
1.130 - * if (buffer != NULL) { g_byte_array_free (buffer, TRUE);
1.131 - * buffer = NULL; } goto program_chain_changed;
1.132 - */
1.133 - } else if (result == GMYTH_FILE_READ_OK) {
1.134 - /*
1.135 - * remove wasteful, NUV file header data
1.136 - */
1.137 - /*
1.138 - * buffer = g_byte_array_remove_range( buffer, 0, 512 );
1.139 - */
1.140 - /*
1.141 - * TODO: need to send a new segment event to NUVDemux?
1.142 - */
1.143 - // gst_pad_push_event (GST_BASE_SRC_PAD (GST_BASE_SRC
1.144 - // (psrc)),
1.145 - // gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES,
1.146 - // 0, -1, 0));
1.147 -
1.148 - /*
1.149 - * goto change_progchain;
1.150 - */
1.151 - }
1.152 -
1.153 - }
1.154 - /*
1.155 - */
1.156 - if (G_UNLIKELY(buffer->len < 0)) {
1.157 - if (buffer != NULL) {
1.158 - g_byte_array_free(buffer, TRUE);
1.159 - buffer = NULL;
1.160 - }
1.161 -
1.162 - if (src->live_tv ||
1.163 - (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN))
1.164 - goto change_progchain;
1.165 - else
1.166 - goto read_error;
1.167 - } else if (G_UNLIKELY(buffer->len == 0)) {
1.168 -
1.169 - if (buffer != NULL) {
1.170 - g_byte_array_free(buffer, TRUE);
1.171 - buffer = NULL;
1.172 - }
1.173 -
1.174 - if (!src->live_tv) {
1.175 - if (src->eos)
1.176 - goto eos;
1.177 - else
1.178 - goto done;
1.179 - }
1.180 - else
1.181 - goto program_chain_changed;
1.182 - }
1.183 -
1.184 - src->bytes_queue =
1.185 - g_byte_array_append(src->bytes_queue, buffer->data,
1.186 - buffer->len);
1.187 - if (buffer->len > buffer_size_inter)
1.188 - GST_WARNING_OBJECT(src,
1.189 - "INCREASED buffer size! Backend sent more than we ask him... (%d)",
1.190 - abs(buffer->len - buffer_size_inter));
1.191 -
1.192 - src->buffer_remain += buffer->len;
1.193 -
1.194 - if (buffer != NULL) {
1.195 - g_byte_array_free(buffer, TRUE);
1.196 - buffer = NULL;
1.197 - }
1.198 -
1.199 - /*
1.200 - * GST_DEBUG_OBJECT (src, "BYTES READ (actual) = %d, BYTES READ
1.201 - * (cumulative) = %llu, " "OFFSET = %llu, CONTENT SIZE = %llu.",
1.202 - * read, src->bytes_read, src->read_offset, src->content_size);
1.203 - */
1.204 - }
1.205 -
1.206 - guint buffer_size;
1.207 - buffer_size = (src->buffer_remain < MAX_READ_SIZE) ?
1.208 - src->buffer_remain :
1.209 - MAX_READ_SIZE;
1.210
1.211 *outbuf = gst_buffer_new();
1.212 -
1.213 - /*
1.214 - * GST_DEBUG_OBJECT (src, "read from network? %s!, buffer_remain =
1.215 - * %d", (buffer_size_inter == 0) ? "NO, got from buffer" : "YES, go
1.216 - * see the backend's log file", src->buffer_remain);
1.217 - */
1.218 -
1.219 - GST_BUFFER_SIZE(*outbuf) = buffer_size;
1.220 + GST_BUFFER_SIZE(*outbuf) = buffer->len;
1.221 GST_BUFFER_MALLOCDATA(*outbuf) = g_malloc0(GST_BUFFER_SIZE(*outbuf));
1.222 GST_BUFFER_DATA(*outbuf) = GST_BUFFER_MALLOCDATA(*outbuf);
1.223 - g_memmove(GST_BUFFER_DATA((*outbuf)), src->bytes_queue->data,
1.224 + g_memmove(GST_BUFFER_DATA((*outbuf)), buffer->data,
1.225 GST_BUFFER_SIZE(*outbuf));
1.226 GST_BUFFER_OFFSET(*outbuf) = src->read_offset;
1.227 GST_BUFFER_OFFSET_END(*outbuf) =
1.228 src->read_offset + GST_BUFFER_SIZE(*outbuf);
1.229
1.230 - src->buffer_remain -= GST_BUFFER_SIZE(*outbuf);
1.231 -
1.232 src->read_offset += GST_BUFFER_SIZE(*outbuf);
1.233 src->bytes_read += GST_BUFFER_SIZE(*outbuf);
1.234 - // GST_DEBUG_OBJECT (src, "Buffer output with size: %d",
1.235 - // GST_BUFFER_SIZE (*outbuf));
1.236
1.237 - /*
1.238 - * flushs the newly buffer got from byte array
1.239 - */
1.240 - src->bytes_queue =
1.241 - g_byte_array_remove_range(src->bytes_queue, 0, buffer_size);
1.242 + g_byte_array_free (buffer, TRUE);
1.243
1.244 - if (src->eos ||
1.245 - (!src->live_tv && (src->bytes_read >= src->content_size))
1.246 - )
1.247 - goto eos;
1.248 + if (result == GMYTH_FILE_READ_NEXT_PROG_CHAIN) {
1.249 + GstPad *peer;
1.250
1.251 - done:
1.252 - {
1.253 - return ret;
1.254 - }
1.255 - eos:
1.256 - {
1.257 - return GST_FLOW_UNEXPECTED;
1.258 - }
1.259 - /*
1.260 - * ERRORS
1.261 - */
1.262 - read_error:
1.263 - {
1.264 - GST_ELEMENT_ERROR(src, RESOURCE, READ,
1.265 - (NULL), ("Could not read any bytes (%i, %s)",
1.266 - read, src->uri_name));
1.267 - return GST_FLOW_ERROR;
1.268 - }
1.269 - change_progchain:
1.270 - {
1.271 - GST_ELEMENT_ERROR(src, RESOURCE, READ,
1.272 - (NULL),
1.273 - ("Seek failed, go to the next program info... (%i, %s)",
1.274 - read, src->uri_name));
1.275 + peer = gst_pad_get_peer (GST_BASE_SRC_PAD (GST_BASE_SRC (psrc)));
1.276 + gst_pad_send_event (peer,
1.277 + gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0));
1.278
1.279 - /*
1.280 - * TODO: need to send a new segment event to NUVDemux?
1.281 - */
1.282 - gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(psrc)),
1.283 - gst_event_new_new_segment(TRUE, 1.0,
1.284 - GST_FORMAT_TIME, 0,
1.285 - -1, 0));
1.286 -
1.287 - goto program_chain_changed;
1.288 + gst_object_unref (peer);
1.289 }
1.290
1.291 + if (src->eos ||
1.292 + (!src->live_tv && (src->bytes_read >= src->content_size)))
1.293 + ret = GST_FLOW_UNEXPECTED;
1.294 +
1.295 + return ret;
1.296 +
1.297 +read_error:
1.298 + GST_ELEMENT_ERROR(src, RESOURCE, READ,
1.299 + (NULL), ("Could not read any bytes (%i, %s)",
1.300 + read, src->uri_name));
1.301 + return GST_FLOW_ERROR;
1.302 }
1.303
1.304 gint64
1.305 @@ -737,16 +563,10 @@
1.306 gmyth_uri = gmyth_uri_new_with_value(src->uri_name);
1.307 src->backend_info = gmyth_backend_info_new_with_uri(src->uri_name);
1.308 src->live_tv = gmyth_uri_is_livetv(gmyth_uri);
1.309 - /*
1.310 - * testing UPnP...
1.311 - */
1.312 - /*
1.313 - * gmyth_backend_info_set_hostname( src->backend_info, NULL );
1.314 - */
1.315 +
1.316 if (src->live_tv) {
1.317 src->spawn_livetv = gmyth_livetv_new(src->backend_info);
1.318 -
1.319 - gchar *ch = gmyth_uri_get_channel_name(gmyth_uri);
1.320 + gchar *ch = gmyth_uri_get_channel_name(gmyth_uri);
1.321 if (ch != NULL)
1.322 src->channel_name = ch;
1.323
1.324 @@ -781,6 +601,7 @@
1.325 GMYTH_FILE(gmyth_livetv_create_file_transfer
1.326 (src->spawn_livetv));
1.327
1.328 +
1.329 if (NULL == src->file) {
1.330 GST_INFO_OBJECT(src, "[LiveTV] FileTransfer equals to NULL");
1.331 ret = FALSE;
1.332 @@ -862,12 +683,6 @@
1.333
1.334 src->do_start = FALSE;
1.335
1.336 - /*
1.337 - * this is used for the buffer cache
1.338 - */
1.339 - src->bytes_queue = g_byte_array_sized_new(INTERNAL_BUFFER_SIZE);
1.340 - src->buffer_remain = 0;
1.341 -
1.342 gst_pad_push_event(GST_BASE_SRC_PAD(GST_BASE_SRC(src)),
1.343 gst_event_new_new_segment(TRUE, 1.0,
1.344 GST_FORMAT_TIME, 0,
1.345 @@ -967,11 +782,6 @@
1.346 GstMythtvSrc *src = GST_MYTHTV_SRC(bsrc);
1.347
1.348 gst_mythtv_src_clear(src);
1.349 -
1.350 - /*
1.351 - * src->eos = FALSE;
1.352 - */
1.353 -
1.354 return TRUE;
1.355 }
1.356