From 6f30903cd6aeda5d61b3fa2a0e2e11e7bfb50c1e Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 25 Jan 2011 17:46:43 +0200 Subject: Add inbound links support Store all inbound and outbound links in media_entity.links. Signed-off-by: Laurent Pinchart Signed-off-by: Todor Tomov --- main.c | 8 ++++---- media.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- media.h | 3 +++ 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/main.c b/main.c index b46affe..4bc0d39 100644 --- a/main.c +++ b/main.c @@ -229,7 +229,7 @@ static void media_print_topology_dot(struct media_device *media) continue; } - for (j = 0; j < entity->info.links; j++) { + for (j = 0; j < entity->num_links; j++) { struct media_entity_link *link = &entity->links[j]; if (link->source->entity != entity) @@ -284,7 +284,7 @@ static void media_print_topology_text(struct media_device *media) printf("\n"); - for (k = 0; k < entity->info.links; k++) { + for (k = 0; k < entity->num_links; k++) { struct media_entity_link *link = &entity->links[k]; if (link->source->entity != entity || @@ -383,7 +383,7 @@ static struct media_entity_link *parse_link(struct media_device *media, const ch *endp = end; - for (i = 0; i < source->entity->info.links; i++) { + for (i = 0; i < source->entity->num_links; i++) { link = &source->entity->links[i]; if (link->source == source && link->sink == sink) @@ -691,7 +691,7 @@ static int setup_format(struct media_device *media, const char *p, char **endp) * the remote subdev input pads, if any. */ if (pad->flags & MEDIA_PAD_FLAG_OUTPUT) { - for (i = 0; i < pad->entity->info.links; ++i) { + for (i = 0; i < pad->entity->num_links; ++i) { struct media_entity_link *link = &pad->entity->links[i]; struct v4l2_mbus_framefmt remote_format; diff --git a/media.c b/media.c index 0ec5c16..b88c8c9 100644 --- a/media.c +++ b/media.c @@ -44,7 +44,7 @@ struct media_entity_pad *media_entity_remote_source(struct media_entity_pad *pad if (!(pad->flags & MEDIA_PAD_FLAG_INPUT)) return NULL; - for (i = 0; i < pad->entity->info.links; ++i) { + for (i = 0; i < pad->entity->num_links; ++i) { struct media_entity_link *link = &pad->entity->links[i]; if (!(link->flags & MEDIA_LINK_FLAG_ACTIVE)) @@ -106,7 +106,7 @@ int media_setup_link(struct media_device *media, unsigned int i; int ret; - for (i = 0; i < source->entity->info.links; i++) { + for (i = 0; i < source->entity->num_links; i++) { link = &source->entity->links[i]; if (link->source->entity == source->entity && @@ -116,7 +116,7 @@ int media_setup_link(struct media_device *media, break; } - if (i == source->entity->info.links) { + if (i == source->entity->num_links) { printf("%s: Link not found\n", __func__); return -EINVAL; } @@ -152,10 +152,11 @@ int media_reset_links(struct media_device *media) for (i = 0; i < media->entities_count; ++i) { struct media_entity *entity = &media->entities[i]; - for (j = 0; j < entity->info.links; j++) { + for (j = 0; j < entity->num_links; j++) { struct media_entity_link *link = &entity->links[j]; - if (link->flags & MEDIA_LINK_FLAG_IMMUTABLE) + if (link->flags & MEDIA_LINK_FLAG_IMMUTABLE || + link->source->entity != entity) continue; ret = media_setup_link(media, link->source, link->sink, @@ -168,6 +169,27 @@ int media_reset_links(struct media_device *media) return 0; } +static struct media_entity_link *media_entity_add_link(struct media_entity *entity) +{ + if (entity->num_links >= entity->max_links) { + struct media_entity_link *links = entity->links; + unsigned int max_links = entity->max_links * 2; + unsigned int i; + + links = realloc(links, max_links * sizeof *links); + if (links == NULL) + return NULL; + + for (i = 0; i < entity->num_links; ++i) + links[i].twin->twin = &links[i]; + + entity->max_links = max_links; + entity->links = links; + } + + return &entity->links[entity->num_links++]; +} + static int media_enum_links(struct media_device *media) { __u32 id; @@ -198,6 +220,8 @@ static int media_enum_links(struct media_device *media) for (i = 0; i < entity->info.links; ++i) { struct media_link_desc *link = &links.links[i]; + struct media_entity_link *fwdlink; + struct media_entity_link *backlink; struct media_entity *source; struct media_entity *sink; @@ -210,9 +234,18 @@ static int media_enum_links(struct media_device *media) link->sink.entity, link->sink.index); ret = -EINVAL; } else { - entity->links[i].source = &source->pads[link->source.index]; - entity->links[i].sink = &sink->pads[link->sink.index]; - entity->links[i].flags = links.links[i].flags; + fwdlink = media_entity_add_link(source); + fwdlink->source = &source->pads[link->source.index]; + fwdlink->sink = &sink->pads[link->sink.index]; + fwdlink->flags = links.links[i].flags; + + backlink = media_entity_add_link(sink); + backlink->source = &source->pads[link->source.index]; + backlink->sink = &sink->pads[link->sink.index]; + backlink->flags = links.links[i].flags; + + fwdlink->twin = backlink; + backlink->twin = fwdlink; } } @@ -251,8 +284,14 @@ static int media_enum_entities(struct media_device *media) return -errno; } + /* Number of links (for outbound links) plus number of pads (for + * inbound links) is a good safe initial estimate of the total + * number of links. + */ + entity->max_links = entity->info.pads + entity->info.links; + entity->pads = malloc(entity->info.pads * sizeof(*entity->pads)); - entity->links = malloc(entity->info.links * sizeof(*entity->links)); + entity->links = malloc(entity->max_links * sizeof(*entity->links)); if (entity->pads == NULL || entity->links == NULL) return -ENOMEM; diff --git a/media.h b/media.h index c94e60e..f299072 100644 --- a/media.h +++ b/media.h @@ -25,6 +25,7 @@ struct media_entity_link { struct media_entity_pad *source; struct media_entity_pad *sink; + struct media_entity_link *twin; __u32 flags; }; @@ -38,6 +39,8 @@ struct media_entity { struct media_entity_desc info; struct media_entity_pad *pads; struct media_entity_link *links; + unsigned int max_links; + unsigned int num_links; char devname[32]; int fd; -- cgit v1.2.3