Fix frame rate

This commit is contained in:
Kamil Trzcinski 2022-04-11 17:07:35 +02:00
parent fb400f3139
commit e69f707ef0
3 changed files with 35 additions and 12 deletions

View File

@ -186,6 +186,40 @@ i2ctransfer -y 22 w4@0x0c 0x0 0x85 0x00 0x00
i2ctransfer -y 11 w4@0x0c 0x0 0xXX 0x00 0x00
```
Latency according to my tests is due to the way how buffers are enqueued and processing delay, this is for triple buffering in a case where sensor is able to deliver frames quick enough. Depending on how you queue (on which slope) and when you enqueue buffer you might achieve significantly better latency as shown in the ISP-mode. The `libcamera` can still achieve 120fps, it is just slightly slower :)
#### 2328x1748@30fps
```shell
# libcamera
$ ./camera_stream -camera-path=/base/soc/i2c0mux/i2c@1/imx519@1a -camera-type=libcamera -camera-format=YUYV -camera-fps=120 -camera-width=2328 -camera-height=1748 -camera-high_res_factor=1.5 -log-filter=buffer_lock
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf2 (refs=2), frame=63/0, processing_ms=101.1, frame_ms=33.1
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf0 (refs=2), frame=64/0, processing_ms=99.2, frame_ms=31.9
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf1 (refs=2), frame=65/0, processing_ms=99.6, frame_ms=34.8
# direct ISP-mode
$ ./camera_stream -camera-path=/dev/video0 -camera-format=RG10 -camera-fps=30 -camera-width=2328 -camera-height=1748 -camera-high_res_factor=1.5 -log-filter=buffer_lock
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf1 (refs=2), frame=32/0, processing_ms=49.7, frame_ms=33.3
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf2 (refs=2), frame=33/0, processing_ms=49.7, frame_ms=33.3
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf0 (refs=2), frame=34/0, processing_ms=49.7, frame_ms=33.4
```
#### 1280x720@120fps for Arducam 16MP
```shell
# libcamera
$ ./camera_stream -camera-path=/base/soc/i2c0mux/i2c@1/imx519@1a -camera-type=libcamera -camera-format=YUYV -camera-fps=120 -camera-width=1280 -camera-height=720 -log-filter=buffer_lock
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf0 (refs=2), frame=139/0, processing_ms=20.1, frame_ms=7.9
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf1 (refs=2), frame=140/0, processing_ms=20.6, frame_ms=8.8
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf2 (refs=2), frame=141/0, processing_ms=19.8, frame_ms=8.1
# direct ISP-mode
$ ./camera_stream -camera-path=/dev/video0 -camera-format=RG10 -camera-fps=120 -camera-width=1280 -camera-height=720 -log-filter=buffer_lock
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf0 (refs=2), frame=157/0, processing_ms=18.5, frame_ms=8.4
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf1 (refs=2), frame=158/0, processing_ms=18.5, frame_ms=8.3
device/buffer_lock.c: http_jpeg: Captured buffer JPEG:capture:mplane:buf2 (refs=2), frame=159/0, processing_ms=18.5, frame_ms=8.3
```
## License
GNU General Public License v3.0

View File

@ -76,12 +76,6 @@ int libcamera_buffer_enqueue(buffer_t *buf, const char *who)
request->reuse(libcamera::Request::ReuseBuffers);
// TODO: assign timestamps
// for (auto const &pair : request->buffers()) {
// v4l2_buf.timestamp.tv_sec = buf->captured_time_us / (1000LL * 1000LL);
// v4l2_buf.timestamp.tv_usec = buf->captured_time_us % (1000LL * 1000LL);
// }
if (buf->buf_list->dev->libcamera->camera->queueRequest(buf->libcamera->request.get()) < 0) {
LOG_ERROR(buf, "Can't queue buffer.");
}
@ -119,11 +113,6 @@ int libcamera_buffer_list_dequeue(buffer_list_t *buf_list, buffer_t **bufp)
}
*bufp = buf_list->bufs[index];
// TODO: fix timestamps
// buf->v4l2->flags = v4l2_buf.flags;
// buf->flags.is_keyframe = (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0;
// buf->captured_time_us = get_time_us(CLOCK_FROM_PARAMS, NULL, &v4l2_buf.timestamp, 0);
return 0;
}

View File

@ -88,7 +88,7 @@ int libcamera_buffer_list_set_stream(buffer_list_t *buf_list, bool do_on)
buf_list->dev->libcamera->camera->requestCompleted.connect(
buf_list->libcamera, &buffer_list_libcamera_t::libcamera_buffer_list_dequeued);
if (buf_list->dev->libcamera->camera->start() < 0) {
if (buf_list->dev->libcamera->camera->start(&buf_list->dev->libcamera->controls) < 0) {
LOG_ERROR(buf_list, "Failed to start camera.");
}
} else {