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 *
mp_device_find(const char *driver_name)
mp_device_find(const char *driver_name, const char *dev_name)
{
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);
@@ -476,7 +477,9 @@ mp_device_list_free(MPDeviceList *device_list)
}
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;
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);
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);
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;
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_new(int fd);
void mp_device_close(MPDevice *device);
@@ -74,7 +74,8 @@ MPDeviceList *mp_device_list_new();
void mp_device_list_free(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_get(const MPDeviceList *device_list);

View File

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

View File

@@ -19,22 +19,18 @@ get_time()
int
main(int argc, char *argv[])
{
if (argc != 2 && argc != 3) {
printf("Usage: %s <media_device_name> [<sub_device_name>]\n",
argv[0]);
if (argc != 3) {
printf("Usage: %s <media_device_name> <sub_device_name>\n", argv[0]);
return 1;
}
char *video_name = argv[1];
char *subdev_name = NULL;
if (argc == 3) {
subdev_name = argv[2];
}
char *subdev_name = argv[2];
double find_start = get_time();
// First find the device
MPDevice *device = mp_device_find(video_name);
MPDevice *device = mp_device_find(video_name, subdev_name);
if (!device) {
printf("Device not found\n");
return 1;
@@ -73,50 +69,46 @@ main(int argc, char *argv[])
}
int subdev_fd = -1;
if (subdev_name) {
const struct media_v2_entity *entity =
mp_device_find_entity(device, subdev_name);
if (!entity) {
printf("Unable to find sub-device\n");
return 1;
const struct media_v2_entity *entity =
mp_device_find_entity(device, subdev_name);
if (!entity) {
printf("Unable to find sub-device\n");
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 =
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);
// Then enable ours
mp_device_setup_link(device, source_pad->id, sink_pad->id, true);
// 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_interface *iface =
mp_device_find_entity_interface(device, entity->id);
// Then enable ours
mp_device_setup_link(device, source_pad->id, sink_pad->id, true);
char buf[256];
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 =
mp_device_find_entity_interface(device, entity->id);
char buf[256];
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;
}
subdev_fd = open(buf, O_RDWR);
if (subdev_fd == -1) {
printf("Unable to open sub-device\n");
return 1;
}
double open_end = get_time();