Hi.
I am trying to communicate with a Webcam connected via USB. Since I do not have permissions on /dev/video4 (the device node for my webcam) I thought it would be best to ask for permission via the UsbManager class and then pass the file descriptor to C. This looks good, the fd is a read-write file descriptor and is open (both checked with fcntl), but whenever I try to perform any ioctl calls, I get a ENOTTY error.
This is how I pass the descriptor:
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
Log.v(TAG, "connected to " + device);
UsbDeviceConnection con = manager.openDevice(device);
int fd = con.getFileDescriptor();
Log.e(TAG, "fd " +fd);
int ret = new V4L2Camera(fd, null, 640, 480, 30).initCamera();
}
}
else {
Log.d(TAG, "permission denied for device " + device);
}
}
}
}
};
And here is the calls to ioctl_loop
jint ...nInitCamera
(JNIEnv *env, jobject obj){
struct v4l2_capability capability;
struct v4l2_cropcap cropcap;
struct v4l2_crop crop;
struct v4l2_format format;
unsigned int min;
jclass ClassV4L2Camera = env->GetObjectClass(obj);
jfieldID fdID = env->GetFieldID(ClassV4L2Camera, "fd", "I");
jfieldID widthID = env->GetFieldID(ClassV4L2Camera, "width", "I");
jfieldID heightID = env->GetFieldID(ClassV4L2Camera, "height", "I");
int fd = env->GetIntField(obj, fdID);
int width = env->GetIntField(obj, widthID);
int height = env->GetIntField(obj, heightID);
if (ioctl_loop(fd, VIDIOC_QUERYCAP, &capability) == -1) {
if (errno == EINVAL) {
LOGE("Device does not have any V4L capabilities");
return ERROR_NO_V4L_DEVICE;
} else {
if (errno == ENOTTY)
LOGE("ENOTTY");
return ERROR_CAPABILITIES_QUERRY;
}
}
....
This is the actual call to ioctl, I just retry until I do not get EINTR. In fact, I get ENOTTY.
int ioctl_loop(int fd, int request, void *arg)
{
int r;
do r = ioctl (fd, request, arg);
while (-1 == r && EINTR == errno);
return r;
}
Does anybody have an Idea why the ioctl calls do not work? I am sure the VIDIOC_QUERYCAP must work with any UVC camera, and all the cameras I have tried are UVC compliant.
I am stuck on this for quite some time, any input is very valuable to me. Thanks in advance.