Find the answer to your Linux question:
Results 1 to 2 of 2
I am working on a class library that uses V4L2 to capture video from available video inputs. I've written functions to list the available devices, and I've been able to ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jul 2012
    Posts
    2

    Video For Linux Read Failure


    I am working on a class library that uses V4L2 to capture video from available video inputs. I've written functions to list the available devices, and I've been able to write a function that opens the device and sets the format, but, when trying to read a frame from the V4L2 device, I get a EINVAL error. The V4L2 docs say that this is because the device does not support read caps, but I have already checked the device (in another function) with the QUERYCAPS call checking for the READWRITE flag to be set. So, according to the query, I can read, but when I try to read, it says it can't. Anyone know why this is? Please see my source code for the open function below...

    Code:
    Device_Errors VideoInputDevice::Open(MediaFormat* format){
        Device_Errors retval = SUCCEEDED;
        try
        {
            string file("/dev/video");
            char index[3];
            sprintf(index,"%d", DeviceIndex, 10);
            file = file + index;
            VideoMediaFormat* vformat = (VideoMediaFormat*)format;
            VideoInputDeviceContext* context = new VideoInputDeviceContext();
            context->DeviceHandle = -1;
            context->Format = vformat;
            context->DeviceHandle = open(file.c_str(), O_RDWR);
            if(context->DeviceHandle == -1)
            {
                retval = INVALID_DEVICE;
            }
            else{
                v4l2_format rawfmt;
                memset(&rawfmt, 0, sizeof(v4l2_format));
                rawfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
                rawfmt.fmt.pix.width = vformat->Width;
                rawfmt.fmt.pix.height = vformat->Height;
                rawfmt.fmt.pix.pixelformat = (__u32)GetBPPFCC((VideoPixelFormat)vformat->PixelFormat);
                if(ioctl(context->DeviceHandle, VIDIOC_S_FMT, &rawfmt) == -1)
                {
                    retval = INVALID_FORMAT;
                }
                else{
                    context->Listener = Listener;
                    DeviceContext = context;
                    context->Stopped = false;
                    context->ImageSize = rawfmt.fmt.pix.sizeimage;
                    void* buffer = malloc(context->ImageSize);
                    int r = read(context->DeviceHandle, buffer, context->ImageSize);
                    free(buffer);
                    r = pthread_create( &context->CaptureThread, NULL, &VideoInputDevice_Thread, (void*) DeviceContext);
                }
            }
            
        }
        catch(...){
            retval = UNEXPECTED;
        }
        return retval;
    }
    Last edited by nskipper1110; 07-11-2012 at 01:45 AM.

  2. #2
    Just Joined!
    Join Date
    Jul 2012
    Posts
    2
    Well, I figured it out my own. I had to download the Linux source and look at the UVC_v4l driver, but I found the problem. The read function in the driver just returns EINVAL with no other code, so apparently there is no intention to support direct read. It looked like the preferred method is to use the Memory Map methods for reading frames, so I'm going to implement it that way.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •