Unable to use gstreamer programmaticaly with nvjpegenc and opencv 4.1.1 simultaneously

I link my C++ software with opencv4.1.1 and g-streamer, when the c++ instruction

_jpegEncoder = gst_element_factory_make ("nvjpegenc", "jpegEncoder_0");

is executed, I got following error:

JPEG parameter struct mismatch: library thinks size is 584, caller expects 728.

I think the problem is located on the library libjpeg that now I use libjpeg.so.8 with new opencv. Before I was using libjpeg.so.6 with an older opencv. But I can’t find how I can make it works.

I tried something I’ve seen in the forum to replace libgstnvjpeg.so by libgstjpeg.so I don’t get the error anymore but it don’t work too.

Hi,
You need to use either libjpeg.so or libnvjpeg.so. Please refer to related topic threads:

The main differences with your answer is that I don’t link my software with libjpeg or libnvjpeg directly.

I use opencv 4.1 which is dynamically linked with lib-jpeg.so.8

and

I use g-streamer programmaticaly in c++ and the command

gst_element_factory_make ("nvjpegenc", "jpegEncoder_0");

uses libgstnvjpeg.so which seems to be statically linked with an old lib-jpeg

so I can’t change libjpeg to libnvjpeg because I can’t rebuild libgstnvjpeg.so (or sources are available somewhere I havn’t seen)

The only action I can do is to change the nvjpegenc by jpegenc into my g-streamer pipeline.

In order to do that, I made som tries in command line with gst-launch command.

> gst-launch-1.0 -vvv nvarguscamerasrc num-buffers=1 ! 'video/x-raw(memory:NVMM), width=(int)3280, height=(int)2464, framerate=2/1' ! nvjpegenc ! filesink location=test.jpg -e

This command works well and provide me a jpg.

When I use jpegenc instead of nvjpegenc I got following error

WARNING: erroneous pipeline: could not link nvarguscamerasrc0 to jpegenc0, jpegenc0 can’t handle caps video/x-raw(memory:NVMM), width=(int)3280, height=(int)2464, framerate=(fraction)2/1

jpegenc expects input frames from standard CPU memory. You would try adding nvvidconv for copying from NVMM to CPU memory:

gst-launch-1.0 -vvv nvarguscamerasrc num-buffers=1 ! 'video/x-raw(memory:NVMM), width=(int)3280, height=(int)2464, framerate=2/1' ! nvvidconv ! jpegenc ! filesink location=test.jpg -e

Thanks for your answer.

Yes I’ve just found the same solution. Here is the command line that’s works well:

gst-launch-1.0 nvarguscamerasrc num-buffers=1 sensor_id=2 ! 'video/x-raw(memory:NVMM), width=(int)3280, height=(int)2464, framerate=2/1' ! nvvidconv ! 'video/x-raw, format=(string)BGRx' ! jpegenc ! filesink location=test.jpg -e

But I would prefer to use the nvjpegenc because I think my performances will reduce making jpeg encoding with CPU instead of GPU.

Is there any other solution to use nvjpegenc ? Is it possible to have a more recent library ?

This may work:

gst-launch-1.0 nvarguscamerasrc num-buffers=1 ! 'video/x-raw(memory:NVMM), width=(int)3280, height=(int)2464, framerate=2/1' ! nvjpegenc ! filesink location=test.jpg -e

I cannot tell how to fix the jpeg lib mismatch with opencv. A solution may be using 2 processes (one gst-launch doing nvjpegenc, and your opencv app) communicating through shmsink/shmsrc.

It could be a solution to use shmsink/shmsrc but it complexify my software. I will take a look. thanks.