vorbisenc: Relax overly-tight jitter tolerances in gstvobisenc

vorbisenc currently reacts in a rater draconian fashion if input
timestamps are more than 1/2 sample off what it considers ideal. If data
is 'too late' it truncates buffers, if it is 'too soon' it completely
shuts down encode and restarts it.  This is causingvorbisenc to produce
corrupt output when encoding data produced by sources with bugs that
produce a smple or two of jitter (eg, flacdec)
This commit is contained in:
Monty Montgomery 2011-07-21 17:16:26 -04:00 committed by Sebastian Dröge
parent 7d3858a14d
commit 9cbe7c1403

View file

@ -1012,12 +1012,12 @@ gst_vorbis_enc_buffer_check_discontinuous (GstVorbisEnc * vorbisenc,
vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
timestamp + 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
* to rounding errors. So, we permit small errors (< 3 samples) without
* causing a discont.
*/
int halfsample = GST_SECOND / vorbisenc->frequency / 2;
int threesample = GST_SECOND / vorbisenc->frequency * 3;
if ((GstClockTimeDiff) (timestamp - vorbisenc->expected_ts) > halfsample) {
if ((GstClockTimeDiff) (timestamp - vorbisenc->expected_ts) > threesample) {
GST_DEBUG_OBJECT (vorbisenc, "Expected TS %" GST_TIME_FORMAT
", buffer TS %" GST_TIME_FORMAT,
GST_TIME_ARGS (vorbisenc->expected_ts), GST_TIME_ARGS (timestamp));
@ -1135,28 +1135,36 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
if (vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
timestamp < vorbisenc->expected_ts) {
int threesample = GST_SECOND / vorbisenc->frequency * 3;
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 (timestamp), GST_TIME_ARGS (vorbisenc->expected_ts));
/* Don't freak out on tiny jitters; use the same < 3 sample
tolerance as in the discontinuous detection */
if ((GstClockTimeDiff) (vorbisenc->expected_ts - timestamp) > threesample) {
diff_bytes =
GST_CLOCK_TIME_TO_FRAMES (diff,
vorbisenc->frequency) * vorbisenc->channels * sizeof (gfloat);
if (diff_bytes >= GST_BUFFER_SIZE (buffer)) {
gst_buffer_unref (buffer);
return GST_FLOW_OK;
GST_WARNING_OBJECT (vorbisenc, "Buffer is older than previous "
"timestamp + duration (%" GST_TIME_FORMAT "< %" GST_TIME_FORMAT
"), cannot handle. Clipping buffer.",
GST_TIME_ARGS (timestamp), GST_TIME_ARGS (vorbisenc->expected_ts));
diff_bytes =
GST_CLOCK_TIME_TO_FRAMES (diff,
vorbisenc->frequency) * vorbisenc->channels * sizeof (gfloat);
if (diff_bytes >= GST_BUFFER_SIZE (buffer)) {
gst_buffer_unref (buffer);
return GST_FLOW_OK;
}
buffer = gst_buffer_make_metadata_writable (buffer);
GST_BUFFER_DATA (buffer) += diff_bytes;
GST_BUFFER_SIZE (buffer) -= diff_bytes;
if (GST_BUFFER_DURATION_IS_VALID (buffer))
GST_BUFFER_DURATION (buffer) -= diff;
}
buffer = gst_buffer_make_metadata_writable (buffer);
GST_BUFFER_DATA (buffer) += diff_bytes;
GST_BUFFER_SIZE (buffer) -= diff_bytes;
/* adjust the input timestamp in either case */
GST_BUFFER_TIMESTAMP (buffer) += diff;
if (GST_BUFFER_DURATION_IS_VALID (buffer))
GST_BUFFER_DURATION (buffer) -= diff;
}
if (gst_vorbis_enc_buffer_check_discontinuous (vorbisenc, timestamp,