3

I am currently attempting to retrieve device information for a built in web-cam using the following code:

#include <fcntl.h>
#include <unistd.h>
#include <linux/media.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv) {
   int fd = open("/dev/video0", O_RDONLY, 0);
   if (fd > 0) {
       struct media_device_info *device_data = (struct media_device_info *) malloc (sizeof(struct media_device_info) * 1);

       if (ioctl(fd, MEDIA_IOC_DEVICE_INFO, device_data) ==  0)
            printf("Media Version: %u\nDriver: %s\nVersion: %d\nSerial: %s\n", (unsigned int) device_data->media_version, device_data->driver, (int) device_data->driver_version, device_data->serial);
        else {
               fprintf(stderr, "Couldn't get device info: %d: %s\n", errno, strerror(errno));
       }

       close(fd);
       free(device_data);
    }

    return 0;
}

When the code executes the else block is entered thus giving the following:

Couldn't get device info: 25: Inappropriate ioctl for device

From this it would seem that the device is being opened in the wrong manner such that ioctl cannot use the file descriptor. I must be missing something; could anyone here help me with regards to opening the /dev/video0 device?

Thanks!

p.s. If this has been answered before elsewhere please let me know. If this question is invalid in anyway then please accept my apologies.

tiredone
  • 59
  • 1
  • 9
  • 1
    Do you have `/dev/media*`? – Arkadiusz Drabczyk Jun 01 '18 at 12:54
  • I don't know, but are you sure that you call correct open() function. In examples of ioctl() call open() takes only 2 arguments. But yourth function takes 3. – Sandro Jun 01 '18 at 12:55
  • 1
    Also check if you compiled `linux` with `CONFIG_MEDIA_CONTROLLER` enabled. – Arkadiusz Drabczyk Jun 01 '18 at 12:56
  • Thanks for your comments so far, (1) I do not have any /dev/media* devices (2) I did try with the open method which takes 2 args, got the same result. (3) Running `cat /boot/config-$(uname -r) | grep CONFIG_MEDIA_CONTROLLER` gives `CONFIG_MEDIA_CONTROLLER=y` – tiredone Jun 01 '18 at 13:06
  • are you sure that kernel part supports this ioctl? – Alex Hoppus Jun 01 '18 at 13:16
  • Good question @AlexHoppus, how would I check this? – tiredone Jun 01 '18 at 13:18
  • is /dev/video0 correct device name? Have you chacked that your webcam works with other applications? – Sandro Jun 01 '18 at 13:18
  • `v4l2-ctl -D -d /dev/video0` returns information about the device itself, the /dev/video0 device can be used by VLC etc. – tiredone Jun 01 '18 at 13:20
  • According to http://www.chiark.greenend.org.uk/doc/linux-doc-3.16/html/media_api/func-open.html the flags to `open` should be `O_RDWR`. – deamentiaemundi Jun 01 '18 at 21:03
  • Thanks for your helpful comments, changing the flag to O_RDWR didn't do the trick. I will continue to investigate and report back here. Out of interest did the code work for anyone else? – tiredone Jun 04 '18 at 05:11

1 Answers1

1

It seems that the /dev/video* devices may be bound to separate /dev/media* devices, and you need to issue your MEDIA_IOC_DEVICE_INFO ioctl against the corresponding /dev/media* device for your /dev/video* device.

As to how to locate that corresponding device id, the best I have come up with is to search for media* files within the /sys/class/video4linux/video{N}/device directory.

For example, for a given device /dev/video0 on my system (kernel 4.15.0-34-generic), searching for media* files under /sys/class/video4linux/video0/device turned up media10, which I was then able to use to recover the serial number (open /dev/media10, issue the ioctl command).

I don't know whether this method of finding the corresponding media devices is consistent across distros/versions/kernels/etc.

codeMonkey
  • 376
  • 4
  • 10
  • Followed your steps and found that a media0 was now being listed, and behold it was indeed there- in the devices folder (/dev/media0). So, good advice with regards to navigation. Everybody else who commented were correct in their insistence that /dev/media0 should be present- why it wasn't listed before remains a mystery. – tiredone Oct 01 '18 at 07:59