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

Which dll/lib file is it linking to? / How to link to libjpeg-turbo instead? #6

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

Comments

@Boscop
Copy link

Boscop commented Apr 4, 2018

This crate links to "jpeg" but where is this coming from?
It builds successfully on Win 8.1 and the reencode example works even though I didn't download a jpeg.dll and didn't derive a .lib file from it.

The reason I'm asking is because I want to use libjpeg-turbo. I downloaded libjpeg-turbo-1.5.90-vc64.exe from here and installed it, now I have jpeg62.dll and turbojpeg.dll.
Now I want to derive the .lib file from turbojpeg.dll and rename it to jpeg.lib and link to that, with mozjpeg-sys, how can I do that, if it's linking to some other jpeg lib by default?

(My use case is, I want to decode MJPEG frames coming from a webcam at 30 FPS to send them to the GPU for post-processing with glium. The jpeg-decoder crate uses too much CPU and only reaches 2 FPS in debug mode..)

@kornelski
Copy link
Owner

kornelski commented Apr 4, 2018

The links attribute is intended to mark that it conflicts with crates linking to the jpeg library, and this attribute doesn't do anything apart from that.

In the current implementation there is no dynamic linking, and it doesn't support anything except its own bundled static version of MozJPEG.

In any case, in this crate, I only intend to support MozJPEG, and not plain libjpeg-turbo.

@Boscop
Copy link
Author

Boscop commented Apr 4, 2018

Ok, and is MozJPEG suitable for real-time 30 FPS MJPEG decoding?

@kornelski
Copy link
Owner

If it's not fast enough, you can disable mozjpeg-specific optimizations:

  ffi::jpeg_c_set_bool_param(cinfo, J_BOOLEAN_PARAM::JBOOLEAN_OPTIMIZE_SCANS, false)
  ffi::jpeg_c_set_bool_param(cinfo, J_BOOLEAN_PARAM::JBOOLEAN_USE_SCANS_IN_TRELLIS, false);

@Boscop
Copy link
Author

Boscop commented Apr 4, 2018

Thanks!

Btw, how would decoding MJPEG frames differ from the reencode::decode() function (other than using jpeg_mem_src instead of jpeg_stdio_src)?

I guess I shouldn't call jpeg_read_header?
Should I just call jpeg_std_error, jpeg_create_decompress once during setup and then jpeg_start_decompress and jpeg_read_scanlines for every frame, and then jpeg_finish_decompress and jpeg_destroy_decompress when exiting?
I want to avoid re-doing stuff that doesn't have to be re-done for every frame.


Btw, this is my current code using escapi and the jpeg-decoder crate with glium:

const CAM_WIDTH: u32 = 1920;
const CAM_HEIGHT: u32 = 1080;
const CAM_FRAME_SIZE: usize = (CAM_WIDTH * CAM_HEIGHT) as _;

pub struct CamRenderer<'a> {
	cam: Capture,
	cam_frame: Box<[u32; CAM_FRAME_SIZE]>,
	cam_tex: texture::SrgbTexture2d,
	vertex_buffer: VertexBuffer<Vertex>,
	index_buffer: index::IndexBuffer<u16>,
	program: Program,
	params: DrawParameters<'a>,
	cam_name: &'a str,
	camera_count: u32,
}

impl<'a> CamRenderer<'a> {
	pub fn process<T: Surface>(&mut self, target: &mut T, state: &VjUiState) -> Result<(), i32> {
		if self.cam.is_capture_done() {
			use jpeg_decoder::*;
			let data = unsafe { slice::from_raw_parts(self.cam_frame.as_ptr() as *const u8, CAM_FRAME_SIZE * 4) };
			let mut decoder = Decoder::new(data);
			let decoded = decoder.decode().unwrap();
			self.cam.do_capture();
			self.cam_tex.main_level().write(Rect {
					left: 0,
					bottom: 0,
					width: CAM_WIDTH as u32,
					height: CAM_HEIGHT as u32
				}, texture::RawImage2d {
					data: Cow::Owned(decoded),
					width: CAM_WIDTH as u32,
					height: CAM_HEIGHT as u32,
					format: texture::ClientFormat::U8U8U8
				}
			);
// ... 

@kornelski
Copy link
Owner

Sorry, I don't know details of MJPEG. But the API is 1:1 libjpeg, so if you find any C example, it will be easy to translate.

@Boscop
Copy link
Author

Boscop commented Apr 4, 2018

So it supports images that don't have a huffman table?
It was necessary to add this to the jpeg-decoder crate to support MJPEG:
image-rs/jpeg-decoder#76 (comment)

@kornelski
Copy link
Owner

This implementation is based on libjpeg. Check what libjpeg does in this case.

@Boscop
Copy link
Author

Boscop commented Apr 4, 2018

Thanks, I got it working :)
Btw, is there a way to build the bundled static version of MozJPEG in release mode when I'm building my crate in debug mode?

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