echo reference: fix buffer overflow
commit 33e8f78b introduced a regression causing the input buffer
size to be underestimated when downsampling and doing stereo to mono
conversion.
Also a test in create_echo_reference() was not removed and prevented
write sampling rates lower than read sampling rates.
Change-Id: I2ce2e32748eb9d00f4d5b32e5db5149f177c8804
diff --git a/audio_utils/echo_reference.c b/audio_utils/echo_reference.c
index 87ff4ac..a0a0662 100644
--- a/audio_utils/echo_reference.c
+++ b/audio_utils/echo_reference.c
@@ -174,11 +174,24 @@
// do stereo to mono and down sampling if necessary
if (er->rd_channel_count != er->wr_channel_count ||
er->rd_sampling_rate != er->wr_sampling_rate) {
+ size_t wrBufSize = buffer->frame_count;
- inFrames = (buffer->frame_count * er->rd_sampling_rate) / er->wr_sampling_rate +
- RESAMPLER_HEADROOM_SAMPLES;
- if (er->wr_buf_size < inFrames) {
- er->wr_buf_size = inFrames;
+ inFrames = buffer->frame_count;
+
+ if (er->rd_sampling_rate != er->wr_sampling_rate) {
+ inFrames = (buffer->frame_count * er->rd_sampling_rate) / er->wr_sampling_rate +
+ RESAMPLER_HEADROOM_SAMPLES;
+ // wr_buf is not only used as resampler output but also for stereo to mono conversion
+ // output so buffer size is driven by both write and read sample rates
+ if (inFrames > wrBufSize) {
+ wrBufSize = inFrames;
+ }
+ }
+
+ if (er->wr_buf_size < wrBufSize) {
+ ALOGV("echo_reference_write() increasing write buffer size from %d to %d",
+ er->wr_buf_size, wrBufSize);
+ er->wr_buf_size = wrBufSize;
er->wr_buf = realloc(er->wr_buf, er->wr_buf_size * er->rd_frame_size);
}
@@ -453,11 +466,6 @@
return -EINVAL;
}
- if (wrSamplingRate < rdSamplingRate) {
- ALOGW("create_echo_reference bad smp rate rd %d, wr %d", rdSamplingRate, wrSamplingRate);
- return -EINVAL;
- }
-
er = (struct echo_reference *)calloc(1, sizeof(struct echo_reference));
er->itfe.read = echo_reference_read;