mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-04 13:30:08 -05:00
topology: Merge lookup for data reference into tplg_copy_data()
Code refactor to reduce function calls. Now tplg_copy_data() can look up a referenced data element and merge its data. Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com> Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
bb03d929e8
commit
2481ef315f
4 changed files with 34 additions and 31 deletions
|
|
@ -140,9 +140,9 @@ static int tplg_build_mixer_control(snd_tplg_t *tplg,
|
||||||
err = copy_tlv(elem, ref->elem);
|
err = copy_tlv(elem, ref->elem);
|
||||||
|
|
||||||
} else if (ref->type == SND_TPLG_TYPE_DATA) {
|
} else if (ref->type == SND_TPLG_TYPE_DATA) {
|
||||||
ref->elem = tplg_elem_lookup(&tplg->pdata_list,
|
err = tplg_copy_data(tplg, elem, ref);
|
||||||
ref->id, SND_TPLG_TYPE_DATA);
|
if (err < 0)
|
||||||
err = tplg_copy_data(elem, ref->elem);
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ref->elem) {
|
if (!ref->elem) {
|
||||||
|
|
@ -188,9 +188,9 @@ static int tplg_build_enum_control(snd_tplg_t *tplg,
|
||||||
copy_enum_texts(elem, ref->elem);
|
copy_enum_texts(elem, ref->elem);
|
||||||
|
|
||||||
} else if (ref->type == SND_TPLG_TYPE_DATA) {
|
} else if (ref->type == SND_TPLG_TYPE_DATA) {
|
||||||
ref->elem = tplg_elem_lookup(&tplg->pdata_list,
|
err = tplg_copy_data(tplg, elem, ref);
|
||||||
ref->id, SND_TPLG_TYPE_DATA);
|
if (err < 0)
|
||||||
err = tplg_copy_data(elem, ref->elem);
|
return err;
|
||||||
}
|
}
|
||||||
if (!ref->elem) {
|
if (!ref->elem) {
|
||||||
SNDERR("error: cannot find '%s' referenced by"
|
SNDERR("error: cannot find '%s' referenced by"
|
||||||
|
|
@ -208,6 +208,7 @@ static int tplg_build_bytes_control(snd_tplg_t *tplg, struct tplg_elem *elem)
|
||||||
{
|
{
|
||||||
struct tplg_ref *ref;
|
struct tplg_ref *ref;
|
||||||
struct list_head *base, *pos;
|
struct list_head *base, *pos;
|
||||||
|
int err;
|
||||||
|
|
||||||
base = &elem->ref_list;
|
base = &elem->ref_list;
|
||||||
|
|
||||||
|
|
@ -217,18 +218,11 @@ static int tplg_build_bytes_control(snd_tplg_t *tplg, struct tplg_elem *elem)
|
||||||
if (ref->id == NULL || ref->elem)
|
if (ref->id == NULL || ref->elem)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* bytes control only reference one private data section */
|
if (ref->type == SND_TPLG_TYPE_DATA) {
|
||||||
ref->elem = tplg_elem_lookup(&tplg->pdata_list,
|
err = tplg_copy_data(tplg, elem, ref);
|
||||||
ref->id, SND_TPLG_TYPE_DATA);
|
if (err < 0)
|
||||||
if (!ref->elem) {
|
return err;
|
||||||
SNDERR("error: cannot find data '%s'"
|
|
||||||
" referenced by control '%s'\n",
|
|
||||||
ref->id, elem->id);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy texts to enum elem */
|
|
||||||
return tplg_copy_data(elem, ref->elem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -191,12 +191,11 @@ static int tplg_build_widget(snd_tplg_t *tplg,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SND_TPLG_TYPE_DATA:
|
case SND_TPLG_TYPE_DATA:
|
||||||
if (!ref->elem)
|
err = tplg_copy_data(tplg, elem, ref);
|
||||||
ref->elem = tplg_elem_lookup(&tplg->pdata_list,
|
if (err < 0)
|
||||||
ref->id, SND_TPLG_TYPE_DATA);
|
return err;
|
||||||
if (ref->elem)
|
|
||||||
err = tplg_copy_data(elem, ref->elem);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -889,22 +889,30 @@ int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Merge data from a referenced data element to the parent element's
|
/* Find a referenced data element and copy its data to the parent
|
||||||
* private data buffer.
|
* element's private data buffer.
|
||||||
* An element can refer to multiple data sections. Data of these sections
|
* An element can refer to multiple data sections. Data of these sections
|
||||||
* will be merged in the their reference order.
|
* will be merged in the their reference order.
|
||||||
*/
|
*/
|
||||||
int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
|
int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||||
|
struct tplg_ref *ref)
|
||||||
{
|
{
|
||||||
|
struct tplg_elem *ref_elem;
|
||||||
struct snd_soc_tplg_private *priv, *old_priv;
|
struct snd_soc_tplg_private *priv, *old_priv;
|
||||||
int priv_data_size, old_priv_data_size;
|
int priv_data_size, old_priv_data_size;
|
||||||
void *obj;
|
void *obj;
|
||||||
|
|
||||||
if (!ref)
|
ref_elem = tplg_elem_lookup(&tplg->pdata_list,
|
||||||
|
ref->id, SND_TPLG_TYPE_DATA);
|
||||||
|
if (!ref_elem) {
|
||||||
|
SNDERR("error: cannot find data '%s' referenced by"
|
||||||
|
" element '%s'\n", ref->id, elem->id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
tplg_dbg("Data '%s' used by '%s'\n", ref->id, elem->id);
|
tplg_dbg("Data '%s' used by '%s'\n", ref->id, elem->id);
|
||||||
if (!ref->data || !ref->data->size) /* overlook empty private data */
|
/* overlook empty private data */
|
||||||
|
if (!ref_elem->data || !ref_elem->data->size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
old_priv = get_priv_data(elem);
|
old_priv = get_priv_data(elem);
|
||||||
|
|
@ -912,7 +920,7 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
old_priv_data_size = old_priv->size;
|
old_priv_data_size = old_priv->size;
|
||||||
|
|
||||||
priv_data_size = ref->data->size;
|
priv_data_size = ref_elem->data->size;
|
||||||
obj = realloc(elem->obj,
|
obj = realloc(elem->obj,
|
||||||
elem->size + priv_data_size);
|
elem->size + priv_data_size);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
|
|
@ -926,9 +934,9 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
|
||||||
/* merge the new data block */
|
/* merge the new data block */
|
||||||
elem->size += priv_data_size;
|
elem->size += priv_data_size;
|
||||||
priv->size = priv_data_size + old_priv_data_size;
|
priv->size = priv_data_size + old_priv_data_size;
|
||||||
ref->compound_elem = 1;
|
ref_elem->compound_elem = 1;
|
||||||
memcpy(priv->data + old_priv_data_size,
|
memcpy(priv->data + old_priv_data_size,
|
||||||
ref->data->data, priv_data_size);
|
ref_elem->data->data, priv_data_size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,9 @@ int tplg_build_widgets(snd_tplg_t *tplg);
|
||||||
int tplg_build_routes(snd_tplg_t *tplg);
|
int tplg_build_routes(snd_tplg_t *tplg);
|
||||||
int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type);
|
int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type);
|
||||||
|
|
||||||
int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref);
|
int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||||
|
struct tplg_ref *ref);
|
||||||
|
|
||||||
int tplg_parse_data_refs(snd_config_t *cfg, struct tplg_elem *elem);
|
int tplg_parse_data_refs(snd_config_t *cfg, struct tplg_elem *elem);
|
||||||
|
|
||||||
int tplg_ref_add(struct tplg_elem *elem, int type, const char* id);
|
int tplg_ref_add(struct tplg_elem *elem, int type, const char* id);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue