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.
DaneLLL
December 15, 2020, 1:12am
3
Hi,
You need to use either libjpeg.so or libnvjpeg.so . Please refer to related topic threads:
No. It only runs on TX1/TX2. There is JPG HW component in TX1/TX2. It is not a CUDA implementation.
No. libnvjpeg.so is to modify the source code of libjpeg.so to have HW acceleration.
I think no. The function names are the same and it may trigger double definitions.
We suggest users use NvJpegEncoder and NvJpegDecoder classes.
Hi,
For running with OpenCV, we suggest use jpegenc instead of nvjpegenc. OpenCV links to libjpeg.so in many places and it is difficult to replace it with libnvjpeg.so.
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.