diff options
author | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2009-05-02 16:08:03 +0200 |
---|---|---|
committer | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2009-05-05 22:41:30 +0200 |
commit | b6d4fb9e4f4e562a7de1691b37cded2859b86235 (patch) | |
tree | 55fbe2017ef7128dffca6f1106e23c02e747bed2 | |
parent | 2bd14c7153bf7cb5322f1eeb96d314f87e6b3a7b (diff) |
asfdemux: fixes for streaming mode
* Improve newsegment handling, e.g. upstream might live in TIME.
* Only send newsegment if we have needed info.
* Avoid reading past end of data section.
-rw-r--r-- | gst/asfdemux/gstasfdemux.c | 40 | ||||
-rw-r--r-- | gst/asfdemux/gstasfdemux.h | 2 |
2 files changed, 33 insertions, 9 deletions
diff --git a/gst/asfdemux/gstasfdemux.c b/gst/asfdemux/gstasfdemux.c index 098c615c..d953110d 100644 --- a/gst/asfdemux/gstasfdemux.c +++ b/gst/asfdemux/gstasfdemux.c @@ -303,18 +303,23 @@ gst_asf_demux_sink_event (GstPad * pad, GstEvent * event) gst_event_parse_new_segment (event, NULL, NULL, &newsegment_format, &newsegment_start, NULL, NULL); - if (newsegment_format != GST_FORMAT_BYTES) { - GST_WARNING_OBJECT (demux, "newsegment format not BYTES, ignoring"); + if (newsegment_format == GST_FORMAT_BYTES) { + if (demux->packet_size && newsegment_start > demux->data_offset) + demux->packet = (newsegment_start - demux->data_offset) / + demux->packet_size; + else + demux->packet = 0; + } else if (newsegment_format == GST_FORMAT_TIME) { + /* do not know packet position, not really a problem */ + demux->packet = -1; + } else { + GST_WARNING_OBJECT (demux, "unsupported newsegment format , ignoring"); gst_event_unref (event); break; } + /* in either case, clear some state and generate newsegment later on */ GST_OBJECT_LOCK (demux); - if (demux->packet_size && newsegment_start > demux->data_offset) - demux->packet = (newsegment_start - demux->data_offset) / - demux->packet_size; - else - demux->packet = 0; demux->first_ts = GST_CLOCK_TIME_NONE; demux->need_newsegment = TRUE; gst_asf_demux_reset_stream_state_after_discont (demux); @@ -1188,6 +1193,11 @@ gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force) /* do we need to send a newsegment event */ if (demux->need_newsegment) { + + /* wait until we had a chance to "lock on" some payload's timestamp */ + if (!GST_CLOCK_TIME_IS_VALID (demux->first_ts)) + return GST_FLOW_OK; + if (demux->segment.stop == GST_CLOCK_TIME_NONE && demux->segment.duration > 0) { demux->segment.stop = demux->segment.duration; @@ -1421,6 +1431,11 @@ gst_asf_demux_chain (GstPad * pad, GstBuffer * buf) while (gst_adapter_available (demux->adapter) >= data_size) { GstBuffer *buf; + /* do not overshoot data section when streaming */ + if (demux->num_packets != 0 && demux->packet >= 0 + && demux->packet >= demux->num_packets) + goto eos; + buf = gst_adapter_take_buffer (demux->adapter, data_size); /* FIXME: maybe we should just skip broken packets and error out only @@ -1433,7 +1448,8 @@ gst_asf_demux_chain (GstPad * pad, GstBuffer * buf) ret = gst_asf_demux_push_complete_payloads (demux, FALSE); - ++demux->packet; + if (demux->packet >= 0) + ++demux->packet; } break; } @@ -1441,10 +1457,18 @@ gst_asf_demux_chain (GstPad * pad, GstBuffer * buf) g_assert_not_reached (); } +done: if (ret != GST_FLOW_OK) GST_DEBUG_OBJECT (demux, "flow: %s", gst_flow_get_name (ret)); return ret; + +eos: + { + GST_DEBUG_OBJECT (demux, "Handled last packet, setting EOS"); + ret = GST_FLOW_UNEXPECTED; + goto done; + } } static inline gboolean diff --git a/gst/asfdemux/gstasfdemux.h b/gst/asfdemux/gstasfdemux.h index 92293b49..353820ba 100644 --- a/gst/asfdemux/gstasfdemux.h +++ b/gst/asfdemux/gstasfdemux.h @@ -134,7 +134,7 @@ struct _GstASFDemux { guint64 data_offset; /* byte offset where packets start */ guint64 data_size; /* total size of packet data in bytes, or 0 */ guint64 num_packets; /* total number of data packets, or 0 */ - guint64 packet; /* current packet */ + gint64 packet; /* current packet */ /* bitrates are unused at the moment */ guint32 bitrate[GST_ASF_DEMUX_NUM_STREAM_IDS]; |