Set MBUS formats on all media entities in the path and define SRGGB10P

This commit is contained in:
Martijn Braam 2020-11-11 16:46:42 +01:00
parent f108fe7d06
commit 89953d1c11
2 changed files with 63 additions and 22 deletions

View File

@ -8,6 +8,6 @@ media-driver=qcom-camss
width=4096
height=2304
rate=30
fmt=RGGB8
fmt=RGGB10P
rotate=270
media-links=msm_csiphy0:1->msm_csid0:0,msm_csid0:1->msm_ispif0:0,msm_ispif0:1->msm_vfe0_rdi0:0

83
main.c
View File

@ -42,6 +42,8 @@ struct mp_media_link {
int target_port;
unsigned int source_entity_id;
unsigned int target_entity_id;
char source_fname[260];
char target_fname[260];
int valid;
};
@ -473,6 +475,7 @@ init_sensor(char *fn, int width, int height, int mbus, int rate)
g_printerr("Driver chose %dx%d fmt %d instead\n",
fmt.format.width, fmt.format.height,
fmt.format.code);
// Trigger continuous auto focus if the sensor supports it
if (v4l2_has_control(fd, V4L2_CID_FOCUS_AUTO)) {
@ -501,6 +504,53 @@ init_sensor(char *fn, int width, int height, int mbus, int rate)
current.fd = fd;
}
int
find_dev_node(int maj, int min, char *fnbuf)
{
DIR *d;
struct dirent *dir;
struct stat info;
d = opendir("/dev");
while ((dir = readdir(d)) != NULL) {
sprintf(fnbuf, "/dev/%s", dir->d_name);
stat(fnbuf, &info);
if (!S_ISCHR(info.st_mode)) {
continue;
}
if (major(info.st_rdev) == maj && minor(info.st_rdev) == min) {
return 0;
}
}
return -1;
}
static void
init_media_entity(char *fn, int width, int height, int mbus)
{
int fd;
struct v4l2_subdev_format fmt = {};
fd = open(fn, O_RDWR);
// Apply mode to v4l2 subdev
g_print("Setting node to %dx%d fmt %d\n",
width, height, mbus);
fmt.pad = 0;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = mbus;
fmt.format.width = width;
fmt.format.height = height;
fmt.format.field = V4L2_FIELD_ANY;
if (xioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt) == -1) {
errno_exit("VIDIOC_SUBDEV_S_FMT");
}
if (fmt.format.width != width || fmt.format.height != height || fmt.format.code != mbus)
g_printerr("Driver chose %dx%d fmt %d instead\n",
fmt.format.width, fmt.format.height,
fmt.format.code);
}
static int
init_device(int fd)
{
@ -697,6 +747,7 @@ process_image(const int *p, int size)
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
case V4L2_PIX_FMT_SRGGB10P:
quick_debayer((const uint8_t *)p, pixels, current.fmt,
current.width, current.height, skip,
current.blacklevel);
@ -1094,6 +1145,9 @@ config_ini_handler(void *user, const char *section, const char *name,
} else if (strcmp(value, "GBRG8") == 0) {
cc->fmt = V4L2_PIX_FMT_SGBRG8;
cc->mbus = MEDIA_BUS_FMT_SGBRG8_1X8;
} else if (strcmp(value, "RGGB10P") == 0) {
cc->fmt = V4L2_PIX_FMT_SRGGB10P;
cc->mbus = MEDIA_BUS_FMT_SRGGB10_1X10;
} else if (strcmp(value, "UYVY") == 0) {
cc->fmt = V4L2_PIX_FMT_UYVY;
cc->mbus = MEDIA_BUS_FMT_UYVY8_2X8;
@ -1172,26 +1226,6 @@ config_ini_handler(void *user, const char *section, const char *name,
return 1;
}
int
find_dev_node(int maj, int min, char *fnbuf)
{
DIR *d;
struct dirent *dir;
struct stat info;
d = opendir("/dev");
while ((dir = readdir(d)) != NULL) {
sprintf(fnbuf, "/dev/%s", dir->d_name);
stat(fnbuf, &info);
if (!S_ISCHR(info.st_mode)) {
continue;
}
if (major(info.st_rdev) == maj && minor(info.st_rdev) == min) {
return 0;
}
}
return -1;
}
int
setup_camera(int cid)
{
@ -1226,6 +1260,8 @@ setup_camera(int cid)
link.sink.entity = cameras[cid].interface_entity_id;
link.sink.index = 0;
current = cameras[cid];
if (xioctl(cameras[cid].media_fd, MEDIA_IOC_SETUP_LINK, &link) < 0) {
g_printerr("[%s] Could not enable direct sensor->if link\n", cameras[cid].cfg_name);
@ -1258,9 +1294,10 @@ setup_camera(int cid)
cameras[cid].media_links[i].target_port);
}
init_media_entity(cameras[cid].media_links[i].source_fname, current.width, current.height, current.mbus);
init_media_entity(cameras[cid].media_links[i].target_fname, current.width, current.height, current.mbus);
}
}
current = cameras[cid];
// Find camera node
init_sensor(current.dev_fname, current.width, current.height, current.mbus, current.rate);
@ -1326,10 +1363,14 @@ find_camera_found_media:
if(strncmp(entity.name, cameras[cid].media_links[i].source_name,
strlen(cameras[cid].media_links[i].source_name)) == 0) {
cameras[cid].media_links[i].source_entity_id = entity.id;
find_dev_node(entity.dev.major, entity.dev.minor, cameras[cid].media_links[i].source_fname);
printf("[%s] isp: %s (%s)\n", cameras[cid].cfg_name, cameras[cid].media_links[i].source_fname, entity.name);
}
if(strncmp(entity.name, cameras[cid].media_links[i].target_name,
strlen(cameras[cid].media_links[i].target_name)) == 0) {
cameras[cid].media_links[i].target_entity_id = entity.id;
find_dev_node(entity.dev.major, entity.dev.minor, cameras[cid].media_links[i].target_fname);
printf("[%s] isp: %s (%s)\n", cameras[cid].cfg_name, cameras[cid].media_links[i].target_fname, entity.name);
}
}
}