Skip to content

Commit 64a1657

Browse files
keyonjielgirdwood
authored andcommitted
pipeline: add negotiation before propagating params
For different connected pipelines, they are usually connected via a component with >1 source or sink buffers, as most of those components don't have ability to converse frame format or sample rate, we need add a params negotiation mechanism between those pipelines. If all buffers are iterated in the params propagation direction, no negotiation needed, otherwise we need to iterate all other buffers in the opposite direction, to make sure all connected buffers have chance to take part in the negotiation. The negotiation should happen before we can propagate the params further, when doing negotiation in a branch/buffer, we should check: If a branch is active, check if params is matched, return error to reject the whole .params() requirement if not. If a branch is inactive, force update the params to its calling buffer, to make sure all branches are aligned on the format. We are propagating the params to branched buffer, and the subsequent component's .params() or .prepare() should be responsible to calibrate the buffer params if needed. For example, a component who has different channels buffers should explicitly configure the channels for its branched buffers (the ones connected to another pipeline). Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
1 parent 968eaf1 commit 64a1657

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

src/audio/pipeline.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,64 @@ static int pipeline_comp_hw_params(struct comp_dev *current,
389389
return 0;
390390
}
391391

392+
static int pipeline_comp_params_neg(struct comp_dev *current,
393+
struct comp_buffer *calling_buf,
394+
struct pipeline_walk_context *ctx,
395+
int dir)
396+
{
397+
struct pipeline_data *ppl_data = ctx->comp_data;
398+
uint32_t flags = 0;
399+
int err = 0;
400+
401+
pipe_dbg(ppl_data->p, "pipeline_comp_params_neg(), current->comp.id = %u, dir = %u",
402+
dev_comp_id(current), dir);
403+
404+
/* check if 'current' is already configured */
405+
if (current->state != COMP_STATE_INIT &&
406+
current->state != COMP_STATE_READY) {
407+
/* return 0 if params matches */
408+
if (buffer_params_match(calling_buf,
409+
&ppl_data->params->params,
410+
BUFF_PARAMS_FRAME_FMT |
411+
BUFF_PARAMS_RATE))
412+
return 0;
413+
/*
414+
* the param is conflict with an active pipeline,
415+
* drop an error and reject the .params() command.
416+
*/
417+
pipe_err(ppl_data->p, "pipeline_comp_params_neg(): params conflict with existed active pipeline!");
418+
return -EINVAL;
419+
}
420+
421+
/*
422+
* Negotiation only happen when the current component has > 1
423+
* source or sink, we are propagating the params to branched
424+
* buffers, and the subsequent component's .params() or .prepare()
425+
* should be responsible for calibrating if needed. For example,
426+
* a component who has different channels input/output buffers
427+
* should explicitly configure the channels of the branched buffers.
428+
*/
429+
if (calling_buf) {
430+
buffer_lock(calling_buf, &flags);
431+
err = buffer_set_params(calling_buf,
432+
&ppl_data->params->params,
433+
BUFFER_UPDATE_FORCE);
434+
buffer_unlock(calling_buf, flags);
435+
}
436+
437+
return err;
438+
}
439+
392440
static int pipeline_comp_params(struct comp_dev *current,
393441
struct comp_buffer *calling_buf,
394442
struct pipeline_walk_context *ctx, int dir)
395443
{
396444
struct pipeline_data *ppl_data = ctx->comp_data;
445+
struct pipeline_walk_context param_neg_ctx = {
446+
.comp_func = pipeline_comp_params_neg,
447+
.comp_data = ppl_data,
448+
.skip_incomplete = true,
449+
};
397450
int stream_direction = ppl_data->params->params.direction;
398451
int end_type;
399452
int err;
@@ -427,6 +480,11 @@ static int pipeline_comp_params(struct comp_dev *current,
427480
if (current->state == COMP_STATE_ACTIVE)
428481
return 0;
429482

483+
/* do params negotiation with other branches(opposite direction) */
484+
err = pipeline_for_each_comp(current, &param_neg_ctx, !dir);
485+
if (err < 0 || err == PPL_STATUS_PATH_STOP)
486+
return err;
487+
430488
/* set comp direction */
431489
current->direction = ppl_data->params->params.direction;
432490

0 commit comments

Comments
 (0)