media_graph_walk_next

struct media_entity {
    struct media_gobj graph_obj;    /* must be first field in struct */
    const char *name;
    enum media_entity_type obj_type;
    u32 function;
    unsigned long flags;

    u16 num_pads;
    u16 num_links;
    u16 num_backlinks;
    int internal_idx;

    struct media_pad *pads; //重点看这里,entity中的所有pad
    struct list_head links;      //重点看这里,entity与别的entity之间的所有link

    const struct media_entity_operations *ops;

    int stream_count;
    int use_count;

    struct media_pipeline *pipe;

    union {
        struct {
            u32 major;
            u32 minor;
        } dev;
    } info;
};

/**
 * struct media_graph - Media graph traversal state
 *
 * @stack:        Graph traversal stack; the stack contains information
 *            on the path the media entities to be walked and the
 *            links through which they were reached.
 * @ent_enum:        Visited entities
 * @top:        The top of the stack
 */
struct media_graph {
    struct {
        struct media_entity *entity; 
        struct list_head *link;    //重点看这里,每个entity有多个link,根据这个变量进行深度分叉判断
    } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH];

    struct media_entity_enum ent_enum; //重点看这里,用来判断某个entity是否被放入栈中
    int top;
};

struct media_entity *media_graph_walk_next(struct media_graph *graph)
{
    struct media_entity *entity;

    if (stack_top(graph) == NULL)
        return NULL;

    /*
     * Depth first search. Push entity to stack and continue from
     * top of the stack until no more entities on the level can be
     * found.
     */
    while (link_top(graph) != &stack_top(graph)->links) //判断这个分支上有没有被遍历完
        media_graph_walk_iter(graph);

    entity = stack_pop(graph);
    dev_dbg(entity->graph_obj.mdev->dev,
        "walk: returning entity '%s'\n", entity->name);

    return entity;
}

static void media_graph_walk_iter(struct media_graph *graph)
{
    struct media_entity *entity = stack_top(graph);
    struct media_link *link;
    struct media_entity *next;

    link = list_entry(link_top(graph), typeof(*link), list);

    /* The link is not enabled so we do not follow. */
    if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
        link_top(graph) = link_top(graph)->next;
        dev_dbg(entity->graph_obj.mdev->dev,
            "walk: skipping disabled link '%s':%u -> '%s':%u\n",
            link->source->entity->name, link->source->index,
            link->sink->entity->name, link->sink->index);
        return;
    }

    /* Get the entity in the other end of the link . */
    next = media_entity_other(entity, link);

    /* Has the entity already been visited? */
    if (media_entity_enum_test_and_set(&graph->ent_enum, next)) { //如果已经被遍历过了,换节点上另一个分支,然后返回,下次再进来就是下个分支
        link_top(graph) = link_top(graph)->next;
        dev_dbg(entity->graph_obj.mdev->dev,
            "walk: skipping entity '%s' (already seen)\n",
            next->name);
        return;
    }

    /* Push the new entity to stack and start over. */   //如果没被遍历,往更深一层
    link_top(graph) = link_top(graph)->next;
    stack_push(graph, next);
    dev_dbg(entity->graph_obj.mdev->dev, "walk: pushing '%s' on stack\n",
        next->name);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值