I’m trying to do a image processing on tx2 with NVCAMERA and VIC/ENCODER with Multimedia API.
I wrote the code which can work fine on tx1 with jetpack 24.2.1, but got error on jetpack 28.2.1 with both tx1 and tx2.
The pipeline:
Nvcamera → VIC → Image processing → Nvbuffer create && copy to nvbuffer → pass the nvbuffer fd to VIC → ENCODER → H264
- convert init.
int stitch_vic_init()
{
std::string conv_name_stitch="conv_stitch";
GUARD_PROCESS_OUT_BOOL(stitch_conv = NvVideoConverter::createVideoConverter(conv_name_stitch.c_str()),"create video converter");
GUARD_PROCESS_OUT_INT(stitch_conv->setFlipMethod((enum v4l2_flip_method) -1),"set flip method");
GUARD_PROCESS_OUT_INT(stitch_conv->setInterpolationMethod((enum v4l2_interpolation_method) -1),"set interpolation method");
GUARD_PROCESS_OUT_INT(stitch_conv->setTnrAlgorithm((enum v4l2_tnr_algorithm) -1),"set tnr algorithm");
GUARD_PROCESS_OUT_INT(stitch_conv->setOutputPlaneFormat(V4L2_PIX_FMT_ABGR32, result_rec.width,
result_rec.height, V4L2_NV_BUFFER_LAYOUT_BLOCKLINEAR),"set up VIC output plane format");
GUARD_PROCESS_OUT_INT(stitch_conv->setCapturePlaneFormat(V4L2_PIX_FMT_YUV420M, result_rec.width,
result_rec.height , V4L2_NV_BUFFER_LAYOUT_PITCH),"set up VIC capture plane format");
GUARD_PROCESS_OUT_INT(stitch_conv->output_plane.setupPlane(V4L2_MEMORY_DMABUF,
V4L2_BUFFERS_NUM, false, false) ,"allocate VIC output plane");
GUARD_PROCESS_OUT_INT(stitch_conv->capture_plane.setupPlane(V4L2_MEMORY_MMAP,
V4L2_BUFFERS_NUM, true, false),"allocate VIC capture plane");
GUARD_PROCESS_OUT_BOOL(stitch_buff = (nv_buffer *)malloc(V4L2_BUFFERS_NUM*sizeof(nv_buffer)),"stitch_buff malloc");
conv_output_plane_stitching_buf_queue = new std::queue < nv_buffer * >;
//
GUARD_PROCESS_OUT_BOOL(stitch_buff = (nv_buffer *)malloc(V4L2_BUFFERS_NUM*sizeof(nv_buffer)),"stitch_buff malloc")
sem_init (&g_stitch_sem, 0, 1);
sem_init (&g_stitch_sem_post, 0, 0);
GUARD_PROCESS_OUT_INT(stitch_conv->output_plane.setStreamStatus(true),"set conv output stream on");
GUARD_PROCESS_OUT_INT(stitch_conv->capture_plane.setStreamStatus(true),"set conv capture stream on");
GUARD_PROCESS_OUT_BOOL(stitch_conv->output_plane.setDQThreadCallback(ArgusSamples::stitch_conv_output_dqbuf_thread_callback),\
"set stitch_conv_output_dqbuf_thread_callback");
GUARD_PROCESS_OUT_BOOL(stitch_conv->capture_plane.setDQThreadCallback(ArgusSamples::stitch_conv_capture_dqbuf_thread_callback),\
"set stitch_conv_capture_dqbuf_thread_callback");
GUARD_PROCESS_OUT_INT(stitch_conv->output_plane.startDQThread(&ctx),"start output_plane thread");
GUARD_PROCESS_OUT_INT(stitch_conv->capture_plane.startDQThread(&ctx),"start capture_plane thread");
for (unsigned int index = 0;index < stitch_conv->output_plane.getNumBuffers(); index++)
{
NvBufferCreateParams input_params = {0};
input_params.payloadType = NvBufferPayload_SurfArray;
input_params.nvbuf_tag = NvBufferTag_NONE;
int fd;
input_params.width = result_rec.width;
input_params.height = result_rec.height;
input_params.layout = NvBufferLayout_Pitch;
input_params.colorFormat = NvBufferColorFormat_ABGR32;
if (NvBufferCreateEx(&fd, &input_params) < 0)
ORIGINATE_ERROR("Failed to create NvBuffer.");
int ret = -1;
NvBufferParams parm;
ret = NvBufferGetParams(fd, &parm);
NvBufferParams params = {0};
NvBufferGetParams(fd, ¶ms);
stitch_buff_pitch = params.pitch[0];
ret = NvBufferMemMap(fd, 0, NvBufferMem_Read_Write, (void **)&stitch_buff[index].start);
stitch_buff[index].dmabuff_fd = fd;
stitch_buff[index].size = params.height[0] * params.pitch[0];;
struct v4l2_buffer v4l2_buf;
struct v4l2_plane planes[MAX_PLANES];
memset(&v4l2_buf, 0, sizeof(v4l2_buf));
memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
v4l2_buf.index = index;
v4l2_buf.m.planes = planes;
GUARD_PROCESS_OUT_INT(stitch_conv->output_plane.qBuffer(v4l2_buf, NULL) ,"enqueue empty buffer into VIC output plane");
}
for (unsigned int index = 0;index < stitch_conv->capture_plane.getNumBuffers(); index++)
{
struct v4l2_buffer v4l2_buf;
struct v4l2_plane planes[MAX_PLANES];
memset(&v4l2_buf, 0, sizeof(v4l2_buf));
memset(planes, 0, MAX_PLANES * sizeof(struct v4l2_plane));
v4l2_buf.index = index;
v4l2_buf.m.planes = planes;
GUARD_PROCESS_OUT_INT(stitch_conv->capture_plane.qBuffer(v4l2_buf, NULL) ,"enqueue empty buffer into VIC output plane");
}
return true;
}
- convert_call_back
bool stitch_conv_output_dqbuf_thread_callback(struct v4l2_buffer *v4l2_buf, NvBuffer * buffer, NvBuffer * shared_buffer, void *arg)
{
nv_buffer * cam_g_buff;
sem_wait(&g_stitch_sem_post);
if(conv_output_plane_stitching_buf_queue->size()>0)
{
cam_g_buff = conv_output_plane_stitching_buf_queue->front();
conv_output_plane_stitching_buf_queue->pop();
if (cam_g_buff->dmabuff_fd == 0)
{
printf("-------cam_g_buff->dmabuff_fd == 0\n");
return false;
}
else
{
// Enqueue vic output plane
v4l2_buf->m.planes[0].m.fd = (unsigned long)cam_g_buff->dmabuff_fd;
v4l2_buf->m.planes[0].bytesused = cam_g_buff->size;
}
if (stitch_conv->output_plane.qBuffer(*v4l2_buf, NULL) < 0)
{
ERROR_RETURN("Failed to enqueue VIC output plane");
}
}
return true;
}
- encoder init and its callback
bool encoderCapturePlaneDqCallback(struct v4l2_buffer *v4l2_buf, NvBuffer * buffer,NvBuffer * shared_buffer,void *arg)
{
static int64 t = cv::getTickCount();
static int frame_count = 0;
if (!v4l2_buf)
{
m_VideoEncoder->abort();
THREAD_PRINT("Failed to dequeue buffer from encoder capture plane");
}
if (m_VideoEncoder->capture_plane.qBuffer(*v4l2_buf, NULL) < 0)
{
std::cerr << "Allen: Error while Qing buffer at capture plane" << std::endl;
}
// GOT EOS from m_VideoEncoderoder. Stop dqthread.
if (buffer->planes[0].bytesused == 0)
{
WARN("Got EOS, exiting...\n");
return false;
}
return true;
}
- error log
=================== stitch_conv_output_dqbuf_thread_callback, 795 cam_g_buff->size: 4249600
stitch_conv_capture_dqbuf_thread_callback, 814, v4l2_buf->m.planes[0].bytesused: 1310720
stitch_conv_capture_dqbuf_thread_callback, 820 ==================== buffer->planes[0].bytesused:1310720
===== MSENC blits (mode: 1) into tiled surfaces =====
allen ==== : converterCapturePlaneDqCallback, 506 cam_idx 0
encoderCapturePlaneDqCallback, 625 ==================== byteused: 24
encoderCapturePlaneDqCallback, 649 ==================== byteused: 24
encoderCapturePlaneDqCallback, 655 ==================== byteused: 24
encoderCapturePlaneDqCallback, 625 ==================== byteused: 278
encoderCapturePlaneDqCallback, 649 ==================== byteused: 278
encoderCapturePlaneDqCallback, 655 ==================== byteused: 278
=================== stitch_conv_output_dqbuf_thread_callback, 795 cam_g_buff->size: 4249600
stitch_conv_capture_dqbuf_thread_callback, 814, v4l2_buf->m.planes[0].bytesused: 1310720
stitch_conv_capture_dqbuf_thread_callback, 820 ==================== buffer->planes[0].bytesused:1310720
encoderCapturePlaneDqCallback, 625 ==================== byteused: 111
encoderCapturePlaneDqCallback, 649 ==================== byteused: 111
encoderCapturePlaneDqCallback, 655 ==================== byteused: 111
=================== stitch_conv_output_dqbuf_thread_callback, 795 cam_g_buff->size: 4249600
stitch_conv_capture_dqbuf_thread_callback, 814, v4l2_buf->m.planes[0].bytesused: 1310720
stitch_conv_capture_dqbuf_thread_callback, 820 ==================== buffer->planes[0].bytesused:1310720
encoderCapturePlaneDqCallback, 625 ==================== byteused: 104
encoderCapturePlaneDqCallback, 649 ==================== byteused: 104
encoderCapturePlaneDqCallback, 655 ==================== byteused: 104
=================== stitch_conv_output_dqbuf_thread_callback, 795 cam_g_buff->size: 4249600
stitch_conv_capture_dqbuf_thread_callback, 814, v4l2_buf->m.planes[0].bytesused: 1310720
stitch_conv_capture_dqbuf_thread_callback, 820 ==================== buffer->planes[0].bytesused:1310720
=================== stitch_conv_output_dqbuf_thread_callback, 795 cam_g_buff->size: 4249600
stitch_conv_capture_dqbuf_thread_callback, 814, v4l2_buf->m.planes[0].bytesused: 1310720
stitch_conv_capture_dqbuf_thread_callback, 820 ==================== buffer->planes[0].bytesused:1310720
[ERROR] (NvV4l2ElementPlane.cpp:254) <enc0> Output Plane:Error while Qing buffer: Device or resource busy
Could anyone give some help on this.