summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2008-08-08 16:20:26 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-08-08 16:20:26 +0000
commitba69194f332856cc53a870ee381a806b0fd65ff5 (patch)
treef773e6e402e332212c8902b3ec0704f499549b45 /gst
parentc0468721320c10978e70a4ac9072d1d8774e5e62 (diff)
gst/matroska/matroska-demux.*: Close the current segment if we're doing a non-flushing seek and send the close-segmen...
Original commit message from CVS: * gst/matroska/matroska-demux.c: (gst_matroska_demux_reset), (gst_matroska_demux_element_send_event), (gst_matroska_demux_handle_seek_event), (gst_matroska_demux_loop): * gst/matroska/matroska-demux.h: Close the current segment if we're doing a non-flushing seek and send the close-segment and the new segment of the seek from the streaming thread.
Diffstat (limited to 'gst')
-rw-r--r--gst/matroska/matroska-demux.c97
-rw-r--r--gst/matroska/matroska-demux.h9
2 files changed, 69 insertions, 37 deletions
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 8e3dc94c..42ef2703 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -21,12 +21,9 @@
* Boston, MA 02111-1307, USA.
*/
-/* TODO: dynamic number of tracks without upper bound
- * TODO: check CRC32 if present
+/* TODO: check CRC32 if present
* TODO: there can be a segment after the first segment. Handle like
* chained oggs. Fixes #334082
- * TODO: Better handling of segments: close old segments, start first segment
- * at the first buffer timestamp and not at 0
* TODO: Test samples: http://www.matroska.org/samples/matrix/index.html
* http://samples.mplayerhq.hu/Matroska/
* TODO: check if demuxing is done correct for all codecs according to spec
@@ -360,6 +357,16 @@ gst_matroska_demux_reset (GstElement * element)
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
demux->duration = -1;
+
+ if (demux->close_segment) {
+ gst_event_unref (demux->close_segment);
+ demux->close_segment = NULL;
+ }
+
+ if (demux->new_segment) {
+ gst_event_unref (demux->new_segment);
+ demux->new_segment = NULL;
+ }
}
static gint
@@ -2012,7 +2019,8 @@ gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event)
if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
res = gst_matroska_demux_handle_seek_event (demux, NULL, event);
} else {
- GST_WARNING ("Unhandled event of type %s", GST_EVENT_TYPE_NAME (event));
+ GST_WARNING_OBJECT (demux, "Unhandled event of type %s",
+ GST_EVENT_TYPE_NAME (event));
res = FALSE;
}
gst_event_unref (event);
@@ -2027,7 +2035,6 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
GstSeekFlags flags;
GstSeekType cur_type, stop_type;
GstFormat format;
- GstEvent *newsegment_event;
gboolean flush, keyunit;
gdouble rate;
gint64 cur, stop;
@@ -2045,13 +2052,13 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
/* we can only seek on time */
if (format != GST_FORMAT_TIME) {
- GST_DEBUG ("Can only seek on TIME");
+ GST_DEBUG_OBJECT (demux, "Can only seek on TIME");
return FALSE;
}
/* cannot yet do backwards playback */
if (rate <= 0.0) {
- GST_DEBUG ("Can only seek with positive rate");
+ GST_DEBUG_OBJECT (demux, "Can only seek with positive rate");
return FALSE;
}
@@ -2059,11 +2066,11 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
if (cur_type == GST_SEEK_TYPE_SET) {
GST_OBJECT_LOCK (demux);
if (!gst_matroskademux_do_index_seek (demux, 0, cur, -1, FALSE)) {
- GST_DEBUG ("No matching seek entry in index");
+ GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
GST_OBJECT_UNLOCK (demux);
return FALSE;
}
- GST_DEBUG ("Seek position looks sane");
+ GST_DEBUG_OBJECT (demux, "Seek position looks sane");
GST_OBJECT_UNLOCK (demux);
}
@@ -2071,7 +2078,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
keyunit = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
if (flush) {
- GST_DEBUG ("Starting flush");
+ GST_DEBUG_OBJECT (demux, "Starting flush");
gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
gst_matroska_demux_send_event (demux, gst_event_new_flush_start ());
} else {
@@ -2109,35 +2116,56 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
segment_stop = -1;
}
- GST_DEBUG ("New segment positions: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
+ GST_DEBUG_OBJECT (demux,
+ "New segment positions: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
GST_TIME_ARGS (segment_start), GST_TIME_ARGS (segment_stop));
entry = gst_matroskademux_do_index_seek (demux, track, segment_start,
segment_stop, keyunit);
if (!entry) {
- GST_DEBUG ("No matching seek entry in index");
+ GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
goto seek_error;
}
/* seek (relative to matroska segment) */
if (gst_ebml_read_seek (GST_EBML_READ (demux),
entry->pos + demux->ebml_segment_start) != GST_FLOW_OK) {
- GST_DEBUG ("Failed to seek to offset %" G_GUINT64_FORMAT,
+ GST_DEBUG_OBJECT (demux, "Failed to seek to offset %" G_GUINT64_FORMAT,
entry->pos + demux->ebml_segment_start);
goto seek_error;
}
- GST_DEBUG ("Seeked to offset %" G_GUINT64_FORMAT, entry->pos +
+ GST_DEBUG_OBJECT (demux, "Seeked to offset %" G_GUINT64_FORMAT, entry->pos +
demux->ebml_segment_start);
if (keyunit) {
- GST_DEBUG ("seek to key unit, adjusting segment start to %"
+ GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
segment_start = entry->time;
}
- GST_DEBUG ("Committing new seek segment");
+ GST_OBJECT_UNLOCK (demux);
+
+ if (flush) {
+ GST_DEBUG_OBJECT (demux, "Stopping flush");
+ gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
+ gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
+ } else if (demux->segment_running) {
+ GST_DEBUG_OBJECT (demux, "Closing currently running segment");
+
+ GST_OBJECT_LOCK (demux);
+ if (demux->close_segment)
+ gst_event_unref (demux->close_segment);
+
+ demux->close_segment = gst_event_new_new_segment (TRUE,
+ demux->segment.rate, GST_FORMAT_TIME, demux->segment.start,
+ demux->segment.last_stop, demux->segment.last_stop);
+ GST_OBJECT_UNLOCK (demux);
+ }
+
+ GST_OBJECT_LOCK (demux);
+ GST_DEBUG_OBJECT (demux, "Committing new seek segment");
demux->segment.rate = rate;
demux->segment.flags = flags;
@@ -2156,21 +2184,14 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
gst_element_post_message (GST_ELEMENT (demux), msg);
}
- newsegment_event = gst_event_new_new_segment (FALSE, rate,
+ GST_OBJECT_LOCK (demux);
+ if (demux->new_segment)
+ gst_event_unref (demux->new_segment);
+ demux->new_segment = gst_event_new_new_segment (FALSE, rate,
GST_FORMAT_TIME, segment_start, segment_stop, segment_start);
+ GST_OBJECT_UNLOCK (demux);
- if (flush) {
- GST_DEBUG ("Stopping flush");
- gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop ());
- gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
- } else if (demux->segment_running) {
- /* FIXME, the current segment was still running when we performed the
- * seek, we need to close the current segment */
- GST_DEBUG ("Closing currently running segment");
- }
-
- /* send newsegment event to all source pads and update the time */
- gst_matroska_demux_send_event (demux, newsegment_event);
+ /* update the time */
g_assert (demux->src->len == demux->num_streams);
for (i = 0; i < demux->src->len; i++) {
GstMatroskaTrackContext *context = g_ptr_array_index (demux->src, i);
@@ -2195,7 +2216,7 @@ seek_error:
{
/* FIXME: shouldn't we either make it a real error or start the task
* function again so that things can continue from where they left off? */
- GST_DEBUG ("Got a seek error");
+ GST_DEBUG_OBJECT (demux, "Got a seek error");
GST_OBJECT_UNLOCK (demux);
GST_PAD_STREAM_UNLOCK (demux->sinkpad);
return FALSE;
@@ -4787,6 +4808,20 @@ gst_matroska_demux_loop (GstPad * pad)
demux->state = GST_MATROSKA_DEMUX_STATE_HEADER;
}
+ /* If we have to close a segment are send a new segment do
+ * this now */
+
+ if (demux->state == GST_MATROSKA_DEMUX_STATE_DATA) {
+ if (demux->close_segment) {
+ gst_matroska_demux_send_event (demux, demux->close_segment);
+ demux->close_segment = NULL;
+ }
+ if (demux->new_segment) {
+ gst_matroska_demux_send_event (demux, demux->new_segment);
+ demux->new_segment = NULL;
+ }
+ }
+
ret = gst_matroska_demux_loop_stream (demux);
if (ret != GST_FLOW_OK)
goto pause;
diff --git a/gst/matroska/matroska-demux.h b/gst/matroska/matroska-demux.h
index 6ed07feb..846ce289 100644
--- a/gst/matroska/matroska-demux.h
+++ b/gst/matroska/matroska-demux.h
@@ -46,12 +46,6 @@ typedef enum {
GST_MATROSKA_DEMUX_STATE_DATA
} GstMatroskaDemuxState;
-typedef struct _GstMatroskaDemuxIndex {
- guint64 pos; /* of the corresponding *cluster*! */
- guint16 track; /* reference to 'num' */
- guint64 time; /* in nanoseconds */
-} GstMatroskaDemuxIndex;
-
typedef struct _GstMatroskaDemux {
GstEbmlRead parent;
@@ -93,6 +87,9 @@ typedef struct _GstMatroskaDemux {
GstSegment segment;
gboolean segment_running;
gint64 duration;
+
+ GstEvent *close_segment;
+ GstEvent *new_segment;
} GstMatroskaDemux;
typedef struct _GstMatroskaDemuxClass {