[haiku-commits] r42688 - in haiku/trunk/src: add-ons/media/media-add-ons/usb_webcam add-ons/media/media-add-ons/usb_webcam/addons/uvc bin
- From: korli@xxxxxxxxxxxxxxxx
- To: haiku-commits@xxxxxxxxxxxxx
- Date: Thu, 25 Aug 2011 18:36:48 +0200 (CEST)
Author: korli
Date: 2011-08-25 18:36:48 +0200 (Thu, 25 Aug 2011)
New Revision: 42688
Changeset: https://dev.haiku-os.org/changeset/42688
Added:
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCDeframer.cpp
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCDeframer.h
Modified:
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.cpp
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/Jamfile
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
haiku/trunk/src/bin/listusb.cpp
Log:
Patch from Gabriel Hartmann for his GSoC UVC project. Coding style updates by
myself. Thanks!
Modified: haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.cpp
===================================================================
--- haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.cpp
2011-08-24 23:38:22 UTC (rev 42687)
+++ haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/CamDevice.cpp
2011-08-25 16:36:48 UTC (rev 42688)
@@ -565,8 +565,15 @@
}
#ifdef SUPPORT_ISO
else if (SupportsIsochronous()) {
- int numPacketDescriptors = 20;
+ int numPacketDescriptors = 16;
usb_iso_packet_descriptor
packetDescriptors[numPacketDescriptors];
+
+ // Initialize packetDescriptor request lengths
+ for (int i = 0; i<numPacketDescriptors; i++)
+ packetDescriptors[i].request_length = 256;
+
+ int fullPackets = 0;
+ int totalPackets = 0;
while (fTransferEnabled) {
ssize_t len = -1;
BAutolock lock(fLocker);
@@ -575,7 +582,8 @@
if (!fIsoIn)
break;
#ifndef DEBUG_DISCARD_INPUT
- len = fIsoIn->IsochronousTransfer(fBuffer, fBufferLen,
packetDescriptors, numPacketDescriptors);
+ len = fIsoIn->IsochronousTransfer(fBuffer, fBufferLen,
packetDescriptors,
+ numPacketDescriptors);
#endif
//PRINT((CH ": got %d bytes" CT, len));
@@ -594,8 +602,16 @@
#ifndef DEBUG_DISCARD_DATA
if (fDataInput) {
- fDataInput->Write(fBuffer, len);
- // else drop
+ int fBufferIndex = 0;
+ for (int i = 0; i < numPacketDescriptors; i++) {
+ int actual_length =
((usb_iso_packet_descriptor)
+
packetDescriptors[i]).actual_length;
+ if (actual_length > 0) {
+
fDataInput->Write(&fBuffer[fBufferIndex],
+ actual_length);
+ }
+ fBufferIndex += actual_length;
+ }
}
#endif
//snooze(2000);
Modified: haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/Jamfile
2011-08-24 23:38:22 UTC (rev 42687)
+++ haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/Jamfile
2011-08-25 16:36:48 UTC (rev 42688)
@@ -35,7 +35,7 @@
QuickCamDevice.cpp
SonixCamDevice.cpp
NW80xCamDevice.cpp
-# UVCCamDevice.cpp
+# UVCCamDevice.cpp UVCDeframer.cpp
;
## colorspace transforms sources
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-08-24 23:38:22 UTC (rev 42687)
+++
haiku/trunk/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp
2011-08-25 16:36:48 UTC (rev 42688)
@@ -1,4 +1,5 @@
/*
+ * Copyright 2011, Gabriel Hartmann, gabriel.hartmann@xxxxxxxxxx
* Copyright 2011, Jérôme Duval, korli@xxxxxxxxxxxxxxxxx
* Copyright 2009, Ithamar Adema, <ithamar.adema@xxxxxxxxxxxxxxxx>.
* Distributed under the terms of the MIT License.
@@ -6,12 +7,14 @@
#include "UVCCamDevice.h"
+#include "UVCDeframer.h"
#include <stdio.h>
+#include <stdlib.h>
+#include <ParameterWeb.h>
+#include <media/Buffer.h>
-#include "CamStreamingDeframer.h"
-
usb_webcam_support_descriptor kSupportedDevices[] = {
// ofcourse we support a generic UVC device...
{{ CC_VIDEO, SC_VIDEOCONTROL, 0, 0, 0 }, "USB", "Video Class", "??" },
@@ -60,27 +63,14 @@
}
-// TODO dumb sof_marks and eof_marks
-static const uint8 sof_mark_1[] = { 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x00 };
-static const uint8 sof_mark_2[] = { 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96, 0x01 };
-static const uint8 *sof_marks[] = { sof_mark_1, sof_mark_2 };
-
-static const uint8 eof_mark_1[] = { 0x00, 0x00, 0x00, 0x00 };
-static const uint8 eof_mark_2[] = { 0x40, 0x00, 0x00, 0x00 };
-static const uint8 eof_mark_3[] = { 0x80, 0x00, 0x00, 0x00 };
-static const uint8 eof_mark_4[] = { 0xc0, 0x00, 0x00, 0x00 };
-static const uint8 *eof_marks[] = { eof_mark_1, eof_mark_2, eof_mark_3,
eof_mark_4 };
-
-
-
-UVCCamDevice::UVCCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device)
+UVCCamDevice::UVCCamDevice(CamDeviceAddon& _addon, BUSBDevice* _device)
: CamDevice(_addon, _device),
fHeaderDescriptor(NULL),
- fInterruptIn(NULL)
+ fInterruptIn(NULL),
+ fUncompressedFormatIndex(1),
+ fUncompressedFrameIndex(1)
{
- fDeframer = new CamStreamingDeframer(this);
- fDeframer->RegisterSOFTags(sof_marks, 2, sizeof(sof_mark_1), 12);
- fDeframer->RegisterEOFTags(eof_marks, 4, sizeof(eof_mark_1),
sizeof(eof_mark_1));
+ fDeframer = new UVCDeframer(this);
SetDataInput(fDeframer);
const BUSBConfiguration* config;
@@ -88,7 +78,7 @@
usb_descriptor* generic;
uint8 buffer[1024];
- generic = (usb_descriptor *)buffer;
+ generic = (usb_descriptor*)buffer;
for (uint32 i = 0; i < _device->CountConfigurations(); i++) {
config = _device->ConfigurationAt(i);
@@ -111,9 +101,8 @@
_ParseVideoControl((const
usbvc_class_descriptor*)generic,
generic->generic.length);
}
-
for (uint32 k = 0; k <
interface->CountEndpoints(); k++) {
- const BUSBEndpoint *e =
interface->EndpointAt(i);
+ const BUSBEndpoint* e =
interface->EndpointAt(i);
if (e && e->IsInterrupt() &&
e->IsInput()) {
fInterruptIn = e;
break;
@@ -137,7 +126,7 @@
}
for (uint32 k = 0; k <
interface->CountEndpoints(); k++) {
- const BUSBEndpoint *e =
interface->EndpointAt(i);
+ const BUSBEndpoint* e =
interface->EndpointAt(i);
if (e && e->IsIsochronous() &&
e->IsInput()) {
fIsoIn = e;
break;
@@ -151,6 +140,7 @@
UVCCamDevice::~UVCCamDevice()
{
+ free(fHeaderDescriptor);
}
@@ -158,11 +148,11 @@
UVCCamDevice::_ParseVideoStreaming(const usbvc_class_descriptor* _descriptor,
size_t len)
{
- switch(_descriptor->descriptorSubtype) {
+ switch (_descriptor->descriptorSubtype) {
case VS_INPUT_HEADER:
{
- const usbvc_input_header_descriptor* descriptor =
- (const
usbvc_input_header_descriptor*)_descriptor;
+ const usbvc_input_header_descriptor* descriptor
+ = (const
usbvc_input_header_descriptor*)_descriptor;
printf("VS_INPUT_HEADER:\t#fmts=%d,ept=0x%x\n",
descriptor->numFormats,
descriptor->endpointAddress);
if (descriptor->info & 1)
@@ -173,7 +163,7 @@
printf("\ttrigger button fixed to still
capture=%s\n",
descriptor->triggerUsage ? "no" :
"yes");
}
- const uint8 *controls = descriptor->controls;
+ const uint8* controls = descriptor->controls;
for (uint8 i = 0; i < descriptor->numFormats; i++,
controls += descriptor->controlSize) {
printf("\tfmt%d: %s %s %s %s - %s %s\n", i,
@@ -188,8 +178,9 @@
}
case VS_FORMAT_UNCOMPRESSED:
{
- const usbvc_format_descriptor* descriptor =
- (const usbvc_format_descriptor*)_descriptor;
+ const usbvc_format_descriptor* descriptor
+ = (const usbvc_format_descriptor*)_descriptor;
+ fUncompressedFormatIndex = descriptor->formatIndex;
printf("VS_FORMAT_UNCOMPRESSED:\tbFormatIdx=%d,#frmdesc=%d,guid=",
descriptor->formatIndex,
descriptor->numFrameDescriptors);
print_guid(descriptor->uncompressed.format);
@@ -206,7 +197,7 @@
if (descriptor->uncompressed.interlaceFlags & 4)
printf("\tField 1 first\n");
printf("\tField Pattern: ");
- switch((descriptor->uncompressed.interlaceFlags & 0x30)
>> 4) {
+ switch ((descriptor->uncompressed.interlaceFlags &
0x30) >> 4) {
case 0: printf("Field 1 only\n"); break;
case 1: printf("Field 2 only\n"); break;
case 2: printf("Regular pattern of fields 1 and
2\n"); break;
@@ -217,13 +208,18 @@
break;
}
case VS_FRAME_MJPEG:
- printf("VS_FRAME_MJPEG:"); // fall through
case VS_FRAME_UNCOMPRESSED:
{
- if (_descriptor->descriptorSubtype ==
VS_FRAME_UNCOMPRESSED)
+ const usbvc_frame_descriptor* descriptor
+ = (const usbvc_frame_descriptor*)_descriptor;
+ if (_descriptor->descriptorSubtype ==
VS_FRAME_UNCOMPRESSED) {
printf("VS_FRAME_UNCOMPRESSED:");
- const usbvc_frame_descriptor* descriptor =
- (const usbvc_frame_descriptor*)_descriptor;
+ fUncompressedFrames.AddItem(
+ new
usbvc_frame_descriptor(*descriptor));
+ } else {
+ printf("VS_FRAME_MJPEG:");
+ fMJPEGFrames.AddItem(new
usbvc_frame_descriptor(*descriptor));
+ }
printf("\tbFrameIdx=%d,stillsupported=%s,"
"fixedframerate=%s\n", descriptor->frameIndex,
(descriptor->capabilities & 1) ? "yes" : "no",
@@ -240,17 +236,17 @@
descriptor->continuous.maxFrameInterval,
descriptor->continuous.frameIntervalStep);
} else for (uint8 i = 0; i <
descriptor->frameIntervalType; i++) {
- printf("discrete frame interval: %lu\n",
+ printf("\tdiscrete frame interval: %lu\n",
descriptor->discreteFrameIntervals[i]);
}
break;
}
case VS_COLORFORMAT:
{
- const usbvc_color_matching_descriptor* descriptor =
- (const
usbvc_color_matching_descriptor*)_descriptor;
+ const usbvc_color_matching_descriptor* descriptor
+ = (const
usbvc_color_matching_descriptor*)_descriptor;
printf("VS_COLORFORMAT:\n\tbColorPrimaries: ");
- switch(descriptor->colorPrimaries) {
+ switch (descriptor->colorPrimaries) {
case 0: printf("Unspecified\n"); break;
case 1: printf("BT.709,sRGB\n"); break;
case 2: printf("BT.470-2(M)\n"); break;
@@ -260,7 +256,7 @@
default: printf("Invalid (%d)\n",
descriptor->colorPrimaries);
}
printf("\tbTransferCharacteristics: ");
- switch(descriptor->transferCharacteristics) {
+ switch (descriptor->transferCharacteristics) {
case 0: printf("Unspecified\n"); break;
case 1: printf("BT.709\n"); break;
case 2: printf("BT.470-2(M)\n"); break;
@@ -273,7 +269,7 @@
descriptor->transferCharacteristics);
}
printf("\tbMatrixCoefficients: ");
- switch(descriptor->matrixCoefficients) {
+ switch (descriptor->matrixCoefficients) {
case 0: printf("Unspecified\n"); break;
case 1: printf("BT.709\n"); break;
case 2: printf("FCC\n"); break;
@@ -286,12 +282,12 @@
}
case VS_OUTPUT_HEADER:
{
- const usbvc_output_header_descriptor* descriptor =
- (const
usbvc_output_header_descriptor*)_descriptor;
+ const usbvc_output_header_descriptor* descriptor
+ = (const
usbvc_output_header_descriptor*)_descriptor;
printf("VS_OUTPUT_HEADER:\t#fmts=%d,ept=0x%x\n",
descriptor->numFormats,
descriptor->endpointAddress);
printf("\toutput terminal id=%d\n",
descriptor->terminalLink);
- const uint8 *controls = descriptor->controls;
+ const uint8* controls = descriptor->controls;
for (uint8 i = 0; i < descriptor->numFormats; i++,
controls += descriptor->controlSize) {
printf("\tfmt%d: %s %s %s %s\n", i,
@@ -304,8 +300,8 @@
}
case VS_STILL_IMAGE_FRAME:
{
- const usbvc_still_image_frame_descriptor* descriptor =
- (const
usbvc_still_image_frame_descriptor*)_descriptor;
+ const usbvc_still_image_frame_descriptor* descriptor
+ = (const
usbvc_still_image_frame_descriptor*)_descriptor;
printf("VS_STILL_IMAGE_FRAME:\t#imageSizes=%d,compressions=%d,"
"ept=0x%x\n", descriptor->numImageSizePatterns,
descriptor->NumCompressionPatterns(),
@@ -323,8 +319,9 @@
}
case VS_FORMAT_MJPEG:
{
- const usbvc_format_descriptor* descriptor =
- (const usbvc_format_descriptor*)_descriptor;
+ const usbvc_format_descriptor* descriptor
+ = (const usbvc_format_descriptor*)_descriptor;
+ fMJPEGFormatIndex = descriptor->formatIndex;
printf("VS_FORMAT_MJPEG:\tbFormatIdx=%d,#frmdesc=%d\n",
descriptor->formatIndex,
descriptor->numFrameDescriptors);
printf("\t#flgs=%d,optfrmidx=%d,aspRX=%d,aspRY=%d\n",
@@ -340,7 +337,7 @@
if (descriptor->mjpeg.interlaceFlags & 4)
printf("\tField 1 first\n");
printf("\tField Pattern: ");
- switch((descriptor->mjpeg.interlaceFlags & 0x30) >> 4) {
+ switch ((descriptor->mjpeg.interlaceFlags & 0x30) >> 4)
{
case 0: printf("Field 1 only\n"); break;
case 1: printf("Field 2 only\n"); break;
case 2: printf("Regular pattern of fields 1 and
2\n"); break;
@@ -376,10 +373,15 @@
UVCCamDevice::_ParseVideoControl(const usbvc_class_descriptor* _descriptor,
size_t len)
{
- switch(_descriptor->descriptorSubtype) {
+ switch (_descriptor->descriptorSubtype) {
case VC_HEADER:
{
- fHeaderDescriptor =
(usbvc_interface_header_descriptor*)_descriptor;
+ if (fHeaderDescriptor != NULL) {
+ printf("ERROR: multiple VC_HEADER!
Skipping...\n");
+ break;
+ }
+ fHeaderDescriptor =
(usbvc_interface_header_descriptor*)malloc(len);
+ memcpy(fHeaderDescriptor, _descriptor, len);
printf("VC_HEADER:\tUVC v%x.%02x, clk %.5f MHz\n",
fHeaderDescriptor->version >> 8,
fHeaderDescriptor->version & 0xff,
@@ -392,16 +394,16 @@
}
case VC_INPUT_TERMINAL:
{
- const usbvc_input_terminal_descriptor* descriptor =
- (const
usbvc_input_terminal_descriptor*)_descriptor;
+ const usbvc_input_terminal_descriptor* descriptor
+ = (const
usbvc_input_terminal_descriptor*)_descriptor;
printf("VC_INPUT_TERMINAL:\tid=%d,type=%04x,associated
terminal="
"%d\n", descriptor->terminalID,
descriptor->terminalType,
descriptor->associatedTerminal);
printf("\tDesc: %s\n",
fDevice->DecodeStringDescriptor(descriptor->terminal));
if (descriptor->terminalType == 0x201) {
- const usbvc_camera_terminal_descriptor* desc =
- (const
usbvc_camera_terminal_descriptor*)descriptor;
+ const usbvc_camera_terminal_descriptor* desc
+ = (const
usbvc_camera_terminal_descriptor*)descriptor;
printf("\tObjectiveFocalLength Min/Max %d/%d\n",
desc->objectiveFocalLengthMin,
desc->objectiveFocalLengthMax);
@@ -412,8 +414,8 @@
}
case VC_OUTPUT_TERMINAL:
{
- const usbvc_output_terminal_descriptor* descriptor =
- (const
usbvc_output_terminal_descriptor*)_descriptor;
+ const usbvc_output_terminal_descriptor* descriptor
+ = (const
usbvc_output_terminal_descriptor*)_descriptor;
printf("VC_OUTPUT_TERMINAL:\tid=%d,type=%04x,associated
terminal="
"%d, src id=%d\n", descriptor->terminalID,
descriptor->terminalType,
descriptor->associatedTerminal,
@@ -424,8 +426,8 @@
}
case VC_SELECTOR_UNIT:
{
- const usbvc_selector_unit_descriptor* descriptor =
- (const
usbvc_selector_unit_descriptor*)_descriptor;
+ const usbvc_selector_unit_descriptor* descriptor
+ = (const
usbvc_selector_unit_descriptor*)_descriptor;
printf("VC_SELECTOR_UNIT:\tid=%d,#pins=%d\n",
descriptor->unitID, descriptor->numInputPins);
printf("\t");
@@ -438,9 +440,10 @@
}
case VC_PROCESSING_UNIT:
{
- const usbvc_processing_unit_descriptor* descriptor =
- (const
usbvc_processing_unit_descriptor*)_descriptor;
- printf("VC_PROCESSING_UNIT:\tid=%d,src id=%d,
digmul=%d\n",
+ const usbvc_processing_unit_descriptor* descriptor
+ = (const
usbvc_processing_unit_descriptor*)_descriptor;
+ fControlRequestIndex = fControlIndex +
(descriptor->unitID << 8);
+ printf("VC_PROCESSING_UNIT:\t unit id=%d,src id=%d,
digmul=%d\n",
descriptor->unitID, descriptor->sourceID,
descriptor->maxMultiplier);
printf("\tbControlSize=%d\n", descriptor->controlSize);
@@ -502,8 +505,8 @@
}
case VC_EXTENSION_UNIT:
{
- const usbvc_extension_unit_descriptor* descriptor =
- (const
usbvc_extension_unit_descriptor*)_descriptor;
+ const usbvc_extension_unit_descriptor* descriptor
+ = (const
usbvc_extension_unit_descriptor*)_descriptor;
printf("VC_EXTENSION_UNIT:\tid=%d, guid=",
descriptor->unitID);
print_guid(descriptor->guidExtensionCode);
printf("\n\t#ctrls=%d, #pins=%d\n",
descriptor->numControls,
@@ -547,34 +550,81 @@
status_t
-UVCCamDevice::SuggestVideoFrame(uint32 &width, uint32 &height)
+UVCCamDevice::SuggestVideoFrame(uint32& width, uint32& height)
{
+ printf("UVCCamDevice::SuggestVideoFrame(%ld, %ld)\n", width, height);
+ // As in AcceptVideoFrame(), the suggestion should probably just be the
+ // first advertised uncompressed format, but current applications prefer
+ // 320x240, so this is tried first here as a suggestion.
width = 320;
height = 240;
+ if (!AcceptVideoFrame(width, height)) {
+ const usbvc_frame_descriptor* descriptor
+ = (const
usbvc_frame_descriptor*)fUncompressedFrames.FirstItem();
+ width = (*descriptor).width;
+ height = (*descriptor).height;
+ }
return B_OK;
}
status_t
-UVCCamDevice::AcceptVideoFrame(uint32 &width, uint32 &height)
+UVCCamDevice::AcceptVideoFrame(uint32& width, uint32& height)
{
- width = 320;
- height = 240;
+ printf("UVCCamDevice::AcceptVideoFrame(%ld, %ld)\n", width, height);
+ if (width <= 0 || height <= 0) {
+ // Uncomment below when applications support dimensions other
than 320x240
+ // This code selects the first listed available uncompressed
frame format
+ /*
+ const usbvc_frame_descriptor* descriptor
+ = (const
usbvc_frame_descriptor*)fUncompressedFrames.FirstItem();
+ width = (*descriptor).width;
+ height = (*descriptor).height;
+ SetVideoFrame(BRect(0, 0, width - 1, height - 1));
+ return B_OK;
+ */
+
+ width = 320;
+ height = 240;
+ }
- SetVideoFrame(BRect(0, 0, width - 1, height - 1));
- return B_OK;
+ for (int i = 0; i<fUncompressedFrames.CountItems(); i++) {
+ const usbvc_frame_descriptor* descriptor
+ = (const
usbvc_frame_descriptor*)fUncompressedFrames.ItemAt(i);
+ if ((*descriptor).width == width && (*descriptor).height ==
height) {
+ fUncompressedFrameIndex = i;
+ SetVideoFrame(BRect(0, 0, width - 1, height - 1));
+ return B_OK;
+ }
+ }
+
+ fprintf(stderr, "UVCCamDevice::AcceptVideoFrame() Invalid frame
dimensions"
+ "\n");
+ return B_ERROR;
}
status_t
UVCCamDevice::_ProbeCommitFormat()
{
+ printf("UVCCamDevice::_ProbeCommitFormat()\n");
+ printf("UVCCamDevice::fStreamingIndex = %ld\n", fStreamingIndex);
+
+ /*
+ char error;
+ printf("BEFORE ERROR CODE CHECK.\n");
+ fDevice->ControlTransfer(
+ USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, GET_CUR,
+ VS_STREAM_ERROR_CODE_CONTROL << 8, fStreamingIndex, 1,
&error);
+ printf("Error code = Ox%x\n", error);
+ */
+
usbvc_probecommit request;
memset(&request, 0, sizeof(request));
- request.hint = 1 << 8;
+ request.hint = 1;
request.SetFrameInterval(333333);
- request.formatIndex = 1;
- request.frameIndex = 3;
+ request.formatIndex = fUncompressedFormatIndex;
+ request.frameIndex = fUncompressedFrameIndex;
size_t length = fHeaderDescriptor->version > 0x100 ? 34 : 26;
size_t actualLength = fDevice->ControlTransfer(
USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, SET_CUR,
@@ -584,7 +634,8 @@
" failed %ld\n", actualLength);
return B_ERROR;
}
-
+
+ /*
usbvc_probecommit response;
actualLength = fDevice->ControlTransfer(
USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, GET_MAX,
@@ -597,8 +648,17 @@
printf("usbvc_probecommit response.compQuality %d\n",
response.compQuality);
request.compQuality = response.compQuality;
-
+ */
+
+
+ usbvc_probecommit response;
+ memset(&response, 0, sizeof(response));
actualLength = fDevice->ControlTransfer(
+ USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, GET_CUR,
+ VS_PROBE_CONTROL << 8, fStreamingIndex, length, &response);
+
+ /*
+ actualLength = fDevice->ControlTransfer(
USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, SET_CUR,
VS_PROBE_CONTROL << 8, fStreamingIndex, length, &request);
if (actualLength != length) {
@@ -606,6 +666,7 @@
" failed\n");
return B_ERROR;
}
+ */
actualLength = fDevice->ControlTransfer(
USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, SET_CUR,
@@ -616,12 +677,14 @@
return B_ERROR;
}
+
fMaxVideoFrameSize = response.maxVideoFrameSize;
fMaxPayloadTransferSize = response.maxPayloadTransferSize;
printf("usbvc_probecommit setup done maxVideoFrameSize:%ld"
" maxPayloadTransferSize:%ld\n", fMaxVideoFrameSize,
fMaxPayloadTransferSize);
+ printf("UVCCamDevice::_ProbeCommitFormat()\n --> SUCCESSFUL\n");
return B_OK;
}
@@ -629,17 +692,18 @@
status_t
UVCCamDevice::_SelectBestAlternate()
{
- const BUSBConfiguration *config = fDevice->ActiveConfiguration();
- const BUSBInterface *streaming = config->InterfaceAt(fStreamingIndex);
+ printf("UVCCamDevice::_SelectBestAlternate()\n");
+ 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);
+ const BUSBInterface* alternate = streaming->AlternateAt(i);
for (uint32 j = 0; j < alternate->CountEndpoints(); j++) {
- const BUSBEndpoint *endpoint = alternate->EndpointAt(j);
+ const BUSBEndpoint* endpoint = alternate->EndpointAt(j);
if (!endpoint->IsIsochronous() || !endpoint->IsInput())
continue;
if (fMaxPayloadTransferSize > endpoint->MaxPacketSize())
@@ -660,7 +724,7 @@
}
printf("UVCCamDevice::_SelectBestAlternate() %ld\n", bestBandwidth);
- if (((BUSBInterface *)streaming)->SetAlternate(alternateIndex) != B_OK)
{
+ if (((BUSBInterface*)streaming)->SetAlternate(alternateIndex) != B_OK) {
fprintf(stderr, "UVCCamDevice::_SelectBestAlternate()"
" selecting alternate failed\n");
return B_ERROR;
@@ -675,9 +739,10 @@
status_t
UVCCamDevice::_SelectIdleAlternate()
{
- const BUSBConfiguration *config = fDevice->ActiveConfiguration();
- const BUSBInterface *streaming = config->InterfaceAt(fStreamingIndex);
- if (((BUSBInterface *)streaming)->SetAlternate(0) != B_OK) {
+ printf("UVCCamDevice::_SelectIdleAlternate()\n");
+ const BUSBConfiguration* config = fDevice->ActiveConfiguration();
+ const BUSBInterface* streaming = config->InterfaceAt(fStreamingIndex);
+ if (((BUSBInterface*)streaming)->SetAlternate(0) != B_OK) {
fprintf(stderr, "UVCCamDevice::_SelectIdleAlternate()"
" selecting alternate failed\n");
return B_ERROR;
@@ -692,6 +757,7 @@
UVCCamDeviceAddon::UVCCamDeviceAddon(WebCamMediaAddOn* webcam)
: CamDeviceAddon(webcam)
{
+ printf("UVCCamDeviceAddon::UVCCamDeviceAddon(WebCamMediaAddOn*
webcam)\n");
SetSupportedDevices(kSupportedDevices);
}
@@ -704,17 +770,627 @@
const char *
UVCCamDeviceAddon::BrandName()
{
+ printf("UVCCamDeviceAddon::BrandName()\n");
return "USB Video Class";
}
UVCCamDevice *
-UVCCamDeviceAddon::Instantiate(CamRoster &roster, BUSBDevice *from)
+UVCCamDeviceAddon::Instantiate(CamRoster& roster, BUSBDevice* from)
{
+ printf("UVCCamDeviceAddon::Instantiate()\n");
return new UVCCamDevice(*this, from);
}
+float
+UVCCamDevice::_AddParameter(BParameterGroup* group,
+ BParameterGroup** subgroup, int32 index, uint16 wValue, const char*
name)
+{
+ float minValue = 0.0;
+ float maxValue = 100.0;
+ float currValue = 0.0;
+
+ BContinuousParameter* p;
+ uint16 data;
+
+ wValue = wValue << 8;
+
+ fDevice->ControlTransfer(USB_REQTYPE_CLASS |
USB_REQTYPE_INTERFACE_IN,
+ GET_MAX, wValue, fControlRequestIndex, 2, &data);
+ maxValue = (float)(*((uint16*)data));
+ fDevice->ControlTransfer(USB_REQTYPE_CLASS |
USB_REQTYPE_INTERFACE_IN,
+ GET_MIN, wValue, fControlRequestIndex, 2, &data);
+ minValue = (float)(*((uint16*)data));
+ fDevice->ControlTransfer(USB_REQTYPE_CLASS |
USB_REQTYPE_INTERFACE_IN,
+ GET_CUR, wValue, fControlRequestIndex, 2, &data);
+ currValue = (float)data;
+
+ *subgroup = group->MakeGroup(name);
+ p = (*subgroup)->MakeContinuousParameter(index,
+ B_MEDIA_RAW_VIDEO, name,
+ B_GAIN, "", minValue, maxValue, 1.0 / (maxValue - minValue));
+
+ return currValue;
+}
+
+
+int UVCCamDevice::_AddAutoParameter(BParameterGroup* subgroup, int32 index,
+ uint16 wValue)
+{
+ uint8 data;
+ wValue <<= 8;
+
+ fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN,
+ GET_CUR, wValue, fControlRequestIndex, 1, &data);
+ subgroup->MakeDiscreteParameter(index, B_MEDIA_RAW_VIDEO, "Auto",
+ B_ENABLE);
+
+ return data;
+}
+
+
+void
+UVCCamDevice::AddParameters(BParameterGroup* group, int32& index)
+{
+ printf("UVCCamDevice::AddParameters()\n");
+ fFirstParameterID = index;
+// debug_printf("fIndex = %d\n",fIndex);
+ BParameterGroup* subgroup;
+ BContinuousParameter* p;
+ CamDevice::AddParameters(group, index);
+
+ const BUSBConfiguration* config;
+ const BUSBInterface* interface;
+ usb_descriptor* generic;
+ uint8 buffer[1024];
+
+ void* data = (void*)(new uint16);
+
+ generic = (usb_descriptor*)buffer;
+
+ for (uint32 i = 0; i < fDevice->CountConfigurations(); i++) {
+ config = fDevice->ConfigurationAt(i);
+ fDevice->SetConfiguration(config);
+ for (uint32 j = 0; j < config->CountInterfaces(); j++) {
+ interface = config->InterfaceAt(j);
+ if (interface->Class() == CC_VIDEO &&
interface->Subclass()
+ == SC_VIDEOCONTROL) {
+ for (uint32 k = 0;
interface->OtherDescriptorAt(k, generic,
+ sizeof(buffer)) == B_OK; k++) {
+ if (generic->generic.descriptor_type !=
(USB_REQTYPE_CLASS
+ | USB_DESCRIPTOR_INTERFACE))
+ continue;
+
+ if (((const
usbvc_class_descriptor*)generic)->descriptorSubtype
+ == VC_PROCESSING_UNIT) {
+ const
usbvc_processing_unit_descriptor* descriptor
+ = (const
usbvc_processing_unit_descriptor*)generic;
+ uint16 wValue = 0; // Control
Selector
+ float minValue = 0.0;
+ float maxValue = 100.0;
+ if (descriptor->controlSize >=
1) {
+ if
(descriptor->controls[0] & 1) {
+ //
debug_printf("\tBRIGHTNESS\n");
+ fBrightness =
_AddParameter(group, &subgroup, index,
+
PU_BRIGHTNESS_CONTROL, "Brightness");
+ }
+ if
(descriptor->controls[0] & 2) {
+ //
debug_printf("\tCONSTRAST\n");
+ fContrast =
_AddParameter(group, &subgroup, index + 1,
+
PU_CONTRAST_CONTROL, "Contrast");
+ }
+ if
(descriptor->controls[0] & 4) {
+ //
debug_printf("\tHUE\n");
+ fHue =
_AddParameter(group, &subgroup, index + 2,
+
PU_HUE_CONTROL, "Hue");
+ if
(descriptor->controlSize >= 2) {
+ if
(descriptor->controls[1] & 8) {
+
fHueAuto = _AddAutoParameter(subgroup, index + 3,
+
PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL);
+ }
+ }
+ }
+ if
(descriptor->controls[0] & 8) {
+ //
debug_printf("\tSATURATION\n");
+ fSaturation =
_AddParameter(group, &subgroup, index + 4,
+
PU_SATURATION_CONTROL, "Saturation");
+ }
+ if
(descriptor->controls[0] & 16) {
+ //
debug_printf("\tSHARPNESS\n");
+ fSharpness =
_AddParameter(group, &subgroup, index + 5,
+
PU_SHARPNESS_CONTROL, "Sharpness");
+ }
+ if
(descriptor->controls[0] & 32) {
+ //
debug_printf("\tGamma\n");
+ fGamma =
_AddParameter(group, &subgroup, index + 6,
+
PU_GAMMA_CONTROL, "Gamma");
+ }
+ if
(descriptor->controls[0] & 64) {
+ //
debug_printf("\tWHITE BALANCE TEMPERATURE\n");
+ fWBTemp =
_AddParameter(group, &subgroup, index + 7,
+
PU_WHITE_BALANCE_TEMPERATURE_CONTROL, "WB Temperature");
+ if
(descriptor->controlSize >= 2) {
+ if
(descriptor->controls[1] & 16) {
+
fWBTempAuto = _AddAutoParameter(subgroup, index + 8,
+
PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL);
+ }
+ }
+ }
+ if
(descriptor->controls[0] & 128) {
+ //
debug_printf("\tWhite Balance Component\n");
+ fWBComponent =
_AddParameter(group, &subgroup, index + 9,
+
PU_WHITE_BALANCE_COMPONENT_CONTROL, "WB Component");
+ if
(descriptor->controlSize >= 2) {
+ if
(descriptor->controls[1] & 32) {
+
fWBTempAuto = _AddAutoParameter(subgroup, index + 10,
+
PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL);
+ }
+ }
+ }
+ }
+ if (descriptor->controlSize >=
2) {
+ if
(descriptor->controls[1] & 1) {
+ //
debug_printf("\tBACKLIGHT COMPENSATION\n");
+ wValue =
PU_BACKLIGHT_COMPENSATION_CONTROL;
+ wValue = wValue
<< 8;
+
fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN,
+
GET_MAX, wValue, fControlRequestIndex, 2, data);
+ maxValue =
(float)(*((uint16*)data));
+
fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN,
+
GET_MIN, wValue, fControlRequestIndex, 2, data);
+ minValue =
(float)(*((uint16*)data));
+
fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN,
+
GET_CUR, wValue, fControlRequestIndex, 2, data);
+
fBacklightCompensation = (float)(*((uint16*)data));
+ subgroup =
group->MakeGroup("Backlight Compensation");
+ if (maxValue -
minValue == 1) { // Binary Switch
+
fBinaryBacklightCompensation = true;
+
subgroup->MakeDiscreteParameter(index + 11,
+
B_MEDIA_RAW_VIDEO, "Backlight Compensation",
+
B_ENABLE);
+ } else { //
Range of values
+
fBinaryBacklightCompensation = false;
+ p =
subgroup->MakeContinuousParameter(index + 11,
+
B_MEDIA_RAW_VIDEO, "Backlight Compensation",
+ B_GAIN,
"", minValue, maxValue, 1.0/(maxValue - minValue));
+ }
+ }
+ if
(descriptor->controls[1] & 2) {
+ //
debug_printf("\tGAIN\n");
+ fGain =
_AddParameter(group, &subgroup, index + 12, PU_GAIN_CONTROL,
+ "Gain");
+ }
+ if
(descriptor->controls[1] & 4) {
+ //
debug_printf("\tPOWER LINE FREQUENCY\n");
+ wValue =
PU_POWER_LINE_FREQUENCY_CONTROL;
+ wValue = wValue
<< 8;
+
fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN,
+
GET_CUR, wValue, fControlRequestIndex, 1, data);
+
fPowerlineFrequency = (uint16)(*((uint8*)data));
+ subgroup =
group->MakeGroup("Power Line Frequency");
+ p =
subgroup->MakeContinuousParameter(index + 13,
+
B_MEDIA_RAW_VIDEO, "Frequency",
+ B_GAIN, "", 0,
60.0, 1.0 / 60.0);
+ }
+ // TODO Determine
whether controls apply to these
+ /*
+ if
(descriptor->controls[1] & 64)
+
debug_printf("\tDigital Multiplier\n");
+ if
(descriptor->controls[1] & 128)
+
debug_printf("\tDigital Multiplier Limit\n");
+ */
+ }
+ // TODO Determine whether
controls apply to these
+ /*
+ if (descriptor->controlSize >=
3) {
+ if
(descriptor->controls[2] & 1)
+
debug_printf("\tAnalog Video Standard\n");
+ if
(descriptor->controls[2] & 2)
+
debug_printf("\tAnalog Video Lock Status\n");
+ }
+ */
+ }
+ }
+ }
+ }
+ }
+}
+
+
+status_t
+UVCCamDevice::GetParameterValue(int32 id, bigtime_t* last_change, void* value,
+ size_t* size)
+{
+ printf("UVCCAmDevice::GetParameterValue(%ld)\n", id -
fFirstParameterID);
+ float* currValue;
+ int* currValueInt;
+ void* data;
+ uint16 wValue = 0;
+ switch (id - fFirstParameterID) {
+ case 0:
+ // debug_printf("\tBrightness:\n");
+ // debug_printf("\tValue = %f\n",fBrightness);
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ *currValue = fBrightness;
+ *last_change = fLastParameterChanges;
+ return B_OK;
+ case 1:
+ // debug_printf("\tContrast:\n");
+ // debug_printf("\tValue = %f\n",fContrast);
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ *currValue = fContrast;
+ *last_change = fLastParameterChanges;
+ return B_OK;
+ case 2:
+ // debug_printf("\tHue:\n");
+ // debug_printf("\tValue = %f\n",fHue);
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ *currValue = fHue;
+ *last_change = fLastParameterChanges;
+ return B_OK;
+ case 4:
+ // debug_printf("\tSaturation:\n");
+ // debug_printf("\tValue = %f\n",fSaturation);
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ *currValue = fSaturation;
+ *last_change = fLastParameterChanges;
+ return B_OK;
+ case 5:
+ // debug_printf("\tSharpness:\n");
+ // debug_printf("\tValue = %f\n",fSharpness);
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ *currValue = fSharpness;
+ *last_change = fLastParameterChanges;
+ return B_OK;
+ case 7:
+ // debug_printf("\tWB Temperature:\n");
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ wValue = PU_WHITE_BALANCE_TEMPERATURE_CONTROL;
+ wValue = wValue << 8;
+ fDevice->ControlTransfer(USB_REQTYPE_CLASS |
USB_REQTYPE_INTERFACE_IN,
+ GET_CUR, wValue, fControlRequestIndex, 2, data);
+ fWBTemp = (float)(*((uint16*)data));
+ // debug_printf("\tValue = %f\n",fWBTemp);
+ *currValue = fWBTemp;
+ *last_change = fLastParameterChanges;
+ return B_OK;
+ case 8:
+ // debug_printf("\tWB Temperature Auto:\n");
+ // debug_printf("\tValue = %d\n",fWBTempAuto);
+ *size = sizeof(int);
+ currValueInt = ((int*)value);
+ *currValueInt = fWBTempAuto;
+ *last_change = fLastParameterChanges;
+ return B_OK;
+ case 11:
+ if (!fBinaryBacklightCompensation) {
+ // debug_printf("\tBacklight Compensation:\n");
+ // debug_printf("\tValue =
%f\n",fBacklightCompensation);
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ *currValue = fBacklightCompensation;
+ *last_change = fLastParameterChanges;
+ } else {
+ // debug_printf("\tBacklight Compensation:\n");
+ // debug_printf("\tValue =
%d\n",fBacklightCompensationBinary);
+ currValueInt = ((int*)value);
+ *currValueInt = fBacklightCompensationBinary;
+ *last_change = fLastParameterChanges;
+ }
+ return B_OK;
+ case 12:
+ // debug_printf("\tGain:\n");
+ // debug_printf("\tValue = %f\n",fGain);
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ *currValue = fGain;
+ *last_change = fLastParameterChanges;
+ return B_OK;
+ case 13:
+ // debug_printf("\tPowerline Frequency:\n");
+ // debug_printf("\tValue = %d\n",fPowerlineFrequency);
+ *size = sizeof(float);
+ currValue = ((float*)value);
+ switch (fPowerlineFrequency) {
+ case 0:
+ *currValue = 0.0;
+ break;
+ case 1:
+ *currValue = 50.0;
+ break;
+ case 2:
+ *currValue = 60.0;
+ break;
+ }
+ *last_change = fLastParameterChanges;
+ return B_OK;
+
+ }
+ return B_BAD_VALUE;
+}
+
+
+status_t
+UVCCamDevice::SetParameterValue(int32 id, bigtime_t when, const void* value,
+ size_t size)
+{
+ printf("UVCCamDevice::SetParameterValue(%ld)\n", id -
fFirstParameterID);
+ uint16 wValue = 0; //Control Selector
+ uint16 setValue = 0;
+ switch (id - fFirstParameterID) {
+ case 0:
+ // debug_printf("\tBrightness:\n");
+ // debug_printf("\tValue = %f\n",*((float*)value));
+ if (!value || (size != sizeof(float)))
+ return B_BAD_VALUE;
+ wValue = PU_BRIGHTNESS_CONTROL;
+ wValue = wValue << 8;
+ fBrightness = *((float*)value);
+ fLastParameterChanges = when;
+ setValue = (uint16)fBrightness;
+ fDevice->ControlTransfer(USB_REQTYPE_CLASS |
USB_REQTYPE_INTERFACE_OUT,
+ SET_CUR, wValue, fControlRequestIndex, 2,
&setValue);
+ return B_OK;
+ case 1:
+ // debug_printf("\tContrast:\n");
+ // debug_printf("\tValue = %f\n",*((float*)value));
+ if (!value || (size != sizeof(float)))
+ return B_BAD_VALUE;
+ wValue = PU_CONTRAST_CONTROL;
+ wValue = wValue << 8;
+ fContrast = *((float*)value);
+ fLastParameterChanges = when;
+ setValue = (uint16)fContrast;
+ fDevice->ControlTransfer(USB_REQTYPE_CLASS |
USB_REQTYPE_INTERFACE_OUT,
+ SET_CUR, wValue, fControlRequestIndex, 2,
&setValue);
+ return B_OK;
+ case 2:
+ // debug_printf("\tHue:\n");
+ // debug_printf("\tValue = %f\n",*((float*)value));
+ if (!value || (size != sizeof(float)))
+ return B_BAD_VALUE;
+ wValue = PU_HUE_CONTROL;
+ wValue = wValue << 8;
+ fHue = *((float*)value);
+ fLastParameterChanges = when;
+ setValue = (uint16)fHue;
+ fDevice->ControlTransfer(USB_REQTYPE_CLASS |
USB_REQTYPE_INTERFACE_OUT,
+ SET_CUR, wValue, fControlRequestIndex, 2,
&setValue);
+ return B_OK;
[... truncated: 447 lines follow ...]
Other related posts:
- » [haiku-commits] r42688 - in haiku/trunk/src: add-ons/media/media-add-ons/usb_webcam add-ons/media/media-add-ons/usb_webcam/addons/uvc bin - korli