mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge "Camera: Advertise numbered string ID for external cameras" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
7bf05d75bc
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <regex>
|
||||
#include <linux/videodev2.h>
|
||||
#include "android-base/macros.h"
|
||||
#include "CameraMetadata.h"
|
||||
@@ -46,10 +47,20 @@ constexpr int OPEN_RETRY_SLEEP_US = 100000; // 100ms * MAX_RETRY = 0.5 seconds
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
const std::regex kDevicePathRE("/dev/video([0-9]+)");
|
||||
|
||||
ExternalCameraDevice::ExternalCameraDevice(
|
||||
const std::string& cameraId, const ExternalCameraConfig& cfg) :
|
||||
mCameraId(cameraId),
|
||||
mCfg(cfg) {}
|
||||
const std::string& devicePath, const ExternalCameraConfig& cfg) :
|
||||
mCameraId("-1"),
|
||||
mDevicePath(devicePath),
|
||||
mCfg(cfg) {
|
||||
std::smatch sm;
|
||||
if (std::regex_match(mDevicePath, sm, kDevicePathRE)) {
|
||||
mCameraId = std::to_string(mCfg.cameraIdOffset + std::stoi(sm[1]));
|
||||
} else {
|
||||
ALOGE("%s: device path match failed for %s", __FUNCTION__, mDevicePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ExternalCameraDevice::~ExternalCameraDevice() {}
|
||||
|
||||
@@ -129,20 +140,20 @@ Return<void> ExternalCameraDevice::open(
|
||||
return Void();
|
||||
}
|
||||
|
||||
unique_fd fd(::open(mCameraId.c_str(), O_RDWR));
|
||||
unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
|
||||
if (fd.get() < 0) {
|
||||
int numAttempt = 0;
|
||||
do {
|
||||
ALOGW("%s: v4l2 device %s open failed, wait 33ms and try again",
|
||||
__FUNCTION__, mCameraId.c_str());
|
||||
__FUNCTION__, mDevicePath.c_str());
|
||||
usleep(OPEN_RETRY_SLEEP_US); // sleep and try again
|
||||
fd.reset(::open(mCameraId.c_str(), O_RDWR));
|
||||
fd.reset(::open(mDevicePath.c_str(), O_RDWR));
|
||||
numAttempt++;
|
||||
} while (fd.get() < 0 && numAttempt <= MAX_RETRY);
|
||||
|
||||
if (fd.get() < 0) {
|
||||
ALOGE("%s: v4l2 device open %s failed: %s",
|
||||
__FUNCTION__, mCameraId.c_str(), strerror(errno));
|
||||
__FUNCTION__, mDevicePath.c_str(), strerror(errno));
|
||||
mLock.unlock();
|
||||
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
|
||||
return Void();
|
||||
@@ -203,9 +214,9 @@ Return<void> ExternalCameraDevice::dumpState(const ::android::hardware::hidl_han
|
||||
status_t ExternalCameraDevice::initCameraCharacteristics() {
|
||||
if (mCameraCharacteristics.isEmpty()) {
|
||||
// init camera characteristics
|
||||
unique_fd fd(::open(mCameraId.c_str(), O_RDWR));
|
||||
unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
|
||||
if (fd.get() < 0) {
|
||||
ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mCameraId.c_str());
|
||||
ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mDevicePath.c_str());
|
||||
return DEAD_OBJECT;
|
||||
}
|
||||
|
||||
|
||||
@@ -703,6 +703,7 @@ namespace external {
|
||||
namespace common {
|
||||
|
||||
namespace {
|
||||
const int kDefaultCameraIdOffset = 100;
|
||||
const int kDefaultJpegBufSize = 5 << 20; // 5MB
|
||||
const int kDefaultNumVideoBuffer = 4;
|
||||
const int kDefaultNumStillBuffer = 2;
|
||||
@@ -738,6 +739,11 @@ ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMLElement *cameraIdOffset = providerCfg->FirstChildElement("CameraIdOffset");
|
||||
if (cameraIdOffset != nullptr) {
|
||||
ret.cameraIdOffset = std::atoi(cameraIdOffset->GetText());
|
||||
}
|
||||
|
||||
XMLElement *ignore = providerCfg->FirstChildElement("ignore");
|
||||
if (ignore == nullptr) {
|
||||
ALOGI("%s: no internal ignored device specified", __FUNCTION__);
|
||||
@@ -874,6 +880,7 @@ bool ExternalCameraConfig::updateFpsList(tinyxml2::XMLElement* fpsList,
|
||||
}
|
||||
|
||||
ExternalCameraConfig::ExternalCameraConfig() :
|
||||
cameraIdOffset(kDefaultCameraIdOffset),
|
||||
maxJpegBufSize(kDefaultJpegBufSize),
|
||||
numVideoBuffers(kDefaultNumVideoBuffer),
|
||||
numStillBuffers(kDefaultNumStillBuffer),
|
||||
|
||||
@@ -149,6 +149,7 @@ protected:
|
||||
bool mInitialized = false;
|
||||
bool mInitFailed = false;
|
||||
std::string mCameraId;
|
||||
std::string mDevicePath;
|
||||
const ExternalCameraConfig& mCfg;
|
||||
std::vector<SupportedV4L2Format> mSupportedFormats;
|
||||
CroppingType mCroppingType;
|
||||
|
||||
@@ -68,6 +68,9 @@ struct ExternalCameraConfig {
|
||||
static const char* kDefaultCfgPath;
|
||||
static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
|
||||
|
||||
// CameraId base offset for numerical representation
|
||||
uint32_t cameraIdOffset;
|
||||
|
||||
// List of internal V4L2 video nodes external camera HAL must ignore.
|
||||
std::unordered_set<std::string> mInternalDevices;
|
||||
|
||||
|
||||
@@ -44,17 +44,19 @@ const int kMaxDevicePathLen = 256;
|
||||
const char* kDevicePath = "/dev/";
|
||||
constexpr char kPrefix[] = "video";
|
||||
constexpr int kPrefixLen = sizeof(kPrefix) - 1;
|
||||
constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1;
|
||||
|
||||
bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
|
||||
std::string* cameraId) {
|
||||
bool matchDeviceName(int cameraIdOffset,
|
||||
const hidl_string& deviceName, std::string* deviceVersion,
|
||||
std::string* cameraDevicePath) {
|
||||
std::string deviceNameStd(deviceName.c_str());
|
||||
std::smatch sm;
|
||||
if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
|
||||
if (deviceVersion != nullptr) {
|
||||
*deviceVersion = sm[1];
|
||||
}
|
||||
if (cameraId != nullptr) {
|
||||
*cameraId = sm[2];
|
||||
if (cameraDevicePath != nullptr) {
|
||||
*cameraDevicePath = "/dev/video" + std::to_string(std::stoi(sm[2]) - cameraIdOffset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -146,8 +148,9 @@ Return<void> ExternalCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
|
||||
const hidl_string& cameraDeviceName,
|
||||
ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) {
|
||||
|
||||
std::string cameraId, deviceVersion;
|
||||
bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
|
||||
std::string cameraDevicePath, deviceVersion;
|
||||
bool match = matchDeviceName(mCfg.cameraIdOffset, cameraDeviceName,
|
||||
&deviceVersion, &cameraDevicePath);
|
||||
if (!match) {
|
||||
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
||||
return Void();
|
||||
@@ -164,19 +167,19 @@ Return<void> ExternalCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
|
||||
case 4: {
|
||||
ALOGV("Constructing v3.4 external camera device");
|
||||
deviceImpl = new device::V3_4::implementation::ExternalCameraDevice(
|
||||
cameraId, mCfg);
|
||||
cameraDevicePath, mCfg);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
ALOGV("Constructing v3.5 external camera device");
|
||||
deviceImpl = new device::V3_5::implementation::ExternalCameraDevice(
|
||||
cameraId, mCfg);
|
||||
cameraDevicePath, mCfg);
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
ALOGV("Constructing v3.6 external camera device");
|
||||
deviceImpl = new device::V3_6::implementation::ExternalCameraDevice(
|
||||
cameraId, mCfg);
|
||||
cameraDevicePath, mCfg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -186,7 +189,7 @@ Return<void> ExternalCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
|
||||
}
|
||||
|
||||
if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
|
||||
ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
|
||||
ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraDevicePath.c_str());
|
||||
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
|
||||
return Void();
|
||||
}
|
||||
@@ -210,12 +213,14 @@ void ExternalCameraProviderImpl_2_4::addExternalCamera(const char* devName) {
|
||||
ALOGI("ExtCam: adding %s to External Camera HAL!", devName);
|
||||
Mutex::Autolock _l(mLock);
|
||||
std::string deviceName;
|
||||
std::string cameraId = std::to_string(mCfg.cameraIdOffset +
|
||||
std::atoi(devName + kDevicePrefixLen));
|
||||
if (mPreferredHal3MinorVersion == 6) {
|
||||
deviceName = std::string("device@3.6/external/") + devName;
|
||||
deviceName = std::string("device@3.6/external/") + cameraId;
|
||||
} else if (mPreferredHal3MinorVersion == 5) {
|
||||
deviceName = std::string("device@3.5/external/") + devName;
|
||||
deviceName = std::string("device@3.5/external/") + cameraId;
|
||||
} else {
|
||||
deviceName = std::string("device@3.4/external/") + devName;
|
||||
deviceName = std::string("device@3.4/external/") + cameraId;
|
||||
}
|
||||
mCameraStatusMap[deviceName] = CameraDeviceStatus::PRESENT;
|
||||
if (mCallbacks != nullptr) {
|
||||
@@ -259,12 +264,14 @@ void ExternalCameraProviderImpl_2_4::deviceAdded(const char* devName) {
|
||||
void ExternalCameraProviderImpl_2_4::deviceRemoved(const char* devName) {
|
||||
Mutex::Autolock _l(mLock);
|
||||
std::string deviceName;
|
||||
std::string cameraId = std::to_string(mCfg.cameraIdOffset +
|
||||
std::atoi(devName + kDevicePrefixLen));
|
||||
if (mPreferredHal3MinorVersion == 6) {
|
||||
deviceName = std::string("device@3.6/external/") + devName;
|
||||
deviceName = std::string("device@3.6/external/") + cameraId;
|
||||
} else if (mPreferredHal3MinorVersion == 5) {
|
||||
deviceName = std::string("device@3.5/external/") + devName;
|
||||
deviceName = std::string("device@3.5/external/") + cameraId;
|
||||
} else {
|
||||
deviceName = std::string("device@3.4/external/") + devName;
|
||||
deviceName = std::string("device@3.4/external/") + cameraId;
|
||||
}
|
||||
if (mCameraStatusMap.find(deviceName) != mCameraStatusMap.end()) {
|
||||
mCameraStatusMap.erase(deviceName);
|
||||
|
||||
Reference in New Issue
Block a user