+2005-10-20 Tim-Philipp Müller <tim at centricular dot net>
+
+ * 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 <wim@fluendo.com>
* gst/playback/gstplaybasebin.c: (group_destroy),
#include "vorbisdec.h"
#include <string.h>
+#include <gst/audio/audio.h>
#include <gst/tag/tag.h>
#include <gst/audio/multichannel.h>
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
}
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;
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);
*/
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) {
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);
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;