Fix memory issues
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(libmegapixels C)
|
||||
|
||||
set(LIBRARY_VERSION_MAJOR 0)
|
||||
|
@@ -42,10 +42,17 @@ struct _lmp_mode {
|
||||
uint32_t media_busfmt;
|
||||
|
||||
int num_cmds;
|
||||
libmegapixels_cmd *cmds;
|
||||
libmegapixels_cmd **cmds;
|
||||
};
|
||||
typedef struct _lmp_mode libmegapixels_mode;
|
||||
|
||||
struct _lmp_subdev {
|
||||
char *path;
|
||||
int fd;
|
||||
uint32_t entity_id;
|
||||
};
|
||||
typedef struct _lmp_subdev libmegapixels_subdev;
|
||||
|
||||
struct _lmp_camera {
|
||||
char *name;
|
||||
char *sensor_name;
|
||||
@@ -59,7 +66,10 @@ struct _lmp_camera {
|
||||
int video_fd;
|
||||
|
||||
int num_modes;
|
||||
libmegapixels_mode *modes;
|
||||
libmegapixels_mode **modes;
|
||||
|
||||
int num_handles;
|
||||
libmegapixels_subdev **handles;
|
||||
};
|
||||
typedef struct _lmp_camera libmegapixels_camera;
|
||||
|
||||
|
74
src/parse.c
74
src/parse.c
@@ -129,10 +129,37 @@ find_media_node(libmegapixels_camera *camera, const char *media_name, const char
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO: find /dev path for this entity
|
||||
break;
|
||||
}
|
||||
}
|
||||
camera->num_handles = 0;
|
||||
for (int i = 0; i < topology.num_links; i++) {
|
||||
if (!(links[i].flags & MEDIA_LNK_FL_INTERFACE_LINK)) {
|
||||
continue;
|
||||
}
|
||||
camera->num_handles++;
|
||||
}
|
||||
|
||||
camera->handles = calloc(camera->num_handles, sizeof(libmegapixels_subdev));
|
||||
int h = 0;
|
||||
for (int i = 0; i < topology.num_links; i++) {
|
||||
if (!(links[i].flags & MEDIA_LNK_FL_INTERFACE_LINK)) {
|
||||
continue;
|
||||
}
|
||||
libmegapixels_subdev *sd;
|
||||
sd = malloc(sizeof(libmegapixels_subdev));
|
||||
camera->handles[h] = sd;
|
||||
camera->handles[h]->entity_id = links[i].sink_id;
|
||||
camera->handles[h]->fd = 0;
|
||||
|
||||
for (int j = 0; j < topology.num_interfaces; j++) {
|
||||
if (links[i].source_id != interfaces[j].id) {
|
||||
continue;
|
||||
}
|
||||
camera->handles[h]->path = find_path_for_devnode(interfaces[j].devnode);
|
||||
}
|
||||
h++;
|
||||
}
|
||||
|
||||
close(media_fd);
|
||||
if (found == 2) {
|
||||
@@ -159,6 +186,10 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
|
||||
}
|
||||
libmegapixels_camera *camera;
|
||||
camera = malloc(sizeof(libmegapixels_camera));
|
||||
camera->sensor_fd = 0;
|
||||
camera->media_fd = 0;
|
||||
camera->video_fd = 0;
|
||||
|
||||
int res = find_media_node(camera, bridge_driver, sensor_driver);
|
||||
if (res < 0) {
|
||||
free(camera);
|
||||
@@ -178,7 +209,7 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
|
||||
config_setting_t *mode;
|
||||
|
||||
int num_modes = config_setting_length(modes);
|
||||
camera->modes = malloc(num_modes * sizeof(libmegapixels_mode));
|
||||
camera->modes = malloc(num_modes * sizeof(libmegapixels_mode *));
|
||||
camera->num_modes = num_modes;
|
||||
int n = 0;
|
||||
while (1) {
|
||||
@@ -186,31 +217,33 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
|
||||
if (mode == NULL) {
|
||||
break;
|
||||
}
|
||||
if (!config_setting_lookup_int(mode, "Width", &(camera->modes[n].width))) {
|
||||
libmegapixels_mode *mm = malloc(sizeof(libmegapixels_mode));
|
||||
camera->modes[n] = mm;
|
||||
if (!config_setting_lookup_int(mode, "Width", &mm->width)) {
|
||||
return -1;
|
||||
}
|
||||
if (!config_setting_lookup_int(mode, "Height", &(camera->modes[n].height))) {
|
||||
if (!config_setting_lookup_int(mode, "Height", &mm->height)) {
|
||||
return -1;
|
||||
}
|
||||
if (!config_setting_lookup_int(mode, "Rate", &(camera->modes[n].rate))) {
|
||||
if (!config_setting_lookup_int(mode, "Rate", &mm->rate)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *fmt;
|
||||
config_setting_lookup_string(mode, "Format", &fmt);
|
||||
camera->modes[n].v4l_pixfmt = format_name_to_v4l_pixfmt(fmt);
|
||||
camera->modes[n].media_busfmt = format_name_to_media_busfmt(fmt);
|
||||
mm->v4l_pixfmt = format_name_to_v4l_pixfmt(fmt);
|
||||
mm->media_busfmt = format_name_to_media_busfmt(fmt);
|
||||
|
||||
|
||||
if (!config_setting_lookup_int(mode, "Rotate", &(camera->modes[n].rotation))) {
|
||||
camera->modes[n].rotation = 0;
|
||||
if (!config_setting_lookup_int(mode, "Rotate", &mm->rotation)) {
|
||||
mm->rotation = 0;
|
||||
}
|
||||
|
||||
if (!config_setting_lookup_float(mode, "FocalLength", &(camera->modes[n].focal_length))) {
|
||||
camera->modes[n].focal_length = 0.0f;
|
||||
if (!config_setting_lookup_float(mode, "FocalLength", &mm->focal_length)) {
|
||||
mm->focal_length = 0.0f;
|
||||
}
|
||||
if (!config_setting_lookup_float(mode, "FNumber", &(camera->modes[n].f_number))) {
|
||||
camera->modes[n].f_number = 0.0f;
|
||||
if (!config_setting_lookup_float(mode, "FNumber", &mm->f_number)) {
|
||||
mm->f_number = 0.0f;
|
||||
}
|
||||
|
||||
config_setting_t *cmds = config_setting_lookup(mode, "Pipeline");
|
||||
@@ -223,21 +256,22 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
|
||||
}
|
||||
|
||||
int num_cmds = config_setting_length(cmds);
|
||||
camera->modes[n].cmds = malloc(num_cmds * sizeof(libmegapixels_cmd));
|
||||
camera->modes[n].num_cmds = num_cmds;
|
||||
mm->cmds = (libmegapixels_cmd **) calloc(num_cmds, sizeof(libmegapixels_cmd *));
|
||||
mm->num_cmds = num_cmds;
|
||||
int m = 0;
|
||||
while (1) {
|
||||
cmd = config_setting_get_elem(cmds, m);
|
||||
if (cmd == NULL) {
|
||||
break;
|
||||
}
|
||||
libmegapixels_cmd *cur = &(camera->modes[n].cmds[m]);
|
||||
libmegapixels_cmd *cur = calloc(1, sizeof(libmegapixels_cmd));
|
||||
mm->cmds[m] = cur;
|
||||
const char *type;
|
||||
if (!config_setting_lookup_string(cmd, "Type", &type)) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(type, "Link") == 0) {
|
||||
camera->modes[n].cmds[m].type = LIBMEGAPIXELS_CMD_LINK;
|
||||
camera->modes[n]->cmds[m]->type = LIBMEGAPIXELS_CMD_LINK;
|
||||
if (!config_setting_lookup_string(cmd, "From", &cur->entity_from)) {
|
||||
fprintf(stderr, "Missing From\n");
|
||||
break;
|
||||
@@ -253,16 +287,16 @@ load_camera(libmegapixels_devconfig *config, config_t *cfg, const char *name)
|
||||
cur->pad_to = 0;
|
||||
}
|
||||
} else if (strcmp(type, "Mode") == 0) {
|
||||
camera->modes[n].cmds[m].type = LIBMEGAPIXELS_CMD_MODE;
|
||||
camera->modes[n]->cmds[m]->type = LIBMEGAPIXELS_CMD_MODE;
|
||||
if (!config_setting_lookup_string(cmd, "Entity", &cur->entity_from)) {
|
||||
fprintf(stderr, "Missing entity\n");
|
||||
break;
|
||||
}
|
||||
if (!config_setting_lookup_int(cmd, "Width", &cur->width)) {
|
||||
cur->width = camera->modes[n].width;
|
||||
cur->width = camera->modes[n]->width;
|
||||
}
|
||||
if (!config_setting_lookup_int(cmd, "Height", &cur->height)) {
|
||||
cur->height = camera->modes[n].height;
|
||||
cur->height = camera->modes[n]->height;
|
||||
}
|
||||
}
|
||||
m++;
|
||||
|
@@ -54,10 +54,10 @@ load_entity_ids(libmegapixels_camera *camera)
|
||||
}
|
||||
|
||||
for (int i = 0; i < camera->num_modes; i++) {
|
||||
libmegapixels_mode *mode = &camera->modes[i];
|
||||
libmegapixels_mode *mode = camera->modes[i];
|
||||
|
||||
for (int j = 0; j < mode->num_cmds; j++) {
|
||||
libmegapixels_cmd *cmd = &mode->cmds[j];
|
||||
libmegapixels_cmd *cmd = mode->cmds[j];
|
||||
|
||||
if (cmd->type == LIBMEGAPIXELS_CMD_LINK) {
|
||||
int found_from = 0;
|
||||
@@ -80,6 +80,18 @@ load_entity_ids(libmegapixels_camera *camera)
|
||||
log_error("Could not find entity '%s'\n", cmd->entity_to);
|
||||
return -1;
|
||||
}
|
||||
} else if (cmd->type == LIBMEGAPIXELS_CMD_MODE) {
|
||||
int found = 0;
|
||||
for (int k = 0; k < topology.num_entities; k++) {
|
||||
if (strncmp(entities[k].name, cmd->entity_from, strlen(cmd->entity_from)) == 0) {
|
||||
cmd->entity_from_id = entities[k].id;
|
||||
found++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found != 1) {
|
||||
log_error("Could not find entity '%s'\n", cmd->entity_from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,7 +173,7 @@ unsigned int
|
||||
libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode)
|
||||
{
|
||||
for (int i = 0; i < mode->num_cmds; i++) {
|
||||
libmegapixels_cmd *cmd = &mode->cmds[i];
|
||||
libmegapixels_cmd *cmd = mode->cmds[i];
|
||||
struct v4l2_subdev_format subdev_fmt = {};
|
||||
fprintf(stderr, "Do %d\n", cmd->type);
|
||||
switch (cmd->type) {
|
||||
@@ -179,7 +191,29 @@ libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode
|
||||
subdev_fmt.format.height = cmd->height;
|
||||
subdev_fmt.format.code = mode->media_busfmt;
|
||||
subdev_fmt.format.field = V4L2_FIELD_ANY;
|
||||
if (xioctl(camera->sensor_fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt) == -1) {
|
||||
|
||||
libmegapixels_subdev *sd;
|
||||
int found = 0;
|
||||
for (int h = 0; h < camera->num_handles; h++) {
|
||||
if (camera->handles[h]->entity_id == cmd->entity_from_id) {
|
||||
sd = camera->handles[h];
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found != 1) {
|
||||
log_error("Could not find handle for entity\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (sd->fd == 0) {
|
||||
sd->fd = open(sd->path, O_RDWR);
|
||||
if (sd->fd < 0) {
|
||||
log_error("Could not open %s\n", sd->path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (xioctl(sd->fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt) == -1) {
|
||||
log_error("Could not set mode on sensor: %s\n", strerror(errno));
|
||||
}
|
||||
break;
|
||||
|
@@ -51,7 +51,7 @@ main()
|
||||
return 1;
|
||||
}
|
||||
|
||||
libmegapixels_mode *mode = &camera->modes[0];
|
||||
libmegapixels_mode *mode = camera->modes[0];
|
||||
unsigned int frame_size = libmegapixels_select_mode(camera, mode);
|
||||
if (frame_size == 0) {
|
||||
fprintf(stderr, "Could not select mode\n");
|
||||
|
Reference in New Issue
Block a user