]> git.alsa-project.org Git - alsa-lib.git/commitdiff
topology: Group elements with the same index value into a block
authorFuwei Tang <fuweix.tang@intel.com>
Thu, 13 Apr 2017 06:52:47 +0000 (14:52 +0800)
committerTakashi Iwai <tiwai@suse.de>
Fri, 21 Apr 2017 10:57:59 +0000 (12:57 +0200)
Topology objects(widgets,controls) with different index value should be grouped
into different blocks and the block headers contain the index value.

Signed-off-by: Fuwei Tang <fuweix.tang@intel.com>
Reviewed-by: Mengdong Lin <mengdong.lin@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
src/topology/builder.c

index dcd9e2a1cb4190c4025fa14a85b3e2d0d558d30e..ca5cbe1a3860545db7a1b2a049ccb559764ad6ba 100644 (file)
@@ -86,58 +86,66 @@ static int write_block_header(snd_tplg_t *tplg, unsigned int type,
 static int write_elem_block(snd_tplg_t *tplg,
        struct list_head *base, int size, int tplg_type, const char *obj_name)
 {
-       struct list_head *pos;
-       struct tplg_elem *elem;
-       int ret, wsize = 0, count = 0, vendor_type;
+       struct list_head *pos, *sub_pos, *sub_base;
+       struct tplg_elem *elem, *elem_next;
+       int ret, wsize = 0, total_size = 0, count = 0, block_size = 0;
 
-       /* count number of elements */
-       list_for_each(pos, base)
-               count++;
-       if (!count)
-               return 0;
-
-       /* write the header for this block */
-       elem = list_entry(base->next, struct tplg_elem, list);
-       vendor_type = elem->vendor_type;
-
-       ret = write_block_header(tplg, tplg_type, vendor_type,
-               tplg->version, 0, size, count);
-       if (ret < 0) {
-               SNDERR("error: failed to write %s block %d\n",
-                       obj_name, ret);
-               return ret;
-       }
-
-       /* write each elem to block */
+       sub_base = base;
        list_for_each(pos, base) {
-
+               /* find elems with the same index to make a block */
                elem = list_entry(pos, struct tplg_elem, list);
+               elem_next = list_entry(pos->next, struct tplg_elem, list);
+               block_size += elem->size;
+               count++;
 
-               /* compound elems have already been copied to other elems */
-               if (elem->compound_elem)
-                       continue;
-
-               if (elem->type != SND_TPLG_TYPE_DAPM_GRAPH)
-                       verbose(tplg, " %s '%s': write %d bytes\n",
-                               obj_name, elem->id, elem->size);
-               else
-                       verbose(tplg, " %s '%s': write %d bytes\n",
-                               obj_name, elem->route->source, elem->size);
-
-               count = write(tplg->out_fd, elem->obj, elem->size);
-               if (count < 0) {
-                       SNDERR("error: failed to write %s %d\n",
-                               obj_name, ret);
-                       return ret;
+               if ((pos->next == base) || (elem_next->index != elem->index)) {
+                       /* write header for the block */
+                       ret = write_block_header(tplg, tplg_type, elem->vendor_type,
+                               tplg->version, elem->index, block_size, count);
+                       if (ret < 0) {
+                               SNDERR("error: failed to write %s block %d\n",
+                                       obj_name, ret);
+                               return ret;
+                       }
+
+                       /* write elems for the block */
+                       list_for_each(sub_pos, sub_base) {
+                               elem = list_entry(sub_pos, struct tplg_elem, list);
+                               /* compound elems have already been copied to other elems */
+                               if (elem->compound_elem)
+                                       continue;
+
+                               if (elem->type != SND_TPLG_TYPE_DAPM_GRAPH)
+                                       verbose(tplg, " %s '%s': write %d bytes\n",
+                                               obj_name, elem->id, elem->size);
+                               else
+                                       verbose(tplg, " %s '%s': write %d bytes\n",
+                                               obj_name, elem->route->source, elem->size);
+
+                               wsize = write(tplg->out_fd, elem->obj, elem->size);
+                               if (wsize < 0) {
+                                       SNDERR("error: failed to write %s %d\n",
+                                               obj_name, ret);
+                                       return ret;
+                               }
+
+                               total_size += wsize;
+                               /* get to the end of sub list */
+                               if (sub_pos == pos)
+                                       break;
+                       }
+                       /* the last elem of the current sub list as the head of 
+                       next sub list*/
+                       sub_base = pos;
+                       count = 0;
+                       block_size = 0;
                }
-
-               wsize += count;
        }
 
        /* make sure we have written the correct size */
-       if (wsize != size) {
+       if (total_size != size) {
                SNDERR("error: size mismatch. Expected %d wrote %d\n",
-                       size, wsize);
+                       size, total_size);
                return -EIO;
        }