Hi,
I’m trying to use the output_plane with the NvVideoEncoder component. When I queue a buffer with some data (i.e. bytesused != 0), the dequeue of this buffer in the output_plane gives me v4l2_buf->m.planes[0].m.bytesused = 0, signalling an end-of-stream. Both v4l2_buf->m.planes[0].m.bytesused and buffer->planes[0].bytesused give the value zero. For the NvVideoConverter however, the dequeued buffer has a value != 0.
Is this a problem in video-encoder component?
I’m using tegra_multimedia_api version 28.2.1 on a Jetson TX2.
Hi,
Please compare your code with tegra_multimedia_api\samples\01_video_encode.
Hi Dane,
The 01_video_encode example doesn’t use an EOS detection in the output_plane of the NvVideoEncoder component. So It is difficult to compare it. I’m using a dqThread on both the output_plane and the capture_plane. This is the code for my output_plane callback
bool TegraInStreamProcessor::EncoderOutputPlaneDqCallback(struct v4l2_buffer* v4l2_buf, NvBuffer* buffer, NvBuffer * shared_buffer)
{
// Got EOS signal?
if (v4l2_buf->m.planes[0].bytesused == 0) {
fprintf(stderr, "[%s] EncoderOutputPlaneDqCallback() received EOS\n", name_);
return false;
}
return true;
}
The first buffer sent to the encoder output-plane (with bytesused != 0) immediately triggers the EOS signal to terminate the output_plane dqThread. I cannot find any of the examples in the tegra_multimedia_api that use a dqThread on the output_plane of the NvVideoEncoder…
Best regards,
Boris.
Hi,
We design to send bytesused=0 as EOS in capture plane. Does it meet v4l2 spec to send it in output plane?
I don’t know. If I look in the example “tegra_multimedia_api/samples/frontend/VideoEncoder.cpp”, you see that EOS marker is sent to the output plane by setting bytesused to 0.
This is part of the implementation (line 132 - 148):
...
CHECK_ERROR(m_VideoEncoder->output_plane.dqBuffer(v4l2_buf, NULL, NULL, 10));
// Buffer done, execute callback
m_callback(v4l2_buf.m.planes[0].m.fd, m_callbackArg);
m_dmabufFdSet.erase(v4l2_buf.m.planes[0].m.fd);
if (dmabuf_fd < 0)
{
// Send EOS
v4l2_buf.m.planes[0].bytesused = 0;
}
else
{
v4l2_buf.m.planes[0].m.fd = dmabuf_fd;
v4l2_buf.m.planes[0].bytesused = 1; // byteused must be non-zero
m_dmabufFdSet.insert(dmabuf_fd);
}
CHECK_ERROR(m_VideoEncoder->output_plane.qBuffer(v4l2_buf, NULL));
...
Hi,
You misunderstand v4l2 flow. We queue video frames to output plane and the encoded frames are sent out in capture plane. Once we want to terminate the encoding, we queue bytesused=0 to output plane to notify encoder. Once encoder has encoded all frames, it sends out bytesused=0(EOS) to capture plane.
You should check EOS in capture plane.
Ok, that makes sense.
So the implementation for the encoder is different than e.g. the converter? If I look at the example “00_video_decode/video_decode_main.cpp”, the bytesused value in the output_plane of the video-converter is checked for EOS to terminate the dqThread.
Part of the file (line 290 - 308):
conv0_output_dqbuf_thread_callback(struct v4l2_buffer *v4l2_buf,
NvBuffer * buffer, NvBuffer * shared_buffer,
void *arg)
{
context_t *ctx = (context_t *) arg;
struct v4l2_buffer dec_capture_ret_buffer;
struct v4l2_plane planes[MAX_PLANES];
if (!v4l2_buf)
{
cerr << "Error while dequeueing conv output plane buffer" << endl;
abort(ctx);
return false;
}
if (v4l2_buf->m.planes[0].bytesused == 0)
{
return false;
}
....
return true;
}
Hi,
In running NvVideoConverter, we have to register dqueue callback function in output plane. And it sends bytesused=0 to notify this is last callback. In NvVideoEncoder, we don’t design dqueue callback in output plane.
Ok. Thank you for your help.
Regards,
Boris.