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

It always uses decode_mcu_slow even with dinfo.dct_method = J_DCT_METHOD::JDCT_IFAST #8

Open
Boscop opened this issue Apr 21, 2018 · 4 comments

Comments

@Boscop
Copy link

Boscop commented Apr 21, 2018

When I write dinfo.dct_method = J_DCT_METHOD::JDCT_IFAST; it seems to call the same decode_mcu_slow function as without.
It seems to not change anything (same CPU usage when decoding 30fps 1080p MJPEG).
Is this library hardcoded to use ISLOW or is it dictated by the specific jpeg image that it cannot be decoded with IFAST?

This is what I'm doing every frame:

	let mut err: jpeg_error_mgr = mem::zeroed();
	let mut dinfo: jpeg_decompress_struct = mem::zeroed();
	dinfo.common.err = jpeg_std_error(&mut err);
	jpeg_create_decompress(&mut dinfo);
	dinfo.dct_method = J_DCT_METHOD::JDCT_IFAST;
	jpeg_mem_src(&mut dinfo, self.cam_frame.as_ptr() as *const u8, self.cam_frame.len() as u32 * 4);
	jpeg_read_header(&mut dinfo, true as boolean);
	dinfo.out_color_space = J_COLOR_SPACE::JCS_RGB;
	jpeg_start_decompress(&mut dinfo);
	let row_stride = dinfo.image_width as usize * dinfo.output_components as usize;
	let buffer_size = row_stride * dinfo.image_height as usize;
	debug_assert!(buffer_size <= DECODED_MJPEG_FRAME_SIZE);
	while dinfo.output_scanline < dinfo.output_height {
		let offset = dinfo.output_scanline as usize * row_stride;
		let mut jsamparray = [self.decoded_mjpeg[offset..].as_mut_ptr()];
		jpeg_read_scanlines(&mut dinfo, jsamparray.as_mut_ptr(), 1);
	}
	jpeg_finish_decompress(&mut dinfo);
	jpeg_destroy_decompress(&mut dinfo);

I profiled it, and IFAST made no difference, I got the same execution times as without setting it:

vf_9 _cpu_mozjpeg2

Any idea how I can make it really use IFAST? :)

@kornelski
Copy link
Owner

You're changing DCT method, but profiling MCU entropy decoding. These are completely different unrelated things. Use of decode_mcu_slow indicates that the JPEG data is corrupt or incomplete.

@kornelski
Copy link
Owner

BTW, MozJPEG is slow by design. It intentionally uses slowest (but highest quality) version of everything.

@Boscop
Copy link
Author

Boscop commented Apr 22, 2018

Use of decode_mcu_slow indicates that the JPEG data is corrupt or incomplete.

Hm, any idea why it could be corrupt/incomplete? I'm getting complete frames out at the end, and I'm just forwarding the data that I'm getting from the webcam.
The thing that's definitely missing is the huffman tables (so the default ones are used), but how could it be corrupt or missing something else?

Could it be because it's a cheap webcam that delivers corrupted MJPEG frames?

MozJPEG is slow by design. It intentionally uses slowest (but highest quality) version of everything.

Is there any jpeg decoder that's faster and also has Rust bindings? :)

(Btw, with this crate I'm getting 9-10% CPU usage (and without webcam decoding, my application only has 4% CPU usage). I tried the jpeg_decoder crate but it uses even more CPU than mozjpeg (total 16%).)

@kornelski
Copy link
Owner

I haven't studied MJPEG spec, so I can't say why exactly it's like that.

If you could reproduce the issue with pure C code, you could ask about it in libjpeg-turbo project (MozJPEG is a fork of libjpeg-turbo).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants