NvJPEGEncoder-encodeFromBuffer-tegra_multimedia_api

Dear Nvidia,

    1. I refer to the 05_jpeg_encode example to encode raw data into jpeg.
      Errors occur after running hundreds of times each time.

terminate called after throwing an instance of ‘std::logic_error’
what(): basic_string::_M_construct null not valid
Aborted

or

NVMAP_IOC_GET_FD failed: Bad address
PosixMemMap:74 FD from Handle failed : Bad address
NvJpeg_Tvmr_Error: tvmrNvjpgJPEGEncoderCreate: 590: ring buffers allocation failed
Segmentation fault

The dmesg log as below.
[ 9258.250626] nvmap: __nvmap_dmabuf_fd() NvMap: FD limit is crossed for uid 0

    1. My source code is as follows.
static int save_image(cv::Mat outMat, char * video_node, uint64_t timestamp)
{
    char image_name[70];
    sprintf(image_name, PATH, *video_node, timestamp);

    uint32_t width = outMat.cols;
    uint32_t height = outMat.rows;
    unsigned long out_buf_size = width * height;
    unsigned char *out_buf;


	NvBuffer buffer(V4L2_PIX_FMT_YUV420M, width, 2 * height / 3, 0);
	int ret = buffer.allocateMemory();
	if(ret < 0)
			printf("allocate memory failed\n");
	memcpy(buffer.planes[0].data, outMat.data, 2 * width * height / 3);
	buffer.planes[0].bytesused = width * height * 2 / 3;
	memcpy(buffer.planes[1].data, outMat.data + width * height * 2 / 3, width * height/6);
	buffer.planes[1].bytesused = width * height / 6;
	memcpy(buffer.planes[2].data, outMat.data + (5*width * height)/6, width * height/6);
	buffer.planes[2].bytesused = width * height / 6;
	
	NvJPEGEncoder *jpegenc = NvJPEGEncoder::createJPEGEncoder("jpenenc");
	out_buf = new unsigned char[out_buf_size];
	ret = jpegenc->encodeFromBuffer(buffer, JCS_YCbCr, &out_buf, out_buf_size, 85);

	out_file->write((char *) out_buf, out_buf_size);

    delete[] out_buf;
    delete out_file;
    /**
     * Destructors do all the cleanup, unmapping and deallocating buffers
     * and calling v4l2_close on fd
     */
    delete jpegenc;

    return 0;
}
    1. I located the problem with this line of code.
      ret = jpegenc->encodeFromBuffer(buffer, JCS_YCbCr, &out_buf, out_buf_size, 85);
    1. Current issue HW and SW infomation:
      Jetson AGX Orin - Jetpack 5.0.2 GA [L4T 35.1.0]

Please help to check this issue, thanks.

Hi,
It looks like YUV420 frame data is not copied directly. It should be Y plane with (width*height) bytes and UY plane with (width*height)*0.5 bytes. And please allocate Nvbuffer and out_buf to (width*height)*1.5 bytes.

Dear Sir,

I changed the code to look like this.
When the code is executed to the 257th time, a segment fault will be reported.

I have confirmed that there was no error reported in memory allocation, and the error was reported when executing the following line of code.

memcpy(buffer.planes[0].data, outMat.data, width * height);

static int save_image(cv::Mat outMat, char * video_node, uint64_t timestamp)
{
        char image_name[70];
        sprintf(image_name, PATH, *video_node, timestamp);

        uint32_t width = outMat.cols;
        uint32_t height = outMat.rows;
        unsigned long out_buf_size = width * height * 3 / 2;
        unsigned char *out_buf;

        std::ofstream * out_file = new ofstream(image_name);

        NvBuffer buffer(V4L2_PIX_FMT_YUV420M, width, height, 0);
        int ret = buffer.allocateMemory();
        if(ret < 0)
                printf("allocate memory failed\n");

        memcpy(buffer.planes[0].data, outMat.data, width * height);
        buffer.planes[0].bytesused = width * height;
        memcpy(buffer.planes[1].data, outMat.data + width * height, width * height / 4);
        buffer.planes[1].bytesused = width * height / 4;
        memcpy(buffer.planes[2].data, outMat.data + 5 * width * height / 4, width * height / 4);
        buffer.planes[2].bytesused = width * height / 4;
        NvJPEGEncoder *jpegenc = NvJPEGEncoder::createJPEGEncoder("jpenenc");

        out_buf = new unsigned char[out_buf_size];

        ret = jpegenc->encodeFromBuffer(buffer, JCS_YCbCr, &out_buf, out_buf_size, 85);

        out_file->write((char *) out_buf, out_buf_size);
        usleep(500);
        out_file->close();

        buffer.deallocateMemory();
        delete[] out_buf;
        delete out_file;
        delete jpegenc;

    return 0;
}

Hi,
You can set this option to 05_jpeg_encode to make sure it does not happen to the default sample:

-s Stress test [Default = 1]

If default sample works, you may compare your code with the default code.

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