Message ID | 20221003121852.616745-13-tomi.valkeinen@ideasonboard.com |
---|---|
State | Superseded |
Headers | show |
Series | v4l: routing and streams support | expand |
On 03.10.2022 15:18, Tomi Valkeinen wrote: >Add two helper functions to make dealing with streams easier: > >v4l2_subdev_routing_find_opposite_end - given a routing table and a pad >+ stream, return the pad + stream on the opposite side of the subdev. > >v4l2_subdev_state_get_opposite_stream_format - return a pointer to the >format on the pad + stream on the opposite side from the given pad + >stream. > >Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> >Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> >Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> >--- > drivers/media/v4l2-core/v4l2-subdev.c | 49 +++++++++++++++++++++++++++ > include/media/v4l2-subdev.h | 36 ++++++++++++++++++++ > 2 files changed, 85 insertions(+) > >diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c >index 1cea6ec750c0..7d2d8e8d3aea 100644 >--- a/drivers/media/v4l2-core/v4l2-subdev.c >+++ b/drivers/media/v4l2-core/v4l2-subdev.c >@@ -1514,6 +1514,55 @@ v4l2_subdev_state_get_stream_compose(struct v4l2_subdev_state *state, > } > EXPORT_SYMBOL_GPL(v4l2_subdev_state_get_stream_compose); > >+int v4l2_subdev_routing_find_opposite_end(const struct v4l2_subdev_krouting *routing, >+ u32 pad, u32 stream, u32 *other_pad, >+ u32 *other_stream) >+{ >+ unsigned int i; >+ >+ for (i = 0; i < routing->num_routes; ++i) { >+ struct v4l2_subdev_route *route = &routing->routes[i]; >+ >+ if (route->source_pad == pad && >+ route->source_stream == stream) { >+ if (other_pad) >+ *other_pad = route->sink_pad; >+ if (other_stream) >+ *other_stream = route->sink_stream; >+ return 0; >+ } >+ >+ if (route->sink_pad == pad && route->sink_stream == stream) { Hi, I think here you should also check that the FL_SOURCE flag is not set to make sure that sink_pad/stream are used Thanks, Dafna >+ if (other_pad) >+ *other_pad = route->source_pad; >+ if (other_stream) >+ *other_stream = route->source_stream; >+ return 0; >+ } >+ } >+ >+ return -EINVAL; >+} >+EXPORT_SYMBOL_GPL(v4l2_subdev_routing_find_opposite_end); >+ >+struct v4l2_mbus_framefmt * >+v4l2_subdev_state_get_opposite_stream_format(struct v4l2_subdev_state *state, >+ u32 pad, u32 stream) >+{ >+ u32 other_pad, other_stream; >+ int ret; >+ >+ ret = v4l2_subdev_routing_find_opposite_end(&state->routing, >+ pad, stream, >+ &other_pad, &other_stream); >+ if (ret) >+ return NULL; >+ >+ return v4l2_subdev_state_get_stream_format(state, other_pad, >+ other_stream); >+} >+EXPORT_SYMBOL_GPL(v4l2_subdev_state_get_opposite_stream_format); >+ > #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */ > > #endif /* CONFIG_MEDIA_CONTROLLER */ >diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h >index d6273ad2eea8..6f4719e28ad1 100644 >--- a/include/media/v4l2-subdev.h >+++ b/include/media/v4l2-subdev.h >@@ -1527,6 +1527,42 @@ struct v4l2_rect * > v4l2_subdev_state_get_stream_compose(struct v4l2_subdev_state *state, > unsigned int pad, u32 stream); > >+/** >+ * v4l2_subdev_routing_find_opposite_end() - Find the opposite stream >+ * @routing: routing used to find the opposite side >+ * @pad: pad id >+ * @stream: stream id >+ * @other_pad: pointer used to return the opposite pad >+ * @other_stream: pointer used to return the opposite stream >+ * >+ * This function uses the routing table to find the pad + stream which is >+ * opposite the given pad + stream. >+ * >+ * @other_pad and/or @other_stream can be NULL if the caller does not need the >+ * value. >+ * >+ * Returns 0 on success, or -EINVAL if no matching route is found. >+ */ >+int v4l2_subdev_routing_find_opposite_end(const struct v4l2_subdev_krouting *routing, >+ u32 pad, u32 stream, u32 *other_pad, >+ u32 *other_stream); >+ >+/** >+ * v4l2_subdev_state_get_opposite_stream_format() - Get pointer to opposite >+ * stream format >+ * @state: subdevice state >+ * @pad: pad id >+ * @stream: stream id >+ * >+ * This returns a pointer to &struct v4l2_mbus_framefmt for the pad + stream >+ * that is opposite the given pad + stream in the subdev state. >+ * >+ * If the state does not contain the given pad + stream, NULL is returned. >+ */ >+struct v4l2_mbus_framefmt * >+v4l2_subdev_state_get_opposite_stream_format(struct v4l2_subdev_state *state, >+ u32 pad, u32 stream); >+ > #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */ > > #endif /* CONFIG_MEDIA_CONTROLLER */ >-- >2.34.1 >
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 1cea6ec750c0..7d2d8e8d3aea 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -1514,6 +1514,55 @@ v4l2_subdev_state_get_stream_compose(struct v4l2_subdev_state *state, } EXPORT_SYMBOL_GPL(v4l2_subdev_state_get_stream_compose); +int v4l2_subdev_routing_find_opposite_end(const struct v4l2_subdev_krouting *routing, + u32 pad, u32 stream, u32 *other_pad, + u32 *other_stream) +{ + unsigned int i; + + for (i = 0; i < routing->num_routes; ++i) { + struct v4l2_subdev_route *route = &routing->routes[i]; + + if (route->source_pad == pad && + route->source_stream == stream) { + if (other_pad) + *other_pad = route->sink_pad; + if (other_stream) + *other_stream = route->sink_stream; + return 0; + } + + if (route->sink_pad == pad && route->sink_stream == stream) { + if (other_pad) + *other_pad = route->source_pad; + if (other_stream) + *other_stream = route->source_stream; + return 0; + } + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_routing_find_opposite_end); + +struct v4l2_mbus_framefmt * +v4l2_subdev_state_get_opposite_stream_format(struct v4l2_subdev_state *state, + u32 pad, u32 stream) +{ + u32 other_pad, other_stream; + int ret; + + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, + pad, stream, + &other_pad, &other_stream); + if (ret) + return NULL; + + return v4l2_subdev_state_get_stream_format(state, other_pad, + other_stream); +} +EXPORT_SYMBOL_GPL(v4l2_subdev_state_get_opposite_stream_format); + #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */ #endif /* CONFIG_MEDIA_CONTROLLER */ diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index d6273ad2eea8..6f4719e28ad1 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1527,6 +1527,42 @@ struct v4l2_rect * v4l2_subdev_state_get_stream_compose(struct v4l2_subdev_state *state, unsigned int pad, u32 stream); +/** + * v4l2_subdev_routing_find_opposite_end() - Find the opposite stream + * @routing: routing used to find the opposite side + * @pad: pad id + * @stream: stream id + * @other_pad: pointer used to return the opposite pad + * @other_stream: pointer used to return the opposite stream + * + * This function uses the routing table to find the pad + stream which is + * opposite the given pad + stream. + * + * @other_pad and/or @other_stream can be NULL if the caller does not need the + * value. + * + * Returns 0 on success, or -EINVAL if no matching route is found. + */ +int v4l2_subdev_routing_find_opposite_end(const struct v4l2_subdev_krouting *routing, + u32 pad, u32 stream, u32 *other_pad, + u32 *other_stream); + +/** + * v4l2_subdev_state_get_opposite_stream_format() - Get pointer to opposite + * stream format + * @state: subdevice state + * @pad: pad id + * @stream: stream id + * + * This returns a pointer to &struct v4l2_mbus_framefmt for the pad + stream + * that is opposite the given pad + stream in the subdev state. + * + * If the state does not contain the given pad + stream, NULL is returned. + */ +struct v4l2_mbus_framefmt * +v4l2_subdev_state_get_opposite_stream_format(struct v4l2_subdev_state *state, + u32 pad, u32 stream); + #endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */ #endif /* CONFIG_MEDIA_CONTROLLER */