-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers: video: "remote-endpoint" does nothing #72311
Comments
I believe this can greatly simplify examples of video applications on Zephyr, as well as an enabler for implementing an USB Video Class (UVC) where all it takes to implement it is passing a camera sensor phandle on the device tree like done for CDC ACM:
Drivers could want to affect their source (i.e. image sensor) and sinks (i.e. display):
Affected open PRs: |
I am willing to bring an implementation for it, but wanted to discuss it early. The strategy sketched does not seems to break the devicetree or drivers! => I will provide a real RFC at some point, you can wait for it |
@CharlesDias This might interest you. |
V4L2 needs 2 kinds of interface:
Zephyr only needs one interface, merged between the two: sub-devices are the final user API:
So no implicit "driver" for a pipeline: we need to use the same mechanism as the one to interconnect drivers: DeviceTree. No DeviceTree involved to select an endpopint on Zephyr though:
No "OUT" on the DeviceTree, though, only an "IN": zephyr/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts Lines 280 to 282 in 638f1d5
The "OUT" is actually implicit, only defined inside the driver as a sanity check: zephyr/drivers/video/video_mcux_csi.c Lines 266 to 268 in 638f1d5
And no way to say "2nd MIPI input" with the enum: zephyr/include/zephyr/drivers/video.h Lines 126 to 131 in 638f1d5
Zephyr already comes with an API to refer things defined in the DeviceTree. => Should we replace |
One way that could be used to replace the This permits to build a /**
* @brief Get a node identifier of a node's remote-endpoint connection.
*
* This will follow the phandle pointed to by the remote-endpoint property.
* This requires a port child with an endoint child, and the endpoint holding
* the remote-endpoint property.
*
* @param node_id node identifier
* @param port name of the port to follow, port_0 for port@0
* @param endpoint name of the endpoint to follow, endpoint_0 for endpoint@0
* @return node ID of the endpoint linked to the given port and endpoint
*/
#define VIDEO_DT_REMOTE_ENDPOINT(node_id, port, endpoint) \
DT_PROP(DT_CHILD(DT_CHILD(node_id, port), endpoint), remote_endpoint)
/**
* @brief Get a device reference for the node identifier's remote endpoint
*
* This will follow the phandle pointed to by the remote-endpoint property.
*
* @param node_id node identifier of a remote-endpoint phandle property
*
* @see VIDEO_DT_REMOTE_ENDPOINT()
*/
#define VIDEO_DT_SPEC_GET(node_id) \
{ \
.dev = DEVICE_DT_GET(DT_GPARENT(node_id)), \
.port = DT_PROP_OR(DT_PARENT(node_id), reg, 0), \
.endpoint = DT_PROP_OR(node_id, reg, 0) \
}
/**
* @brief Video Device Tree endpoint identifier
*
* Identify a particular port and particular endpoint of a video device,
* providing all the context necessary to act upon a video device, via one of
* its endpoint.
*/
struct video_dt_spec {
/** Device instance of the remote video device to communicate with. */
const struct device *dev;
/** Port Device Tree address, the reg property of the port. */
uint16_t port;
/** Endpoint Device Tree address, the reg property of the endpoint. */
uint16_t endpoint;
}; => A pull request will proposed when the new API is complete |
If keeping This can be solved by sharing a FIFO between the two sides of the API (source and sink):
Example: a "funnel" driver/application that selects one active source among many, and pass it to down: k_fifo_put(&sink_fifo, k_fifo_get(&active_source_fifo, K_FOREVER)); => API for data movement was found, I will open a separate RFC for it |
Here is an illustration of a complex pipeline, so that it is easier to review the data flow.
FIFOs are placed between each driver, so that there is no need to decide who should enqueue and who should implement an enqueue API, which would get in the way if an application (main.c) should be interleaved. ImageSensor (via MIPI DMA peripheral) come in different format and size, so one of them is resized and pixel format is converted. YUYV2RGB re-uses the same buffer Resizer frees and allocates a new buffer because the buffer size is different between source/destination. Selector is a pure software implementation that decides which input buffer should wait and which input buffer can be passed down unmodified. Display can implement a video API, or eventually be a generic driver to convert between video and display API. |
There is already a subsystem in Zephyr in charge of handling I/O of many devices efficiently in Zephyr: RTIO. The problem it has (and that the Video driver API also has) is that it is only meant for communication between the application and a device driver, rather than moving data directly from driver to driver: Linux's Maybe it is possible to implement As soon as one device completes a TX request, the remote-endpoint's device would receive an RX request: I/O directly between video devices.
=> |
Currently, only the Video driver uses Linux has this set of generic APIs for Chaining the calls like this: |
Follow-up issue and pull-request series: |
As seen on #76798, it is possible to implement an UVC class without introducing |
This is part of a series of proposal for incremental changes for the Video API:
Is your enhancement proposal related to a problem? Please describe.
In the video drivers, the device tree declaration Linux-style
remote-endpoint
is used nowhere. It is up to the user to connect drivers together in a way that hopefully matches the devicetree.Describe the solution you'd like
<&phandle>
to make the drivers communicate with each other. For instance how it is done in https://github.com/zephyrproject-rtos/zephyr/blob/main/tests/subsys/usb/uac2/app.overlay#L53 to allow connecting a different video source by changing the device tree.Describe alternatives you've considered
Additional context
My final goal is to implement the USB Video Class (UVC) to implement USB3 webcams with Zephyr.
Currently in Zephyr like in other RTOS, it is up to the user to glue video devices together.
remote-endpoint:
is ignored by everything:video_common.c
,video.h
,main.c
,video_sw_generator.c
Using the devicetree information to let the driver perform I/O would allow:
Thank you for this wonderful Video4Zephyr lean and mean driver API introduced in 2019! Glad to see more interest coming into it after a few years!
[EDIT: typo and wording]
The text was updated successfully, but these errors were encountered: