1.1 --- a/gst-gmyth/mythsrc/gstmythtvsrc.c Wed Aug 22 14:57:53 2007 +0100
1.2 +++ b/gst-gmyth/mythsrc/gstmythtvsrc.c Wed Aug 22 17:57:16 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
2.1 --- a/gst-gmyth/mythsrc/gstmythtvsrc.h Wed Aug 22 14:57:53 2007 +0100
2.2 +++ b/gst-gmyth/mythsrc/gstmythtvsrc.h Wed Aug 22 17:57:16 2007 +0100
2.3 @@ -79,8 +79,6 @@
2.4
2.5 gint64 read_offset;
2.6
2.7 - gint buffer_remain;
2.8 -
2.9 gboolean eos;
2.10
2.11 gboolean do_start;
2.12 @@ -102,15 +100,6 @@
2.13 */
2.14 GstCaps *mythtv_caps;
2.15
2.16 - GByteArray *bytes_queue;
2.17 -
2.18 -#ifndef GST_DISABLE_GST_DEBUG
2.19 - /*
2.20 - * enable Myth TV debug messages
2.21 - */
2.22 - gboolean mythtv_msgs_dbg;
2.23 -#endif
2.24 -
2.25 gboolean update_prog_chain;
2.26
2.27 /*
3.1 --- a/gst-gmyth/nuvdemux/gstnuvdemux.c Wed Aug 22 14:57:53 2007 +0100
3.2 +++ b/gst-gmyth/nuvdemux/gstnuvdemux.c Wed Aug 22 17:57:16 2007 +0100
3.3 @@ -739,8 +739,13 @@
3.4 static void
3.5 gst_nuv_demux_create_pads(GstNuvDemux * nuv)
3.6 {
3.7 - if (nuv->priv->h.i_video_blocks != 0) {
3.8 - GstCaps *video_caps = NULL;
3.9 + if ((nuv->priv->src_video_pad != NULL) ||
3.10 + (nuv->priv->src_audio_pad != NULL)) {
3.11 + return;
3.12 + }
3.13 +
3.14 + if (nuv->priv->h.i_video_blocks != 0){
3.15 + GstCaps *video_caps = NULL;
3.16
3.17 video_caps = gst_caps_new_simple("video/x-divx",
3.18 "divxversion", G_TYPE_INT, 4,
3.19 @@ -764,13 +769,15 @@
3.20 }
3.21
3.22 if (nuv->priv->h.i_audio_blocks != 0) {
3.23 - GstCaps *audio_caps = NULL;
3.24 + GstCaps *audio_caps = NULL;
3.25
3.26 - audio_caps = gst_caps_new_simple("audio/mpeg", "rate", G_TYPE_INT, nuv->priv->eh.i_audio_sample_rate, "format", GST_TYPE_FOURCC, nuv->priv->eh.i_audio_fcc, "channels", G_TYPE_INT, nuv->priv->eh.i_audio_channels, "layer", G_TYPE_INT, 3, // fixme:
3.27 - // magic
3.28 - // number
3.29 - "mpegversion", G_TYPE_INT,
3.30 - nuv->priv->eh.i_version, NULL);
3.31 + audio_caps = gst_caps_new_simple("audio/mpeg",
3.32 + "rate", G_TYPE_INT, nuv->priv->eh.i_audio_sample_rate,
3.33 + "format", GST_TYPE_FOURCC, nuv->priv->eh.i_audio_fcc,
3.34 + "channels", G_TYPE_INT, nuv->priv->eh.i_audio_channels,
3.35 + "layer", G_TYPE_INT, 3, // fixme: magic number
3.36 + "mpegversion", G_TYPE_INT, nuv->priv->eh.i_version,
3.37 + NULL);
3.38
3.39 nuv->priv->src_audio_pad =
3.40 gst_nuv_demux_create_pad(nuv, audio_caps, &audio_src_template,
3.41 @@ -854,7 +861,7 @@
3.42 return TRUE;
3.43 }
3.44
3.45 -static GstFlowReturn
3.46 +static GstFlowReturn
3.47 gst_nuv_demux_stream_data(GstNuvDemux * nuv)
3.48 {
3.49 GstFlowReturn ret = GST_FLOW_OK;
3.50 @@ -1643,57 +1650,17 @@
3.51 nuv = GST_NUV_DEMUX(gst_pad_get_parent(pad));
3.52
3.53 switch (GST_EVENT_TYPE(event)) {
3.54 - case GST_EVENT_NEWSEGMENT:
3.55 - {
3.56 - gboolean update;
3.57 - gdouble rate;
3.58 - GstFormat format;
3.59 - gint64 start;
3.60 - gint64 stop;
3.61 - gint64 position;
3.62 -
3.63 - gst_event_parse_new_segment(event, &update, &rate, &format,
3.64 - &start, &stop, &position);
3.65 - if ((format == GST_FORMAT_BYTES) && (start == 0)) {
3.66 - g_debug("NEW SEGMENT 0");
3.67 - if (nuv->priv->segment > 0) {
3.68 - nuv->priv->new_file = TRUE;
3.69 - nuv->priv->state = GST_NUV_DEMUX_START;
3.70 - nuv->priv->offset = 0;
3.71 - }
3.72 - nuv->priv->segment++;
3.73 -
3.74 - /*
3.75 - * newsegment_event = gst_event_new_new_segment (FALSE,
3.76 - * rate, GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE,
3.77 - * GST_CLOCK_TIME_NONE);
3.78 - *
3.79 - * gst_pad_push_event (nuv->priv->src_audio_pad,
3.80 - * gst_event_ref (newsegment_event)); gst_pad_push_event
3.81 - * (nuv->priv->src_video_pad, gst_event_ref
3.82 - * (newsegment_event)); gst_event_unref
3.83 - * (newsegment_event);
3.84 - */
3.85 - res = gst_pad_event_default(pad, event);
3.86 - }
3.87 - break;
3.88 - }
3.89 - case GST_EVENT_CUSTOM_DOWNSTREAM:
3.90 - {
3.91 - /*
3.92 - * nuv->priv->new_file = TRUE; nuv->priv->state =
3.93 - * GST_NUV_DEMUX_START; nuv->priv->offset = 0;
3.94 - */
3.95 + case GST_EVENT_NEWSEGMENT:
3.96 GST_PAD_STREAM_LOCK(pad);
3.97 gst_nuv_demux_reset(nuv);
3.98 GST_PAD_STREAM_UNLOCK(pad);
3.99
3.100 + //res = gst_pad_event_default(pad, event);
3.101 + res = TRUE;
3.102 + break;
3.103 + default:
3.104 res = gst_pad_event_default(pad, event);
3.105 break;
3.106 - }
3.107 - default:
3.108 - res = gst_pad_event_default(pad, event);
3.109 - break;
3.110 }
3.111
3.112 return res;
3.113 @@ -1783,7 +1750,6 @@
3.114 {
3.115 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
3.116
3.117 - g_debug("Nuvdemux state_change");
3.118 switch (transition) {
3.119 case GST_STATE_CHANGE_NULL_TO_READY:
3.120 gst_nuv_demux_reset(GST_NUV_DEMUX(element));
3.121 @@ -1793,8 +1759,6 @@
3.122 break;
3.123 }
3.124
3.125 - g_debug("Nuvdemux state_change: 1");
3.126 -
3.127 ret =
3.128 GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
3.129 if (ret == GST_STATE_CHANGE_FAILURE) {
3.130 @@ -1802,8 +1766,6 @@
3.131 }
3.132
3.133
3.134 - g_debug("Nuvdemux state_change: 2");
3.135 -
3.136 switch (transition) {
3.137 case GST_STATE_CHANGE_READY_TO_NULL:
3.138 gst_nuv_demux_reset(GST_NUV_DEMUX(element));
3.139 @@ -1812,10 +1774,6 @@
3.140 default:
3.141 break;
3.142 }
3.143 -
3.144 -
3.145 - g_debug("Nuvdemux state_change: DONE");
3.146 -
3.147 done:
3.148 return ret;
3.149 }