audiolatency: Handle audio buffers with invalid duration

pipewiresrc outputs audio buffers without a valid duration, so we need
to calculate it manually in that case.

Upstream issue: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1438

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2419>
This commit is contained in:
Nirbheek Chauhan 2021-07-21 19:40:17 +05:30
parent 99636cd101
commit 0bde6bf750

View file

@ -292,7 +292,7 @@ buffer_has_wave (GstBuffer * buffer, GstPad * pad)
GstMapInfo minfo;
guint64 duration;
gint64 offset;
gint ii, channels, fsize;
gint ii, channels, fsize, rate;
gfloat *fdata;
gboolean ret;
GstMemory *memory = NULL;
@ -317,18 +317,26 @@ buffer_has_wave (GstBuffer * buffer, GstPad * pad)
caps = gst_pad_get_current_caps (pad);
s = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (s, "channels", &channels);
/* channels and rate are required in caps, so will always be present */
gst_structure_get_int (s, "channels", &channels);
gst_structure_get_int (s, "rate", &rate);
gst_caps_unref (caps);
if (!ret) {
GST_WARNING_OBJECT (pad, "unknown number of channels, can't detect wave");
return -1;
}
fdata = (gfloat *) minfo.data;
fsize = minfo.size / sizeof (gfloat);
offset = -1;
duration = GST_BUFFER_DURATION (buffer);
if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
duration = GST_BUFFER_DURATION (buffer);
} else {
/* Cannot do a rounding-accurate duration calculation here because in the
* case when the duration is invalid, the pts might also be invalid */
duration = gst_util_uint64_scale_int_round (GST_SECOND, fsize / channels,
rate);
GST_LOG_OBJECT (pad, "buffer duration is invalid, calculated likely "
"duration as %" G_GINT64_FORMAT "us", duration / GST_USECOND);
}
/* Read only one channel */
for (ii = 1; ii < fsize; ii += channels) {
if (ABS (fdata[ii]) > 0.7) {
@ -420,8 +428,9 @@ gst_audiolatency_sink_chain (GstPad * pad, GstObject * parent,
latency = (self->recv_pts - self->send_pts);
gst_audiolatency_set_latency (self, latency);
GST_INFO ("recv pts: %" G_GINT64_FORMAT "us, latency: %" G_GINT64_FORMAT "ms",
self->recv_pts, latency / 1000);
GST_INFO ("recv pts: %" G_GINT64_FORMAT "us, latency: %" G_GINT64_FORMAT
"ms, offset: %" G_GINT64_FORMAT "ms", self->recv_pts, latency / 1000,
offset / 1000);
out:
gst_buffer_unref (buffer);