media: mc: entity: Add pad iterator for media_pipeline
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Wed, 21 Dec 2022 09:33:37 +0000 (10:33 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 6 Feb 2023 07:31:51 +0000 (08:31 +0100)
Add a media_pipeline_for_each_pad() macro to iterate over pads in a
pipeline. This should be used by driver as a replacement of the
media_graph_walk API, as iterating over the media_pipeline uses the
cached list of pads and is thus more efficient.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/mc/mc-entity.c
include/media/media-entity.h

index 6ec2092d7f803a82754c836c6e7f5d320462505c..83797d6b1753f5f2b4aabe6b6e718095813e4911 100644 (file)
@@ -945,6 +945,24 @@ out:
 }
 EXPORT_SYMBOL_GPL(media_pipeline_alloc_start);
 
+struct media_pad *
+__media_pipeline_pad_iter_next(struct media_pipeline *pipe,
+                              struct media_pipeline_pad_iter *iter,
+                              struct media_pad *pad)
+{
+       if (!pad)
+               iter->cursor = pipe->pads.next;
+
+       if (iter->cursor == &pipe->pads)
+               return NULL;
+
+       pad = list_entry(iter->cursor, struct media_pipeline_pad, list)->pad;
+       iter->cursor = iter->cursor->next;
+
+       return pad;
+}
+EXPORT_SYMBOL_GPL(__media_pipeline_pad_iter_next);
+
 /* -----------------------------------------------------------------------------
  * Links management
  */
index 47863e8fde7b8c44790a218209ccb04f561b47f6..11351579a4d237b9795b2ff6588e594b7869e9c9 100644 (file)
@@ -130,6 +130,15 @@ struct media_pipeline_pad {
        struct media_pad *pad;
 };
 
+/**
+ * struct media_pipeline_pad_iter - Iterator for media_pipeline_for_each_pad
+ *
+ * @cursor: The current element
+ */
+struct media_pipeline_pad_iter {
+       struct list_head *cursor;
+};
+
 /**
  * struct media_link - A link object part of a media graph.
  *
@@ -1165,6 +1174,26 @@ void media_pipeline_stop(struct media_pad *pad);
  */
 void __media_pipeline_stop(struct media_pad *pad);
 
+struct media_pad *
+__media_pipeline_pad_iter_next(struct media_pipeline *pipe,
+                              struct media_pipeline_pad_iter *iter,
+                              struct media_pad *pad);
+
+/**
+ * media_pipeline_for_each_pad - Iterate on all pads in a media pipeline
+ * @pipe: The pipeline
+ * @iter: The iterator (struct media_pipeline_pad_iter)
+ * @pad: The iterator pad
+ *
+ * Iterate on all pads in a media pipeline. This is only valid after the
+ * pipeline has been built with media_pipeline_start() and before it gets
+ * destroyed with media_pipeline_stop().
+ */
+#define media_pipeline_for_each_pad(pipe, iter, pad)                   \
+       for (pad = __media_pipeline_pad_iter_next((pipe), iter, NULL);  \
+            pad != NULL;                                               \
+            pad = __media_pipeline_pad_iter_next((pipe), iter, pad))
+
 /**
  * media_pipeline_alloc_start - Mark a pipeline as streaming
  * @pad: Starting pad