From ba34565cfcd3a23c1e1eccb9893b955e13b05fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 20 Oct 2005 16:01:43 +0000 Subject: [PATCH] ext/vorbis/vorbisdec.*: Vorbis streams can be embedded in other container formats than ogg, container formats where t... Original commit message from CVS: * ext/vorbis/vorbisdec.c: (vorbis_dec_sink_event), (vorbis_handle_data_packet), (vorbis_dec_chain), (vorbis_dec_change_state): * ext/vorbis/vorbisdec.h: Vorbis streams can be embedded in other container formats than ogg, container formats where the demuxer might set timestamps on encoded vorbis buffers instead of those silly granulepos thingies. In short: make vorbisdec handle timestamps on incoming buffers as well. --- ChangeLog | 12 ++++++++++++ ext/vorbis/vorbisdec.c | 41 +++++++++++++++++++++++++++++++++++++---- ext/vorbis/vorbisdec.h | 3 +++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24672bca93..9c04b8f0bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2005-10-20 Tim-Philipp Müller + + * ext/vorbis/vorbisdec.c: (vorbis_dec_sink_event), + (vorbis_handle_data_packet), (vorbis_dec_chain), + (vorbis_dec_change_state): + * ext/vorbis/vorbisdec.h: + Vorbis streams can be embedded in other container formats + than ogg, container formats where the demuxer might set + timestamps on encoded vorbis buffers instead of those silly + granulepos thingies. In short: make vorbisdec handle + timestamps on incoming buffers as well. + 2005-10-20 Wim Taymans * gst/playback/gstplaybasebin.c: (group_destroy), diff --git a/ext/vorbis/vorbisdec.c b/ext/vorbis/vorbisdec.c index 9f9651d0ce..d4e2e19668 100644 --- a/ext/vorbis/vorbisdec.c +++ b/ext/vorbis/vorbisdec.c @@ -23,6 +23,7 @@ #include "vorbisdec.h" #include +#include #include #include @@ -452,6 +453,9 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event) dec->segment_base = base; dec->granulepos = -1; + dec->cur_timestamp = GST_CLOCK_TIME_NONE; + dec->prev_timestamp = GST_CLOCK_TIME_NONE; + #ifdef HAVE_VORBIS_SYNTHESIS_RESTART vorbis_synthesis_restart (&dec->vd); #endif @@ -791,6 +795,18 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet) } GST_BUFFER_DURATION (out) = sample_count * GST_SECOND / vd->vi.rate; + if (vd->cur_timestamp != GST_CLOCK_TIME_NONE) { + GST_BUFFER_TIMESTAMP (out) = vd->cur_timestamp; + GST_DEBUG ("cur_timestamp: %" GST_TIME_FORMAT " + %" GST_TIME_FORMAT " = % " + GST_TIME_FORMAT, GST_TIME_ARGS (vd->cur_timestamp), + GST_TIME_ARGS (GST_BUFFER_DURATION (out)), + GST_TIME_ARGS (vd->cur_timestamp + GST_BUFFER_DURATION (out))); + vd->cur_timestamp += GST_BUFFER_DURATION (out); + GST_BUFFER_OFFSET (out) = GST_CLOCK_TIME_TO_FRAMES (vd->cur_timestamp, + vd->vi.rate); + GST_BUFFER_OFFSET_END (out) = GST_BUFFER_OFFSET (out) + sample_count; + } + if (vd->granulepos != -1) vd->granulepos += sample_count; @@ -847,6 +863,21 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer) GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL), ("empty buffer received")); return GST_FLOW_ERROR; } + + /* only ogg has granulepos, demuxers of other container formats + * might provide us with timestamps instead (e.g. matroskademux) */ + if (GST_BUFFER_OFFSET_END (buffer) == GST_BUFFER_OFFSET_NONE && + GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE) { + /* we might get multiple consecutive buffers with the same timestamp */ + if (GST_BUFFER_TIMESTAMP (buffer) != vd->prev_timestamp) { + vd->cur_timestamp = GST_BUFFER_TIMESTAMP (buffer); + vd->prev_timestamp = GST_BUFFER_TIMESTAMP (buffer); + } + } else { + vd->cur_timestamp = GST_CLOCK_TIME_NONE; + vd->prev_timestamp = GST_CLOCK_TIME_NONE; + } + /* make ogg_packet out of the buffer */ packet.packet = GST_BUFFER_DATA (buffer); packet.bytes = GST_BUFFER_SIZE (buffer); @@ -860,8 +891,8 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer) */ packet.e_o_s = 0; - GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GUINT64_FORMAT, - packet.granulepos); + GST_DEBUG_OBJECT (vd, "vorbis granule: %" G_GINT64_FORMAT, + (gint64) packet.granulepos); /* switch depending on packet type */ if (packet.packet[0] & 1) { @@ -874,8 +905,8 @@ vorbis_dec_chain (GstPad * pad, GstBuffer * buffer) result = vorbis_handle_data_packet (vd, &packet); } - GST_DEBUG_OBJECT (vd, "offset end: %" G_GUINT64_FORMAT, - GST_BUFFER_OFFSET_END (buffer)); + GST_DEBUG_OBJECT (vd, "offset end: %" G_GINT64_FORMAT, + (gint64) GST_BUFFER_OFFSET_END (buffer)); done: gst_buffer_unref (buffer); @@ -897,6 +928,8 @@ vorbis_dec_change_state (GstElement * element, GstStateChange transition) vorbis_info_init (&vd->vi); vorbis_comment_init (&vd->vc); vd->initialized = FALSE; + vd->cur_timestamp = GST_CLOCK_TIME_NONE; + vd->prev_timestamp = GST_CLOCK_TIME_NONE; vd->granulepos = -1; vd->packetno = 0; break; diff --git a/ext/vorbis/vorbisdec.h b/ext/vorbis/vorbisdec.h index 6ca7fd378a..4c0136690b 100644 --- a/ext/vorbis/vorbisdec.h +++ b/ext/vorbis/vorbisdec.h @@ -63,6 +63,9 @@ struct _GstVorbisDec { gint64 segment_start; gint64 segment_stop; gint64 segment_base; + + GstClockTime cur_timestamp; /* only used with non-ogg container formats */ + GstClockTime prev_timestamp; /* only used with non-ogg container formats */ }; struct _GstVorbisDecClass {