Camera: plumb external camera API1 support
And also some refactoring to unify external camera
config file logics.
Bug: 72261912
Change-Id: If83d779c57540809bdaa58a5a32cf4ade734fafe
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 569acfd..61b8921 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -44,9 +44,10 @@
} // anonymous namespace
-ExternalCameraDevice::ExternalCameraDevice(const std::string& cameraId) :
+ExternalCameraDevice::ExternalCameraDevice(
+ const std::string& cameraId, const ExternalCameraConfig& cfg) :
mCameraId(cameraId),
- mCfg(ExternalCameraDeviceConfig::loadFromCfg()) {
+ mCfg(cfg) {
status_t ret = initCameraCharacteristics();
if (ret != OK) {
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 51bfe36..74fd7f4 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -55,7 +55,7 @@
ExternalCameraDeviceSession::ExternalCameraDeviceSession(
const sp<ICameraDeviceCallback>& callback,
- const ExternalCameraDeviceConfig& cfg,
+ const ExternalCameraConfig& cfg,
const std::vector<SupportedV4L2Format>& sortedFormats,
const CroppingType& croppingType,
const common::V1_0::helper::CameraMetadata& chars,
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 212573a..80f296c 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -30,14 +30,6 @@
namespace V3_4 {
namespace implementation {
-namespace {
- const int kDefaultJpegBufSize = 5 << 20; // 5MB
- const int kDefaultNumVideoBuffer = 4;
- const int kDefaultNumStillBuffer = 2;
-} // anonymous namespace
-
-const char* ExternalCameraDeviceConfig::kDefaultCfgPath = "/vendor/etc/external_camera_config.xml";
-
V4L2Frame::V4L2Frame(
uint32_t w, uint32_t h, uint32_t fourcc,
int bufIdx, int fd, uint32_t dataSize, uint64_t offset) :
@@ -148,10 +140,32 @@
return 0;
}
+bool isAspectRatioClose(float ar1, float ar2) {
+ const float kAspectRatioMatchThres = 0.025f; // This threshold is good enough to distinguish
+ // 4:3/16:9/20:9
+ // 1.33 / 1.78 / 2
+ return (std::abs(ar1 - ar2) < kAspectRatioMatchThres);
+}
-ExternalCameraDeviceConfig ExternalCameraDeviceConfig::loadFromCfg(const char* cfgPath) {
+} // namespace implementation
+} // namespace V3_4
+} // namespace device
+
+
+namespace external {
+namespace common {
+
+namespace {
+ const int kDefaultJpegBufSize = 5 << 20; // 5MB
+ const int kDefaultNumVideoBuffer = 4;
+ const int kDefaultNumStillBuffer = 2;
+} // anonymous namespace
+
+const char* ExternalCameraConfig::kDefaultCfgPath = "/vendor/etc/external_camera_config.xml";
+
+ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) {
using namespace tinyxml2;
- ExternalCameraDeviceConfig ret;
+ ExternalCameraConfig ret;
XMLDocument configXml;
XMLError err = configXml.LoadFile(cfgPath);
@@ -169,6 +183,29 @@
return ret;
}
+ XMLElement *providerCfg = extCam->FirstChildElement("Provider");
+ if (providerCfg == nullptr) {
+ ALOGI("%s: no external camera provider config specified", __FUNCTION__);
+ return ret;
+ }
+
+ XMLElement *ignore = providerCfg->FirstChildElement("ignore");
+ if (ignore == nullptr) {
+ ALOGI("%s: no internal ignored device specified", __FUNCTION__);
+ return ret;
+ }
+
+ XMLElement *id = ignore->FirstChildElement("id");
+ while (id != nullptr) {
+ const char* text = id->GetText();
+ if (text != nullptr) {
+ ret.mInternalDevices.insert(text);
+ ALOGI("%s: device %s will be ignored by external camera provider",
+ __FUNCTION__, text);
+ }
+ id = id->NextSiblingElement("id");
+ }
+
XMLElement *deviceCfg = extCam->FirstChildElement("Device");
if (deviceCfg == nullptr) {
ALOGI("%s: no external camera device config specified", __FUNCTION__);
@@ -226,7 +263,7 @@
ret.fpsLimits = limits;
}
- ALOGI("%s: external camera cfd loaded: maxJpgBufSize %d,"
+ ALOGI("%s: external camera cfg loaded: maxJpgBufSize %d,"
" num video buffers %d, num still buffers %d",
__FUNCTION__, ret.maxJpegBufSize,
ret.numVideoBuffers, ret.numStillBuffers);
@@ -237,7 +274,7 @@
return ret;
}
-ExternalCameraDeviceConfig::ExternalCameraDeviceConfig() :
+ExternalCameraConfig::ExternalCameraConfig() :
maxJpegBufSize(kDefaultJpegBufSize),
numVideoBuffers(kDefaultNumVideoBuffer),
numStillBuffers(kDefaultNumStillBuffer) {
@@ -247,16 +284,9 @@
fpsLimits.push_back({/*Size*/{4096, 3072}, /*FPS upper bound*/5.0});
}
-bool isAspectRatioClose(float ar1, float ar2) {
- const float kAspectRatioMatchThres = 0.025f; // This threshold is good enough to distinguish
- // 4:3/16:9/20:9
- // 1.33 / 1.78 / 2
- return (std::abs(ar1 - ar2) < kAspectRatioMatchThres);
-}
-} // namespace implementation
-} // namespace V3_4
-} // namespace device
+} // namespace common
+} // namespace external
} // namespace camera
} // namespace hardware
} // namespace android
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index fabf26a..cced3f7 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -67,6 +67,9 @@
using ::android::hardware::camera::common::V1_0::Status;
using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
using ::android::hardware::camera::common::V1_0::helper::ExifUtils;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+using ::android::hardware::camera::external::common::Size;
+using ::android::hardware::camera::external::common::SizeHasher;
using ::android::hardware::graphics::common::V1_0::BufferUsage;
using ::android::hardware::graphics::common::V1_0::Dataspace;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
@@ -84,7 +87,7 @@
struct ExternalCameraDeviceSession : public virtual RefBase {
ExternalCameraDeviceSession(const sp<ICameraDeviceCallback>&,
- const ExternalCameraDeviceConfig& cfg,
+ const ExternalCameraConfig& cfg,
const std::vector<SupportedV4L2Format>& sortedFormats,
const CroppingType& croppingType,
const common::V1_0::helper::CameraMetadata& chars,
@@ -277,7 +280,7 @@
mutable Mutex mLock; // Protect all private members except otherwise noted
const sp<ICameraDeviceCallback> mCallback;
- const ExternalCameraDeviceConfig mCfg;
+ const ExternalCameraConfig& mCfg;
const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
const std::vector<SupportedV4L2Format> mSupportedFormats;
const CroppingType mCroppingType;
@@ -293,7 +296,7 @@
bool mV4l2Streaming = false;
SupportedV4L2Format mV4l2StreamingFmt;
- size_t mV4L2BufferCount;
+ size_t mV4L2BufferCount = 0;
static const int kBufferWaitTimeoutSec = 3; // TODO: handle long exposure (or not allowing)
std::mutex mV4l2BufferLock; // protect the buffer count and condition below
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
index ef4b41c..5880469 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h
@@ -38,6 +38,8 @@
using ::android::hardware::camera::common::V1_0::CameraResourceCost;
using ::android::hardware::camera::common::V1_0::TorchMode;
using ::android::hardware::camera::common::V1_0::Status;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+using ::android::hardware::camera::external::common::Size;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
@@ -54,7 +56,7 @@
// be multiple CameraDevice trying to access the same physical camera. Also, provider will have
// to keep track of all CameraDevice objects in order to notify CameraDevice when the underlying
// camera is detached.
- ExternalCameraDevice(const std::string& cameraId);
+ ExternalCameraDevice(const std::string& cameraId, const ExternalCameraConfig& cfg);
~ExternalCameraDevice();
// Caller must use this method to check if CameraDevice ctor failed
@@ -95,7 +97,7 @@
Mutex mLock;
bool mInitFailed = false;
std::string mCameraId;
- const ExternalCameraDeviceConfig mCfg;
+ const ExternalCameraConfig& mCfg;
std::vector<SupportedV4L2Format> mSupportedFormats;
CroppingType mCroppingType;
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
index 849f947..e56160a 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
@@ -21,6 +21,7 @@
#include "utils/LightRefBase.h"
#include <mutex>
#include <vector>
+#include <unordered_set>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
using android::hardware::graphics::mapper::V2_0::IMapper;
@@ -29,6 +30,60 @@
namespace android {
namespace hardware {
namespace camera {
+
+namespace external {
+namespace common {
+
+struct Size {
+ uint32_t width;
+ uint32_t height;
+
+ bool operator==(const Size& other) const {
+ return (width == other.width && height == other.height);
+ }
+};
+
+struct SizeHasher {
+ size_t operator()(const Size& sz) const {
+ size_t result = 1;
+ result = 31 * result + sz.width;
+ result = 31 * result + sz.height;
+ return result;
+ }
+};
+
+struct ExternalCameraConfig {
+ static const char* kDefaultCfgPath;
+ static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
+
+ // List of internal V4L2 video nodes external camera HAL must ignore.
+ std::unordered_set<std::string> mInternalDevices;
+
+ // Maximal size of a JPEG buffer, in bytes
+ uint32_t maxJpegBufSize;
+
+ // Maximum Size that can sustain 30fps streaming
+ Size maxVideoSize;
+
+ // Size of v4l2 buffer queue when streaming <= kMaxVideoSize
+ uint32_t numVideoBuffers;
+
+ // Size of v4l2 buffer queue when streaming > kMaxVideoSize
+ uint32_t numStillBuffers;
+
+ struct FpsLimitation {
+ Size size;
+ float fpsUpperBound;
+ };
+ std::vector<FpsLimitation> fpsLimits;
+
+private:
+ ExternalCameraConfig();
+};
+
+} // common
+} // external
+
namespace device {
namespace V3_4 {
namespace implementation {
@@ -85,50 +140,6 @@
VERTICAL = 1
};
-struct Size {
- uint32_t width;
- uint32_t height;
-
- bool operator==(const Size& other) const {
- return (width == other.width && height == other.height);
- }
-};
-
-struct SizeHasher {
- size_t operator()(const Size& sz) const {
- size_t result = 1;
- result = 31 * result + sz.width;
- result = 31 * result + sz.height;
- return result;
- }
-};
-
-struct ExternalCameraDeviceConfig {
- static const char* kDefaultCfgPath;
- static ExternalCameraDeviceConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
-
- // Maximal size of a JPEG buffer, in bytes
- uint32_t maxJpegBufSize;
-
- // Maximum Size that can sustain 30fps streaming
- Size maxVideoSize;
-
- // Size of v4l2 buffer queue when streaming <= kMaxVideoSize
- uint32_t numVideoBuffers;
-
- // Size of v4l2 buffer queue when streaming > kMaxVideoSize
- uint32_t numStillBuffers;
-
- struct FpsLimitation {
- Size size;
- float fpsUpperBound;
- };
- std::vector<FpsLimitation> fpsLimits;
-
-private:
- ExternalCameraDeviceConfig();
-};
-
// Aspect ratio is defined as width/height here and ExternalCameraDevice
// will guarantee all supported sizes has width >= height (so aspect ratio >= 1.0)
#define ASPECT_RATIO(sz) (static_cast<float>((sz).width) / (sz).height)