# ISP User Guide

## Overview

This guide aims to help users understand and use the K230 Linux ISP functionality. The main content includes how to use the V4L2 ISP (Video Processing Unit) interface.
Through this guide, users will be able to:

- Master the usage of V4L2 ISP, including image capture and display, and a V4L2 ISP demo demonstration is provided

## V4L2 ISP User Guide

### V4l2 ISP Setting crop

The crop of this ISP is a hardware crop, and the usage flow is sensor input ---> crop --->scaler--->output. The ISP pipe follows this process.

There are two ways to set crop via V4L2. One is through the VIDIOC_S_CROP method, and the code implementation is as follows:

```shell
struct v4l2_crop crop;
struct v4l2_cropcap cropcap;

memset (&cropcap, 0, sizeof (cropcap));
cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;

if (-1 == ioctl (context[i].video_fd, VIDIOC_CROPCAP, &cropcap)) {
    perror ("VIDIOC_CROPCAP");
}

memset (&crop, 0, sizeof (crop));
crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
crop.c = cropcap.defrect;

crop.c.width = context[i].crop_size.width;
crop.c.height = context[i].crop_size.height;
crop.c.left = context[i].crop_size.offset_x;
crop.c.top = context[i].crop_size.offset_y;

/* Ignore if cropping is not supported (EINVAL). */

if (-1 == ioctl (context[i].video_fd, VIDIOC_S_CROP, &crop)
    && errno != EINVAL) {
    perror ("VIDIOC_S_CROP");
}
printf("set crop crop.c.height is %d \n", crop.c.height);

```

The other way is implemented using VIDIOC_S_SELECTION. The code is as follows:

```shell
struct v4l2_selection sel = {
    .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
    .target = V4L2_SEL_TGT_COMPOSE_BOUNDS,
};
struct v4l2_rect r;
int ret = 0;

ret = ioctl(context[i].video_fd, VIDIOC_G_SELECTION, &sel);
if(ret < 0)
    printf("get VIDIOC_G_SELECTION err \n");

/* setting smaller compose rectangle */
r.width = context[i].crop_size.width;
r.height = context[i].crop_size.height;
r.left = context[i].crop_size.offset_x;
r.top = context[i].crop_size.offset_y;

sel.r = r;
sel.target = V4L2_SEL_TGT_COMPOSE;
sel.flags = V4L2_SEL_FLAG_LE;

ret = ioctl(context[i].video_fd, VIDIOC_S_SELECTION, &sel);
if(ret < 0)
    printf("get VIDIOC_S_SELECTION err \n");

```

Currently, both of these two methods are supported in V4L2. The注意事项 (items to note) are as follows:

- Setting crop needs to be done before setting VIDIOC_S_FMT
- For the VIDIOC_S_SELECTION method, the target value currently only supports V4L2_SEL_TGT_COMPOSE. Setting other values will return an error
- The crop size set must be larger than the ISP output size (the size set by VIDIOC_S_FMT) and smaller than the sensor output size

The test command is as follows:

```shell
v4l2-drm -d 1 -w 640 -h 480 -x 0 -y 0 --crop-width 1280 --crop-height 960
```
