Home | History | Annotate | Download | only in metadata
      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 #ifndef V4L2_CAMERA_HAL_METADATA_CONTROL_FACTORY_H_
     18 #define V4L2_CAMERA_HAL_METADATA_CONTROL_FACTORY_H_
     19 
     20 #include "../common.h"
     21 #include "control.h"
     22 #include "menu_control_options.h"
     23 #include "no_effect_control_delegate.h"
     24 #include "ranged_converter.h"
     25 #include "slider_control_options.h"
     26 #include "state.h"
     27 #include "tagged_control_delegate.h"
     28 #include "tagged_control_options.h"
     29 #include "v4l2_control_delegate.h"
     30 
     31 namespace v4l2_camera_hal {
     32 
     33 enum class ControlType { kMenu, kSlider };
     34 
     35 // Static functions to create partial metadata. Nullptr is returned on failures.
     36 
     37 // FixedState: A state that doesn't change.
     38 template <typename T>
     39 static std::unique_ptr<State<T>> FixedState(int32_t tag, T value);
     40 
     41 // NoEffectOptionlessControl: A control that accepts any value,
     42 // and has no effect. A default value is given.
     43 template <typename T>
     44 static std::unique_ptr<Control<T>> NoEffectOptionlessControl(
     45     int32_t delegate_tag, T default_value);
     46 
     47 // NoEffectMenuControl: Some menu options, but they have no effect.
     48 template <typename T>
     49 static std::unique_ptr<Control<T>> NoEffectMenuControl(
     50     int32_t delegate_tag,
     51     int32_t options_tag,
     52     const std::vector<T>& options,
     53     std::map<int, T> default_values = {});
     54 
     55 // NoEffectSliderControl: A slider of options, but they have no effect.
     56 template <typename T>
     57 static std::unique_ptr<Control<T>> NoEffectSliderControl(
     58     int32_t delegate_tag,
     59     int32_t options_tag,
     60     T min,
     61     T max,
     62     std::map<int, T> default_values = {});
     63 
     64 // NoEffectControl: A control with no effect and only a single allowable
     65 // value. Chooses an appropriate ControlOptionsInterface depending on type.
     66 template <typename T>
     67 static std::unique_ptr<Control<T>> NoEffectControl(
     68     ControlType type,
     69     int32_t delegate_tag,
     70     int32_t options_tag,
     71     T value,
     72     std::map<int, T> default_values = {});
     73 
     74 // V4L2Control: A control corresponding to a V4L2 control.
     75 template <typename T>
     76 static std::unique_ptr<Control<T>> V4L2Control(
     77     ControlType type,
     78     int32_t delegate_tag,
     79     int32_t options_tag,
     80     std::shared_ptr<V4L2Wrapper> device,
     81     int control_id,
     82     std::shared_ptr<ConverterInterface<T, int32_t>> converter,
     83     std::map<int, T> default_values = {});
     84 
     85 // V4L2ControlOrDefault: Like V4L2Control, but if the V4L2Control fails to
     86 // initialize for some reason, this method will fall back to NoEffectControl
     87 // with an initial value defined by |fallback_default|.
     88 template <typename T>
     89 static std::unique_ptr<Control<T>> V4L2ControlOrDefault(
     90     ControlType type,
     91     int32_t delegate_tag,
     92     int32_t options_tag,
     93     std::shared_ptr<V4L2Wrapper> device,
     94     int control_id,
     95     std::shared_ptr<ConverterInterface<T, int32_t>> converter,
     96     T fallback_default,
     97     std::map<int, T> default_values = {});
     98 
     99 // -----------------------------------------------------------------------------
    100 
    101 template <typename T>
    102 std::unique_ptr<State<T>> FixedState(int32_t tag, T value) {
    103   HAL_LOG_ENTER();
    104 
    105   // Take advantage of ControlDelegate inheriting from StateDelegate;
    106   // This will only expose GetValue, not SetValue, so the default will
    107   // always be returned.
    108   return std::make_unique<State<T>>(
    109       tag, std::make_unique<NoEffectControlDelegate<T>>(value));
    110 }
    111 
    112 template <typename T>
    113 std::unique_ptr<Control<T>> NoEffectOptionlessControl(int32_t delegate_tag,
    114                                                       T default_value) {
    115   HAL_LOG_ENTER();
    116 
    117   return std::make_unique<Control<T>>(
    118       std::make_unique<TaggedControlDelegate<T>>(
    119           delegate_tag,
    120           std::make_unique<NoEffectControlDelegate<T>>(default_value)),
    121       nullptr);
    122 }
    123 
    124 template <typename T>
    125 std::unique_ptr<Control<T>> NoEffectMenuControl(
    126     int32_t delegate_tag,
    127     int32_t options_tag,
    128     const std::vector<T>& options,
    129     std::map<int, T> default_values) {
    130   HAL_LOG_ENTER();
    131 
    132   if (options.empty()) {
    133     HAL_LOGE("At least one option must be provided.");
    134     return nullptr;
    135   }
    136 
    137   return std::make_unique<Control<T>>(
    138       std::make_unique<TaggedControlDelegate<T>>(
    139           delegate_tag,
    140           std::make_unique<NoEffectControlDelegate<T>>(options[0])),
    141       std::make_unique<TaggedControlOptions<T>>(
    142           options_tag,
    143           std::make_unique<MenuControlOptions<T>>(options, default_values)));
    144 }
    145 
    146 template <typename T>
    147 std::unique_ptr<Control<T>> NoEffectSliderControl(
    148     int32_t delegate_tag,
    149     int32_t options_tag,
    150     T min,
    151     T max,
    152     std::map<int, T> default_values) {
    153   HAL_LOG_ENTER();
    154 
    155   return std::make_unique<Control<T>>(
    156       std::make_unique<TaggedControlDelegate<T>>(
    157           delegate_tag, std::make_unique<NoEffectControlDelegate<T>>(min)),
    158       std::make_unique<TaggedControlOptions<T>>(
    159           options_tag,
    160           std::make_unique<SliderControlOptions<T>>(min, max, default_values)));
    161 }
    162 
    163 template <typename T>
    164 std::unique_ptr<Control<T>> NoEffectControl(ControlType type,
    165                                             int32_t delegate_tag,
    166                                             int32_t options_tag,
    167                                             T value,
    168                                             std::map<int, T> default_values) {
    169   HAL_LOG_ENTER();
    170 
    171   switch (type) {
    172     case ControlType::kMenu:
    173       return NoEffectMenuControl<T>(
    174           delegate_tag, options_tag, {value}, default_values);
    175     case ControlType::kSlider:
    176       return NoEffectSliderControl(
    177           delegate_tag, options_tag, value, value, default_values);
    178   }
    179 }
    180 
    181 template <typename T>
    182 std::unique_ptr<Control<T>> V4L2Control(
    183     ControlType type,
    184     int32_t delegate_tag,
    185     int32_t options_tag,
    186     std::shared_ptr<V4L2Wrapper> device,
    187     int control_id,
    188     std::shared_ptr<ConverterInterface<T, int32_t>> converter,
    189     std::map<int, T> default_values) {
    190   HAL_LOG_ENTER();
    191 
    192   // Query the device.
    193   v4l2_query_ext_ctrl control_query;
    194   int res = device->QueryControl(control_id, &control_query);
    195   if (res) {
    196     HAL_LOGE("Failed to query control %d.", control_id);
    197     return nullptr;
    198   }
    199 
    200   int32_t control_min = static_cast<int32_t>(control_query.minimum);
    201   int32_t control_max = static_cast<int32_t>(control_query.maximum);
    202   int32_t control_step = static_cast<int32_t>(control_query.step);
    203   if (control_min > control_max) {
    204     HAL_LOGE("No acceptable values (min %d is greater than max %d).",
    205              control_min,
    206              control_max);
    207     return nullptr;
    208   }
    209 
    210   // Variables needed by the various switch statements.
    211   std::vector<T> options;
    212   T metadata_val;
    213   T metadata_min;
    214   T metadata_max;
    215   // Set up the result converter and result options based on type.
    216   std::shared_ptr<ConverterInterface<T, int32_t>> result_converter(converter);
    217   std::unique_ptr<ControlOptionsInterface<T>> result_options;
    218   switch (control_query.type) {
    219     case V4L2_CTRL_TYPE_BOOLEAN:
    220       if (type != ControlType::kMenu) {
    221         HAL_LOGE(
    222             "V4L2 control %d is of type %d, which isn't compatible with "
    223             "desired metadata control type %d",
    224             control_id,
    225             control_query.type,
    226             type);
    227         return nullptr;
    228       }
    229 
    230       // Convert each available option,
    231       // ignoring ones without a known conversion.
    232       for (int32_t i = control_min; i <= control_max; i += control_step) {
    233         res = converter->V4L2ToMetadata(i, &metadata_val);
    234         if (res == -EINVAL) {
    235           HAL_LOGV("V4L2 value %d for control %d has no metadata equivalent.",
    236                    i,
    237                    control_id);
    238           continue;
    239         } else if (res) {
    240           HAL_LOGE("Error converting value %d for control %d.", i, control_id);
    241           return nullptr;
    242         }
    243         options.push_back(metadata_val);
    244       }
    245       // Check to make sure there's at least one option.
    246       if (options.empty()) {
    247         HAL_LOGE("No valid options for control %d.", control_id);
    248         return nullptr;
    249       }
    250 
    251       result_options.reset(new MenuControlOptions<T>(options, default_values));
    252       // No converter changes necessary.
    253       break;
    254     case V4L2_CTRL_TYPE_INTEGER:
    255       if (type != ControlType::kSlider) {
    256         HAL_LOGE(
    257             "V4L2 control %d is of type %d, which isn't compatible with "
    258             "desired metadata control type %d",
    259             control_id,
    260             control_query.type,
    261             type);
    262         return nullptr;
    263       }
    264 
    265       // Upgrade to a range/step-clamping converter.
    266       result_converter.reset(new RangedConverter<T, int32_t>(
    267           converter, control_min, control_max, control_step));
    268 
    269       // Convert the min and max.
    270       res = result_converter->V4L2ToMetadata(control_min, &metadata_min);
    271       if (res) {
    272         HAL_LOGE(
    273             "Failed to convert V4L2 min value %d for control %d to metadata.",
    274             control_min,
    275             control_id);
    276         return nullptr;
    277       }
    278       res = result_converter->V4L2ToMetadata(control_max, &metadata_max);
    279       if (res) {
    280         HAL_LOGE(
    281             "Failed to convert V4L2 max value %d for control %d to metadata.",
    282             control_max,
    283             control_id);
    284         return nullptr;
    285       }
    286       result_options.reset(new SliderControlOptions<T>(
    287           metadata_min, metadata_max, default_values));
    288       break;
    289     default:
    290       HAL_LOGE("Control %d (%s) is of unsupported type %d",
    291                control_id,
    292                control_query.name,
    293                control_query.type);
    294       return nullptr;
    295   }
    296 
    297   // Construct the control.
    298   return std::make_unique<Control<T>>(
    299       std::make_unique<TaggedControlDelegate<T>>(
    300           delegate_tag,
    301           std::make_unique<V4L2ControlDelegate<T>>(
    302               device, control_id, result_converter)),
    303       std::make_unique<TaggedControlOptions<T>>(options_tag,
    304                                                 std::move(result_options)));
    305 }
    306 
    307 template <typename T>
    308 std::unique_ptr<Control<T>> V4L2ControlOrDefault(
    309     ControlType type,
    310     int32_t delegate_tag,
    311     int32_t options_tag,
    312     std::shared_ptr<V4L2Wrapper> device,
    313     int control_id,
    314     std::shared_ptr<ConverterInterface<T, int32_t>> converter,
    315     T fallback_default,
    316     std::map<int, T> default_values) {
    317   HAL_LOG_ENTER();
    318 
    319   std::unique_ptr<Control<T>> result = V4L2Control(type,
    320                                                    delegate_tag,
    321                                                    options_tag,
    322                                                    device,
    323                                                    control_id,
    324                                                    converter,
    325                                                    default_values);
    326   if (!result) {
    327     result = NoEffectControl(
    328         type, delegate_tag, options_tag, fallback_default, default_values);
    329   }
    330   return result;
    331 }
    332 
    333 }  // namespace v4l2_camera_hal
    334 
    335 #endif  // V4L2_CAMERA_HAL_METADATA_CONTROL_FACTORY_H_
    336