| 1) Why such library is needed |
| ========================== |
| |
| Media devices can be very complex. It is not trivial how to detect what's the |
| other devices associated with a video node. |
| |
| This API provides the capabilities of getting the associated devices with a |
| video node. |
| |
| It is currently implemented at http://git.linuxtv.org/v4l-utils.git, at the |
| utils/libmedia_dev/. After validating it, it makes sense to move it to be |
| part of libv4l. |
| |
| 2) Provided functions |
| ================== |
| |
| The API defines a macro with its current version. Currently, it is: |
| |
| #define GET_MEDIA_DEVICES_VERSION 0x0104 |
| |
| Each device type that is known by the API is defined inside enum device_type, |
| currently defined as: |
| |
| enum device_type { |
| UNKNOWN = 65535, |
| NONE = 65534, |
| MEDIA_V4L_VIDEO = 0, |
| MEDIA_V4L_VBI, |
| MEDIA_DVB_FRONTEND, |
| MEDIA_DVB_DEMUX, |
| MEDIA_DVB_DVR, |
| MEDIA_DVB_NET, |
| MEDIA_DVB_CA, |
| MEDIA_SND_CARD, |
| MEDIA_SND_CAP, |
| MEDIA_SND_OUT, |
| MEDIA_SND_CONTROL, |
| MEDIA_SND_HW, |
| }; |
| |
| The first function discovers the media devices and stores the information |
| at an internal representation. Such representation should be opaque to |
| the userspace applications, as it can change from version to version. |
| |
| 2.1) Device discover and release functions |
| ===================================== |
| |
| The device discover is done by calling: |
| |
| void *discover_media_devices(void); |
| |
| In order to release the opaque structure, a free method is provided: |
| |
| void free_media_devices(void *opaque); |
| |
| 2.2) Functions to help printing the discovered devices |
| ================================================= |
| |
| In order to allow printing the device type, a function is provided to |
| convert from enum device_type into string: |
| |
| char *media_device_type(enum device_type type); |
| |
| All discovered devices can be displayed by calling: |
| |
| void display_media_devices(void *opaque); |
| |
| 2.3) Functions to get device associations |
| ==================================== |
| |
| The API provides 3 methods to get the associated devices: |
| |
| a) get_associated_device: returns the next device associated with another one |
| |
| char *get_associated_device(void *opaque, |
| char *last_seek, |
| enum device_type desired_type, |
| char *seek_device, |
| enum device_type seek_type); |
| The parameters are: |
| |
| 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. |
| |
| 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. |
| |
| |
| b) fget_associated_device: returns the next device associated with another one |
| |
| char *fget_associated_device(void *opaque, |
| char *last_seek, |
| enum device_type desired_type, |
| int fd_seek_device, |
| enum device_type seek_type); |
| |
| The parameters are: |
| |
| opaque: media devices opaque descriptor |
| last_seek: last seek result. Use NULL to get the first result |
| desired_type: type of the desired device |
| fd_seek_device: file handler for the device where the association will |
| be made |
| seek_type: type of the seek device. Using NONE produces the same |
| result of using NULL for the seek_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 an open file descriptor |
| |
| c) get_not_associated_device: Returns the next device not associated with |
| an specific device type. |
| |
| char *get_not_associated_device(void *opaque, |
| char *last_seek, |
| enum device_type desired_type, |
| enum device_type not_desired_type); |
| |
| The parameters are: |
| |
| 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 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. |
| |
| 3) Examples with typical usecases |
| ============================== |
| |
| a) Just displaying all media devices: |
| |
| void *md = discover_media_devices(); |
| display_media_devices(md); |
| free_media_devices(md); |
| |
| The devices will be shown at the order they appear at the computer buses. |
| |
| b) For video0, prints the associated alsa capture device(s): |
| |
| void *md = discover_media_devices(); |
| char *devname = NULL, video0 = "/dev/video0"; |
| do { |
| devname = get_associated_device(md, devname, MEDIA_SND_CAP, |
| video0, MEDIA_V4L_VIDEO); |
| if (devname) |
| printf("Alsa capture: %s\n", devname); |
| } while (devname); |
| free_media_devices(md); |
| |
| Note: the video0 string can be declarated as "/dev/video0" or as just "video0", |
| as the search functions will discard any patch on it. |
| |
| c) Get the alsa capture device associated with an opened file descriptor: |
| |
| int fd = open("/dev/video0", O_RDWR); |
| ... |
| void *md = discover_media_devices(); |
| vid = fget_associated_device(md, NULL, MEDIA_SND_CAP, fd, |
| MEDIA_V4L_VIDEO); |
| printf("\n\nAlsa device = %s\n", vid); |
| close(fd); |
| free_media_devices(md); |
| |
| d) Get the mainboard alsa playback devices: |
| |
| char *devname = NULL; |
| void *md = discover_media_devices(); |
| do { |
| devname = get_not_associated_device(md, devname, MEDIA_SND_OUT, |
| MEDIA_V4L_VIDEO); |
| if (devname) |
| printf("Alsa playback: %s\n", devname); |
| } while (devname); |
| free_media_devices(md); |
| |
| e) Get all video devices: |
| |
| void *md = discover_media_devices(); |
| char *vid = NULL; |
| do { |
| vid = get_associated_device(md, vid, MEDIA_V4L_VIDEO, |
| NULL, NONE); |
| if (!vid) |
| break; |
| printf("Video device: %s\n", vid); |
| } while (vid); |
| free_media_devices(md); |