From d4c0fe30d67b7597d77079a0304647b6ea74284f Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Tue, 13 Mar 2018 19:46:57 -0700 Subject: [PATCH] Camera2: Add distortion correction support This allows camera devices to correct geometric distortion in their optics, when requested by the application. The correction only applies to processed (YUV, JPEG, etc) outputs, not RAW buffers, or the result metadata. Also fix metadata generation code to handle entries and their hal_versions, to fix code generation for the HIDL layer. A clone entry inherits its target entry's hal version, but can override it to a higher version if necessary; an error is generated if the version is less than the target entry. In addition, fix bug in generating HIDL output when there are multiple new sections in a new HAL version. Test: New CTS test passes Bug: 74434422 Change-Id: I6154e9757310636565aec5344a8988408234c164 --- camera/docs/HidlMetadata.mako | 4 +- camera/docs/camera_device_info.proto | 1 + camera/docs/docs.html | 361 +++++++++++++++++++++++++++ camera/docs/metadata_definitions.xml | 71 ++++++ camera/docs/metadata_definitions.xsd | 1 + camera/docs/metadata_model.py | 12 +- camera/docs/metadata_parser_xml.py | 2 + camera/docs/metadata_template.mako | 6 +- camera/docs/metadata_validate.py | 23 ++ camera/include/system/camera_metadata_tags.h | 17 ++ camera/src/camera_metadata_tag_info.c | 37 +++ 11 files changed, 530 insertions(+), 5 deletions(-) diff --git a/camera/docs/HidlMetadata.mako b/camera/docs/HidlMetadata.mako index 4a307cb9..dcbbde73 100644 --- a/camera/docs/HidlMetadata.mako +++ b/camera/docs/HidlMetadata.mako @@ -42,6 +42,7 @@ import android.hardware.camera.metadata@${hal_major_version()}.${i}; % endif <% gotSections = False %>\ +<% gotFirstNewSection = False %>\ % for idx, section in enumerate(find_all_sections_added_in_hal(metadata, hal_major_version(), hal_minor_version())): % if idx == 0: <% gotSections = True %>\ @@ -51,9 +52,10 @@ import android.hardware.camera.metadata@${hal_major_version()}.${i}; */ enum CameraMetadataSection : ${'uint32_t' if first_hal_minor_version(hal_major_version()) == hal_minor_version() else '@%d.%d::CameraMetadataSection' % (hal_major_version(), hal_minor_version()-1)} { % endif - % if first_hal_minor_version(hal_major_version()) != hal_minor_version(): + % if first_hal_minor_version(hal_major_version()) != hal_minor_version() and not gotFirstNewSection: ${path_name(section) | csym} = android.hardware.camera.metadata@${hal_major_version()}.${hal_minor_version()-1}::CameraMetadataSection:ANDROID_SECTION_COUNT, +<% gotFirstNewSection = True %>\ % else: ${path_name(section) | csym}, % endif diff --git a/camera/docs/camera_device_info.proto b/camera/docs/camera_device_info.proto index 392bad98..10b8f871 100644 --- a/camera/docs/camera_device_info.proto +++ b/camera/docs/camera_device_info.proto @@ -155,6 +155,7 @@ message CameraDeviceInfo { optional int32 android_reprocess_maxCaptureStall = 1638400; optional bool android_depth_depthIsExclusive = 1703936; optional int32 android_logicalMultiCamera_sensorSyncType = 1769472; + repeated int32 android_distortionCorrection_availableModes = 1835008; // End of codegen fields } diff --git a/camera/docs/docs.html b/camera/docs/docs.html index 6719a54c..81469aef 100644 --- a/camera/docs/docs.html +++ b/camera/docs/docs.html @@ -1185,6 +1185,32 @@ +
  • + distortionCorrection + +
  • @@ -29772,6 +29798,339 @@ onCaptureStarted callback.

    + distortionCorrection + + + controls + + + + Property Name + Type + Description + Units + Range + Initial HIDL HAL version + Tags + + + + + + + + + + + + + + + + + android.distortionCorrection.mode + + + byte + + [public] + + + + + + + + + + +

    Mode of operation for the lens distortion correction block.

    + + + + + + +

    android.distortionCorrection.availableModes

    + + + +

    3.3

    + + + + + + + + Details + + + +

    The lens distortion correction block attempts to improve image quality by fixing +radial, tangential, or other geometric aberrations in the camera device's optics. If +available, the android.lens.distortion field documents the lens's distortion parameters.

    +

    OFF means no distortion correction is done.

    +

    FAST/HIGH_QUALITY both mean camera device determined distortion correction will be +applied. HIGH_QUALITY mode indicates that the camera device will use the highest-quality +correction algorithms, even if it slows down capture rate. FAST means the camera device +will not slow down capture rate when applying correction. FAST may be the same as OFF if +any correction at all would slow down capture rate. Every output stream will have a +similar amount of enhancement applied.

    +

    The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not +applied to any RAW output. Metadata coordinates such as face rectangles or metering +regions are also not affected by correction.

    +

    Applications enabling distortion correction need to pay extra attention when converting +image coordinates between corrected output buffers and the sensor array. For example, if +the app supports tap-to-focus and enables correction, it then has to apply the distortion +model described in android.lens.distortion to the image buffer tap coordinates to properly +calculate the tap position on the sensor active array to be used with +android.control.afRegions. The same applies in reverse to detected face rectangles if +they need to be drawn on top of the corrected output buffers.

    + + + + + + + + + + + + static + + + + Property Name + Type + Description + Units + Range + Initial HIDL HAL version + Tags + + + + + + + + + + + + + + + + + android.distortionCorrection.availableModes + + + byte + x + + + n + + [public as enumList] + + + + +
    list of enums
    + + + + + +

    List of distortion correction modes for android.distortionCorrection.mode that are +supported by this camera device.

    + + + + + + +

    Any value listed in android.distortionCorrection.mode

    + + + +

    3.3

    + + + + + + + + + Details + + + +

    No device is required to support this API; such devices will always list only 'OFF'. +All devices that support this API will list both FAST and HIGH_QUALITY.

    + + + + + HAL Implementation Details + + + +

    HAL must support both FAST and HIGH_QUALITY if distortion correction is available +on the camera device, but the underlying implementation can be the same for both modes. +That is, if the highest quality implementation on the camera device does not slow down +capture rate, then FAST and HIGH_QUALITY will generate the same output.

    + + + + + + + + + + + dynamic + + + + Property Name + Type + Description + Units + Range + Initial HIDL HAL version + Tags + + + + + + + + + + + + + + + + + android.distortionCorrection.mode + + + byte + + [public] + + + + + + + + + + +

    Mode of operation for the lens distortion correction block.

    + + + + + + +

    android.distortionCorrection.availableModes

    + + + +

    3.3

    + + + + + + + + Details + + + +

    The lens distortion correction block attempts to improve image quality by fixing +radial, tangential, or other geometric aberrations in the camera device's optics. If +available, the android.lens.distortion field documents the lens's distortion parameters.

    +

    OFF means no distortion correction is done.

    +

    FAST/HIGH_QUALITY both mean camera device determined distortion correction will be +applied. HIGH_QUALITY mode indicates that the camera device will use the highest-quality +correction algorithms, even if it slows down capture rate. FAST means the camera device +will not slow down capture rate when applying correction. FAST may be the same as OFF if +any correction at all would slow down capture rate. Every output stream will have a +similar amount of enhancement applied.

    +

    The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not +applied to any RAW output. Metadata coordinates such as face rectangles or metering +regions are also not affected by correction.

    +

    Applications enabling distortion correction need to pay extra attention when converting +image coordinates between corrected output buffers and the sensor array. For example, if +the app supports tap-to-focus and enables correction, it then has to apply the distortion +model described in android.lens.distortion to the image buffer tap coordinates to properly +calculate the tap position on the sensor active array to be used with +android.control.afRegions. The same applies in reverse to detected face rectangles if +they need to be drawn on top of the corrected output buffers.

    + + + + + + + + + + + + + @@ -29894,6 +30253,7 @@ onCaptureStarted callback.

  • android.statistics.hotPixelMap (dynamic)
  • android.sync.frameNumber (dynamic)
  • android.sync.maxLatency (static)
  • +
  • android.distortionCorrection.availableModes (static)
  • android.edge.mode (dynamic)
  • android.hotPixel.mode (dynamic)
  • android.lens.aperture (dynamic)
  • @@ -29982,6 +30342,7 @@ onCaptureStarted callback.

  • android.scaler.availableInputOutputFormatsMap (static)
  • android.reprocess.effectiveExposureFactor (controls)
  • android.reprocess.maxCaptureStall (static)
  • +
  • android.distortionCorrection.availableModes (static)
  • android.edge.mode (dynamic)
  • android.noiseReduction.mode (dynamic)
  • diff --git a/camera/docs/metadata_definitions.xml b/camera/docs/metadata_definitions.xml index e96a0a6d..48cb694e 100644 --- a/camera/docs/metadata_definitions.xml +++ b/camera/docs/metadata_definitions.xml @@ -9662,5 +9662,76 @@ xsi:schemaLocation="http://schemas.android.com/service/camera/metadata/ metadata +
    + + + + OFF + No distortion correction is applied. + FAST Lens distortion correction is applied without reducing frame rate + relative to sensor output. It may be the same as OFF if distortion correction would + reduce frame rate relative to sensor. + HIGH_QUALITY High-quality distortion correction is applied, at the cost of + possibly reduced frame rate relative to sensor output. + + Mode of operation for the lens distortion correction block. + android.distortionCorrection.availableModes +
    The lens distortion correction block attempts to improve image quality by fixing + radial, tangential, or other geometric aberrations in the camera device's optics. If + available, the android.lens.distortion field documents the lens's distortion parameters. + + OFF means no distortion correction is done. + + FAST/HIGH_QUALITY both mean camera device determined distortion correction will be + applied. HIGH_QUALITY mode indicates that the camera device will use the highest-quality + correction algorithms, even if it slows down capture rate. FAST means the camera device + will not slow down capture rate when applying correction. FAST may be the same as OFF if + any correction at all would slow down capture rate. Every output stream will have a + similar amount of enhancement applied. + + The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not + applied to any RAW output. Metadata coordinates such as face rectangles or metering + regions are also not affected by correction. + + Applications enabling distortion correction need to pay extra attention when converting + image coordinates between corrected output buffers and the sensor array. For example, if + the app supports tap-to-focus and enables correction, it then has to apply the distortion + model described in android.lens.distortion to the image buffer tap coordinates to properly + calculate the tap position on the sensor active array to be used with + android.control.afRegions. The same applies in reverse to detected face rectangles if + they need to be drawn on top of the corrected output buffers. +
    +
    +
    + + + + n + + + List of distortion correction modes for android.distortionCorrection.mode that are + supported by this camera device. + + Any value listed in android.distortionCorrection.mode +
    + No device is required to support this API; such devices will always list only 'OFF'. + All devices that support this API will list both FAST and HIGH_QUALITY. +
    + + HAL must support both FAST and HIGH_QUALITY if distortion correction is available + on the camera device, but the underlying implementation can be the same for both modes. + That is, if the highest quality implementation on the camera device does not slow down + capture rate, then FAST and HIGH_QUALITY will generate the same output. + + + +
    +
    + + + + +
    diff --git a/camera/docs/metadata_definitions.xsd b/camera/docs/metadata_definitions.xsd index cd021bdb..8e46cb10 100644 --- a/camera/docs/metadata_definitions.xsd +++ b/camera/docs/metadata_definitions.xsd @@ -329,5 +329,6 @@ + diff --git a/camera/docs/metadata_model.py b/camera/docs/metadata_model.py index daebcb24..398e43a7 100644 --- a/camera/docs/metadata_model.py +++ b/camera/docs/metadata_model.py @@ -416,7 +416,9 @@ class Metadata(Node): target_kind = p.target_kind target_entry = self._entry_map[target_kind].get(p.name) p._entry = target_entry - + if (p.hal_major_version == 0): + p._hal_major_version = target_entry._hal_major_version + p._hal_minor_version = target_entry._hal_minor_version # should not throw if we pass validation # but can happen when importing obsolete CSV entries if target_entry is None: @@ -1365,8 +1367,12 @@ class Entry(Node): hal_version = kwargs.get('hal_version') if hal_version is None: - self._hal_major_version = 3 - self._hal_minor_version = 2 + if self.is_clone(): + self._hal_major_version = 0 + self._hal_minor_version = 0 + else: + self._hal_major_version = 3 + self._hal_minor_version = 2 else: self._hal_major_version = int(hal_version.partition('.')[0]) self._hal_minor_version = int(hal_version.partition('.')[2]) diff --git a/camera/docs/metadata_parser_xml.py b/camera/docs/metadata_parser_xml.py index db2c1547..91af192a 100755 --- a/camera/docs/metadata_parser_xml.py +++ b/camera/docs/metadata_parser_xml.py @@ -156,6 +156,8 @@ class MetadataParserXml: # no type_notes since its the same } d2 = {} + if 'hal_version' in entry.attrs: + d2['hal_version'] = entry['hal_version'] insert = self.metadata.insert_clone diff --git a/camera/docs/metadata_template.mako b/camera/docs/metadata_template.mako index 22c68a5b..02689f0b 100644 --- a/camera/docs/metadata_template.mako +++ b/camera/docs/metadata_template.mako @@ -69,7 +69,11 @@ <%def name="insert_entry(prop)"> % if prop.is_clone(): - + % if prop.details is not None:
    ${prop.details}
    diff --git a/camera/docs/metadata_validate.py b/camera/docs/metadata_validate.py index 44f860ac..ede14494 100755 --- a/camera/docs/metadata_validate.py +++ b/camera/docs/metadata_validate.py @@ -222,6 +222,29 @@ def validate_clones(soup): validate_error(error_msg) success = False + if matching_entry is not None: + entry_hal_major_version = 3 + entry_hal_minor_version = 2 + entry_hal_version = matching_entry.get('hal_version') + if entry_hal_version is not None: + entry_hal_major_version = int(entry_hal_version.partition('.')[0]) + entry_hal_minor_version = int(entry_hal_version.partition('.')[2]) + + clone_hal_major_version = entry_hal_major_version + clone_hal_minor_version = entry_hal_minor_version + clone_hal_version = clone.get('hal_version') + if clone_hal_version is not None: + clone_hal_major_version = int(clone_hal_version.partition('.')[0]) + clone_hal_minor_version = int(clone_hal_version.partition('.')[2]) + + if clone_hal_major_version < entry_hal_major_version or \ + (clone_hal_major_version == entry_hal_major_version and \ + clone_hal_minor_version < entry_hal_minor_version): + error_msg = ("Clone '%s' HAL version '%d.%d' is older than entry target HAL version '%d.%d'" \ + % (clone_name, clone_hal_major_version, clone_hal_minor_version, entry_hal_major_version, entry_hal_minor_version)) + validate_error(error_msg) + success = False + return success # All elements with container=$foo have a <$foo> child diff --git a/camera/include/system/camera_metadata_tags.h b/camera/include/system/camera_metadata_tags.h index 823c4141..d8cd02ea 100644 --- a/camera/include/system/camera_metadata_tags.h +++ b/camera/include/system/camera_metadata_tags.h @@ -62,6 +62,7 @@ typedef enum camera_metadata_section { ANDROID_REPROCESS, ANDROID_DEPTH, ANDROID_LOGICAL_MULTI_CAMERA, + ANDROID_DISTORTION_CORRECTION, ANDROID_SECTION_COUNT, VENDOR_SECTION = 0x8000 @@ -101,6 +102,9 @@ typedef enum camera_metadata_section_start { ANDROID_LOGICAL_MULTI_CAMERA_START = ANDROID_LOGICAL_MULTI_CAMERA << 16, + ANDROID_DISTORTION_CORRECTION_START + = ANDROID_DISTORTION_CORRECTION + << 16, VENDOR_SECTION_START = VENDOR_SECTION << 16 } camera_metadata_section_start_t; @@ -435,6 +439,11 @@ typedef enum camera_metadata_tag { ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE, // enum | public | HIDL v3.3 ANDROID_LOGICAL_MULTI_CAMERA_END, + ANDROID_DISTORTION_CORRECTION_MODE = // enum | public | HIDL v3.3 + ANDROID_DISTORTION_CORRECTION_START, + ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES, // byte[] | public | HIDL v3.3 + ANDROID_DISTORTION_CORRECTION_END, + } camera_metadata_tag_t; /** @@ -985,3 +994,11 @@ typedef enum camera_metadata_enum_android_logical_multi_camera_sensor_sync_type } camera_metadata_enum_android_logical_multi_camera_sensor_sync_type_t; +// ANDROID_DISTORTION_CORRECTION_MODE +typedef enum camera_metadata_enum_android_distortion_correction_mode { + ANDROID_DISTORTION_CORRECTION_MODE_OFF , // HIDL v3.3 + ANDROID_DISTORTION_CORRECTION_MODE_FAST , // HIDL v3.3 + ANDROID_DISTORTION_CORRECTION_MODE_HIGH_QUALITY , // HIDL v3.3 +} camera_metadata_enum_android_distortion_correction_mode_t; + + diff --git a/camera/src/camera_metadata_tag_info.c b/camera/src/camera_metadata_tag_info.c index b420fc16..0d7b6791 100644 --- a/camera/src/camera_metadata_tag_info.c +++ b/camera/src/camera_metadata_tag_info.c @@ -58,6 +58,8 @@ const char *camera_metadata_section_names[ANDROID_SECTION_COUNT] = { [ANDROID_REPROCESS] = "android.reprocess", [ANDROID_DEPTH] = "android.depth", [ANDROID_LOGICAL_MULTI_CAMERA] = "android.logicalMultiCamera", + [ANDROID_DISTORTION_CORRECTION] + = "android.distortionCorrection", }; unsigned int camera_metadata_section_bounds[ANDROID_SECTION_COUNT][2] = { @@ -115,6 +117,9 @@ unsigned int camera_metadata_section_bounds[ANDROID_SECTION_COUNT][2] = { ANDROID_DEPTH_END }, [ANDROID_LOGICAL_MULTI_CAMERA] = { ANDROID_LOGICAL_MULTI_CAMERA_START, ANDROID_LOGICAL_MULTI_CAMERA_END }, + [ANDROID_DISTORTION_CORRECTION] + = { ANDROID_DISTORTION_CORRECTION_START, + ANDROID_DISTORTION_CORRECTION_END }, }; static tag_info_t android_color_correction[ANDROID_COLOR_CORRECTION_END - @@ -709,6 +714,14 @@ static tag_info_t android_logical_multi_camera[ANDROID_LOGICAL_MULTI_CAMERA_END { "sensorSyncType", TYPE_BYTE }, }; +static tag_info_t android_distortion_correction[ANDROID_DISTORTION_CORRECTION_END - + ANDROID_DISTORTION_CORRECTION_START] = { + [ ANDROID_DISTORTION_CORRECTION_MODE - ANDROID_DISTORTION_CORRECTION_START ] = + { "mode", TYPE_BYTE }, + [ ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES - ANDROID_DISTORTION_CORRECTION_START ] = + { "availableModes", TYPE_BYTE }, +}; + tag_info_t *tag_info[ANDROID_SECTION_COUNT] = { android_color_correction, @@ -738,6 +751,7 @@ tag_info_t *tag_info[ANDROID_SECTION_COUNT] = { android_reprocess, android_depth, android_logical_multi_camera, + android_distortion_correction, }; int camera_metadata_enum_snprint(uint32_t tag, @@ -2758,6 +2772,29 @@ int camera_metadata_enum_snprint(uint32_t tag, break; } + case ANDROID_DISTORTION_CORRECTION_MODE: { + switch (value) { + case ANDROID_DISTORTION_CORRECTION_MODE_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_DISTORTION_CORRECTION_MODE_FAST: + msg = "FAST"; + ret = 0; + break; + case ANDROID_DISTORTION_CORRECTION_MODE_HIGH_QUALITY: + msg = "HIGH_QUALITY"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES: { + break; + } + } strncpy(dst, msg, size - 1); -- 2.11.0