summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaas <klaas@rivercrew.net>2008-10-08 12:08:01 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-10-08 12:08:01 +0000
commit93f2eaa98c246368592052792439521194c2b170 (patch)
treedba018e926b8a17f82c5b7d18bcf75739d22b8b2
parentc915582c17f420bd32b7d3538f95dfeb47ca51c2 (diff)
ext/vorbis/vorbisenc.*: Keep track of the upstream segments and use the running time on that segment instead of the b...
Original commit message from CVS: Based on a patch by: Klaas <klaas at rivercrew dot net> * ext/vorbis/vorbisenc.c: (gst_vorbis_enc_sink_event), (gst_vorbis_enc_buffer_check_discontinuous), (gst_vorbis_enc_chain), (gst_vorbis_enc_change_state): * ext/vorbis/vorbisenc.h: Keep track of the upstream segments and use the running time on that segment instead of the buffer timestamp everywhere. Fixes bug #525807.
-rw-r--r--ChangeLog11
-rw-r--r--ext/vorbis/vorbisenc.c66
-rw-r--r--ext/vorbis/vorbisenc.h1
3 files changed, 53 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 78a5aab683..12bfe0e5f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2008-10-08 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ Based on a patch by: Klaas <klaas at rivercrew dot net>
+
+ * ext/vorbis/vorbisenc.c: (gst_vorbis_enc_sink_event),
+ (gst_vorbis_enc_buffer_check_discontinuous),
+ (gst_vorbis_enc_chain), (gst_vorbis_enc_change_state):
+ * ext/vorbis/vorbisenc.h:
+ Keep track of the upstream segments and use the running time on that
+ segment instead of the buffer timestamp everywhere. Fixes bug #525807.
+
+2008-10-08 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+
* gst/audioconvert/audioconvert.c: (audio_convert_convert):
Prevent overflows with big buffer when calculating the size of
the intermediate buffer by using gst_util_uint64_scale() instead of
diff --git a/ext/vorbis/vorbisenc.c b/ext/vorbis/vorbisenc.c
index 08089fc03b..842738d040 100644
--- a/ext/vorbis/vorbisenc.c
+++ b/ext/vorbis/vorbisenc.c
@@ -1033,6 +1033,20 @@ gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event)
}
res = gst_pad_push_event (vorbisenc->srcpad, event);
break;
+ case GST_EVENT_NEWSEGMENT:
+ {
+ gboolean update;
+ gdouble rate, applied_rate;
+ GstFormat format;
+ gint64 start, stop, position;
+
+ gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
+ &format, &start, &stop, &position);
+ if (format == GST_FORMAT_TIME)
+ gst_segment_set_newsegment (&vorbisenc->segment, update, rate, format,
+ start, stop, position);
+ }
+ /* fall through */
default:
res = gst_pad_push_event (vorbisenc->srcpad, event);
break;
@@ -1042,33 +1056,29 @@ gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event)
static gboolean
gst_vorbis_enc_buffer_check_discontinuous (GstVorbisEnc * vorbisenc,
- GstBuffer * buffer)
+ GstClockTime timestamp, GstClockTime duration)
{
gboolean ret = FALSE;
- if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE &&
+ if (timestamp != GST_CLOCK_TIME_NONE &&
vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
- GST_BUFFER_TIMESTAMP (buffer) != vorbisenc->expected_ts) {
+ duration != vorbisenc->expected_ts) {
/* It turns out that a lot of elements don't generate perfect streams due
* to rounding errors. So, we permit small errors (< 1/2 a sample) without
* causing a discont.
*/
int halfsample = GST_SECOND / vorbisenc->frequency / 2;
- if ((GstClockTimeDiff) (GST_BUFFER_TIMESTAMP (buffer) -
- vorbisenc->expected_ts) > halfsample) {
+ if ((GstClockTimeDiff) (timestamp - vorbisenc->expected_ts) > halfsample) {
GST_DEBUG_OBJECT (vorbisenc, "Expected TS %" GST_TIME_FORMAT
", buffer TS %" GST_TIME_FORMAT,
- GST_TIME_ARGS (vorbisenc->expected_ts),
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
+ GST_TIME_ARGS (vorbisenc->expected_ts), GST_TIME_ARGS (timestamp));
ret = TRUE;
}
}
- if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE &&
- GST_BUFFER_DURATION (buffer) != GST_CLOCK_TIME_NONE) {
- vorbisenc->expected_ts = GST_BUFFER_TIMESTAMP (buffer) +
- GST_BUFFER_DURATION (buffer);
+ if (timestamp != GST_CLOCK_TIME_NONE && duration != GST_CLOCK_TIME_NONE) {
+ vorbisenc->expected_ts = timestamp + duration;
} else
vorbisenc->expected_ts = GST_CLOCK_TIME_NONE;
@@ -1086,12 +1096,17 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
float **vorbis_buffer;
GstBuffer *buf1, *buf2, *buf3;
gboolean first = FALSE;
+ GstClockTime timestamp = GST_CLOCK_TIME_NONE;
vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
if (!vorbisenc->setup)
goto not_setup;
+ timestamp =
+ gst_segment_to_running_time (&vorbisenc->segment, GST_FORMAT_TIME,
+ GST_BUFFER_TIMESTAMP (buffer));
+
if (!vorbisenc->header_sent) {
/* Vorbis streams begin with three headers; the initial header (with
most of the codec setup parameters) which is mandated by the Ogg
@@ -1148,10 +1163,10 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
/* now adjust starting granulepos accordingly if the buffer's timestamp is
nonzero */
- vorbisenc->next_ts = GST_BUFFER_TIMESTAMP (buffer);
- vorbisenc->expected_ts = GST_BUFFER_TIMESTAMP (buffer);
+ vorbisenc->next_ts = timestamp;
+ vorbisenc->expected_ts = timestamp;
vorbisenc->granulepos_offset = gst_util_uint64_scale
- (GST_BUFFER_TIMESTAMP (buffer), vorbisenc->frequency, GST_SECOND);
+ (timestamp, vorbisenc->frequency, GST_SECOND);
vorbisenc->subgranule_offset = 0;
vorbisenc->subgranule_offset =
vorbisenc->next_ts - granulepos_to_timestamp_offset (vorbisenc, 0);
@@ -1161,15 +1176,14 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
}
if (vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
- GST_BUFFER_TIMESTAMP (buffer) < vorbisenc->expected_ts) {
- guint64 diff = vorbisenc->expected_ts - GST_BUFFER_TIMESTAMP (buffer);
+ timestamp < vorbisenc->expected_ts) {
+ guint64 diff = vorbisenc->expected_ts - timestamp;
guint64 diff_bytes;
GST_WARNING_OBJECT (vorbisenc, "Buffer is older than previous "
"timestamp + duration (%" GST_TIME_FORMAT "< %" GST_TIME_FORMAT
"), cannot handle. Clipping buffer.",
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
- GST_TIME_ARGS (vorbisenc->expected_ts));
+ GST_TIME_ARGS (timestamp), GST_TIME_ARGS (vorbisenc->expected_ts));
diff_bytes =
GST_CLOCK_TIME_TO_FRAMES (diff,
@@ -1187,11 +1201,12 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
GST_BUFFER_DURATION (buffer) -= diff;
}
- if (gst_vorbis_enc_buffer_check_discontinuous (vorbisenc, buffer) && !first) {
- GST_WARNING_OBJECT (vorbisenc, "Buffer is discontinuous, flushing encoder "
- "and restarting (Discont from %" GST_TIME_FORMAT
- " to %" GST_TIME_FORMAT ")", GST_TIME_ARGS (vorbisenc->next_ts),
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
+ if (gst_vorbis_enc_buffer_check_discontinuous (vorbisenc, timestamp,
+ GST_BUFFER_DURATION (buffer)) && !first) {
+ GST_WARNING_OBJECT (vorbisenc,
+ "Buffer is discontinuous, flushing encoder "
+ "and restarting (Discont from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT
+ ")", GST_TIME_ARGS (vorbisenc->next_ts), GST_TIME_ARGS (timestamp));
/* Re-initialise encoder (there's unfortunately no API to flush it) */
if ((ret = gst_vorbis_enc_clear (vorbisenc)) != GST_FLOW_OK)
return ret;
@@ -1200,11 +1215,11 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
we successfully initialised earlier */
/* Now, set our granulepos offset appropriately. */
- vorbisenc->next_ts = GST_BUFFER_TIMESTAMP (buffer);
+ vorbisenc->next_ts = timestamp;
/* We need to round to the nearest whole number of samples, not just do
* a truncating division here */
vorbisenc->granulepos_offset = gst_util_uint64_scale
- (GST_BUFFER_TIMESTAMP (buffer) + GST_SECOND / vorbisenc->frequency / 2
+ (timestamp + GST_SECOND / vorbisenc->frequency / 2
- vorbisenc->subgranule_offset, vorbisenc->frequency, GST_SECOND);
vorbisenc->header_sent = TRUE;
@@ -1418,6 +1433,7 @@ gst_vorbis_enc_change_state (GstElement * element, GstStateChange transition)
vorbisenc->setup = FALSE;
vorbisenc->next_discont = FALSE;
vorbisenc->header_sent = FALSE;
+ gst_segment_init (&vorbisenc->segment, GST_FORMAT_TIME);
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
break;
diff --git a/ext/vorbis/vorbisenc.h b/ext/vorbis/vorbisenc.h
index d837ee333d..840f2bdd3d 100644
--- a/ext/vorbis/vorbisenc.h
+++ b/ext/vorbis/vorbisenc.h
@@ -80,6 +80,7 @@ struct _GstVorbisEnc {
gboolean next_discont;
guint64 granulepos_offset;
gint64 subgranule_offset;
+ GstSegment segment;
GstTagList * tags;