jpegTegraEncoderCompress() crashes with a SEGV

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).

Hi,
Please check if you can run successfully by calling NvJPEGEncoder::encodeFromFd(). You would need to call NvBufferCreate() to get the fd nd set to cinfo.fd.

I’m using NvJPEGEncoder::encodeFromFd(). My class is copy & paste of the encodeFromFd() function, except for the buffer and I added f_ in front of the variable members which makes it a lot easier to know these are such.

Also, I can’t use an NvBuffer along that function. It just expects one fd as a parameter. I have such from my frame which was just converted (I get NAL data which I decompress then convert and finally display on the screen). Displaying on the screen works perfectly with that same fd. So I thought that if the fd works with NvEGLImageFromFd(), it would work just find with the JPEG library extensions.

    f_egl_images[idx] = NvEGLImageFromFd(
                              display
                            , frame->get_fd());

Further, I have a JPEG decoder (similar the other way around) and that one works perfectly. It can load JPEG images as long as they are in 4:2:0 and RGB.

Hi,
Could you try to call NvBufferGetParams(fd) and see if you can get information about the buffer?

Okay, I realized that the NvBuffer I have was converted to RGB so I could just save the frame using a PPM image. Much easier and it doesn’t crash.

I think that the issue was that your code probably doesn’t check whether the 3 planes are properly defined and if one is a null pointer, it just tries to access data at that invalid address and crashes.

In any event, I’m good on my end. Thank you for your help.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.