UVC Driver -- GSoC Midterm Report
Since my last blog entry a lot of progress has been made. Currently I’m right on the cusp of actually producing images on the screen that have been captured by my camera. Successful communication is occurring between the driver and the camera in at least two different forms.
The first form of communication to be successfully implemented involves the setting of values within the camera which affect image capture. These are the familiar brightness, contrast, sharpness etc. settings which most cameras support. Nearly all of the options available to my camera are now presented for manipulation by end-users and successfully communicated to the camera. These values are maintained within the camera between power cycles and this fact is successfully communicated to the user via the available controls. The controls can be viewed and modified in the media preferences application or the cortex demo application. ParameterWeb control documentation indicates a range of different style controls within the continuous or discrete parameter varieties. However it appears to me that the only discrete value input method currently supported with an appropriate gui interface is the binary on/off option. This is suitable for features like the auto value for white balance which can only be either on or off. However the powerline frequency setting which has three possible values was unable to be represented with the appropriate discrete control of the B_RECSTATE type which has three possible states. To simulate this capability a continuous control was modified to only allow three values which are indicated by placing the sliding control within a +/-10 range of the desired value. The slider snaps to the available values to indicate this behaviour. One future feature which would perhaps be desirable is controls with auto settings which indicate in real time by their movement what values the camera is using in its auto mode. Right now sliders are simply frozen in their last position when the auto mode is in effect. I had some brief discussion with my mentors about this feature, but it was deemed to be unnecessary at this stage as a lot of work is left to be done in actual image capture.
I have so far not attempted to support all possible features of all UVC compliant cameras. I have only supported those options which I can test on my own camera. Although other features like hue control are very closely analogous to other controls like brightness control I would rather delay implementation of these features until they are testable on a camera supporting these features.
Besides the production of feature controls, actual image payload data is also being extracted from the camera after some difficulty. The UVC specification comes in two different versions, 1.0 and 1.1. These two versions have slightly, but importantly different negotiation requirements for the initiation of isochronous data transfer. In particular the size of the request and response data is different due to the addition of possible negotation terms in version 1.1. An error in the UVC driver constructor was causing my camera to be reported as being a device in compliance with version 1.1, when in reality it is a 1.0 camera. This error occurred due to the reuse of a generic pointer for a variety of pieces of information being reused throughout the driver. The UVC header information should have instead been preserved in its own memory during the initial parsing of the camera’s descriptors. This was a particularly irritating problem as cameras in compliance with the UVC specification are supposed to stall if the negotation phase fails. These stalls caused the media_addon_server to freeze in such a way that a reboot was required. So each time I tried a new approach to solving the negotation problem that didn’t work, I was required to reboot. None of my attempts were ever going to work as long as I believed my camera was correctly reported as a version 1.1 camera.
Once this error was fixed and isochronous transfer negotiation was successful it was possible to start examining payload data to see if it was sensible. At this stage the data does conform to the definition of the requested uncompressed video data, but the nature of the data is a little confusing and perhaps concerning. The vast majority of the data is headers with timestamps and no following data. There is some small amount of actual payload data being transferred, but as of yet I do know if this information is sensible image data. I am currently in the process of writing some code which will decode the information being transmitted and hopefully put it in a form that can be displayed on screen. Right now, a black rectangle in what appears to be the correct aspect ratio is being displayed and the “in use” light on the camera turns on when a transfer is started either by Codycam or the cortex demo. I think this is encouraging news as it indicates to me that at least the camera believes that it is sending sensible data.
It’s hard to say what the likely timeframe is until the production of an image on screen. If the many headers without payload are not a problem, image production could be possible by the end of the week. If that is a problem, finding the source of this difficulty could be time consuming. In any case the goal now is to produce images on for a single low resolution uncompressed format. Once this is accomplished I would like to go back and polish the code to remove temporary references to values specific to my camera which are now hard-coded. Then I would like to expand support to all uncompressed image resolutions and frame rates reported by the camera. The final goal is to support compressed video streams. This, I imagine will fill the rest of GSoC’s time, but if there is any additional time I’d like to do some testing with others who have different cameras to ensure that this driver’s claim of being generic is at least somewhat justifiable.