diff --git a/cscore/src/main/native/windows/UsbCameraImpl.cpp b/cscore/src/main/native/windows/UsbCameraImpl.cpp index f0ed0b3d1f..e45f361d4f 100644 --- a/cscore/src/main/native/windows/UsbCameraImpl.cpp +++ b/cscore/src/main/native/windows/UsbCameraImpl.cpp @@ -497,21 +497,32 @@ bool UsbCameraImpl::CacheProperties(CS_Status* status) const { return true; } -void UsbCameraImpl::DeviceAddProperty(const wpi::Twine& name_, - tagVideoProcAmpProperty tag, - IAMVideoProcAmp* pProcAmp) { +template +void UsbCameraImpl::DeviceAddProperty(const wpi::Twine& name_, TagProperty tag, + IAM* pProcAmp) { // First see if properties exist bool isValid = false; auto property = std::make_unique(name_, tag, false, pProcAmp, &isValid); if (isValid) { - DeviceCacheProperty(std::move(property), pProcAmp); + DeviceCacheProperty(std::move(property), m_sourceReader.Get()); } } +template void UsbCameraImpl::DeviceAddProperty(const wpi::Twine& name_, + tagVideoProcAmpProperty tag, + IAMVideoProcAmp* pProcAmp); + +template void UsbCameraImpl::DeviceAddProperty(const wpi::Twine& name_, + tagCameraControlProperty tag, + IAMCameraControl* pProcAmp); + #define CREATEPROPERTY(val) \ DeviceAddProperty(#val, VideoProcAmp_##val, pProcAmp); +#define CREATECONTROLPROPERTY(val) \ + DeviceAddProperty(#val, CameraControl_##val, pCamControl); + void UsbCameraImpl::DeviceCacheProperties() { if (!m_sourceReader) return; @@ -532,6 +543,21 @@ void UsbCameraImpl::DeviceCacheProperties() { CREATEPROPERTY(Gain) pProcAmp->Release(); } + + IAMCameraControl* pCamControl = NULL; + + if (SUCCEEDED(m_sourceReader->GetServiceForStream( + (DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, + IID_PPV_ARGS(&pCamControl)))) { + CREATECONTROLPROPERTY(Pan) + CREATECONTROLPROPERTY(Tilt) + CREATECONTROLPROPERTY(Roll) + CREATECONTROLPROPERTY(Zoom) + CREATECONTROLPROPERTY(Exposure) + CREATECONTROLPROPERTY(Iris) + CREATECONTROLPROPERTY(Focus) + pCamControl->Release(); + } } int UsbCameraImpl::RawToPercentage(const UsbCameraProperty& rawProp, @@ -547,7 +573,7 @@ int UsbCameraImpl::PercentageToRaw(const UsbCameraProperty& rawProp, } void UsbCameraImpl::DeviceCacheProperty( - std::unique_ptr rawProp, IAMVideoProcAmp* pProcAmp) { + std::unique_ptr rawProp, IMFSourceReader* pProcAmp) { // For percentage properties, we want to cache both the raw and the // percentage versions. This function is always called with prop being // the raw property (as it's coming from the camera) so if required, we need @@ -716,16 +742,7 @@ CS_StatusValue UsbCameraImpl::DeviceCmdSetProperty( if (!prop->device) { if (prop->id == kPropConnectVerboseId) m_connectVerbose = value; } else { - IAMVideoProcAmp* pProcAmp = NULL; - if (SUCCEEDED(m_sourceReader->GetServiceForStream( - (DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, - IID_PPV_ARGS(&pProcAmp)))) { - if (!prop->DeviceSet(lock, pProcAmp, value)) { - pProcAmp->Release(); - return CS_PROPERTY_WRITE_FAILED; - } - pProcAmp->Release(); - } else { + if (!prop->DeviceSet(lock, m_sourceReader.Get())) { return CS_PROPERTY_WRITE_FAILED; } } diff --git a/cscore/src/main/native/windows/UsbCameraImpl.h b/cscore/src/main/native/windows/UsbCameraImpl.h index 5b730fb6f6..4013cda5de 100644 --- a/cscore/src/main/native/windows/UsbCameraImpl.h +++ b/cscore/src/main/native/windows/UsbCameraImpl.h @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2018 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -132,11 +132,12 @@ class UsbCameraImpl : public SourceImpl, CS_StatusValue DeviceSetMode(); void DeviceCacheMode(); void DeviceCacheProperty(std::unique_ptr rawProp, - IAMVideoProcAmp* pProcAmp); + IMFSourceReader* sourceReader); void DeviceCacheProperties(); void DeviceCacheVideoModes(); - void DeviceAddProperty(const wpi::Twine& name_, tagVideoProcAmpProperty tag, - IAMVideoProcAmp* pProcAmp); + template + void DeviceAddProperty(const wpi::Twine& name_, TagProperty tag, + IAM* pProcAmp); ComPtr DeviceCheckModeValid(const VideoMode& toCheck); diff --git a/cscore/src/main/native/windows/UsbCameraProperty.cpp b/cscore/src/main/native/windows/UsbCameraProperty.cpp index 73bc6c01fd..ee4198b493 100644 --- a/cscore/src/main/native/windows/UsbCameraProperty.cpp +++ b/cscore/src/main/native/windows/UsbCameraProperty.cpp @@ -7,13 +7,16 @@ #include "UsbCameraProperty.h" +#include "ComPtr.h" + using namespace cs; UsbCameraProperty::UsbCameraProperty(const wpi::Twine& name_, tagVideoProcAmpProperty tag, bool autoProp, IAMVideoProcAmp* pProcAmp, bool* isValid) : PropertyImpl{autoProp ? name_ + "_auto" : name_} { - this->tag = tag; + this->tagVideoProc = tag; + this->isControlProperty = false; this->isAutoProp = autoProp; long paramVal, paramFlag; // NOLINT(runtime/int) HRESULT hr; @@ -42,7 +45,7 @@ bool UsbCameraProperty::DeviceGet(std::unique_lock& lock, lock.unlock(); long newValue = 0, paramFlag = 0; // NOLINT(runtime/int) - if (SUCCEEDED(pProcAmp->Get(tag, &newValue, ¶mFlag))) { + if (SUCCEEDED(pProcAmp->Get(tagVideoProc, &newValue, ¶mFlag))) { lock.lock(); value = newValue; return true; @@ -60,10 +63,127 @@ bool UsbCameraProperty::DeviceSet(std::unique_lock& lock, if (!pProcAmp) return true; lock.unlock(); - if (SUCCEEDED(pProcAmp->Set(tag, newValue, VideoProcAmp_Flags_Manual))) { + if (SUCCEEDED( + pProcAmp->Set(tagVideoProc, newValue, VideoProcAmp_Flags_Manual))) { lock.lock(); return true; } return false; } + +UsbCameraProperty::UsbCameraProperty(const wpi::Twine& name_, + tagCameraControlProperty tag, + bool autoProp, IAMCameraControl* pProcAmp, + bool* isValid) + : PropertyImpl{autoProp ? name_ + "_auto" : name_} { + this->tagCameraControl = tag; + this->isControlProperty = true; + this->isAutoProp = autoProp; + long paramVal, paramFlag; // NOLINT(runtime/int) + HRESULT hr; + long minVal, maxVal, stepVal; // NOLINT(runtime/int) + hr = pProcAmp->GetRange(tag, &minVal, &maxVal, &stepVal, ¶mVal, + ¶mFlag); // Unable to get the property, trying to + // return default value + if (SUCCEEDED(hr)) { + minimum = minVal; + maximum = maxVal; + hasMaximum = true; + hasMinimum = true; + defaultValue = paramVal; + step = stepVal; + value = paramVal; + propKind = CS_PropertyKind::CS_PROP_INTEGER; + *isValid = true; + } else { + *isValid = false; + } +} + +bool UsbCameraProperty::DeviceGet(std::unique_lock& lock, + IAMCameraControl* pProcAmp) { + if (!pProcAmp) return true; + + lock.unlock(); + long newValue = 0, paramFlag = 0; // NOLINT(runtime/int) + if (SUCCEEDED(pProcAmp->Get(tagCameraControl, &newValue, ¶mFlag))) { + lock.lock(); + value = newValue; + return true; + } + + return false; +} +bool UsbCameraProperty::DeviceSet(std::unique_lock& lock, + IAMCameraControl* pProcAmp) const { + return DeviceSet(lock, pProcAmp, value); +} +bool UsbCameraProperty::DeviceSet(std::unique_lock& lock, + IAMCameraControl* pProcAmp, + int newValue) const { + if (!pProcAmp) return true; + + lock.unlock(); + if (SUCCEEDED(pProcAmp->Set(tagCameraControl, newValue, + CameraControl_Flags_Manual))) { + lock.lock(); + return true; + } + + return false; +} + +bool UsbCameraProperty::DeviceGet(std::unique_lock& lock, + IMFSourceReader* sourceReader) { + if (!sourceReader) return true; + + if (isControlProperty) { + ComPtr pProcAmp; + if (SUCCEEDED(sourceReader->GetServiceForStream( + (DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, + IID_PPV_ARGS(pProcAmp.GetAddressOf())))) { + return DeviceGet(lock, pProcAmp.Get()); + } else { + return false; + } + } else { + ComPtr pProcAmp; + if (SUCCEEDED(sourceReader->GetServiceForStream( + (DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, + IID_PPV_ARGS(pProcAmp.GetAddressOf())))) { + return DeviceGet(lock, pProcAmp.Get()); + } else { + return false; + } + } +} +bool UsbCameraProperty::DeviceSet(std::unique_lock& lock, + IMFSourceReader* sourceReader) const { + return DeviceSet(lock, sourceReader, value); +} +bool UsbCameraProperty::DeviceSet(std::unique_lock& lock, + IMFSourceReader* sourceReader, + int newValue) const { + if (!sourceReader) return true; + + if (isControlProperty) { + ComPtr pProcAmp; + if (SUCCEEDED(sourceReader->GetServiceForStream( + (DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, + IID_PPV_ARGS(pProcAmp.GetAddressOf())))) { + return DeviceSet(lock, pProcAmp.Get(), newValue); + } else { + return false; + } + } else { + ComPtr pProcAmp; + if (SUCCEEDED(sourceReader->GetServiceForStream( + (DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, + IID_PPV_ARGS(pProcAmp.GetAddressOf())))) { + return DeviceSet(lock, pProcAmp.Get(), newValue); + } else { + return false; + } + } +} diff --git a/cscore/src/main/native/windows/UsbCameraProperty.h b/cscore/src/main/native/windows/UsbCameraProperty.h index 5d63c73652..68795fc359 100644 --- a/cscore/src/main/native/windows/UsbCameraProperty.h +++ b/cscore/src/main/native/windows/UsbCameraProperty.h @@ -7,6 +7,10 @@ #pragma once +#include +#include +#include + #include #include @@ -49,16 +53,23 @@ class UsbCameraProperty : public PropertyImpl { UsbCameraProperty(const wpi::Twine& name_, tagVideoProcAmpProperty tag, bool autoProp, IAMVideoProcAmp* pProcAmp, bool* isValid); - bool DeviceGet(std::unique_lock& lock, IAMVideoProcAmp* pProcAmp); + UsbCameraProperty(const wpi::Twine& name_, tagCameraControlProperty tag, + bool autoProp, IAMCameraControl* pProcAmp, bool* isValid); + + bool DeviceGet(std::unique_lock& lock, + IMFSourceReader* sourceReader); bool DeviceSet(std::unique_lock& lock, - IAMVideoProcAmp* pProcAmp) const; - bool DeviceSet(std::unique_lock& lock, IAMVideoProcAmp* pProcAmp, - int newValue) const; + IMFSourceReader* sourceReader) const; + bool DeviceSet(std::unique_lock& lock, + IMFSourceReader* sourceReader, int newValue) const; // If this is a device (rather than software) property bool device{true}; bool isAutoProp{true}; - tagVideoProcAmpProperty tag; + + bool isControlProperty{false}; + tagVideoProcAmpProperty tagVideoProc; + tagCameraControlProperty tagCameraControl; // If this is a percentage (rather than raw) property bool percentage{false}; @@ -68,5 +79,19 @@ class UsbCameraProperty : public PropertyImpl { unsigned id{0}; // implementation-level id int type{0}; // implementation type, not CS_PropertyKind! + + private: + bool DeviceGet(std::unique_lock& lock, + IAMCameraControl* pProcAmp); + bool DeviceSet(std::unique_lock& lock, + IAMCameraControl* pProcAmp) const; + bool DeviceSet(std::unique_lock& lock, IAMCameraControl* pProcAmp, + int newValue) const; + + bool DeviceGet(std::unique_lock& lock, IAMVideoProcAmp* pProcAmp); + bool DeviceSet(std::unique_lock& lock, + IAMVideoProcAmp* pProcAmp) const; + bool DeviceSet(std::unique_lock& lock, IAMVideoProcAmp* pProcAmp, + int newValue) const; }; } // namespace cs