Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/audio/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ static bool comp_check_eos(struct comp_dev *dev)
enum sof_audio_buffer_state sink_state = AUDIOBUF_STATE_INITIAL;
struct comp_buffer *buffer;

if (!dev->pipeline->expect_eos)
if (!dev->expect_eos)
return false;

comp_dev_for_each_producer(dev, buffer) {
Expand Down
2 changes: 1 addition & 1 deletion src/audio/host-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ static inline bool host_handle_eos(struct host_data *hd, struct comp_dev *dev,
struct sof_audio_buffer *buffer = &hd->local_buffer->audio_buffer;
enum sof_audio_buffer_state state = audio_buffer_get_state(buffer);

if (!dev->pipeline->expect_eos)
if (!dev->expect_eos)
return false;

if (!avail_samples) {
Expand Down
4 changes: 2 additions & 2 deletions src/audio/module_adapter/module/cadence.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ int cadence_codec_process_data(struct processing_module *mod,
return 0;
}

if (dev->pipeline->expect_eos) {
if (dev->expect_eos) {
/* Signal that the stream is expected to end anytime soon */
API_CALL(cd, XA_API_CMD_INPUT_OVER, 0, NULL, ret);
if (ret != LIB_NO_ERROR) {
Expand Down Expand Up @@ -596,7 +596,7 @@ int cadence_codec_process_data(struct processing_module *mod,
return ret;
}

if (dev->pipeline->expect_eos) {
if (dev->expect_eos) {
/*
* AAC decoder cannot signal DONE, check if it stopped
* producing data when EOS is expected
Expand Down
79 changes: 69 additions & 10 deletions src/audio/module_adapter/module/cadence_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,28 +135,41 @@ static int cadence_configure_mp3_enc_params(struct processing_module *mod)
return 0;
}

/** Configure AAC output and the external stream parameters needed for RAW input. */
static int cadence_configure_aac_dec_params(struct processing_module *mod)
{
struct cadence_codec_data *cd = module_get_private_data(mod);
struct module_config *setup_cfg = &cd->setup_cfg;
struct comp_dev *dev = mod->dev;
struct snd_codec *codec_params;
int bitstream_format = XA_AACDEC_EBITSTREAM_TYPE_AAC_ADTS;
const struct snd_codec *codec_params;
int bitstream_format;
int sample_rate;
int to_stereo;
int word_size;
int ret;

/* check bitstream format. Only MPEG-4 ADTS supported for now */
if (setup_cfg->avail) {
codec_params = (struct snd_codec *)cd->setup_cfg.data;
if (codec_params->format != SND_AUDIOSTREAMFORMAT_MP4ADTS) {
comp_err(dev, "Unsupported AAC format: %d", codec_params->format);
return -EINVAL;
}
} else {
if (!setup_cfg->avail) {
comp_err(dev, "No setup config available for AAC decoder");
return -EINVAL;
}

codec_params = setup_cfg->data;
switch (codec_params->format) {
case SND_AUDIOSTREAMFORMAT_MP2ADTS:
case SND_AUDIOSTREAMFORMAT_MP4ADTS:
bitstream_format = XA_AACDEC_EBITSTREAM_TYPE_AAC_ADTS;
break;
case SND_AUDIOSTREAMFORMAT_ADIF:
bitstream_format = XA_AACDEC_EBITSTREAM_TYPE_AAC_ADIF;
break;
case SND_AUDIOSTREAMFORMAT_RAW:
bitstream_format = XA_AACDEC_EBITSTREAM_TYPE_AAC_RAW;
break;
default:
comp_err(dev, "Unsupported AAC format: %d", codec_params->format);
return -EINVAL;
}

/* AAC decoder module only supports 16bit or 24 bits for word size */
switch (cd->base_cfg.audio_fmt.depth) {
case IPC4_DEPTH_16BIT:
Expand Down Expand Up @@ -192,6 +205,30 @@ static int cadence_configure_aac_dec_params(struct processing_module *mod)
comp_warn(dev, "applied param bitstream format return code: %#x", ret);
}

if (bitstream_format == XA_AACDEC_EBITSTREAM_TYPE_AAC_RAW) {
sample_rate = codec_params->sample_rate;
API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM,
XA_AACDEC_CONFIG_PARAM_EXTERNAL_SAMPLERATE, &sample_rate, ret);
if (ret != LIB_NO_ERROR) {
if (LIB_IS_FATAL_ERROR(ret)) {
comp_err(dev, "failed to apply external sample rate: error: %#x", ret);
return ret;
}
comp_warn(dev, "applied external sample rate return code: %#x", ret);
}

to_stereo = codec_params->ch_out == 2;
API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM,
XA_AACDEC_CONFIG_PARAM_TO_STEREO, &to_stereo, ret);
if (ret != LIB_NO_ERROR) {
if (LIB_IS_FATAL_ERROR(ret)) {
comp_err(dev, "failed to apply stereo output: error: %#x", ret);
return ret;
}
comp_warn(dev, "applied stereo output return code: %#x", ret);
}
}

return 0;
}

Expand Down Expand Up @@ -447,6 +484,26 @@ static int cadence_codec_prepare(struct processing_module *mod,
return 0;
}

/** Detect zero-filled host padding while draining RAW AAC. */
static bool cadence_raw_aac_input_is_padding(struct processing_module *mod)
{
struct cadence_codec_data *cd = module_get_private_data(mod);
struct module_data *codec = &mod->priv;
const uint8_t *input = codec->mpd.in_buff;
const struct snd_codec *codec_params = cd->setup_cfg.data;
uint32_t offset;

if (!mod->dev->expect_eos || cd->api_id != CADENCE_CODEC_AAC_DEC_ID ||
!cd->setup_cfg.avail || codec_params->format != SND_AUDIOSTREAMFORMAT_RAW)
return false;

for (offset = 0; offset < codec->mpd.avail; offset++)
if (input[offset])
return false;

return true;
}

static int cadence_codec_process(struct processing_module *mod, struct sof_source **sources,
int num_of_sources, struct sof_sink **sinks, int num_of_sinks)
{
Expand Down Expand Up @@ -494,6 +551,8 @@ static int cadence_codec_process(struct processing_module *mod, struct sof_sourc
cadence_copy_data_from_buffer(codec->mpd.in_buff, src_ptr, codec->mpd.in_buff_size,
src_bytes, source_buffer_start);
codec->mpd.avail = codec->mpd.in_buff_size;
if (cadence_raw_aac_input_is_padding(mod))
codec->mpd.avail = 0;

comp_dbg(dev, "cadence_codec_process() start");

Expand Down
36 changes: 36 additions & 0 deletions src/audio/pipeline/pipeline-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,42 @@ int pipeline_free(struct pipeline *p)
return 0;
}

static int pipeline_comp_set_eos(struct comp_dev *current,
struct comp_buffer *calling_buf,
struct pipeline_walk_context *ctx, int dir)
{
if (ctx->comp_data != (void *)current->pipeline)
return 0;

current->expect_eos = *(bool *)ctx->buff_data;

return pipeline_for_each_comp(current, ctx, dir);
}

void pipeline_set_eos(struct pipeline *p, bool eos)
{
struct pipeline_walk_context walk_ctx = {
.comp_func = pipeline_comp_set_eos,
.comp_data = p,
.buff_data = &eos,
};
struct comp_dev *start;
int dir;

if (!p->source_comp || !p->sink_comp)
return;

if (p->source_comp->direction == SOF_IPC_STREAM_PLAYBACK) {
dir = PPL_DIR_UPSTREAM;
start = p->sink_comp;
} else {
dir = PPL_DIR_DOWNSTREAM;
start = p->source_comp;
}

walk_ctx.comp_func(start, NULL, &walk_ctx, dir);
}

static int pipeline_comp_complete(struct comp_dev *current,
struct comp_buffer *calling_buf,
struct pipeline_walk_context *ctx, int dir)
Expand Down
1 change: 1 addition & 0 deletions src/include/sof/audio/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,7 @@ struct comp_dev {
/* runtime */
uint16_t state; /**< COMP_STATE_ */
uint32_t frames; /**< number of frames we copy to sink */
bool expect_eos; /**< end of stream expected */
struct pipeline *pipeline; /**< pipeline we belong to */

struct task *task; /**< component's processing task used
Expand Down
8 changes: 7 additions & 1 deletion src/include/sof/audio/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ struct pipeline {
int32_t xrun_bytes; /* last xrun length */
uint32_t status; /* pipeline status */
struct tr_ctx tctx; /* trace settings */
bool expect_eos; /* pipeline is expecting end of stream */

/* scheduling */
#ifdef CONFIG_IPC_MAJOR_4
Expand Down Expand Up @@ -225,6 +224,13 @@ void pipeline_posn_grant_access(struct k_thread *thread);
*/
int pipeline_reset(struct pipeline *p, struct comp_dev *host_cd);

/**
* \brief Sets End Of Stream state for all devices in the pipeline.
* \param[in] p pipeline.
* \param[in] eos End Of Stream state.
*/
void pipeline_set_eos(struct pipeline *p, bool eos);

/**
* \brief Walks the pipeline graph for each component.
* \param[in] current Current pipeline component.
Expand Down
6 changes: 3 additions & 3 deletions src/ipc/ipc4/handler-user.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd)

switch (cmd) {
case SOF_IPC4_PIPELINE_STATE_RUNNING:
if (ppl_icd->pipeline->expect_eos) {
if (ppl_icd->pipeline->source_comp && ppl_icd->pipeline->source_comp->expect_eos) {
ipc_cmd_err(&ipc_tr, "pipeline %d: Can't transition from EOS to RUNNING",
ppl_icd->id);
return IPC4_INVALID_REQUEST;
Expand Down Expand Up @@ -385,7 +385,7 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd)
ppl_icd->id, status);
return IPC4_INVALID_REQUEST;
}
ppl_icd->pipeline->expect_eos = true;
pipeline_set_eos(ppl_icd->pipeline, true);
return 0; /* Must return here. Any other transition clears expect_eos. */
/* special case - TODO */
case SOF_IPC4_PIPELINE_STATE_SAVED:
Expand All @@ -399,7 +399,7 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd)
if (ret < 0)
return IPC4_INVALID_REQUEST;

ppl_icd->pipeline->expect_eos = false;
pipeline_set_eos(ppl_icd->pipeline, false);

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion test/cmocka/src/audio/mux/demux_copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ static int setup_test_case(void **state)
dummy_pipe = test_malloc(sizeof(*dummy_pipe));
if (!dummy_pipe)
return -ENOMEM;
dummy_pipe->expect_eos = false;
dev->expect_eos = false;
dev->pipeline = dummy_pipe;

mod = comp_mod(dev);
Expand Down
2 changes: 1 addition & 1 deletion test/cmocka/src/audio/mux/mux_copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ static int setup_test_case(void **state)
dummy_pipe = test_malloc(sizeof(*dummy_pipe));
if (!dummy_pipe)
return -ENOMEM;
dummy_pipe->expect_eos = false;
dev->expect_eos = false;
dev->pipeline = dummy_pipe;

mod = comp_mod(dev);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# All input formats for e.g. host-copier, decoder,
# and module-copier
num_input_audio_formats 40
num_input_audio_formats 72
CombineArrays.Object.Base.input_audio_format [
{
in_channels [ 1 ]
in_rate [
8000
16000
22050
24000
32000
44100
48000
96000
Expand All @@ -21,6 +25,10 @@
in_channels [ 1 ]
in_rate [
8000
16000
22050
24000
32000
44100
48000
96000
Expand All @@ -35,6 +43,10 @@
in_channels [ 1 ]
in_rate [
8000
16000
22050
24000
32000
44100
48000
96000
Expand All @@ -49,6 +61,10 @@
in_channels [ 1 ]
in_rate [
8000
16000
22050
24000
32000
44100
48000
96000
Expand All @@ -62,6 +78,10 @@
{
in_rate [
8000
16000
22050
24000
32000
44100
48000
96000
Expand All @@ -74,6 +94,10 @@
{
in_rate [
8000
16000
22050
24000
32000
44100
48000
96000
Expand All @@ -85,6 +109,10 @@
{
in_rate [
8000
16000
22050
24000
32000
44100
48000
96000
Expand All @@ -96,6 +124,10 @@
{
in_rate [
8000
16000
22050
24000
32000
44100
48000
96000
Expand Down
Loading
Loading