Merge "Camera: Advertise numbered string ID for external cameras" into rvc-dev am: 7bf05d75bc

Change-Id: Ie249d2be0b955cfae416672df52e78aea3483d63
This commit is contained in:
TreeHugger Robot
2020-03-18 21:52:15 +00:00
committed by Automerger Merge Worker
5 changed files with 54 additions and 25 deletions

View File

@@ -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;
}

View File

@@ -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),

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);