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
16 changes: 16 additions & 0 deletions src/audio/buffers/comp_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,20 @@ static int comp_buffer_source_get_state(struct sof_source *source)
return comp_get_state(comp_buffer_get_source_component(buffer));
}

static int comp_buffer_sink_set_size(struct sof_sink *sink, size_t size)
{
struct comp_buffer *buffer = comp_buffer_get_from_sink(sink);

return buffer_set_size(buffer, size, buffer->stream.byte_align_req);
}

static int comp_buffer_source_set_size(struct sof_source *source, size_t size)
{
struct comp_buffer *buffer = comp_buffer_get_from_source(source);

return buffer_set_size(buffer, size, buffer->stream.byte_align_req);
}

static int comp_buffer_set_ipc_params(struct sof_audio_buffer *audio_buffer,
struct sof_ipc_stream_params *params,
bool force_update)
Expand Down Expand Up @@ -195,6 +209,7 @@ APP_TASK_DATA static const struct source_ops comp_buffer_source_ops = {
.on_audio_format_set = audio_buffer_source_on_audio_format_set,
.set_alignment_constants = audio_buffer_source_set_alignment_constants,
.get_state = comp_buffer_source_get_state,
.set_size = comp_buffer_source_set_size,
};

APP_TASK_DATA static const struct sink_ops comp_buffer_sink_ops = {
Expand All @@ -206,6 +221,7 @@ APP_TASK_DATA static const struct sink_ops comp_buffer_sink_ops = {
.set_alignment_constants = audio_buffer_sink_set_alignment_constants,
.get_lft = audio_buffer_sink_get_lft,
.get_state = comp_buffer_sink_get_state,
.set_size = comp_buffer_sink_set_size,
};

static const struct audio_buffer_ops audio_buffer_ops = {
Expand Down
143 changes: 80 additions & 63 deletions src/audio/module_adapter/module/cadence_ipc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static int cadence_codec_init(struct processing_module *mod)
struct module_config *setup_cfg;
int ret;

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

cd = mod_zalloc(mod, sizeof(struct cadence_codec_data));
if (!cd) {
Expand Down Expand Up @@ -83,7 +83,7 @@ static int cadence_codec_init(struct processing_module *mod)
setup_cfg->avail = true;
}

comp_dbg(dev, "cadence_codec_init() done");
comp_dbg(dev, "done");

return 0;

Expand All @@ -103,7 +103,7 @@ int cadence_codec_apply_config(struct processing_module *mod)
struct module_data *codec = &mod->priv;
struct cadence_codec_data *cd = codec->private;

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

cfg = &codec->cfg;

Expand All @@ -115,25 +115,13 @@ int cadence_codec_apply_config(struct processing_module *mod)
size = cfg->size;

if (!cfg->avail || !size) {
comp_err(dev, "cadence_codec_apply_config() error: no config available");
comp_err(dev, "no config available");
return -EIO;
}

return cadence_codec_apply_params(mod, size, data);
}

static int cadence_codec_deep_buff_allowed(struct processing_module *mod)
{
struct cadence_codec_data *cd = module_get_private_data(mod);

switch (cd->api_id) {
case CADENCE_CODEC_MP3_ENC_ID:
return 0;
default:
return 1;
}
}

static int cadence_codec_prepare(struct processing_module *mod,
struct sof_source **sources, int num_of_sources,
struct sof_sink **sinks, int num_of_sinks)
Expand All @@ -143,48 +131,56 @@ static int cadence_codec_prepare(struct processing_module *mod,
struct module_data *codec = &mod->priv;
struct cadence_codec_data *cd = codec->private;

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

ret = cadence_init_codec_object(mod);
if (ret)
return ret;

ret = cadence_codec_apply_config(mod);
if (ret) {
comp_err(dev, "cadence_codec_prepare() error %x: failed to apply config",
comp_err(dev, "error %x: failed to apply config",
ret);
return ret;
}

/* Allocate memory for the codec */
API_CALL(cd, XA_API_CMD_GET_MEMTABS_SIZE, 0, &mem_tabs_size, ret);
if (ret != LIB_NO_ERROR) {
comp_err(dev, "cadence_codec_prepare() error %x: failed to get memtabs size",
comp_err(dev, "error %x: failed to get memtabs size",
ret);
return ret;
}

cd->mem_tabs = mod_alloc(mod, mem_tabs_size);
if (!cd->mem_tabs) {
comp_err(dev, "cadence_codec_prepare() error: failed to allocate space for memtabs");
comp_err(dev, "failed to allocate space for memtabs");
return -ENOMEM;
}

comp_dbg(dev, "allocated %d bytes for memtabs", mem_tabs_size);

API_CALL(cd, XA_API_CMD_SET_MEMTABS_PTR, 0, cd->mem_tabs, ret);
if (ret != LIB_NO_ERROR) {
comp_err(dev, "cadence_codec_prepare() error %x: failed to set memtabs",
comp_err(dev, "error %x: failed to set memtabs",
ret);
goto free;
}

ret = cadence_codec_init_memory_tables(mod);
if (ret != LIB_NO_ERROR) {
comp_err(dev, "cadence_codec_prepare() error %x: failed to init memory tables",
comp_err(dev, "error %x: failed to init memory tables",
ret);
goto free;
}

/* grow the sink so a whole decoded frame fits */
ret = sink_set_size(sinks[0], 2 * codec->mpd.out_buff_size);
if (ret < 0) {
comp_err(dev, "error %d: failed to resize sink", ret);
goto free;
}

/* Check init done status. Note, it may happen that init_done flag will return
* false value, this is normal since some codec variants needs input in order to
* fully finish initialization. That's why at codec_adapter_copy() we call
Expand All @@ -200,85 +196,106 @@ static int cadence_codec_prepare(struct processing_module *mod,
API_CALL(cd, XA_API_CMD_INIT, XA_CMD_TYPE_INIT_DONE_QUERY,
&codec->mpd.init_done, ret);
if (ret != LIB_NO_ERROR) {
comp_err(dev, "cadence_codec_init_process() error %x: failed to get lib init status",
comp_err(dev, "error %x: failed to get lib init status",
ret);
return ret;
}
#endif
comp_dbg(dev, "cadence_codec_prepare() done");
comp_dbg(dev, "done");
return 0;
free:
mod_free(mod, cd->mem_tabs);
return ret;
}

static int
cadence_codec_process(struct processing_module *mod,
struct input_stream_buffer *input_buffers, int num_input_buffers,
struct output_stream_buffer *output_buffers, int num_output_buffers)
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)
{
struct comp_buffer *local_buff;
struct comp_dev *dev = mod->dev;
struct module_data *codec = &mod->priv;
int free_bytes, output_bytes = cadence_codec_get_samples(mod) *
mod->stream_params->sample_container_bytes *
mod->stream_params->channels;
uint32_t remaining = input_buffers[0].size;
const size_t in_size = source_get_data_available(sources[0]);
const size_t output_bytes = cadence_codec_get_samples(mod) *
mod->stream_params->sample_container_bytes *
mod->stream_params->channels;
const size_t out_space = sink_get_free_size(sinks[0]);
const void *source_buffer_start, *src_ptr;
void *sink_buffer_start, *sink_ptr;
size_t buffer_size;
int ret;

if (!cadence_codec_deep_buff_allowed(mod))
mod->deep_buff_bytes = 0;

/* Proceed only if we have enough data to fill the module buffer completely */
if (input_buffers[0].size < codec->mpd.in_buff_size) {
if (in_size < codec->mpd.in_buff_size) {
comp_dbg(dev, "not enough data to process");
return -ENODATA;
}

if (!codec->mpd.init_done) {
memcpy_s(codec->mpd.in_buff, codec->mpd.in_buff_size, input_buffers[0].data,
codec->mpd.in_buff_size);
codec->mpd.avail = codec->mpd.in_buff_size;
/* Acquire data from the source buffer */
ret = source_get_data(sources[0], codec->mpd.in_buff_size, &src_ptr,
&source_buffer_start, &buffer_size);
if (ret) {
comp_err(dev, "cannot get data from source buffer");
return ret;
}

cadence_copy_data_from_buffer(codec->mpd.in_buff, src_ptr, codec->mpd.in_buff_size,
buffer_size, source_buffer_start);

codec->mpd.avail = codec->mpd.in_buff_size;
ret = cadence_codec_init_process(mod);
if (ret)
if (ret) {
source_release_data(sources[0], 0);
return ret;
}

source_release_data(sources[0], codec->mpd.consumed);

remaining -= codec->mpd.consumed;
input_buffers[0].consumed = codec->mpd.consumed;
/* Proceed only if we have enough data to fill the module buffer completely */
if (in_size - codec->mpd.consumed < codec->mpd.in_buff_size)
return -ENODATA;
}

/* do not proceed with processing if not enough free space left in the local buffer */
local_buff = list_first_item(&mod->raw_data_buffers_list, struct comp_buffer, buffers_list);
free_bytes = audio_stream_get_free(&local_buff->stream);
if (free_bytes < output_bytes)
if (out_space < output_bytes)
return -ENOSPC;

/* Proceed only if we have enough data to fill the module buffer completely */
if (remaining < codec->mpd.in_buff_size)
return -ENODATA;
/* Acquire data from the source buffer */
ret = source_get_data(sources[0], codec->mpd.in_buff_size, &src_ptr, &source_buffer_start,
&buffer_size);
if (ret) {
comp_err(dev, "cannot get data from source buffer");
return ret;
}

memcpy_s(codec->mpd.in_buff, codec->mpd.in_buff_size,
(uint8_t *)input_buffers[0].data + input_buffers[0].consumed,
codec->mpd.in_buff_size);
cadence_copy_data_from_buffer(codec->mpd.in_buff, src_ptr, codec->mpd.in_buff_size,
buffer_size, source_buffer_start);
codec->mpd.avail = codec->mpd.in_buff_size;

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

ret = cadence_codec_process_data(mod, NULL);
if (ret)
if (ret) {
source_release_data(sources[0], 0);
return ret;
}

ret = sink_get_buffer(sinks[0], codec->mpd.produced, &sink_ptr, &sink_buffer_start,
&buffer_size);
if (ret) {
comp_err(dev, "cannot get sink buffer");
source_release_data(sources[0], 0);
return ret;
}

/* update consumed with the number of samples consumed during init */
input_buffers[0].consumed += codec->mpd.consumed;
codec->mpd.consumed = input_buffers[0].consumed;
/* Copy the produced samples into the output buffer */
cadence_copy_data_to_buffer(sink_ptr, codec->mpd.produced, buffer_size,
sink_buffer_start, codec->mpd.out_buff);

/* copy the produced samples into the output buffer */
memcpy_s(output_buffers[0].data, codec->mpd.produced, codec->mpd.out_buff,
codec->mpd.produced);
output_buffers[0].size = codec->mpd.produced;
source_release_data(sources[0], codec->mpd.consumed);
sink_commit_buffer(sinks[0], codec->mpd.produced);

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

return 0;
}
Expand Down Expand Up @@ -308,7 +325,7 @@ static int cadence_codec_reset(struct processing_module *mod)
static const struct module_interface cadence_codec_interface = {
.init = cadence_codec_init,
.prepare = cadence_codec_prepare,
.process_raw_data = cadence_codec_process,
.process = cadence_codec_process,
.set_configuration = cadence_codec_set_configuration,
.reset = cadence_codec_reset,
.free = cadence_codec_free
Expand Down
15 changes: 15 additions & 0 deletions src/include/module/audio/sink_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ struct sink_ops {
const uint32_t byte_align,
const uint32_t frame_align_req);

/**
* OPTIONAL
* see comment for sink_set_size
*/
int (*set_size)(struct sof_sink *sink, size_t size);

/**
* OPTIONAL
* events called when a module is starting / finishing using of the API
Expand Down Expand Up @@ -303,6 +309,15 @@ int sink_set_alignment_constants(struct sof_sink *sink,
const uint32_t byte_align,
const uint32_t frame_align_req);

/**
* Resize the buffer backing the sink.
*
* @param sink a handler to sink
* @param size requested buffer size in bytes
* @return 0 on success, -ENOSYS if the sink implementation does not support resizing
*/
int sink_set_size(struct sof_sink *sink, size_t size);

int sink_set_valid_fmt(struct sof_sink *sink, enum sof_ipc_frame valid_sample_fmt);
int sink_set_rate(struct sof_sink *sink, unsigned int rate);
int sink_set_channels(struct sof_sink *sink, unsigned int channels);
Expand Down
15 changes: 15 additions & 0 deletions src/include/module/audio/source_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ struct source_ops {
const uint32_t byte_align,
const uint32_t frame_align_req);

/**
* OPTIONAL
* see comment for source_set_size
*/
int (*set_size)(struct sof_source *source, size_t size);

/**
* OPTIONAL
* events called when a module is starting / finishing using of the API
Expand Down Expand Up @@ -265,6 +271,15 @@ int source_get_data_s32(struct sof_source *source, size_t req_size, int32_t cons
*/
int source_release_data(struct sof_source *source, size_t free_size);

/**
* Resize the buffer backing the source.
*
* @param source a handler to source
* @param size requested buffer size in bytes
* @return 0 on success, -ENOSYS if the source implementation does not support resizing
*/
int source_set_size(struct sof_source *source, size_t size);

/** set of functions for retrieve audio parameters */
static inline enum sof_ipc_frame source_get_valid_fmt(struct sof_source *source)
{
Expand Down
8 changes: 8 additions & 0 deletions src/module/audio/sink_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,11 @@ int sink_set_alignment_constants(struct sof_sink *sink, const uint32_t byte_alig
return 0;
}
EXPORT_SYMBOL(sink_set_alignment_constants);

int sink_set_size(struct sof_sink *sink, size_t size)
{
if (sink->ops->set_size)
return sink->ops->set_size(sink, size);
return -ENOSYS;
}
EXPORT_SYMBOL(sink_set_size);
8 changes: 8 additions & 0 deletions src/module/audio/source_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,11 @@ size_t source_get_data_frames_available(struct sof_source *source)
return 0;
}
EXPORT_SYMBOL(source_get_data_frames_available);

int source_set_size(struct sof_source *source, size_t size)
{
if (source->ops->set_size)
return source->ops->set_size(source, size);
return -ENOSYS;
}
EXPORT_SYMBOL(source_set_size);
Loading