UsbCamera: Implement LifeCam HD-3000 exposure quirk.

On Linux, the V4L exposure setting is logarithmic and only accepts
certain exact values.
This commit is contained in:
Peter Johnson
2016-12-22 23:44:40 -08:00
parent 9ffc09a11b
commit 6f41b3cde7
2 changed files with 35 additions and 0 deletions

View File

@@ -95,14 +95,35 @@ static bool IsPercentageProperty(llvm::StringRef name) {
name == "exposure_absolute";
}
static constexpr const int quirkLifeCamHd3000[] = {
5, 10, 20, 39, 78, 156, 312, 625, 1250, 2500, 5000, 10000, 20000};
int UsbCameraImpl::RawToPercentage(const UsbCameraProperty& rawProp,
int rawValue) {
// LifeCam HD-3000 exposure setting quirk
if (m_hd3000 && rawProp.name == "raw_exposure_absolute" &&
rawProp.minimum == 5 && rawProp.maximum == 20000) {
int nelems = llvm::array_lengthof(quirkLifeCamHd3000);
for (int i = 0; i < nelems; ++i) {
if (rawValue < quirkLifeCamHd3000[i]) return 100.0 * i / nelems;
}
return 100;
}
return 100.0 * (rawValue - rawProp.minimum) /
(rawProp.maximum - rawProp.minimum);
}
int UsbCameraImpl::PercentageToRaw(const UsbCameraProperty& rawProp,
int percentValue) {
// LifeCam HD-3000 exposure setting quirk
if (m_hd3000 && rawProp.name == "raw_exposure_absolute" &&
rawProp.minimum == 5 && rawProp.maximum == 20000) {
int nelems = llvm::array_lengthof(quirkLifeCamHd3000);
int ndx = nelems * percentValue / 100.0;
if (ndx < 0) ndx = 0;
if (ndx >= nelems) ndx = nelems - 1;
return quirkLifeCamHd3000[ndx];
}
return rawProp.minimum +
(rawProp.maximum - rawProp.minimum) * (percentValue / 100.0);
}
@@ -188,6 +209,7 @@ UsbCameraImpl::UsbCameraImpl(llvm::StringRef name, llvm::StringRef path)
m_command_fd{eventfd(0, 0)},
m_active{true} {
SetDescription(GetDescriptionImpl(m_path.c_str()));
SetQuirks();
}
UsbCameraImpl::~UsbCameraImpl() {
@@ -500,6 +522,9 @@ void UsbCameraImpl::DeviceConnect() {
// Update description (as it may have changed)
SetDescription(GetDescriptionImpl(m_path.c_str()));
// Update quirks settings
SetQuirks();
// Notify
SetConnected(true);
}
@@ -1115,6 +1140,11 @@ bool UsbCameraImpl::CacheProperties(CS_Status* status) const {
return true;
}
void UsbCameraImpl::SetQuirks() {
llvm::SmallString<128> desc;
m_hd3000 = GetDescription(desc).endswith("LifeCam HD-3000");
}
void UsbCameraImpl::SetProperty(int property, int value, CS_Status* status) {
auto msg = CreateMessage(Message::kCmdSetProperty);
msg->data[0] = property;