2020-10-24 05:36:28 +02:00
|
|
|
#include "device.h"
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
bool
|
|
|
|
mp_find_device_path(struct media_v2_intf_devnode devnode, char *path, int length)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
char uevent_path[256];
|
|
|
|
snprintf(uevent_path, 256, "/sys/dev/char/%d:%d/uevent", devnode.major,
|
|
|
|
devnode.minor);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
FILE *f = fopen(uevent_path, "r");
|
|
|
|
if (!f) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
char line[512];
|
|
|
|
while (fgets(line, 512, f)) {
|
|
|
|
if (strncmp(line, "DEVNAME=", 8) == 0) {
|
|
|
|
// Drop newline
|
|
|
|
int length = strlen(line);
|
|
|
|
if (line[length - 1] == '\n')
|
|
|
|
line[length - 1] = '\0';
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
snprintf(path, length, "/dev/%s", line + 8);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
fclose(f);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
return false;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct _MPDevice {
|
2020-12-06 15:44:31 +01:00
|
|
|
int fd;
|
|
|
|
|
|
|
|
struct media_device_info info;
|
|
|
|
|
|
|
|
struct media_v2_entity *entities;
|
|
|
|
size_t num_entities;
|
|
|
|
struct media_v2_interface *interfaces;
|
|
|
|
size_t num_interfaces;
|
|
|
|
struct media_v2_pad *pads;
|
|
|
|
size_t num_pads;
|
|
|
|
struct media_v2_link *links;
|
|
|
|
size_t num_links;
|
2020-10-24 05:36:28 +02:00
|
|
|
};
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
static void
|
|
|
|
errno_printerr(const char *s)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
g_printerr("MPDevice: %s error %d, %s\n", s, errno, strerror(errno));
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
static int
|
|
|
|
xioctl(int fd, int request, void *arg)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
int r;
|
|
|
|
do {
|
|
|
|
r = ioctl(fd, request, arg);
|
|
|
|
} while (r == -1 && errno == EINTR);
|
|
|
|
return r;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *
|
|
|
|
mp_device_find(const char *driver_name)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDeviceList *list = mp_device_list_new();
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *found_device = mp_device_list_find_remove(&list, driver_name);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
mp_device_list_free(list);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
return found_device;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *
|
|
|
|
mp_device_open(const char *path)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
int fd = open(path, O_RDWR);
|
|
|
|
if (fd == -1) {
|
|
|
|
errno_printerr("open");
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
return mp_device_new(fd);
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *
|
|
|
|
mp_device_new(int fd)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
// Get the topology of the media device
|
|
|
|
struct media_v2_topology topology = {};
|
|
|
|
if (xioctl(fd, MEDIA_IOC_G_TOPOLOGY, &topology) == -1 ||
|
|
|
|
topology.num_entities == 0) {
|
|
|
|
close(fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
// Create the device
|
|
|
|
MPDevice *device = calloc(1, sizeof(MPDevice));
|
|
|
|
device->fd = fd;
|
|
|
|
device->entities =
|
|
|
|
calloc(topology.num_entities, sizeof(struct media_v2_entity));
|
|
|
|
device->num_entities = topology.num_entities;
|
|
|
|
device->interfaces =
|
|
|
|
calloc(topology.num_interfaces, sizeof(struct media_v2_interface));
|
|
|
|
device->num_interfaces = topology.num_interfaces;
|
|
|
|
device->pads = calloc(topology.num_pads, sizeof(struct media_v2_pad));
|
|
|
|
device->num_pads = topology.num_pads;
|
|
|
|
device->links = calloc(topology.num_links, sizeof(struct media_v2_link));
|
|
|
|
device->num_links = topology.num_links;
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
// Get the actual devices and interfaces
|
|
|
|
topology.ptr_entities = (uint64_t)device->entities;
|
|
|
|
topology.ptr_interfaces = (uint64_t)device->interfaces;
|
|
|
|
topology.ptr_pads = (uint64_t)device->pads;
|
|
|
|
topology.ptr_links = (uint64_t)device->links;
|
|
|
|
if (xioctl(fd, MEDIA_IOC_G_TOPOLOGY, &topology) == -1) {
|
|
|
|
errno_printerr("MEDIA_IOC_G_TOPOLOGY");
|
|
|
|
mp_device_close(device);
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
// Get device info
|
|
|
|
if (xioctl(fd, MEDIA_IOC_DEVICE_INFO, &device->info) == -1) {
|
|
|
|
errno_printerr("MEDIA_IOC_DEVICE_INFO");
|
|
|
|
mp_device_close(device);
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
return device;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
void
|
|
|
|
mp_device_close(MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
close(device->fd);
|
|
|
|
free(device->entities);
|
|
|
|
free(device->interfaces);
|
|
|
|
free(device->pads);
|
|
|
|
free(device->links);
|
|
|
|
free(device);
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
bool
|
|
|
|
mp_device_setup_link(MPDevice *device, uint32_t source_pad_id, uint32_t sink_pad_id,
|
|
|
|
bool enabled)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_pad *source_pad =
|
|
|
|
mp_device_get_pad(device, source_pad_id);
|
|
|
|
g_return_val_if_fail(source_pad, false);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_pad *sink_pad = mp_device_get_pad(device, sink_pad_id);
|
|
|
|
g_return_val_if_fail(sink_pad, false);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
struct media_link_desc link = {};
|
|
|
|
link.flags = enabled ? MEDIA_LNK_FL_ENABLED : 0;
|
|
|
|
link.source.entity = source_pad->entity_id;
|
|
|
|
link.source.index = 0;
|
|
|
|
link.sink.entity = sink_pad->entity_id;
|
|
|
|
link.sink.index = 0;
|
|
|
|
if (xioctl(device->fd, MEDIA_IOC_SETUP_LINK, &link) == -1) {
|
|
|
|
errno_printerr("MEDIA_IOC_SETUP_LINK");
|
|
|
|
return false;
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
return true;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_entity *
|
|
|
|
mp_device_find_entity(const MPDevice *device, const char *driver_name)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
int length = strlen(driver_name);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
// Find the entity from the name
|
|
|
|
for (uint32_t i = 0; i < device->num_entities; ++i) {
|
|
|
|
if (strncmp(device->entities[i].name, driver_name, length) == 0) {
|
|
|
|
return &device->entities[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_entity *
|
|
|
|
mp_device_find_entity_type(const MPDevice *device, const uint32_t type)
|
2020-11-28 18:57:11 +01:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
// Find the entity from the entity type
|
|
|
|
for (uint32_t i = 0; i < device->num_entities; ++i) {
|
|
|
|
if (device->entities[i].function == type) {
|
|
|
|
return &device->entities[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-11-28 18:57:11 +01:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_device_info *
|
|
|
|
mp_device_get_info(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return &device->info;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_entity *
|
|
|
|
mp_device_get_entity(const MPDevice *device, uint32_t id)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
for (int i = 0; i < device->num_entities; ++i) {
|
|
|
|
if (device->entities[i].id == id) {
|
|
|
|
return &device->entities[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_entity *
|
|
|
|
mp_device_get_entities(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device->entities;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
size_t
|
|
|
|
mp_device_get_num_entities(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device->num_entities;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_interface *
|
|
|
|
mp_device_find_entity_interface(const MPDevice *device, uint32_t entity_id)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
// Find the interface through the link
|
|
|
|
const struct media_v2_link *link = mp_device_find_link_to(device, entity_id);
|
|
|
|
if (!link) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return mp_device_get_interface(device, link->source_id);
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_interface *
|
|
|
|
mp_device_get_interface(const MPDevice *device, uint32_t id)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
for (int i = 0; i < device->num_interfaces; ++i) {
|
|
|
|
if (device->interfaces[i].id == id) {
|
|
|
|
return &device->interfaces[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_interface *
|
|
|
|
mp_device_get_interfaces(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device->interfaces;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
size_t
|
|
|
|
mp_device_get_num_interfaces(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device->num_interfaces;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_pad *
|
|
|
|
mp_device_get_pad_from_entity(const MPDevice *device, uint32_t entity_id)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
for (int i = 0; i < device->num_pads; ++i) {
|
|
|
|
if (device->pads[i].entity_id == entity_id) {
|
|
|
|
return &device->pads[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_pad *
|
|
|
|
mp_device_get_pad(const MPDevice *device, uint32_t id)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
for (int i = 0; i < device->num_pads; ++i) {
|
|
|
|
if (device->pads[i].id == id) {
|
|
|
|
return &device->pads[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_pad *
|
|
|
|
mp_device_get_pads(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device->pads;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
size_t
|
|
|
|
mp_device_get_num_pads(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device->num_pads;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_link *
|
|
|
|
mp_device_find_entity_link(const MPDevice *device, uint32_t entity_id)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_pad *pad =
|
|
|
|
mp_device_get_pad_from_entity(device, entity_id);
|
|
|
|
const struct media_v2_link *link = mp_device_find_link_to(device, pad->id);
|
|
|
|
if (link) {
|
|
|
|
return link;
|
|
|
|
}
|
|
|
|
return mp_device_find_link_from(device, pad->id);
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_link *
|
|
|
|
mp_device_find_link_from(const MPDevice *device, uint32_t source)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
for (int i = 0; i < device->num_links; ++i) {
|
|
|
|
if (device->links[i].source_id == source) {
|
|
|
|
return &device->links[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_link *
|
|
|
|
mp_device_find_link_to(const MPDevice *device, uint32_t sink)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
for (int i = 0; i < device->num_links; ++i) {
|
|
|
|
if (device->links[i].sink_id == sink) {
|
|
|
|
return &device->links[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_link *
|
|
|
|
mp_device_find_link_between(const MPDevice *device, uint32_t source, uint32_t sink)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
for (int i = 0; i < device->num_links; ++i) {
|
|
|
|
if (device->links[i].source_id == source &&
|
|
|
|
device->links[i].sink_id == sink) {
|
|
|
|
return &device->links[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_link *
|
|
|
|
mp_device_get_link(const MPDevice *device, uint32_t id)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
for (int i = 0; i < device->num_links; ++i) {
|
|
|
|
if (device->links[i].id == id) {
|
|
|
|
return &device->links[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
const struct media_v2_link *
|
|
|
|
mp_device_get_links(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device->links;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
size_t
|
|
|
|
mp_device_get_num_links(const MPDevice *device)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device->num_links;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct _MPDeviceList {
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *device;
|
|
|
|
MPDeviceList *next;
|
2020-10-24 05:36:28 +02:00
|
|
|
};
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDeviceList *
|
|
|
|
mp_device_list_new()
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDeviceList *current = NULL;
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
// Enumerate media device files
|
|
|
|
struct dirent *dir;
|
|
|
|
DIR *d = opendir("/dev");
|
|
|
|
while ((dir = readdir(d)) != NULL) {
|
|
|
|
if (strncmp(dir->d_name, "media", 5) == 0) {
|
|
|
|
char path[261];
|
|
|
|
snprintf(path, 261, "/dev/%s", dir->d_name);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *device = mp_device_open(path);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
if (device) {
|
|
|
|
MPDeviceList *next = malloc(sizeof(MPDeviceList));
|
|
|
|
next->device = device;
|
|
|
|
next->next = current;
|
|
|
|
current = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(d);
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
return current;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
void
|
|
|
|
mp_device_list_free(MPDeviceList *device_list)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
while (device_list) {
|
|
|
|
MPDeviceList *tmp = device_list;
|
|
|
|
device_list = tmp->next;
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
mp_device_close(tmp->device);
|
|
|
|
free(tmp);
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *
|
|
|
|
mp_device_list_find_remove(MPDeviceList **list, const char *driver_name)
|
2020-11-25 14:31:52 +01:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *found_device = NULL;
|
|
|
|
int length = strlen(driver_name);
|
2020-11-25 14:31:52 +01:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
while (*list) {
|
|
|
|
MPDevice *device = mp_device_list_get(*list);
|
|
|
|
const struct media_device_info *info = mp_device_get_info(device);
|
2020-11-25 14:31:52 +01:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
if (strncmp(info->driver, driver_name, length) == 0) {
|
|
|
|
found_device = mp_device_list_remove(list);
|
|
|
|
break;
|
|
|
|
}
|
2020-11-25 14:31:52 +01:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
list = &(*list)->next;
|
|
|
|
}
|
2020-11-25 14:31:52 +01:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
return found_device;
|
2020-11-25 14:31:52 +01:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *
|
|
|
|
mp_device_list_remove(MPDeviceList **device_list)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *device = (*device_list)->device;
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
if ((*device_list)->next) {
|
|
|
|
MPDeviceList *tmp = (*device_list)->next;
|
|
|
|
**device_list = *tmp;
|
|
|
|
free(tmp);
|
|
|
|
} else {
|
|
|
|
free(*device_list);
|
|
|
|
*device_list = NULL;
|
|
|
|
}
|
2020-10-24 05:36:28 +02:00
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
return device;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDevice *
|
|
|
|
mp_device_list_get(const MPDeviceList *device_list)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device_list->device;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 15:44:31 +01:00
|
|
|
MPDeviceList *
|
|
|
|
mp_device_list_next(const MPDeviceList *device_list)
|
2020-10-24 05:36:28 +02:00
|
|
|
{
|
2020-12-06 15:44:31 +01:00
|
|
|
return device_list->next;
|
2020-10-24 05:36:28 +02:00
|
|
|
}
|