[{"id":2623,"web_url":"https://patchwork.libcamera.org/comment/2623/","msgid":"<20190905211717.GR5035@pendragon.ideasonboard.com>","date":"2019-09-05T21:17:17","subject":"Re: [libcamera-devel] [PATCH v7 7/9] android: camera_device: Use\n\tthe new CameraMetadata helper class","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Thu, Sep 05, 2019 at 11:09:38PM +0200, Jacopo Mondi wrote:\n> From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> Simplify the implementation of metadata handling in the CameraDevice\n> class by using the new CameraMetadata helper class.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n>  src/android/camera_device.cpp | 535 ++++++++++++++--------------------\n>  src/android/camera_device.h   |  15 +-\n>  2 files changed, 221 insertions(+), 329 deletions(-)\n> \n> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\n> index 5f8d19b9ef3d..8d42b13b60b8 100644\n> --- a/src/android/camera_device.cpp\n> +++ b/src/android/camera_device.cpp\n> @@ -7,10 +7,10 @@\n>  \n>  #include \"camera_device.h\"\n>  \n> -#include <system/camera_metadata.h>\n> -\n>  #include \"log.h\"\n> +#include \"utils.h\"\n>  \n> +#include \"camera_metadata.h\"\n>  #include \"thread_rpc.h\"\n>  \n>  using namespace libcamera;\n> @@ -59,12 +59,10 @@ CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camer\n>  CameraDevice::~CameraDevice()\n>  {\n>  \tif (staticMetadata_)\n> -\t\tfree_camera_metadata(staticMetadata_);\n> -\tstaticMetadata_ = nullptr;\n> +\t\tdelete staticMetadata_;\n>  \n>  \tif (requestTemplate_)\n> -\t\tfree_camera_metadata(requestTemplate_);\n> -\trequestTemplate_ = nullptr;\n> +\t\tdelete requestTemplate_;\n>  }\n>  \n>  /*\n> @@ -117,10 +115,8 @@ void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)\n>   */\n>  camera_metadata_t *CameraDevice::getStaticMetadata()\n>  {\n> -\tint ret;\n> -\n>  \tif (staticMetadata_)\n> -\t\treturn staticMetadata_;\n> +\t\treturn staticMetadata_->get();\n>  \n>  \t/*\n>  \t * The here reported metadata are enough to implement a basic capture\n> @@ -132,16 +128,21 @@ camera_metadata_t *CameraDevice::getStaticMetadata()\n>  \t * \\todo Keep this in sync with the actual number of entries.\n>  \t * Currently: 46 entries, 390 bytes\n\nThere are 47 entries.\n\n>  \t */\n> -\tstaticMetadata_ = allocate_camera_metadata(50, 500);\n> +\tstaticMetadata_ = new CameraMetadata(50, 500);\n> +\tif (!staticMetadata_->isValid()) {\n> +\t\tLOG(HAL, Error) << \"Failed to allocate static metadata\";\n> +\t\tdelete staticMetadata_;\n> +\t\tstaticMetadata_ = nullptr;\n> +\t\treturn nullptr;\n> +\t}\n>  \n>  \t/* Color correction static metadata. */\n>  \tstd::vector<uint8_t> aberrationModes = {\n>  \t\tANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,\n> -\t\t\taberrationModes.data(), aberrationModes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,\n> +\t\t\t\t  aberrationModes.data(),\n> +\t\t\t\t  aberrationModes.size());\n>  \n>  \t/* Control static metadata. */\n>  \tstd::vector<uint8_t> aeAvailableAntiBandingModes = {\n> @@ -150,294 +151,228 @@ camera_metadata_t *CameraDevice::getStaticMetadata()\n>  \t\tANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,\n>  \t\tANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,\n> -\t\t\taeAvailableAntiBandingModes.data(),\n> -\t\t\taeAvailableAntiBandingModes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,\n> +\t\t\t\t  aeAvailableAntiBandingModes.data(),\n> +\t\t\t\t  aeAvailableAntiBandingModes.size());\n>  \n>  \tstd::vector<uint8_t> aeAvailableModes = {\n>  \t\tANDROID_CONTROL_AE_MODE_ON,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AE_AVAILABLE_MODES,\n> -\t\t\taeAvailableModes.data(), aeAvailableModes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,\n> +\t\t\t\t  aeAvailableModes.data(),\n> +\t\t\t\t  aeAvailableModes.size());\n>  \n>  \tstd::vector<int32_t> availableAeFpsTarget = {\n>  \t\t15, 30,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,\n> -\t\t\tavailableAeFpsTarget.data(),\n> -\t\t\tavailableAeFpsTarget.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,\n> +\t\t\t\t  availableAeFpsTarget.data(),\n> +\t\t\t\t  availableAeFpsTarget.size());\n>  \n>  \tstd::vector<int32_t> aeCompensationRange = {\n>  \t\t0, 0,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AE_COMPENSATION_RANGE,\n> -\t\t\taeCompensationRange.data(),\n> -\t\t\taeCompensationRange.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,\n> +\t\t\t\t  aeCompensationRange.data(),\n> +\t\t\t\t  aeCompensationRange.size());\n>  \n>  \tconst camera_metadata_rational_t aeCompensationStep[] = {\n>  \t\t{ 0, 1 }\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AE_COMPENSATION_STEP,\n> -\t\t\taeCompensationStep, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,\n> +\t\t\t\t  aeCompensationStep, 1);\n>  \n>  \tstd::vector<uint8_t> availableAfModes = {\n>  \t\tANDROID_CONTROL_AF_MODE_OFF,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AF_AVAILABLE_MODES,\n> -\t\t\tavailableAfModes.data(), availableAfModes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,\n> +\t\t\t\t  availableAfModes.data(),\n> +\t\t\t\t  availableAfModes.size());\n>  \n>  \tstd::vector<uint8_t> availableEffects = {\n>  \t\tANDROID_CONTROL_EFFECT_MODE_OFF,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AVAILABLE_EFFECTS,\n> -\t\t\tavailableEffects.data(), availableEffects.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,\n> +\t\t\t\t  availableEffects.data(),\n> +\t\t\t\t  availableEffects.size());\n>  \n>  \tstd::vector<uint8_t> availableSceneModes = {\n>  \t\tANDROID_CONTROL_SCENE_MODE_DISABLED,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AVAILABLE_SCENE_MODES,\n> -\t\t\tavailableSceneModes.data(), availableSceneModes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,\n> +\t\t\t\t  availableSceneModes.data(),\n> +\t\t\t\t  availableSceneModes.size());\n>  \n>  \tstd::vector<uint8_t> availableStabilizationModes = {\n>  \t\tANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,\n> -\t\t\tavailableStabilizationModes.data(),\n> -\t\t\tavailableStabilizationModes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,\n> +\t\t\t\t  availableStabilizationModes.data(),\n> +\t\t\t\t  availableStabilizationModes.size());\n>  \n>  \tstd::vector<uint8_t> availableAwbModes = {\n>  \t\tANDROID_CONTROL_AWB_MODE_OFF,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AWB_AVAILABLE_MODES,\n> -\t\t\tavailableAwbModes.data(), availableAwbModes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,\n> +\t\t\t\t  availableAwbModes.data(),\n> +\t\t\t\t  availableAwbModes.size());\n>  \n>  \tstd::vector<int32_t> availableMaxRegions = {\n>  \t\t0, 0, 0,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_MAX_REGIONS,\n> -\t\t\tavailableMaxRegions.data(), availableMaxRegions.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,\n> +\t\t\t\t  availableMaxRegions.data(),\n> +\t\t\t\t  availableMaxRegions.size());\n>  \n>  \tstd::vector<uint8_t> sceneModesOverride = {\n>  \t\tANDROID_CONTROL_AE_MODE_ON,\n>  \t\tANDROID_CONTROL_AWB_MODE_AUTO,\n>  \t\tANDROID_CONTROL_AF_MODE_AUTO,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_SCENE_MODE_OVERRIDES,\n> -\t\t\tsceneModesOverride.data(), sceneModesOverride.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,\n> +\t\t\t\t  sceneModesOverride.data(),\n> +\t\t\t\t  sceneModesOverride.size());\n>  \n>  \tuint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AE_LOCK_AVAILABLE,\n> -\t\t\t&aeLockAvailable, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,\n> +\t\t\t\t  &aeLockAvailable, 1);\n>  \n>  \tuint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AWB_LOCK_AVAILABLE,\n> -\t\t\t&awbLockAvailable, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,\n> +\t\t\t\t  &awbLockAvailable, 1);\n>  \n>  \tchar availableControlModes = ANDROID_CONTROL_MODE_AUTO;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_CONTROL_AVAILABLE_MODES,\n> -\t\t\t&availableControlModes, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,\n> +\t\t\t\t  &availableControlModes, 1);\n>  \n>  \t/* JPEG static metadata. */\n>  \tstd::vector<int32_t> availableThumbnailSizes = {\n>  \t\t0, 0,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,\n> -\t\t\tavailableThumbnailSizes.data(),\n> -\t\t\tavailableThumbnailSizes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,\n> +\t\t\t\t  availableThumbnailSizes.data(),\n> +\t\t\t\t  availableThumbnailSizes.size());\n>  \n>  \t/* Sensor static metadata. */\n>  \tint32_t pixelArraySize[] = {\n>  \t\t2592, 1944,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,\n> -\t\t\t\t&pixelArraySize, 2);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,\n> +\t\t\t\t  &pixelArraySize, 2);\n>  \n>  \tint32_t sensorSizes[] = {\n>  \t\t0, 0, 2560, 1920,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,\n> -\t\t\t\t&sensorSizes, 4);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,\n> +\t\t\t\t  &sensorSizes, 4);\n>  \n>  \tint32_t sensitivityRange[] = {\n>  \t\t32, 2400,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_SENSOR_INFO_SENSITIVITY_RANGE,\n> -\t\t\t\t&sensitivityRange, 2);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,\n> +\t\t\t\t  &sensitivityRange, 2);\n>  \n>  \tuint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,\n> -\t\t\t\t&filterArr, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,\n> +\t\t\t\t  &filterArr, 1);\n>  \n>  \tint64_t exposureTimeRange[] = {\n>  \t\t100000, 200000000,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,\n> -\t\t\t\t&exposureTimeRange, 2);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,\n> +\t\t\t\t  &exposureTimeRange, 2);\n>  \n>  \tint32_t orientation = 0;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_SENSOR_ORIENTATION,\n> -\t\t\t\t&orientation, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION,\n> +\t\t\t\t  &orientation, 1);\n>  \n>  \tstd::vector<int32_t> testPatterModes = {\n>  \t\tANDROID_SENSOR_TEST_PATTERN_MODE_OFF,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,\n> -\t\t\t\ttestPatterModes.data(), testPatterModes.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,\n> +\t\t\t\t  testPatterModes.data(),\n> +\t\t\t\t  testPatterModes.size());\n>  \n>  \tstd::vector<float> physicalSize = {\n>  \t\t2592, 1944,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_SENSOR_INFO_PHYSICAL_SIZE,\n> -\t\t\t\tphysicalSize.data(), physicalSize.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,\n> +\t\t\t\t  physicalSize.data(),\n> +\t\t\t\t  physicalSize.size());\n>  \n>  \tuint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,\n> -\t\t\t&timestampSource, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,\n> +\t\t\t\t  &timestampSource, 1);\n>  \n>  \t/* Statistics static metadata. */\n>  \tuint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,\n> -\t\t\t&faceDetectMode, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,\n> +\t\t\t\t  &faceDetectMode, 1);\n>  \n>  \tint32_t maxFaceCount = 0;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_STATISTICS_INFO_MAX_FACE_COUNT,\n> -\t\t\t&maxFaceCount, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,\n> +\t\t\t\t  &maxFaceCount, 1);\n>  \n>  \t/* Sync static metadata. */\n>  \tint32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);\n>  \n>  \t/* Flash static metadata. */\n>  \tchar flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_FLASH_INFO_AVAILABLE,\n> -\t\t\t&flashAvailable, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,\n> +\t\t\t\t  &flashAvailable, 1);\n>  \n>  \t/* Lens static metadata. */\n>  \tstd::vector<float> lensApertures = {\n>  \t\t2.53 / 100,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_LENS_INFO_AVAILABLE_APERTURES,\n> -\t\t\t\tlensApertures.data(), lensApertures.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,\n> +\t\t\t\t  lensApertures.data(),\n> +\t\t\t\t  lensApertures.size());\n>  \n>  \tuint8_t lensFacing = ANDROID_LENS_FACING_FRONT;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_LENS_FACING, &lensFacing, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);\n>  \n>  \tstd::vector<float> lensFocalLenghts = {\n>  \t\t1,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,\n> -\t\t\t\tlensFocalLenghts.data(),\n> -\t\t\t\tlensFocalLenghts.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,\n> +\t\t\t\t  lensFocalLenghts.data(),\n> +\t\t\t\t  lensFocalLenghts.size());\n>  \n>  \tstd::vector<uint8_t> opticalStabilizations = {\n>  \t\tANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,\n> -\t\t\t\topticalStabilizations.data(),\n> -\t\t\t\topticalStabilizations.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,\n> +\t\t\t\t  opticalStabilizations.data(),\n> +\t\t\t\t  opticalStabilizations.size());\n>  \n>  \tfloat hypeFocalDistance = 0;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,\n> -\t\t\t\t&hypeFocalDistance, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,\n> +\t\t\t\t  &hypeFocalDistance, 1);\n>  \n>  \tfloat minFocusDistance = 0;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,\n> -\t\t\t\t&minFocusDistance, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,\n> +\t\t\t\t  &minFocusDistance, 1);\n>  \n>  \t/* Noise reduction modes. */\n>  \tuint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\t\tANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,\n> -\t\t\t\t&noiseReductionModes, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,\n> +\t\t\t\t  &noiseReductionModes, 1);\n>  \n>  \t/* Scaler static metadata. */\n>  \tfloat maxDigitalZoom = 1;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,\n> -\t\t\t&maxDigitalZoom, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,\n> +\t\t\t\t  &maxDigitalZoom, 1);\n>  \n>  \tstd::vector<uint32_t> availableStreamFormats = {\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_BLOB,\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_SCALER_AVAILABLE_FORMATS,\n> -\t\t\tavailableStreamFormats.data(),\n> -\t\t\tavailableStreamFormats.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_FORMATS,\n> +\t\t\t\t  availableStreamFormats.data(),\n> +\t\t\t\t  availableStreamFormats.size());\n>  \n>  \tstd::vector<uint32_t> availableStreamConfigurations = {\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920,\n> @@ -447,65 +382,58 @@ camera_metadata_t *CameraDevice::getStaticMetadata()\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, 2560, 1920,\n>  \t\tANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,\n> -\t\t\tavailableStreamConfigurations.data(),\n> -\t\t\tavailableStreamConfigurations.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,\n> +\t\t\t\t  availableStreamConfigurations.data(),\n> +\t\t\t\t  availableStreamConfigurations.size());\n>  \n>  \tstd::vector<int64_t> availableStallDurations = {\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_SCALER_AVAILABLE_STALL_DURATIONS,\n> -\t\t\tavailableStallDurations.data(),\n> -\t\t\tavailableStallDurations.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,\n> +\t\t\t\t  availableStallDurations.data(),\n> +\t\t\t\t  availableStallDurations.size());\n>  \n>  \tstd::vector<int64_t> minFrameDurations = {\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, 2560, 1920, 33333333,\n>  \t\tANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888, 2560, 1920, 33333333,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,\n> -\t\t\tminFrameDurations.data(), minFrameDurations.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,\n> +\t\t\t\t  minFrameDurations.data(),\n> +\t\t\t\t  minFrameDurations.size());\n>  \n>  \tuint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);\n>  \n>  \t/* Info static metadata. */\n>  \tuint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,\n> -\t\t\t&supportedHWLevel, 1);\n> +\tstaticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,\n> +\t\t\t\t  &supportedHWLevel, 1);\n>  \n>  \t/* Request static metadata. */\n>  \tint32_t partialResultCount = 1;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_REQUEST_PARTIAL_RESULT_COUNT,\n> -\t\t\t&partialResultCount, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,\n> +\t\t\t\t  &partialResultCount, 1);\n>  \n>  \tuint8_t maxPipelineDepth = 2;\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_REQUEST_PIPELINE_MAX_DEPTH,\n> -\t\t\t&maxPipelineDepth, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,\n> +\t\t\t\t  &maxPipelineDepth, 1);\n>  \n>  \tstd::vector<uint8_t> availableCapabilities = {\n>  \t\tANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,\n>  \t};\n> -\tret = add_camera_metadata_entry(staticMetadata_,\n> -\t\t\tANDROID_REQUEST_AVAILABLE_CAPABILITIES,\n> -\t\t\tavailableCapabilities.data(),\n> -\t\t\tavailableCapabilities.size());\n> -\tMETADATA_ASSERT(ret);\n> +\tstaticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,\n> +\t\t\t\t  availableCapabilities.data(),\n> +\t\t\t\t  availableCapabilities.size());\n> +\n> +\tif (!staticMetadata_->isValid()) {\n> +\t\tLOG(HAL, Error) << \"Failed to construct static metadata\";\n> +\t\tdelete staticMetadata_;\n> +\t\tstaticMetadata_ = nullptr;\n> +\t\treturn nullptr;\n> +\t}\n>  \n> -\treturn staticMetadata_;\n> +\treturn staticMetadata_->get();\n>  }\n>  \n>  /*\n> @@ -513,8 +441,6 @@ camera_metadata_t *CameraDevice::getStaticMetadata()\n>   */\n>  const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)\n>  {\n> -\tint ret;\n> -\n>  \t/*\n>  \t * \\todo Inspect type and pick the right metadata pack.\n>  \t * As of now just use a single one for all templates.\n> @@ -545,89 +471,75 @@ const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)\n>  \t}\n>  \n>  \tif (requestTemplate_)\n> -\t\treturn requestTemplate_;\n> +\t\treturn requestTemplate_->get();\n>  \n>  \t/*\n>  \t * \\todo Keep this in sync with the actual number of entries.\n>  \t * Currently: 12 entries, 15 bytes\n>  \t */\n> -\trequestTemplate_ = allocate_camera_metadata(15, 20);\n> +\trequestTemplate_ = new CameraMetadata(15, 20);\n>  \tif (!requestTemplate_) {\n>  \t\tLOG(HAL, Error) << \"Failed to allocate template metadata\";\n> +\t\tdelete requestTemplate_;\n> +\t\trequestTemplate_ = nullptr;\n>  \t\treturn nullptr;\n>  \t}\n>  \n>  \tuint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_CONTROL_AE_MODE,\n> -\t\t\t&aeMode, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_CONTROL_AE_MODE,\n> +\t\t\t\t   &aeMode, 1);\n>  \n>  \tint32_t aeExposureCompensation = 0;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,\n> -\t\t\t&aeExposureCompensation, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,\n> +\t\t\t\t   &aeExposureCompensation, 1);\n>  \n>  \tuint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,\n> -\t\t\t&aePrecaptureTrigger, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,\n> +\t\t\t\t   &aePrecaptureTrigger, 1);\n>  \n>  \tuint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_CONTROL_AE_LOCK,\n> -\t\t\t&aeLock, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_CONTROL_AE_LOCK,\n> +\t\t\t\t   &aeLock, 1);\n>  \n>  \tuint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_CONTROL_AF_TRIGGER,\n> -\t\t\t&afTrigger, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_CONTROL_AF_TRIGGER,\n> +\t\t\t\t   &afTrigger, 1);\n>  \n>  \tuint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_CONTROL_AWB_MODE,\n> -\t\t\t&awbMode, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_CONTROL_AWB_MODE,\n> +\t\t\t\t   &awbMode, 1);\n>  \n>  \tuint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_CONTROL_AWB_LOCK,\n> -\t\t\t&awbLock, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_CONTROL_AWB_LOCK,\n> +\t\t\t\t   &awbLock, 1);\n>  \n>  \tuint8_t flashMode = ANDROID_FLASH_MODE_OFF;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_FLASH_MODE,\n> -\t\t\t&flashMode, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_FLASH_MODE,\n> +\t\t\t\t   &flashMode, 1);\n>  \n>  \tuint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_STATISTICS_FACE_DETECT_MODE,\n> -\t\t\t&faceDetectMode, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,\n> +\t\t\t\t   &faceDetectMode, 1);\n>  \n>  \tuint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_NOISE_REDUCTION_MODE, &noiseReduction, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_NOISE_REDUCTION_MODE,\n> +\t\t\t\t   &noiseReduction, 1);\n>  \n>  \tuint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;\n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_COLOR_CORRECTION_ABERRATION_MODE,\n> -\t\t\t&aberrationMode, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,\n> +\t\t\t\t   &aberrationMode, 1);\n>  \n> -\tret = add_camera_metadata_entry(requestTemplate_,\n> -\t\t\tANDROID_CONTROL_CAPTURE_INTENT,\n> -\t\t\t&captureIntent, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\trequestTemplate_->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,\n> +\t\t\t\t   &captureIntent, 1);\n>  \n> -\treturn requestTemplate_;\n> +\tif (!requestTemplate_->isValid()) {\n> +\t\tLOG(HAL, Error) << \"Failed to construct request template\";\n> +\t\tdelete requestTemplate_;\n> +\t\trequestTemplate_ = nullptr;\n> +\t\treturn nullptr;\n> +\t}\n> +\n> +\treturn requestTemplate_->get();\n>  }\n>  \n>  /*\n> @@ -799,7 +711,7 @@ void CameraDevice::requestComplete(Request *request,\n>  {\n>  \tBuffer *libcameraBuffer = buffers.begin()->second;\n>  \tcamera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;\n> -\tcamera_metadata_t *resultMetadata = nullptr;\n> +\tstd::unique_ptr<CameraMetadata> resultMetadata;\n>  \n>  \tif (request->status() != Request::RequestComplete) {\n>  \t\tLOG(HAL, Error) << \"Request not succesfully completed: \"\n> @@ -826,27 +738,30 @@ void CameraDevice::requestComplete(Request *request,\n>  \tcaptureResult.output_buffers =\n>  \t\tconst_cast<const camera3_stream_buffer_t *>(descriptor->buffers);\n>  \n> -\tif (status == CAMERA3_BUFFER_STATUS_ERROR) {\n> -\t\t/* \\todo Improve error handling. */\n> -\t\tnotifyError(descriptor->frameNumber,\n> -\t\t\t    descriptor->buffers[0].stream);\n> -\t} else {\n> +\tif (status == CAMERA3_BUFFER_STATUS_OK) {\n>  \t\tnotifyShutter(descriptor->frameNumber,\n>  \t\t\t      libcameraBuffer->timestamp());\n>  \n>  \t\tcaptureResult.partial_result = 1;\n>  \t\tresultMetadata = getResultMetadata(descriptor->frameNumber,\n>  \t\t\t\t\t\t   libcameraBuffer->timestamp());\n> -\t\tcaptureResult.result = resultMetadata;\n> +\t\tcaptureResult.result = resultMetadata->get();\n> +\t}\n> +\n> +\tif (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {\n> +\t\t/* \\todo Improve error handling. In case we notify an error\n> +\t\t * because the metadata generation fails, a shutter event has\n> +\t\t * already been notified for this frame number before the erro\n\ns/erro/error/\n\n> +\t\t * is here signaled. Make shure the error path plays well with\n\ns/signaled/signalled/\ns/shure/sure/\n\n> +\t\t * the camera stack state machine.\n> +\t\t */\n> +\t\tnotifyError(descriptor->frameNumber,\n> +\t\t\t    descriptor->buffers[0].stream);\n>  \t}\n>  \n>  \tcallbacks_->process_capture_result(callbacks_, &captureResult);\n>  \n>  \tdelete descriptor;\n> -\tif (resultMetadata)\n> -\t\tfree_camera_metadata(resultMetadata);\n> -\n> -\treturn;\n>  }\n>  \n>  void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)\n> @@ -875,89 +790,71 @@ void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)\n>  /*\n>   * Produce a set of fixed result metadata.\n>   */\n> -camera_metadata_t *CameraDevice::getResultMetadata(int frame_number,\n> -\t\t\t\t\t\t   int64_t timestamp)\n> +std::unique_ptr<CameraMetadata> CameraDevice::getResultMetadata(int frame_number,\n> +\t\t\t\t\t\t\t\tint64_t timestamp)\n>  {\n> -\tint ret;\n> -\n>  \t/*\n>  \t * \\todo Keep this in sync with the actual number of entries.\n>  \t * Currently: 13 entries, 36 bytes\n\nThere are 12 entries.\n\nWith those small issues fixed (I'm OK if you fix the number of entries\nin this patch, even though ideally they should be fixed where they are\nintroduced and/or modified), ship it :-)\n\n>  \t */\n> -\tcamera_metadata_t *resultMetadata = allocate_camera_metadata(15, 50);\n> +\tstd::unique_ptr<CameraMetadata> resultMetadata =\n> +\t\tutils::make_unique<CameraMetadata>(15, 50);\n> +\tif (!resultMetadata->isValid()) {\n> +\t\tLOG(HAL, Error) << \"Failed to allocate static metadata\";\n> +\t\treturn nullptr;\n> +\t}\n>  \n>  \tconst uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;\n> -\tret = add_camera_metadata_entry(resultMetadata, ANDROID_CONTROL_AE_STATE,\n> -\t\t\t\t\t&ae_state, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);\n>  \n>  \tconst uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;\n> -\tret = add_camera_metadata_entry(resultMetadata, ANDROID_CONTROL_AE_LOCK,\n> -\t\t\t\t\t&ae_lock, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);\n>  \n>  \tuint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;\n> -\tret = add_camera_metadata_entry(resultMetadata, ANDROID_CONTROL_AF_STATE,\n> -\t\t\t\t\t&af_state, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);\n>  \n>  \tconst uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;\n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_CONTROL_AWB_STATE,\n> -\t\t\t\t\t&awb_state, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);\n>  \n>  \tconst uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;\n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_CONTROL_AWB_LOCK,\n> -\t\t\t\t\t&awb_lock, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);\n>  \n>  \tconst uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;\n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_LENS_STATE,\n> -\t\t\t\t\t&lens_state, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);\n>  \n>  \tint32_t sensorSizes[] = {\n>  \t\t0, 0, 2560, 1920,\n>  \t};\n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_SCALER_CROP_REGION,\n> -\t\t\t\t\tsensorSizes, 4);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);\n>  \n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_SENSOR_TIMESTAMP,\n> -\t\t\t\t\t&timestamp, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);\n>  \n>  \t/* 33.3 msec */\n>  \tconst int64_t rolling_shutter_skew = 33300000;\n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_SENSOR_ROLLING_SHUTTER_SKEW,\n> -\t\t\t\t\t&rolling_shutter_skew, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,\n> +\t\t\t\t &rolling_shutter_skew, 1);\n>  \n>  \t/* 16.6 msec */\n>  \tconst int64_t exposure_time = 16600000;\n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_SENSOR_EXPOSURE_TIME,\n> -\t\t\t\t\t&exposure_time, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,\n> +\t\t\t\t &exposure_time, 1);\n>  \n>  \tconst uint8_t lens_shading_map_mode =\n>  \t\t\t\tANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;\n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_STATISTICS_LENS_SHADING_MAP_MODE,\n> -\t\t\t\t\t&lens_shading_map_mode, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,\n> +\t\t\t\t &lens_shading_map_mode, 1);\n>  \n>  \tconst uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;\n> -\tret = add_camera_metadata_entry(resultMetadata,\n> -\t\t\t\t\tANDROID_STATISTICS_SCENE_FLICKER,\n> -\t\t\t\t\t&scene_flicker, 1);\n> -\tMETADATA_ASSERT(ret);\n> +\tresultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,\n> +\t\t\t\t &scene_flicker, 1);\n> +\n> +\t/*\n> +\t * Return the result metadata pack even is not valid: get() will return\n> +\t * nullptr.\n> +\t */\n> +\tif (!resultMetadata->isValid()) {\n> +\t\tLOG(HAL, Error) << \"Failed to construct result metadata\";\n> +\t}\n>  \n>  \treturn resultMetadata;\n>  }\n> diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n> index 7897ba9dc5c7..65ba877a02ea 100644\n> --- a/src/android/camera_device.h\n> +++ b/src/android/camera_device.h\n> @@ -19,13 +19,7 @@\n>  \n>  #include \"message.h\"\n>  \n> -#define METADATA_ASSERT(_r)\t\t\\\n> -\tdo {\t\t\t\t\\\n> -\t\tif (!(_r)) break;\t\\\n> -\t\tLOG(HAL, Error) << \"Error: \" << __func__ << \":\" << __LINE__; \\\n> -\t\treturn nullptr;\t\t\\\n> -\t} while(0);\n> -\n> +class CameraMetadata;\n>  class ThreadRpc;\n>  \n>  class CameraDevice : public libcamera::Object\n> @@ -59,14 +53,15 @@ private:\n>  \n>  \tvoid notifyShutter(uint32_t frameNumber, uint64_t timestamp);\n>  \tvoid notifyError(uint32_t frameNumber, camera3_stream_t *stream);\n> -\tcamera_metadata_t *getResultMetadata(int frame_number, int64_t timestamp);\n> +\tstd::unique_ptr<CameraMetadata> getResultMetadata(int frame_number,\n> +\t\t\t\t\t\t\t  int64_t timestamp);\n>  \n>  \tbool running_;\n>  \tstd::shared_ptr<libcamera::Camera> camera_;\n>  \tstd::unique_ptr<libcamera::CameraConfiguration> config_;\n>  \n> -\tcamera_metadata_t *staticMetadata_;\n> -\tcamera_metadata_t *requestTemplate_;\n> +\tCameraMetadata *staticMetadata_;\n> +\tCameraMetadata *requestTemplate_;\n>  \tconst camera3_callback_ops_t *callbacks_;\n>  };\n>","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4209F60C18\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  5 Sep 2019 23:17:24 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7E6C79C7;\n\tThu,  5 Sep 2019 23:17:23 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1567718243;\n\tbh=ZN3j8nznCoNX5JIJqKfo7wUT0NI1I21RwoPH0wyF8kE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=nsHP6VRGIc4Jw7OqJlfFHVkWMqClMtoZH9iIQcX+rd/jva59LoBOsPxEYIaPH94Ol\n\tARjoqyy4Bor+QNw7XUV0KLwcWScu2U5lUK1ic/8ZDGGQ/5BSnd83RFlU/0dwxSUTAB\n\ter/a5664V+ArrVBMNo68dS1KurdhmSbjarassnXo=","Date":"Fri, 6 Sep 2019 00:17:17 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190905211717.GR5035@pendragon.ideasonboard.com>","References":"<20190905210940.32358-1-jacopo@jmondi.org>\n\t<20190905210940.32358-8-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20190905210940.32358-8-jacopo@jmondi.org>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v7 7/9] android: camera_device: Use\n\tthe new CameraMetadata helper class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Thu, 05 Sep 2019 21:17:24 -0000"}}]