/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // #define LOG_NDEBUG 0 #define LOG_TAG "MetadataReader" #include "metadata_reader.h" #include #include #include "metadata_common.h" namespace default_camera_hal { MetadataReader::MetadataReader( std::unique_ptr metadata) : metadata_(std::move(metadata)) {} MetadataReader::~MetadataReader() {} int MetadataReader::Facing(int* facing) const { uint8_t metadata_facing = 0; int res = v4l2_camera_hal::SingleTagValue( *metadata_, ANDROID_LENS_FACING, &metadata_facing); if (res) { ALOGE("%s: Failed to get facing from static metadata.", __func__); return res; } switch (metadata_facing) { case (ANDROID_LENS_FACING_FRONT): *facing = CAMERA_FACING_FRONT; break; case (ANDROID_LENS_FACING_BACK): *facing = CAMERA_FACING_BACK; break; case (ANDROID_LENS_FACING_EXTERNAL): *facing = CAMERA_FACING_EXTERNAL; break; default: ALOGE("%s: Invalid facing from static metadata: %d.", __func__, metadata_facing); return -EINVAL; } return 0; } int MetadataReader::Orientation(int* orientation) const { int32_t metadata_orientation = 0; int res = v4l2_camera_hal::SingleTagValue( *metadata_, ANDROID_SENSOR_ORIENTATION, &metadata_orientation); if (res) { ALOGE("%s: Failed to get orientation from static metadata.", __func__); return res; } // Orientation must be 0, 90, 180, or 270. if (metadata_orientation < 0 || metadata_orientation > 270 || metadata_orientation % 90 != 0) { ALOGE( "%s: Invalid orientation %d " "(must be a 90-degree increment in [0, 360)).", __func__, metadata_orientation); return -EINVAL; } *orientation = static_cast(metadata_orientation); return 0; } int MetadataReader::MaxInputStreams(int32_t* max_input) const { int res = v4l2_camera_hal::SingleTagValue( *metadata_, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, max_input); if (res == -ENOENT) { // Not required; default to 0. *max_input = 0; } else if (res) { ALOGE("%s: Failed to get max output streams from static metadata.", __func__); return res; } return 0; } int MetadataReader::MaxOutputStreams(int32_t* max_raw, int32_t* max_non_stalling, int32_t* max_stalling) const { std::array max_output_streams; int res = v4l2_camera_hal::SingleTagValue( *metadata_, ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, &max_output_streams); if (res) { ALOGE("%s: Failed to get max output streams from static metadata.", __func__); return res; } *max_raw = max_output_streams[0]; *max_non_stalling = max_output_streams[1]; *max_stalling = max_output_streams[2]; return 0; } int MetadataReader::RequestCapabilities(std::set* capabilities) const { std::vector raw_capabilities; int res = v4l2_camera_hal::VectorTagValue( *metadata_, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &raw_capabilities); if (res) { ALOGE("%s: Failed to get request capabilities from static metadata.", __func__); return res; } // Move from vector to set. capabilities->insert(raw_capabilities.begin(), raw_capabilities.end()); return 0; } int MetadataReader::StreamConfigurations( std::vector* configs) const { std::vector raw_stream_configs; int res = v4l2_camera_hal::VectorTagValue( *metadata_, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &raw_stream_configs); if (res) { ALOGE("%s: Failed to get stream configs from static metadata.", __func__); return res; } // TODO(b/31384253): check for required configs. // Convert from raw. configs->insert( configs->end(), raw_stream_configs.begin(), raw_stream_configs.end()); // Check that all configs are valid. for (const auto& config : *configs) { // Must have positive dimensions. if (config.spec.width < 1 || config.spec.height < 1) { ALOGE("%s: Invalid stream config: non-positive dimensions (%d, %d).", __func__, config.spec.width, config.spec.height); return -EINVAL; } // Must have a known direction enum. switch (config.direction) { case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT: case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT: break; default: ALOGE("%s: Invalid stream config direction: %d.", __func__, config.direction); return -EINVAL; } } return 0; } int MetadataReader::StreamStallDurations( std::vector* stalls) const { std::vector raw_stream_stall_durations; int res = v4l2_camera_hal::VectorTagValue(*metadata_, ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, &raw_stream_stall_durations); if (res) { ALOGE("%s: Failed to get stall durations from static metadata.", __func__); return res; } // Convert from raw. stalls->insert(stalls->end(), raw_stream_stall_durations.begin(), raw_stream_stall_durations.end()); // Check that all stalls are valid. for (const auto& stall : *stalls) { // Must have positive dimensions. if (stall.spec.width < 1 || stall.spec.height < 1) { ALOGE("%s: Invalid stall duration: non-positive dimensions (%d, %d).", __func__, stall.spec.width, stall.spec.height); return -EINVAL; } // Must have a non-negative stall. if (stall.duration < 0) { ALOGE("%s: Invalid stall duration: negative stall %lld.", __func__, static_cast(stall.duration)); return -EINVAL; } // TODO(b/31384253): YUV_420_888, RAW10, RAW12, RAW_OPAQUE, // and IMPLEMENTATION_DEFINED must have 0 stall duration. } return 0; } int MetadataReader::ReprocessFormats(ReprocessFormatMap* reprocess_map) const { std::vector input_output_formats; int res = v4l2_camera_hal::VectorTagValue( *metadata_, ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &input_output_formats); if (res) { ALOGE("%s: Failed to get input output format map from static metadata.", __func__); return res; } // Convert from the raw vector. for (size_t i = 0; i < input_output_formats.size();) { // The map is represented as variable-length entries of the format // input, num_outputs, . // Get the input format. int32_t input_format = input_output_formats[i++]; // Find the output begin and end for this format. int32_t num_output_formats = input_output_formats[i++]; if (num_output_formats < 1) { ALOGE( "%s: No output formats for input format %d.", __func__, input_format); return -EINVAL; } size_t outputs_end = i + num_output_formats; if (outputs_end > input_output_formats.size()) { ALOGE("%s: Input format %d requests more data than available.", __func__, input_format); return -EINVAL; } // Copy all the output formats into the map. (*reprocess_map)[input_format].insert( input_output_formats.data() + i, input_output_formats.data() + outputs_end); // Move on to the next entry. i = outputs_end; } // TODO(b/31384253): check for required mappings. return 0; } } // namespace default_camera_hal