Home | History | Annotate | Download | only in usbcamera
      1 /*
      2  * Copyright (C) 2015 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 "Camera"
     19 
     20 #include <errno.h>
     21 #include <stdio.h>
     22 #include <string.h>
     23 #include <time.h>
     24 
     25 #include <cstdlib>
     26 
     27 #include <log/log.h>
     28 #include <utils/Mutex.h>
     29 
     30 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
     31 #include <utils/Trace.h>
     32 
     33 #include <hardware/camera3.h>
     34 #include <system/camera_metadata.h>
     35 #include <system/graphics.h>
     36 
     37 #include "CameraHAL.h"
     38 #include "Metadata.h"
     39 #include "Stream.h"
     40 
     41 #include "Camera.h"
     42 
     43 namespace usb_camera_hal {
     44 
     45 extern "C" {
     46 // Shim passed to the framework to close an opened device.
     47 static int close_device(hw_device_t* dev) {
     48     camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
     49     Camera* cam = static_cast<Camera*>(cam_dev->priv);
     50     return cam->close();
     51 }
     52 
     53 // Get handle to camera from device priv data
     54 static Camera *camdev_to_camera(const camera3_device_t *dev) {
     55     return reinterpret_cast<Camera*>(dev->priv);
     56 }
     57 
     58 static int initialize(const camera3_device_t *dev,
     59         const camera3_callback_ops_t *callback_ops) {
     60     return camdev_to_camera(dev)->initialize(callback_ops);
     61 }
     62 
     63 static int configure_streams(const camera3_device_t *dev,
     64         camera3_stream_configuration_t *stream_list) {
     65     return camdev_to_camera(dev)->configureStreams(stream_list);
     66 }
     67 
     68 static const camera_metadata_t *construct_default_request_settings(
     69         const camera3_device_t *dev, int type) {
     70     return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
     71 }
     72 
     73 static int process_capture_request(const camera3_device_t *dev,
     74         camera3_capture_request_t *request) {
     75     return camdev_to_camera(dev)->processCaptureRequest(request);
     76 }
     77 
     78 static void dump(const camera3_device_t *dev, int fd) {
     79     camdev_to_camera(dev)->dump(fd);
     80 }
     81 
     82 static int flush(const camera3_device_t *dev) {
     83     return camdev_to_camera(dev)->flush();
     84 }
     85 
     86 } // extern "C"
     87 
     88 const camera3_device_ops_t Camera::sOps = {
     89     .initialize = usb_camera_hal::initialize,
     90     .configure_streams = usb_camera_hal::configure_streams,
     91     .register_stream_buffers = NULL,
     92     .construct_default_request_settings
     93         = usb_camera_hal::construct_default_request_settings,
     94     .process_capture_request = usb_camera_hal::process_capture_request,
     95     .get_metadata_vendor_tag_ops = NULL,
     96     .dump = usb_camera_hal::dump,
     97     .flush = usb_camera_hal::flush,
     98     .reserved = {0},
     99 };
    100 
    101 Camera::Camera(int id)
    102           : mId(id),
    103             mStaticInfo(NULL),
    104             mBusy(false),
    105             mCallbackOps(NULL),
    106             mSettings(NULL),
    107             mIsInitialized(false) {
    108     memset(&mTemplates, 0, sizeof(mTemplates));
    109     memset(&mDevice, 0, sizeof(mDevice));
    110     mDevice.common.tag    = HARDWARE_DEVICE_TAG;
    111     // TODO: Upgrade to HAL3.3
    112     mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_2;
    113     mDevice.common.close  = close_device;
    114     mDevice.ops           = const_cast<camera3_device_ops_t*>(&sOps);
    115     mDevice.priv          = this;
    116 }
    117 
    118 Camera::~Camera() {
    119     if (mStaticInfo != NULL) {
    120         free_camera_metadata(mStaticInfo);
    121     }
    122 
    123     for (int i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
    124         free_camera_metadata(mTemplates[i]);
    125     }
    126 
    127     if (mSettings != NULL) {
    128         free_camera_metadata(mSettings);
    129     }
    130 }
    131 
    132 int Camera::open(const hw_module_t *module, hw_device_t **device) {
    133     ALOGI("%s:%d: Opening camera device", __func__, mId);
    134     ATRACE_CALL();
    135     android::Mutex::Autolock al(mDeviceLock);
    136 
    137     if (mBusy) {
    138         ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
    139         return -EBUSY;
    140     }
    141 
    142     mBusy = true;
    143     mDevice.common.module = const_cast<hw_module_t*>(module);
    144     *device = &mDevice.common;
    145     return openDevice();
    146 }
    147 
    148 int Camera::getInfo(struct camera_info *info) {
    149     android::Mutex::Autolock al(mStaticInfoLock);
    150 
    151     // TODO: update to CAMERA_FACING_EXTERNAL once the HAL API changes are merged.
    152     info->facing = CAMERA_FACING_FRONT;
    153     info->orientation = 0;
    154     info->device_version = mDevice.common.version;
    155     if (mStaticInfo == NULL) {
    156         initStaticInfo();
    157     }
    158     info->static_camera_characteristics = mStaticInfo;
    159     return 0;
    160 }
    161 
    162 void Camera::updateInfo() {
    163     android::Mutex::Autolock al(mStaticInfoLock);
    164     initStaticInfo();
    165 }
    166 
    167 int Camera::close() {
    168     ALOGI("%s:%d: Closing camera device", __func__, mId);
    169     ATRACE_CALL();
    170     android::Mutex::Autolock al(mDeviceLock);
    171 
    172     if (!mBusy) {
    173         ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
    174         return -EINVAL;
    175     }
    176 
    177     mBusy = false;
    178     mIsInitialized = false;
    179     return closeDevice();
    180 }
    181 
    182 int Camera::initialize(const camera3_callback_ops_t *callback_ops) {
    183     int res;
    184 
    185     ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
    186     ATRACE_CALL();
    187     android::Mutex::Autolock al(mDeviceLock);
    188 
    189     mCallbackOps = callback_ops;
    190     // per-device specific initialization
    191     res = initDevice();
    192     if (res != 0) {
    193         ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
    194         return res;
    195     }
    196 
    197     mIsInitialized = true;
    198     return 0;
    199 }
    200 
    201 int Camera::configureStreams(camera3_stream_configuration_t *stream_config) {
    202     camera3_stream_t *astream;
    203     android::Vector<Stream *> newStreams;
    204 
    205     ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
    206     ATRACE_CALL();
    207     android::Mutex::Autolock al(mDeviceLock);
    208     if (!mIsInitialized) {
    209         ALOGE("Device is not initialized yet");
    210         return -EINVAL;
    211     }
    212 
    213     if (stream_config == NULL) {
    214         ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
    215         return -EINVAL;
    216     }
    217     if (stream_config->num_streams == 0) {
    218         ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
    219         return -EINVAL;
    220     }
    221 
    222     ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
    223             stream_config->num_streams);
    224     // Mark all current streams unused for now
    225     for (size_t i = 0; i < mStreams.size(); i++) {
    226         mStreams[i]->mReuse = false;
    227     }
    228     // Fill new stream array with reused streams and new streams
    229     for (unsigned int i = 0; i < stream_config->num_streams; i++) {
    230         astream = stream_config->streams[i];
    231         if (astream->max_buffers > 0) {
    232             ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
    233             newStreams.add(reuseStreamLocked(astream));
    234         } else {
    235             ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
    236             newStreams.add(new Stream(mId, astream));
    237         }
    238 
    239         if (newStreams[i] == NULL) {
    240             ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
    241             goto err_out;
    242         }
    243         astream->priv = reinterpret_cast<void *>(newStreams[i]);
    244     }
    245 
    246     // Verify the set of streams in aggregate
    247     if (!isValidStreamSetLocked(newStreams)) {
    248         ALOGE("%s:%d: Invalid stream set", __func__, mId);
    249         goto err_out;
    250     }
    251 
    252     // Set up all streams (calculate usage/max_buffers for each)
    253     setupStreamsLocked(newStreams);
    254 
    255     // Destroy all old streams and replace stream array with new one
    256     destroyStreamsLocked(mStreams);
    257     mStreams = newStreams;
    258 
    259     // Clear out last seen settings metadata
    260     updateSettingsLocked(NULL);
    261     return 0;
    262 
    263 err_out:
    264     // Clean up temporary streams, preserve existing mStreams
    265     destroyStreamsLocked(newStreams);
    266     return -EINVAL;
    267 }
    268 
    269 void Camera::destroyStreamsLocked(android::Vector<Stream *> &streams) {
    270     for (size_t i = 0; i < streams.size(); i++) {
    271         delete streams[i];
    272     }
    273     streams.clear();
    274 }
    275 
    276 Stream *Camera::reuseStreamLocked(camera3_stream_t *astream) {
    277     Stream *priv = reinterpret_cast<Stream*>(astream->priv);
    278     // Verify the re-used stream's parameters match
    279     if (!priv->isValidReuseStream(mId, astream)) {
    280         ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
    281         return NULL;
    282     }
    283     // Mark stream to be reused
    284     priv->mReuse = true;
    285     return priv;
    286 }
    287 
    288 bool Camera::isValidStreamSetLocked(const android::Vector<Stream *> &streams) {
    289     int inputs = 0;
    290     int outputs = 0;
    291 
    292     if (streams.isEmpty()) {
    293         ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
    294         return false;
    295     }
    296     // Validate there is at most one input stream and at least one output stream
    297     for (size_t i = 0; i < streams.size(); i++) {
    298         // A stream may be both input and output (bidirectional)
    299         if (streams[i]->isInputType())
    300             inputs++;
    301         if (streams[i]->isOutputType())
    302             outputs++;
    303     }
    304     ALOGV("%s:%d: Configuring %d output streams and %d input streams",
    305             __func__, mId, outputs, inputs);
    306     if (outputs < 1) {
    307         ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
    308         return false;
    309     }
    310     if (inputs > 1) {
    311         ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
    312         return false;
    313     }
    314     // TODO: check for correct number of Bayer/YUV/JPEG/Encoder streams
    315     return true;
    316 }
    317 
    318 void Camera::setupStreamsLocked(android::Vector<Stream *> &streams) {
    319     /*
    320      * This is where the HAL has to decide internally how to handle all of the
    321      * streams, and then produce usage and max_buffer values for each stream.
    322      * Note, the stream vector has been checked before this point for ALL invalid
    323      * conditions, so it must find a successful configuration for this stream
    324      * array.  The HAL may not return an error from this point.
    325      *
    326      * TODO: we just set all streams to be the same dummy values;
    327      * real implementations will want to avoid USAGE_SW_{READ|WRITE}_OFTEN.
    328      */
    329     for (size_t i = 0; i < streams.size(); i++) {
    330         uint32_t usage = 0;
    331 
    332         if (streams[i]->isOutputType())
    333             usage |= GRALLOC_USAGE_SW_WRITE_OFTEN |
    334                      GRALLOC_USAGE_HW_CAMERA_WRITE;
    335         if (streams[i]->isInputType())
    336             usage |= GRALLOC_USAGE_SW_READ_OFTEN |
    337                      GRALLOC_USAGE_HW_CAMERA_READ;
    338 
    339         streams[i]->setUsage(usage);
    340         streams[i]->setMaxBuffers(1);
    341     }
    342 }
    343 
    344 bool Camera::isValidTemplateType(int type) {
    345     return type >= 1 && type < CAMERA3_TEMPLATE_COUNT;
    346 }
    347 
    348 const camera_metadata_t* Camera::constructDefaultRequestSettings(int type) {
    349     ALOGV("%s:%d: type=%d", __func__, mId, type);
    350     android::Mutex::Autolock al(mDeviceLock);
    351 
    352     if (!isValidTemplateType(type)) {
    353         ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
    354         return NULL;
    355     }
    356 
    357     // DO NOT try to initialize the device here, it will be guaranteed deadlock.
    358     if (!mIsInitialized) {
    359         ALOGE("Device is not initialized yet");
    360         return NULL;
    361     }
    362 
    363     return mTemplates[type];
    364 }
    365 
    366 // This implementation is a copy-paste, probably we should override (or move) this to
    367 // device specific class.
    368 int Camera::processCaptureRequest(camera3_capture_request_t *request) {
    369     camera3_capture_result result;
    370     ALOGV("%s:%d: request=%p", __func__, mId, request);
    371     ATRACE_CALL();
    372     android::Mutex::Autolock al(mDeviceLock);
    373 
    374     if (request == NULL) {
    375         ALOGE("%s:%d: NULL request recieved", __func__, mId);
    376         return -EINVAL;
    377     }
    378 
    379     ALOGV("%s:%d: Request Frame:%d Settings:%p", __func__, mId,
    380             request->frame_number, request->settings);
    381 
    382     // NULL indicates use last settings
    383     if (request->settings == NULL) {
    384         if (mSettings == NULL) {
    385             ALOGE("%s:%d: NULL settings without previous set Frame:%d Req:%p",
    386                     __func__, mId, request->frame_number, request);
    387             return -EINVAL;
    388         }
    389     } else {
    390         updateSettingsLocked(request->settings);
    391     }
    392 
    393     if (request->input_buffer != NULL) {
    394         ALOGV("%s:%d: Reprocessing input buffer is not supported yet", __func__, mId);
    395         return -EINVAL;
    396     } else {
    397         ALOGV("%s:%d: Capturing new frame.", __func__, mId);
    398 
    399         if (!isValidCaptureSettings(request->settings)) {
    400             ALOGE("%s:%d: Invalid settings for capture request: %p",
    401                     __func__, mId, request->settings);
    402             return -EINVAL;
    403         }
    404     }
    405 
    406     if (request->num_output_buffers <= 0) {
    407         ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
    408                 request->num_output_buffers);
    409         return -EINVAL;
    410     }
    411     result.num_output_buffers = request->num_output_buffers;
    412     result.output_buffers = new camera3_stream_buffer_t[result.num_output_buffers];
    413     for (unsigned int i = 0; i < request->num_output_buffers; i++) {
    414         int res = processCaptureBuffer(&request->output_buffers[i],
    415                 const_cast<camera3_stream_buffer_t*>(&result.output_buffers[i]));
    416         if (res) {
    417             delete [] result.output_buffers;
    418             // TODO: this should probably be a total device failure; transient for now
    419             return -EINVAL;
    420         }
    421     }
    422 
    423     result.frame_number = request->frame_number;
    424     // TODO: return actual captured/reprocessed settings
    425     result.result = request->settings;
    426     // TODO: asynchronously return results
    427     notifyShutter(request->frame_number, 0);
    428     mCallbackOps->process_capture_result(mCallbackOps, &result);
    429 
    430     // Free up capture result related resources, HAL owns the capture result, and it
    431     // is only valid during the process_capture_result call.
    432     delete[] result.output_buffers;
    433 
    434     return 0;
    435 }
    436 
    437 int Camera::flush() {
    438     int res;
    439 
    440     ALOGV("%s:%d: flush device", __func__, mId);
    441     // per-device specific flush
    442     res = flushDevice();
    443     if (res != 0) {
    444         ALOGE("%s:%d: Failed to flush device!", __func__, mId);
    445         return res;
    446     }
    447     return 0;
    448 }
    449 
    450 void Camera::updateSettingsLocked(const camera_metadata_t *new_settings) {
    451     if (mSettings != NULL) {
    452         free_camera_metadata(mSettings);
    453         mSettings = NULL;
    454     }
    455 
    456     if (new_settings != NULL)
    457         mSettings = clone_camera_metadata(new_settings);
    458 }
    459 
    460 void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp) {
    461     int res;
    462     struct timespec ts;
    463 
    464     // If timestamp is 0, get timestamp from right now instead
    465     if (timestamp == 0) {
    466         ALOGW("%s:%d: No timestamp provided, using CLOCK_BOOTTIME",
    467                 __func__, mId);
    468         res = clock_gettime(CLOCK_BOOTTIME, &ts);
    469         if (res == 0) {
    470             timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
    471         } else {
    472             ALOGE("%s:%d: No timestamp and failed to get CLOCK_BOOTTIME %s(%d)",
    473                     __func__, mId, strerror(errno), errno);
    474         }
    475     }
    476     camera3_notify_msg_t m;
    477     memset(&m, 0, sizeof(m));
    478     m.type = CAMERA3_MSG_SHUTTER;
    479     m.message.shutter.frame_number = frame_number;
    480     m.message.shutter.timestamp = timestamp;
    481     mCallbackOps->notify(mCallbackOps, &m);
    482 }
    483 
    484 void Camera::dump(int fd) {
    485     ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
    486     ATRACE_CALL();
    487     android::Mutex::Autolock al(mDeviceLock);
    488 
    489     dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
    490 
    491     // TODO: dump all settings
    492     dprintf(fd, "Most Recent Settings: (%p)\n", mSettings);
    493 
    494     dprintf(fd, "Number of streams: %zu\n", mStreams.size());
    495     for (size_t i = 0; i < mStreams.size(); i++) {
    496         dprintf(fd, "Stream %zu/%zu:\n", i, mStreams.size());
    497         mStreams[i]->dump(fd);
    498     }
    499 }
    500 
    501 const char* Camera::templateToString(int type) {
    502     switch (type) {
    503     case CAMERA3_TEMPLATE_PREVIEW:
    504         return "CAMERA3_TEMPLATE_PREVIEW";
    505     case CAMERA3_TEMPLATE_STILL_CAPTURE:
    506         return "CAMERA3_TEMPLATE_STILL_CAPTURE";
    507     case CAMERA3_TEMPLATE_VIDEO_RECORD:
    508         return "CAMERA3_TEMPLATE_VIDEO_RECORD";
    509     case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
    510         return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
    511     case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
    512         return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
    513     case CAMERA3_TEMPLATE_MANUAL:
    514         return "CAMERA3_TEMPLATE_MANUAL";
    515     }
    516 
    517     return "Invalid template type!";
    518 }
    519 
    520 int Camera::setTemplate(int type, camera_metadata_t *settings) {
    521     android::Mutex::Autolock al(mDeviceLock);
    522 
    523     if (!isValidTemplateType(type)) {
    524         ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
    525         return -EINVAL;
    526     }
    527 
    528     if (mTemplates[type] != NULL) {
    529         ALOGE("%s:%d: Setting already constructed template type %s(%d)",
    530                 __func__, mId, templateToString(type), type);
    531         return -EINVAL;
    532     }
    533 
    534     // Make a durable copy of the underlying metadata
    535     mTemplates[type] = clone_camera_metadata(settings);
    536     if (mTemplates[type] == NULL) {
    537         ALOGE("%s:%d: Failed to clone metadata %p for template type %s(%d)",
    538                 __func__, mId, settings, templateToString(type), type);
    539         return -EINVAL;
    540     }
    541     return 0;
    542 }
    543 
    544 } // namespace usb_camera_hal
    545