static char *device_type_str[] = {
[UNKNOWN] = "unknown",
+ [NONE] = "none",
[V4L_VIDEO] = "video",
[V4L_VBI] = "vbi",
[DVB_FRONTEND] = "dvb frontend",
printf("\n");
}
-char *get_first_alsa_cap_device(void *opaque, char *v4l_device)
+char *get_associated_device(void *opaque,
+ char *last_seek,
+ enum device_type desired_type,
+ char *seek_device,
+ enum device_type seek_type)
{
struct media_devices *md = opaque;
struct media_device_entry *md_ptr = md->md_entry;
int i;
char *prev;
- char p = strrchr(v4l_device, '/');
+ char *p = strrchr(seek_device, '/');
/* Get just the device name */
if (p)
- v4l_device = p + 1;
+ seek_device = p + 1;
- /* Step 1: Find the V4L node */
- for (i = 0; i < md->md_size; i++, md_ptr++) {
- if (md_ptr->type == V4L_VIDEO) {
- if (!strcmp(v4l_device, md_ptr->node))
+ if (seek_type != NONE && seek_device[0]) {
+ /* Step 1: Find the seek node */
+ for (i = 0; i < md->md_size; i++, md_ptr++) {
+ if (md_ptr->type == seek_type &&
+ !strcmp(seek_device, md_ptr->node))
break;
}
- }
- if (i == md->md_size)
- return NULL;
+ if (i == md->md_size)
+ return NULL;
+ i++;
+ } else
+ i = 0;
- /* Step 2: find the alsa node */
+ /* Step 2: find the associated node */
prev = md_ptr->device;
md_ptr++;
- for (i++;i < md->md_size && !strcmp(prev,md_ptr->device); i++) {
- if (md_ptr->type == SND_CAP)
+ for (;i < md->md_size && !strcmp(prev,md_ptr->device); i++, md_ptr++) {
+ if (last_seek && !strcmp(md_ptr->node, last_seek))
+ break;
+ if (md_ptr->type == desired_type)
return md_ptr->node;
- md_ptr++;
}
return NULL;
}
-char *get_first_no_video_out_device(void *opaque)
+char *get_not_associated_device(void *opaque,
+ char *last_seek,
+ enum device_type desired_type,
+ enum device_type not_desired_type)
{
struct media_devices *md = opaque;
struct media_device_entry *md_ptr = md->md_entry;
int i, skip = 0;
- char *prev = "";
+ char *prev = "", *result = NULL;
- /* Step 1: Find a device without video4linux node */
+ /* Step 1: Find a device without seek_type node */
for (i = 0; i < md->md_size; i++, md_ptr++) {
- if (md_ptr->type == V4L_VIDEO)
- skip = 1;
- else if (strcmp(prev, md_ptr->device)) {
+ if (strcmp(prev, md_ptr->device)) {
+ if (!skip && result)
+ break;
prev = md_ptr->device;
skip = 0;
+ result = NULL;
+ }
+ if (md_ptr->type == not_desired_type) {
+ skip = 1;
+ } else if (!skip && !result && md_ptr->type == desired_type) {
+ result = md_ptr->node;
}
- if (!skip && md_ptr->type == SND_OUT)
- return md_ptr->node;
- }
-
- /*
- * Step 2: Fallback: Find any alsa out node. Useful if a machine
- * doesn't have an internal board, but an USB device like the
- * Sirius webcam also provides an alsa output node
- */
- md_ptr = md->md_entry;
- for (i = 0; i < md->md_size; i++, md++) {
- if (!skip && md_ptr->type == SND_OUT)
- return md_ptr->node;
}
+ if (skip)
+ result = NULL;
- return NULL;
+ return result;
}
/*
* Version of the API
*/
-#define GET_MEDIA_DEVICES_VERSION 0x0101
+#define GET_MEDIA_DEVICES_VERSION 0x0102
/*
A typical usecase for the above API is:
*/
enum device_type {
UNKNOWN = 65535,
+ NONE = 65534,
V4L_VIDEO = 0,
V4L_VBI,
DVB_FRONTEND,
void display_media_devices(void *opaque);
/**
- * get_first_alsa_cap_device() - Gets the first alsa capture device for a
- * video node
+ * get_not_associated_device() - Return the next device not associated with
+ * an specific device type.
*
- * @opaque: media devices opaque descriptor
+ * @opaque: media devices opaque descriptor
+ * @last_seek: last seek result. Use NULL to get the first result
+ * @desired_type: type of the desired device
+ * @not_desired_type: type of the seek device
*
- * This function seeks inside the media_devices struct for the first alsa
- * capture device (SND_CAP) that belongs to the same device where the video
- * node exists. The video node should belong to V4L_VIDEO type (video0,
- * video1, etc).
+ * This function seeks inside the media_devices struct for the next physical
+ * device that doesn't support a non_desired type.
+ * This method is useful for example to return the audio devices that are
+ * provided by the motherboard.
*/
-char *get_first_alsa_cap_device(void *opaque, char *v4l_device);
-
-/**
- * get_first_no_video_out_device() - Gets the first alsa playback device
- * that is not associated to a video device.
- *
- * @opaque: media devices opaque descriptor
- *
- * This function seeks inside the media_devices struct for the first alsa
- * playback device (SND_OUT) that is not associated to a video device.
- * The returned value is at the format expected by alsa libraries (like hw:0,0)
- *
- * If there's no playback device that are not associated to a video device,
- * the routine falls back to any existing audio playback device. This is useful
- * in the cases where there's no audio sound device on a system, and an external
- * USB device that provides both video and audio playback is connected.
+char *get_associated_device(void *opaque,
+ char *last_seek,
+ enum device_type desired_type,
+ char *seek_device,
+ enum device_type seek_type);
+
+ /**
+ * get_associated_device() - Return the next device associated with another one
*
- * Note that, as the devices are ordered by the devices ID, this routine
- * may not return hw:0,0. That's OK, as, if the media card is probed before
- * the audio card, the media card will receive the lowest address.
+ * @opaque: media devices opaque descriptor
+ * @last_seek: last seek result. Use NULL to get the first result
+ * @desired_type: type of the desired device
+ * @seek_device: name of the device with you want to get an association.
+ *@ seek_type: type of the seek device. Using NONE produces the same
+ * result of using NULL for the seek_device.
*
- * In general, it will return the alsa device for the default audio playback
- * device.
+ * This function seeks inside the media_devices struct for the next device
+ * that it is associated with a seek parameter.
+ * It can be used to get an alsa device associated with a video device. If
+ * the seek_device is NULL or seek_type is NONE, it will just search for
+ * devices of the desired_type.
*/
-char *get_first_no_video_out_device(void *opaque);
+char *get_not_associated_device(void *opaque,
+ char *last_seek,
+ enum device_type desired_type,
+ enum device_type not_desired_type);
md = discover_media_devices();
display_media_devices(md);
- alsa = get_first_alsa_cap_device(md, "video0");
+ alsa = get_associated_device(md, NULL, SND_CAP, "video0", V4L_VIDEO);
if (alsa)
printf("Alsa device associated with video0 capture: %s\n", alsa);
- alsa = get_first_no_video_out_device(md);
+ alsa = get_not_associated_device(md, NULL, SND_OUT, V4L_VIDEO);
if (alsa)
printf("Alsa output device: %s\n", alsa);