device: Always use a pair of driver and subdev names to find the device (MR 9)

Otherwise Megapixels fails to find the correct device on systems where
there are multiple media devices handled by the same driver, like imx8mq.
This commit is contained in:
Sebastian Krzyszkowiak
2022-01-21 15:03:32 +01:00
committed by Martijn Braam
parent e75eb375de
commit 1dc3d3d455
4 changed files with 58 additions and 57 deletions

View File

@@ -74,11 +74,12 @@ xioctl(int fd, int request, void *arg)
} }
MPDevice * MPDevice *
mp_device_find(const char *driver_name) mp_device_find(const char *driver_name, const char *dev_name)
{ {
MPDeviceList *list = mp_device_list_new(); MPDeviceList *list = mp_device_list_new();
MPDevice *found_device = mp_device_list_find_remove(&list, driver_name); MPDevice *found_device =
mp_device_list_find_remove(&list, driver_name, dev_name);
mp_device_list_free(list); mp_device_list_free(list);
@@ -476,7 +477,9 @@ mp_device_list_free(MPDeviceList *device_list)
} }
MPDevice * MPDevice *
mp_device_list_find_remove(MPDeviceList **list, const char *driver_name) mp_device_list_find_remove(MPDeviceList **list,
const char *driver_name,
const char *dev_name)
{ {
MPDevice *found_device = NULL; MPDevice *found_device = NULL;
int length = strlen(driver_name); int length = strlen(driver_name);
@@ -485,7 +488,8 @@ mp_device_list_find_remove(MPDeviceList **list, const char *driver_name)
MPDevice *device = mp_device_list_get(*list); MPDevice *device = mp_device_list_get(*list);
const struct media_device_info *info = mp_device_get_info(device); const struct media_device_info *info = mp_device_get_info(device);
if (strncmp(info->driver, driver_name, length) == 0) { if (strncmp(info->driver, driver_name, length) == 0 &&
mp_device_find_entity(device, dev_name)) {
found_device = mp_device_list_remove(list); found_device = mp_device_list_remove(list);
break; break;
} }

View File

@@ -12,7 +12,7 @@ mp_find_device_path(struct media_v2_intf_devnode devnode, char *path, int length
typedef struct _MPDevice MPDevice; typedef struct _MPDevice MPDevice;
MPDevice *mp_device_find(const char *driver_name); MPDevice *mp_device_find(const char *driver_name, const char *dev_name);
MPDevice *mp_device_open(const char *path); MPDevice *mp_device_open(const char *path);
MPDevice *mp_device_new(int fd); MPDevice *mp_device_new(int fd);
void mp_device_close(MPDevice *device); void mp_device_close(MPDevice *device);
@@ -74,7 +74,8 @@ MPDeviceList *mp_device_list_new();
void mp_device_list_free(MPDeviceList *device_list); void mp_device_list_free(MPDeviceList *device_list);
MPDevice *mp_device_list_find_remove(MPDeviceList **device_list, MPDevice *mp_device_list_find_remove(MPDeviceList **device_list,
const char *driver_name); const char *driver_name,
const char *dev_name);
MPDevice *mp_device_list_remove(MPDeviceList **device_list); MPDevice *mp_device_list_remove(MPDeviceList **device_list);
MPDevice *mp_device_list_get(const MPDeviceList *device_list); MPDevice *mp_device_list_get(const MPDeviceList *device_list);

View File

@@ -54,6 +54,7 @@ struct camera_info {
struct device_info { struct device_info {
const char *media_dev_name; // owned by camera config const char *media_dev_name; // owned by camera config
const char *dev_name; // owned by camera config
MPDevice *device; MPDevice *device;
@@ -132,8 +133,10 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
// Find device info // Find device info
size_t device_index = 0; size_t device_index = 0;
for (; device_index < num_devices; ++device_index) { for (; device_index < num_devices; ++device_index) {
if (strcmp(config->media_dev_name, if ((strcmp(config->media_dev_name,
devices[device_index].media_dev_name) == 0) { devices[device_index].media_dev_name) == 0) &&
(strcmp(config->dev_name, devices[device_index].dev_name) ==
0)) {
break; break;
} }
} }
@@ -144,8 +147,9 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
// Initialize new device // Initialize new device
struct device_info *info = &devices[device_index]; struct device_info *info = &devices[device_index];
info->media_dev_name = config->media_dev_name; info->media_dev_name = config->media_dev_name;
info->device = mp_device_list_find_remove(device_list, info->dev_name = config->dev_name;
info->media_dev_name); info->device = mp_device_list_find_remove(
device_list, info->media_dev_name, info->dev_name);
if (!info->device) { if (!info->device) {
g_printerr("Could not find /dev/media* node matching '%s'\n", g_printerr("Could not find /dev/media* node matching '%s'\n",
info->media_dev_name); info->media_dev_name);

View File

@@ -19,22 +19,18 @@ get_time()
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
if (argc != 2 && argc != 3) { if (argc != 3) {
printf("Usage: %s <media_device_name> [<sub_device_name>]\n", printf("Usage: %s <media_device_name> <sub_device_name>\n", argv[0]);
argv[0]);
return 1; return 1;
} }
char *video_name = argv[1]; char *video_name = argv[1];
char *subdev_name = NULL; char *subdev_name = argv[2];
if (argc == 3) {
subdev_name = argv[2];
}
double find_start = get_time(); double find_start = get_time();
// First find the device // First find the device
MPDevice *device = mp_device_find(video_name); MPDevice *device = mp_device_find(video_name, subdev_name);
if (!device) { if (!device) {
printf("Device not found\n"); printf("Device not found\n");
return 1; return 1;
@@ -73,50 +69,46 @@ main(int argc, char *argv[])
} }
int subdev_fd = -1; int subdev_fd = -1;
if (subdev_name) { const struct media_v2_entity *entity =
const struct media_v2_entity *entity = mp_device_find_entity(device, subdev_name);
mp_device_find_entity(device, subdev_name); if (!entity) {
if (!entity) { printf("Unable to find sub-device\n");
printf("Unable to find sub-device\n"); return 1;
return 1; }
const struct media_v2_pad *source_pad =
mp_device_get_pad_from_entity(device, entity->id);
const struct media_v2_pad *sink_pad =
mp_device_get_pad_from_entity(device, video_entity_id);
// Disable other links
const struct media_v2_entity *entities = mp_device_get_entities(device);
for (int i = 0; i < mp_device_get_num_entities(device); ++i) {
if (entities[i].id != video_entity_id &&
entities[i].id != entity->id) {
const struct media_v2_pad *pad =
mp_device_get_pad_from_entity(device,
entities[i].id);
mp_device_setup_link(device, pad->id, sink_pad->id, false);
} }
}
const struct media_v2_pad *source_pad = // Then enable ours
mp_device_get_pad_from_entity(device, entity->id); mp_device_setup_link(device, source_pad->id, sink_pad->id, true);
const struct media_v2_pad *sink_pad =
mp_device_get_pad_from_entity(device, video_entity_id);
// Disable other links const struct media_v2_interface *iface =
const struct media_v2_entity *entities = mp_device_find_entity_interface(device, entity->id);
mp_device_get_entities(device);
for (int i = 0; i < mp_device_get_num_entities(device); ++i) {
if (entities[i].id != video_entity_id &&
entities[i].id != entity->id) {
const struct media_v2_pad *pad =
mp_device_get_pad_from_entity(
device, entities[i].id);
mp_device_setup_link(
device, pad->id, sink_pad->id, false);
}
}
// Then enable ours char buf[256];
mp_device_setup_link(device, source_pad->id, sink_pad->id, true); if (!mp_find_device_path(iface->devnode, buf, 256)) {
printf("Unable to find sub-device path\n");
return 1;
}
const struct media_v2_interface *iface = subdev_fd = open(buf, O_RDWR);
mp_device_find_entity_interface(device, entity->id); if (subdev_fd == -1) {
printf("Unable to open sub-device\n");
char buf[256]; return 1;
if (!mp_find_device_path(iface->devnode, buf, 256)) {
printf("Unable to find sub-device path\n");
return 1;
}
subdev_fd = open(buf, O_RDWR);
if (subdev_fd == -1) {
printf("Unable to open sub-device\n");
return 1;
}
} }
double open_end = get_time(); double open_end = get_time();