This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM365 VPFE capture drivers won't fill all of the queued buffers

We are developing on custom hardware based around a DM365/8 which is being fed 640x960 4:2:0 video at 10fps from an FPGA.  Our kernel is based off of the dvsdk branch of the linux-davinci git kernel, version 2.6.37.

We are having an issue wherein the VPFE capture drivers only fill n-1 buffers, for n queued buffers.  For example:

VIDIOC_REQBUFS for 3 buffers - OK

VIDIOC_QUERYBUF/mmap all 3 buffers - OK

VIDIOC_QBUF all 3 buffers - OK

VIDIOC_STREAMON - OK

Wait 5 seconds

VIDIOC_QUERYBUF buffer 0, buffer.flags == V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE

VIDIOC_QUERYBUF buffer 1, buffer.flags == V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE

VIDIOC_QUERYBUF buffer 2, buffer.flags == V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED

That last buffer should also have the V4L2_BUF_FLAG_DONE bit set, and not V4L2_BUF_FLAG_QUEUED.  Kernel messages confirm that all of the capture interrupts are still firing.  The line that seems to be preventing a captured frame from filling the last buffer is (in our case with the resizer chained) in vpfe_resizer.c:rsz_dma_isr:

              if (!list_empty(&video_out->dma_queue) &&
                        video_out->cur_frm == video_out->next_frm)
                        schedule_capture = 1;

Specifically, video_out->dma_queue is empty, preventing the schedule_capture flag from being set and the subsequent call to vpfe_schedule_next_buffer.

This is even more problematic if you only queue 1 buffer... that buffer will never get filled, and any attempt to DQBUF that one buffer will hang indefinitely.

Is anybody familiar with why this may be happening?


Thanks in advance,

Frank

  • Hi Frank,

    We are developing on custom hardware based around a DM365/8 which is being fed 640x960 4:2:0 video at 10fps from an FPGA.  Our kernel is based off of the dvsdk branch of the linux-davinci git kernel, version 2.6.37.

    We are having an issue wherein the VPFE capture drivers only fill n-1 buffers, for n queued buffers.

    Did you see any issue while running the Apps provided by the DVSDK  on the DM365/8 EVM ?

    This is even more problematic if you only queue 1 buffer... that buffer will never get filled, and any attempt to DQBUF that one buffer will hang indefinitely.

    For Continuous mode a minimum of 3 buffers are required compulsory.

    Regards,

    --Prabhakar Lad

  • Hi Prabhakar,

    Prabhakar Lad said:
    Did you see any issue while running the Apps provided by the DVSDK  on the DM365/8 EVM ?

    I don't recall if this issued arose or not... I will switch everything around and check it tonight.

    Prabhakar Lad said:
    For Continuous mode a minimum of 3 buffers are required compulsory.

    I know the driver has a 3-buffer minimum as far as the number of buffers requested, and will allocate 3 if you request fewer, but I'm referring to the number of buffers actually queued via the VIDIOC_QBUF call (as opposed to allocated via VIDIOC_REQBUF, wherein the driver enforces the 3 buffer minimum).  If I queue 3 buffers, the 3rd one never gets filled, no matter how long I let the application sit with captured frames streaming.  If I request and queue 4 buffers, the 4th one never gets filled, etc.

    Frank

  • Prabhakar,

    Prabhakar Lad said:
    Did you see any issue while running the Apps provided by the DVSDK  on the DM365/8 EVM ?

    Yes, I just hooked our EVM back up, and ran the example program, modified to wait for a second after VIDIOC_STREAMON and then VIDIOC_QUERYBUF'ing each buffer to check its flags.  Again, the last buffer does not get filled.  If I further modify the program (step 19) to only queue 1 buffer, the VIDIOC_DQBUF call never completes.

    I have attached the example program, and the output.

    Can you explain what's going on, and how to fix it?  Thanks.

    Frank

    5127.4604.tvp514x_ccdc_prv_rsz_file_420_mmap_output.txt

    1881.4604.tvp514x_ccdc_prv_rsz_file_420_mmap.c

  • Hi Frank,

    What is the necessity to queue only 1 buffer?

    The flow of the apps should be like this

    1: You Request for buffers

    2: Query the buffers (in MMAP case).

    3: Queue all the buffers.

    4:Start the Hardware (stream on).

    5: You D-queue the buffer.

    6: Queue the buffer...

    7: Repeat step 5 and 6.

    8: Stop the hardware (stream off)

    Regards,

    --Prabhakar Lad

  • Hi Prabhakar,

    The necessity arises because when the system comes under load, an application can't always process all of the buffers in time, and will need the driver to queue buffers for it... that's the whole point of having the FIFO in the driver, to take up that slack.  Video recording is only one small part of our application, and while it is the highest priority, Linux is not a hard real time OS as deployed here, so there are going to be times when the buffers are going to get backed up.  If our application takes longer than a frame period to process a frame, and we get down to only 2 buffers in the queue, it cuts our frame rate in half, because the driver doesn't initiate capture of the next frame until QBUF gets called again, even though there is already a buffer queued, delaying the capture by up to another entire frame period.  For example:

    0 DONE
    1 DONE
    2 QUEUED
    DQBUF
    0 UNAVAIL
    1 DONE
    2 QUEUED
    //Application still processing buffer 0
    DQBUF
    0 UNAVAIL
    1 UNAVAIL
    2 QUEUED
    //Application done processing buffer 0
    QBUF
    0 QUEUED
    1 UNAVAIL
    2 QUEUED <--this will only now get filled, and it can take up to a frame period, intervening frame could be dropped
    DQBUF <--may have to wait for almost a frame period for buffer 2 to become DONE

    Does that make sense?

    Frank