From: Sebastian Dröge Date: Fri, 8 May 2020 19:36:01 +0000 (+0300) Subject: audiobuffersplit: Perform discont tracking on running time X-Git-Tag: 1.19.3~507^2~1895 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=79e65951a90eebfa496cae35b76b4b9eaa92931e;p=platform%2Fupstream%2Fgstreamer.git 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: --- diff --git a/gst/audiobuffersplit/gstaudiobuffersplit.c b/gst/audiobuffersplit/gstaudiobuffersplit.c index ac1c3bd..bd66e9e 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 @@ -387,21 +387,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; @@ -412,9 +412,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); @@ -442,16 +445,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) @@ -461,45 +483,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, @@ -567,12 +583,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); @@ -585,7 +601,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; @@ -663,6 +680,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 d22eba6..d902cbd 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 */