bool Camera::SetVideoMode(unsigned int reqx, unsigned int reqy, unsigned int reqfps, bool use_Jpeg) { uInt32 count; uInt32 currentMode; if (debugOutput) printf("Set Video Mode, requesting %u x %u at %u fps %s.\n", reqx, reqy, reqfps, use_Jpeg ? "use JPEG" : "not JPEG"); // most of this is copied from wpilibC++Devices/src/USBCamera.cpp IMAQdxEnumerateVideoModes(session, NULL, &count, ¤tMode); // first call to get the count of modes IMAQdxVideoMode modes[count]; // then get the modes IMAQdxEnumerateVideoModes(session, modes, &count, ¤tMode); if (debugOutput) printf("Set Video Mode, %lu modes; Current mode %lu is %s = %lu\n", count, currentMode, modes[currentMode].Name, modes[currentMode].Value); // Groups are: // 0 - width // 1 - height // 2 - format // 3 - fps std::regex reMode("([0-9]+)\\s*x\\s*([0-9]+)\\s+(.*?)\\s+([0-9.]+)\\s*fps"); IMAQdxVideoMode* foundMode = nullptr; IMAQdxVideoMode* currentModePtr = &modes[currentMode]; double foundFps = 1000.0; for (unsigned int i = 0; i < count; i++) { if (debugOutput) printf("Video mode[%u] is %s = %lu\n", i, modes[i].Name, modes[i].Value); std::cmatch m; if (!std::regex_match(modes[i].Name, m, reMode)) continue; unsigned int width = (unsigned int) std::stoul(m[1].str()); unsigned int height = (unsigned int) std::stoul(m[2].str()); if (width != reqx) continue; if (height != reqy) continue; double fps = atof(m[4].str().c_str()); if (fps < reqfps) continue; if (fps > foundFps) continue; bool isJpeg = m[3].str().compare("jpeg") == 0 || m[3].str().compare("JPEG") == 0; if ((use_Jpeg && !isJpeg) || (!use_Jpeg && isJpeg)) continue; foundMode = &modes[i]; foundFps = fps; } if (foundMode != nullptr) { if (foundMode->Value != currentModePtr->Value) { printf("Found mode is %s = %lu\n", foundMode->Name, foundMode->Value); IMAQdxSetAttribute(session, IMAQdxAttributeVideoMode, IMAQdxValueTypeU32, foundMode->Value); return true; } } return false; }
void USBCamera::UpdateSettings() { std::lock_guard<priority_recursive_mutex> lock(m_mutex); bool wasActive = m_active; if (wasActive) StopCapture(); if (m_open) CloseCamera(); OpenCamera(); uInt32 count = 0; uInt32 currentMode = 0; SAFE_IMAQ_CALL(IMAQdxEnumerateVideoModes, m_id, nullptr, &count, ¤tMode); auto modes = std::make_unique<IMAQdxVideoMode[]>(count); SAFE_IMAQ_CALL(IMAQdxEnumerateVideoModes, m_id, modes.get(), &count, ¤tMode); // Groups are: // 0 - width // 1 - height // 2 - format // 3 - fps std::regex reMode("([0-9]+)\\s*x\\s*([0-9]+)\\s+(.*?)\\s+([0-9.]+)\\s*fps"); IMAQdxVideoMode* foundMode = nullptr; IMAQdxVideoMode* currentModePtr = &modes[currentMode]; double foundFps = 1000.0; // Loop through the modes, and find the match with the lowest fps for (unsigned int i = 0; i < count; i++) { std::cmatch m; if (!std::regex_match(modes[i].Name, m, reMode)) continue; unsigned int width = (unsigned int)std::stoul(m[1].str()); unsigned int height = (unsigned int)std::stoul(m[2].str()); if (width != m_width) continue; if (height != m_height) continue; double fps = atof(m[4].str().c_str()); if (fps < m_fps) continue; if (fps > foundFps) continue; bool isJpeg = m[3].str().compare("jpeg") == 0 || m[3].str().compare("JPEG") == 0; if ((m_useJpeg && !isJpeg) || (!m_useJpeg && isJpeg)) continue; foundMode = &modes[i]; foundFps = fps; } if (foundMode != nullptr) { if (foundMode->Value != currentModePtr->Value) { SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, IMAQdxAttributeVideoMode, IMAQdxValueTypeU32, foundMode->Value); } } if (m_whiteBalance.compare(AUTO) == 0) { SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, ATTR_WB_MODE, IMAQdxValueTypeString, AUTO); } else { SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, ATTR_WB_MODE, IMAQdxValueTypeString, MANUAL); if (m_whiteBalanceValuePresent) SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, ATTR_WB_VALUE, IMAQdxValueTypeU32, m_whiteBalanceValue); } if (m_exposure.compare(AUTO) == 0) { SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, ATTR_EX_MODE, IMAQdxValueTypeString, std::string("AutoAperaturePriority").c_str()); } else { SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, ATTR_EX_MODE, IMAQdxValueTypeString, MANUAL); if (m_exposureValuePresent) { double minv = 0.0; double maxv = 0.0; SAFE_IMAQ_CALL(IMAQdxGetAttributeMinimum, m_id, ATTR_EX_VALUE, IMAQdxValueTypeF64, &minv); SAFE_IMAQ_CALL(IMAQdxGetAttributeMaximum, m_id, ATTR_EX_VALUE, IMAQdxValueTypeF64, &maxv); double val = minv + ((maxv - minv) * ((double)m_exposureValue / 100.0)); SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, ATTR_EX_VALUE, IMAQdxValueTypeF64, val); } } SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, ATTR_BR_MODE, IMAQdxValueTypeString, MANUAL); double minv = 0.0; double maxv = 0.0; SAFE_IMAQ_CALL(IMAQdxGetAttributeMinimum, m_id, ATTR_BR_VALUE, IMAQdxValueTypeF64, &minv); SAFE_IMAQ_CALL(IMAQdxGetAttributeMaximum, m_id, ATTR_BR_VALUE, IMAQdxValueTypeF64, &maxv); double val = minv + ((maxv - minv) * ((double)m_brightness / 100.0)); SAFE_IMAQ_CALL(IMAQdxSetAttribute, m_id, ATTR_BR_VALUE, IMAQdxValueTypeF64, val); if (wasActive) StartCapture(); }