Tegra_multimedia_api (NvJPEGEncoder::encodeFromBuffer) segmentation fault

Dear Everyone,

I am working with Jetson Tx1 and Jetpack version 2.3.1. I use Tegra_multimedia_api to encode YUV420 to jpeg , but sometimes I get the segmentation fault. It does not happen all the times, so I don’t know what is the problem. I don’t know how to attach the screenshot, so I would like to make some description as below.segmentation fault at jpeg_write_raw_data() due to memcpy().

int
NvJPEGEncoder::encodeFromBuffer(NvBuffer & buffer, J_COLOR_SPACE color_space,
        unsigned char **out_buf, unsigned long &out_buf_size)
{
	.........
	
    for (i = 0; i < height; i += v_max_samp * DCTSIZE)
    {
        for (k = 0; k < channels; k++)
        {
            for (j = 0; j < v_samp[k] * DCTSIZE; j++)
            {
                line[k][j] = base[k];
                if (base[k] + stride[k] < end[k])
                    base[k] += stride[k];
            }
        }
        jpeg_write_raw_data(&cinfo, line, v_max_samp * DCTSIZE);//>>> segmentation fault in this line of code due to memcpy()
    }

	.........
	
    return 0;
}

when I print out the debug information like this:

printf("encodeFromBuffer out_buf_size:%d, width:%d, height:%d, v_max_samp:%d, cinfo.width:%d, cinfo.height:%d\n", out_buf_size, width, height, v_max_samp, cinfo.image_width, cinfo.image_height);
    int v = 0;
    for (i = 0; i < height; i += v_max_samp * DCTSIZE)
    {
        for (k = 0; k < channels; k++)
        {
            for (j = 0; j < v_samp[k] * DCTSIZE; j++)
            {
                line[k][j] = base[k];
                if (base[k] + stride[k] < end[k])
                    base[k] += stride[k];
            }
        }

        printf("channels:%d, i:%d, k:%d, j:%d, v:%d, line:%08X, cinfo->comp_info[0].v_samp_factor:%d\n", channels,i, k, j, v,line, cinfo.comp_info[0].v_samp_factor);
        v += jpeg_write_raw_data(&cinfo, line, v_max_samp * DCTSIZE);
        if (cinfo.err->msg_code)
        {
        	printf("jpeg_write_raw_data error code :%d\n", cinfo.err->msg_code);
        }
    }

I got:

channels:3, i:832, k:3, j:8, v:832, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:848, k:3, j:8, v:848, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:864, k:3, j:8, v:864, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:880, k:3, j:8, v:880, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:896, k:3, j:8, v:896, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:912, k:3, j:8, v:912, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:928, k:3, j:8, v:928, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:944, k:3, j:8, v:944, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:960, k:3, j:8, v:960, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:976, k:3, j:8, v:976, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:992, k:3, j:8, v:992, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:1008, k:3, j:8, v:1008, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:1024, k:3, j:8, v:1024, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:1040, k:3, j:8, v:1040, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:1056, k:3, j:8, v:1056, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
channels:3, i:1072, k:3, j:8, v:1072, line:6D870610, cinfo->comp_info[0].v_samp_factor:2
Segmentation fault

Image resolution is FullHD(1920x1080).
Maybe this topic is relevant, but I am not sure, could you confirm whether it is the jetpack api issue?
https://devtalk.nvidia.com/default/topic/1005580/nvjpegenc-segmentation-fault/?offset=7

Thanks for supporting.

More debug information:

Crash 1st:
line unsigned char **[3] 0x7f667fe350
line[0] unsigned char ** 0x7f54003260
line[1] unsigned char ** 0x7f54003020
line[2] unsigned char ** 0x7f540749e0
Caught segfault at address 0x7f54390000

Crash 2nd:
line unsigned char **[3] 0x7f667fe350
line[0] unsigned char ** 0x7f4c002070
line[1] unsigned char ** 0x7f4c002520
line[2] unsigned char ** 0x7f4c001f00
Caught segfault at address 0x7f4c390000

I am looking forward to any suggestion or information.
Thanks.

Dear Nvidia Tx1 moderator,

Could you give me any information for my issue ?

Thanks

Long65rzy,
Sorry for late,
Could you share your sample code?
So I can reproduce on my side.

Thanks
wayne zhu

Dear waynezhu,

I cannot share the whole code, but I am using tegra api as below:

class CEncodeYc2Jpeg {
public:
	CEncodeYc2Jpeg();
	virtual ~CEncodeYc2Jpeg();
	uint32_t encodeYc2Jpeg(char* buffer_in, uint8_t* buffer_out, uint32_t width, uint32_t height);
protected:
	int		encodeYc2Jpeg( unsigned char **output, uint32_t width, uint32_t height, uint32_t &outputSize );
	int		initYc2Jpeg( uint32_t width, uint32_t height );
	int		reinitYc2Jpeg( uint32_t width, uint32_t height  );
private:
	/**
	 * Tegra buffer for yuv420
	 */
	NvBuffer *m_nvbuffer;
	NvJPEGEncoder *m_gJpegenc;

	/**
	 * Jpeg resolution
	 */
	uint32_t m_width;
	uint32_t m_height;
};

CEncodeYc2Jpeg::CEncodeYc2Jpeg():
	 m_nvbuffer(NULL)
	,m_gJpegenc(NULL)
	,m_width(1920)
	,m_height(1080)
{
	int nInit = -1;
	m_gJpegenc = NvJPEGEncoder::createJPEGEncoder("jpenenc");
	if (m_gJpegenc != nullptr) {
		nInit = initYc2Jpeg( 1920, 1080);
		if(nInit == -1){
			printf("CEncodeYc2Jpeg Init fails\n");
		}else{
			printf("CEncodeYc2Jpeg Init frame size width = %d height = %d\n", m_width, m_height);
		}
	}else{
		printf("createJPEGEncoder fail !\n");
	}
}

CEncodeYc2Jpeg::~CEncodeYc2Jpeg() {
	delete m_nvbuffer;
	m_nvbuffer = nullptr;
	delete m_gJpegenc;
	m_gJpegenc = nullptr;
}

int CEncodeYc2Jpeg::initYc2Jpeg( uint32_t width, uint32_t height  )
{
	m_gJpegenc->setCropRect(0, 0, width, height);
	m_nvbuffer = new NvBuffer(V4L2_PIX_FMT_YUV420M, width, height, 0);
	if( m_nvbuffer->allocateMemory() != 0){
		printf("CEncodeYc2Jpeg NvBuffer allocateMemory fail !\n");
		return -1;
	}
	//printf("m_nvbuffer memory address of plane[1] %LX plane[2] %LX plane[3] %LX\n",
			//m_nvbuffer->planes[0], m_nvbuffer->planes[2], m_nvbuffer->planes[3]);
	return 0;
}

int CEncodeYc2Jpeg::reinitYc2Jpeg( uint32_t width, uint32_t height  )
{
	int ret = 0;
	delete m_nvbuffer;
	m_nvbuffer = nullptr;
	ret = initYc2Jpeg(width, height);
	return ret;
}

/*
 * convert Yc to Jpeg
 * */
int CEncodeYc2Jpeg::encodeYc2Jpeg( unsigned char **output, uint32_t width, uint32_t height, uint32_t &outputSize )
{
	int ret = 0;

	if (output != nullptr && *output != nullptr) {
		unsigned long outputSizeTmp = width * height * 3 / 2;
		ret = m_gJpegenc->encodeFromBuffer( *m_nvbuffer, JCS_YCbCr, output, outputSizeTmp);
		outputSize = outputSizeTmp & 0xffffffff;
	}
	return ret;
}

uint32_t CEncodeYc2Jpeg::encodeYc2Jpeg(char* buffer_in, uint8_t* buffer_out, uint32_t width, uint32_t height)
{
	int read_video_frame(char * ycraw, NvBuffer & buffer);
	uint32_t outputSize = 0;

	//reinitialize in case of size change
	if( m_width != width || m_height != height){
		if ( reinitYc2Jpeg(width, height) != 0 ){
			return outputSize;
		}
		m_width = width;
		m_height = height;
		printf("CEncodeYc2Jpeg update frame size width = %d height = %d\n", m_width, m_height);
	}

	read_video_frame(buffer_in,*m_nvbuffer);
	encodeYc2Jpeg(&buffer_out, width, height, outputSize);
	return outputSize;
}

encodeYc2Jpeg(char* buffer_in, uint8_t* buffer_out, uint32_t width, uint32_t height) is used to encode yuv420 to jpeg from memory buffer.

It is successful most of the time, but sometimes it gets segmentation fault at Tegra_multimedia_api as my above description.

I would like to confirm more information that if Nvjpegenc segmentation fault - Jetson TX1 - NVIDIA Developer Forums is similar. And whether libnvjpeg has any problem ?.
Because I am not using the latest Jetpack. My using version is 2.3.1.

If possible please tell me how to attach an image file for more detail, because I cannot share the whole source.

I think yes, fix is already on rel28.1

wayne zhu,
Sorry, but my product is in production process, and Jetpack cannot be updated at this time.
Is there any work around for this issue ?

wayne zhu,
Sorry, but my product is in production process, and Jetpack cannot be updated at this time.
Is there any work around for this issue ?

I will send you a so for fix.
libnvjpeg.7z (110 KB)

Thanks for your support.