From dae67b0a29d0d189aec5d11a64b67be9e2fbd69c Mon Sep 17 00:00:00 2001 From: Marcin Rajwa Date: Tue, 27 Apr 2021 12:23:22 +0200 Subject: [PATCH] cadence codecs: update stream params This patch takes care of the update of stream parameters during runtime. It is important to start stream base on its runtime params and not those read from the topology which may not match those of stream. For now we only take care of sample rate, sample width and number of channels. Notice that Cadence API has the following particularities: * each codec has its own set of parameters IDs (e.g sample rate ID for AAC might be different for sample rate ID for MP3). * setting parameters is not always valid and can return a fatal error. This patch only takes care of updating the parameters for wildcard codec id (which is used by Intel). Signed-off-by: Marcin Rajwa Signed-off-by: Daniel Baluta --- src/audio/codec_adapter/codec/cadence.c | 112 ++++++++++++++++++ .../sof/audio/codec_adapter/codec/cadence.h | 6 + 2 files changed, 118 insertions(+) diff --git a/src/audio/codec_adapter/codec/cadence.c b/src/audio/codec_adapter/codec/cadence.c index dd2d9ccce9f5..8c74ed702106 100644 --- a/src/audio/codec_adapter/codec/cadence.c +++ b/src/audio/codec_adapter/codec/cadence.c @@ -157,6 +157,110 @@ int cadence_codec_init(struct comp_dev *dev) return ret; } +static int update_stream_sample_rate(struct comp_dev *dev) +{ + struct comp_data *ca_data = comp_get_drvdata(dev); + struct codec_data *codec = comp_get_codec(dev); + struct cadence_codec_data *cd = codec->private; + struct sof_ipc_stream_params *stream = &ca_data->stream_params; + uint32_t api_id = CODEC_GET_API_ID(codec->id); + uint32_t sample_rate_id; + int ret; + + switch (api_id) { + case CADENCE_CODEC_WRAPPER_ID: + sample_rate_id = CADENCE_SAMPLE_RATE_ID; + break; + default: + return 0; + } + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, sample_rate_id, &stream->rate, ret); + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "update_stream_sample_params(): failed to set sample rate."); + return ret; + } + + return 0; +} + +static int update_stream_sample_width(struct comp_dev *dev) +{ + struct comp_data *ca_data = comp_get_drvdata(dev); + struct codec_data *codec = comp_get_codec(dev); + struct cadence_codec_data *cd = codec->private; + struct sof_ipc_stream_params *stream = &ca_data->stream_params; + uint32_t api_id = CODEC_GET_API_ID(codec->id); + uint32_t sample_width = (stream->frame_fmt == SOF_IPC_FRAME_S16_LE) ? 16 : 32; + uint32_t sample_width_id; + int ret; + + switch (api_id) { + case CADENCE_CODEC_WRAPPER_ID: + sample_width_id = CADENCE_SAMPLE_WIDTH_ID; + break; + default: + return 0; + } + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, sample_width_id, &sample_width, ret); + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "update_stream_sample_width(): failed to set sample width."); + return ret; + } + + return 0; +} + +static int update_stream_channels(struct comp_dev *dev) +{ + struct comp_data *ca_data = comp_get_drvdata(dev); + struct codec_data *codec = comp_get_codec(dev); + struct cadence_codec_data *cd = codec->private; + struct sof_ipc_stream_params *stream = &ca_data->stream_params; + uint32_t api_id = CODEC_GET_API_ID(codec->id); + uint32_t sample_channels_id; + int ret; + + switch (api_id) { + case CADENCE_CODEC_WRAPPER_ID: + sample_channels_id = CADENCE_CHANNELS_COUNT_ID; + break; + default: + return 0; + } + + API_CALL(cd, XA_API_CMD_SET_CONFIG_PARAM, sample_channels_id, &stream->channels, ret); + if (LIB_IS_FATAL_ERROR(ret)) { + comp_err(dev, "update_stream_channels(): failed to set channels"); + return ret; + } + + return 0; +} + +static int update_stream_params(struct comp_dev *dev) +{ + int ret = 0; + + comp_dbg(dev, "update_stream_params() start"); + + ret = update_stream_sample_rate(dev); + if (ret) + return ret; + + ret = update_stream_sample_width(dev); + if (ret) + return ret; + + ret = update_stream_channels(dev); + if (ret) + return ret; + + comp_dbg(dev, "update_stream_params() done"); + return 0; +} + static int apply_config(struct comp_dev *dev, enum codec_cfg_type type) { int ret = 0; @@ -413,6 +517,14 @@ int cadence_codec_prepare(struct comp_dev *dev) } } + /* Update codec config with stream parameters */ + ret = update_stream_params(dev); + if (ret) { + comp_err(dev, "cadence_codec_prepare() error %x: failed to update stream params", + ret); + goto err; + } + /* Allocate memory for the codec */ API_CALL(cd, XA_API_CMD_GET_MEMTABS_SIZE, 0, &mem_tabs_size, ret); if (ret != LIB_NO_ERROR) { diff --git a/src/include/sof/audio/codec_adapter/codec/cadence.h b/src/include/sof/audio/codec_adapter/codec/cadence.h index 76e833eb6bd1..e95219e47def 100644 --- a/src/include/sof/audio/codec_adapter/codec/cadence.h +++ b/src/include/sof/audio/codec_adapter/codec/cadence.h @@ -36,6 +36,12 @@ struct cadence_api { xa_codec_func_t *api; }; +enum default_stream_params_ids { + CADENCE_SAMPLE_RATE_ID = 1, + CADENCE_SAMPLE_WIDTH_ID = 2, + CADENCE_CHANNELS_COUNT_ID = 4, +}; + struct cadence_codec_data { char name[LIB_NAME_MAX_LEN]; void *self;