Skip to content
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: introduce semantics for enum endpoint_id #73009

Merged
merged 2 commits into from
Aug 24, 2024

Conversation

josuah
Copy link
Collaborator

@josuah josuah commented May 20, 2024

This is part of a series of proposal for incremental changes for the Video API:

This adds slightly new semantics for endpoint_id:

  • IN is not "the main input endpoint" anymore but "each and every input endpoint"
  • OUT is not "the main output endpoint" anymore but "each and every output endpoint"
  • ANY ALL is not "one endpoint of choice" anymore but "every single endpoint"
  • NONE is not "does not affect any interface" anymore but "affects something not bound to any interface"
  • Other values >= 0 are allowed to specify a particular interface.

@erwango
Copy link
Member

erwango commented May 20, 2024

@CharlesDias FYI

@loicpoulain
Copy link
Collaborator

loicpoulain commented May 20, 2024

would it make sense to have a bit assigned to OUT/IN in the ID and corresponding macro, so that we can have some type enforcement, like VIDEO_EP_IN(index) VIDEO_EP_OUT(index), e.g:
VIDEO_EP_IN(0)
VIDEO_EP_OUT(0)
VIDEO_EP_OUT(ANY)
...
VIDEO_EP_IS_OUT(ep_id)

@josuah
Copy link
Collaborator Author

josuah commented May 20, 2024

It could be an extra reg index, making the depth field mandatory, with 0 = Out and 1 = In.

(A) This can be a nibble:
i.e. endpoint 3 out -> endpoint@30 { reg = <0x3 0>; };
i.e. endpoint 1 in -> endpoint@11 { reg = <0x1 1>; };
i.e. port 7 endpoint 2 out -> endpoint@720 { reg = <0x7 0x2 0>; };

(B) This can be a byte:
i.e. endpoint 3 out -> endpoint@0300 { reg = <0x03 0>; };
i.e. endpoint 1 in -> endpoint@0101 { reg = <0x01 0>; };
i.e. port 7 endpoint 2 out -> endpoint@070200 { reg = <0x07 0x02 0>; };

(C) This can be a nibble after bytes:
i.e. endpoint 3 out -> endpoint@030 { reg = <0x03 0>; };
i.e. endpoint 1 in -> endpoint@011 { reg = <0x01 0>; };
i.e. port 7 endpoint 2 out -> endpoint@07020 { reg = <0x07 0x02 0>; };

This can also be hidden behind a macro on the reg:
i.e. endpoint 3 out -> endpoint@030 { reg = <0x03 VIDEO_ID_OUT>; };
i.e. endpoint 1 in -> endpoint@011 { reg = <0x01 VIDEO_ID_IN>; };
i.e. port 7 endpoint 2 out -> endpoint@07020 { reg = <0x07 0x02 VIDEO_ID_OUT>; };

With the matching macro definitions in C, i.e. for a nibble:
i.e. endpoint 3 out -> VIDEO_EP_OUT(3)
i.e. endpoint 1 in -> VIDEO_EP_IN(1)
i.e. port 7 endpoint 2 out -> VIDEO_EP_OUT(0x72) or VIDEO_EP_OUT(0x0702)

[EDIT: selected option (A)]

@josuah josuah force-pushed the pr-video-endpoint-id-semantics branch 3 times, most recently from 8229acb to 2bbfd19 Compare May 20, 2024 23:57
@josuah
Copy link
Collaborator Author

josuah commented May 21, 2024

I changed VIDEO_EP_IN/OUT(ANY) to VIDEO_EP_ANY_IN/OUT as was easier to implement and still works with VIDEO_EP_IS_IN/OUT().

VIDEO_EP_IS_IN/OUT(VIDEO_EP_ANY) is returning true for both IN/OUT.

Extra VIDEO_DIR_IN/OUT/ANY/NONE were also introduced to avoid magic numbers through the source.

@dleach02
Copy link
Member

@josuah please address the CI issues

@josuah josuah marked this pull request as draft May 23, 2024 15:00
@josuah
Copy link
Collaborator Author

josuah commented May 23, 2024

@josuah please address the CI issues

Yes, some more API changes are needed. converting back to a draft, sorry for the burden involved.

@@ -121,7 +121,16 @@ static int video_mcux_csi_set_fmt(const struct device *dev, enum video_endpoint_
unsigned int bpp = video_pix_fmt_bpp(fmt->pixelformat);
status_t ret;

if (!bpp || ep != VIDEO_EP_OUT) {
switch (ep) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That repeated pattern would probably deserve a macro or function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will propose something in another PR when there will be a pretext to touch to the video drivers again (to limit review burden), but it seems possible to use macros with the new scheme:

#define VIDEO_EP_OUT_SELECTED(ep, match) \
        ((ep) == VIDEO_EP_OUT || (ep) == VIDEO_EP_ALL || (ep) == (match))

#define VIDEO_EP_IN_SELECTED(ep, match) \
        ((ep) == VIDEO_EP_IN || (ep) == VIDEO_EP_ALL || (ep) == (match))

/* Filter away, 0x00 used when only 1 endpoint supported */

if (bpp == 0 || !VIDEO_EP_OUT_SELECTED(ep, 0x00)) {
       return -EINVAL;
}

/* Matches endpoint 0x00 or 0x01 or 0x02 */

if (VIDEO_EP_OUT_SELECTED(ep, 0x00)) {
       work_on_ep0();
}

if (VIDEO_EP_OUT_SELECTED(ep, 0x01)) {
       work_on_ep1();
}

if (VIDEO_EP_IN_SELECTED(ep, 0x02)) {
       work_on_ep2();
}

/* If ep == VIDEO_EP_ALL, then all endpoint are enacted... this works */

@josuah josuah force-pushed the pr-video-endpoint-id-semantics branch from 2bbfd19 to 86a99a2 Compare July 28, 2024 00:17
@josuah
Copy link
Collaborator Author

josuah commented Jul 28, 2024

Here is a simpler, less intrusive attempt: just give negative values to VIDEO_EP_IN VIDEO_EP_OUT etc.
Individual interface numbers can still be given on enum video_endpoint_id ep arguments.

@@ -449,7 +453,7 @@ static inline int video_stream_stop(const struct device *dev)
}

ret = api->stream_stop(dev);
video_flush(dev, VIDEO_EP_ANY, true);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only place I have found VIDEO_EP_ANY used.
If video_endpoint_id is a direction, "ANY" makes a lot of sense, but if allowing it to be an endpoint number, "ALL" seems less ambiguous (i.e. here flushing all endpoints rather than flushing endpoints for any direction).

Comment on lines 127 to 134
/** Targets some part of the video device not bound to an endpoint */
VIDEO_EP_NONE = -1,
/** Targets all input or output endpoints of the device */
VIDEO_EP_ALL = -2,
/** Targets all input endpoints of the device */
VIDEO_EP_IN = -3,
/** Targets all output endpoints of the device */
VIDEO_EP_OUT = -4,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not encode any direction information into the video_endpoint_id, which allow using endpoint IDs exactly as in the manufacturer datasheet. Does it make sense?

@@ -155,7 +155,7 @@ static int video_mcux_csi_set_fmt(const struct device *dev, enum video_endpoint_
status_t ret;
struct video_format format = *fmt;

if (!bpp || ep != VIDEO_EP_OUT) {
if (bpp != 0 || (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL)) {
Copy link
Collaborator Author

@josuah josuah Jul 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing !bpp to bpp != 0 in the process, let me know if I should avoid it.
[EDIT: sorry I should pay more attention! !bpp is bpp == 0!]

@josuah josuah marked this pull request as ready for review July 28, 2024 00:34
@josuah josuah requested a review from loicpoulain July 28, 2024 00:34
@josuah josuah force-pushed the pr-video-endpoint-id-semantics branch from 86a99a2 to bea302c Compare July 28, 2024 17:52
This define the enum values so that they never clash with custom
endpoint IDs passed numerically, for devices that supports more
than one IN or OUT enpoint.

This also documents semantics for VIDEO_EP_IN/OUT/ALL/NONE,
while renaming VIDEO_EP_ANY to VIDEO_EP_ALL to remove the
ambiguity when there are several IN and/or OUT endpoints.

Signed-off-by: Josuah Demangeon <me@josuah.net>
@josuah
Copy link
Collaborator Author

josuah commented Aug 16, 2024

As pointed out by @XenuIsWatching, one use-case would be:

Some Cameras may be a bit 'advanced', and be able to stream out multiple frame types out at once such as a IR image along with a RGB image, I'm not sure how that would be currently implemented to select which frame type to enable or set a ctrl for. Maybe enum video_endpoint_id ep could be used for it? -- #72959 (comment)

Something like this could work after this gets merged:

/* Configure format RGB on 0 and InfraRed on 1 */
video_set_format(video_dev, 0, &fmt_rgb);
video_set_format(video_dev, 1, &fmt_ir);

/* Enqueue transfers separately to endpoints 0 and 1 */
video_enqueue(video_dev, 0, &vbuf_rgb);
video_enqueue(video_dev, 1, &vbuf_ir);

/* Enqueue transfers on both endpoints at the same time in the same feed */
video_enqueue(video_dev, VIDEO_EP_OUT, &vbuf_either);

Maybe a flag would need to be added to struct video_buffer to remind which endpoint this was coming from, but this would be for another PR.

@dleach02
Copy link
Member

Folks, I'm the assignee because I guess I won the files touched lottery. I need some of the relevant subject matter experts to weigh in and give their +1/-1 so we can move this PR along.

loicpoulain
loicpoulain previously approved these changes Aug 20, 2024
Copy link
Collaborator

@loicpoulain loicpoulain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@josuah josuah force-pushed the pr-video-endpoint-id-semantics branch from bea302c to 7745d17 Compare August 20, 2024 10:58
The current video drivers did not allow VIDEO_EP_ALL to be selected,
as used by video_stream_stop().

This adds the VIDEO_EP_ALL to each video driver that filtered endpoints.

Signed-off-by: Josuah Demangeon <me@josuah.net>
@josuah
Copy link
Collaborator Author

josuah commented Aug 20, 2024

Sorry, I did a beginner mistake by converting !bpp to bpp != 0 instead of bpp == 0.
I will pay more attention in the future.
@dleach02 @loicpoulain could you review once again?

@dleach02
Copy link
Member

dleach02 commented Aug 23, 2024

LGTM

@loicpoulain can you give this a +1 then?

@erwango and ST driver was also touched so +1?

@nashif nashif merged commit c0f8658 into zephyrproject-rtos:main Aug 24, 2024
23 checks passed
@josuah josuah deleted the pr-video-endpoint-id-semantics branch August 24, 2024 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Video Video subsystem platform: NXP Drivers NXP Semiconductors, drivers platform: STM32 ST Micro STM32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants