[Sound-open-firmware] [PATCH resend 1/2] SRC: Bug fix for handling a deleted conversion
This patch fixes a regression that caused SRC to try to initialize for a mode that has been disabled from in/out rates matrix. The feature exist to save tables RAM with modes those are not required. The bug caused a divide by zero to happen in src_buffer_lengths() function.
Signed-off-by: Seppo Ingalsuo seppo.ingalsuo@linux.intel.com --- src/audio/src_core.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/audio/src_core.c b/src/audio/src_core.c index dc22772..d8b9a3d 100644 --- a/src/audio/src_core.c +++ b/src/audio/src_core.c @@ -133,7 +133,6 @@ int src_buffer_lengths(struct src_param *a, int fs_in, int fs_out, int nch, { struct src_stage *stage1; struct src_stage *stage2; - int k; int q; int den; int num; @@ -149,18 +148,25 @@ int src_buffer_lengths(struct src_param *a, int fs_in, int fs_out, int nch, a->idx_in = src_find_fs(src_in_fs, NUM_IN_FS, fs_in); a->idx_out = src_find_fs(src_out_fs, NUM_OUT_FS, fs_out);
- /* Set blk_in, blk_out so that the muted fallback SRC keeps - * just source & sink in sync in pipeline without drift. - */ + /* Check that both in and out rates are supported */ if ((a->idx_in < 0) || (a->idx_out < 0)) { - k = gcd(fs_in, fs_out); - a->blk_in = fs_in / k; - a->blk_out = fs_out / k; + trace_src_error("us1"); + tracev_value(fs_in); + tracev_value(fs_out); return -EINVAL; }
stage1 = src_table1[a->idx_out][a->idx_in]; stage2 = src_table2[a->idx_out][a->idx_in]; + + /* Check from stage1 parameter for a deleted in/out rate combination.*/ + if (stage1->filter_length < 1) { + trace_src_error("us2"); + tracev_value(fs_in); + tracev_value(fs_out); + return -EINVAL; + } + a->fir_s1 = nch * src_fir_delay_length(stage1); a->out_s1 = nch * src_out_delay_length(stage1);
This patch prevents SRC to stall due to too demanding criteria of function comp_buffer_can_copy_bytes. Since the input and output rate and period length of SRC are different for source and sink both buffers do not need to meet both criteria.
Signed-off-by: Seppo Ingalsuo seppo.ingalsuo@linux.intel.com --- src/audio/src.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/src/audio/src.c b/src/audio/src.c index 3378065..0103e2e 100644 --- a/src/audio/src.c +++ b/src/audio/src.c @@ -496,7 +496,6 @@ static int src_copy(struct comp_dev *dev) int need_sink; size_t consumed = 0; size_t produced = 0; - int res;
trace_src("SRC");
@@ -519,30 +518,26 @@ static int src_copy(struct comp_dev *dev) /* make sure source component buffer has enough data available and that * the sink component buffer has enough free bytes for copy. Also * check for XRUNs */ - res = comp_buffer_can_copy_bytes(source, sink, need_source); - if (res) { + if (source->avail < need_source) { trace_src_error("xru"); return -EIO; /* xrun */ } - res = comp_buffer_can_copy_bytes(source, sink, need_sink); - if (res) { + if (sink->free < need_sink) { trace_src_error("xro"); return -EIO; /* xrun */ }
- /* Run SRC function if buffers avail and free allow */ - if (((int) source->avail >= need_source) && ((int) sink->free >= need_sink)) { - cd->src_func(dev, source, sink, &consumed, &produced); + cd->src_func(dev, source, sink, &consumed, &produced);
- /* Calc new free and available if data was processed. These - * functions must not be called with 0 consumed/produced. - */ - if (consumed > 0) - comp_update_buffer_consume(source, consumed); + /* Calc new free and available if data was processed. These + * functions must not be called with 0 consumed/produced. + */ + if (consumed > 0) + comp_update_buffer_consume(source, consumed); + + if (produced > 0) + comp_update_buffer_produce(sink, produced);
- if (produced > 0) - comp_update_buffer_produce(sink, produced); - } return 0; }
On Tue, 2017-12-05 at 15:54 +0200, Seppo Ingalsuo wrote:
This patch prevents SRC to stall due to too demanding criteria of function comp_buffer_can_copy_bytes. Since the input and output rate and period length of SRC are different for source and sink both buffers do not need to meet both criteria.
Signed-off-by: Seppo Ingalsuo seppo.ingalsuo@linux.intel.com
Applied.
On Tue, 2017-12-05 at 15:54 +0200, Seppo Ingalsuo wrote:
This patch fixes a regression that caused SRC to try to initialize for a mode that has been disabled from in/out rates matrix. The feature exist to save tables RAM with modes those are not required. The bug caused a divide by zero to happen in src_buffer_lengths() function.
Signed-off-by: Seppo Ingalsuo seppo.ingalsuo@linux.intel.com
Applied.
participants (2)
-
Liam Girdwood
-
Seppo Ingalsuo