raymanfx / ffimage

Foreign function image handling in Rust
MIT License
11 stars 3 forks source link

`panic` when converting to YUV420 to RGB #2

Open mfreeborn opened 1 year ago

mfreeborn commented 1 year ago

I have a raw buffer of bytes which is a YUV420 format frame from a camera, which I am trying to convert to RGB (well, ultimately to a JPEG).

My code, however, panics when I try to do the conversion, looking something like this:

let frame_data: Vec<u8> = ...; // a 1920x1080 resolution YUV420 frame, 3110400 bytes long
let view = Image::<Yuv<u8>, _>::from_buf(&frame_data, 1920, 1080).unwrap();
let mut rgb_buf = Image::<Rgb<u8>, _>::new(0, 0, 0u8);
view.convert(&mut rgb_buf); 

And then I get a really long panic message:

thread '<unnamed>' panicked at 'range end index 3116160 out of range for slice of length 3110400', /home/michael/.cargo/registry/src/github.com-1ecc6299db9ec823/ffimage-0.9.0/src/packed/convert/rayon.rs:86:27
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread '<unnamed>' panicked at 'range end index 3306240 out of range for slice of length 3110400', /home/michael/.cargo/registry/src/github.com-1ecc6299db9ec823/ffimage-0.9.0/src/packed/convert/rayon.rs:86:27
... repeated absolutely loads of times with an incrementing "range end index"

Is YUV420 conversion supported?

raymanfx commented 1 year ago

Hi, YUV420 is not supported right now. We currently only have conversion support for the packed/interleaved YUV formats, i.e. YUYV and UYVY.

YUV420 looks like a planar format - can you confirm this is the case for your image? There's a helpful format description in the VLC wiki: https://wiki.videolan.org/YUV#UYVY.

mfreeborn commented 1 year ago

Thanks for the reply - that VLC article has clarified things significantly. Yes, my format is I420 - planar.

I understand the functionality of this crate now and can make some progress.

raymanfx commented 1 year ago

Would you be interested in adding this functionality to this crate? Planar image support is something I‘ve wanted to tackle for some time now, but never really got to it.

I can draft a first implementation for you to test if you don’t want to handle it. Should not take more than a week or two - there’s some smaller fish to fry first.

raymanfx commented 1 year ago

I just pushed preliminiary YUV 420p support to the next branch: https://github.com/raymanfx/ffimage/commit/e133a7dcfd89df030a873b0168f643e13126e206. It's untested though.

next is a major rework of the code that's in master right now, but the benchmark code in the commit should give you an idea how to use it.