From patchwork Thu Apr 22 09:40:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 12074 X-Patchwork-Delegate: paul.elder@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id EEF62BDB17 for ; Thu, 22 Apr 2021 09:41:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 890E76886A; Thu, 22 Apr 2021 11:41:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ol8fDO0i"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BA3C06886A for ; Thu, 22 Apr 2021 11:41:25 +0200 (CEST) Received: from pyrite.rasen.tech (unknown [IPv6:2400:4051:61:600:2c71:1b79:d06d:5032]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6B6B73EE; Thu, 22 Apr 2021 11:41:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1619084485; bh=JeADEKri/fxivXxPB3eygIXKGKrdC+F0/teuLg1JhNQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ol8fDO0ifJRW4BhBD/LlwueBPOGbdj4cJIVHmOkFhPefvE3Yr3mZNAzSW54kyQpbs zrEZcwHLgcwcyLK3rrwM0otqMzp5P9Cin/g4YZRGf9om+2ksF1oncmq/mwHhrApcmW sqTo20/aoFxFXyCa6Nhj2PHzAjLLohJQvO8h1YxI= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Thu, 22 Apr 2021 18:40:57 +0900 Message-Id: <20210422094102.371772-8-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210422094102.371772-1-paul.elder@ideasonboard.com> References: <20210422094102.371772-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 07/12] android: camera_device: Set result metadata for FULL requirements 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Set the result metadata to satisfy FULL hardware level requirements. Also add the new result metadata tags to the static metadata. This fixes many tests under: - android.hardware.camera2.cts.CaptureRequestTest - testAeModeAndLock - testAntiBandingModes - testAwbModeAndLock - testBlackLevelLock - testEdgeModeControlFastFps - testNoiseReductionModeControlFastFps - testToneMapControl - android.hardware.camera2.cts.CaptureResultTest - testCameraCaptureResultAllKeys - android.hardware.camera2.cts.ImageReaderTest - testDiscardFreeBuffers - testFlexibleYuv - testJpeg - testLongProcessingRepeatingFlexibleYuv - testRepeatingJpeg - android.hardware.camera2.cts.StaticMetadataTest - testCapabilities Signed-off-by: Paul Elder --- Again, not sure if the entries in the results key list needs to be added to the static metadata allocation size. --- src/android/camera_device.cpp | 127 ++++++++++++++++++++++++++++++---- src/android/camera_device.h | 2 + 2 files changed, 117 insertions(+), 12 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index c9d4afc3..99c67555 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -402,7 +402,7 @@ CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor( CameraDevice::CameraDevice(unsigned int id, std::shared_ptr camera) : id_(id), running_(false), camera_(std::move(camera)), - facing_(CAMERA_FACING_FRONT), orientation_(0) + facing_(CAMERA_FACING_FRONT), orientation_(0), lastTimestamp_(0) { camera_->requestCompleted.connect(this, &CameraDevice::requestComplete); @@ -776,10 +776,10 @@ std::tuple CameraDevice::calculateStaticMetadataSize() { /* * \todo Keep this in sync with the actual number of entries. - * Currently: 63 entries, 990 bytes of static metadata + * Currently: 63 entries, 1014 bytes of static metadata */ uint32_t numEntries = 63; - uint32_t byteSize = 990; + uint32_t byteSize = 1014; // do i need to add for entries in the available keys? // +1, +4 for EDGE_AVAILABLE_EDGE_MODES @@ -787,6 +787,7 @@ std::tuple CameraDevice::calculateStaticMetadataSize() // +1, +4 for BLACK_LEVEL_PATTERN // +1, +4 for TONEMAP_AVAILABLE_TONE_MAP_MODES // +1, +4 for TONEMAP_MAX_CURVE_POINTS + // +4x9 = 36 for the new result tags // +36 for new request keys @@ -1419,8 +1420,9 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() /* * required for FULL * \todo get from camera (camCapabilities[camId]->tonemapCurvePoints?) + * at least 64 */ - int32_t tonemapCurvePoints = 0; + int32_t tonemapCurvePoints = 64; staticMetadata_->addEntry(ANDROID_TONEMAP_MAX_CURVE_POINTS, &tonemapCurvePoints, 1); @@ -1526,6 +1528,9 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() ANDROID_SHADING_MODE, ANDROID_STATISTICS_FACE_DETECT_MODE, ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, + ANDROID_TONEMAP_CURVE_BLUE, + ANDROID_TONEMAP_CURVE_GREEN, + ANDROID_TONEMAP_CURVE_RED, ANDROID_TONEMAP_MODE, }; staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, @@ -1533,6 +1538,7 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() availableRequestKeys.size()); std::vector availableResultKeys = { + ANDROID_BLACK_LEVEL_LOCK, ANDROID_COLOR_CORRECTION_ABERRATION_MODE, ANDROID_CONTROL_AE_ANTIBANDING_MODE, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, @@ -1552,8 +1558,10 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() ANDROID_CONTROL_MODE, ANDROID_CONTROL_SCENE_MODE, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, + ANDROID_EDGE_MODE, ANDROID_FLASH_MODE, ANDROID_FLASH_STATE, + ANDROID_HOT_PIXEL_MODE, ANDROID_JPEG_GPS_COORDINATES, ANDROID_JPEG_GPS_PROCESSING_METHOD, ANDROID_JPEG_GPS_TIMESTAMP, @@ -1563,20 +1571,30 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() ANDROID_JPEG_THUMBNAIL_QUALITY, ANDROID_JPEG_THUMBNAIL_SIZE, ANDROID_LENS_APERTURE, + ANDROID_LENS_FILTER_DENSITY, ANDROID_LENS_FOCAL_LENGTH, + ANDROID_LENS_FOCUS_DISTANCE, + ANDROID_LENS_FOCUS_RANGE, // undocumented ANDROID_LENS_OPTICAL_STABILIZATION_MODE, ANDROID_LENS_STATE, ANDROID_NOISE_REDUCTION_MODE, ANDROID_REQUEST_PIPELINE_DEPTH, ANDROID_SCALER_CROP_REGION, ANDROID_SENSOR_EXPOSURE_TIME, + ANDROID_SENSOR_FRAME_DURATION, ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, + ANDROID_SENSOR_SENSITIVITY, ANDROID_SENSOR_TEST_PATTERN_MODE, ANDROID_SENSOR_TIMESTAMP, + ANDROID_SHADING_MODE, ANDROID_STATISTICS_FACE_DETECT_MODE, ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, ANDROID_STATISTICS_SCENE_FLICKER, + ANDROID_TONEMAP_CURVE_BLUE, + ANDROID_TONEMAP_CURVE_GREEN, + ANDROID_TONEMAP_CURVE_RED, + ANDROID_TONEMAP_MODE, }; staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, availableResultKeys.data(), @@ -2277,6 +2295,10 @@ void CameraDevice::requestComplete(Request *request) resultMetadata = getResultMetadata(descriptor); + const ControlList &metadata = descriptor->request_->metadata(); + if (metadata.contains(controls::SensorTimestamp)) + lastTimestamp_ = metadata.get(controls::SensorTimestamp); + /* Handle any JPEG compression. */ for (camera3_stream_buffer_t &buffer : descriptor.buffers_) { CameraStream *cameraStream = @@ -2416,7 +2438,7 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons * Total bytes for JPEG metadata: 82 */ std::unique_ptr resultMetadata = - std::make_unique(44, 166); + std::make_unique(57, 303); if (!resultMetadata->isValid()) { LOG(HAL, Error) << "Failed to allocate result metadata"; return nullptr; @@ -2428,6 +2450,11 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons * from libcamera::Request::metadata. */ + /* FULL */ + found = settings.getEntry(ANDROID_BLACK_LEVEL_LOCK, &entry); + bool valueBool = found ? *entry.data.u8 : false; + resultMetadata->addEntry(ANDROID_BLACK_LEVEL_LOCK, &valueBool, 1); + uint8_t value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF; resultMetadata->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &value, 1); @@ -2439,8 +2466,11 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons resultMetadata->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &value32, 1); + /* \todo apply this */ value = ANDROID_CONTROL_AE_LOCK_OFF; - resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &value, 1); + found = settings.getEntry(ANDROID_CONTROL_AE_LOCK, &entry); + resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, + found ? entry.data.u8 : &value, 1); value = ANDROID_CONTROL_AE_MODE_ON; resultMetadata->addEntry(ANDROID_CONTROL_AE_MODE, &value, 1); @@ -2472,12 +2502,16 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons resultMetadata->addEntry(ANDROID_CONTROL_AF_TRIGGER, &value, 1); value = ANDROID_CONTROL_AWB_MODE_AUTO; - resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, &value, 1); + found = settings.getEntry(ANDROID_CONTROL_AWB_MODE, &entry); + resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, + found ? entry.data.u8 : &value, 1); - value = ANDROID_CONTROL_AWB_LOCK_OFF; + found = settings.getEntry(ANDROID_CONTROL_AWB_LOCK, &entry); + value = found ? *entry.data.u8 : ANDROID_CONTROL_AWB_LOCK_OFF; resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &value, 1); - value = ANDROID_CONTROL_AWB_STATE_CONVERGED; + value = value ? ANDROID_CONTROL_AWB_STATE_LOCKED : + ANDROID_CONTROL_AWB_STATE_CONVERGED; resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &value, 1); value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; @@ -2495,18 +2529,37 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; resultMetadata->addEntry(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &value, 1); + found = settings.getEntry(ANDROID_EDGE_MODE, &entry); + value = found ? *entry.data.u8 : ANDROID_EDGE_MODE_OFF; + resultMetadata->addEntry(ANDROID_EDGE_MODE, &value, 1); + value = ANDROID_FLASH_MODE_OFF; resultMetadata->addEntry(ANDROID_FLASH_MODE, &value, 1); value = ANDROID_FLASH_STATE_UNAVAILABLE; resultMetadata->addEntry(ANDROID_FLASH_STATE, &value, 1); + value = ANDROID_HOT_PIXEL_MODE_OFF; + resultMetadata->addEntry(ANDROID_HOT_PIXEL_MODE, &value, 1); + if (settings.getEntry(ANDROID_LENS_APERTURE, &entry)) resultMetadata->addEntry(ANDROID_LENS_APERTURE, entry.data.f, 1); + float filterDensity = 0.0f; + resultMetadata->addEntry(ANDROID_LENS_FILTER_DENSITY, + &filterDensity, 1); + float focal_length = 1.0; resultMetadata->addEntry(ANDROID_LENS_FOCAL_LENGTH, &focal_length, 1); + float focusDistance = 0.0f; + resultMetadata->addEntry(ANDROID_LENS_FOCUS_DISTANCE, + &focusDistance, 1); + + /* there's no documentation on this */ + float focusRange[] = { 0.0f, 1.0f }; + resultMetadata->addEntry(ANDROID_LENS_FOCUS_RANGE, &focusRange, 2); + value = ANDROID_LENS_STATE_STATIONARY; resultMetadata->addEntry(ANDROID_LENS_STATE, &value, 1); @@ -2518,6 +2571,11 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons resultMetadata->addEntry(ANDROID_SENSOR_TEST_PATTERN_MODE, &value32, 1); + + /* \todo get this from request? and set it. handle map mode too */ + value = ANDROID_SHADING_MODE_OFF; + resultMetadata->addEntry(ANDROID_SHADING_MODE, &value, 1); + value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, &value, 1); @@ -2534,14 +2592,48 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER, &value, 1); + /* \todo handle this */ + found = settings.getEntry(ANDROID_TONEMAP_MODE, &entry); + value = found ? *entry.data.u8 : ANDROID_TONEMAP_MODE_FAST; + resultMetadata->addEntry(ANDROID_TONEMAP_MODE, &value, 1); + value = ANDROID_NOISE_REDUCTION_MODE_OFF; - resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, &value, 1); + found = settings.getEntry(ANDROID_NOISE_REDUCTION_MODE, &entry); + resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, + found ? entry.data.u8 : &value, 1); /* 33.3 msec */ const int64_t rolling_shutter_skew = 33300000; resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, &rolling_shutter_skew, 1); + /* + * CTS doesn't actually check if this is equal to the requested + * tonemap, so just set a linear tonemap + * it's in [in, out] [in, out] format + */ + std::vector tonemap = { + 0.0, 0.0, + 1.0, 1.0, + }; + resultMetadata->addEntry(ANDROID_TONEMAP_CURVE_BLUE, + tonemap.data(), tonemap.size()); + resultMetadata->addEntry(ANDROID_TONEMAP_CURVE_GREEN, + tonemap.data(), tonemap.size()); + resultMetadata->addEntry(ANDROID_TONEMAP_CURVE_RED, + tonemap.data(), tonemap.size()); + + /* + * \todo get the tonemap gamma and tonemap preset curve from request + * and copy to result + */ + + /* \todo get this from camera */ + value32 = 32; + found = settings.getEntry(ANDROID_SENSOR_SENSITIVITY, &entry); + resultMetadata->addEntry(ANDROID_SENSOR_SENSITIVITY, + found ? entry.data.i32 : &value32, 1); + /* Add metadata tags reported by libcamera. */ if (metadata.contains(controls::draft::PipelineDepth)) { uint8_t pipeline_depth = @@ -2550,15 +2642,26 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons &pipeline_depth, 1); } - if (metadata.contains(controls::ExposureTime)) { + found = settings.getEntry(ANDROID_SENSOR_EXPOSURE_TIME, &entry); + if (found || metadata.contains(controls::ExposureTime)) { int64_t exposure = metadata.get(controls::ExposureTime) * 1000ULL; resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME, - &exposure, 1); + found ? entry.data.i64 : &exposure, 1); } if (metadata.contains(controls::SensorTimestamp)) { int64_t timestamp = metadata.get(controls::SensorTimestamp); resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, ×tamp, 1); + + int64_t frameDuration = timestamp - lastTimestamp_; + /* + * frame duration should be at last as long as the requested + * exposure time, hardcode it for now + */ + if (found && frameDuration < *entry.data.i64) + frameDuration = *entry.data.i64; + resultMetadata->addEntry(ANDROID_SENSOR_FRAME_DURATION, + &frameDuration, 1); } if (metadata.contains(controls::ScalerCrop)) { diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 8edbcdfd..fcd57fcd 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -139,6 +139,8 @@ private: unsigned int maxJpegBufferSize_; + int64_t lastTimestamp_; + CameraMetadata lastSettings_; };