diff --git a/include/cameraserver_c.h b/include/cameraserver_c.h index a5d284ea0d..5f9f2d898a 100644 --- a/include/cameraserver_c.h +++ b/include/cameraserver_c.h @@ -44,9 +44,14 @@ typedef CS_Handle CS_Source; // Status values // enum CS_StatusValue { + CS_PROPERTY_WRITE_FAILED = 2000, CS_OK = 0, CS_INVALID_HANDLE = -2000, // handle was invalid (does not exist) - CS_WRONG_HANDLE_SUBTYPE = -2001 + CS_WRONG_HANDLE_SUBTYPE = -2001, + CS_INVALID_PROPERTY = -2002, + CS_WRONG_PROPERTY_TYPE = -2003, + CS_PROPERTY_READ_FAILED = -2004, + CS_SOURCE_IS_DISCONNECTED = -2005 }; // diff --git a/src/HTTPSinkImpl.cpp b/src/HTTPSinkImpl.cpp index 3f003bb581..c259eb394d 100644 --- a/src/HTTPSinkImpl.cpp +++ b/src/HTTPSinkImpl.cpp @@ -192,32 +192,33 @@ void HTTPSinkImpl::SendJSON(llvm::raw_ostream& os, SourceImpl& source, else os << ",\n"; os << "{"; + CS_Status status = 0; llvm::SmallString<128> name; - source.GetPropertyName(prop, name); + source.GetPropertyName(prop, name, &status); auto type = source.GetPropertyType(prop); os << "\n\"name\": \"" << name << '"'; os << ",\n\"id\": \"" << prop << '"'; os << ",\n\"type\": \"" << type << '"'; - os << ",\n\"min\": \"" << source.GetPropertyMin(prop) << '"'; - os << ",\n\"max\": \"" << source.GetPropertyMax(prop) << '"'; + os << ",\n\"min\": \"" << source.GetPropertyMin(prop, &status) << '"'; + os << ",\n\"max\": \"" << source.GetPropertyMax(prop, &status) << '"'; // os << ",\n\"step\": \"" << param->step << '"'; // os << ",\n\"default\": \"" << param->default_value << '"'; os << ",\n\"value\": \""; switch (type) { case CS_PROP_BOOLEAN: - os << (source.GetBooleanProperty(prop) ? "1" : "0"); + os << (source.GetBooleanProperty(prop, &status) ? "1" : "0"); break; case CS_PROP_DOUBLE: - os << source.GetDoubleProperty(prop); + os << source.GetDoubleProperty(prop, &status); break; case CS_PROP_STRING: { llvm::SmallString<128> strval; - source.GetStringProperty(prop, strval); + source.GetStringProperty(prop, strval, &status); os << strval.str(); break; } case CS_PROP_ENUM: - os << source.GetEnumProperty(prop); + os << source.GetEnumProperty(prop, &status); break; default: break; @@ -230,7 +231,7 @@ void HTTPSinkImpl::SendJSON(llvm::raw_ostream& os, SourceImpl& source, // append the menu object to the menu typecontrols if (source.GetPropertyType(prop) == CS_PROP_ENUM) { os << ",\n\"menu\": {"; - auto choices = source.GetEnumPropertyChoices(prop); + auto choices = source.GetEnumPropertyChoices(prop, &status); int j = 0; for (auto choice = choices.begin(), end = choices.end(); choice != end; ++j, ++choice) { diff --git a/src/SourceImpl.h b/src/SourceImpl.h index 725f5585d1..4c4035cb63 100644 --- a/src/SourceImpl.h +++ b/src/SourceImpl.h @@ -82,23 +82,28 @@ class SourceImpl { virtual llvm::ArrayRef EnumerateProperties( llvm::SmallVectorImpl& vec) const = 0; virtual CS_PropertyType GetPropertyType(int property) const = 0; - virtual llvm::StringRef GetPropertyName( - int property, llvm::SmallVectorImpl& buf) const = 0; - virtual bool GetBooleanProperty(int property) const = 0; - virtual void SetBooleanProperty(int property, bool value) = 0; - virtual double GetDoubleProperty(int property) const = 0; - virtual void SetDoubleProperty(int property, double value) = 0; - virtual double GetPropertyMin(int property) const = 0; - virtual double GetPropertyMax(int property) const = 0; - virtual double GetPropertyStep(int property) const = 0; - virtual double GetPropertyDefault(int property) const = 0; - virtual llvm::StringRef GetStringProperty( - int property, llvm::SmallVectorImpl& buf) const = 0; - virtual void SetStringProperty(int property, llvm::StringRef value) = 0; - virtual int GetEnumProperty(int property) const = 0; - virtual void SetEnumProperty(int property, int value) = 0; + virtual llvm::StringRef GetPropertyName(int property, + llvm::SmallVectorImpl& buf, + CS_Status* status) const = 0; + virtual bool GetBooleanProperty(int property, CS_Status* status) const = 0; + virtual void SetBooleanProperty(int property, bool value, + CS_Status* status) = 0; + virtual double GetDoubleProperty(int property, CS_Status* status) const = 0; + virtual void SetDoubleProperty(int property, double value, + CS_Status* status) = 0; + virtual double GetPropertyMin(int property, CS_Status* status) const = 0; + virtual double GetPropertyMax(int property, CS_Status* status) const = 0; + virtual double GetPropertyStep(int property, CS_Status* status) const = 0; + virtual double GetPropertyDefault(int property, CS_Status* status) const = 0; + virtual llvm::StringRef GetStringProperty(int property, + llvm::SmallVectorImpl& buf, + CS_Status* status) const = 0; + virtual void SetStringProperty(int property, llvm::StringRef value, + CS_Status* status) = 0; + virtual int GetEnumProperty(int property, CS_Status* status) const = 0; + virtual void SetEnumProperty(int property, int value, CS_Status* status) = 0; virtual std::vector GetEnumPropertyChoices( - int property) const = 0; + int property, CS_Status* status) const = 0; protected: void StartFrame(); diff --git a/src/USBCameraImpl.cpp b/src/USBCameraImpl.cpp index 9aec2c0b83..363e3802e1 100644 --- a/src/USBCameraImpl.cpp +++ b/src/USBCameraImpl.cpp @@ -334,19 +334,19 @@ llvm::ArrayRef USBCameraImpl::EnumerateProperties( bool USBCameraImpl::GetPropertyTypeValueFd(int property, CS_PropertyType propType, - unsigned* id, int* type, - int* fd) const { + unsigned* id, int* type, int* fd, + CS_Status* status) const { // Get id and type from cached properties { if (!m_properties_cached) CacheProperties(); std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); if (it == m_property_data.end()) { - //*status = ; + *status = CS_INVALID_PROPERTY; return false; } if (it->getSecond().propType != propType) { - //*status = ; + *status = CS_WRONG_PROPERTY_TYPE; return false; } *id = it->getSecond().id; @@ -355,7 +355,7 @@ bool USBCameraImpl::GetPropertyTypeValueFd(int property, *fd = m_fd.load(); if (*fd < 0) { - //*status = ; + *status = CS_SOURCE_IS_DISCONNECTED; return false; } return true; @@ -365,129 +365,135 @@ CS_PropertyType USBCameraImpl::GetPropertyType(int property) const { if (!m_properties_cached) CacheProperties(); std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); - if (it == m_property_data.end()) { - //*status = ; - return CS_PROP_NONE; - } + if (it == m_property_data.end()) return CS_PROP_NONE; return it->getSecond().propType; } -llvm::StringRef USBCameraImpl::GetPropertyName( - int property, llvm::SmallVectorImpl& buf) const { +llvm::StringRef USBCameraImpl::GetPropertyName(int property, + llvm::SmallVectorImpl& buf, + CS_Status* status) const { if (!m_properties_cached) CacheProperties(); std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); if (it == m_property_data.end()) { - //*status = ; + *status = CS_INVALID_PROPERTY; return llvm::StringRef{}; } return it->getSecond().name; // safe because we never modify it after caching } -bool USBCameraImpl::GetBooleanProperty(int property) const { +bool USBCameraImpl::GetBooleanProperty(int property, CS_Status* status) const { unsigned id; int type; int fd; - if (!GetPropertyTypeValueFd(property, CS_PROP_BOOLEAN, &id, &type, &fd)) + if (!GetPropertyTypeValueFd(property, CS_PROP_BOOLEAN, &id, &type, &fd, + status)) return false; int64_t value = 0; if (GetIntCtrlIoctl(fd, id, type, &value) < 0) { - //*status = ; + *status = CS_PROPERTY_READ_FAILED; return false; } return value != 0; } -void USBCameraImpl::SetBooleanProperty(int property, bool value) { +void USBCameraImpl::SetBooleanProperty(int property, bool value, + CS_Status* status) { unsigned id; int type; int fd; - if (!GetPropertyTypeValueFd(property, CS_PROP_BOOLEAN, &id, &type, &fd)) + if (!GetPropertyTypeValueFd(property, CS_PROP_BOOLEAN, &id, &type, &fd, + status)) return; if (SetIntCtrlIoctl(fd, id, type, value ? 1 : 0) < 0) { - //*status = ; + *status = CS_PROPERTY_WRITE_FAILED; } } -double USBCameraImpl::GetDoubleProperty(int property) const { +double USBCameraImpl::GetDoubleProperty(int property, CS_Status* status) const { unsigned id; int type; int fd; - if (!GetPropertyTypeValueFd(property, CS_PROP_DOUBLE, &id, &type, &fd)) + if (!GetPropertyTypeValueFd(property, CS_PROP_DOUBLE, &id, &type, &fd, + status)) return false; int64_t value = 0; if (GetIntCtrlIoctl(fd, id, type, &value) < 0) { - //*status = ; + *status = CS_PROPERTY_READ_FAILED; return false; } return value; } -void USBCameraImpl::SetDoubleProperty(int property, double value) { +void USBCameraImpl::SetDoubleProperty(int property, double value, + CS_Status* status) { unsigned id; int type; int fd; - if (!GetPropertyTypeValueFd(property, CS_PROP_DOUBLE, &id, &type, &fd)) + if (!GetPropertyTypeValueFd(property, CS_PROP_DOUBLE, &id, &type, &fd, + status)) return; if (SetIntCtrlIoctl(fd, id, type, static_cast(value)) < 0) { - //*status = ; + *status = CS_PROPERTY_WRITE_FAILED; } } -double USBCameraImpl::GetPropertyMin(int property) const { +double USBCameraImpl::GetPropertyMin(int property, CS_Status* status) const { if (!m_properties_cached) CacheProperties(); std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); if (it == m_property_data.end()) { - //*status = ; + *status = CS_INVALID_PROPERTY; return 0; } return it->getSecond().minimum; } -double USBCameraImpl::GetPropertyMax(int property) const { +double USBCameraImpl::GetPropertyMax(int property, CS_Status* status) const { if (!m_properties_cached) CacheProperties(); std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); if (it == m_property_data.end()) { - //*status = ; + *status = CS_INVALID_PROPERTY; return 0; } return it->getSecond().maximum; } -double USBCameraImpl::GetPropertyStep(int property) const { +double USBCameraImpl::GetPropertyStep(int property, CS_Status* status) const { if (!m_properties_cached) CacheProperties(); std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); if (it == m_property_data.end()) { - //*status = ; + *status = CS_INVALID_PROPERTY; return 0; } return it->getSecond().step; } -double USBCameraImpl::GetPropertyDefault(int property) const { +double USBCameraImpl::GetPropertyDefault(int property, + CS_Status* status) const { if (!m_properties_cached) CacheProperties(); std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); if (it == m_property_data.end()) { - //*status = ; + *status = CS_INVALID_PROPERTY; return 0; } return it->getSecond().defaultValue; } llvm::StringRef USBCameraImpl::GetStringProperty( - int property, llvm::SmallVectorImpl& buf) const { + int property, llvm::SmallVectorImpl& buf, CS_Status* status) const { unsigned id; int type; int fd; - if (!GetPropertyTypeValueFd(property, CS_PROP_STRING, &id, &type, &fd)) + if (!GetPropertyTypeValueFd(property, CS_PROP_STRING, &id, &type, &fd, + status)) return llvm::StringRef{}; struct v4l2_ext_control ctrl; @@ -499,14 +505,15 @@ llvm::StringRef USBCameraImpl::GetStringProperty( ctrls.controls = &ctrl; int rc = DoIoctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls); if (rc < 0) { - //*status = ; + *status = CS_PROPERTY_READ_FAILED; return llvm::StringRef{}; } buf.append(ctrl.string, ctrl.string + std::strlen(ctrl.string)); return llvm::StringRef(buf.data(), buf.size()); } -void USBCameraImpl::SetStringProperty(int property, llvm::StringRef value) { +void USBCameraImpl::SetStringProperty(int property, llvm::StringRef value, + CS_Status* status) { unsigned id; std::size_t maximum; // Get id and maximum from cached properties @@ -515,11 +522,11 @@ void USBCameraImpl::SetStringProperty(int property, llvm::StringRef value) { std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); if (it == m_property_data.end()) { - //*status = ; + *status = CS_INVALID_PROPERTY; return; } if (it->getSecond().propType != CS_PROP_STRING) { - //*status = ; + *status = CS_WRONG_PROPERTY_TYPE; return; } id = it->getSecond().id; @@ -528,7 +535,7 @@ void USBCameraImpl::SetStringProperty(int property, llvm::StringRef value) { int fd = m_fd.load(); if (fd < 0) { - //*status = ; + *status = CS_SOURCE_IS_DISCONNECTED; return; } @@ -545,39 +552,41 @@ void USBCameraImpl::SetStringProperty(int property, llvm::StringRef value) { ctrls.controls = &ctrl; int rc = DoIoctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls); if (rc < 0) { - //*status = ; + *status = CS_PROPERTY_WRITE_FAILED; return; } } -int USBCameraImpl::GetEnumProperty(int property) const { +int USBCameraImpl::GetEnumProperty(int property, CS_Status* status) const { unsigned id; int type; int fd; - if (!GetPropertyTypeValueFd(property, CS_PROP_ENUM, &id, &type, &fd)) + if (!GetPropertyTypeValueFd(property, CS_PROP_ENUM, &id, &type, &fd, status)) return false; int64_t value = 0; if (GetIntCtrlIoctl(fd, id, type, &value) < 0) { - //*status = ; + *status = CS_PROPERTY_READ_FAILED; return false; } return static_cast(value); } -void USBCameraImpl::SetEnumProperty(int property, int value) { +void USBCameraImpl::SetEnumProperty(int property, int value, + CS_Status* status) { unsigned id; int type; int fd; - if (!GetPropertyTypeValueFd(property, CS_PROP_ENUM, &id, &type, &fd)) return; + if (!GetPropertyTypeValueFd(property, CS_PROP_ENUM, &id, &type, &fd, status)) + return; if (SetIntCtrlIoctl(fd, id, type, value) < 0) { - //*status = ; + *status = CS_PROPERTY_WRITE_FAILED; } } std::vector USBCameraImpl::GetEnumPropertyChoices( - int property) const { + int property, CS_Status* status) const { unsigned id; unsigned minimum; unsigned maximum; @@ -587,11 +596,11 @@ std::vector USBCameraImpl::GetEnumPropertyChoices( std::lock_guard lock(m_mutex); auto it = m_property_data.find(property); if (it == m_property_data.end()) { - //*status = ; + *status = CS_INVALID_PROPERTY; return std::vector{}; } if (it->getSecond().propType != CS_PROP_ENUM) { - //*status = ; + *status = CS_WRONG_PROPERTY_TYPE; return std::vector{}; } id = it->getSecond().id; @@ -601,7 +610,7 @@ std::vector USBCameraImpl::GetEnumPropertyChoices( int fd = m_fd.load(); if (fd < 0) { - //*status = ; + *status = CS_SOURCE_IS_DISCONNECTED; return std::vector{}; } diff --git a/src/USBCameraImpl.h b/src/USBCameraImpl.h index 088efdb50e..57b168cc27 100644 --- a/src/USBCameraImpl.h +++ b/src/USBCameraImpl.h @@ -38,22 +38,27 @@ class USBCameraImpl : public SourceImpl { llvm::ArrayRef EnumerateProperties( llvm::SmallVectorImpl& vec) const override; CS_PropertyType GetPropertyType(int property) const override; - llvm::StringRef GetPropertyName( - int property, llvm::SmallVectorImpl& buf) const override; - bool GetBooleanProperty(int property) const override; - void SetBooleanProperty(int property, bool value) override; - double GetDoubleProperty(int property) const override; - void SetDoubleProperty(int property, double value) override; - double GetPropertyMin(int property) const override; - double GetPropertyMax(int property) const override; - double GetPropertyStep(int property) const override; - double GetPropertyDefault(int property) const override; - llvm::StringRef GetStringProperty( - int property, llvm::SmallVectorImpl& buf) const override; - void SetStringProperty(int property, llvm::StringRef value) override; - int GetEnumProperty(int property) const override; - void SetEnumProperty(int property, int value) override; - std::vector GetEnumPropertyChoices(int property) const override; + llvm::StringRef GetPropertyName(int property, + llvm::SmallVectorImpl& buf, + CS_Status* status) const override; + bool GetBooleanProperty(int property, CS_Status* status) const override; + void SetBooleanProperty(int property, bool value, CS_Status* status) override; + double GetDoubleProperty(int property, CS_Status* status) const override; + void SetDoubleProperty(int property, double value, + CS_Status* status) override; + double GetPropertyMin(int property, CS_Status* status) const override; + double GetPropertyMax(int property, CS_Status* status) const override; + double GetPropertyStep(int property, CS_Status* status) const override; + double GetPropertyDefault(int property, CS_Status* status) const override; + llvm::StringRef GetStringProperty(int property, + llvm::SmallVectorImpl& buf, + CS_Status* status) const override; + void SetStringProperty(int property, llvm::StringRef value, + CS_Status* status) override; + int GetEnumProperty(int property, CS_Status* status) const override; + void SetEnumProperty(int property, int value, CS_Status* status) override; + std::vector GetEnumPropertyChoices( + int property, CS_Status* status) const override; void Stop(); @@ -84,7 +89,8 @@ class USBCameraImpl : public SourceImpl { void CacheProperty(PropertyData&& prop) const; void CacheProperties() const; bool GetPropertyTypeValueFd(int property, CS_PropertyType propType, - unsigned* id, int* type, int* fd) const; + unsigned* id, int* type, int* fd, + CS_Status* status) const; void CameraThreadMain(); diff --git a/src/cameraserver_cpp.cpp b/src/cameraserver_cpp.cpp index 450bf5b2dd..16e0beddec 100644 --- a/src/cameraserver_cpp.cpp +++ b/src/cameraserver_cpp.cpp @@ -51,7 +51,7 @@ std::string GetPropertyName(CS_Property property, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return std::string{}; - return source->GetPropertyName(propertyIndex, buf); + return source->GetPropertyName(propertyIndex, buf, status); } llvm::StringRef GetPropertyName(CS_Property property, @@ -60,72 +60,71 @@ llvm::StringRef GetPropertyName(CS_Property property, int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return llvm::StringRef{}; - return source->GetPropertyName(propertyIndex, buf); + return source->GetPropertyName(propertyIndex, buf, status); } bool GetBooleanProperty(CS_Property property, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return false; - return source->GetBooleanProperty(propertyIndex); + return source->GetBooleanProperty(propertyIndex, status); } void SetBooleanProperty(CS_Property property, bool value, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return; - source->SetBooleanProperty(propertyIndex, value); + source->SetBooleanProperty(propertyIndex, value, status); } double GetDoubleProperty(CS_Property property, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return false; - return source->GetDoubleProperty(propertyIndex); + return source->GetDoubleProperty(propertyIndex, status); } void SetDoubleProperty(CS_Property property, double value, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return; - source->SetDoubleProperty(propertyIndex, value); + source->SetDoubleProperty(propertyIndex, value, status); } double GetPropertyMin(CS_Property property, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return 0.0; - return source->GetPropertyMin(propertyIndex); + return source->GetPropertyMin(propertyIndex, status); } double GetPropertyMax(CS_Property property, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return 0.0; - return source->GetPropertyMax(propertyIndex); + return source->GetPropertyMax(propertyIndex, status); } double GetPropertyStep(CS_Property property, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return 0.0; - return source->GetPropertyStep(propertyIndex); + return source->GetPropertyStep(propertyIndex, status); } double GetPropertyDefault(CS_Property property, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return 0.0; - return source->GetPropertyDefault(propertyIndex); + return source->GetPropertyDefault(propertyIndex, status); } std::string GetStringProperty(CS_Property property, CS_Status* status) { - llvm::SmallString<128> value; + llvm::SmallString<128> buf; int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return std::string{}; - source->GetStringProperty(propertyIndex, value); - return value.str(); + return source->GetStringProperty(propertyIndex, buf, status); } llvm::StringRef GetStringProperty(CS_Property property, @@ -134,7 +133,7 @@ llvm::StringRef GetStringProperty(CS_Property property, int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return llvm::StringRef{}; - return source->GetStringProperty(propertyIndex, buf); + return source->GetStringProperty(propertyIndex, buf, status); } void SetStringProperty(CS_Property property, llvm::StringRef value, @@ -142,21 +141,21 @@ void SetStringProperty(CS_Property property, llvm::StringRef value, int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return; - source->SetStringProperty(propertyIndex, value); + source->SetStringProperty(propertyIndex, value, status); } int GetEnumProperty(CS_Property property, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return 0; - return source->GetEnumProperty(propertyIndex); + return source->GetEnumProperty(propertyIndex, status); } void SetEnumProperty(CS_Property property, int value, CS_Status* status) { int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return; - source->SetEnumProperty(propertyIndex, value); + source->SetEnumProperty(propertyIndex, value, status); } std::vector GetEnumPropertyChoices(CS_Property property, @@ -164,7 +163,7 @@ std::vector GetEnumPropertyChoices(CS_Property property, int propertyIndex; auto source = GetPropertySource(property, &propertyIndex, status); if (!source) return std::vector{}; - return source->GetEnumPropertyChoices(propertyIndex); + return source->GetEnumPropertyChoices(propertyIndex, status); } //