[haiku-commits] r41196 - haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 7 Apr 2011 23:54:26 +0200 (CEST)

Author: korli
Date: 2011-04-07 23:54:25 +0200 (Thu, 07 Apr 2011)
New Revision: 41196
Changeset: https://dev.haiku-os.org/changeset/41196

Modified:
   
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp
   
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.h
Log:
* improves traces
* added _ProbeCommitFormat() and _SelectBestAlternate()
* to be noticed: BUSBInterface::SetAlternate() isn't const and there is no mean 
to get a non-const BUSBInterface.


Modified: 
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp
===================================================================
--- 
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp
  2011-04-07 20:59:30 UTC (rev 41195)
+++ 
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp
  2011-04-07 21:54:25 UTC (rev 41196)
@@ -70,6 +70,7 @@
 
        for (uint32 i = 0; i < _device->CountConfigurations(); i++) {
                config = _device->ConfigurationAt(i);
+               _device->SetConfiguration(config);
                for (uint32 j = 0; j < config->CountInterfaces(); j++) {
                        interface = config->InterfaceAt(j);
 
@@ -81,26 +82,43 @@
                                // look for class specific interface 
descriptors and parse them
                                for (uint32 k = 0; 
interface->OtherDescriptorAt(k, generic,
                                        sizeof(buffer)) == B_OK; k++) {
-                                       if (generic->generic.descriptor_type == 
(USB_REQTYPE_CLASS
-                                               | USB_DESCRIPTOR_INTERFACE)) {
-                                               ParseVideoControl((const 
usbvc_class_descriptor*)generic,
-                                                       
generic->generic.length);
+                                       if (generic->generic.descriptor_type != 
(USB_REQTYPE_CLASS
+                                               | USB_DESCRIPTOR_INTERFACE))
+                                               continue;
+                                       fControlIndex = interface->Index();
+                                       _ParseVideoControl((const 
usbvc_class_descriptor*)generic,
+                                               generic->generic.length);
+                               }
+
+                               for (uint32 k = 0; k < 
interface->CountEndpoints(); k++) {
+                                       const BUSBEndpoint *e = 
interface->EndpointAt(i);
+                                       if (e && e->IsInterrupt() && 
e->IsInput()) {
+                                               fInterruptIn = e;
+                                               break;
                                        }
                                }
-
                                fInitStatus = B_OK;
                        } else if (interface->Class() == CC_VIDEO && 
interface->Subclass()
                                == SC_VIDEOSTREAMING) {
-                               printf("UVCCamDevice: (%lu,%lu): Found Video 
Control interface.\n",
-                                       i, j);
+                               printf("UVCCamDevice: (%lu,%lu): Found Video 
Streaming "
+                                       "interface.\n", i, j);
 
                                // look for class specific interface 
descriptors and parse them
                                for (uint32 k = 0; 
interface->OtherDescriptorAt(k, generic,
                                        sizeof(buffer)) == B_OK; k++) {
-                                       if (generic->generic.descriptor_type == 
(USB_REQTYPE_CLASS
-                                               | USB_DESCRIPTOR_INTERFACE)) {
-                                               ParseVideoStreaming((const 
usbvc_class_descriptor*)generic,
-                                                       
generic->generic.length);
+                                       if (generic->generic.descriptor_type != 
(USB_REQTYPE_CLASS
+                                               | USB_DESCRIPTOR_INTERFACE))
+                                               continue;
+                                       fStreamingIndex = interface->Index();
+                                       _ParseVideoStreaming((const 
usbvc_class_descriptor*)generic,
+                                               generic->generic.length);
+                               }
+                               
+                               for (uint32 k = 0; k < 
interface->CountEndpoints(); k++) {
+                                       const BUSBEndpoint *e = 
interface->EndpointAt(i);
+                                       if (e && e->IsIsochronous() && 
e->IsInput()) {
+                                               fIsoIn = e;
+                                               break;
                                        }
                                }
                        }
@@ -109,8 +127,13 @@
 }
 
 
+UVCCamDevice::~UVCCamDevice()
+{
+}
+
+
 void
-UVCCamDevice::ParseVideoStreaming(const usbvc_class_descriptor* _descriptor,
+UVCCamDevice::_ParseVideoStreaming(const usbvc_class_descriptor* _descriptor,
        size_t len)
 {
        switch(_descriptor->descriptorSubtype) {
@@ -328,20 +351,20 @@
 
 
 void
-UVCCamDevice::ParseVideoControl(const usbvc_class_descriptor* _descriptor,
+UVCCamDevice::_ParseVideoControl(const usbvc_class_descriptor* _descriptor,
        size_t len)
 {
        switch(_descriptor->descriptorSubtype) {
                case VC_HEADER:
                {
-                       const usbvc_interface_header_descriptor* descriptor =
-                               (const 
usbvc_interface_header_descriptor*)_descriptor;
+                       fHeaderDescriptor = 
(usbvc_interface_header_descriptor*)_descriptor;
                        printf("VC_HEADER:\tUVC v%x.%02x, clk %.5f MHz\n",
-                               descriptor->version >> 8, descriptor->version & 
0xff,
-                               descriptor->clockFrequency / 1000000.0);
-                       for (uint8 i = 0; i < descriptor->numInterfacesNumbers; 
i++) {
+                               fHeaderDescriptor->version >> 8,
+                               fHeaderDescriptor->version & 0xff,
+                               fHeaderDescriptor->clockFrequency / 1000000.0);
+                       for (uint8 i = 0; i < 
fHeaderDescriptor->numInterfacesNumbers; i++) {
                                printf("\tStreaming Interface %d\n",
-                                       descriptor->interfaceNumbers[i]);
+                                       fHeaderDescriptor->interfaceNumbers[i]);
                        }
                        break;
                }
@@ -477,11 +500,6 @@
 }
 
 
-UVCCamDevice::~UVCCamDevice()
-{
-}
-
-
 bool
 UVCCamDevice::SupportsIsochronous()
 {
@@ -492,6 +510,8 @@
 status_t
 UVCCamDevice::StartTransfer()
 {
+       if (_ProbeCommitFormat() != B_OK || _SelectBestAlternate() != B_OK)
+               return B_ERROR;
        return CamDevice::StartTransfer();
 }
 
@@ -503,6 +523,132 @@
 }
 
 
+status_t
+UVCCamDevice::SuggestVideoFrame(uint32 &width, uint32 &height)
+{
+       width = 320;
+       height = 240;
+       return B_OK;
+}
+
+
+status_t
+UVCCamDevice::AcceptVideoFrame(uint32 &width, uint32 &height)
+{
+       width = 320;
+       height = 240;
+       
+       SetVideoFrame(BRect(0, 0, width - 1, height - 1));
+       return B_OK;
+}
+
+
+status_t
+UVCCamDevice::_ProbeCommitFormat()
+{
+       usbvc_probecommit request;
+       memset(&request, 0, sizeof(request));
+       request.hint = 1 << 8;
+       request.SetFrameInterval(333333);
+       request.formatIndex = 1;
+       request.frameIndex = 3;
+       size_t length = fHeaderDescriptor->version > 0x100 ? 34 : 26;
+       size_t actualLength = fDevice->ControlTransfer(
+               USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, SET_CUR,
+               VS_PROBE_CONTROL << 8, fStreamingIndex, length, &request);
+       if (actualLength != length) {
+               fprintf(stderr, "UVCCamDevice::_ProbeFormat() SET_CUR 
ProbeControl1"
+                       " failed %ld\n", actualLength);
+               return B_ERROR;
+       }
+
+       usbvc_probecommit response;
+       actualLength = fDevice->ControlTransfer(
+               USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, GET_MAX,
+               VS_PROBE_CONTROL << 8, fStreamingIndex, sizeof(response), 
&response);
+       if (actualLength != sizeof(response)) {
+               fprintf(stderr, "UVCCamDevice::_ProbeFormat() GetMax 
ProbeControl"
+                       " failed\n");
+               return B_ERROR;
+       }
+       
+       printf("usbvc_probecommit response.compQuality %d\n", 
response.compQuality);
+       request.compQuality = response.compQuality;
+
+       actualLength = fDevice->ControlTransfer(
+               USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, SET_CUR,
+               VS_PROBE_CONTROL << 8, fStreamingIndex, length, &request);
+       if (actualLength != length) {
+               fprintf(stderr, "UVCCamDevice::_ProbeFormat() SetCur 
ProbeControl2"
+                       " failed\n");
+               return B_ERROR;
+       }
+
+       actualLength = fDevice->ControlTransfer(
+               USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, SET_CUR,
+               VS_COMMIT_CONTROL << 8, fStreamingIndex, length, &request);
+       if (actualLength != length) {
+               fprintf(stderr, "UVCCamDevice::_ProbeFormat() SetCur 
CommitControl"
+                       " failed\n");
+               return B_ERROR;
+       }
+       
+       fMaxVideoFrameSize = response.maxVideoFrameSize;
+       fMaxPayloadTransferSize = response.maxPayloadTransferSize;      
+       printf("usbvc_probecommit setup done maxVideoFrameSize:%ld"
+               " maxPayloadTransferSize:%ld\n", fMaxVideoFrameSize,
+               fMaxPayloadTransferSize);
+       
+       return B_OK;
+}
+
+
+status_t
+UVCCamDevice::_SelectBestAlternate()
+{
+       const BUSBConfiguration *config = fDevice->ActiveConfiguration();
+       const BUSBInterface *streaming = config->InterfaceAt(fStreamingIndex);
+       
+       uint32 bestBandwidth = 0;
+       uint32 alternateIndex = 0;
+       uint32 endpointIndex = 0;
+       
+       for (uint32 i = 0; i < streaming->CountAlternates(); i++) {
+               const BUSBInterface *alternate = streaming->AlternateAt(i);
+               for (uint32 j = 0; j < alternate->CountEndpoints(); j++) {
+                       const BUSBEndpoint *endpoint = alternate->EndpointAt(j);
+                       if (!endpoint->IsIsochronous() || !endpoint->IsInput())
+                               continue;
+                       if (fMaxPayloadTransferSize > endpoint->MaxPacketSize())
+                               continue;
+                       if (bestBandwidth != 0
+                               && bestBandwidth < endpoint->MaxPacketSize())
+                               continue;
+                       bestBandwidth = endpoint->MaxPacketSize();
+                       endpointIndex = j;
+                       alternateIndex = i;
+               }
+       }
+       
+       if (bestBandwidth == 0) {
+               fprintf(stderr, "UVCCamDevice::_SelectBestAlternate()"
+                       " couldn't find a valid alternate\n");
+               return B_ERROR;
+       }
+       
+       printf("UVCCamDevice::_SelectBestAlternate() %ld\n", bestBandwidth);
+       if (((BUSBInterface *)streaming)->SetAlternate(alternateIndex) != B_OK) 
{
+               fprintf(stderr, "UVCCamDevice::_SelectBestAlternate()"
+                       " selecting alternate failed\n");
+               return B_ERROR;
+       }
+       
+       fIsoIn = streaming->EndpointAt(endpointIndex);
+       
+       return B_OK;
+}
+
+
 UVCCamDeviceAddon::UVCCamDeviceAddon(WebCamMediaAddOn* webcam)
        : CamDeviceAddon(webcam)
 {

Modified: 
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.h
===================================================================
--- 
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.h
    2011-04-07 20:59:30 UTC (rev 41195)
+++ 
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.h
    2011-04-07 21:54:25 UTC (rev 41196)
@@ -20,13 +20,28 @@
        virtual bool                            SupportsIsochronous();
        virtual status_t                        StartTransfer();
        virtual status_t                        StopTransfer();
+       virtual status_t                        SuggestVideoFrame(uint32 &width,
+                                                                       uint32 
&height);
+       virtual status_t                        AcceptVideoFrame(uint32 &width,
+                                                                       uint32 
&height);
+
 private:
-                       void                            ParseVideoControl(
+                       void                            _ParseVideoControl(
                                                                        const 
usbvc_class_descriptor* descriptor,
                                                                        size_t 
len);
-                       void                            ParseVideoStreaming(
+                       void                            _ParseVideoStreaming(
                                                                        const 
usbvc_class_descriptor* descriptor,
                                                                        size_t 
len);
+                       status_t                        _ProbeCommitFormat();
+                       status_t                        _SelectBestAlternate();
+
+                       usbvc_interface_header_descriptor *fHeaderDescriptor;
+                       
+                       const BUSBEndpoint*     fInterruptIn;
+                       uint32                          fControlIndex;
+                       uint32                          fStreamingIndex;
+                       uint32                          fMaxVideoFrameSize;
+                       uint32                          fMaxPayloadTransferSize;
 };
 
 


Other related posts:

  • » [haiku-commits] r41196 - haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc - korli