From c94e964c3644639169e4b23dfcf984f227b81ba5 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 5 Jun 2004 18:50:47 +0000 Subject: gst/qtdemux/qtdemux.*: Bitch. Also known as seeking, querying & co. Original commit message from CVS: * gst/qtdemux/qtdemux.c: (gst_qtdemux_init), (gst_qtdemux_handle_src_query), (gst_qtdemux_handle_src_event), (gst_qtdemux_handle_sink_event), (gst_qtdemux_change_state), (gst_qtdemux_loop_header), (qtdemux_dump_mvhd), (qtdemux_parse_trak): * gst/qtdemux/qtdemux.h: Bitch. Also known as seeking, querying & co. * sys/oss/gstosssink.c: (gst_osssink_init), (gst_osssink_chain), (gst_osssink_change_state): * sys/oss/gstosssink.h: Resyncing is for weenies, this hack is no longer needed and was broken anyway (since it - unintendedly - always leaves resync to TRUE). --- gst/qtdemux/qtdemux.c | 99 ++++++++++++++++++++++++++++++++++++++++----------- gst/qtdemux/qtdemux.h | 3 ++ 2 files changed, 82 insertions(+), 20 deletions(-) (limited to 'gst/qtdemux') diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index 833c805f..6b97ad29 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -231,6 +231,10 @@ gst_qtdemux_init (GstQTDemux * qtdemux) gst_element_set_loop_function (GST_ELEMENT (qtdemux), gst_qtdemux_loop_header); gst_element_add_pad (GST_ELEMENT (qtdemux), qtdemux->sinkpad); + + qtdemux->last_ts = GST_CLOCK_TIME_NONE; + qtdemux->need_discont = FALSE; + qtdemux->need_flush = FALSE; } static const GstFormat * @@ -332,7 +336,8 @@ static gboolean gst_qtdemux_handle_src_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value) { - gboolean res = TRUE; + gboolean res = FALSE; + GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad)); //QtDemuxStream *stream = gst_pad_get_element_private(pad); @@ -340,7 +345,11 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstQueryType type, case GST_QUERY_TOTAL: switch (*format) { case GST_FORMAT_TIME: - *value = 0; /* FIXME */ + if (qtdemux->duration != 0 && qtdemux->timescale != 0) { + *value = + (guint64) qtdemux->duration * GST_SECOND / qtdemux->timescale; + res = TRUE; + } break; case GST_FORMAT_BYTES: *value = 0; /* FIXME */ @@ -356,7 +365,10 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstQueryType type, case GST_QUERY_POSITION: switch (*format) { case GST_FORMAT_TIME: - *value = 0; /* FIXME */ + if (GST_CLOCK_TIME_IS_VALID (qtdemux->last_ts)) { + *value = qtdemux->last_ts; + res = TRUE; + } break; case GST_FORMAT_BYTES: *value = 0; /* FIXME */ @@ -381,8 +393,7 @@ static gboolean gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event) { gboolean res = TRUE; - - //QtDemuxStream *stream = gst_pad_get_element_private(pad); + GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEEK: @@ -391,13 +402,35 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event) switch (GST_EVENT_SEEK_FORMAT (event)) { case GST_FORMAT_BYTES: case GST_FORMAT_DEFAULT: + res = FALSE; + break; case GST_FORMAT_TIME: { gint64 desired_offset = GST_EVENT_SEEK_OFFSET (event); + gint i = 0, n; + QtDemuxStream *stream = gst_pad_get_element_private (pad); GST_DEBUG ("seeking to %" G_GINT64_FORMAT, desired_offset); - res = FALSE; + if (!stream->n_samples) { + res = FALSE; + break; + } + + /* resync to new time */ + for (n = 0; n < qtdemux->n_streams; n++) { + QtDemuxStream *str = qtdemux->streams[n]; + + for (i = 0; i < str->n_samples; i++) { + if (str->samples[i].timestamp > desired_offset) + break; + } + str->sample_index = i; + } + qtdemux->need_discont = TRUE; + if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) + qtdemux->need_flush = TRUE; + break; } default: res = FALSE; @@ -456,7 +489,6 @@ gst_qtdemux_handle_sink_event (GstQTDemux * qtdemux) gst_pad_event_default (qtdemux->sinkpad, event); return FALSE; case GST_EVENT_FLUSH: - //g_warning("flush event"); break; case GST_EVENT_DISCONTINUOUS: GST_DEBUG ("discontinuous event"); @@ -490,6 +522,9 @@ gst_qtdemux_change_state (GstElement * element) case GST_STATE_PLAYING_TO_PAUSED: break; case GST_STATE_PAUSED_TO_READY: + qtdemux->last_ts = GST_CLOCK_TIME_NONE; + qtdemux->need_discont = FALSE; + qtdemux->need_flush = FALSE; break; case GST_STATE_READY_TO_NULL: gst_bytestream_destroy (qtdemux->bs); @@ -727,8 +762,29 @@ gst_qtdemux_loop_header (GstElement * element) GST_BUFFER_TIMESTAMP (buf) = stream->samples[stream->sample_index].timestamp; + qtdemux->last_ts = GST_BUFFER_TIMESTAMP (buf); GST_BUFFER_DURATION (buf) = stream->samples[stream->sample_index].duration; + if (qtdemux->need_flush) { + gst_pad_event_default (qtdemux->sinkpad, + gst_event_new (GST_EVENT_FLUSH)); + qtdemux->need_flush = FALSE; + } + if (qtdemux->need_discont) { + GstEvent *event = gst_event_new_discontinuous (FALSE, + GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf), + GST_FORMAT_UNDEFINED); + gint n; + + qtdemux->need_discont = FALSE; + for (n = 0; n < qtdemux->n_streams; n++) { + gst_event_ref (event); + gst_pad_push (qtdemux->streams[n]->pad, GST_DATA (event)); + } + gst_event_unref (event); + } + g_print ("Pushing buf with time=%" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); gst_pad_push (stream->pad, GST_DATA (buf)); GST_INFO ("pushing buffer on %" GST_PTR_FORMAT, stream->pad); @@ -1307,6 +1363,8 @@ qtdemux_dump_mvhd (GstQTDemux * qtdemux, void *buffer, int depth) QTDEMUX_GUINT32_GET (buffer + 20)); GST_LOG ("%*s duration: %u", depth, "", QTDEMUX_GUINT32_GET (buffer + 24)); + qtdemux->duration = QTDEMUX_GUINT32_GET (buffer + 24); + qtdemux->timescale = QTDEMUX_GUINT32_GET (buffer + 20); GST_LOG ("%*s pref. rate: %g", depth, "", QTDEMUX_FP32_GET (buffer + 28)); GST_LOG ("%*s pref. volume: %g", depth, "", QTDEMUX_FP16_GET (buffer + 32)); GST_LOG ("%*s preview time: %u", depth, "", @@ -2077,30 +2135,31 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) sample_index += samples_per_chunk; } } -/* -done2: - n_sample_times = QTDEMUX_GUINT32_GET(stts->data + 12); - GST_LOG("n_sample_times = %d",n_sample_times); +#if 0 + done2: + n_sample_times = QTDEMUX_GUINT32_GET (stts->data + 12); + GST_LOG ("n_sample_times = %d", n_sample_times); timestamp = 0; index = 0; sample_index = 0; - for(i=0;idata + 16 + 8*i); - duration = QTDEMUX_GUINT32_GET(stts->data + 16 + 8*i + 4); - for(;index < n_samples && samples[index].sample_index < sample_index;index++){ - int size; + + sample_index += QTDEMUX_GUINT32_GET (stts->data + 16 + 8 * i); + duration = QTDEMUX_GUINT32_GET (stts->data + 16 + 8 * i + 4); + for (; index < n_samples && samples[index].sample_index < sample_index; + index++) { + int size; samples[index].timestamp = timestamp; - size = samples[index+1].sample_index - samples[index].sample_index; - time = GST_SECOND / stream->rate; //(GST_SECOND * duration * samples[index].size)/stream->timescale ; + size = samples[index + 1].sample_index - samples[index].sample_index; + time = GST_SECOND / stream->rate; //(GST_SECOND * duration * samples[index].size)/stream->timescale ; timestamp += time; samples[index].duration = time; } } -*/ +#endif } done2: #if 0 diff --git a/gst/qtdemux/qtdemux.h b/gst/qtdemux/qtdemux.h index 0feaea05..d6ed313e 100644 --- a/gst/qtdemux/qtdemux.h +++ b/gst/qtdemux/qtdemux.h @@ -74,6 +74,9 @@ struct _GstQTDemux { /* track stuff */ + guint64 last_ts; + gboolean need_discont; + gboolean need_flush; }; struct _GstQTDemuxClass { -- cgit v1.2.1