From 67eb6cdee80a9b30e0bb8e922dcf9b4ba4ea76d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 30 Aug 2011 22:10:46 +0000 Subject: [PATCH] * extracted some private methods to have a more readable code * fixed negative parameter values handling * clean up and method shuffle git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42703 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../usb_webcam/addons/uvc/UVCCamDevice.cpp | 665 +++++++++--------- .../usb_webcam/addons/uvc/UVCCamDevice.h | 27 +- 2 files changed, 334 insertions(+), 358 deletions(-) diff --git a/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp b/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp index 3db7689d47..8973d756d3 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp +++ b/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.cpp @@ -73,7 +73,7 @@ UVCCamDevice::UVCCamDevice(CamDeviceAddon& _addon, BUSBDevice* _device) { fDeframer = new UVCDeframer(this); SetDataInput(fDeframer); - + const BUSBConfiguration* config; const BUSBInterface* interface; usb_descriptor* generic; @@ -125,7 +125,7 @@ UVCCamDevice::UVCCamDevice(CamDeviceAddon& _addon, BUSBDevice* _device) _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()) { @@ -178,7 +178,7 @@ UVCCamDevice::_ParseVideoStreaming(const usbvc_class_descriptor* _descriptor, break; } case VS_FORMAT_UNCOMPRESSED: - { + { const usbvc_format_descriptor* descriptor = (const usbvc_format_descriptor*)_descriptor; fUncompressedFormatIndex = descriptor->formatIndex; @@ -216,7 +216,7 @@ UVCCamDevice::_ParseVideoStreaming(const usbvc_class_descriptor* _descriptor, if (_descriptor->descriptorSubtype == VS_FRAME_UNCOMPRESSED) { printf("VS_FRAME_UNCOMPRESSED:"); fUncompressedFrames.AddItem( - new usbvc_frame_descriptor(*descriptor)); + new usbvc_frame_descriptor(*descriptor)); } else { printf("VS_FRAME_MJPEG:"); fMJPEGFrames.AddItem(new usbvc_frame_descriptor(*descriptor)); @@ -229,7 +229,7 @@ UVCCamDevice::_ParseVideoStreaming(const usbvc_class_descriptor* _descriptor, descriptor->width, descriptor->height, descriptor->minBitRate, descriptor->maxBitRate, descriptor->maxVideoFrameBufferSize); - printf("\tdefault frame interval: %lu, #intervals(0=cont): %d\n", + printf("\tdefault frame interval: %lu, #intervals(0=cont): %d\n", descriptor->defaultFrameInterval, descriptor->frameIntervalType); if (descriptor->frameIntervalType == 0) { printf("min/max frame interval=%lu/%lu, step=%lu\n", @@ -319,7 +319,7 @@ UVCCamDevice::_ParseVideoStreaming(const usbvc_class_descriptor* _descriptor, break; } case VS_FORMAT_MJPEG: - { + { const usbvc_format_descriptor* descriptor = (const usbvc_format_descriptor*)_descriptor; fMJPEGFormatIndex = descriptor->formatIndex; @@ -379,7 +379,7 @@ UVCCamDevice::_ParseVideoControl(const usbvc_class_descriptor* _descriptor, { if (fHeaderDescriptor != NULL) { printf("ERROR: multiple VC_HEADER! Skipping...\n"); - break; + break; } fHeaderDescriptor = (usbvc_interface_header_descriptor*)malloc(len); memcpy(fHeaderDescriptor, _descriptor, len); @@ -584,11 +584,11 @@ UVCCamDevice::AcceptVideoFrame(uint32& width, uint32& height) SetVideoFrame(BRect(0, 0, width - 1, height - 1)); return B_OK; */ - + width = 320; height = 240; } - + for (int i = 0; iControlTransfer( @@ -646,18 +646,18 @@ UVCCamDevice::_ProbeCommitFormat() " failed\n"); return B_ERROR; } - + 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, @@ -677,14 +677,14 @@ UVCCamDevice::_ProbeCommitFormat() " failed\n"); return B_ERROR; } - - + + fMaxVideoFrameSize = response.maxVideoFrameSize; - fMaxPayloadTransferSize = response.maxPayloadTransferSize; + fMaxPayloadTransferSize = response.maxPayloadTransferSize; printf("usbvc_probecommit setup done maxVideoFrameSize:%ld" " maxPayloadTransferSize:%ld\n", fMaxVideoFrameSize, fMaxPayloadTransferSize); - + printf("UVCCamDevice::_ProbeCommitFormat()\n --> SUCCESSFUL\n"); return B_OK; } @@ -696,11 +696,11 @@ UVCCamDevice::_SelectBestAlternate() 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); for (uint32 j = 0; j < alternate->CountEndpoints(); j++) { @@ -717,22 +717,22 @@ UVCCamDevice::_SelectBestAlternate() 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; } @@ -748,85 +748,195 @@ UVCCamDevice::_SelectIdleAlternate() " selecting alternate failed\n"); return B_ERROR; } - + fIsoIn = NULL; - + return B_OK; } -UVCCamDeviceAddon::UVCCamDeviceAddon(WebCamMediaAddOn* webcam) - : CamDeviceAddon(webcam) +void +UVCCamDevice::_AddProcessingParameter(BParameterGroup* group, + int32 index, const usbvc_processing_unit_descriptor* descriptor) { - printf("UVCCamDeviceAddon::UVCCamDeviceAddon(WebCamMediaAddOn* webcam)\n"); - SetSupportedDevices(kSupportedDevices); + BParameterGroup* subgroup; + BContinuousParameter* p; + 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"); + int16 data; + wValue = PU_BACKLIGHT_COMPENSATION_CONTROL << 8; + fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, + GET_MAX, wValue, fControlRequestIndex, sizeof(data), &data); + maxValue = (float)data; + fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, + GET_MIN, wValue, fControlRequestIndex, sizeof(data), &data); + minValue = (float)data; + fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, + GET_CUR, wValue, fControlRequestIndex, sizeof(data), &data); + fBacklightCompensation = (float)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 << 8; + int8 data; + if (fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, + GET_CUR, wValue, fControlRequestIndex, sizeof(data), &data) == sizeof(data)) { + fPowerlineFrequency = 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"); + } + */ + } -UVCCamDeviceAddon::~UVCCamDeviceAddon() -{ -} - - -const char * -UVCCamDeviceAddon::BrandName() -{ - printf("UVCCamDeviceAddon::BrandName()\n"); - return "USB Video Class"; -} - - -UVCCamDevice * -UVCCamDeviceAddon::Instantiate(CamRoster& roster, BUSBDevice* from) -{ - printf("UVCCamDeviceAddon::Instantiate()\n"); - return new UVCCamDevice(*this, from); -} - float -UVCCamDevice::_AddParameter(BParameterGroup* group, +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; + float minValue = 0.0; + float maxValue = 100.0; + float currValue = 0.0; + int16 data; - *subgroup = group->MakeGroup(name); - p = (*subgroup)->MakeContinuousParameter(index, - B_MEDIA_RAW_VIDEO, name, - B_GAIN, "", minValue, maxValue, 1.0 / (maxValue - minValue)); - - return currValue; + wValue <<= 8; + + if (fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, + GET_MAX, wValue, fControlRequestIndex, sizeof(data), &data) + == sizeof(data)) { + maxValue = (float)data; + } + if (fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, + GET_MIN, wValue, fControlRequestIndex, sizeof(data), &data) + == sizeof(data)) { + minValue = (float)data; + } + if (fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, + GET_CUR, wValue, fControlRequestIndex, sizeof(data), &data) + == sizeof(data)) { + currValue = (float)data; + } + + *subgroup = group->MakeGroup(name); + BContinuousParameter* 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 +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; } @@ -837,163 +947,34 @@ 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; - + usb_descriptor* 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"); - } - */ - } + if (interface->Class() != CC_VIDEO || interface->Subclass() + != SC_VIDEOCONTROL) + continue; + 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) { + _AddProcessingParameter(group, index, + (const usbvc_processing_unit_descriptor*)generic); } - } + } } } } @@ -1006,60 +987,61 @@ UVCCamDevice::GetParameterValue(int32 id, bigtime_t* last_change, void* value, printf("UVCCAmDevice::GetParameterValue(%ld)\n", id - fFirstParameterID); float* currValue; int* currValueInt; - void* data; + int16 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; + 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; + 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; + 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; + 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; + 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)); + currValue = (float*)value; + wValue = PU_WHITE_BALANCE_TEMPERATURE_CONTROL << 8; + if (fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_IN, + GET_CUR, wValue, fControlRequestIndex, sizeof(data), &data) + == sizeof(data)) { + fWBTemp = (float)data; + } // debug_printf("\tValue = %f\n",fWBTemp); - *currValue = fWBTemp; + *currValue = fWBTemp; *last_change = fLastParameterChanges; return B_OK; case 8: @@ -1067,7 +1049,7 @@ UVCCamDevice::GetParameterValue(int32 id, bigtime_t* last_change, void* value, // debug_printf("\tValue = %d\n",fWBTempAuto); *size = sizeof(int); currValueInt = ((int*)value); - *currValueInt = fWBTempAuto; + *currValueInt = fWBTempAuto; *last_change = fLastParameterChanges; return B_OK; case 11: @@ -1075,14 +1057,14 @@ UVCCamDevice::GetParameterValue(int32 id, bigtime_t* last_change, void* value, // debug_printf("\tBacklight Compensation:\n"); // debug_printf("\tValue = %f\n",fBacklightCompensation); *size = sizeof(float); - currValue = ((float*)value); - *currValue = fBacklightCompensation; + 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; + currValueInt = (int*)value; + *currValueInt = fBacklightCompensationBinary; *last_change = fLastParameterChanges; } return B_OK; @@ -1090,15 +1072,15 @@ UVCCamDevice::GetParameterValue(int32 id, bigtime_t* last_change, void* value, // debug_printf("\tGain:\n"); // debug_printf("\tValue = %f\n",fGain); *size = sizeof(float); - currValue = ((float*)value); - *currValue = fGain; + 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); + currValue = (float*)value; switch (fPowerlineFrequency) { case 0: *currValue = 0.0; @@ -1112,7 +1094,7 @@ UVCCamDevice::GetParameterValue(int32 id, bigtime_t* last_change, void* value, } *last_change = fLastParameterChanges; return B_OK; - + } return B_BAD_VALUE; } @@ -1123,149 +1105,87 @@ 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; + return _SetParameterValue(PU_BRIGHTNESS_CONTROL, (int16)fBrightness); 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; + return _SetParameterValue(PU_CONTRAST_CONTROL, (int16)fContrast); 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; + return _SetParameterValue(PU_HUE_CONTROL, (int16)fHue); case 4: // debug_printf("\tSaturation:\n"); - // debug_printf("\tValue = %f\n",*((float*)value)); if (!value || (size != sizeof(float))) return B_BAD_VALUE; - wValue = PU_SATURATION_CONTROL; - wValue = wValue << 8; fSaturation = *((float*)value); fLastParameterChanges = when; - setValue = (uint16)fSaturation; - fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, - SET_CUR, wValue, fControlRequestIndex, 2, &setValue); - return B_OK; + return _SetParameterValue(PU_SATURATION_CONTROL, (int16)fSaturation); case 5: // debug_printf("\tSharpness:\n"); - // debug_printf("\tValue = %f\n",*((float*)value)); if (!value || (size != sizeof(float))) return B_BAD_VALUE; - wValue = PU_SHARPNESS_CONTROL; - wValue = wValue << 8; fSharpness = *((float*)value); fLastParameterChanges = when; - setValue = (uint16)fSharpness; - fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, - SET_CUR, wValue, fControlRequestIndex, 2, &setValue); - return B_OK; + return _SetParameterValue(PU_SHARPNESS_CONTROL, (int16)fSharpness); case 7: - if (!fWBTempAuto) { - // debug_printf("\tWB Temperature:\n"); - // debug_printf("\tValue = %f\n",*((float*)value)); - if (!value || (size != sizeof(float))) - return B_BAD_VALUE; - wValue = PU_WHITE_BALANCE_TEMPERATURE_CONTROL; - wValue = wValue << 8; - fWBTemp = *((float*)value); - fLastParameterChanges = when; - setValue = (uint16)fWBTemp; - fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, - SET_CUR, wValue, fControlRequestIndex, 2, &setValue); - } - return B_OK; + if (fWBTempAuto) + return B_OK; + // debug_printf("\tWB Temperature:\n"); + if (!value || (size != sizeof(float))) + return B_BAD_VALUE; + fWBTemp = *((float*)value); + fLastParameterChanges = when; + return _SetParameterValue(PU_WHITE_BALANCE_TEMPERATURE_CONTROL, + (int16)fWBTemp); case 8: // debug_printf("\tWB Temperature Auto:\n"); if (!value || (size != sizeof(int))) return B_BAD_VALUE; - // debug_printf("\tValue = %d\n",*((int*)value)); - wValue = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL; - wValue = wValue << 8; fWBTempAuto = *((int*)value); fLastParameterChanges = when; - setValue = fWBTempAuto; - fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, - SET_CUR, wValue, fControlRequestIndex, 1, &setValue); - return B_OK; + return _SetParameterValue( + PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, (int8)fWBTempAuto); case 11: if (!fBinaryBacklightCompensation) { // debug_printf("\tBacklight Compensation:\n"); if (!value || (size != sizeof(float))) return B_BAD_VALUE; - // debug_printf("\tValue = %f\n",*((float*)value)); - wValue = PU_BACKLIGHT_COMPENSATION_CONTROL; - wValue = wValue << 8; fBacklightCompensation = *((float*)value); - fLastParameterChanges = when; - setValue = (uint16)fBacklightCompensation; - fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, - SET_CUR, wValue, fControlRequestIndex, 2, &setValue); - }else{ + } else { // debug_printf("\tBacklight Compensation:\n"); if (!value || (size != sizeof(int))) return B_BAD_VALUE; - // debug_printf("\tValue = %d\n",*((int*)value)); - wValue = PU_BACKLIGHT_COMPENSATION_CONTROL; - wValue = wValue << 8; fBacklightCompensationBinary = *((int*)value); - fLastParameterChanges = when; - setValue = fBacklightCompensationBinary; - fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, - SET_CUR, wValue, fControlRequestIndex, 2, &setValue); } - return B_OK; + fLastParameterChanges = when; + return _SetParameterValue(PU_BACKLIGHT_COMPENSATION_CONTROL, + (int16)fBacklightCompensationBinary); case 12: // debug_printf("\tGain:\n"); - // debug_printf("\tValue = %f\n",*((float*)value)); if (!value || (size != sizeof(float))) return B_BAD_VALUE; - wValue = PU_GAIN_CONTROL; - wValue = wValue << 8; fGain = *((float*)value); fLastParameterChanges = when; - setValue = (uint16)fGain; - fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, - SET_CUR, wValue, fControlRequestIndex, 2, &setValue); - return B_OK; + return _SetParameterValue(PU_GAIN_CONTROL, (int16)fGain); case 13: // debug_printf("\tPowerline Frequency:\n"); // debug_printf("\tValue = %f\n",*((float*)value)); if (!value || (size != sizeof(float))) return B_BAD_VALUE; - wValue = PU_POWER_LINE_FREQUENCY_CONTROL; - wValue = wValue << 8; float inValue = *((float*)value); fPowerlineFrequency = 0; if (inValue > 45.0 && inValue < 55.0) { @@ -1275,19 +1195,35 @@ UVCCamDevice::SetParameterValue(int32 id, bigtime_t when, const void* value, fPowerlineFrequency = 2; } fLastParameterChanges = when; - setValue = (uint8)fPowerlineFrequency; - fDevice->ControlTransfer(USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, - SET_CUR, wValue, fControlRequestIndex, 1, &setValue); - return B_OK; - + return _SetParameterValue(PU_POWER_LINE_FREQUENCY_CONTROL, + (int8)fPowerlineFrequency); + } return B_BAD_VALUE; } +status_t +UVCCamDevice::_SetParameterValue(uint16 wValue, int16 setValue) +{ + return (fDevice->ControlTransfer(USB_REQTYPE_CLASS + | USB_REQTYPE_INTERFACE_OUT, SET_CUR, wValue << 8, fControlRequestIndex, + sizeof(setValue), &setValue)) == sizeof(setValue); +} + + +status_t +UVCCamDevice::_SetParameterValue(uint16 wValue, int8 setValue) +{ + return (fDevice->ControlTransfer(USB_REQTYPE_CLASS + | USB_REQTYPE_INTERFACE_OUT, SET_CUR, wValue << 8, fControlRequestIndex, + sizeof(setValue), &setValue)) == sizeof(setValue); +} + + status_t UVCCamDevice::FillFrameBuffer(BBuffer* buffer, bigtime_t* stamp) -{ +{ memset(buffer->Data(), 0, buffer->SizeAvailable()); status_t err = fDeframer->WaitFrame(2000000); if (err < B_OK) { @@ -1304,21 +1240,21 @@ UVCCamDevice::FillFrameBuffer(BBuffer* buffer, bigtime_t* stamp) long int w = (long)(VideoFrame().right - VideoFrame().left + 1); long int h = (long)(VideoFrame().bottom - VideoFrame().top + 1); - + if (buffer->SizeAvailable() >= (size_t)w * h * 4) { // TODO: The Video Producer only outputs B_RGB32. This is OK for most // applications. This could be leveraged if applications can // consume B_YUV422. - _DecodeColor((unsigned char*)buffer->Data(), + _DecodeColor((unsigned char*)buffer->Data(), (unsigned char*)f->Buffer(), w, h); - } + } delete f; - return B_OK; + return B_OK; } void -UVCCamDevice::_DecodeColor(unsigned char* dst, unsigned char* src, +UVCCamDevice::_DecodeColor(unsigned char* dst, unsigned char* src, int32 width, int32 height) { long int i; @@ -1392,6 +1328,37 @@ UVCCamDevice::_DecodeColor(unsigned char* dst, unsigned char* src, } + + +UVCCamDeviceAddon::UVCCamDeviceAddon(WebCamMediaAddOn* webcam) + : CamDeviceAddon(webcam) +{ + printf("UVCCamDeviceAddon::UVCCamDeviceAddon(WebCamMediaAddOn* webcam)\n"); + SetSupportedDevices(kSupportedDevices); +} + + +UVCCamDeviceAddon::~UVCCamDeviceAddon() +{ +} + + +const char * +UVCCamDeviceAddon::BrandName() +{ + printf("UVCCamDeviceAddon::BrandName()\n"); + return "USB Video Class"; +} + + +UVCCamDevice * +UVCCamDeviceAddon::Instantiate(CamRoster& roster, BUSBDevice* from) +{ + printf("UVCCamDeviceAddon::Instantiate()\n"); + return new UVCCamDevice(*this, from); +} + + extern "C" status_t B_WEBCAM_MKINTFUNC(uvccam) (WebCamMediaAddOn* webcam, CamDeviceAddon **addon) diff --git a/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.h b/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.h index 26ecbf2d26..b40ef1fad5 100644 --- a/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.h +++ b/src/add-ons/media/media-add-ons/usb_webcam/addons/uvc/UVCCamDevice.h @@ -49,14 +49,23 @@ private: unsigned char *src, int32 width, int32 height); + void _AddProcessingParameter(BParameterGroup* group, + int32 index, + const usbvc_processing_unit_descriptor* + descriptor); float _AddParameter(BParameterGroup* group, BParameterGroup** subgroup, int32 index, uint16 wValue, const char* name); - int _AddAutoParameter(BParameterGroup* subgroup, + uint8 _AddAutoParameter(BParameterGroup* subgroup, int32 index, uint16 wValue); - + status_t _SetParameterValue(uint16 wValue, + int16 setValue); + status_t _SetParameterValue(uint16 wValue, + int8 setValue); + + usbvc_interface_header_descriptor *fHeaderDescriptor; - + const BUSBEndpoint* fInterruptIn; uint32 fControlIndex; uint16 fControlRequestIndex; @@ -67,10 +76,10 @@ private: uint32 fMJPEGFrameIndex; uint32 fMaxVideoFrameSize; uint32 fMaxPayloadTransferSize; - + BList fUncompressedFrames; BList fMJPEGFrames; - + float fBrightness; float fContrast; float fHue; @@ -81,16 +90,16 @@ private: float fWBComponent; float fBacklightCompensation; float fGain; - + bool fBinaryBacklightCompensation; - + int fWBTempAuto; int fWBCompAuto; int fHueAuto; int fBacklightCompensationBinary; int fPowerlineFrequency; - - + + };