-
Notifications
You must be signed in to change notification settings - Fork 393
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
New planar pixel formats: Y_U_V24
/Y_U_V16
/Y_U_V12
- _LimitedRange
/FullRange
#7666
Conversation
Y_U_V24
/Y_U_V16
/Y_U_V12
_LimitedRange
/FullRange
Y_U_V24
/Y_U_V16
/Y_U_V12
- _LimitedRange
/FullRange
Y_U_V24
/Y_U_V16
/Y_U_V12
- _LimitedRange
/FullRange
Y_U_V24
/Y_U_V16
/Y_U_V12
- _LimitedRange
/FullRange
Deployed docs
|
92cfcda
to
a25cc74
Compare
/// This uses limited range YUV, i.e. Y is expected to be within [16, 235] and U/V within [16, 240]. | ||
/// | ||
/// First comes entire image in Y in one plane, followed by the U and V planes. | ||
Y_U_V24_LimitedRange = 39, |
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.
the ordering in respect to the numbers in here is rather dubious
I tried to order this logically rather than by enum numbers (which are derived from Ocean). But that makes it hard for the codes beyond Ocean :/
@@ -31,6 +31,7 @@ _deps | |||
# Python build artifacts: | |||
__pycache__ | |||
*.pyc | |||
*.pyd |
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.
not sure why this didn't come up before, but while working on this I accidentally pushed a .pyd file which wasn't on the ignore list. better safe than sorry (again), so I added this here
crates/viewer/re_renderer/src/resource_managers/yuv_converter.rs
Outdated
Show resolved
Hide resolved
…. lotsa fixes etc. on the way
squasing and deleting this branch should be enough to remove it from history
f276ba0
to
f296688
Compare
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.
Niiiice!
/// | ||
/// This uses entire range YUV, i.e. Y is expected to be within [0, 255]. | ||
/// (as opposed to "limited range" YUV as used e.g. in NV12). | ||
Y8_FullRange = 30, |
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.
At some point it would be nice if LimitedRange/FullRange
was its own component. Maybe.
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.
yeah... maybe. See PR description 😄
// TODO(andreas): This shouldn't be ColorModel::RGB, but our YUV converter can't do anything else right now. | ||
Self::Y8_LimitedRange | Self::Y8_FullRange => ColorModel::RGB, |
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.
Can you elaborate on this?
You mean the GPU always outputs RGB, so we consider Y
to be a very stupid way of compressing RGB?
What is color_model
used for? Is there anything that will break due to this "lie"?
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.
(will add to comment)
GPU doesn't have to always output RGB, but having it sometimes output R(8) specifically for the YUV converter requires me to do more bookkeeping (needs a new renderpipeline and I expect other ripples) which I just don't want to do right now.
We do use this property mostly for things in the hover logic afaik.
very stupid way of compressing RGB
hm well. no. That's just because our gpu conversion pipeline is stupid atm. But it still doesn't take up extra CPU memory and GPU textures are only held as long as they are in use (image cache for instance doesn't cache gpu transfer step!)
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.
a fun way to see this short-lived-cacheing in action is to observe what happens when you change the shader code in yuv_converter.wgsl
in a debug build:
It will reload the shader which has no effect unless you show and hide the respective space views at which point the shader runs again.
(was very very very useful for developing that shader! I ended up having a separate dummy-recording that I switched to and back :D)
/// Returns true if the format is a YUV format using | ||
/// limited range YUV. | ||
/// | ||
/// I.e. for 8bit data, Y is valid in [16, 235] and U/V [16, 240], rather than 0-255. | ||
pub fn is_limited_yuv_range(&self) -> bool { |
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 would be nicer as fn yuv_range(&self) -> Option<YuvRange>
so we can return None
for non-yuv formats in the future. Also, enums is nicer than bools.
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.
yeah but I didn't want to introduce this enum a third time (1x each in re_renderer, re_types and re_video -.-)
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.
If it was a good idea in the other places, why isn't it a good idea here?
Some(_) => { | ||
// We do the lazy thing here since we convert everything to RGB8 right now anyways. |
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.
Maybe it would be smart to prepare ourself for HDR though?
Some(_) => { | |
// We do the lazy thing here since we convert everything to RGB8 right now anyways. | |
Some(pixel_format) => { | |
let max_value = pixel_format.max_component_value(); | |
… |
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.
Unfortunately this isn't about the max component value of the pixel format but rather what we show which right now is a bit different. max_component_value would be an interesting one also for limited range YUV stuff 🤔
I'm leaving an additional note on this for the next person!
scripts/ci/main.py
Outdated
def bgra2y_u_v24(bgra: Any, full_range: bool) -> np.ndarray: | ||
if full_range: | ||
yvu = cv2.cvtColor(bgra, cv2.COLOR_BGR2YCrCb) | ||
y, v, u = cv2.split(yvu) | ||
else: | ||
yuv = cv2.cvtColor(bgra, cv2.COLOR_BGR2YUV) | ||
y, u, v = cv2.split(yuv) | ||
y = np.array(y).flatten() | ||
u = np.array(u).flatten() | ||
v = np.array(v).flatten() | ||
yuv24 = np.concatenate((y, u, v)) | ||
return yuv24.astype(np.uint8) |
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.
is there no python library 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.
dunno, surely but looking and comparing this would have taken me more time than just writing it out myself
having an eye on the missing testing, but will delay a bit here in order to move on to the next thing! |
What
Adds a whole bunch of new pixel formats with limited & full range YUV variants. All of these are needed by our AV1 decoder (branch is a misnomer though, this is coming in another pr!)
Naming & categorizing these formats is quite the struggle just as expected:
If limited to YUV variants, the overall picutre becomes sharper (ironic, eh) and it's possible to specify the combinatorics in a deceptively simple pattern:
That's what is happening in
re_renderer
's YUV converter now and is very useful for writing the conversions themselves!However (!!!), in the wild names make these properties often convoluted with each other, making the categorization a lot harder. E.g. NV12 is almost always (afaik just almost) implying
LimitedRange
YUV (which is generally a common default unless you're dealing with jpeg derived data [...]).This, and the fact that we already set out with
PixelFormat
for a flat list of names, strongly compelled me to continue the current naming scheme (and Ocean's numbering as far as possible) in the user facing API. Worth revisiting in the future.The primary motivation to expose these formats right away was to be able to easily test these variants. However, I refrained from throwing color primaries into the mix here because I think they should in fact be separately defined, causing a bigger expansion of the APIs. The docs are intentionally kept vague on color space for the moment (trying hard to not further get entangled here).
(screenshot of the release checklist which is part of this pr (moved from a previous test). I manually tested the color inspection feature against a reference color picker - slight rounding errors occasionally, but they are hard to avoid since GPU/CPU don't always do the exact same thing :/)As a result, our internal processing is now fairly explicit on the matter, but the input interpretation is rather vague.
https://rerun.io/viewer/pr/7666?url=https%3A%2F%2Fstatic.rerun.io%2Frrd%2F0.19.0%2Fchroma_4688549ca3c20018fa2fb658b56482b955817b6a.rrd
Checklist
main
build: rerun.io/viewernightly
build: rerun.io/viewerCHANGELOG.md
and the migration guideTo run all checks from
main
, comment on the PR with@rerun-bot full-check
.