summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.net>2006-04-20 13:23:40 +0000
committerTim-Philipp Müller <tim@centricular.net>2006-04-20 13:23:40 +0000
commit857f6cf2a83139874961773ea9a4f8901866ef52 (patch)
treeebe2363d17d6a39cbff7feb403d1a47507d02d79 /gst
parenta0522c2394640863d4049873fbacf0ad4dddd115 (diff)
gst/matroska/: Set DISCONT flag on first buffer after a discontinuity.
Original commit message from CVS: * gst/matroska/matroska-demux.c: (gst_matroska_demux_add_stream), (gst_matroskademux_do_index_seek), (gst_matroska_demux_handle_seek_event), (gst_matroska_demux_parse_blockgroup_or_simpleblock): * gst/matroska/matroska-ids.h: Set DISCONT flag on first buffer after a discontinuity. Fix newsegment events sent when seeking and honour KEY_UNIT seek flag. Create pad with bogus caps if we don't recognise the stream codec id. * gst/matroska/matroska-demux.h: Fix GObject macros.
Diffstat (limited to 'gst')
-rw-r--r--gst/matroska/matroska-demux.c107
-rw-r--r--gst/matroska/matroska-demux.h4
-rw-r--r--gst/matroska/matroska-ids.h2
3 files changed, 82 insertions, 31 deletions
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index f3427813..1d4248ad 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -315,6 +315,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
context->type = 0; /* no type yet */
context->default_duration = 0;
context->pos = 0;
+ context->set_discont = TRUE;
demux->num_streams++;
/* start with the master */
@@ -908,9 +909,29 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
GST_TAG_LANGUAGE_CODE, context->language, NULL);
}
+ if (caps == NULL) {
+ GST_WARNING_OBJECT (demux, "could not determine caps for stream with "
+ "codec_id='%s'", context->codec_id);
+ switch (context->type) {
+ case GST_MATROSKA_TRACK_TYPE_VIDEO:
+ caps = gst_caps_new_simple ("video/x-unknown", NULL);
+ break;
+ case GST_MATROSKA_TRACK_TYPE_AUDIO:
+ caps = gst_caps_new_simple ("audio/x-unknown", NULL);
+ break;
+ case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
+ caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
+ break;
+ case GST_MATROSKA_TRACK_TYPE_COMPLEX:
+ default:
+ caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
+ break;
+ }
+ }
+
/* the pad in here */
context->pad = gst_pad_new_from_template (templ, padname);
- context->caps = caps ? caps : gst_caps_new_empty ();
+ context->caps = caps;
gst_pad_set_event_function (context->pad,
GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
@@ -919,20 +940,13 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux)
gst_pad_set_query_function (context->pad,
GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
- if (caps) {
- GST_LOG ("Adding pad '%s' with caps %" GST_PTR_FORMAT, padname, caps);
- if (gst_caps_is_fixed (caps)) {
- gst_pad_use_fixed_caps (context->pad);
- gst_pad_set_caps (context->pad, context->caps);
- gst_pad_set_active (context->pad, TRUE);
- gst_element_add_pad (GST_ELEMENT (demux), context->pad);
- } else {
- g_warning ("FIXME: non-fixed caps: %s", gst_caps_to_string (caps));
- }
- } else {
- /* FIXME: are we leaking the pad here? can this even happen? */
- GST_LOG ("Not adding pad '%s' with empty caps", padname);
- }
+ GST_INFO_OBJECT (demux, "Adding pad '%s' with caps %" GST_PTR_FORMAT,
+ padname, caps);
+
+ gst_pad_use_fixed_caps (context->pad);
+ gst_pad_set_caps (context->pad, context->caps);
+ gst_pad_set_active (context->pad, TRUE);
+ gst_element_add_pad (GST_ELEMENT (demux), context->pad);
/* tags */
if (list) {
@@ -1014,21 +1028,41 @@ gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
static GstMatroskaIndex *
-gst_matroskademux_do_index_seek (GstMatroskaDemux * demux, guint64 seek_pos)
+gst_matroskademux_do_index_seek (GstMatroskaDemux * demux, gint64 seek_pos,
+ gint64 segment_stop, gboolean keyunit)
{
- guint entry = demux->num_indexes - 1;
+ guint entry;
guint n = 0;
if (!demux->num_indexes)
return NULL;
- while (n < demux->num_indexes - 1) {
- if ((demux->index[n].time <= seek_pos) &&
- (demux->index[n + 1].time > seek_pos)) {
- entry = n;
- break;
+ if (keyunit) {
+ /* find index entry closest to the requested position */
+ entry = 0;
+ for (n = 0; n < demux->num_indexes; ++n) {
+ gdouble d_entry, d_this;
+
+ d_entry = fabs ((gdouble) demux->index[entry].time - (gdouble) seek_pos);
+ d_this = fabs ((gdouble) demux->index[n].time - (gdouble) seek_pos);
+
+ if (d_this < d_entry &&
+ (demux->index[n].time < segment_stop || segment_stop == -1)) {
+ entry = n;
+ }
+ }
+ } else {
+ /* find index entry at or before the requested position */
+ entry = demux->num_indexes - 1;
+
+ while (n < demux->num_indexes - 1) {
+ if ((demux->index[n].time <= seek_pos) &&
+ (demux->index[n + 1].time > seek_pos)) {
+ entry = n;
+ break;
+ }
+ n++;
}
- n++;
}
return &demux->index[entry];
@@ -1080,7 +1114,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
GstSeekType cur_type, stop_type;
GstFormat format;
GstEvent *newsegment_event;
- gboolean flush;
+ gboolean flush, keyunit;
gdouble rate;
gint64 cur, stop;
gint64 segment_start, segment_stop;
@@ -1104,7 +1138,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
/* check sanity before we start flushing and all that */
if (cur_type == GST_SEEK_TYPE_SET) {
GST_OBJECT_LOCK (demux);
- if (!gst_matroskademux_do_index_seek (demux, cur)) {
+ if (!gst_matroskademux_do_index_seek (demux, cur, -1, FALSE)) {
GST_DEBUG ("No matching seek entry in index");
GST_OBJECT_UNLOCK (demux);
return FALSE;
@@ -1114,6 +1148,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
}
flush = !!(flags & GST_SEEK_FLAG_FLUSH);
+ keyunit = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
if (flush) {
GST_DEBUG ("Starting flush");
@@ -1156,7 +1191,9 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
GST_DEBUG ("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, segment_start);
+ entry = gst_matroskademux_do_index_seek (demux, segment_start,
+ segment_stop, keyunit);
+
if (!entry) {
GST_DEBUG ("No matching seek entry in index");
goto seek_error;
@@ -1173,6 +1210,12 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
GST_DEBUG ("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_TIME_FORMAT, GST_TIME_ARGS (entry->time));
+ segment_start = entry->time;
+ }
+
GST_DEBUG ("Committing new seek segment");
demux->segment_rate = rate;
@@ -1192,9 +1235,8 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
gst_element_post_message (GST_ELEMENT (demux), msg);
}
- /* FIXME: should be demux->segment_start, not entry->time */
newsegment_event = gst_event_new_new_segment (FALSE, rate,
- GST_FORMAT_TIME, entry->time, segment_stop, entry->time);
+ GST_FORMAT_TIME, segment_start, segment_stop, segment_start);
GST_DEBUG ("Stopping flush");
if (flush) {
@@ -1204,8 +1246,10 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
/* send newsegment event to all source pads and update the time */
gst_matroska_demux_send_event (demux, newsegment_event);
- for (i = 0; i < demux->num_streams; i++)
+ for (i = 0; i < demux->num_streams; i++) {
demux->src[i]->pos = entry->time;
+ demux->src[i]->set_discont = TRUE;
+ }
demux->pos = entry->time;
/* restart our task since it might have been stopped when we did the
@@ -2363,6 +2407,11 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DELTA_UNIT);
}
+ if (stream->set_discont) {
+ GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT);
+ stream->set_discont = FALSE;
+ }
+
GST_DEBUG ("Pushing data of size %d for stream %d, time=%"
GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT,
GST_BUFFER_SIZE (sub), stream_num,
diff --git a/gst/matroska/matroska-demux.h b/gst/matroska/matroska-demux.h
index 14401a58..49b073bb 100644
--- a/gst/matroska/matroska-demux.h
+++ b/gst/matroska/matroska-demux.h
@@ -34,10 +34,10 @@ G_BEGIN_DECLS
#define GST_MATROSKA_DEMUX(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MATROSKA_DEMUX, GstMatroskaDemux))
#define GST_MATROSKA_DEMUX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MATROSKA_DEMUX, GstMatroskaDemux))
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MATROSKA_DEMUX, GstMatroskaDemuxClass))
#define GST_IS_MATROSKA_DEMUX(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MATROSKA_DEMUX))
-#define GST_IS_MATROSKA_DEMUX_CLASS(obj) \
+#define GST_IS_MATROSKA_DEMUX_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MATROSKA_DEMUX))
#define GST_MATROSKA_DEMUX_MAX_STREAMS 64
diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h
index 71dfc634..c8c6d371 100644
--- a/gst/matroska/matroska-ids.h
+++ b/gst/matroska/matroska-ids.h
@@ -243,6 +243,8 @@ typedef struct _GstMatroskaTrackContext {
GstMatroskaTrackFlags flags;
guint64 default_duration;
guint64 pos;
+
+ gboolean set_discont; /* TRUE = set DISCONT flag on next buffer */
} GstMatroskaTrackContext;
typedef struct _GstMatroskaTrackVideoContext {