Pipelines

class "pipeline" {

   ipc_pipe

   comp_list : list of components

   buffer_list : list of buffers

   pipe_task

   sched_comp : comp_dev *

   status : uint32_t

}

hide pipeline methods



class sof_ipc_pipe_new {

   comp_id

   pipeline_id

   sched_id

   ...

}

hide sof_ipc_pipe_new methods

note right: attributes provided\nthrough ipc



class task

hide task members

hide task attributes

note right: task registered\nin scheduler



pipeline -- sof_ipc_pipe_new : ipc_pipe

pipeline - task : "pipe_task"

Figure 60 Pipeline structure

Creating a Pipeline

participant "pipeline" as ppl



-> ppl : pipeline_new(pipe_desc, cd)

   ppl -> heap : rzalloc(RZONE_RUNTIME, ...)

   ppl -> ppl : sched_comp = cd

   note right: sched_comp is used as root comp for pipeline scheduling

<-- ppl

Figure 61 Creating a pipeline

The scheduling component (sched_comp) is configured by the driver inside the IPC request. It is usually set to the dai component id for pipelines that are attached to a dai instance and are driven by that dai’s IO events.

Executing an Operation

Most of the pipeline functions sets the operation id and executes a common routine, either component_op_downstream() in case of a playback path or component_op_upstream() otherwise.

participant "pipeline" as ppl



-> ppl : <pipeline operation> (op = COMP_OPS_...)

   alt SOF_IPC_STREAM_PLAYBACK

      ppl -> ppl : comp_op_downstream(op)

   else

      ppl -> ppl : comp_op_upstream(op)

   end

<-- ppl

Figure 62 Pipeline Operation

Propagating the Operation Downstream

participant "pipeline" as ppl

participant "component" as comp

-> ppl : comp_op_downstream(op_data,\nstart, current, previous)

   note right: start, current, and previous are struct *comp_dev

   alt op_data->op == COMP_OPS_PARAMS

      ppl -> comp : comp_install_params(current)

      ppl -> comp : comp_params(current)

   else COMP_OPS_CMD

      ppl -> comp : comp_cmd(current)

      ppl -> ppl : pipeline_cmd_update(current)

   else COMP_OPS_PREPARE

      ppl -> comp : comp_prepare(current)

   else COMP_OPS_RESET

      ppl -> comp : comp_reset(current)

   else COMP_OPS_BUFFER

      note right: error, handled by other API calls

   end

   loop for each current's sink

      ppl -> ppl : component_op_downstream(..., current = consumer @ sink/source)

      note right: recursive call

   end

<-- ppl

Figure 63 Going downstream

Propagating the Operation Upstream

The comp_op_upstream() algorithm is identical except for the loop at the end that runs over the sources and calls itself recursively for producers.

Resetting Pipeline

participant "pipeline" as ppl



-> ppl : pipeline_reset()

   ppl -> ppl : <pipeline operation> (COMP_OPS_RESET)

<-- ppl

Figure 64 Resetting a pipeline

Configuring Audio Parameters & Preparing for Use

actor driver as drv

participant ipc

participant "pipeline" as ppl



drv -> ipc : ipc_stream_pcm_params()

   activate ipc

   ipc -> ppl : pipeline_params()

      activate ppl

      ppl -> ppl : <pipeline operation> (COMP_OPS_PARAMS, first = pcm_dev, params)

   ipc <-- ppl

   deactivate ppl



   ipc -> ppl : pipeline_prepare()

      activate ppl

      ppl -> ppl : <pipeline operation> (COMP_OPS_PREPARE)

      ppl -> ppl : component_prepare_buffers_downstream/upstream()

   ipc <-- ppl

   deactivate ppl

drv <-- ipc

deactivate ipc

Figure 65 Configuring audio parameters

Scheduling

A pipeline’s task (see _Processing_) may be scheduled at a certain point in time using pipeline_schedule_copy(start). In order to schedule the next stream copy operation in idle (see pre-loader), pipeline_schedule_copy_idle() should be used.

Processing

participant "pipeline" as ppl



-> ppl : pipeline_task()

   activate ppl

   ppl -> ppl : pipeline_copy()

      activate ppl

      ppl -> ppl : pipeline_copy_from_upstream()

         activate ppl

         deactivate ppl

      ppl -> ppl : pipeline_copy_to_downstream()

         activate ppl

         deactivate ppl

   deactivate ppl

<-- ppl

deactivate ppl

Figure 66 Pipeline task routine called by the scheduler