Add V4L2EnumControls to V4L2Metadata.
Add all current enum controls and their mappings
to the metadata constructor.
BUG: https://b/30140438
Change-Id: Ie4a5b89d8bc4bc75531425e5fc8bfb4a181b0a03
diff --git a/modules/camera/3_4/metadata/v4l2_enum_control.cpp b/modules/camera/3_4/metadata/v4l2_enum_control.cpp
index 21ca22b..58e1b6b 100644
--- a/modules/camera/3_4/metadata/v4l2_enum_control.cpp
+++ b/modules/camera/3_4/metadata/v4l2_enum_control.cpp
@@ -32,10 +32,11 @@
HAL_LOGE("Failed to query control %d.", v4l2_control);
return nullptr;
}
- if (control_query.type != V4L2_CTRL_TYPE_MENU) {
+ if (control_query.type != V4L2_CTRL_TYPE_MENU &&
+ control_query.type != V4L2_CTRL_TYPE_BOOLEAN) {
HAL_LOGE(
- "Enum controls can only be constructed from V4L2 menu controls (%d is "
- "of type %d)",
+ "Enum controls can only be constructed from V4L2 menu and boolean "
+ "controls (%d is of type %d)",
v4l2_control, control_query.type);
return nullptr;
}
diff --git a/modules/camera/3_4/metadata/v4l2_enum_control_test.cpp b/modules/camera/3_4/metadata/v4l2_enum_control_test.cpp
index 6df7321..54f78f3 100644
--- a/modules/camera/3_4/metadata/v4l2_enum_control_test.cpp
+++ b/modules/camera/3_4/metadata/v4l2_enum_control_test.cpp
@@ -77,7 +77,7 @@
v4l2_query_ext_ctrl query_result;
query_result.type = V4L2_CTRL_TYPE_MENU;
query_result.minimum = 1;
- query_result.maximum = 5;
+ query_result.maximum = 7;
query_result.step = 2;
EXPECT_CALL(*device_, QueryControl(v4l2_control_, _))
.WillOnce(DoAll(SetArgPointee<1>(query_result), Return(0)));
@@ -104,7 +104,8 @@
// Should populate the options according to capabilities returned.
android::CameraMetadata metadata;
ASSERT_EQ(test_control->PopulateStaticFields(&metadata), 0);
- // Min 1, max 5, step 2 means {1,3,5} converted to metadata values.
+ // Min 1, max 7, step 2 means {1,3,5} converted to metadata values.
+ // There is no 7 in the map, so it shouldn't be present.
std::vector<uint8_t> expected_options;
expected_options.push_back(V4L2ToMetadata(1));
expected_options.push_back(V4L2ToMetadata(3));
diff --git a/modules/camera/3_4/v4l2_metadata.cpp b/modules/camera/3_4/v4l2_metadata.cpp
index 1ebd9c0..9ec892f 100644
--- a/modules/camera/3_4/v4l2_metadata.cpp
+++ b/modules/camera/3_4/v4l2_metadata.cpp
@@ -21,15 +21,21 @@
#include "common.h"
#include "metadata/fixed_property.h"
#include "metadata/ignored_control.h"
+#include "metadata/v4l2_enum_control.h"
namespace v4l2_camera_hal {
-V4L2Metadata::V4L2Metadata(V4L2Wrapper* device) : device_(device) {
+V4L2Metadata::V4L2Metadata(std::shared_ptr<V4L2Wrapper> device)
+ : device_(std::move(device)) {
HAL_LOG_ENTER();
+ // TODO: Temporarily connect to the device so that V4L2-specific components
+ // can make any necessary queries.
+
// TODO(b/30140438): Add all metadata components used by V4L2Camera here.
- // Currently these are all the fixed properties. Will add the other properties
- // as more PartialMetadata subclasses get implemented.
+ // Currently these are all the fixed properties, ignored controls, and
+ // V4L2 enum controls. Will add the other properties as more PartialMetadata
+ // subclasses get implemented.
AddComponent(
std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
@@ -40,9 +46,92 @@
ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST)));
// TODO(b/30510395): subcomponents of 3A.
+ // In general, default to ON/AUTO since they imply pretty much nothing,
+ // while OFF implies guarantees about not hindering performance.
AddComponent(std::unique_ptr<PartialMetadataInterface>(
new FixedProperty<std::array<int32_t, 3>>(
ANDROID_CONTROL_MAX_REGIONS, {{/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0}})));
+ AddEnumControlOrDefault(V4L2_CID_EXPOSURE_AUTO, ANDROID_CONTROL_AE_MODE,
+ ANDROID_CONTROL_AE_AVAILABLE_MODES,
+ {{V4L2_EXPOSURE_AUTO, ANDROID_CONTROL_AE_MODE_ON},
+ {V4L2_EXPOSURE_MANUAL, ANDROID_CONTROL_AE_MODE_OFF}},
+ ANDROID_CONTROL_AE_MODE_ON);
+ AddEnumControlOrDefault(V4L2_CID_POWER_LINE_FREQUENCY,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE,
+ ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+ {{V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF},
+ {V4L2_CID_POWER_LINE_FREQUENCY_50HZ,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ},
+ {V4L2_CID_POWER_LINE_FREQUENCY_60HZ,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ},
+ {V4L2_CID_POWER_LINE_FREQUENCY_AUTO,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO}},
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO);
+ // V4L2 offers multiple white balance interfaces. Try the advanced one before
+ // falling
+ // back to the simpler version.
+ // Modes from each API that don't match up:
+ // Android: WARM_FLUORESCENT, TWILIGHT.
+ // V4L2: FLUORESCENT_H, HORIZON, FLASH.
+ std::unique_ptr<PartialMetadataInterface> awb(
+ V4L2EnumControl::NewV4L2EnumControl(
+ device_, V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
+ ANDROID_CONTROL_AWB_MODE, ANDROID_CONTROL_AWB_AVAILABLE_MODES,
+ {{V4L2_WHITE_BALANCE_MANUAL, ANDROID_CONTROL_AWB_MODE_OFF},
+ {V4L2_WHITE_BALANCE_AUTO, ANDROID_CONTROL_AWB_MODE_AUTO},
+ {V4L2_WHITE_BALANCE_INCANDESCENT,
+ ANDROID_CONTROL_AWB_MODE_INCANDESCENT},
+ {V4L2_WHITE_BALANCE_FLUORESCENT,
+ ANDROID_CONTROL_AWB_MODE_FLUORESCENT},
+ {V4L2_WHITE_BALANCE_DAYLIGHT, ANDROID_CONTROL_AWB_MODE_DAYLIGHT},
+ {V4L2_WHITE_BALANCE_CLOUDY,
+ ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT},
+ {V4L2_WHITE_BALANCE_SHADE, ANDROID_CONTROL_AWB_MODE_SHADE}}));
+ if (awb) {
+ AddComponent(std::move(awb));
+ } else {
+ // Fall back to simpler AWB or even just an ignored control.
+ AddEnumControlOrDefault(
+ V4L2_CID_AUTO_WHITE_BALANCE, ANDROID_CONTROL_AWB_MODE,
+ ANDROID_CONTROL_AWB_AVAILABLE_MODES,
+ {{0, ANDROID_CONTROL_AWB_MODE_OFF}, {1, ANDROID_CONTROL_AWB_MODE_AUTO}},
+ ANDROID_CONTROL_AWB_MODE_AUTO);
+ }
+ // TODO(b/30510395): subcomponents of scene modes
+ // (may itself be a subcomponent of 3A).
+ // Modes from each API that don't match up:
+ // Android: FACE_PRIORITY, ACTION, NIGHT_PORTRAIT, THEATRE, STEADYPHOTO,
+ // BARCODE, HIGH_SPEED_VIDEO, SNOW (combined with BEACH in V4L2. Only BEACH
+ // is reported to avoid ambiguity).
+ // V4L2: BACKLIGHT, DAWN_DUSK, FALL_COLORS, TEXT.
+ AddEnumControlOrDefault(
+ V4L2_CID_SCENE_MODE, ANDROID_CONTROL_SCENE_MODE,
+ ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
+ {{V4L2_SCENE_MODE_NONE, ANDROID_CONTROL_SCENE_MODE_DISABLED},
+ {V4L2_SCENE_MODE_BEACH_SNOW, ANDROID_CONTROL_SCENE_MODE_BEACH},
+ {V4L2_SCENE_MODE_CANDLE_LIGHT, ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT},
+ {V4L2_SCENE_MODE_FIREWORKS, ANDROID_CONTROL_SCENE_MODE_FIREWORKS},
+ {V4L2_SCENE_MODE_LANDSCAPE, ANDROID_CONTROL_SCENE_MODE_LANDSCAPE},
+ {V4L2_SCENE_MODE_NIGHT, ANDROID_CONTROL_SCENE_MODE_NIGHT},
+ {V4L2_SCENE_MODE_PARTY_INDOOR, ANDROID_CONTROL_SCENE_MODE_PARTY},
+ {V4L2_SCENE_MODE_SPORTS, ANDROID_CONTROL_SCENE_MODE_SPORTS},
+ {V4L2_SCENE_MODE_SUNSET, ANDROID_CONTROL_SCENE_MODE_SUNSET}},
+ ANDROID_CONTROL_SCENE_MODE_DISABLED);
+ // Modes from each API that don't match up:
+ // Android: POSTERIZE, WHITEBOARD, BLACKBOARD.
+ // V4L2: ANTIQUE, ART_FREEZE, EMBOSS, GRASS_GREEN, SKETCH, SKIN_WHITEN,
+ // SKY_BLUE, SILHOUETTE, VIVID, SET_CBCR.
+ AddEnumControlOrDefault(
+ V4L2_CID_COLORFX, ANDROID_CONTROL_EFFECT_MODE,
+ ANDROID_CONTROL_AVAILABLE_EFFECTS,
+ {{V4L2_COLORFX_NONE, ANDROID_CONTROL_EFFECT_MODE_OFF},
+ {V4L2_COLORFX_BW, ANDROID_CONTROL_EFFECT_MODE_MONO},
+ {V4L2_COLORFX_NEGATIVE, ANDROID_CONTROL_EFFECT_MODE_NEGATIVE},
+ {V4L2_COLORFX_SOLARIZATION, ANDROID_CONTROL_EFFECT_MODE_SOLARIZE},
+ {V4L2_COLORFX_SEPIA, ANDROID_CONTROL_EFFECT_MODE_SEPIA},
+ {V4L2_COLORFX_AQUA, ANDROID_CONTROL_EFFECT_MODE_AQUA}},
+ ANDROID_CONTROL_EFFECT_MODE_OFF);
// Not sure if V4L2 does or doesn't do this, but HAL documentation says
// all devices must support FAST, and FAST can be equivalent to OFF, so
@@ -105,6 +194,20 @@
ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
{ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF},
ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF)));
+ // V4L2 doesn't differentiate between OPTICAL and VIDEO stabilization,
+ // so only report one (and report the other as OFF).
+ AddEnumControlOrDefault(V4L2_CID_IMAGE_STABILIZATION,
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+ ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
+ {{0, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF},
+ {1, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON}},
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF);
+ AddComponent(
+ std::unique_ptr<PartialMetadataInterface>(new IgnoredControl<uint8_t>(
+ ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+ ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+ {ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF},
+ ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF)));
// Unable to control noise reduction in V4L2 devices,
// but FAST is allowed to be the same as OFF.
@@ -195,4 +298,21 @@
V4L2Metadata::~V4L2Metadata() { HAL_LOG_ENTER(); }
+void V4L2Metadata::AddEnumControlOrDefault(
+ int v4l2_control, int32_t control_tag, int32_t options_tag,
+ const std::map<int32_t, uint8_t>& v4l2_to_metadata, uint8_t default_value) {
+ HAL_LOG_ENTER();
+
+ std::unique_ptr<PartialMetadataInterface> control(
+ V4L2EnumControl::NewV4L2EnumControl(device_, v4l2_control, control_tag,
+ options_tag, v4l2_to_metadata));
+
+ if (!control) {
+ control.reset(new IgnoredControl<uint8_t>(control_tag, options_tag,
+ {default_value}, default_value));
+ }
+
+ AddComponent(std::move(control));
+}
+
} // namespace v4l2_camera_hal
diff --git a/modules/camera/3_4/v4l2_metadata.h b/modules/camera/3_4/v4l2_metadata.h
index ff157c0..f99ceac 100644
--- a/modules/camera/3_4/v4l2_metadata.h
+++ b/modules/camera/3_4/v4l2_metadata.h
@@ -17,21 +17,32 @@
#ifndef V4L2_CAMERA_HAL_V4L2_METADATA_H_
#define V4L2_CAMERA_HAL_V4L2_METADATA_H_
+#include <map>
+#include <memory>
+
#include <hardware/camera3.h>
#include "common.h"
+#include "metadata/control.h"
#include "metadata/metadata.h"
#include "v4l2_wrapper.h"
namespace v4l2_camera_hal {
class V4L2Metadata : public Metadata {
public:
- V4L2Metadata(V4L2Wrapper* device);
+ V4L2Metadata(std::shared_ptr<V4L2Wrapper> device);
virtual ~V4L2Metadata();
private:
+ // Attempt to construct and add an enum control. If construction fails,
+ // use an IgnoredControl with only the default value instead.
+ void AddEnumControlOrDefault(
+ int v4l2_control, int32_t control_tag, int32_t options_tag,
+ const std::map<int32_t, uint8_t>& v4l2_to_metadata,
+ uint8_t default_value);
+
// Access to the device.
- V4L2Wrapper* device_;
+ std::shared_ptr<V4L2Wrapper> device_;
DISALLOW_COPY_AND_ASSIGN(V4L2Metadata);
};