Home | History | Annotate | Download | only in 3_4
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "FormatMetadataFactory"
     19 
     20 #include "format_metadata_factory.h"
     21 
     22 #include <algorithm>
     23 #include <set>
     24 
     25 #include "arc/image_processor.h"
     26 #include "common.h"
     27 #include "metadata/array_vector.h"
     28 #include "metadata/partial_metadata_factory.h"
     29 #include "metadata/property.h"
     30 
     31 namespace v4l2_camera_hal {
     32 
     33 static int GetHalFormats(const std::shared_ptr<V4L2Wrapper>& device,
     34                          std::set<int32_t>* result_formats) {
     35   if (!result_formats) {
     36     HAL_LOGE("Null result formats pointer passed");
     37     return -EINVAL;
     38   }
     39 
     40   std::set<uint32_t> v4l2_formats;
     41   int res = device->GetFormats(&v4l2_formats);
     42   if (res) {
     43     HAL_LOGE("Failed to get device formats.");
     44     return res;
     45   }
     46 
     47   for (auto v4l2_format : v4l2_formats) {
     48     int32_t hal_format = StreamFormat::V4L2ToHalPixelFormat(v4l2_format);
     49     if (hal_format < 0) {
     50       // Unrecognized/unused format. Skip it.
     51       continue;
     52     }
     53     result_formats->insert(hal_format);
     54   }
     55 
     56   return 0;
     57 }
     58 
     59 static int FpsRangesCompare(std::array<int32_t, 2> a,
     60                             std::array<int32_t, 2> b) {
     61   if (a[1] == b[1]) {
     62     return a[0] > b[0];
     63   }
     64   return a[1] > b[1];
     65 }
     66 
     67 int AddFormatComponents(
     68     std::shared_ptr<V4L2Wrapper> device,
     69     std::insert_iterator<PartialMetadataSet> insertion_point) {
     70   HAL_LOG_ENTER();
     71 
     72   // Get all supported formats.
     73   std::set<int32_t> hal_formats;
     74   int res = GetHalFormats(device, &hal_formats);
     75   if (res) {
     76     return res;
     77   }
     78 
     79   std::set<int32_t> unsupported_hal_formats;
     80   if (hal_formats.find(HAL_PIXEL_FORMAT_YCbCr_420_888) == hal_formats.end()) {
     81     HAL_LOGW("YCbCr_420_888 (0x%x) not directly supported by device.",
     82              HAL_PIXEL_FORMAT_YCbCr_420_888);
     83     hal_formats.insert(HAL_PIXEL_FORMAT_YCbCr_420_888);
     84     unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_YCbCr_420_888);
     85   }
     86   if (hal_formats.find(HAL_PIXEL_FORMAT_BLOB) == hal_formats.end()) {
     87     HAL_LOGW("JPEG (0x%x) not directly supported by device.",
     88              HAL_PIXEL_FORMAT_BLOB);
     89     hal_formats.insert(HAL_PIXEL_FORMAT_BLOB);
     90     unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_BLOB);
     91   }
     92 
     93   // As hal_formats is populated by reading and converting V4L2 formats to the
     94   // matching HAL formats, we will never see an implementation defined format in
     95   // the list. We populate it ourselves and map it to a qualified format. If no
     96   // qualified formats exist, this will be the first available format.
     97   hal_formats.insert(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
     98   unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
     99 
    100   // Qualified formats are the set of formats supported by this camera that the
    101   // image processor can translate into the YU12 format. We additionally check
    102   // that the conversion from YU12 to the desired hal format is supported.
    103   std::vector<uint32_t> qualified_formats;
    104   res = device->GetQualifiedFormats(&qualified_formats);
    105   if (res && unsupported_hal_formats.size() > 1) {
    106     HAL_LOGE(
    107         "Failed to retrieve qualified formats, cannot perform conversions.");
    108     return res;
    109   }
    110 
    111   HAL_LOGI("Supports %zu qualified formats.", qualified_formats.size());
    112 
    113   // Find sizes and frame/stall durations for all formats.
    114   // We also want to find the smallest max frame duration amongst all formats,
    115   // And the largest min frame duration amongst YUV (i.e. largest max frame rate
    116   // supported by all YUV sizes).
    117   // Stream configs are {format, width, height, direction} (input or output).
    118   ArrayVector<int32_t, 4> stream_configs;
    119   // Frame durations are {format, width, height, duration} (duration in ns).
    120   ArrayVector<int64_t, 4> min_frame_durations;
    121   // Stall durations are {format, width, height, duration} (duration in ns).
    122   ArrayVector<int64_t, 4> stall_durations;
    123   int64_t min_max_frame_duration = std::numeric_limits<int64_t>::max();
    124   std::vector<std::array<int32_t, 2>> fps_ranges;
    125   for (auto hal_format : hal_formats) {
    126     // Get the corresponding V4L2 format.
    127     uint32_t v4l2_format = StreamFormat::HalToV4L2PixelFormat(hal_format);
    128     if (v4l2_format == 0) {
    129       // Unrecognized/unused format. Should never happen since hal_formats
    130       // came from translating a bunch of V4L2 formats above.
    131       HAL_LOGE("Couldn't find V4L2 format for HAL format %d", hal_format);
    132       return -ENODEV;
    133     } else if (unsupported_hal_formats.find(hal_format) !=
    134                unsupported_hal_formats.end()) {
    135       if (hal_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
    136         if (qualified_formats.size() != 0) {
    137           v4l2_format = qualified_formats[0];
    138         } else if (unsupported_hal_formats.size() == 1) {
    139           v4l2_format = StreamFormat::HalToV4L2PixelFormat(
    140               HAL_PIXEL_FORMAT_YCbCr_420_888);
    141         } else {
    142           // No-op. If there are no qualified formats, and implementation
    143           // defined is not the only unsupported format, then other unsupported
    144           // formats will throw an error.
    145         }
    146         HAL_LOGW(
    147             "Implementation-defined format is set to V4L2 pixel format 0x%x",
    148             v4l2_format);
    149       } else if (qualified_formats.size() == 0) {
    150         HAL_LOGE(
    151             "Camera does not support required format: 0x%x, and there are no "
    152             "qualified"
    153             "formats to transform from.",
    154             hal_format);
    155         return -ENODEV;
    156       } else if (!arc::ImageProcessor::SupportsConversion(V4L2_PIX_FMT_YUV420,
    157                                                           v4l2_format)) {
    158         HAL_LOGE(
    159             "The image processor does not support conversion to required "
    160             "format: 0x%x",
    161             hal_format);
    162         return -ENODEV;
    163       } else {
    164         v4l2_format = qualified_formats[0];
    165         HAL_LOGW(
    166             "Hal format 0x%x will be converted from V4L2 pixel format 0x%x",
    167             hal_format, v4l2_format);
    168       }
    169     }
    170 
    171     // Get the available sizes for this format.
    172     std::set<std::array<int32_t, 2>> frame_sizes;
    173     res = device->GetFormatFrameSizes(v4l2_format, &frame_sizes);
    174     if (res) {
    175       HAL_LOGE("Failed to get all frame sizes for format %d", v4l2_format);
    176       return res;
    177     }
    178 
    179     for (const auto& frame_size : frame_sizes) {
    180       // Note the format and size combination in stream configs.
    181       stream_configs.push_back(
    182           {{hal_format,
    183             frame_size[0],
    184             frame_size[1],
    185             ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}});
    186 
    187       // Find the duration range for this format and size.
    188       std::array<int64_t, 2> duration_range;
    189       res = device->GetFormatFrameDurationRange(
    190           v4l2_format, frame_size, &duration_range);
    191       if (res) {
    192         HAL_LOGE(
    193             "Failed to get frame duration range for format %d, "
    194             "size %u x %u",
    195             v4l2_format,
    196             frame_size[0],
    197             frame_size[1]);
    198         return res;
    199       }
    200       int64_t size_min_frame_duration = duration_range[0];
    201       int64_t size_max_frame_duration = duration_range[1];
    202       min_frame_durations.push_back({{hal_format,
    203                                       frame_size[0],
    204                                       frame_size[1],
    205                                       size_min_frame_duration}});
    206 
    207       // Note the stall duration for this format and size.
    208       // Usually 0 for non-jpeg, non-zero for JPEG.
    209       // Randomly choosing absurd 1 sec for JPEG. Unsure what this breaks.
    210       int64_t stall_duration = 0;
    211       if (hal_format == HAL_PIXEL_FORMAT_BLOB) {
    212         stall_duration = 1000000000;
    213       }
    214       stall_durations.push_back(
    215           {{hal_format, frame_size[0], frame_size[1], stall_duration}});
    216 
    217       // Update our search for general min & max frame durations.
    218       // In theory max frame duration (min frame rate) should be consistent
    219       // between all formats, but we check and only advertise the smallest
    220       // available max duration just in case.
    221       if (size_max_frame_duration < min_max_frame_duration) {
    222         min_max_frame_duration = size_max_frame_duration;
    223       }
    224       // ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES will contain all
    225       // the fps ranges for YUV_420_888 only since YUV_420_888 format is
    226       // the default camera format by Android.
    227       if (hal_format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
    228         // Convert from frame durations measured in ns.
    229         // Min, max fps supported by all YUV formats.
    230         const int32_t min_fps = 1000000000 / size_max_frame_duration;
    231         const int32_t max_fps = 1000000000 / size_min_frame_duration;
    232         if (std::find(fps_ranges.begin(), fps_ranges.end(),
    233                       std::array<int32_t, 2>{min_fps, max_fps}) ==
    234             fps_ranges.end()) {
    235           fps_ranges.push_back({min_fps, max_fps});
    236         }
    237       }
    238     }
    239   }
    240 
    241   // Sort fps ranges in descending order.
    242   std::sort(fps_ranges.begin(), fps_ranges.end(), FpsRangesCompare);
    243 
    244   // Construct the metadata components.
    245   insertion_point = std::make_unique<Property<ArrayVector<int32_t, 4>>>(
    246       ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
    247       std::move(stream_configs));
    248   insertion_point = std::make_unique<Property<ArrayVector<int64_t, 4>>>(
    249       ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
    250       std::move(min_frame_durations));
    251   insertion_point = std::make_unique<Property<ArrayVector<int64_t, 4>>>(
    252       ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, std::move(stall_durations));
    253   insertion_point = std::make_unique<Property<int64_t>>(
    254       ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, min_max_frame_duration);
    255   // TODO(b/31019725): This should probably not be a NoEffect control.
    256   insertion_point = NoEffectMenuControl<std::array<int32_t, 2>>(
    257       ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
    258       ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fps_ranges,
    259       {{CAMERA3_TEMPLATE_VIDEO_RECORD, fps_ranges.front()},
    260        {OTHER_TEMPLATES, fps_ranges.back()}});
    261 
    262   return 0;
    263 }
    264 
    265 }  // namespace v4l2_camera_hal
    266