-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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: add format utilities to improve usability #79476
base: main
Are you sure you want to change the base?
drivers: video: add format utilities to improve usability #79476
Conversation
include/zephyr/drivers/video.h
Outdated
/** | ||
* @brief Print formatter to use in printf() style format strings. | ||
* | ||
* This prints a video format in the form of "{width}x{height} {fourcc}" format |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From macro below, should be "{fourcc} {width}x{height}" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I changed it after seeing how v4l2-ctl
and the examples show the formats but forgot to update thedoc. I will adjust it along with other doc fixups.
Thank you for pointing it!
29a4758
to
6c21f48
Compare
c021247
to
d541c10
Compare
force-push: CI fixes |
d541c10
to
a9587f1
Compare
force-push: use |
12ca486
to
75345f9
Compare
force-push: split |
75345f9
to
ac056cf
Compare
ac056cf
to
390f9dc
Compare
force-push:
This also propagate the changes to the various files involved. |
390f9dc
to
777832b
Compare
force-push:
|
Since #76475 is merged, you will need some rebase. Overall, LGTM. |
777832b
to
c80bcff
Compare
force-push:
About the naming of |
include/zephyr/drivers/video.h
Outdated
/** | ||
* 5-bit blue followed by 6-bit green followed by 5-bit red, in little-endian over two bytes. | ||
* @verbatim | ||
* | gggRrrrr | BbbbbGgg | ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I documented the BGR565-LE instead of RGB565-LE, but let's resolve the RGB565 discussion first...
#79996
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, this is the RGB565, even if R is on the right in the MSB first representation, it is at BIT(0)
, and seems to be what is expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is BGR565-LE. Per my understanding, for RGB565, R always needs to be presented first.
In BE, it begins at bit 15 while in LE it begins at bit 8 (because of byte order). I don't understand why here, R begin at bit 4 (in the middle of the byte) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Endianess is about the byte address order (a chunk of 8 bits), not about the bit order (MSB or LSB first), neither a chunk of 4 bits.
To get it simple, I think we can begin with BE first. An RGB565 in BE is represented as two bytes with the most significant byte stored first in memory address.
- RRRRRGGG(1st byte in memory) then GGGBBBBB(2nd byte in memory)
At this point, I think we all agree with this. Then, LE is basically just reversing the byte order (only for a multi-byte value), i.e. lower significant bytes get lower addresses. So it becomes:
- GGGBBBBB(1st byte in memory) then RRRRRGGG(2nd byte in memory)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I documented here follows Libav and the LWN article, from where I had the representation:
If representing the format in MSBit first, B is on the left.
Big-endian, MSBit first:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
B b b b b G g g g g g R r r r r
little-endian, MSBit first:
7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8
g g g R r r r r B b b b b G g g
If representing the format in LSBit first, R is on the left. This representation is confusing when mixing bit-endianness and byte endianness.
big-endian, LSBit first:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
r r r r R g g g g g G b b b b B
little-endian, LSBit first:
8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7
g g G b b b b B r r r r R g g g
At this point, I think we all agree with this.
I am trying to understand what the major implementations did agree... and they seem to differ? I am really not sure as they are around since a lot of time. ^_^' Can we settle that the hardware is right to break the tie?
Looking at #79996 (comment) it looks like red in MSBit position wins.
A test pattern generator looks "ok" (stripes of color) even with the wrong color order, and the LWN article is just text, not code that was checked against hardware. Some deeply anchored confusion in tech it seems!
Thank you for your patience and sorry for the confusion.
Committing the fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I believe strongly that the LWN article is WRONG. Personally, If I need a reference, I am usually based on the kernel document. The kernel document of the latest Linux release describes the same layout about the RGB565-LE as I pointed in above comment:
https://www.kernel.org/doc/html/v6.11/userspace-api/media/v4l/pixfmt-rgb.html
9f922fe
to
cc79ee7
Compare
force-push:
|
cc79ee7
to
5e8e31d
Compare
force-push:
|
5e8e31d
to
e95d1c6
Compare
e95d1c6
to
7069a8b
Compare
Introduce a new text documentation of the video formats, describing every bit, gives the position of the most significant bit, outline how it is cut in bytes, and show the pixel segmentation. Extra care is taken for the RGB565 which requies paying attention to the bit endianess as well as the byte endianess. Signed-off-by: Josuah Demangeon <[email protected]>
Rename video_fourcc() to VIDEO_FOURCC(), differing from the Linux implementation, but more compliant with the coding style. Also introduce a VIDEO_FOURCC_FROM_STR() to generate a FOURCC format code out of a 4-characters string. Signed-off-by: Josuah Demangeon <[email protected]>
This was present in the form of video_pix_fmt_bpp() inside ST and NXP drivers, and was returning the number of bytes, which does not allow support for 10-bits, 4-bits or non-byte aligned video formats. The helper leverages the VIDEO_PIX_FMT_*_BITS macros. Signed-off-by: Josuah Demangeon <[email protected]>
7069a8b
to
97746bd
Compare
*/ | ||
static inline unsigned int video_pix_fmt_bpp(uint32_t pixfmt) | ||
static inline unsigned int video_bits_per_pixel(uint32_t pixfmt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need migration guide for the dropped API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is not an API. It's just an utility / helper function. Do we also need migration guide for this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps I misunderstood ... It seems all functions in a .h are considered as APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anything that's part of a public header and not explicitly marked as internal is to be considered de-facto API :) (see e.g. https://docs.zephyrproject.org/latest/doxygen/html/group__video__interface.html#gabc1c6fd4e13480b269cac9f224ee1c5b)
You may want to review the current API and look for those utilities you folks would like to mark as internal (but that would still require a heads-up to users in the form of a migration guide so that they are aware they might want to move away from using the now internal API).
FWIW it looks to me as if it would be fine to actually keep this as a public API though, it's a utility that might be useful for any user, not just in-tree drivers..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it should not be internal and can be used by any user. Thanks
Introduce several enhancements for dealing with the video API:
note: this image is wrong for RGB565 format!
But in a text-based format to be easy to maintain and colorblindness-friendly, and easy to
grep
through[EDIT: fixed version below]:Add a printf() formatter like stdint.h's PRIu32:
printf("video format: " PRIvfmt, PRIvfmt_arg(&fmt));
This is present elsewhere on Zephyr
Convert
video_fourcc()
toVIDEO_FOURCC()
and make it visible to the documentation, now that it is used outside of the header itself.Add a
VIDEO_FOURCC_FROM_STR()
to easily convert a string from i.e. Kconfig or the devicetree.Looking forward to your feedback and advises.