summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2020-05-08 22:36:01 +0300
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-09-25 22:26:33 +0000
commitf52d387e87e676fddb8e47d13065fafdc73d364f (patch)
tree3094e81b35f7289bd45d186198359c22588f7562
parentdf19d69c0068b409d99965248c917dc896fea116 (diff)
downloadgstreamer-plugins-bad-f52d387e87e676fddb8e47d13065fafdc73d364f.tar.gz
audiobuffersplit: Perform discont tracking on running time
Otherwise we would have to drain on every segment event. Like this we can handle segment events that don't cause a discontinuity in running time to be handled without draining. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1602>
-rw-r--r--gst/audiobuffersplit/gstaudiobuffersplit.c131
-rw-r--r--gst/audiobuffersplit/gstaudiobuffersplit.h2
2 files changed, 80 insertions, 53 deletions
diff --git a/gst/audiobuffersplit/gstaudiobuffersplit.c b/gst/audiobuffersplit/gstaudiobuffersplit.c
index 08514cdb8..7d2738add 100644
--- a/gst/audiobuffersplit/gstaudiobuffersplit.c
+++ b/gst/audiobuffersplit/gstaudiobuffersplit.c
@@ -361,9 +361,9 @@ gst_audio_buffer_split_output (GstAudioBufferSplit * self, gboolean force,
{
gint size, avail;
GstFlowReturn ret = GST_FLOW_OK;
- GstClockTime resync_time;
+ GstClockTime resync_pts;
- resync_time = self->resync_time;
+ resync_pts = self->resync_pts;
size = samples_per_buffer * bpf;
/* If we accumulated enough error for one sample, include one
@@ -392,21 +392,21 @@ gst_audio_buffer_split_output (GstAudioBufferSplit * self, gboolean force,
resync_time_diff =
gst_util_uint64_scale (self->current_offset, GST_SECOND, rate);
if (self->out_segment.rate < 0.0) {
- if (resync_time > resync_time_diff)
- GST_BUFFER_TIMESTAMP (buffer) = resync_time - resync_time_diff;
+ if (resync_pts > resync_time_diff)
+ GST_BUFFER_PTS (buffer) = resync_pts - resync_time_diff;
else
- GST_BUFFER_TIMESTAMP (buffer) = 0;
+ GST_BUFFER_PTS (buffer) = 0;
GST_BUFFER_DURATION (buffer) =
gst_util_uint64_scale (size / bpf, GST_SECOND, rate);
self->current_offset += size / bpf;
} else {
- GST_BUFFER_TIMESTAMP (buffer) = resync_time + resync_time_diff;
+ GST_BUFFER_PTS (buffer) = resync_pts + resync_time_diff;
self->current_offset += size / bpf;
resync_time_diff =
gst_util_uint64_scale (self->current_offset, GST_SECOND, rate);
GST_BUFFER_DURATION (buffer) =
- resync_time_diff - (GST_BUFFER_TIMESTAMP (buffer) - resync_time);
+ resync_time_diff - (GST_BUFFER_PTS (buffer) - resync_pts);
}
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
@@ -417,9 +417,12 @@ gst_audio_buffer_split_output (GstAudioBufferSplit * self, gboolean force,
self->error_per_buffer) % self->output_buffer_duration_d;
GST_LOG_OBJECT (self,
- "Outputting buffer at timestamp %" GST_TIME_FORMAT " with duration %"
- GST_TIME_FORMAT " (%u samples)",
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
+ "Outputting buffer at running time %" GST_TIME_FORMAT
+ " with timestamp %" GST_TIME_FORMAT " with duration %" GST_TIME_FORMAT
+ " (%u samples)",
+ GST_TIME_ARGS (gst_segment_to_running_time (&self->out_segment,
+ GST_FORMAT_TIME, GST_BUFFER_PTS (buffer))),
+ GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)), size / bpf);
ret = gst_pad_push (self->srcpad, buffer);
@@ -447,16 +450,35 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
guint avail = gst_adapter_available (self->adapter);
guint avail_samples = avail / bpf;
guint64 new_offset;
- GstClockTime current_timestamp;
- GstClockTime current_timestamp_end;
+ GstClockTime input_rt, current_rt;
+ GstClockTime input_duration;
+ GstClockTime current_rt_end;
+
+ input_rt =
+ gst_segment_to_running_time (&self->in_segment, GST_FORMAT_TIME,
+ GST_BUFFER_PTS (buffer));
+ input_duration =
+ (gst_buffer_get_size (buffer) / bpf) / ABS (self->in_segment.rate);
GST_OBJECT_LOCK (self);
+
+ if (self->in_segment.rate < 0) {
+ discont = FALSE;
+ } else {
+ discont = GST_BUFFER_IS_DISCONT (buffer)
+ || GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_RESYNC);
+ }
+
+ /* If the segment rate is changing this is a discontinuity */
+ discont = discont || (self->out_segment.format != GST_FORMAT_UNDEFINED
+ && self->in_segment.rate != self->out_segment.rate);
+
+ /* If this is the very first buffer we also have a discontinuity */
+ discont = discont || self->current_offset == -1;
+
discont =
gst_audio_stream_align_process (self->stream_align,
- self->in_segment.rate < 0 ? FALSE : GST_BUFFER_IS_DISCONT (buffer)
- || GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_RESYNC),
- GST_BUFFER_PTS (buffer), gst_buffer_get_size (buffer) / bpf, NULL, NULL,
- NULL);
+ discont, input_rt, input_duration, NULL, NULL, NULL);
GST_OBJECT_UNLOCK (self);
if (!discont)
@@ -466,45 +488,39 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
self->drop_samples = 0;
if (self->in_segment.rate < 0.0) {
- current_timestamp =
- self->resync_time - gst_util_uint64_scale (self->current_offset +
- avail_samples, GST_SECOND, rate);
- current_timestamp_end =
- self->resync_time - gst_util_uint64_scale (self->current_offset,
- GST_SECOND, rate);
+ current_rt =
+ self->resync_rt - gst_util_uint64_scale (self->current_offset +
+ avail_samples, GST_SECOND, rate * ABS (self->in_segment.rate));
+ current_rt_end =
+ self->resync_rt - gst_util_uint64_scale (self->current_offset,
+ GST_SECOND, rate * ABS (self->in_segment.rate));
} else {
- current_timestamp =
- self->resync_time + gst_util_uint64_scale (self->current_offset,
- GST_SECOND, rate);
- current_timestamp_end =
- self->resync_time + gst_util_uint64_scale (self->current_offset +
- avail_samples, GST_SECOND, rate);
+ current_rt =
+ self->resync_rt + gst_util_uint64_scale (self->current_offset,
+ GST_SECOND, rate * self->in_segment.rate);
+ current_rt_end =
+ self->resync_rt + gst_util_uint64_scale (self->current_offset +
+ avail_samples, GST_SECOND, rate * self->in_segment.rate);
}
if (self->gapless) {
- if (self->current_offset == -1) {
- /* We only set resync time on the very first buffer */
- self->current_offset = 0;
- self->resync_time = GST_BUFFER_PTS (buffer);
- discont = FALSE;
- } else {
+ if (self->current_offset != -1) {
GST_DEBUG_OBJECT (self,
- "Got discont in gapless mode: Current timestamp %" GST_TIME_FORMAT
- ", current end timestamp %" GST_TIME_FORMAT
- ", timestamp after discont %" GST_TIME_FORMAT,
- GST_TIME_ARGS (current_timestamp),
- GST_TIME_ARGS (current_timestamp_end),
- GST_TIME_ARGS (GST_BUFFER_PTS (buffer)));
+ "Got discont in gapless mode: Current running time %" GST_TIME_FORMAT
+ ", current end running time %" GST_TIME_FORMAT
+ ", running time after discont %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (current_rt),
+ GST_TIME_ARGS (current_rt_end), GST_TIME_ARGS (input_rt));
new_offset =
- gst_util_uint64_scale (GST_BUFFER_PTS (buffer) - self->resync_time,
- rate, GST_SECOND);
- if (GST_BUFFER_PTS (buffer) < self->resync_time) {
+ gst_util_uint64_scale (current_rt - self->resync_rt,
+ rate * ABS (self->in_segment.rate), GST_SECOND);
+ if (current_rt < self->resync_rt) {
guint64 drop_samples;
new_offset =
- gst_util_uint64_scale (self->resync_time -
- GST_BUFFER_PTS (buffer), rate, GST_SECOND);
+ gst_util_uint64_scale (self->resync_rt -
+ current_rt, rate * ABS (self->in_segment.rate), GST_SECOND);
drop_samples = self->current_offset + avail_samples + new_offset;
GST_DEBUG_OBJECT (self,
@@ -572,12 +588,12 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
/* We might end up in here also in gapless mode, if the above code decided
* that no silence is to be inserted, because e.g. the gap is too big */
GST_DEBUG_OBJECT (self,
- "Got discont: Current timestamp %" GST_TIME_FORMAT
- ", current end timestamp %" GST_TIME_FORMAT
- ", timestamp after discont %" GST_TIME_FORMAT,
- GST_TIME_ARGS (current_timestamp),
- GST_TIME_ARGS (current_timestamp_end),
- GST_TIME_ARGS (GST_BUFFER_PTS (buffer)));
+ "Got %s: Current running time %" GST_TIME_FORMAT
+ ", current end running time %" GST_TIME_FORMAT
+ ", running time after discont %" GST_TIME_FORMAT,
+ self->current_offset == -1 ? "first buffer" : "discont",
+ GST_TIME_ARGS (current_rt),
+ GST_TIME_ARGS (current_rt_end), GST_TIME_ARGS (input_rt));
if (self->strict_buffer_size) {
gst_adapter_clear (self->adapter);
@@ -590,7 +606,8 @@ gst_audio_buffer_split_handle_discont (GstAudioBufferSplit * self,
self->current_offset = 0;
self->accumulated_error = 0;
- self->resync_time = GST_BUFFER_PTS (buffer);
+ self->resync_pts = GST_BUFFER_PTS (buffer);
+ self->resync_rt = input_rt;
if (self->segment_pending) {
GstEvent *event;
@@ -668,6 +685,16 @@ gst_audio_buffer_split_sink_chain (GstPad * pad, GstObject * parent,
samples_per_buffer = self->samples_per_buffer;
GST_OBJECT_UNLOCK (self);
+ GST_LOG_OBJECT (self,
+ "Processing buffer at running time %" GST_TIME_FORMAT
+ " with timestamp %" GST_TIME_FORMAT " with duration %" GST_TIME_FORMAT
+ " (%u samples)",
+ GST_TIME_ARGS (gst_segment_to_running_time (&self->in_segment,
+ GST_FORMAT_TIME, GST_BUFFER_PTS (buffer))),
+ GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
+ GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)),
+ (guint) (gst_buffer_get_size (buffer) / bpf));
+
if (format == GST_AUDIO_FORMAT_UNKNOWN || samples_per_buffer == 0) {
gst_buffer_unref (buffer);
return GST_FLOW_NOT_NEGOTIATED;
diff --git a/gst/audiobuffersplit/gstaudiobuffersplit.h b/gst/audiobuffersplit/gstaudiobuffersplit.h
index d22eba682..d902cbd09 100644
--- a/gst/audiobuffersplit/gstaudiobuffersplit.h
+++ b/gst/audiobuffersplit/gstaudiobuffersplit.h
@@ -55,7 +55,7 @@ struct _GstAudioBufferSplit {
GstAdapter *adapter;
GstAudioStreamAlign *stream_align;
- GstClockTime resync_time;
+ GstClockTime resync_pts, resync_rt;
guint64 current_offset; /* offset from start time in samples */
guint64 drop_samples; /* number of samples to drop in gapless mode */