mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
audioresample: provide as much valid output ts and offset as valid input
... by independently tracking time and offset, rather than having no offset leading to no output ts.
This commit is contained in:
parent
7728f3d3a7
commit
a7cf165289
2 changed files with 56 additions and 47 deletions
|
@ -240,8 +240,8 @@ gst_audio_resample_start (GstBaseTransform * base)
|
|||
resample->t0 = GST_CLOCK_TIME_NONE;
|
||||
resample->in_offset0 = GST_BUFFER_OFFSET_NONE;
|
||||
resample->out_offset0 = GST_BUFFER_OFFSET_NONE;
|
||||
resample->next_in_offset = GST_BUFFER_OFFSET_NONE;
|
||||
resample->next_out_offset = GST_BUFFER_OFFSET_NONE;
|
||||
resample->samples_in = 0;
|
||||
resample->samples_out = 0;
|
||||
|
||||
resample->tmp_in = NULL;
|
||||
resample->tmp_in_size = 0;
|
||||
|
@ -854,24 +854,29 @@ gst_audio_resample_push_drain (GstAudioResample * resample)
|
|||
return;
|
||||
}
|
||||
|
||||
/* time */
|
||||
if (GST_CLOCK_TIME_IS_VALID (resample->t0)) {
|
||||
GST_BUFFER_OFFSET (outbuf) = resample->next_out_offset;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed;
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 +
|
||||
gst_util_uint64_scale_int_round (GST_BUFFER_OFFSET (outbuf) -
|
||||
resample->out_offset0, GST_SECOND, resample->outrate);
|
||||
GST_BUFFER_DURATION (outbuf) = resample->t0 +
|
||||
gst_util_uint64_scale_int_round (GST_BUFFER_OFFSET_END (outbuf) -
|
||||
resample->out_offset0, GST_SECOND, resample->outrate) -
|
||||
GST_BUFFER_TIMESTAMP (outbuf);
|
||||
resample->next_out_offset += out_processed;
|
||||
resample->next_in_offset += 0;
|
||||
gst_util_uint64_scale_int_round (resample->samples_out, GST_SECOND,
|
||||
resample->outrate);
|
||||
GST_BUFFER_DURATION (outbuf) =
|
||||
gst_util_uint64_scale_int_round (resample->samples_out + out_processed,
|
||||
GST_SECOND, resample->outrate) - GST_BUFFER_TIMESTAMP (outbuf);
|
||||
} else {
|
||||
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
/* offset */
|
||||
if (resample->out_offset0 != GST_BUFFER_OFFSET_NONE) {
|
||||
GST_BUFFER_OFFSET (outbuf) = resample->out_offset0 + resample->samples_out;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed;
|
||||
} else {
|
||||
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
}
|
||||
/* move along */
|
||||
resample->samples_out += out_processed;
|
||||
resample->samples_in += 0;
|
||||
|
||||
GST_BUFFER_SIZE (outbuf) =
|
||||
out_processed * resample->channels * (resample->width / 8);
|
||||
|
@ -904,8 +909,8 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event)
|
|||
resample->t0 = GST_CLOCK_TIME_NONE;
|
||||
resample->in_offset0 = GST_BUFFER_OFFSET_NONE;
|
||||
resample->out_offset0 = GST_BUFFER_OFFSET_NONE;
|
||||
resample->next_in_offset = GST_BUFFER_OFFSET_NONE;
|
||||
resample->next_out_offset = GST_BUFFER_OFFSET_NONE;
|
||||
resample->samples_in = 0;
|
||||
resample->samples_out = 0;
|
||||
resample->need_discont = TRUE;
|
||||
break;
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
|
@ -914,8 +919,8 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event)
|
|||
resample->t0 = GST_CLOCK_TIME_NONE;
|
||||
resample->in_offset0 = GST_BUFFER_OFFSET_NONE;
|
||||
resample->out_offset0 = GST_BUFFER_OFFSET_NONE;
|
||||
resample->next_in_offset = GST_BUFFER_OFFSET_NONE;
|
||||
resample->next_out_offset = GST_BUFFER_OFFSET_NONE;
|
||||
resample->samples_in = 0;
|
||||
resample->samples_out = 0;
|
||||
resample->need_discont = TRUE;
|
||||
break;
|
||||
case GST_EVENT_EOS:
|
||||
|
@ -941,21 +946,18 @@ gst_audio_resample_check_discont (GstAudioResample * resample, GstBuffer * buf)
|
|||
|
||||
/* no valid timestamps or offsets to compare --> no discontinuity */
|
||||
if (G_UNLIKELY (!(GST_BUFFER_TIMESTAMP_IS_VALID (buf) &&
|
||||
GST_CLOCK_TIME_IS_VALID (resample->t0) &&
|
||||
resample->in_offset0 != GST_BUFFER_OFFSET_NONE &&
|
||||
resample->next_in_offset != GST_BUFFER_OFFSET_NONE)))
|
||||
GST_CLOCK_TIME_IS_VALID (resample->t0))))
|
||||
return FALSE;
|
||||
|
||||
/* convert the inbound timestamp to an offset. */
|
||||
offset =
|
||||
resample->in_offset0 +
|
||||
gst_util_uint64_scale_int_round (GST_BUFFER_TIMESTAMP (buf) -
|
||||
resample->t0, resample->inrate, GST_SECOND);
|
||||
|
||||
/* many elements generate imperfect streams due to rounding errors, so we
|
||||
* permit a small error (up to one sample) without triggering a filter
|
||||
* flush/restart (if triggered incorrectly, this will be audible) */
|
||||
delta = ABS ((gint64) (offset - resample->next_in_offset));
|
||||
delta = ABS ((gint64) (offset - resample->samples_in));
|
||||
if (delta <= 1)
|
||||
return FALSE;
|
||||
|
||||
|
@ -1030,24 +1032,29 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
|
|||
in_processed, in_len);
|
||||
}
|
||||
|
||||
/* time */
|
||||
if (GST_CLOCK_TIME_IS_VALID (resample->t0)) {
|
||||
GST_BUFFER_OFFSET (outbuf) = resample->next_out_offset;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed;
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 +
|
||||
gst_util_uint64_scale_int_round (GST_BUFFER_OFFSET (outbuf) -
|
||||
resample->out_offset0, GST_SECOND, resample->outrate);
|
||||
GST_BUFFER_DURATION (outbuf) = resample->t0 +
|
||||
gst_util_uint64_scale_int_round (GST_BUFFER_OFFSET_END (outbuf) -
|
||||
resample->out_offset0, GST_SECOND, resample->outrate) -
|
||||
GST_BUFFER_TIMESTAMP (outbuf);
|
||||
resample->next_out_offset += out_processed;
|
||||
resample->next_in_offset += in_len;
|
||||
gst_util_uint64_scale_int_round (resample->samples_out, GST_SECOND,
|
||||
resample->outrate);
|
||||
GST_BUFFER_DURATION (outbuf) =
|
||||
gst_util_uint64_scale_int_round (resample->samples_out + out_processed,
|
||||
GST_SECOND, resample->outrate) - GST_BUFFER_TIMESTAMP (outbuf);
|
||||
} else {
|
||||
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
/* offset */
|
||||
if (resample->out_offset0 != GST_BUFFER_OFFSET_NONE) {
|
||||
GST_BUFFER_OFFSET (outbuf) = resample->out_offset0 + resample->samples_out;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed;
|
||||
} else {
|
||||
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
}
|
||||
/* move along */
|
||||
resample->samples_out += out_processed;
|
||||
resample->samples_in += in_len;
|
||||
|
||||
GST_BUFFER_SIZE (outbuf) =
|
||||
out_processed * resample->channels * (resample->width / 8);
|
||||
|
@ -1106,24 +1113,26 @@ gst_audio_resample_transform (GstBaseTransform * base, GstBuffer * inbuf,
|
|||
|
||||
/* handle discontinuity */
|
||||
if (G_UNLIKELY (resample->need_discont)) {
|
||||
/* reset */
|
||||
resample->samples_in = 0;
|
||||
resample->samples_out = 0;
|
||||
GST_DEBUG_OBJECT (resample, "found discontinuity; resyncing");
|
||||
/* resync the timestamp and offset counters if possible */
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (inbuf) &&
|
||||
GST_BUFFER_OFFSET_IS_VALID (inbuf)) {
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (inbuf)) {
|
||||
resample->t0 = GST_BUFFER_TIMESTAMP (inbuf);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (resample, "... but new timestamp is invalid");
|
||||
resample->t0 = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
if (GST_BUFFER_OFFSET_IS_VALID (inbuf)) {
|
||||
resample->in_offset0 = GST_BUFFER_OFFSET (inbuf);
|
||||
resample->out_offset0 =
|
||||
gst_util_uint64_scale_int_round (resample->in_offset0,
|
||||
resample->outrate, resample->inrate);
|
||||
resample->next_in_offset = resample->in_offset0;
|
||||
resample->next_out_offset = resample->out_offset0;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (resample, "found discontinuity but timestamp and/or "
|
||||
"offset is invalid, cannot sync output timestamp and offset counter");
|
||||
resample->t0 = GST_CLOCK_TIME_NONE;
|
||||
GST_DEBUG_OBJECT (resample, "... but new offset is invalid");
|
||||
resample->in_offset0 = GST_BUFFER_OFFSET_NONE;
|
||||
resample->out_offset0 = GST_BUFFER_OFFSET_NONE;
|
||||
resample->next_in_offset = GST_BUFFER_OFFSET_NONE;
|
||||
resample->next_out_offset = GST_BUFFER_OFFSET_NONE;
|
||||
}
|
||||
/* set DISCONT flag on output buffer */
|
||||
GST_DEBUG_OBJECT (resample, "marking this buffer with the DISCONT flag");
|
||||
|
|
|
@ -61,9 +61,9 @@ struct _GstAudioResample {
|
|||
GstClockTime t0;
|
||||
guint64 in_offset0;
|
||||
guint64 out_offset0;
|
||||
guint64 next_in_offset;
|
||||
guint64 next_out_offset;
|
||||
|
||||
guint64 samples_in;
|
||||
guint64 samples_out;
|
||||
|
||||
gint channels;
|
||||
gint inrate;
|
||||
gint outrate;
|
||||
|
|
Loading…
Reference in a new issue