esp32-cam-demo icon indicating copy to clipboard operation
esp32-cam-demo copied to clipboard

framerate is very low

Open easeway opened this issue 7 years ago • 5 comments

I made the code working without change with my OV2640 module. However, the frame is obtained over 200ms. I've tried tuning the XCLK and OV2640 CLKRC, and finally I got a working combination of:

XCLK = 20MHz, CLKRC = 0x81 (15fps), QVGA, which ends up 70ms per frame with some code modification (I changed DMA to transfer to whole frame instead of by lines).

It seems the framerate is lowered on purpose:

https://github.com/igrr/esp32-cam-demo/blob/master/components/camera/ov2640.c#L462:

    if (framesize <= FRAMESIZE_SVGA) {
        clkrc =0x83;
        regs = svga_regs;
    } else {
        clkrc =0x87;
        regs = uxga_regs;
    }

To put camera in full speed, CLKRC should be 0 or 0x80. I don't know why here the camera is explicitly put under 1/4 (<= SVGA) and 1/8 (UXGA) of highest framerate.

With XCLK = 20MHz, I tried to put CLKRC = 0x80 (or 0), QVGA, the framerate raised to 30fps (the period between two VSYNC is about 30ms), however, the I2S DMA didn't seem to catch up with PCLK.

With an estimation PCLK = 320*240*2/30ms = 5.12MHz. I suspect the I2S DMA is able to catch up with this frequency. I observed a lot of sample loss or corruption.

As I came to a relatively stable configuration (XCLK = 20MHz, CLKRC = 0x81, QVGA), the DMA seems still missing 2 samples at the beginning of transfer. To test that, I set JPEG and pixformat, and OV2640 always generates 0xff 0xd8 0xff 0xe0 0x00 0x10 0x4a 0x46 0x49 0x46 0x00 0x01 0x01 0x01 0x00 0x00 as the first 16 bytes. So it's very easy to observe what goes wrong in received bytes via DMA.

It's very likely caused by hardware issue, but not sure what it is...

Now I'm happy with a working OV2640 a little less than 15fps in QVGA JPEG mode. I appreciate if anyone can help to raise the fps to 30.

easeway avatar Jan 13 '18 03:01 easeway

Some updates after a few stress test: (bad news) the 15fps configuration is actually unstable.

I realized that the biggest issue is about the noise. As I soldered all wires over a prototype board. The only STABLE configuration I got so far was still at 4fps. 8fps may work some how, but I can observe random corrupted frames. 15fps brought me more corrupted frames.

easeway avatar Jan 15 '18 21:01 easeway

@easeway I too am interested in increasing the frame rate at QVGA and would like to test what you have done on my test PCB. No long wires here so maybe i could help verify your findings. One question though. When you say "XCLK = 20MHz, CLKRC = 0x81 (15fps), QVGA, which ends up 70ms per frame with some code modification (I changed DMA to transfer to whole frame instead of by lines)." How did you change the DMA to transfer a whole frame instead of line by line? Thx

wdouglas1999 avatar Jan 18 '18 20:01 wdouglas1999

@wdouglas1999 regarding frame rate, it doesn't matter whether DMA transfers the whole image or line-by-line, according to my test. Actually line-by-line can save a lot of memory. So I changed my code back to use line-by-line. I put comments on your issue. Please let me know if you successfully increased the frame rate to 15fps with stable jpeg stream.

The change I made to transfer the whole image is simply as follow:

  1. estimate the maximum buffer size according to jpeg quality, see code starting from https://github.com/igrr/esp32-cam-demo/blob/master/components/camera/camera.c#L263

  2. prepare a list of DMA desc to cover the maximum buffer. Each desc covers a buffer with less than 4096 bytes, to be aligned with word, I use 4092.

  3. Start DMA from first VSYNC ISR handler and stop DMA in the next VSYNC ISR.

This solution doesn't need in_done ISR from DMA controller.

According to my test, this doesn't help to speed up memory transfer (as this is not the bottle neck), so I changed back to line-by-line. However, with JPEG, the pixel data is already compressed, so not actually by lines. I simply uses a ring of 4 descs each of size 4092. When each desc completes, it will trigger in_done ISR, so I can send the buffer to decode task while DMA is working on the next buffer. This sounds a lot better: consumes less memory, and can possibly work in parallel. Anyway, it doesn't make any difference as transfer is not bottleneck.

easeway avatar Jan 19 '18 05:01 easeway

@easeway Hi, have you had any further success with increasing the frame rate? I am getting about 5 FPS at a resolution on 800 x 600. My XCLK is at 8Mhz and CLKRC is at 0x81. I still am not able to get it to work in HS mode. Have you gotten HS mode to work? I’m using a WRover dev kit 3. Thx

wdouglas1999 avatar Mar 29 '18 04:03 wdouglas1999

@wdouglas1999 I haven't tried anymore. I start receiving corrupted images from ~8fps. I temporarily gave up, and fallback to USB cam + Linux SBC + MCU solution.

easeway avatar Mar 29 '18 05:03 easeway