I wrote the following function using the fd_to_jpeg_impl
class.
However, when I call the compress()
function, it crashes with a SEGV in:
0x0000007fb6531354 in jpegTegraEncoderCompress () from /usr/lib/aarch64-linux-gnu/tegra/libnvjpeg.so
Here are my class & function:
namespace
{
class fd_to_jpeg_impl
{
public:
fd_to_jpeg_impl();
~fd_to_jpeg_impl();
void compress(int fd);
void save(std::string const & filename);
private:
jpeg_compress_struct f_cinfo = {};
jpeg_error_mgr f_jerr = {};
std::vector<char> f_buffer = {};
};
fd_to_jpeg_impl::fd_to_jpeg_impl()
{
f_cinfo.err = jpeg_std_error(&f_jerr);
jpeg_create_compress(&f_cinfo);
jpeg_suppress_tables(&f_cinfo, TRUE);
}
fd_to_jpeg_impl::~fd_to_jpeg_impl()
{
jpeg_destroy_compress(&f_cinfo);
}
void fd_to_jpeg_impl::compress(int fd)
{
if(fd == -1)
{
std::cerr << "error: fd_to_jpeg expects a valid fd as input." << std::endl;
return;
}
// allocate a buffer to save the compressed data
//
f_buffer.resize(3840 * 2160 * 3);
unsigned char * out_buf(reinterpret_cast<unsigned char *>(f_buffer.data()));
unsigned long out_buf_size(f_buffer.size());
jpeg_mem_dest(&f_cinfo, &out_buf, &out_buf_size);
if(out_buf != reinterpret_cast<unsigned char *>(f_buffer.data()))
{
free(reinterpret_cast<void *>(*out_buf));
std::cerr << "error: the JPEG library reallocated our buffer." << std::endl;
return;
}
f_cinfo.fd = fd;
f_cinfo.IsVendorbuf = TRUE;
f_cinfo.raw_data_in = TRUE;
f_cinfo.in_color_space = JCS_YCbCr;
jpeg_set_defaults(&f_cinfo);
jpeg_set_quality(&f_cinfo, 75, TRUE); // 75 is a bit low, but we're just debugging with those
jpeg_set_hardware_acceleration_parameters_enc(&f_cinfo, TRUE, out_buf_size, 0, 0);
// TBD: useless? it's already set that way above
//
f_cinfo.in_color_space = JCS_YCbCr;
jpeg_start_compress(&f_cinfo, 0);
if(f_cinfo.err->msg_code)
{
char err_string[256];
f_cinfo.err->format_message((j_common_ptr) &f_cinfo, err_string);
std::cerr << "error:fd_to_jpeg: " << err_string << std::endl;
return;
}
jpeg_write_raw_data(&f_cinfo, nullptr, 0); // <-- crashes in this call
jpeg_finish_compress(&f_cinfo);
}
void fd_to_jpeg_impl::save(std::string const & filename)
{
...code not reached...
}
void fd_to_jpeg(int fd, std::string const & filename)
{
fd_to_jpeg_impl obj;
obj.compress(fd);
obj.save(filename);
}
Here is the beginning of the stack up to fd_to_jpeg()
:
Thread 1 "favorite-icon-g" received signal SIGSEGV, Segmentation fault.
0x0000007fb6531354 in jpegTegraEncoderCompress () from /usr/lib/aarch64-linux-gnu/tegra/libnvjpeg.so
(gdb) where
#0 0x0000007fb6531354 in jpegTegraEncoderCompress () at /usr/lib/aarch64-linux-gnu/tegra/libnvjpeg.so
#1 0x0000007fb64fb354 in jpeg_write_raw_data () at /usr/lib/aarch64-linux-gnu/tegra/libnvjpeg.so
#2 0x00000055555949f4 in (anonymous namespace)::fd_to_jpeg_impl::compress(int) (this=0x7fffffdf20, fd=1194)
at /home/alexis/ve/virtual-entertainment/panel-ve/src/fd_to_jpeg.cpp:142
#3 0x0000005555594c10 in fd_to_jpeg(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (fd=1194, filename="f1000a.jpg") at /home/alexis/ve/virtual-entertainment/panel-ve/src/fd_to_jpeg.cpp:173
I’m wondering whether someone would know about the reason for that crash.
The class above uses the samples/common/classes/NvJpegEncoder.cpp
code one to one (except for the name of the variables and the destination buffer).