1 /* 2 * Copyright 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 #ifndef HDR_PLUS_TYPES_H 17 #define HDR_PLUS_TYPES_H 18 19 #include <array> 20 #include <stdint.h> 21 #include <string> 22 #include <vector> 23 24 namespace pbcamera { 25 26 // This file defines the common types used in HDR+ client and HDR+ service API. 27 28 typedef int32_t status_t; 29 30 /* 31 * ImageConfiguration and PlaneConfiguration define the layout of a buffer. 32 * The following is an example of a NV21 buffer. 33 * 34 * <-------Y stride (in bytes)-------> 35 * <----width (in pixels)----> 36 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ 37 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 38 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 39 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . height Y scanline 40 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . (in lines) (in lines) 41 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 42 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 43 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 44 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | 45 * Y Y Y Y Y Y Y Y Y Y Y Y Y Y . . . . v | 46 * . . . . . . . . . . . . . . . . . . | 47 * . . . . . . . . . . . . . . . . . . v 48 * <------V/U stride (in bytes)------> 49 * V U V U V U V U V U V U V U . . . . ^ 50 * V U V U V U V U V U V U V U . . . . | 51 * V U V U V U V U V U V U V U . . . . | 52 * V U V U V U V U V U V U V U . . . . V/U scanline 53 * V U V U V U V U V U V U V U . . . . (in lines) 54 * . . . . . . . . . . . . . . . . . . | 55 * . . . . . . . . . . . . . . . . . . v 56 * . . . . . . . . . . . . . . . . . . -> Image padding. 57 */ 58 59 // PlaneConfiguration defines an image planes configuration. 60 struct PlaneConfiguration { 61 // Number of bytes in each line including padding. 62 uint32_t stride; 63 // Number of lines vertically including padding. 64 uint32_t scanline; 65 PlaneConfigurationPlaneConfiguration66 PlaneConfiguration() : stride(0), scanline(0) {}; 67 68 bool operator==(const PlaneConfiguration &other) const { 69 return stride == other.stride && 70 scanline == other.scanline; 71 } 72 73 bool operator!=(const PlaneConfiguration &other) const { 74 return !(*this == other); 75 } 76 }; 77 78 // ImageConfiguration defines an image configuration. 79 struct ImageConfiguration { 80 // Image width. 81 uint32_t width; 82 // Image height; 83 uint32_t height; 84 // Image format; 85 int format; 86 // Configuration for each planes. 87 std::vector<PlaneConfiguration> planes; 88 // Number of padded bytes after the last plane. 89 uint32_t padding; 90 ImageConfigurationImageConfiguration91 ImageConfiguration() : width(0), height(0), format(0), padding(0) {}; 92 93 bool operator==(const ImageConfiguration &other) const { 94 return width == other.width && 95 height == other.height && 96 format == other.format && 97 planes == other.planes && 98 padding == other.padding; 99 } 100 101 bool operator!=(const ImageConfiguration &other) const { 102 return !(*this == other); 103 } 104 }; 105 106 /* 107 * StreamConfiguration defines a stream's configuration, such as its image buffer resolution, used 108 * during stream configuration. 109 */ 110 struct StreamConfiguration { 111 /* 112 * Unique ID of the stream. Each stream must have an unique ID so it can be used to identify 113 * the output streams of a StreamBuffer in CaptureRequest. 114 */ 115 uint32_t id; 116 117 // Image configuration. 118 ImageConfiguration image; 119 120 bool operator==(const StreamConfiguration &other) const { 121 return id == other.id && 122 image == other.image; 123 } 124 125 bool operator!=(const StreamConfiguration &other) const { 126 return !(*this == other); 127 } 128 }; 129 130 /* 131 * SensorMode contains the sensor mode information. 132 */ 133 struct SensorMode { 134 // Usually 0 is back camera and 1 is front camera. 135 uint32_t cameraId; 136 137 // Pixel array resolution. 138 uint32_t pixelArrayWidth; 139 uint32_t pixelArrayHeight; 140 141 // Active array resolution. 142 uint32_t activeArrayWidth; 143 uint32_t activeArrayHeight; 144 145 // Sensor output pixel clock. 146 uint32_t outputPixelClkHz; 147 148 // Sensor timestamp offset due to gyro calibration. When comparing timestamps between AP and 149 // Easel, this offset should be subtracted from AP timestamp. 150 int64_t timestampOffsetNs; 151 152 // Sensor timestamp offset due to sensor cropping. When comparing timestamps between AP and 153 // Easel, this offset should be subtracted from AP timestamp. 154 int64_t timestampCropOffsetNs; 155 156 // Sensor output format as defined in android_pixel_format. 157 int format; 158 SensorModeSensorMode159 SensorMode() : cameraId(0), pixelArrayWidth(0), pixelArrayHeight(0), activeArrayWidth(0), 160 activeArrayHeight(0), outputPixelClkHz(0) {}; 161 }; 162 163 /* 164 * InputConfiguration defines the input configuration for HDR+ service. 165 */ 166 struct InputConfiguration { 167 // Whether the input frames come from sensor MIPI or AP. If true, HDR+ service will get input 168 // frames from sensor and sensorMode contains the sensor mode information. If false, HDR+ 169 // service will get input frames from AP and streamConfig contains the input stream 170 // configuration. 171 bool isSensorInput; 172 // Sensor mode if isSensorInput is true. 173 SensorMode sensorMode; 174 // Input stream configuration if isSensorInput is false. 175 StreamConfiguration streamConfig; 176 InputConfigurationInputConfiguration177 InputConfiguration() : isSensorInput(false) {}; 178 }; 179 180 /* 181 * StreamBuffer defines a buffer in a stream. 182 */ 183 struct StreamBuffer { 184 // ID of the stream that this buffer belongs to. 185 uint32_t streamId; 186 // DMA buffer fd for this buffer if it's an ION buffer. 187 int32_t dmaBufFd; 188 // Pointer to the data of this buffer. 189 void* data; 190 // Size of the allocated data. 191 uint32_t dataSize; 192 }; 193 194 /* 195 * CaptureRequest defines a capture request that HDR+ client sends to HDR+ service. 196 */ 197 struct CaptureRequest { 198 /* 199 * ID of the capture request. Each capture request must have an unique ID. When HDR+ service 200 * sends a CaptureResult to HDR+ client for this request, CaptureResult.requestId will be 201 * assigned to this ID. 202 */ 203 uint32_t id; 204 /* 205 * Output buffers of the request. The buffers will be filled with captured image when HDR+ 206 * service sends the output buffers in CaptureResult. 207 */ 208 std::vector<StreamBuffer> outputBuffers; 209 }; 210 211 // Util functions used in StaticMetadata and FrameMetadata. 212 namespace metadatautils { 213 template<typename T> 214 void appendValueToString(std::string *strOut, const char* key, T value); 215 216 template<typename T> 217 void appendVectorOrArrayToString(std::string *strOut, T values); 218 219 template<typename T> 220 void appendVectorOrArrayToString(std::string *strOut, const char* key, T values); 221 222 template<typename T, size_t SIZE> 223 void appendVectorArrayToString(std::string *strOut, const char* key, 224 std::vector<std::array<T, SIZE>> values); 225 226 template<typename T, size_t SIZE> 227 void appendArrayArrayToString(std::string *strOut, const char* key, 228 std::array<T, SIZE> values); 229 } // namespace metadatautils 230 231 static const uint32_t DEBUG_PARAM_NONE = 0u; 232 static const uint32_t DEBUG_PARAM_SAVE_GCAME_INPUT_METERING = (1u); 233 static const uint32_t DEBUG_PARAM_SAVE_GCAME_INPUT_PAYLOAD = (1u << 1); 234 static const uint32_t DEBUG_PARAM_SAVE_GCAME_TEXT = (1u << 2); 235 static const uint32_t DEBUG_PARAM_SAVE_PROFILE = (1u << 3); 236 static const uint32_t DEBUG_PARAM_SAVE_GCAME_IPU_WATERMARK = (1u << 4); 237 238 /* 239 * StaticMetadata defines a camera device's characteristics. 240 * 241 * If this structure is changed, serialization in MessengerToHdrPlusService and deserialization in 242 * MessengerListenerFromHdrPlusClient should also be updated. 243 */ 244 struct StaticMetadata { 245 // The following are from Android Camera Metadata 246 uint8_t flashInfoAvailable; // android.flash.info.available 247 std::array<int32_t, 2> sensitivityRange; // android.sensor.info.sensitivityRange 248 int32_t maxAnalogSensitivity; // android.sensor.maxAnalogSensitivity 249 std::array<int32_t, 2> pixelArraySize; // android.sensor.info.pixelArraySize 250 std::array<int32_t, 4> activeArraySize; // android.sensor.info.activeArraySize 251 std::vector<std::array<int32_t, 4>> opticalBlackRegions; // android.sensor.opticalBlackRegions 252 // android.scaler.availableStreamConfigurations 253 std::vector<std::array<int32_t, 4>> availableStreamConfigurations; 254 uint8_t referenceIlluminant1; // android.sensor.referenceIlluminant1 255 uint8_t referenceIlluminant2; // android.sensor.referenceIlluminant2 256 std::array<float, 9> calibrationTransform1; // android.sensor.calibrationTransform1 257 std::array<float, 9> calibrationTransform2; // android.sensor.calibrationTransform2 258 std::array<float, 9> colorTransform1; // android.sensor.colorTransform1 259 std::array<float, 9> colorTransform2; // android.sensor.colorTransform2 260 int32_t whiteLevel; // android.sensor.info.whiteLevel 261 uint8_t colorFilterArrangement; // android.sensor.info.colorFilterArrangement 262 std::vector<float> availableApertures; // android.lens.info.availableApertures 263 std::vector<float> availableFocalLengths; // android.lens.info.availableFocalLengths 264 std::array<int32_t, 2> shadingMapSize; // android.lens.info.shadingMapSize 265 uint8_t focusDistanceCalibration; // android.lens.info.focusDistanceCalibration 266 std::array<int32_t, 2> aeCompensationRange; // android.control.aeCompensationRange 267 float aeCompensationStep; // android.control.aeCompensationStep 268 269 uint32_t debugParams; // Use HDRPLUS_DEBUG_PARAM_* 270 271 // Convert this static metadata to a string and append it to the specified string. appendToStringStaticMetadata272 void appendToString(std::string *strOut) const { 273 if (strOut == nullptr) return; 274 275 metadatautils::appendValueToString(strOut, "flashInfoAvailable", flashInfoAvailable); 276 metadatautils::appendVectorOrArrayToString(strOut, "sensitivityRange", sensitivityRange); 277 metadatautils::appendValueToString(strOut, "maxAnalogSensitivity", maxAnalogSensitivity); 278 metadatautils::appendVectorOrArrayToString(strOut, "pixelArraySize", pixelArraySize); 279 metadatautils::appendVectorOrArrayToString(strOut, "activeArraySize", activeArraySize); 280 metadatautils::appendVectorArrayToString(strOut, "opticalBlackRegions", 281 opticalBlackRegions); 282 metadatautils::appendVectorArrayToString(strOut, "availableStreamConfigurations", 283 availableStreamConfigurations); 284 metadatautils::appendValueToString(strOut, "referenceIlluminant1", referenceIlluminant1); 285 metadatautils::appendValueToString(strOut, "referenceIlluminant2", referenceIlluminant2); 286 metadatautils::appendVectorOrArrayToString(strOut, "calibrationTransform1", 287 calibrationTransform1); 288 metadatautils::appendVectorOrArrayToString(strOut, "calibrationTransform2", 289 calibrationTransform2); 290 metadatautils::appendVectorOrArrayToString(strOut, "colorTransform1", colorTransform1); 291 metadatautils::appendVectorOrArrayToString(strOut, "colorTransform2", colorTransform2); 292 metadatautils::appendValueToString(strOut, "whiteLevel", whiteLevel); 293 metadatautils::appendValueToString(strOut, "colorFilterArrangement", 294 colorFilterArrangement); 295 metadatautils::appendVectorOrArrayToString(strOut, "availableApertures", 296 availableApertures); 297 metadatautils::appendVectorOrArrayToString(strOut, "availableFocalLengths", 298 availableFocalLengths); 299 metadatautils::appendVectorOrArrayToString(strOut, "shadingMapSize", shadingMapSize); 300 metadatautils::appendValueToString(strOut, "focusDistanceCalibration", 301 focusDistanceCalibration); 302 metadatautils::appendVectorOrArrayToString(strOut, "aeCompensationRange", 303 aeCompensationRange); 304 metadatautils::appendValueToString(strOut, "aeCompensationStep", 305 aeCompensationStep); 306 metadatautils::appendValueToString(strOut, "debugParams", debugParams); 307 } 308 }; 309 310 /* 311 * FrameMetadata defines properties of a frame captured on AP. 312 * 313 * If this structure is changed, serialization in MessengerToHdrPlusService and deserialization in 314 * MessengerListenerFromHdrPlusClient should also be updated. 315 */ 316 struct FrameMetadata { 317 int64_t easelTimestamp; // Easel timestamp 318 319 // The following are from Android Camera Metadata 320 int64_t exposureTime; // android.sensor.exposureTime 321 int32_t sensitivity; // android.sensor.sensitivity 322 int32_t postRawSensitivityBoost; // android.control.postRawSensitivityBoost 323 uint8_t flashMode; // android.flash.mode 324 std::array<float, 4> colorCorrectionGains; // android.colorCorrection.gains 325 std::array<float, 9> colorCorrectionTransform; // android.colorCorrection.transform 326 std::array<float, 3> neutralColorPoint; // android.sensor.neutralColorPoint 327 int64_t timestamp; // android.sensor.timestamp 328 uint8_t blackLevelLock; // android.blackLevel.lock 329 uint8_t faceDetectMode; // android.statistics.faceDetectMode 330 std::vector<int32_t> faceIds; // android.statistics.faceIds 331 std::vector<std::array<int32_t, 6>> faceLandmarks; // android.statistics.faceLandmarks 332 std::vector<std::array<int32_t, 4>> faceRectangles; // android.statistics.faceRectangles 333 std::vector<uint8_t> faceScores; // android.statistics.faceScores 334 uint8_t sceneFlicker; // android.statistics.sceneFlicker 335 std::array<std::array<double, 2>, 4> noiseProfile; // android.sensor.noiseProfile 336 std::array<float, 4> dynamicBlackLevel; // android.sensor.dynamicBlackLevel 337 std::vector<float> lensShadingMap; // android.statistics.lensShadingMap 338 float focusDistance; // android.lens.focusDistance 339 int32_t aeExposureCompensation; // android.control.aeExposureCompensation 340 uint8_t aeMode; // android.control.aeMode 341 uint8_t aeLock; // android.control.aeLock 342 uint8_t aeState; // android.control.aeState 343 uint8_t aePrecaptureTrigger; // android.control.aePrecaptureTrigger 344 std::vector<std::array<int32_t, 5>> aeRegions; // android.control.aeRegions 345 346 // Convert this static metadata to a string and append it to the specified string. appendToStringFrameMetadata347 void appendToString(std::string *strOut) const { 348 if (strOut == nullptr) return; 349 350 metadatautils::appendValueToString(strOut, "easelTimestamp", easelTimestamp); 351 metadatautils::appendValueToString(strOut, "exposureTime", exposureTime); 352 metadatautils::appendValueToString(strOut, "sensitivity", sensitivity); 353 metadatautils::appendValueToString(strOut, "postRawSensitivityBoost", 354 postRawSensitivityBoost); 355 metadatautils::appendValueToString(strOut, "flashMode", flashMode); 356 metadatautils::appendVectorOrArrayToString(strOut, "colorCorrectionGains", 357 colorCorrectionGains); 358 metadatautils::appendVectorOrArrayToString(strOut, "colorCorrectionTransform", 359 colorCorrectionTransform); 360 metadatautils::appendVectorOrArrayToString(strOut, "neutralColorPoint", neutralColorPoint); 361 metadatautils::appendValueToString(strOut, "timestamp", timestamp); 362 metadatautils::appendValueToString(strOut, "blackLevelLock", blackLevelLock); 363 metadatautils::appendValueToString(strOut, "faceDetectMode", faceDetectMode); 364 metadatautils::appendVectorOrArrayToString(strOut, "faceIds", faceIds); 365 metadatautils::appendVectorArrayToString(strOut, "faceLandmarks", faceLandmarks); 366 metadatautils::appendVectorArrayToString(strOut, "faceRectangles", faceRectangles); 367 metadatautils::appendVectorOrArrayToString(strOut, "faceScores", faceScores); 368 metadatautils::appendArrayArrayToString(strOut, "noiseProfile", noiseProfile); 369 metadatautils::appendValueToString(strOut, "sceneFlicker", sceneFlicker); 370 metadatautils::appendVectorOrArrayToString(strOut, "dynamicBlackLevel", dynamicBlackLevel); 371 metadatautils::appendVectorOrArrayToString(strOut, "lensShadingMap", lensShadingMap); 372 metadatautils::appendValueToString(strOut, "focusDistance", focusDistance); 373 metadatautils::appendValueToString(strOut, "aeExposureCompensation", aeExposureCompensation); 374 metadatautils::appendValueToString(strOut, "aeMode", aeMode); 375 metadatautils::appendValueToString(strOut, "aeLock", aeLock); 376 metadatautils::appendValueToString(strOut, "aeState", aeState); 377 metadatautils::appendValueToString(strOut, "aePrecaptureTrigger", aePrecaptureTrigger); 378 metadatautils::appendVectorArrayToString(strOut, "aeRegions", aeRegions); 379 } 380 }; 381 382 /* 383 * RequestMetadata defines the properties for a capture request. 384 * 385 * If this structure is changed, serialization in MessengerToHdrPlusClient and deserialization in 386 * MessengerListenerFromHdrPlusService should also be updated. 387 */ 388 struct RequestMetadata { 389 std::array<int32_t, 4> cropRegion; // android.scaler.cropRegion (x_min, y_min, width, height) 390 int32_t aeExposureCompensation; // android.control.aeExposureCompensation 391 392 bool postviewEnable; // com.google.nexus.experimental2017.stats.postview_enable 393 bool continuousCapturing; // Whether to capture RAW while HDR+ processing. 394 395 // Convert this static metadata to a string and append it to the specified string. appendToStringRequestMetadata396 void appendToString(std::string *strOut) const { 397 if (strOut == nullptr) return; 398 metadatautils::appendVectorOrArrayToString(strOut, "cropRegion", cropRegion); 399 metadatautils::appendValueToString(strOut, "aeExposureCompensation", aeExposureCompensation); 400 metadatautils::appendValueToString(strOut, "postviewEnable", postviewEnable); 401 metadatautils::appendValueToString(strOut, "continuousCapturing", continuousCapturing); 402 } 403 }; 404 405 /* 406 * ResultMetadata defines a process frame's properties that have been modified due to processing. 407 * 408 * If this structure is changed, serialization in MessengerToHdrPlusClient and deserialization in 409 * MessengerListenerFromHdrPlusService should also be updated. 410 */ 411 struct ResultMetadata { 412 int64_t easelTimestamp; // Easel timestamp of SOF of the base frame. 413 int64_t timestamp; // android.sensor.timestamp. AP timestamp of exposure start of the base 414 // frame. 415 std::string makernote; // Obfuscated capture information. 416 417 // Convert this static metadata to a string and append it to the specified string. appendToStringResultMetadata418 void appendToString(std::string *strOut) const { 419 if (strOut == nullptr) return; 420 metadatautils::appendValueToString(strOut, "easelTimestamp", easelTimestamp); 421 metadatautils::appendValueToString(strOut, "timestamp", timestamp); 422 metadatautils::appendValueToString(strOut, "makernote", makernote.size()); 423 } 424 }; 425 426 /* 427 * CaptureResult defines a capture result that HDR+ service returns to HDR+ client. 428 */ 429 struct CaptureResult { 430 /* 431 * ID of the CaptureRequest that this capture result corresponds to. It can be used to match 432 * the original CaptureRequest when the HDR+ client receives this result. 433 */ 434 uint32_t requestId; 435 /* 436 * Output buffers filled with processed frame by HDR+ service. 437 */ 438 std::vector<StreamBuffer> outputBuffers; 439 440 /* 441 * Result metadata including modified properties due to processing. 442 */ 443 ResultMetadata metadata; 444 }; 445 446 // Util functions used in StaticMetadata and FrameMetadata. 447 namespace metadatautils { 448 449 /* 450 * Append a key and a value to a string. 451 * 452 * strOut is the string to append a key and a value to. 453 * key is the name of the data. 454 * value is the value of the data. 455 */ 456 template<typename T> appendValueToString(std::string * strOut,const char * key,T value)457 void appendValueToString(std::string *strOut, const char* key, T value) { 458 if (strOut == nullptr) return; 459 (*strOut) += std::string(key) + ": " + std::to_string(value) + "\n"; 460 } 461 462 /* 463 * Append a vector or an array of values to a string. 464 * 465 * strOut is the string to append a key and values to. 466 * values is a vector or an array containing values to append to the string. 467 */ 468 template<typename T> appendVectorOrArrayToString(std::string * strOut,T values)469 void appendVectorOrArrayToString(std::string *strOut, T values) { 470 if (strOut == nullptr) return; 471 for (size_t i = 0; i < values.size(); i++) { 472 (*strOut) += std::to_string(values[i]); 473 if (i != values.size() - 1) { 474 (*strOut) +=", "; 475 } 476 } 477 } 478 479 /* 480 * Append a key and a vector or an array of values to a string. 481 * 482 * strOut is the string to append a key and values to. 483 * key is the name of the data. 484 * values is a vector or an array containing values to append to the string. 485 */ 486 template<typename T> appendVectorOrArrayToString(std::string * strOut,const char * key,T values)487 void appendVectorOrArrayToString(std::string *strOut, const char* key, T values) { 488 if (strOut == nullptr) return; 489 (*strOut) += std::string(key) + ": "; 490 appendVectorOrArrayToString(strOut, values); 491 (*strOut) += "\n"; 492 } 493 494 /* 495 * Append a key and a vector of arrays to a string. 496 * 497 * strOut is the string to append a key and values to. 498 * key is the name of the data. 499 * values is a vector of arrays containing values to append to the string. 500 */ 501 template<typename T, size_t SIZE> appendVectorArrayToString(std::string * strOut,const char * key,std::vector<std::array<T,SIZE>> values)502 void appendVectorArrayToString(std::string *strOut, const char* key, 503 std::vector<std::array<T, SIZE>> values) { 504 if (strOut == nullptr) return; 505 (*strOut) += std::string(key) + ": "; 506 for (size_t i = 0; i < values.size(); i++) { 507 appendVectorOrArrayToString(strOut, values[i]); 508 if (i != values.size() - 1) { 509 (*strOut) +=", "; 510 } 511 } 512 (*strOut) += "\n"; 513 } 514 515 /* 516 * Append a key and an array of arrays to a string. 517 * 518 * strOut is the string to append a key and values to. 519 * key is the name of the data. 520 * values is an array of arrays containing values to append to the string. 521 */ 522 template<typename T, size_t SIZE> appendArrayArrayToString(std::string * strOut,const char * key,std::array<T,SIZE> values)523 void appendArrayArrayToString(std::string *strOut, const char* key, 524 std::array<T, SIZE> values) { 525 if (strOut == nullptr) return; 526 (*strOut) += std::string(key) + ": "; 527 for (size_t i = 0; i < values.size(); i++) { 528 appendVectorOrArrayToString(strOut, values[i]); 529 if (i != values.size() - 1) { 530 (*strOut) +=", "; 531 } 532 } 533 (*strOut) += "\n"; 534 } 535 536 } // namespace metadatautils 537 538 } // namespace pbcamera 539 540 #endif // HDR_PLUS_TYPES_H 541