diff --git a/src/audio/codec_adapter/codec/cadence.c b/src/audio/codec_adapter/codec/cadence.c index 1aecef978b1a..0fcfc7dca4b3 100644 --- a/src/audio/codec_adapter/codec/cadence.c +++ b/src/audio/codec_adapter/codec/cadence.c @@ -254,9 +254,46 @@ static int init_memory_tables(struct comp_dev *dev) return ret; } +int cadence_codec_init_process(struct comp_dev *dev) +{ + int ret; + struct codec_data *codec = comp_get_codec(dev); + struct cadence_codec_data *cd = codec->private; + + API_CALL(cd, XA_API_CMD_SET_INPUT_BYTES, 0, &codec->cpd.avail, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_init_process() error %x: failed to set size of input data", + ret); + return ret; + } + + API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_PROCESS, NULL, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_init_process() error %x: failed to initialize codec", + ret); + return ret; + } + + API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_DONE_QUERY, + &codec->cpd.init_done, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_init_process() error %x: failed to get lib init status", + ret); + return ret; + } + + API_CALL(cd, XA_API_CMD_GET_CURIDX_INPUT_BUF, 0, &codec->cpd.consumed, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_init_process() error %x: could not get consumed bytes", + ret); + return ret; + } + + return 0; +} int cadence_codec_prepare(struct comp_dev *dev) { - int ret = 0, mem_tabs_size, lib_init_status; + int ret = 0, mem_tabs_size; struct codec_data *codec = comp_get_codec(dev); struct cadence_codec_data *cd = codec->private; @@ -324,26 +361,9 @@ int cadence_codec_prepare(struct comp_dev *dev) goto free; } - API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_PROCESS, NULL, ret); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_prepare() error %x: failed to initialize codec", - ret); - goto free; - } - - API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_DONE_QUERY, - &lib_init_status, ret); - if (ret != LIB_NO_ERROR) { - comp_err(dev, "cadence_codec_prepare() error %x: failed to get lib init status", - ret); - goto free; - } else if (!lib_init_status) { - comp_err(dev, "cadence_codec_prepare() error: lib has not been initiated properly"); - ret = -EINVAL; + ret = cadence_codec_init_process(dev); + if (ret) goto free; - } else { - comp_dbg(dev, "cadence_codec_prepare(): lib has been initialized properly"); - } comp_dbg(dev, "cadence_codec_prepare() done"); return 0; @@ -383,6 +403,13 @@ int cadence_codec_process(struct comp_dev *dev) goto err; } + API_CALL(cd, XA_API_CMD_GET_CURIDX_INPUT_BUF, 0, &codec->cpd.consumed, ret); + if (ret != LIB_NO_ERROR) { + comp_err(dev, "cadence_codec_process() error %x: could not get consumed bytes", + ret); + goto err; + } + comp_dbg(dev, "cadence_codec_process() done"); return 0; diff --git a/src/audio/codec_adapter/codec/generic.c b/src/audio/codec_adapter/codec/generic.c index 8c1259f8805b..aee53aae2419 100644 --- a/src/audio/codec_adapter/codec/generic.c +++ b/src/audio/codec_adapter/codec/generic.c @@ -245,6 +245,25 @@ int codec_prepare(struct comp_dev *dev) return ret; } +int codec_init_process(struct comp_dev *dev) +{ + int ret; + struct comp_data *cd = comp_get_drvdata(dev); + struct codec_data *codec = &cd->codec; + + comp_dbg(dev, "codec_init_process() start"); + + ret = codec->ops->init_process(dev); + if (ret) { + comp_err(dev, "codec_init_process() error %x", ret); + goto out; + } + + comp_dbg(dev, "codec_init_process() done"); +out: + return ret; +} + int codec_process(struct comp_dev *dev) { int ret; diff --git a/src/audio/codec_adapter/codec_adapter.c b/src/audio/codec_adapter/codec_adapter.c index 5ce1a18bd57b..6413b42021e0 100644 --- a/src/audio/codec_adapter/codec_adapter.c +++ b/src/audio/codec_adapter/codec_adapter.c @@ -364,7 +364,7 @@ static void generate_zeroes(struct comp_buffer *sink, uint32_t bytes) static int codec_adapter_copy(struct comp_dev *dev) { int ret = 0; - uint32_t bytes_to_process, copy_bytes, processed = 0; + uint32_t bytes_to_process, copy_bytes, processed = 0, produced = 0; struct comp_data *cd = comp_get_drvdata(dev); struct codec_data *codec = &cd->codec; struct comp_buffer *source = cd->ca_source; @@ -379,6 +379,22 @@ static int codec_adapter_copy(struct comp_dev *dev) comp_dbg(dev, "codec_adapter_copy() start: codec_buff_size: %d, local_buff free: %d source avail %d", codec_buff_size, local_buff->stream.free, source->stream.avail); + if (!codec->cpd.init_done) { + if (bytes_to_process < codec_buff_size) + goto db_verify; + + buffer_invalidate(source, codec_buff_size); + codec_adapter_copy_from_source_to_lib(&source->stream, &codec->cpd, + codec_buff_size); + codec->cpd.avail = codec_buff_size; + ret = codec_init_process(dev); + if (ret) + return ret; + + bytes_to_process -= codec->cpd.consumed; + comp_update_buffer_consume(source, codec->cpd.consumed); + } + while (bytes_to_process) { /* Proceed only if we have enough data to fill the lib buffer * completely. If you don't fill whole buffer @@ -407,18 +423,19 @@ static int codec_adapter_copy(struct comp_dev *dev) codec_adapter_copy_from_lib_to_sink(&codec->cpd, &local_buff->stream, codec->cpd.produced); - bytes_to_process -= codec->cpd.produced; - processed += codec->cpd.produced; + bytes_to_process -= codec->cpd.consumed; + processed += codec->cpd.consumed; + produced += codec->cpd.produced; } - if (!processed && !cd->deep_buff_bytes) { + if (!produced && !cd->deep_buff_bytes) { comp_dbg(dev, "codec_adapter_copy(): nothing processed in this call"); goto end; - } else if (!processed && cd->deep_buff_bytes) { + } else if (!produced && cd->deep_buff_bytes) { goto db_verify; } - audio_stream_produce(&local_buff->stream, processed); + audio_stream_produce(&local_buff->stream, produced); comp_update_buffer_consume(source, processed); db_verify: diff --git a/src/include/sof/audio/codec_adapter/codec/cadence.h b/src/include/sof/audio/codec_adapter/codec/cadence.h index f16c23e4c360..7f12b1077c4e 100644 --- a/src/include/sof/audio/codec_adapter/codec/cadence.h +++ b/src/include/sof/audio/codec_adapter/codec/cadence.h @@ -42,6 +42,7 @@ struct cadence_codec_data { /*****************************************************************************/ int cadence_codec_init(struct comp_dev *dev); int cadence_codec_prepare(struct comp_dev *dev); +int cadence_codec_init_process(struct comp_dev *dev); int cadence_codec_process(struct comp_dev *dev); int cadence_codec_apply_config(struct comp_dev *dev); int cadence_codec_reset(struct comp_dev *dev); diff --git a/src/include/sof/audio/codec_adapter/codec/generic.h b/src/include/sof/audio/codec_adapter/codec/generic.h index 32b7f38346ad..c2b48596c0df 100644 --- a/src/include/sof/audio/codec_adapter/codec/generic.h +++ b/src/include/sof/audio/codec_adapter/codec/generic.h @@ -48,6 +48,14 @@ struct codec_interface { * component preparation in .prepare() */ int (*prepare)(struct comp_dev *dev); + /** + * Codec specific init processing procedure, called as a part of + * codec_adapter component copy in .copy(). Typically in this + * phase a processing algorithm searches for the valid header, + * does header decoding to get the parameters and initializes + * state and configuration structures. + */ + int (*init_process)(struct comp_dev *dev); /** * Codec specific processing procedure, called as part of codec_adapter * component copy in .copy(). This procedure is responsible to consume @@ -159,7 +167,9 @@ struct codec_processing_data { uint32_t in_buff_size; /**< Specifies the size of codec input buffer. */ uint32_t out_buff_size; /**< Specifies the size of codec output buffer.*/ uint32_t avail; /**< Specifies how much data is available for codec to process.*/ - uint32_t produced; /**< Specifies how much data the codec processed in its last task.*/ + uint32_t produced; /**< Specifies how much data the codec produced in its last task.*/ + uint32_t consumed; /**< Specified how much data the codec consumed in its last task */ + uint32_t init_done; /**< Specifies if the codec initialization is finished */ void *in_buff; /**< A pointer to codec input buffer. */ void *out_buff; /**< A pointer to codec output buffer. */ }; @@ -201,6 +211,7 @@ void *codec_allocate_memory(struct comp_dev *dev, uint32_t size, int codec_free_memory(struct comp_dev *dev, void *ptr); void codec_free_all_memory(struct comp_dev *dev); int codec_prepare(struct comp_dev *dev); +int codec_init_process(struct comp_dev *dev); int codec_process(struct comp_dev *dev); int codec_apply_runtime_config(struct comp_dev *dev); int codec_reset(struct comp_dev *dev);