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.
This commit is contained in:
Tim-Philipp Müller 2005-10-20 16:01:43 +00:00
parent d108bc0882
commit ba34565cfc
3 changed files with 52 additions and 4 deletions

View file

@ -1,3 +1,15 @@
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),

View file

@ -23,6 +23,7 @@
#include "vorbisdec.h"
#include <string.h>
#include <gst/audio/audio.h>
#include <gst/tag/tag.h>
#include <gst/audio/multichannel.h>
@ -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;

View file

@ -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 {