Hi DaneLLL,
Thanks for your reply.
I have 2 question about resolution-change.
(1) Sample code
I cannot understand why the function query_and_set_capture(ctx) is called twice in the sample code: 00_video_decode.
static void *
dec_capture_loop_fcn(void *arg)
{
do
{
ret = dec->dqEvent(ev, 50000);
(Abbreviated)
}
while ((ev.type != V4L2_EVENT_RESOLUTION_CHANGE) && !ctx->got_error);
// query_and_set_capture acts on the resolution change event
if (!ctx->got_error)
<b>query_and_set_capture(ctx)</b>;
// Exit on error or EOS which is signalled in main()
while (!(ctx->got_error || dec->isInError() || ctx->got_eos))
{
(Abbreviated)
// Check for Resolution change again
ret = dec->dqEvent(ev, false);
if (ret == 0)
{
switch (ev.type)
{
case V4L2_EVENT_RESOLUTION_CHANGE:
<b>query_and_set_capture(ctx)</b>;
continue;
}
}
while (1)
{
(Abbreviated)
// Dequeue a filled buffer
if (dec->capture_plane.dqBuffer(v4l2_buf, &dec_buffer, NULL, 0))
{
(Abbreviated)
}
}
}
(Abbreviated)
return NULL;
}
(2) In your comment “re-initialize”
Before “re-initialize”, I think that the decoder has to be stopped and cleared,
then it will be re-configured with new parameters.
NvVideoDecoder engine does not have any STOP function (in MMAPI).
NvVideoEncoder and NvVideoConverter can be stopped by STREAMOFF and deinit the both planes.
I guess that stopping NvVideDecoder needs one of these operations:
- STREAMOFF and deinit the both plane
- close device ----> execute it in the destuctor of NvV4l2Element
- delete NvVideoDecoder object —> call the destructor and close device
- reboot Linux for Tegra
- cold start TegraTX2 SoC (with hardware reset operation)
- Power down and up JetsonTX2
Are there any other method ?
If STREAMOFF and deinit are not sufficient for “re-initialize”,
it needs delete object, reboot Linux or power down JetsonTX2, I think.
Of cource, reboot and power down are senseless specification.
Then I asked you:
[i]>> When the resolution of images is changed,
do I have to delete the object of NvVideoDecoder ?[/i]
In the sample 00_video_decode, deinit function of capture plane of the decoder is called.
If initializing decoder is only once, there is no necessity for deinit,
because it is before setupPlane of capture plane.
Why is there the function call capture_plane.deinit() ?
static void
query_and_set_capture(context_t * ctx)
{
ret = dec->capture_plane.getFormat(format);
ret = dec->capture_plane.getCrop(crop);
if (ctx->conv)
{
ret = <b>sendEOStoConverter</b>(ctx);
ctx->conv->capture_plane.waitForDQThread(2000);
ctx->conv-><b>output_plane.deinitPlane()</b>;
ctx->conv-><b>capture_plane.deinitPlane()</b>;
while(!ctx->conv_output_plane_buf_queue->empty())
{
ctx->conv_output_plane_buf_queue->pop();
}
}
if (!ctx->disable_rendering)
{
<b>delete ctx->renderer</b>;
ctx->renderer = NvEglRenderer::createEglRenderer("renderer0", window_width,
window_height, ctx->window_x,
ctx->window_y);
ctx->renderer->setFPS(ctx->fps);
}
// deinitPlane unmaps the buffers and calls REQBUFS with count 0
<b><u>dec->capture_plane.deinitPlane();</u></b>
ret = dec->setCapturePlaneFormat(format.fmt.pix_mp.pixelformat,
format.fmt.pix_mp.width,
format.fmt.pix_mp.height);
ctx->video_height = format.fmt.pix_mp.height;
ctx->video_width = format.fmt.pix_mp.width;
// Get the minimum buffers which have to be requested on the capture plane
ret = dec->getMinimumCapturePlaneBuffers(min_dec_capture_buffers);
ret = dec->capture_plane.setupPlane(V4L2_MEMORY_MMAP,
min_dec_capture_buffers + 5, false, false);
if (ctx->conv)
{
ret = ctx->conv->setOutputPlaneFormat(format.fmt.pix_mp.pixelformat,
format.fmt.pix_mp.width,
format.fmt.pix_mp.height,
V4L2_NV_BUFFER_LAYOUT_BLOCKLINEAR);
ret = ctx->conv->setCapturePlaneFormat((ctx->out_pixfmt == 1 ?
V4L2_PIX_FMT_NV12M :
V4L2_PIX_FMT_YUV420M),
crop.c.width,
crop.c.height,
V4L2_NV_BUFFER_LAYOUT_PITCH);
ret = ctx->conv->setCropRect(0, 0, crop.c.width, crop.c.height);
ret = ctx->conv->output_plane.setupPlane(V4L2_MEMORY_DMABUF,
dec->capture_plane.
getNumBuffers(), false, false);
ret = ctx->conv->capture_plane.setupPlane(V4L2_MEMORY_MMAP,
dec->capture_plane.
getNumBuffers(), true, false);
ret = ctx->conv->output_plane.setStreamStatus(true);
ret = ctx->conv->capture_plane.setStreamStatus(true);
for (uint32_t i = 0; i < ctx->conv->output_plane.getNumBuffers(); i++)
{
ctx->conv_output_plane_buf_queue->push(ctx->conv->output_plane. getNthBuffer(i));
}
for (uint32_t i = 0; i < ctx->conv->capture_plane.getNumBuffers(); i++)
{
ret = ctx->conv->capture_plane.qBuffer(v4l2_buf, NULL);
}
ctx->conv->output_plane.startDQThread(ctx);
ctx->conv->capture_plane.startDQThread(ctx);
}
ret = dec->capture_plane.setStreamStatus(true);
for (uint32_t i = 0; i < dec->capture_plane.getNumBuffers(); i++)
{
ret = dec->capture_plane.qBuffer(v4l2_buf, NULL);
}
return;
}
Best Regards,