DevicePoll: how it work?

Hi.
I compile and run ‘01_video_encode’ sample from ‘tegra multimedia api’ samples in nonblocking mode.

I count number of events by it’s type. Code as below:

static void *encoder_pollthread_fcn(void *arg)
{

    context_t *ctx = (context_t *) arg;
    v4l2_ctrl_video_device_poll devicepoll;

    cout << "Starting Device Poll Thread " << endl;

    memset(&devicepoll, 0, sizeof(v4l2_ctrl_video_device_poll));

    // wait here until you are signalled to issue the Poll call.
    // Check if the abort status is set , if so exit
    // Else issue the Poll on the decoder and block.
    // When the Poll returns, signal the encoder thread to continue.

    while (!ctx->got_error && !ctx->enc->isInError())
    {
        sem_wait(&ctx->pollthread_sema);

        if (ctx->got_eos)
        {
            cout << "Got eos, exiting poll thread \n";
            return NULL;
        }

        devicepoll.req_events = POLLIN | POLLOUT | POLLERR | POLLPRI;

        // This call shall wait in the v4l2 encoder library
        ctx->enc->DevicePoll(&devicepoll);
        
        uint16_t resp  = devicepoll.resp_events;
        uint16_t in    = resp & POLLIN;
        uint16_t out   = resp & POLLOUT;
        uint16_t inout = (in || out) ? 1 : 0;
        uint16_t zero  = (resp == 0) ? 1 : 0;
        uint16_t other = (in || out || zero) ? 0 : 1;        
        
        ctx->pollall++;
        if(in) {
            ctx->pollin++;
        }
        if(out) {
            ctx->pollout++;
        }
        if(zero) {
            ctx->pollzero++;
        }
        if(inout)
            ctx->pollinout++;
        if(other) {
            ctx->pollother++;
        }
        
        // We can check the devicepoll.resp_events bitmask to see which events are set.
        sem_post(&ctx->encoderthread_sema);
    }
    return NULL;
}
// at the end of main

cout << "App run was successful" << endl;
cout << 
"in: "     << ctx.pollin << 
" out: "   << ctx.pollout <<
" zero: "  << ctx.pollzero << 
" inout: " << ctx.pollinout << 
" other: " << ctx.pollother <<
" all: "   << ctx.pollall << endl;

I run compiled programm with params:

./video_encode out.yuv 640 360 H264 out.h264 --blocking-mode 0

Samples output :

in: 1366 out: 982 zero: 1254 inout: 1367 other: 0 all: 2621
in: 1321 out: 915 zero: 4142 inout: 1325 other: 0 all: 5467
in: 1295 out: 872 zero: 1270 inout: 1296 other: 0 all: 2566
in: 1346 out: 1014 zero: 1831 inout: 1350 other: 0 all: 3181

My question is why zero event is occured often?

Hi,
Please share version of your release:

$ head -1 /etc/nv_tegra_release
head -1 /etc/nv_tegra_release
# R32 (release), REVISION: 1.0, GCID: 14531094, BOARD: t186ref, EABI: aarch64, DATE: Wed Mar 13 07:41:08 UTC 2019

Hi,
Please try r32.2.1 The test result looks ok on r32.2.1:

$ gst-launch-1.0 videotestsrc num-buffers=1600 ! video/x-raw,width=640,height=360 ! filesink location= /home/nvidia/a.yuv
$ ./video_encode /home/nvidia/a.yuv 640 360 H264 /home/nvidia/a.h264 --blocking-mode 0

Result:

in: 411 out: 79 zero: 80 inout: 411 other: 0 all: 491

After executing ‘sudo jetson_clocks’, the result gets better:

in: 144 out: 29 zero: 0 inout: 144 other: 0 all: 144

Hi.
Thank you. But in my case this actions has no effect.

head -1 /etc/nv_tegra_release
# R32 (release), REVISION: 2.1, GCID: 16294929, BOARD: t186ref, EABI: aarch64, DATE: Tue Aug 13 04:45:36 UTC 2019

Result:

sudo jetson_clocks
./video_encode /home/nvidia/a.yuv 640 360 H264 /home/nvidia/a.h264 --blocking-mode 0

in: 183 out: 18 zero: 102 inout: 183 other: 0 all: 285
in: 604 out: 307 zero: 2397 inout: 604 other: 0 all: 3001
in: 394 out: 125 zero: 1168 inout: 394 other: 0 all: 1562
in: 1054 out: 475 zero: 4335 inout: 1057 other: 0 all: 5392
in: 749 out: 452 zero: 5599 inout: 750 other: 0 all: 6349

have any idea?

Hi,
We think the behavior is fine in non-blocking mode. If the polling gets blocked in low-level, it may behave like blocking mode. You may reduce the polling frequency in zero resp_events, or run in blocking mode.