Skip to content

Commit 7346243

Browse files
authored
Merge pull request #269 from singalsu/src_prefill_proposal
SRC: Prevent downstream pipeline xruns with sink buffer pre-fill
2 parents a8cf2f9 + 20e1c1f commit 7346243

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

src/audio/src.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct comp_data {
7878
int32_t *sbuf_w_ptr;
7979
int32_t *sbuf_r_ptr;
8080
int sbuf_avail;
81+
int prefill;
8182
void (*src_func)(struct comp_dev *dev,
8283
struct comp_buffer *source,
8384
struct comp_buffer *sink,
@@ -606,6 +607,7 @@ static int src_params(struct comp_dev *dev)
606607
int err;
607608
int frames_is_for_source;
608609
int q;
610+
int d;
609611

610612
trace_src("par");
611613

@@ -716,6 +718,13 @@ static int src_params(struct comp_dev *dev)
716718
*/
717719
q = src_ceil_divide(cd->param.blk_out, (int)dev->frames) + 1;
718720

721+
/* If conversion specific minimum period length is less than
722+
* default period length there is need to pre-fill into sink buffer
723+
* zero PCM samples.
724+
*/
725+
d = dev->frames - cd->param.blk_out;
726+
cd->prefill = (d > 0) ? d * dev->frame_bytes : 0;
727+
719728
/* Configure downstream buffer */
720729
sink = list_first_item(&dev->bsink_list, struct comp_buffer,
721730
source_list);
@@ -776,14 +785,27 @@ static int src_copy(struct comp_dev *dev)
776785
size_t consumed = 0;
777786
size_t produced = 0;
778787

779-
trace_src("SRC");
788+
tracev_src("SRC");
780789

781790
/* src component needs 1 source and 1 sink buffer */
782791
source = list_first_item(&dev->bsource_list, struct comp_buffer,
783792
sink_list);
784793
sink = list_first_item(&dev->bsink_list, struct comp_buffer,
785794
source_list);
786795

796+
/* In some conversions the first copy run needs to pre-fill buffer
797+
* with sufficient amount of zeros if the min. output block length
798+
* is too short. It prevents xrun for the downstream component. In
799+
* successive copy executions the block length will jitter around the
800+
* nominal period length and xruns won't happen.
801+
*/
802+
if (cd->prefill && sink->free >= cd->prefill) {
803+
tracev_src("psn");
804+
tracev_value(cd->prefill);
805+
comp_update_buffer_produce(sink, cd->prefill);
806+
cd->prefill = 0;
807+
}
808+
787809
/* Calculate needed amount of source buffer and sink buffer
788810
* for one SRC run. The blk_in and blk are minimum condition to
789811
* call copy. Copy can consume or produce a slightly larger block

0 commit comments

Comments
 (0)