Camera.cpp revision c6bf2f291ddca5e8807268f89733e9f6637b4303
1/* 2 * Copyright (C) 2012 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#include <cstdlib> 18#include <pthread.h> 19#include <hardware/camera3.h> 20#include <sync/sync.h> 21#include <system/camera_metadata.h> 22#include <system/graphics.h> 23#include "CameraHAL.h" 24#include "Metadata.h" 25#include "Stream.h" 26 27//#define LOG_NDEBUG 0 28#define LOG_TAG "Camera" 29#include <cutils/log.h> 30 31#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL) 32#include <cutils/trace.h> 33#include "ScopedTrace.h" 34 35#include "Camera.h" 36 37#define CAMERA_SYNC_TIMEOUT 5000 // in msecs 38 39#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 40 41namespace default_camera_hal { 42 43extern "C" { 44// Shim passed to the framework to close an opened device. 45static int close_device(hw_device_t* dev) 46{ 47 camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev); 48 Camera* cam = static_cast<Camera*>(cam_dev->priv); 49 return cam->close(); 50} 51} // extern "C" 52 53Camera::Camera(int id) 54 : mId(id), 55 mStaticInfo(NULL), 56 mBusy(false), 57 mCallbackOps(NULL), 58 mStreams(NULL), 59 mNumStreams(0), 60 mSettings(NULL) 61{ 62 pthread_mutex_init(&mMutex, 63 NULL); // No pthread mutex attributes. 64 65 memset(&mDevice, 0, sizeof(mDevice)); 66 mDevice.common.tag = HARDWARE_DEVICE_TAG; 67 mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_0; 68 mDevice.common.close = close_device; 69 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps); 70 mDevice.priv = this; 71} 72 73Camera::~Camera() 74{ 75} 76 77int Camera::open(const hw_module_t *module, hw_device_t **device) 78{ 79 ALOGI("%s:%d: Opening camera device", __func__, mId); 80 CAMTRACE_CALL(); 81 pthread_mutex_lock(&mMutex); 82 if (mBusy) { 83 pthread_mutex_unlock(&mMutex); 84 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId); 85 return -EBUSY; 86 } 87 88 // TODO: open camera dev nodes, etc 89 mBusy = true; 90 mDevice.common.module = const_cast<hw_module_t*>(module); 91 *device = &mDevice.common; 92 93 pthread_mutex_unlock(&mMutex); 94 return 0; 95} 96 97int Camera::getInfo(struct camera_info *info) 98{ 99 int ret = 0; 100 101 info->facing = CAMERA_FACING_FRONT; 102 info->orientation = 0; 103 info->device_version = mDevice.common.version; 104 105 pthread_mutex_lock(&mMutex); 106 if (mStaticInfo == NULL) { 107 ret = initStaticInfo(); 108 } 109 pthread_mutex_unlock(&mMutex); 110 111 info->static_camera_characteristics = mStaticInfo; 112 113 return ret; 114} 115 116int Camera::close() 117{ 118 ALOGI("%s:%d: Closing camera device", __func__, mId); 119 CAMTRACE_CALL(); 120 pthread_mutex_lock(&mMutex); 121 if (!mBusy) { 122 pthread_mutex_unlock(&mMutex); 123 ALOGE("%s:%d: Error! Camera device not open", __func__, mId); 124 return -EINVAL; 125 } 126 127 // TODO: close camera dev nodes, etc 128 mBusy = false; 129 130 pthread_mutex_unlock(&mMutex); 131 return 0; 132} 133 134int Camera::initialize(const camera3_callback_ops_t *callback_ops) 135{ 136 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops); 137 mCallbackOps = callback_ops; 138 return 0; 139} 140 141int Camera::initStaticInfo() 142{ 143 /* 144 * Setup static camera info. This will have to customized per camera 145 * device. 146 */ 147 148 /* android.control */ 149 int32_t android_control_ae_available_target_fps_ranges[] = {30, 30}; 150 mMetadata.addInt32(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 151 ARRAY_SIZE(android_control_ae_available_target_fps_ranges), 152 android_control_ae_available_target_fps_ranges); 153 154 int32_t android_control_ae_compensation_range[] = {-4, 4}; 155 mMetadata.addInt32(ANDROID_CONTROL_AE_COMPENSATION_RANGE, 156 ARRAY_SIZE(android_control_ae_compensation_range), 157 android_control_ae_compensation_range); 158 159 camera_metadata_rational_t android_control_ae_compensation_step[] = {{2,1}}; 160 mMetadata.addRational(ANDROID_CONTROL_AE_COMPENSATION_STEP, 161 ARRAY_SIZE(android_control_ae_compensation_step), 162 android_control_ae_compensation_step); 163 164 int32_t android_control_max_regions[] = {1}; 165 mMetadata.addInt32(ANDROID_CONTROL_MAX_REGIONS, 166 ARRAY_SIZE(android_control_max_regions), 167 android_control_max_regions); 168 169 /* android.jpeg */ 170 int32_t android_jpeg_available_thumbnail_sizes[] = {0, 0, 128, 96}; 171 mMetadata.addInt32(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 172 ARRAY_SIZE(android_jpeg_available_thumbnail_sizes), 173 android_jpeg_available_thumbnail_sizes); 174 175 /* android.lens */ 176 float android_lens_info_available_focal_lengths[] = {1.0}; 177 mMetadata.addFloat(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 178 ARRAY_SIZE(android_lens_info_available_focal_lengths), 179 android_lens_info_available_focal_lengths); 180 181 /* android.request */ 182 int32_t android_request_max_num_output_streams[] = {0, 3, 1}; 183 mMetadata.addInt32(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, 184 ARRAY_SIZE(android_request_max_num_output_streams), 185 android_request_max_num_output_streams); 186 187 /* android.scaler */ 188 int32_t android_scaler_available_formats[] = { 189 HAL_PIXEL_FORMAT_RAW_SENSOR, 190 HAL_PIXEL_FORMAT_BLOB, 191 HAL_PIXEL_FORMAT_RGBA_8888, 192 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 193 // These are handled by YCbCr_420_888 194 // HAL_PIXEL_FORMAT_YV12, 195 // HAL_PIXEL_FORMAT_YCrCb_420_SP, 196 HAL_PIXEL_FORMAT_YCbCr_420_888}; 197 mMetadata.addInt32(ANDROID_SCALER_AVAILABLE_FORMATS, 198 ARRAY_SIZE(android_scaler_available_formats), 199 android_scaler_available_formats); 200 201 int64_t android_scaler_available_jpeg_min_durations[] = {1}; 202 mMetadata.addInt64(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS, 203 ARRAY_SIZE(android_scaler_available_jpeg_min_durations), 204 android_scaler_available_jpeg_min_durations); 205 206 int32_t android_scaler_available_jpeg_sizes[] = {640, 480}; 207 mMetadata.addInt32(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 208 ARRAY_SIZE(android_scaler_available_jpeg_sizes), 209 android_scaler_available_jpeg_sizes); 210 211 float android_scaler_available_max_digital_zoom[] = {1}; 212 mMetadata.addFloat(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, 213 ARRAY_SIZE(android_scaler_available_max_digital_zoom), 214 android_scaler_available_max_digital_zoom); 215 216 int64_t android_scaler_available_processed_min_durations[] = {1}; 217 mMetadata.addInt64(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS, 218 ARRAY_SIZE(android_scaler_available_processed_min_durations), 219 android_scaler_available_processed_min_durations); 220 221 int32_t android_scaler_available_processed_sizes[] = {640, 480}; 222 mMetadata.addInt32(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 223 ARRAY_SIZE(android_scaler_available_processed_sizes), 224 android_scaler_available_processed_sizes); 225 226 int64_t android_scaler_available_raw_min_durations[] = {1}; 227 mMetadata.addInt64(ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS, 228 ARRAY_SIZE(android_scaler_available_raw_min_durations), 229 android_scaler_available_raw_min_durations); 230 231 int32_t android_scaler_available_raw_sizes[] = {640, 480}; 232 mMetadata.addInt32(ANDROID_SCALER_AVAILABLE_RAW_SIZES, 233 ARRAY_SIZE(android_scaler_available_raw_sizes), 234 android_scaler_available_raw_sizes); 235 236 /* android.sensor */ 237 238 int32_t android_sensor_info_active_array_size[] = {0, 0, 640, 480}; 239 mMetadata.addInt32(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, 240 ARRAY_SIZE(android_sensor_info_active_array_size), 241 android_sensor_info_active_array_size); 242 243 int32_t android_sensor_info_available_sensitivities[] = 244 {100, 200, 400, 800, 1600}; 245 mMetadata.addInt32(ANDROID_SENSOR_INFO_AVAILABLE_SENSITIVITIES, 246 ARRAY_SIZE(android_sensor_info_available_sensitivities), 247 android_sensor_info_available_sensitivities); 248 249 int64_t android_sensor_info_max_frame_duration[] = {30000000000}; 250 mMetadata.addInt64(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, 251 ARRAY_SIZE(android_sensor_info_max_frame_duration), 252 android_sensor_info_max_frame_duration); 253 254 float android_sensor_info_physical_size[] = {3.2, 2.4}; 255 mMetadata.addFloat(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 256 ARRAY_SIZE(android_sensor_info_physical_size), 257 android_sensor_info_physical_size); 258 259 int32_t android_sensor_info_pixel_array_size[] = {640, 480}; 260 mMetadata.addInt32(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, 261 ARRAY_SIZE(android_sensor_info_pixel_array_size), 262 android_sensor_info_pixel_array_size); 263 264 int32_t android_sensor_orientation[] = {0}; 265 mMetadata.addInt32(ANDROID_SENSOR_ORIENTATION, 266 ARRAY_SIZE(android_sensor_orientation), 267 android_sensor_orientation); 268 269 /* End of static camera characteristics */ 270 271 mStaticInfo = mMetadata.generate(); 272 273 return 0; 274} 275 276int Camera::configureStreams(camera3_stream_configuration_t *stream_config) 277{ 278 camera3_stream_t *astream; 279 Stream **newStreams = NULL; 280 281 CAMTRACE_CALL(); 282 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config); 283 284 if (stream_config == NULL) { 285 ALOGE("%s:%d: NULL stream configuration array", __func__, mId); 286 return -EINVAL; 287 } 288 if (stream_config->num_streams == 0) { 289 ALOGE("%s:%d: Empty stream configuration array", __func__, mId); 290 return -EINVAL; 291 } 292 293 // Create new stream array 294 newStreams = new Stream*[stream_config->num_streams]; 295 ALOGV("%s:%d: Number of Streams: %d", __func__, mId, 296 stream_config->num_streams); 297 298 pthread_mutex_lock(&mMutex); 299 300 // Mark all current streams unused for now 301 for (int i = 0; i < mNumStreams; i++) 302 mStreams[i]->mReuse = false; 303 // Fill new stream array with reused streams and new streams 304 for (unsigned int i = 0; i < stream_config->num_streams; i++) { 305 astream = stream_config->streams[i]; 306 if (astream->max_buffers > 0) 307 newStreams[i] = reuseStream(astream); 308 else 309 newStreams[i] = new Stream(mId, astream); 310 311 if (newStreams[i] == NULL) { 312 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i); 313 goto err_out; 314 } 315 astream->priv = newStreams[i]; 316 } 317 318 // Verify the set of streams in aggregate 319 if (!isValidStreamSet(newStreams, stream_config->num_streams)) { 320 ALOGE("%s:%d: Invalid stream set", __func__, mId); 321 goto err_out; 322 } 323 324 // Set up all streams (calculate usage/max_buffers for each) 325 setupStreams(newStreams, stream_config->num_streams); 326 327 // Destroy all old streams and replace stream array with new one 328 destroyStreams(mStreams, mNumStreams); 329 mStreams = newStreams; 330 mNumStreams = stream_config->num_streams; 331 332 // Clear out last seen settings metadata 333 setSettings(NULL); 334 335 pthread_mutex_unlock(&mMutex); 336 return 0; 337 338err_out: 339 // Clean up temporary streams, preserve existing mStreams/mNumStreams 340 destroyStreams(newStreams, stream_config->num_streams); 341 pthread_mutex_unlock(&mMutex); 342 return -EINVAL; 343} 344 345void Camera::destroyStreams(Stream **streams, int count) 346{ 347 if (streams == NULL) 348 return; 349 for (int i = 0; i < count; i++) { 350 // Only destroy streams that weren't reused 351 if (streams[i] != NULL && !streams[i]->mReuse) 352 delete streams[i]; 353 } 354 delete [] streams; 355} 356 357Stream *Camera::reuseStream(camera3_stream_t *astream) 358{ 359 Stream *priv = reinterpret_cast<Stream*>(astream->priv); 360 // Verify the re-used stream's parameters match 361 if (!priv->isValidReuseStream(mId, astream)) { 362 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId); 363 return NULL; 364 } 365 // Mark stream to be reused 366 priv->mReuse = true; 367 return priv; 368} 369 370bool Camera::isValidStreamSet(Stream **streams, int count) 371{ 372 int inputs = 0; 373 int outputs = 0; 374 375 if (streams == NULL) { 376 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId); 377 return false; 378 } 379 if (count == 0) { 380 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId); 381 return false; 382 } 383 // Validate there is at most one input stream and at least one output stream 384 for (int i = 0; i < count; i++) { 385 // A stream may be both input and output (bidirectional) 386 if (streams[i]->isInputType()) 387 inputs++; 388 if (streams[i]->isOutputType()) 389 outputs++; 390 } 391 if (outputs < 1) { 392 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId); 393 return false; 394 } 395 if (inputs > 1) { 396 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId); 397 return false; 398 } 399 // TODO: check for correct number of Bayer/YUV/JPEG/Encoder streams 400 return true; 401} 402 403void Camera::setupStreams(Stream **streams, int count) 404{ 405 /* 406 * This is where the HAL has to decide internally how to handle all of the 407 * streams, and then produce usage and max_buffer values for each stream. 408 * Note, the stream array has been checked before this point for ALL invalid 409 * conditions, so it must find a successful configuration for this stream 410 * array. The HAL may not return an error from this point. 411 * 412 * In this demo HAL, we just set all streams to be the same dummy values; 413 * real implementations will want to avoid USAGE_SW_{READ|WRITE}_OFTEN. 414 */ 415 for (int i = 0; i < count; i++) { 416 uint32_t usage = 0; 417 418 if (streams[i]->isOutputType()) 419 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN | 420 GRALLOC_USAGE_HW_CAMERA_WRITE; 421 if (streams[i]->isInputType()) 422 usage |= GRALLOC_USAGE_SW_READ_OFTEN | 423 GRALLOC_USAGE_HW_CAMERA_READ; 424 425 streams[i]->setUsage(usage); 426 streams[i]->setMaxBuffers(1); 427 } 428} 429 430int Camera::registerStreamBuffers(const camera3_stream_buffer_set_t *buf_set) 431{ 432 ALOGV("%s:%d: buffer_set=%p", __func__, mId, buf_set); 433 if (buf_set == NULL) { 434 ALOGE("%s:%d: NULL buffer set", __func__, mId); 435 return -EINVAL; 436 } 437 if (buf_set->stream == NULL) { 438 ALOGE("%s:%d: NULL stream handle", __func__, mId); 439 return -EINVAL; 440 } 441 Stream *stream = reinterpret_cast<Stream*>(buf_set->stream->priv); 442 return stream->registerBuffers(buf_set); 443} 444 445const camera_metadata_t* Camera::constructDefaultRequestSettings(int type) 446{ 447 ALOGV("%s:%d: type=%d", __func__, mId, type); 448 // TODO: return statically built default request 449 return NULL; 450} 451 452int Camera::processCaptureRequest(camera3_capture_request_t *request) 453{ 454 camera3_capture_result result; 455 456 ALOGV("%s:%d: request=%p", __func__, mId, request); 457 CAMTRACE_CALL(); 458 459 if (request == NULL) { 460 ALOGE("%s:%d: NULL request recieved", __func__, mId); 461 return -EINVAL; 462 } 463 464 ALOGV("%s:%d: Request Frame:%d Settings:%p", __func__, mId, 465 request->frame_number, request->settings); 466 467 // NULL indicates use last settings 468 if (request->settings == NULL) { 469 if (mSettings == NULL) { 470 ALOGE("%s:%d: NULL settings without previous set Frame:%d Req:%p", 471 __func__, mId, request->frame_number, request); 472 return -EINVAL; 473 } 474 } else { 475 setSettings(request->settings); 476 } 477 478 if (request->input_buffer != NULL) { 479 ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId, 480 request->input_buffer); 481 482 if (!isValidReprocessSettings(request->settings)) { 483 ALOGE("%s:%d: Invalid settings for reprocess request: %p", 484 __func__, mId, request->settings); 485 return -EINVAL; 486 } 487 } else { 488 ALOGV("%s:%d: Capturing new frame.", __func__, mId); 489 490 if (!isValidCaptureSettings(request->settings)) { 491 ALOGE("%s:%d: Invalid settings for capture request: %p", 492 __func__, mId, request->settings); 493 return -EINVAL; 494 } 495 } 496 497 if (request->num_output_buffers <= 0) { 498 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId, 499 request->num_output_buffers); 500 return -EINVAL; 501 } 502 result.num_output_buffers = request->num_output_buffers; 503 result.output_buffers = new camera3_stream_buffer_t[result.num_output_buffers]; 504 for (unsigned int i = 0; i < request->num_output_buffers; i++) { 505 int res = processCaptureBuffer(&request->output_buffers[i], 506 const_cast<camera3_stream_buffer_t*>(&result.output_buffers[i])); 507 if (res) 508 goto err_out; 509 } 510 511 result.frame_number = request->frame_number; 512 // TODO: return actual captured/reprocessed settings 513 result.result = request->settings; 514 // TODO: asynchronously return results 515 mCallbackOps->process_capture_result(mCallbackOps, &result); 516 517 return 0; 518 519err_out: 520 delete [] result.output_buffers; 521 // TODO: this should probably be a total device failure; transient for now 522 return -EINVAL; 523} 524 525void Camera::setSettings(const camera_metadata_t *new_settings) 526{ 527 if (mSettings != NULL) { 528 free_camera_metadata(mSettings); 529 mSettings = NULL; 530 } 531 532 if (new_settings != NULL) 533 mSettings = clone_camera_metadata(new_settings); 534} 535 536bool Camera::isValidCaptureSettings(const camera_metadata_t* /*settings*/) 537{ 538 // TODO: reject settings that cannot be captured 539 return true; 540} 541 542bool Camera::isValidReprocessSettings(const camera_metadata_t* /*settings*/) 543{ 544 // TODO: reject settings that cannot be reprocessed 545 // input buffers unimplemented, use this to reject reprocessing requests 546 ALOGE("%s:%d: Input buffer reprocessing not implemented", __func__, mId); 547 return false; 548} 549 550int Camera::processCaptureBuffer(const camera3_stream_buffer_t *in, 551 camera3_stream_buffer_t *out) 552{ 553 int res = sync_wait(in->acquire_fence, CAMERA_SYNC_TIMEOUT); 554 if (res == -ETIME) { 555 ALOGE("%s:%d: Timeout waiting on buffer acquire fence", __func__, mId); 556 return res; 557 } else if (res) { 558 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)", 559 __func__, mId, strerror(-res), res); 560 return res; 561 } 562 563 out->stream = in->stream; 564 out->buffer = in->buffer; 565 out->status = CAMERA3_BUFFER_STATUS_OK; 566 // TODO: use driver-backed release fences 567 out->acquire_fence = -1; 568 out->release_fence = -1; 569 570 // TODO: lock and software-paint buffer 571 return 0; 572} 573 574void Camera::getMetadataVendorTagOps(vendor_tag_query_ops_t *ops) 575{ 576 ALOGV("%s:%d: ops=%p", __func__, mId, ops); 577 // TODO: return vendor tag ops 578} 579 580void Camera::dump(int fd) 581{ 582 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd); 583 // TODO: dprintf all relevant state to fd 584} 585 586extern "C" { 587// Get handle to camera from device priv data 588static Camera *camdev_to_camera(const camera3_device_t *dev) 589{ 590 return reinterpret_cast<Camera*>(dev->priv); 591} 592 593static int initialize(const camera3_device_t *dev, 594 const camera3_callback_ops_t *callback_ops) 595{ 596 return camdev_to_camera(dev)->initialize(callback_ops); 597} 598 599static int configure_streams(const camera3_device_t *dev, 600 camera3_stream_configuration_t *stream_list) 601{ 602 return camdev_to_camera(dev)->configureStreams(stream_list); 603} 604 605static int register_stream_buffers(const camera3_device_t *dev, 606 const camera3_stream_buffer_set_t *buffer_set) 607{ 608 return camdev_to_camera(dev)->registerStreamBuffers(buffer_set); 609} 610 611static const camera_metadata_t *construct_default_request_settings( 612 const camera3_device_t *dev, int type) 613{ 614 return camdev_to_camera(dev)->constructDefaultRequestSettings(type); 615} 616 617static int process_capture_request(const camera3_device_t *dev, 618 camera3_capture_request_t *request) 619{ 620 return camdev_to_camera(dev)->processCaptureRequest(request); 621} 622 623static void get_metadata_vendor_tag_ops(const camera3_device_t *dev, 624 vendor_tag_query_ops_t *ops) 625{ 626 camdev_to_camera(dev)->getMetadataVendorTagOps(ops); 627} 628 629static void dump(const camera3_device_t *dev, int fd) 630{ 631 camdev_to_camera(dev)->dump(fd); 632} 633} // extern "C" 634 635const camera3_device_ops_t Camera::sOps = { 636 .initialize = default_camera_hal::initialize, 637 .configure_streams = default_camera_hal::configure_streams, 638 .register_stream_buffers = default_camera_hal::register_stream_buffers, 639 .construct_default_request_settings = 640 default_camera_hal::construct_default_request_settings, 641 .process_capture_request = default_camera_hal::process_capture_request, 642 .get_metadata_vendor_tag_ops = 643 default_camera_hal::get_metadata_vendor_tag_ops, 644 .dump = default_camera_hal::dump 645}; 646 647} // namespace default_camera_hal 648