Implement FAKE_CAMERA_SENSOR to allow fake image sensor used

Example, make `arducam_64mp` to behave as `imx519` as `imx519`
does have auto exposure control:

```
FAKE_CAMERA_SENSOR=arducam_64mp=imx519
```
This commit is contained in:
Kamil Trzcinski 2022-07-14 14:18:13 +02:00
parent 4e641dea1e
commit 6530e5f5b6

View File

@ -0,0 +1,65 @@
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <linux/media.h>
#include "opts/log.h"
// This is special code to force `libcamera` to think that given sensor is different
// ex.: fake `arducam_64mp` to be run as `imx519`
void fake_camera_sensor(struct media_v2_topology *topology)
{
struct media_v2_entity *ents = (struct media_v2_entity *)topology->ptr_entities;
if (!ents) {
return;
}
const char *fake_camera = getenv("FAKE_CAMERA_SENSOR");
if (!fake_camera) {
return;
}
char source[256];
sprintf(source, fake_camera);
char *target = strstr(source, "=");
if (!target) {
return;
}
*target++ = ' ';
for (int i = 0; i < topology->num_entities; i++) {
if (strncmp(ents[i].name, source, target-source) != 0) {
continue;
}
char name[sizeof(ents[i].name)];
strcpy(name, target);
strcat(name, " ");
strcat(name, ents[i].name + (target-source));
LOG_INFO(NULL, "Rewrote entity (%d): %s => %s", i, ents[i].name, name);
strcpy(ents[i].name, name);
}
}
int ioctl (int fd, unsigned long int req, ...)
{
void *arg;
va_list ap;
va_start(ap, req);
arg = va_arg(ap, void *);
va_end(ap);
int ret = syscall(SYS_ioctl, fd, req, arg);
if (!ret && req == MEDIA_IOC_G_TOPOLOGY) {
fake_camera_sensor(arg);
}
return ret;
}