CRAS: float_buffer - Fix readable count
Fix a bug in float_buffer when passing non-zero offset. Without
the fix, the result readable frames count could be incorrectly
larger and cause crash.
BUG=chromium:892608
TEST=unittest
Change-Id: I2d5f1724a032bc3264e4c178bf2b4e488686cde4
Reviewed-on: https://chromium-review.googlesource.com/1265215
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Hsinyu Chao <hychao@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
diff --git a/cras/src/Makefile.am b/cras/src/Makefile.am
index 18e5510..ddb53fa 100644
--- a/cras/src/Makefile.am
+++ b/cras/src/Makefile.am
@@ -354,6 +354,7 @@
edid_utils_unittest \
expr_unittest \
file_wait_unittest \
+ float_buffer_unittest \
fmt_conv_unittest \
hfp_info_unittest \
buffer_share_unittest \
@@ -715,6 +716,12 @@
$(CRAS_UT_TMPDIR_CFLAGS)
file_wait_unittest_LDADD = -lgtest -lpthread
+
+float_buffer_unittest_SOURCES = tests/float_buffer_unittest.cc
+float_buffer_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
+ -I$(top_srcdir)/src/server
+float_buffer_unittest_LDADD = -lgtest -lpthread
+
fmt_conv_unittest_SOURCES = tests/fmt_conv_unittest.cc server/cras_fmt_conv.c
fmt_conv_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server
diff --git a/cras/src/server/float_buffer.h b/cras/src/server/float_buffer.h
index 9b82c04..55e176e 100644
--- a/cras/src/server/float_buffer.h
+++ b/cras/src/server/float_buffer.h
@@ -97,8 +97,8 @@
offset = offset + b->buf->read_idx - b->buf->max_size;
*readable = MIN(*readable, b->buf->write_idx - offset);
} else {
+ *readable = MIN(*readable, nread - offset);
offset += b->buf->read_idx;
- *readable = MIN(*readable, nread);
}
for (i = 0; i < b->num_channels; i++, data += b->buf->max_size)
diff --git a/cras/src/tests/float_buffer_unittest.cc b/cras/src/tests/float_buffer_unittest.cc
new file mode 100644
index 0000000..20d392e
--- /dev/null
+++ b/cras/src/tests/float_buffer_unittest.cc
@@ -0,0 +1,53 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <gtest/gtest.h>
+
+#include "float_buffer.h"
+
+namespace {
+TEST(FloatBuffer, ReadWrite) {
+ unsigned int readable = 10;
+ struct float_buffer *b = float_buffer_create(10, 2);
+ EXPECT_EQ(10, float_buffer_writable(b));
+
+ // (w, r)=(8, 0)
+ float_buffer_written(b, 8);
+ EXPECT_EQ(8, float_buffer_level(b));
+
+ float_buffer_read_pointer(b, 0, &readable);
+ EXPECT_EQ(8, readable);
+ EXPECT_EQ(2, float_buffer_writable(b));
+
+ readable = 10;
+ float_buffer_read_pointer(b, 3, &readable);
+ EXPECT_EQ(5, readable);
+
+ // (w, r)=(8, 6)
+ float_buffer_read(b, 6);
+ EXPECT_EQ(2, float_buffer_writable(b));
+
+ // (w, r)=(0, 6)
+ float_buffer_written(b, 2);
+ EXPECT_EQ(6, float_buffer_writable(b));
+
+ // (w, r)=(3, 6)
+ readable = 10;
+ float_buffer_written(b, 3);
+ float_buffer_read_pointer(b, 0, &readable);
+ EXPECT_EQ(4, readable);
+
+ readable = 10;
+ float_buffer_read_pointer(b, 1, &readable);
+ EXPECT_EQ(3, readable);
+
+ float_buffer_destroy(&b);
+}
+
+} // namespace
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}