From patchwork Tue May 26 14:22:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3860 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EA68F60E08 for ; Tue, 26 May 2020 16:19:24 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 7999D4000B; Tue, 26 May 2020 14:19:24 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 26 May 2020 16:22:30 +0200 Message-Id: <20200526142237.407557-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526142237.407557-1-jacopo@jmondi.org> References: <20200526142237.407557-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/8] android: camera_device: Provide log prefix X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 14:19:25 -0000 Make the CameraDevice a Loggable subclass and provide a logPrefix() method to identify which camera the log outout refers to. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/android/camera_device.cpp | 5 +++++ src/android/camera_device.h | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 4ec429fc3f8f..ad277cb059ca 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -863,6 +863,11 @@ void CameraDevice::requestComplete(Request *request) delete buffer; } +std::string CameraDevice::logPrefix() const +{ + return "'" + camera_->name() + "'"; +} + void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp) { camera3_notify_msg_t notify = {}; diff --git a/src/android/camera_device.h b/src/android/camera_device.h index bce1cfbc85a4..350408c1a3e4 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -16,11 +16,12 @@ #include #include +#include "libcamera/internal/log.h" #include "libcamera/internal/message.h" class CameraMetadata; -class CameraDevice +class CameraDevice : protected libcamera::Loggable { public: CameraDevice(unsigned int id, const std::shared_ptr &camera); @@ -39,6 +40,9 @@ public: int processCaptureRequest(camera3_capture_request_t *request); void requestComplete(libcamera::Request *request); +protected: + std::string logPrefix() const; + private: struct Camera3RequestDescriptor { Camera3RequestDescriptor(unsigned int frameNumber, From patchwork Tue May 26 14:22:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3861 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8E29561075 for ; Tue, 26 May 2020 16:19:25 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 2459040004; Tue, 26 May 2020 14:19:24 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 26 May 2020 16:22:31 +0200 Message-Id: <20200526142237.407557-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526142237.407557-1-jacopo@jmondi.org> References: <20200526142237.407557-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/8] android: hal_manager: Report supported API version X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 14:19:26 -0000 Report the supported API version in the camera_info structure provided to the framework. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/android/camera_hal_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index 759e320dcd3b..b02d8d1a8362 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -110,7 +110,7 @@ int CameraHalManager::getCameraInfo(unsigned int id, struct camera_info *info) /* \todo Get these info dynamically inspecting the camera module. */ info->facing = id ? CAMERA_FACING_FRONT : CAMERA_FACING_BACK; info->orientation = 0; - info->device_version = 0; + info->device_version = CAMERA_DEVICE_API_VERSION_3_3; info->resource_cost = 0; info->static_camera_characteristics = camera->getStaticMetadata(); info->conflicting_devices = nullptr; From patchwork Tue May 26 14:22:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3862 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 36DD96109B for ; Tue, 26 May 2020 16:19:26 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id B80C940004; Tue, 26 May 2020 14:19:25 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 26 May 2020 16:22:32 +0200 Message-Id: <20200526142237.407557-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526142237.407557-1-jacopo@jmondi.org> References: <20200526142237.407557-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/8] android: hal_manager: Do not hardcode properties X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 14:19:26 -0000 The CameraHalManager::getCameraInfo() method hardcodes the camera facing side and orientation (which corresponds, confusingly, to libcamera's location and rotation properties). Instead of hard-coding the values based on the camera id, cache the libcamera Camera properties in a new initialize() method, and use them both to report camera info and to populate the static metadata buffer. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/android/camera_device.cpp | 80 ++++++++++++++++++++---------- src/android/camera_device.h | 8 +++ src/android/camera_hal_manager.cpp | 10 ++-- 3 files changed, 68 insertions(+), 30 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index ad277cb059ca..69b25ed2f11f 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -53,7 +53,8 @@ CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor() */ CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr &camera) - : running_(false), camera_(camera), staticMetadata_(nullptr) + : running_(false), camera_(camera), staticMetadata_(nullptr), + facing_(CAMERA_FACING_FRONT), orientation_(0) { camera_->requestCompleted.connect(this, &CameraDevice::requestComplete); } @@ -67,6 +68,45 @@ CameraDevice::~CameraDevice() delete it.second; } +/* + * Initialize the camera static information. + * This method is called before the camera device is open. + */ +int CameraDevice::initialize() +{ + /* Initialize orientation and facing side of the camera. */ + const ControlList &properties = camera_->properties(); + + if (properties.contains(properties::Location)) { + int32_t location = properties.get(properties::Location); + switch (location) { + case properties::CameraLocationFront: + facing_ = CAMERA_FACING_FRONT; + break; + case properties::CameraLocationBack: + facing_ = CAMERA_FACING_BACK; + break; + case properties::CameraLocationExternal: + facing_ = CAMERA_FACING_EXTERNAL; + break; + } + } + + /* + * The Android orientation metadata and libcamera rotation property are + * defined differently but have identical numerical values for Android + * devices such as phones and tablets. + */ + if (properties.contains(properties::Rotation)) + orientation_ = properties.get(properties::Rotation); + + return 0; +} + +/* + * Open a camera device. The static information on the camera shall have been + * initialized with a call to CameraDevice::init(); + */ int CameraDevice::open(const hw_module_t *hardwareModule) { int ret = camera_->acquire(); @@ -112,8 +152,6 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() if (staticMetadata_) return staticMetadata_->get(); - const ControlList &properties = camera_->properties(); - /* * The here reported metadata are enough to implement a basic capture * example application, but a real camera implementation will require @@ -278,15 +316,7 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, &exposureTimeRange, 2); - /* - * The Android orientation metadata and libcamera rotation property are - * defined differently but have identical numerical values for Android - * devices such as phones and tablets. - */ - int32_t orientation = 0; - if (properties.contains(properties::Rotation)) - orientation = properties.get(properties::Rotation); - staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation, 1); + staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1); std::vector testPatterModes = { ANDROID_SENSOR_TEST_PATTERN_MODE_OFF, @@ -332,20 +362,18 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() lensApertures.data(), lensApertures.size()); - uint8_t lensFacing = ANDROID_LENS_FACING_FRONT; - if (properties.contains(properties::Location)) { - int32_t location = properties.get(properties::Location); - switch (location) { - case properties::CameraLocationFront: - lensFacing = ANDROID_LENS_FACING_FRONT; - break; - case properties::CameraLocationBack: - lensFacing = ANDROID_LENS_FACING_BACK; - break; - case properties::CameraLocationExternal: - lensFacing = ANDROID_LENS_FACING_EXTERNAL; - break; - } + uint8_t lensFacing; + switch (facing_) { + default: + case CAMERA_FACING_FRONT: + lensFacing = ANDROID_LENS_FACING_FRONT; + break; + case CAMERA_FACING_BACK: + lensFacing = ANDROID_LENS_FACING_BACK; + break; + case CAMERA_FACING_EXTERNAL: + lensFacing = ANDROID_LENS_FACING_EXTERNAL; + break; } staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1); diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 350408c1a3e4..ace9c1b7c929 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -27,12 +27,17 @@ public: CameraDevice(unsigned int id, const std::shared_ptr &camera); ~CameraDevice(); + int initialize(); + int open(const hw_module_t *hardwareModule); void close(); unsigned int id() const { return id_; } camera3_device_t *camera3Device() { return &camera3Device_; } + int facing() const { return facing_; } + int orientation() const { return orientation_; } + void setCallbacks(const camera3_callback_ops_t *callbacks); const camera_metadata_t *getStaticMetadata(); const camera_metadata_t *constructDefaultRequestSettings(int type); @@ -69,6 +74,9 @@ private: CameraMetadata *staticMetadata_; std::map requestTemplates_; const camera3_callback_ops_t *callbacks_; + + int facing_; + int orientation_; }; #endif /* __ANDROID_CAMERA_DEVICE_H__ */ diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index b02d8d1a8362..02b6418fb36d 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -65,8 +65,11 @@ int CameraHalManager::init() unsigned int index = 0; for (auto &cam : cameraManager_->cameras()) { CameraDevice *camera = new CameraDevice(index, cam); - cameras_.emplace_back(camera); + ret = camera->initialize(); + if (ret) + continue; + cameras_.emplace_back(camera); ++index; } @@ -107,9 +110,8 @@ int CameraHalManager::getCameraInfo(unsigned int id, struct camera_info *info) CameraDevice *camera = cameras_[id].get(); - /* \todo Get these info dynamically inspecting the camera module. */ - info->facing = id ? CAMERA_FACING_FRONT : CAMERA_FACING_BACK; - info->orientation = 0; + info->facing = camera->facing(); + info->orientation = camera->orientation(); info->device_version = CAMERA_DEVICE_API_VERSION_3_3; info->resource_cost = 0; info->static_camera_characteristics = camera->getStaticMetadata(); From patchwork Tue May 26 14:22:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3863 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E097B61075 for ; Tue, 26 May 2020 16:19:26 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 676BB40002; Tue, 26 May 2020 14:19:26 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 26 May 2020 16:22:33 +0200 Message-Id: <20200526142237.407557-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526142237.407557-1-jacopo@jmondi.org> References: <20200526142237.407557-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/8] android: camera_device: Build stream configuration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 14:19:27 -0000 Build the stream configuration map by applying the Android Camera3 requested resolutions and formats to the libcamera Camera device. For each required format test a list of required and optional resolutions, construct a map to translate from Android format to the libcamera formats and store the available stream configuration to be provided to the Android framework through static metadata. Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 184 ++++++++++++++++++++++++++++++++++ src/android/camera_device.h | 13 +++ 2 files changed, 197 insertions(+) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 69b25ed2f11f..534bfb1df1ef 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -8,6 +8,8 @@ #include "camera_device.h" #include "camera_ops.h" +#include + #include #include @@ -15,9 +17,37 @@ #include "libcamera/internal/utils.h" #include "camera_metadata.h" +#include "system/graphics.h" using namespace libcamera; +namespace { + +std::set camera3Resolutions = { + { 320, 240 }, + { 640, 480 }, + { 1280, 720 }, + { 1920, 1080 } +}; + +std::map> camera3FormatsMap = { + { HAL_PIXEL_FORMAT_BLOB, { DRM_FORMAT_MJPEG } }, + { HAL_PIXEL_FORMAT_YCbCr_420_888, { DRM_FORMAT_NV12, DRM_FORMAT_NV21 } }, + /* + * \todo Translate IMPLEMENTATION_DEFINED inspecting the + * gralloc usage flag. For now, copy the YCbCr_420 configuration. + */ + { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, { DRM_FORMAT_NV12, DRM_FORMAT_NV21 } }, +}; + +std::map camera3ScalerFormatMap = { + { HAL_PIXEL_FORMAT_BLOB, ANDROID_SCALER_AVAILABLE_FORMATS_BLOB }, + { HAL_PIXEL_FORMAT_YCbCr_420_888, ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 }, + { HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED }, +}; + +} /* namespace */ + LOG_DECLARE_CATEGORY(HAL); /* @@ -100,6 +130,160 @@ int CameraDevice::initialize() if (properties.contains(properties::Rotation)) orientation_ = properties.get(properties::Rotation); + int ret = camera_->acquire(); + if (ret) { + LOG(HAL, Error) << "Failed to temporary acquire the camera"; + return ret; + } + + ret = initializeFormats(); + camera_->release(); + return ret; +} + +int CameraDevice::initializeFormats() +{ + /* + * Get the maximum output resolutions + * \todo Get this from the camera properties once defined + */ + std::unique_ptr cameraConfig = + camera_->generateConfiguration({ StillCapture }); + if (!cameraConfig) { + LOG(HAL, Error) << "Failed to get maximum resolution"; + return -EINVAL; + } + StreamConfiguration &cfg = cameraConfig->at(0); + + /* + * \todo JPEG - Adjust the maximum available resolution by + * taking the JPEG encoder requirements into account (alignement + * and aspect ratio). + */ + const Size maxRes = cfg.size; + LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString(); + + /* + * Build the list of supported image resolutions. + * + * The resolutions listed in camera3Resolution are mandatory to be + * supported, up to the camera maximum resolution. + * + * Augment the list by adding resolutions calculated from the camera + * maximum one. + */ + std::set cameraResolutions; + for (const Size &res : camera3Resolutions) { + if (res > maxRes) + continue; + + cameraResolutions.insert(res); + } + + /* Camera3 specification suggest to add 1/2 and 1/4 max resolution. */ + for (unsigned int divider = 2;; divider <<= 1) { + Size derivedSize{}; + derivedSize.width = maxRes.width / divider; + derivedSize.height = maxRes.height / divider; + + if (derivedSize.width < 320 || + derivedSize.height < 240) + break; + + /* std::set::insert() guarantees the entry is unique. */ + cameraResolutions.insert(derivedSize); + } + cameraResolutions.insert(maxRes); + + /* + * Build the list of supported camera format. + * + * To each Android format a list of compatible libcamera formats is + * associated. The first libcamera format that tests successful is added + * to the format translation map used when configuring the streams. + * It is then tested against the list of supported camera resolutions to + * build the stream configuration map reported in the camera static + * metadata. + */ + for (const auto &format : camera3FormatsMap) { + int androidFormatCode = format.first; + const std::forward_list testFormats = format.second; + + /* + * Test the libcamera formats that can produce images + * compatible with the Android's defined format + */ + uint32_t mappedFormatCode = 0; + for (int32_t formatCode : testFormats) { + /* + * \todo Fixed mapping for JPEG + */ + if (androidFormatCode == HAL_PIXEL_FORMAT_BLOB) { + mappedFormatCode = DRM_FORMAT_MJPEG; + break; + } + + /* + * The stream configuration size can be adjusted, + * not the pixel format. + */ + PixelFormat pixelFormat = PixelFormat(formatCode); + cfg.pixelFormat = pixelFormat; + + CameraConfiguration::Status status = cameraConfig->validate(); + if (status != CameraConfiguration::Invalid && + cfg.pixelFormat == pixelFormat) { + mappedFormatCode = pixelFormat.fourcc(); + break; + } + } + if (!mappedFormatCode) { + LOG(HAL, Error) << "Failed to get map Android format " + << utils::hex(androidFormatCode); + return -EINVAL; + } + + /* + * Record the mapping and then proceed to generate the + * stream configuration map, by testing the image resolutions. + */ + formatsMap_[androidFormatCode] = mappedFormatCode; + + for (const Size &res : cameraResolutions) { + PixelFormat pixelFormat = PixelFormat(mappedFormatCode); + cfg.pixelFormat = pixelFormat; + cfg.size = res; + + CameraConfiguration::Status status = cameraConfig->validate(); + /* \todo Assume we the camera can produce JPEG */ + if (androidFormatCode != HAL_PIXEL_FORMAT_BLOB && + status != CameraConfiguration::Valid) + continue; + + auto it = camera3ScalerFormatMap.find(androidFormatCode); + if (it == camera3ScalerFormatMap.end()) { + LOG(HAL, Error) << "Format " << utils::hex(androidFormatCode) + << " has no scaler format associated"; + return -EINVAL; + } + int32_t androidScalerCode = it->second; + + /* + * \todo Add support for input streams. At the moment + * register all stream configurations as output-only. + */ + streamConfigurations_.push_front( + { res, androidScalerCode, false }); + } + } + + LOG(HAL, Debug) << "Collected stream configuration map: "; + for (const auto &entry : streamConfigurations_) { + LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - " + << utils::hex(entry.androidScalerCode) << ": " + << (entry.input ? "input" : "output") << " }"; + } + return 0; } diff --git a/src/android/camera_device.h b/src/android/camera_device.h index ace9c1b7c929..95bd39f590ab 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -7,12 +7,15 @@ #ifndef __ANDROID_CAMERA_DEVICE_H__ #define __ANDROID_CAMERA_DEVICE_H__ +#include +#include #include #include #include #include +#include #include #include @@ -59,6 +62,13 @@ private: camera3_stream_buffer_t *buffers; }; + struct Camera3StreamConfiguration { + libcamera::Size resolution; + int androidScalerCode; + bool input; + }; + + int initializeFormats(); void notifyShutter(uint32_t frameNumber, uint64_t timestamp); void notifyError(uint32_t frameNumber, camera3_stream_t *stream); std::unique_ptr getResultMetadata(int frame_number, @@ -75,6 +85,9 @@ private: std::map requestTemplates_; const camera3_callback_ops_t *callbacks_; + std::forward_list streamConfigurations_; + std::map formatsMap_; + int facing_; int orientation_; }; From patchwork Tue May 26 14:22:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3864 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8E43560E08 for ; Tue, 26 May 2020 16:19:27 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 1BE114000E; Tue, 26 May 2020 14:19:26 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 26 May 2020 16:22:34 +0200 Message-Id: <20200526142237.407557-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526142237.407557-1-jacopo@jmondi.org> References: <20200526142237.407557-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/8] android: camera_device: Calculate metadata size X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 14:19:27 -0000 As we move to have more and more dynamically generated static metadata entries, the size of the metadata buffer has to be calculated dynamically inspecting the information collected from the camera. Provide a method to perform metadata buffers size calculation and use it when generating camera static metadata. Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 42 ++++++++++++++++++++++++++++++----- src/android/camera_device.h | 2 ++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 534bfb1df1ef..6cc377820210 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -331,6 +331,40 @@ void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks) /* * Return static information for the camera. */ +std::pair CameraDevice::calculateStaticMetadataSize() +{ + /* + * \todo Keep this in sync with the actual number of entries. + * Currently: 50 entries, 647 bytes of static metadata + */ + std::pair metadataSize; + metadataSize.first = 50; + metadataSize.second = 647; + + /* + * Calculate space occupation in bytes for dynamically built metadata + * entries. + */ + + /* std::forward_list does not provide a size() method :( */ + for (const auto &entry : streamConfigurations_) { + /* Just please the compiler, otherwise entry is not used. */ + switch (entry.androidScalerCode) { + default: + break; + } + + /* + * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS + * 1 32bits integer for ANDROID_SCALER_AVAILABLE_FORMATS + * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS + */ + metadataSize.second += 52; + } + + return metadataSize; +} + const camera_metadata_t *CameraDevice::getStaticMetadata() { if (staticMetadata_) @@ -341,12 +375,8 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() * example application, but a real camera implementation will require * more. */ - - /* - * \todo Keep this in sync with the actual number of entries. - * Currently: 50 entries, 666 bytes - */ - staticMetadata_ = new CameraMetadata(50, 700); + const std::pair sizes = calculateStaticMetadataSize(); + staticMetadata_ = new CameraMetadata(sizes.first, sizes.second); if (!staticMetadata_->isValid()) { LOG(HAL, Error) << "Failed to allocate static metadata"; delete staticMetadata_; diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 95bd39f590ab..f22a6e3e6c28 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -69,6 +70,7 @@ private: }; int initializeFormats(); + std::pair calculateStaticMetadataSize(); void notifyShutter(uint32_t frameNumber, uint64_t timestamp); void notifyError(uint32_t frameNumber, camera3_stream_t *stream); std::unique_ptr getResultMetadata(int frame_number, From patchwork Tue May 26 14:22:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3865 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3168D60E08 for ; Tue, 26 May 2020 16:19:28 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id B7C684000B; Tue, 26 May 2020 14:19:27 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 26 May 2020 16:22:35 +0200 Message-Id: <20200526142237.407557-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526142237.407557-1-jacopo@jmondi.org> References: <20200526142237.407557-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 6/8] android: camera_manager: Replace hardcoded stream configuration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 14:19:28 -0000 Replace the hardcoded stream configuration map with the information collected at CameraDevice initialization time. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/android/camera_device.cpp | 38 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 6cc377820210..f8a52342abe5 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -623,23 +623,22 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxDigitalZoom, 1); - std::vector availableStreamFormats = { - ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, - ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888, - ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, - }; + std::vector availableStreamFormats; + for (const auto &entry : streamConfigurations_) + availableStreamFormats.push_back(entry.androidScalerCode); staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_FORMATS, availableStreamFormats.data(), availableStreamFormats.size()); - std::vector availableStreamConfigurations = { - ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888, 2560, 1920, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, 2560, 1920, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - }; + std::vector availableStreamConfigurations; + for (const auto &entry : streamConfigurations_) { + availableStreamConfigurations.push_back(entry.androidScalerCode); + availableStreamConfigurations.push_back(entry.resolution.width); + availableStreamConfigurations.push_back(entry.resolution.height); + availableStreamConfigurations.push_back(entry.input ? + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT : + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT); + } staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, availableStreamConfigurations.data(), availableStreamConfigurations.size()); @@ -651,11 +650,14 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() availableStallDurations.data(), availableStallDurations.size()); - std::vector minFrameDurations = { - ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333, - ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, 2560, 1920, 33333333, - ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888, 2560, 1920, 33333333, - }; + /* \todo Collect the minimum frame duration from the camera. */ + std::vector minFrameDurations; + for (const auto &entry : streamConfigurations_) { + minFrameDurations.push_back(entry.androidScalerCode); + minFrameDurations.push_back(entry.resolution.width); + minFrameDurations.push_back(entry.resolution.height); + minFrameDurations.push_back(33333333); + } staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, minFrameDurations.data(), minFrameDurations.size()); From patchwork Tue May 26 14:22:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3866 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1218461075 for ; Tue, 26 May 2020 16:19:28 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 6426C40002; Tue, 26 May 2020 14:19:28 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 26 May 2020 16:22:36 +0200 Message-Id: <20200526142237.407557-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526142237.407557-1-jacopo@jmondi.org> References: <20200526142237.407557-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 7/8] android: camera_device: Translate Android format X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 14:19:30 -0000 Translate the Android format code to the libcamera format code at stream configuration time, using the translation map built at camera device initialization time. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/android/camera_device.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index f8a52342abe5..b0f5a6a2edb5 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -904,12 +904,27 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) << ", format: " << utils::hex(stream->format); } - /* Hardcode viewfinder role, collecting sizes from the stream config. */ + /* Only one stream is supported. */ if (stream_list->num_streams != 1) { LOG(HAL, Error) << "Only one stream supported"; return -EINVAL; } + camera3_stream_t *camera3Stream = stream_list->streams[0]; + + /* Translate Android format code to libcamera format code. */ + auto it = formatsMap_.find(camera3Stream->format); + if (it == formatsMap_.end()) { + LOG(HAL, Error) << "Requested format " + << utils::hex(camera3Stream->format) + << " not supported"; + return -EINVAL; + } + uint32_t libcameraFormatCode = it->second; + /* + * Hardcode viewfinder role, replacing the generate configuration + * parameters with the Android framework requestes ones. + */ StreamRoles roles = { StreamRole::Viewfinder }; config_ = camera_->generateConfiguration(roles); if (!config_ || config_->empty()) { @@ -917,17 +932,10 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) return -EINVAL; } - /* Only one stream is supported. */ - camera3_stream_t *camera3Stream = stream_list->streams[0]; StreamConfiguration *streamConfiguration = &config_->at(0); streamConfiguration->size.width = camera3Stream->width; streamConfiguration->size.height = camera3Stream->height; - - /* - * \todo We'll need to translate from Android defined pixel format codes - * to the libcamera image format codes. For now, do not change the - * format returned from Camera::generateConfiguration(). - */ + streamConfiguration->pixelFormat = PixelFormat(libcameraFormatCode); switch (config_->validate()) { case CameraConfiguration::Valid: From patchwork Tue May 26 14:22:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 3867 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 74727610D5 for ; Tue, 26 May 2020 16:19:29 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from localhost.localdomain (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 05CFE40004; Tue, 26 May 2020 14:19:28 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 26 May 2020 16:22:37 +0200 Message-Id: <20200526142237.407557-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200526142237.407557-1-jacopo@jmondi.org> References: <20200526142237.407557-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 8/8] libcamera: camera: Drop full stop from \return X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 14:19:30 -0000 We don't use full stops at the end of \return directives in Doxygen documentation. Drop it. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/camera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index eac769a43964..dfc3d193bd2b 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -664,7 +664,7 @@ const ControlList &Camera::properties() * * \context This function is \threadsafe. * - * \return An array of all the camera's streams. + * \return An array of all the camera's streams */ const std::set &Camera::streams() const {