This section describes device enumeration, querying information about attached devices and their connection topology.
Simple Device Enumeration
The simplest way to gather information about the available video capture devices is to create a device enumerator (IC4_DEVICE_ENUM) and query the global device list.
The following code snippet shows how to get the list of devices and print device information to the console:
void print_device_list()
{
printf("Enumerating all attached video capture devices in a single list...\n");
{
printf("Failed to create device enumerator");
goto print_error;
}
{
printf("Failed to update device list");
goto print_error;
}
if (count == 0)
{
printf("No devices found\n");
goto cleanup;
}
printf("Found %d devices:\n", count);
for (int i = 0; i < count; ++i)
{
{
printf("Failed to query device info for index %d\n", i);
print_last_error();
continue;
}
printf("\t");
print_device_info(info);
printf("\n");
}
printf("\n");
goto cleanup;
print_error:
print_last_error();
cleanup:
}
The device information is printed using a simple helper function:
Query Interface/Device Topology
Device enumeration can also be performed on a per-interface basis. Interfaces are the physical pieces of hardware that cameras are attached to, e.g. USB controllers or network adapters.
Each interface can in turn be queried for the currently attached video capture devices.
The following code snippet shows how to get the list of interfaces. It then prints interface information and device information to the console:
void print_interface_device_tree()
{
printf("Enumerating video capture devices by interface...\n");
{
printf("Failed to create device enumerator");
goto print_error;
}
{
printf("Failed to update device list");
goto print_error;
}
if (itf_count == 0)
{
printf("No interfaces found\n");
goto cleanup;
}
for (int i = 0; i < itf_count; ++i)
{
{
printf("Failed to query interface info for index %d\n", i);
print_last_error();
continue;
}
{
printf("Failed to update interface device list");
print_last_error();
continue;
}
if (dev_count == 0)
{
printf("\tNo devices found\n");
continue;
}
printf("\tFound %d devices:\n", dev_count);
for (int j = 0; j < dev_count; ++j)
{
{
printf("Failed to query device info for index %d\n", j);
print_last_error();
continue;
}
printf("\t\t");
print_device_info(info);
printf("\n");
}
}
printf("\n");
goto cleanup;
print_error:
print_last_error();
cleanup:
}
Receiving Device Arrival and Removal Notifications
IC4_DEVICE_ENUM objects allow registering a callback function that notifies the program of changes in the list of available devices. To register a callback function, call ic4_devenum_event_add_device_list_changed.
The following code snippet shows how to register and finally unregister a device-list-changed event handler:
int main()
{
{
printf("Failed to create device enumerator\n");
goto print_error;
}
{
printf("Failed to register device-list-changed event handler\n");
goto print_error;
}
{
printf("Failed to update device list\n");
goto print_error;
}
printf("Press ENTER to exit program\n");
printf("%d devices connected initially.\n", initial_device_count);
(void)getchar();
{
printf("Failed to unregister device-list-changed event handler\n");
goto print_error;
}
goto cleanup;
print_error:
print_last_error();
cleanup:
return 0;
}
An example device-list-changed handler can look like this:
void device_list_changed_handler(
struct IC4_DEVICE_ENUM* enumerator,
void* user_ptr)
{
printf("Device list has changed!\n");
printf("Found %d devices\n", new_device_count);
printf("\n");
}