From 863acbbde5737579f3a9ab095058770a4e98cb55 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Tue, 5 Apr 2022 11:26:06 +0200 Subject: [PATCH] Improve ISP compatibility (fractional resizing) --- cmd/camera.h | 4 ++-- cmd/camera_srgb_isp.c | 10 +++++----- cmd/camera_srgb_legacy_isp.c | 6 +++--- cmd/main.c | 14 ++++++++------ hw/buffer_list.c | 11 ++++++----- hw/v4l2.c | 5 +++++ hw/v4l2.h | 1 + 7 files changed, 30 insertions(+), 21 deletions(-) diff --git a/cmd/camera.h b/cmd/camera.h index 418960f..cbe33c3 100644 --- a/cmd/camera.h +++ b/cmd/camera.h @@ -43,7 +43,7 @@ typedef struct camera_s { void camera_init(camera_t *camera); void camera_close(camera_t *camera); int camera_open(camera_t *camera, const char *path); -int camera_configure_srgb_isp(camera_t *camera, bool use_half); -int camera_configure_srgb_legacy_isp(camera_t *camera); +int camera_configure_srgb_isp(camera_t *camera, float high_div, float low_div); +int camera_configure_srgb_legacy_isp(camera_t *camera, float div); int camera_set_params(camera_t *camera); int camera_run(camera_t *camera); diff --git a/cmd/camera_srgb_isp.c b/cmd/camera_srgb_isp.c index 5f00aa8..96fd1e5 100644 --- a/cmd/camera_srgb_isp.c +++ b/cmd/camera_srgb_isp.c @@ -12,7 +12,7 @@ extern bool check_streaming(); void write_yuvu(buffer_t *buffer); -int camera_configure_srgb_isp(camera_t *camera, bool use_half) +int camera_configure_srgb_isp(camera_t *camera, float high_div, float low_div) { if (device_open_buffer_list(camera->camera, true, camera->width, camera->height, V4L2_PIX_FMT_SRGGB10P, 0, camera->nbufs) < 0) { return -1; @@ -26,14 +26,14 @@ int camera_configure_srgb_isp(camera_t *camera, bool use_half) camera->codec_h264 = device_open("H264", "/dev/video11"); if (device_open_buffer_list(camera->isp.isp_srgb, false, src->fmt_width, src->fmt_height, src->fmt_format, src->fmt_bytesperline, camera->nbufs) < 0 || - device_open_buffer_list(camera->isp.isp_yuuv, true, src->fmt_width, src->fmt_height, V4L2_PIX_FMT_YUYV, 0, camera->nbufs) < 0) { + device_open_buffer_list(camera->isp.isp_yuuv, true, src->fmt_width / high_div, src->fmt_height / high_div, V4L2_PIX_FMT_YUYV, 0, camera->nbufs) < 0) { return -1; } - if (use_half) { + if (low_div >= 1) { camera->isp.isp_yuuv_low = device_open("ISP-YUUV-LOW", "/dev/video15"); - if (device_open_buffer_list(camera->isp.isp_yuuv_low, true, src->fmt_width / 2, src->fmt_height / 2, V4L2_PIX_FMT_YUYV, 0, camera->nbufs) < 0) { + if (device_open_buffer_list(camera->isp.isp_yuuv_low, true, src->fmt_width / low_div, src->fmt_height / low_div, V4L2_PIX_FMT_YUYV, 0, camera->nbufs) < 0) { return -1; } @@ -60,7 +60,7 @@ int camera_configure_srgb_isp(camera_t *camera, bool use_half) *links++ = (link_t){ camera->camera, { camera->isp.isp_srgb }, { NULL, check_streaming } }; - if (use_half) { + if (camera->isp.isp_yuuv_low) { *links++ = (link_t){ camera->isp.isp_yuuv, { } }; *links++ = (link_t){ camera->isp.isp_yuuv_low, { camera->codec_jpeg, camera->codec_h264 }, { write_yuvu } }; } else { diff --git a/cmd/camera_srgb_legacy_isp.c b/cmd/camera_srgb_legacy_isp.c index 3a3c294..1ec9747 100644 --- a/cmd/camera_srgb_legacy_isp.c +++ b/cmd/camera_srgb_legacy_isp.c @@ -12,7 +12,7 @@ extern bool check_streaming(); void write_yuvu(buffer_t *buffer) { -#if 1 +#if 0 FILE *fp = fopen("/tmp/capture-yuyv.raw.tmp", "wb"); if (fp) { fwrite(buffer->start, 1, buffer->used, fp); @@ -22,7 +22,7 @@ void write_yuvu(buffer_t *buffer) #endif } -int camera_configure_srgb_legacy_isp(camera_t *camera) +int camera_configure_srgb_legacy_isp(camera_t *camera, float div) { if (device_open_buffer_list(camera->camera, true, camera->width, camera->height, V4L2_PIX_FMT_SRGGB10P, 0, camera->nbufs) < 0) { return -1; @@ -35,7 +35,7 @@ int camera_configure_srgb_legacy_isp(camera_t *camera) camera->codec_h264 = device_open("H264", "/dev/video11"); if (device_open_buffer_list(camera->legacy_isp.isp, false, src->fmt_width, src->fmt_height, src->fmt_format, src->fmt_bytesperline, camera->nbufs) < 0 || - device_open_buffer_list(camera->legacy_isp.isp, true, src->fmt_width, src->fmt_height, V4L2_PIX_FMT_YUYV, 0, camera->nbufs) < 0) { + device_open_buffer_list(camera->legacy_isp.isp, true, src->fmt_width / div, src->fmt_height / div, V4L2_PIX_FMT_YUYV, 0, camera->nbufs) < 0) { return -1; } diff --git a/cmd/main.c b/cmd/main.c index 8dea82b..d6650b6 100644 --- a/cmd/main.c +++ b/cmd/main.c @@ -33,20 +33,22 @@ int main(int argc, char *argv[]) camera_init(&camera); - // camera.width = 2328; - // camera.height = 1748; - // camera.nbufs = 4; + // camera.width = 1920; camera.height = 1080; + camera.width = 2328; camera.height = 1748; // 1164x874 + //camera.width = 4656; camera.height = 3496; + //camera.width = 3840; camera.height = 2160; + camera.nbufs = 4; if (camera_open(&camera, "/dev/video0") < 0) { goto error; } -#if 0 - if (camera_configure_srgb_isp(&camera, true) < 0) { +#if 1 + if (camera_configure_srgb_isp(&camera, 1.6, 0) < 0) { goto error; } #else - if (camera_configure_srgb_legacy_isp(&camera) < 0) { + if (camera_configure_srgb_legacy_isp(&camera, 1.3) < 0) { goto error; } #endif diff --git a/hw/buffer_list.c b/hw/buffer_list.c index d8517ce..6562c7b 100644 --- a/hw/buffer_list.c +++ b/hw/buffer_list.c @@ -76,11 +76,12 @@ int buffer_list_set_format(buffer_list_t *buf_list, unsigned width, unsigned hei retry: - // JPEG is in 16x16 blocks (shrink image to fit) - if (strstr(buf_list->name, "JPEG")) { - width = width / 16 * 16; - height = height / 16 * 16; - printf("JPEG: %dx%d vs %dx%d\n", orig_width, orig_height, width, height); + // JPEG is in 16x16 blocks (shrink image to fit) (but adapt to 32x32) + // And ISP output + if (strstr(buf_list->name, "JPEG") || strstr(buf_list->name, "H264") || buf_list->do_capture && strstr(buf_list->name, "ISP")) { + width = shrink_to_block(width, 32); + height = shrink_to_block(height, 32); + E_LOG_INFO(buf_list, "Adapting size to 32x32 block: %dx%d vs %dx%d", orig_width, orig_height, width, height); } if (buf_list->do_mplanes) { diff --git a/hw/v4l2.c b/hw/v4l2.c index f977364..964b6f5 100644 --- a/hw/v4l2.c +++ b/hw/v4l2.c @@ -75,6 +75,11 @@ unsigned fourcc_to_stride(unsigned width, unsigned format) } } +int shrink_to_block(int size, int block) +{ + return size / block * block; +} + uint64_t get_monotonic_time_us(struct timespec *ts, struct timeval *tv) { struct timespec now; diff --git a/hw/v4l2.h b/hw/v4l2.h index dee6f8e..5824554 100644 --- a/hw/v4l2.h +++ b/hw/v4l2.h @@ -41,6 +41,7 @@ fourcc_string fourcc_to_string(unsigned format); unsigned fourcc_to_stride(unsigned width, unsigned format); int xioctl(const char *name, int fd, int request, void *arg); uint64_t get_monotonic_time_us(struct timespec *ts, struct timeval *tv); +int shrink_to_block(int size, int block); #define E_XIOCTL(dev, _fd, _request, _value, _msg, ...) do { \ int ret; \