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 // Modified from hardware/libhardware/modules/camera/Camera.cpp
     18 
     19 //#define LOG_NDEBUG 0
     20 #define LOG_TAG "Camera"
     21 
     22 #include "camera.h"
     23 
     24 #include <cstdlib>
     25 #include <memory>
     26 
     27 #include <hardware/camera3.h>
     28 #include <sync/sync.h>
     29 #include <system/camera_metadata.h>
     30 #include <system/graphics.h>
     31 #include "metadata/metadata_common.h"
     32 #include "static_properties.h"
     33 
     34 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
     35 #include <utils/Trace.h>
     36 
     37 #define CAMERA_SYNC_TIMEOUT 5000 // in msecs
     38 
     39 namespace default_camera_hal {
     40 
     41 extern "C" {
     42 // Shim passed to the framework to close an opened device.
     43 static int close_device(hw_device_t* dev)
     44 {
     45     camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
     46     Camera* cam = static_cast<Camera*>(cam_dev->priv);
     47     return cam->close();
     48 }
     49 } // extern "C"
     50 
     51 Camera::Camera(int id)
     52   : mId(id),
     53     mSettingsSet(false),
     54     mBusy(false),
     55     mCallbackOps(NULL),
     56     mInFlightTracker(new RequestTracker)
     57 {
     58     memset(&mTemplates, 0, sizeof(mTemplates));
     59     memset(&mDevice, 0, sizeof(mDevice));
     60     mDevice.common.tag    = HARDWARE_DEVICE_TAG;
     61     mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
     62     mDevice.common.close  = close_device;
     63     mDevice.ops           = const_cast<camera3_device_ops_t*>(&sOps);
     64     mDevice.priv          = this;
     65 }
     66 
     67 Camera::~Camera()
     68 {
     69 }
     70 
     71 int Camera::openDevice(const hw_module_t *module, hw_device_t **device)
     72 {
     73     ALOGI("%s:%d: Opening camera device", __func__, mId);
     74     ATRACE_CALL();
     75     android::Mutex::Autolock dl(mDeviceLock);
     76 
     77     if (mBusy) {
     78         ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
     79         return -EBUSY;
     80     }
     81 
     82     int connectResult = connect();
     83     if (connectResult != 0) {
     84       return connectResult;
     85     }
     86     mBusy = true;
     87     mDevice.common.module = const_cast<hw_module_t*>(module);
     88     *device = &mDevice.common;
     89     return 0;
     90 }
     91 
     92 int Camera::getInfo(struct camera_info *info)
     93 {
     94     info->device_version = mDevice.common.version;
     95     initDeviceInfo(info);
     96     if (!mStaticInfo) {
     97         int res = loadStaticInfo();
     98         if (res) {
     99             return res;
    100         }
    101     }
    102     info->static_camera_characteristics = mStaticInfo->raw_metadata();
    103     info->facing = mStaticInfo->facing();
    104     info->orientation = mStaticInfo->orientation();
    105 
    106     return 0;
    107 }
    108 
    109 int Camera::loadStaticInfo() {
    110   // Using a lock here ensures |mStaticInfo| will only ever be set once,
    111   // even in concurrent situations.
    112   android::Mutex::Autolock sl(mStaticInfoLock);
    113 
    114   if (mStaticInfo) {
    115     return 0;
    116   }
    117 
    118   std::unique_ptr<android::CameraMetadata> static_metadata =
    119       std::make_unique<android::CameraMetadata>();
    120   int res = initStaticInfo(static_metadata.get());
    121   if (res) {
    122     ALOGE("%s:%d: Failed to get static info from device.",
    123           __func__, mId);
    124     return res;
    125   }
    126 
    127   mStaticInfo.reset(StaticProperties::NewStaticProperties(
    128       std::move(static_metadata)));
    129   if (!mStaticInfo) {
    130     ALOGE("%s:%d: Failed to initialize static properties from device metadata.",
    131           __func__, mId);
    132     return -ENODEV;
    133   }
    134 
    135   return 0;
    136 }
    137 
    138 int Camera::close()
    139 {
    140     ALOGI("%s:%d: Closing camera device", __func__, mId);
    141     ATRACE_CALL();
    142     android::Mutex::Autolock dl(mDeviceLock);
    143 
    144     if (!mBusy) {
    145         ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
    146         return -EINVAL;
    147     }
    148 
    149     flush();
    150     disconnect();
    151     mBusy = false;
    152     return 0;
    153 }
    154 
    155 int Camera::initialize(const camera3_callback_ops_t *callback_ops)
    156 {
    157     int res;
    158 
    159     ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
    160     mCallbackOps = callback_ops;
    161     // per-device specific initialization
    162     res = initDevice();
    163     if (res != 0) {
    164         ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
    165         return res;
    166     }
    167     return 0;
    168 }
    169 
    170 int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
    171 {
    172     android::Mutex::Autolock dl(mDeviceLock);
    173     android::Mutex::Autolock tl(mInFlightTrackerLock);
    174 
    175     ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
    176     ATRACE_CALL();
    177 
    178     // Check that there are no in-flight requests.
    179     if (!mInFlightTracker->Empty()) {
    180         ALOGE("%s:%d: Can't configure streams while frames are in flight.",
    181               __func__, mId);
    182         return -EINVAL;
    183     }
    184 
    185     // Verify the set of streams in aggregate, and perform configuration if valid.
    186     int res = validateStreamConfiguration(stream_config);
    187     if (res) {
    188         ALOGE("%s:%d: Failed to validate stream set", __func__, mId);
    189     } else {
    190         // Set up all streams. Since they've been validated,
    191         // this should only result in fatal (-ENODEV) errors.
    192         // This occurs after validation to ensure that if there
    193         // is a non-fatal error, the stream configuration doesn't change states.
    194         res = setupStreams(stream_config);
    195         if (res) {
    196             ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
    197         }
    198     }
    199 
    200     // Set trackers based on result.
    201     if (!res) {
    202         // Success, set up the in-flight trackers for the new streams.
    203         mInFlightTracker->SetStreamConfiguration(*stream_config);
    204         // Must provide new settings for the new configuration.
    205         mSettingsSet = false;
    206     } else if (res != -EINVAL) {
    207         // Fatal error, the old configuration is invalid.
    208         mInFlightTracker->ClearStreamConfiguration();
    209     }
    210     // On a non-fatal error the old configuration, if any, remains valid.
    211     return res;
    212 }
    213 
    214 int Camera::validateStreamConfiguration(
    215     const camera3_stream_configuration_t* stream_config)
    216 {
    217     // Check that the configuration is well-formed.
    218     if (stream_config == nullptr) {
    219         ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
    220         return -EINVAL;
    221     } else if (stream_config->num_streams == 0) {
    222         ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
    223         return -EINVAL;
    224     } else if (stream_config->streams == nullptr) {
    225         ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
    226         return -EINVAL;
    227     }
    228 
    229     // Check that the configuration is supported.
    230     // Make sure static info has been initialized before trying to use it.
    231     if (!mStaticInfo) {
    232         int res = loadStaticInfo();
    233         if (res) {
    234             return res;
    235         }
    236     }
    237     if (!mStaticInfo->StreamConfigurationSupported(stream_config)) {
    238         ALOGE("%s:%d: Stream configuration does not match static "
    239               "metadata restrictions.", __func__, mId);
    240         return -EINVAL;
    241     }
    242 
    243     // Dataspace support is poorly documented - unclear if the expectation
    244     // is that a device supports ALL dataspaces that could match a given
    245     // format. For now, defer to child class implementation.
    246     // Rotation support isn't described by metadata, so must defer to device.
    247     if (!validateDataspacesAndRotations(stream_config)) {
    248         ALOGE("%s:%d: Device can not handle configuration "
    249               "dataspaces or rotations.", __func__, mId);
    250         return -EINVAL;
    251     }
    252 
    253     return 0;
    254 }
    255 
    256 bool Camera::isValidTemplateType(int type)
    257 {
    258     return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
    259 }
    260 
    261 const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
    262 {
    263     ALOGV("%s:%d: type=%d", __func__, mId, type);
    264 
    265     if (!isValidTemplateType(type)) {
    266         ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
    267         return NULL;
    268     }
    269 
    270     if (!mTemplates[type]) {
    271         // Check if the device has the necessary features
    272         // for the requested template. If not, don't bother.
    273         if (!mStaticInfo->TemplateSupported(type)) {
    274             ALOGW("%s:%d: Camera does not support template type %d",
    275                   __func__, mId, type);
    276             return NULL;
    277         }
    278 
    279         // Initialize this template if it hasn't been initialized yet.
    280         std::unique_ptr<android::CameraMetadata> new_template =
    281             std::make_unique<android::CameraMetadata>();
    282         int res = initTemplate(type, new_template.get());
    283         if (res || !new_template) {
    284             ALOGE("%s:%d: Failed to generate template of type: %d",
    285                   __func__, mId, type);
    286             return NULL;
    287         }
    288         mTemplates[type] = std::move(new_template);
    289     }
    290 
    291     // The "locking" here only causes non-const methods to fail,
    292     // which is not a problem since the CameraMetadata being locked
    293     // is already const. Destructing automatically "unlocks".
    294     return mTemplates[type]->getAndLock();
    295 }
    296 
    297 int Camera::processCaptureRequest(camera3_capture_request_t *temp_request)
    298 {
    299     int res;
    300     // TODO(b/32917568): A capture request submitted or ongoing during a flush
    301     // should be returned with an error; for now they are mutually exclusive.
    302     android::Mutex::Autolock tl(mInFlightTrackerLock);
    303 
    304     ATRACE_CALL();
    305 
    306     if (temp_request == NULL) {
    307         ALOGE("%s:%d: NULL request recieved", __func__, mId);
    308         return -EINVAL;
    309     }
    310 
    311     // Make a persistent copy of request, since otherwise it won't live
    312     // past the end of this method.
    313     std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request);
    314 
    315     ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
    316 
    317     if (!mInFlightTracker->CanAddRequest(*request)) {
    318         // Streams are full or frame number is not unique.
    319         ALOGE("%s:%d: Can not add request.", __func__, mId);
    320         return -EINVAL;
    321     }
    322 
    323     // Null/Empty indicates use last settings
    324     if (request->settings.isEmpty() && !mSettingsSet) {
    325         ALOGE("%s:%d: NULL settings without previous set Frame:%d",
    326               __func__, mId, request->frame_number);
    327         return -EINVAL;
    328     }
    329 
    330     if (request->input_buffer != NULL) {
    331         ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
    332               request->input_buffer.get());
    333     } else {
    334         ALOGV("%s:%d: Capturing new frame.", __func__, mId);
    335     }
    336 
    337     if (!isValidRequestSettings(request->settings)) {
    338         ALOGE("%s:%d: Invalid request settings.", __func__, mId);
    339         return -EINVAL;
    340     }
    341 
    342     // Pre-process output buffers.
    343     if (request->output_buffers.size() <= 0) {
    344         ALOGE("%s:%d: Invalid number of output buffers: %zu", __func__, mId,
    345               request->output_buffers.size());
    346         return -EINVAL;
    347     }
    348     for (auto& output_buffer : request->output_buffers) {
    349         res = preprocessCaptureBuffer(&output_buffer);
    350         if (res)
    351             return -ENODEV;
    352     }
    353 
    354     // Add the request to tracking.
    355     if (!mInFlightTracker->Add(request)) {
    356         ALOGE("%s:%d: Failed to track request for frame %d.",
    357               __func__, mId, request->frame_number);
    358         return -ENODEV;
    359     }
    360 
    361     // Valid settings have been provided (mSettingsSet is a misnomer;
    362     // all that matters is that a previous request with valid settings
    363     // has been passed to the device, not that they've been set).
    364     mSettingsSet = true;
    365 
    366     // Send the request off to the device for completion.
    367     enqueueRequest(request);
    368 
    369     // Request is now in flight. The device will call completeRequest
    370     // asynchronously when it is done filling buffers and metadata.
    371     return 0;
    372 }
    373 
    374 void Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err)
    375 {
    376     android::Mutex::Autolock tl(mInFlightTrackerLock);
    377 
    378     if (!mInFlightTracker->Remove(request)) {
    379         ALOGE("%s:%d: Completed request %p is not being tracked. "
    380               "It may have been cleared out during a flush.",
    381               __func__, mId, request.get());
    382         return;
    383     }
    384 
    385     // Since |request| has been removed from the tracking, this method
    386     // MUST call sendResult (can still return a result in an error state, e.g.
    387     // through completeRequestWithError) so the frame doesn't get lost.
    388 
    389     if (err) {
    390       ALOGE("%s:%d: Error completing request for frame %d.",
    391             __func__, mId, request->frame_number);
    392       completeRequestWithError(request);
    393       return;
    394     }
    395 
    396     // Notify the framework with the shutter time (extracted from the result).
    397     int64_t timestamp = 0;
    398     // TODO(b/31360070): The general metadata methods should be part of the
    399     // default_camera_hal namespace, not the v4l2_camera_hal namespace.
    400     int res = v4l2_camera_hal::SingleTagValue(
    401         request->settings, ANDROID_SENSOR_TIMESTAMP, &timestamp);
    402     if (res) {
    403         ALOGE("%s:%d: Request for frame %d is missing required metadata.",
    404               __func__, mId, request->frame_number);
    405         // TODO(b/31653322): Send RESULT error.
    406         // For now sending REQUEST error instead.
    407         completeRequestWithError(request);
    408         return;
    409     }
    410     notifyShutter(request->frame_number, timestamp);
    411 
    412     // TODO(b/31653322): Check all returned buffers for errors
    413     // (if any, send BUFFER error).
    414 
    415     sendResult(request);
    416 }
    417 
    418 int Camera::flush()
    419 {
    420     ALOGV("%s:%d: Flushing.", __func__, mId);
    421     // TODO(b/32917568): Synchronization. Behave "appropriately"
    422     // (i.e. according to camera3.h) if process_capture_request()
    423     // is called concurrently with this (in either order).
    424     // Since the callback to completeRequest also may happen on a separate
    425     // thread, this function should behave nicely concurrently with that too.
    426     android::Mutex::Autolock tl(mInFlightTrackerLock);
    427 
    428     std::set<std::shared_ptr<CaptureRequest>> requests;
    429     mInFlightTracker->Clear(&requests);
    430     for (auto& request : requests) {
    431         // TODO(b/31653322): See camera3.h. Should return different error
    432         // depending on status of the request.
    433         completeRequestWithError(request);
    434     }
    435 
    436     ALOGV("%s:%d: Flushed %zu requests.", __func__, mId, requests.size());
    437 
    438     // Call down into the device flushing.
    439     return flushBuffers();
    440 }
    441 
    442 int Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer)
    443 {
    444     int res;
    445     // TODO(b/29334616): This probably should be non-blocking; part
    446     // of the asynchronous request processing.
    447     if (buffer->acquire_fence != -1) {
    448         res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT);
    449         if (res == -ETIME) {
    450             ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
    451                     __func__, mId);
    452             return res;
    453         } else if (res) {
    454             ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
    455                     __func__, mId, strerror(-res), res);
    456             return res;
    457         }
    458         ::close(buffer->acquire_fence);
    459     }
    460 
    461     // Acquire fence has been waited upon.
    462     buffer->acquire_fence = -1;
    463     // No release fence waiting unless the device sets it.
    464     buffer->release_fence = -1;
    465 
    466     buffer->status = CAMERA3_BUFFER_STATUS_OK;
    467     return 0;
    468 }
    469 
    470 void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
    471 {
    472     camera3_notify_msg_t message;
    473     memset(&message, 0, sizeof(message));
    474     message.type = CAMERA3_MSG_SHUTTER;
    475     message.message.shutter.frame_number = frame_number;
    476     message.message.shutter.timestamp = timestamp;
    477     mCallbackOps->notify(mCallbackOps, &message);
    478 }
    479 
    480 void Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request)
    481 {
    482     // Send an error notification.
    483     camera3_notify_msg_t message;
    484     memset(&message, 0, sizeof(message));
    485     message.type = CAMERA3_MSG_ERROR;
    486     message.message.error.frame_number = request->frame_number;
    487     message.message.error.error_stream = nullptr;
    488     message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
    489     mCallbackOps->notify(mCallbackOps, &message);
    490 
    491     // TODO(b/31856611): Ensure all the buffers indicate their error status.
    492 
    493     // Send the errored out result.
    494     sendResult(request);
    495 }
    496 
    497 void Camera::sendResult(std::shared_ptr<CaptureRequest> request) {
    498     // Fill in the result struct
    499     // (it only needs to live until the end of the framework callback).
    500     camera3_capture_result_t result {
    501         request->frame_number,
    502         request->settings.getAndLock(),
    503         static_cast<uint32_t>(request->output_buffers.size()),
    504         request->output_buffers.data(),
    505         request->input_buffer.get(),
    506         1,  // Total result; only 1 part.
    507         0,  // Number of physical camera metadata.
    508         nullptr,
    509         nullptr
    510     };
    511     // Make the framework callback.
    512     mCallbackOps->process_capture_result(mCallbackOps, &result);
    513 }
    514 
    515 void Camera::dump(int fd)
    516 {
    517     ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
    518     ATRACE_CALL();
    519     android::Mutex::Autolock dl(mDeviceLock);
    520 
    521     dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
    522 
    523     // TODO: dump all settings
    524 }
    525 
    526 const char* Camera::templateToString(int type)
    527 {
    528     switch (type) {
    529     case CAMERA3_TEMPLATE_PREVIEW:
    530         return "CAMERA3_TEMPLATE_PREVIEW";
    531     case CAMERA3_TEMPLATE_STILL_CAPTURE:
    532         return "CAMERA3_TEMPLATE_STILL_CAPTURE";
    533     case CAMERA3_TEMPLATE_VIDEO_RECORD:
    534         return "CAMERA3_TEMPLATE_VIDEO_RECORD";
    535     case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
    536         return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
    537     case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
    538         return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
    539     }
    540     // TODO: support vendor templates
    541     return "Invalid template type!";
    542 }
    543 
    544 extern "C" {
    545 // Get handle to camera from device priv data
    546 static Camera *camdev_to_camera(const camera3_device_t *dev)
    547 {
    548     return reinterpret_cast<Camera*>(dev->priv);
    549 }
    550 
    551 static int initialize(const camera3_device_t *dev,
    552         const camera3_callback_ops_t *callback_ops)
    553 {
    554     return camdev_to_camera(dev)->initialize(callback_ops);
    555 }
    556 
    557 static int configure_streams(const camera3_device_t *dev,
    558         camera3_stream_configuration_t *stream_list)
    559 {
    560     return camdev_to_camera(dev)->configureStreams(stream_list);
    561 }
    562 
    563 static const camera_metadata_t *construct_default_request_settings(
    564         const camera3_device_t *dev, int type)
    565 {
    566     return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
    567 }
    568 
    569 static int process_capture_request(const camera3_device_t *dev,
    570         camera3_capture_request_t *request)
    571 {
    572     return camdev_to_camera(dev)->processCaptureRequest(request);
    573 }
    574 
    575 static void dump(const camera3_device_t *dev, int fd)
    576 {
    577     camdev_to_camera(dev)->dump(fd);
    578 }
    579 
    580 static int flush(const camera3_device_t *dev)
    581 {
    582     return camdev_to_camera(dev)->flush();
    583 }
    584 
    585 } // extern "C"
    586 
    587 const camera3_device_ops_t Camera::sOps = {
    588     .initialize = default_camera_hal::initialize,
    589     .configure_streams = default_camera_hal::configure_streams,
    590     .register_stream_buffers = nullptr,
    591     .construct_default_request_settings
    592         = default_camera_hal::construct_default_request_settings,
    593     .process_capture_request = default_camera_hal::process_capture_request,
    594     .get_metadata_vendor_tag_ops = nullptr,
    595     .dump = default_camera_hal::dump,
    596     .flush = default_camera_hal::flush,
    597     .reserved = {0},
    598 };
    599 
    600 }  // namespace default_camera_hal
    601