| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 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 |  | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 17 | #define LOG_TAG "Camera2-Device" | 
 | 18 | #define ATRACE_TAG ATRACE_TAG_CAMERA | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 19 | //#define LOG_NDEBUG 0 | 
| Eino-Ville Talvala | 2c08dc6 | 2012-06-15 12:49:21 -0700 | [diff] [blame] | 20 | //#define LOG_NNDEBUG 0  // Per-frame verbose logging | 
 | 21 |  | 
 | 22 | #ifdef LOG_NNDEBUG | 
 | 23 | #define ALOGVV(...) ALOGV(__VA_ARGS__) | 
 | 24 | #else | 
 | 25 | #define ALOGVV(...) ((void)0) | 
 | 26 | #endif | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 27 |  | 
| Kévin PETIT | 377b2ec | 2014-02-03 12:35:36 +0000 | [diff] [blame] | 28 | #include <inttypes.h> | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 29 | #include <utils/Log.h> | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 30 | #include <utils/Trace.h> | 
| Eino-Ville Talvala | 4c9eb71 | 2012-10-02 13:30:28 -0700 | [diff] [blame] | 31 | #include <utils/Timers.h> | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 32 | #include "Camera2Device.h" | 
| Eino-Ville Talvala | f67e23e | 2014-07-23 17:17:59 -0700 | [diff] [blame] | 33 | #include "CameraService.h" | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 34 |  | 
 | 35 | namespace android { | 
 | 36 |  | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 37 | Camera2Device::Camera2Device(int id): | 
 | 38 |         mId(id), | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 39 |         mHal2Device(NULL) | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 40 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 41 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | c8474b6 | 2012-08-24 16:30:44 -0700 | [diff] [blame] | 42 |     ALOGV("%s: Created device for camera %d", __FUNCTION__, id); | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 43 | } | 
 | 44 |  | 
 | 45 | Camera2Device::~Camera2Device() | 
 | 46 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 47 |     ATRACE_CALL(); | 
| Igor Murashkin | 8dcdb95 | 2012-10-02 16:05:11 -0700 | [diff] [blame] | 48 |     ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId); | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 49 |     disconnect(); | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 50 | } | 
 | 51 |  | 
| Igor Murashkin | 7138105 | 2013-03-04 14:53:08 -0800 | [diff] [blame] | 52 | int Camera2Device::getId() const { | 
 | 53 |     return mId; | 
 | 54 | } | 
 | 55 |  | 
| Yin-Chia Yeh | e074a93 | 2015-01-30 10:29:02 -0800 | [diff] [blame] | 56 | status_t Camera2Device::initialize(CameraModule *module) | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 57 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 58 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | c8474b6 | 2012-08-24 16:30:44 -0700 | [diff] [blame] | 59 |     ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId); | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 60 |     if (mHal2Device != NULL) { | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 61 |         ALOGE("%s: Already initialized!", __FUNCTION__); | 
 | 62 |         return INVALID_OPERATION; | 
 | 63 |     } | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 64 |  | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 65 |     status_t res; | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 66 |     char name[10]; | 
 | 67 |     snprintf(name, sizeof(name), "%d", mId); | 
 | 68 |  | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 69 |     camera2_device_t *device; | 
 | 70 |  | 
| Chien-Yu Chen | d231fd6 | 2015-02-25 16:04:22 -0800 | [diff] [blame] | 71 |     res = module->open(name, reinterpret_cast<hw_device_t**>(&device)); | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 72 |  | 
 | 73 |     if (res != OK) { | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 74 |         ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__, | 
 | 75 |                 mId, strerror(-res), res); | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 76 |         return res; | 
 | 77 |     } | 
 | 78 |  | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 79 |     if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) { | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 80 |         ALOGE("%s: Could not open camera %d: " | 
 | 81 |                 "Camera device is not version %x, reports %x instead", | 
 | 82 |                 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0, | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 83 |                 device->common.version); | 
 | 84 |         device->common.close(&device->common); | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 85 |         return BAD_VALUE; | 
 | 86 |     } | 
 | 87 |  | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 88 |     camera_info info; | 
| Yin-Chia Yeh | e074a93 | 2015-01-30 10:29:02 -0800 | [diff] [blame] | 89 |     res = module->getCameraInfo(mId, &info); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 90 |     if (res != OK ) return res; | 
 | 91 |  | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 92 |     if (info.device_version != device->common.version) { | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 93 |         ALOGE("%s: HAL reporting mismatched camera_info version (%x)" | 
 | 94 |                 " and device version (%x).", __FUNCTION__, | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 95 |                 device->common.version, info.device_version); | 
 | 96 |         device->common.close(&device->common); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 97 |         return BAD_VALUE; | 
 | 98 |     } | 
 | 99 |  | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 100 |     res = mRequestQueue.setConsumerDevice(device); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 101 |     if (res != OK) { | 
 | 102 |         ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)", | 
 | 103 |                 __FUNCTION__, mId, strerror(-res), res); | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 104 |         device->common.close(&device->common); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 105 |         return res; | 
 | 106 |     } | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 107 |     res = mFrameQueue.setProducerDevice(device); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 108 |     if (res != OK) { | 
 | 109 |         ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)", | 
 | 110 |                 __FUNCTION__, mId, strerror(-res), res); | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 111 |         device->common.close(&device->common); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 112 |         return res; | 
 | 113 |     } | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 114 |  | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 115 |     res = device->ops->set_notify_callback(device, notificationCallback, | 
 | 116 |             NULL); | 
 | 117 |     if (res != OK) { | 
 | 118 |         ALOGE("%s: Camera %d: Unable to initialize notification callback!", | 
 | 119 |                 __FUNCTION__, mId); | 
 | 120 |         device->common.close(&device->common); | 
 | 121 |         return res; | 
 | 122 |     } | 
 | 123 |  | 
 | 124 |     mDeviceInfo = info.static_camera_characteristics; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 125 |     mHal2Device = device; | 
| Zhijun He | 204e329 | 2014-07-14 17:09:23 -0700 | [diff] [blame] | 126 |     mDeviceVersion = device->common.version; | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 127 |  | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 128 |     return OK; | 
 | 129 | } | 
 | 130 |  | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 131 | status_t Camera2Device::disconnect() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 132 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 133 |     status_t res = OK; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 134 |     if (mHal2Device) { | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 135 |         ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId); | 
 | 136 |  | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 137 |         int inProgressCount = mHal2Device->ops->get_in_progress_count(mHal2Device); | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 138 |         if (inProgressCount > 0) { | 
 | 139 |             ALOGW("%s: Closing camera device %d with %d requests in flight!", | 
 | 140 |                     __FUNCTION__, mId, inProgressCount); | 
 | 141 |         } | 
| Eino-Ville Talvala | c62bb78 | 2012-09-24 13:44:07 -0700 | [diff] [blame] | 142 |         mReprocessStreams.clear(); | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 143 |         mStreams.clear(); | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 144 |         res = mHal2Device->common.close(&mHal2Device->common); | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 145 |         if (res != OK) { | 
 | 146 |             ALOGE("%s: Could not close camera %d: %s (%d)", | 
 | 147 |                     __FUNCTION__, | 
 | 148 |                     mId, strerror(-res), res); | 
 | 149 |         } | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 150 |         mHal2Device = NULL; | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 151 |         ALOGV("%s: Shutdown complete", __FUNCTION__); | 
 | 152 |     } | 
 | 153 |     return res; | 
 | 154 | } | 
 | 155 |  | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 156 | status_t Camera2Device::dump(int fd, const Vector<String16>& args) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 157 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 158 |     String8 result; | 
| Eino-Ville Talvala | 9719715 | 2012-08-06 14:25:19 -0700 | [diff] [blame] | 159 |     int detailLevel = 0; | 
 | 160 |     int n = args.size(); | 
 | 161 |     String16 detailOption("-d"); | 
 | 162 |     for (int i = 0; i + 1 < n; i++) { | 
 | 163 |         if (args[i] == detailOption) { | 
 | 164 |             String8 levelStr(args[i+1]); | 
 | 165 |             detailLevel = atoi(levelStr.string()); | 
 | 166 |         } | 
 | 167 |     } | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 168 |  | 
| Eino-Ville Talvala | 603b12e | 2012-08-08 09:25:58 -0700 | [diff] [blame] | 169 |     result.appendFormat("  Camera2Device[%d] dump (detail level %d):\n", | 
 | 170 |             mId, detailLevel); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 171 |  | 
| Eino-Ville Talvala | 9719715 | 2012-08-06 14:25:19 -0700 | [diff] [blame] | 172 |     if (detailLevel > 0) { | 
 | 173 |         result = "    Request queue contents:\n"; | 
 | 174 |         write(fd, result.string(), result.size()); | 
 | 175 |         mRequestQueue.dump(fd, args); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 176 |  | 
| Eino-Ville Talvala | 9719715 | 2012-08-06 14:25:19 -0700 | [diff] [blame] | 177 |         result = "    Frame queue contents:\n"; | 
 | 178 |         write(fd, result.string(), result.size()); | 
 | 179 |         mFrameQueue.dump(fd, args); | 
 | 180 |     } | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 181 |  | 
 | 182 |     result = "    Active streams:\n"; | 
 | 183 |     write(fd, result.string(), result.size()); | 
 | 184 |     for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) { | 
 | 185 |         (*s)->dump(fd, args); | 
 | 186 |     } | 
 | 187 |  | 
 | 188 |     result = "    HAL device dump:\n"; | 
 | 189 |     write(fd, result.string(), result.size()); | 
 | 190 |  | 
 | 191 |     status_t res; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 192 |     res = mHal2Device->ops->dump(mHal2Device, fd); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 193 |  | 
 | 194 |     return res; | 
 | 195 | } | 
 | 196 |  | 
| Igor Murashkin | bd02dd1 | 2013-02-13 15:53:56 -0800 | [diff] [blame] | 197 | const CameraMetadata& Camera2Device::info() const { | 
| Eino-Ville Talvala | 9e4c3db | 2012-07-20 11:07:52 -0700 | [diff] [blame] | 198 |     ALOGVV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 199 |  | 
 | 200 |     return mDeviceInfo; | 
 | 201 | } | 
 | 202 |  | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 203 | status_t Camera2Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 204 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 205 |     ALOGV("%s: E", __FUNCTION__); | 
 | 206 |  | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 207 |     mRequestQueue.enqueue(request.release()); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 208 |     return OK; | 
 | 209 | } | 
 | 210 |  | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 211 | status_t Camera2Device::captureList(const List<const CameraMetadata> &requests, | 
 | 212 |                                     int64_t* /*lastFrameNumber*/) { | 
| Jianing Wei | 90e59c9 | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 213 |     ATRACE_CALL(); | 
 | 214 |     ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__); | 
 | 215 |     return INVALID_OPERATION; | 
 | 216 | } | 
 | 217 |  | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 218 | status_t Camera2Device::setStreamingRequest(const CameraMetadata &request, | 
 | 219 |                                             int64_t* /*lastFrameNumber*/) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 220 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 221 |     ALOGV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 222 |     CameraMetadata streamRequest(request); | 
 | 223 |     return mRequestQueue.setStreamSlot(streamRequest.release()); | 
 | 224 | } | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 225 |  | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 226 | status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests, | 
 | 227 |                                                 int64_t* /*lastFrameNumber*/) { | 
| Jianing Wei | 90e59c9 | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 228 |     ATRACE_CALL(); | 
 | 229 |     ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__); | 
 | 230 |     return INVALID_OPERATION; | 
 | 231 | } | 
 | 232 |  | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 233 | status_t Camera2Device::clearStreamingRequest(int64_t* /*lastFrameNumber*/) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 234 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 235 |     return mRequestQueue.setStreamSlot(NULL); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 236 | } | 
 | 237 |  | 
| Eino-Ville Talvala | 4c9eb71 | 2012-10-02 13:30:28 -0700 | [diff] [blame] | 238 | status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) { | 
 | 239 |     ATRACE_CALL(); | 
 | 240 |     return mRequestQueue.waitForDequeue(requestId, timeout); | 
 | 241 | } | 
 | 242 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 243 | status_t Camera2Device::createStream(sp<ANativeWindow> consumer, | 
| Eino-Ville Talvala | 3d82c0d | 2015-02-23 15:19:19 -0800 | [diff] [blame] | 244 |         uint32_t width, uint32_t height, int format, | 
| Yin-Chia Yeh | b97babb | 2015-03-12 13:42:44 -0700 | [diff] [blame] | 245 |         android_dataspace /*dataSpace*/, camera3_stream_rotation_t rotation, int *id) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 246 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 247 |     status_t res; | 
 | 248 |     ALOGV("%s: E", __FUNCTION__); | 
 | 249 |  | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 250 |     sp<StreamAdapter> stream = new StreamAdapter(mHal2Device); | 
| Zhijun He | 28c9b6f | 2014-08-08 12:00:47 -0700 | [diff] [blame] | 251 |     size_t size = 0; | 
 | 252 |     if (format == HAL_PIXEL_FORMAT_BLOB) { | 
 | 253 |         size = getJpegBufferSize(width, height); | 
 | 254 |     } | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 255 |     res = stream->connectToDevice(consumer, width, height, format, size); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 256 |     if (res != OK) { | 
 | 257 |         ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):" | 
 | 258 |                 "%s (%d)", | 
 | 259 |                 __FUNCTION__, mId, width, height, format, strerror(-res), res); | 
 | 260 |         return res; | 
 | 261 |     } | 
 | 262 |  | 
 | 263 |     *id = stream->getId(); | 
 | 264 |  | 
 | 265 |     mStreams.push_back(stream); | 
 | 266 |     return OK; | 
 | 267 | } | 
 | 268 |  | 
| Zhijun He | 28c9b6f | 2014-08-08 12:00:47 -0700 | [diff] [blame] | 269 | ssize_t Camera2Device::getJpegBufferSize(uint32_t width, uint32_t height) const { | 
 | 270 |     // Always give the max jpeg buffer size regardless of the actual jpeg resolution. | 
 | 271 |     camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE); | 
 | 272 |     if (jpegBufMaxSize.count == 0) { | 
 | 273 |         ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId); | 
 | 274 |         return BAD_VALUE; | 
 | 275 |     } | 
 | 276 |  | 
 | 277 |     return jpegBufMaxSize.data.i32[0]; | 
 | 278 | } | 
 | 279 |  | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 280 | status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 281 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 282 |     status_t res; | 
 | 283 |     ALOGV("%s: E", __FUNCTION__); | 
 | 284 |  | 
 | 285 |     bool found = false; | 
 | 286 |     StreamList::iterator streamI; | 
 | 287 |     for (streamI = mStreams.begin(); | 
 | 288 |          streamI != mStreams.end(); streamI++) { | 
 | 289 |         if ((*streamI)->getId() == outputId) { | 
 | 290 |             found = true; | 
 | 291 |             break; | 
 | 292 |         } | 
 | 293 |     } | 
 | 294 |     if (!found) { | 
 | 295 |         ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create " | 
 | 296 |                 "reprocess stream from it!", __FUNCTION__, mId, outputId); | 
 | 297 |         return BAD_VALUE; | 
 | 298 |     } | 
 | 299 |  | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 300 |     sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 301 |  | 
 | 302 |     res = stream->connectToDevice((*streamI)); | 
 | 303 |     if (res != OK) { | 
 | 304 |         ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\ | 
 | 305 |                 "stream %d: %s (%d)", __FUNCTION__, mId, outputId, | 
 | 306 |                 strerror(-res), res); | 
 | 307 |         return res; | 
 | 308 |     } | 
 | 309 |  | 
 | 310 |     *id = stream->getId(); | 
 | 311 |  | 
 | 312 |     mReprocessStreams.push_back(stream); | 
 | 313 |     return OK; | 
 | 314 | } | 
 | 315 |  | 
 | 316 |  | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 317 | status_t Camera2Device::getStreamInfo(int id, | 
| Eino-Ville Talvala | d46a6b9 | 2015-05-14 17:26:24 -0700 | [diff] [blame] | 318 |         uint32_t *width, uint32_t *height, | 
 | 319 |         uint32_t *format, android_dataspace *dataSpace) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 320 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 321 |     ALOGV("%s: E", __FUNCTION__); | 
 | 322 |     bool found = false; | 
 | 323 |     StreamList::iterator streamI; | 
 | 324 |     for (streamI = mStreams.begin(); | 
 | 325 |          streamI != mStreams.end(); streamI++) { | 
 | 326 |         if ((*streamI)->getId() == id) { | 
 | 327 |             found = true; | 
 | 328 |             break; | 
 | 329 |         } | 
 | 330 |     } | 
 | 331 |     if (!found) { | 
 | 332 |         ALOGE("%s: Camera %d: Stream %d does not exist", | 
 | 333 |                 __FUNCTION__, mId, id); | 
 | 334 |         return BAD_VALUE; | 
 | 335 |     } | 
 | 336 |  | 
 | 337 |     if (width) *width = (*streamI)->getWidth(); | 
 | 338 |     if (height) *height = (*streamI)->getHeight(); | 
 | 339 |     if (format) *format = (*streamI)->getFormat(); | 
| Eino-Ville Talvala | d46a6b9 | 2015-05-14 17:26:24 -0700 | [diff] [blame] | 340 |     if (dataSpace) *dataSpace = HAL_DATASPACE_UNKNOWN; | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 341 |  | 
 | 342 |     return OK; | 
 | 343 | } | 
 | 344 |  | 
| Eino-Ville Talvala | c94cd19 | 2012-06-15 12:47:42 -0700 | [diff] [blame] | 345 | status_t Camera2Device::setStreamTransform(int id, | 
 | 346 |         int transform) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 347 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | c94cd19 | 2012-06-15 12:47:42 -0700 | [diff] [blame] | 348 |     ALOGV("%s: E", __FUNCTION__); | 
 | 349 |     bool found = false; | 
 | 350 |     StreamList::iterator streamI; | 
 | 351 |     for (streamI = mStreams.begin(); | 
 | 352 |          streamI != mStreams.end(); streamI++) { | 
 | 353 |         if ((*streamI)->getId() == id) { | 
 | 354 |             found = true; | 
 | 355 |             break; | 
 | 356 |         } | 
 | 357 |     } | 
 | 358 |     if (!found) { | 
 | 359 |         ALOGE("%s: Camera %d: Stream %d does not exist", | 
 | 360 |                 __FUNCTION__, mId, id); | 
 | 361 |         return BAD_VALUE; | 
 | 362 |     } | 
 | 363 |  | 
 | 364 |     return (*streamI)->setTransform(transform); | 
 | 365 | } | 
 | 366 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 367 | status_t Camera2Device::deleteStream(int id) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 368 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 369 |     ALOGV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 370 |     bool found = false; | 
 | 371 |     for (StreamList::iterator streamI = mStreams.begin(); | 
 | 372 |          streamI != mStreams.end(); streamI++) { | 
 | 373 |         if ((*streamI)->getId() == id) { | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 374 |             status_t res = (*streamI)->release(); | 
| Eino-Ville Talvala | 4ecfec3 | 2012-06-12 17:13:48 -0700 | [diff] [blame] | 375 |             if (res != OK) { | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 376 |                 ALOGE("%s: Unable to release stream %d from HAL device: " | 
| Eino-Ville Talvala | 4ecfec3 | 2012-06-12 17:13:48 -0700 | [diff] [blame] | 377 |                         "%s (%d)", __FUNCTION__, id, strerror(-res), res); | 
 | 378 |                 return res; | 
 | 379 |             } | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 380 |             mStreams.erase(streamI); | 
 | 381 |             found = true; | 
 | 382 |             break; | 
 | 383 |         } | 
 | 384 |     } | 
 | 385 |     if (!found) { | 
 | 386 |         ALOGE("%s: Camera %d: Unable to find stream %d to delete", | 
 | 387 |                 __FUNCTION__, mId, id); | 
 | 388 |         return BAD_VALUE; | 
 | 389 |     } | 
 | 390 |     return OK; | 
 | 391 | } | 
 | 392 |  | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 393 | status_t Camera2Device::deleteReprocessStream(int id) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 394 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 395 |     ALOGV("%s: E", __FUNCTION__); | 
 | 396 |     bool found = false; | 
 | 397 |     for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin(); | 
 | 398 |          streamI != mReprocessStreams.end(); streamI++) { | 
 | 399 |         if ((*streamI)->getId() == id) { | 
 | 400 |             status_t res = (*streamI)->release(); | 
 | 401 |             if (res != OK) { | 
 | 402 |                 ALOGE("%s: Unable to release reprocess stream %d from " | 
 | 403 |                         "HAL device: %s (%d)", __FUNCTION__, id, | 
 | 404 |                         strerror(-res), res); | 
 | 405 |                 return res; | 
 | 406 |             } | 
 | 407 |             mReprocessStreams.erase(streamI); | 
 | 408 |             found = true; | 
 | 409 |             break; | 
 | 410 |         } | 
 | 411 |     } | 
 | 412 |     if (!found) { | 
 | 413 |         ALOGE("%s: Camera %d: Unable to find stream %d to delete", | 
 | 414 |                 __FUNCTION__, mId, id); | 
 | 415 |         return BAD_VALUE; | 
 | 416 |     } | 
 | 417 |     return OK; | 
 | 418 | } | 
 | 419 |  | 
| Zhijun He | 1fa8999 | 2015-06-01 15:44:31 -0700 | [diff] [blame] | 420 | status_t Camera2Device::configureStreams(bool isConstrainedHighSpeed) { | 
| Igor Murashkin | e2d167e | 2014-08-19 16:19:59 -0700 | [diff] [blame] | 421 |     ATRACE_CALL(); | 
 | 422 |     ALOGV("%s: E", __FUNCTION__); | 
 | 423 |  | 
 | 424 |     /** | 
 | 425 |      * HAL2 devices do not need to configure streams; | 
 | 426 |      * streams are created on the fly. | 
 | 427 |      */ | 
 | 428 |     ALOGW("%s: No-op for HAL2 devices", __FUNCTION__); | 
 | 429 |  | 
 | 430 |     return OK; | 
 | 431 | } | 
 | 432 |  | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 433 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 434 | status_t Camera2Device::createDefaultRequest(int templateId, | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 435 |         CameraMetadata *request) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 436 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 437 |     status_t err; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 438 |     ALOGV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 439 |     camera_metadata_t *rawRequest; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 440 |     err = mHal2Device->ops->construct_default_request( | 
 | 441 |         mHal2Device, templateId, &rawRequest); | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 442 |     request->acquire(rawRequest); | 
 | 443 |     return err; | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 444 | } | 
 | 445 |  | 
 | 446 | status_t Camera2Device::waitUntilDrained() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 447 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 448 |     static const uint32_t kSleepTime = 50000; // 50 ms | 
 | 449 |     static const uint32_t kMaxSleepTime = 10000000; // 10 s | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 450 |     ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 451 |     if (mRequestQueue.getBufferCount() == | 
 | 452 |             CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION; | 
 | 453 |  | 
 | 454 |     // TODO: Set up notifications from HAL, instead of sleeping here | 
 | 455 |     uint32_t totalTime = 0; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 456 |     while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) { | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 457 |         usleep(kSleepTime); | 
 | 458 |         totalTime += kSleepTime; | 
 | 459 |         if (totalTime > kMaxSleepTime) { | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 460 |             ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__, | 
| Alex Ray | f0eeb53 | 2013-03-17 03:23:18 -0700 | [diff] [blame] | 461 |                     totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device)); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 462 |             return TIMED_OUT; | 
 | 463 |         } | 
 | 464 |     } | 
| Eino-Ville Talvala | 7adb52f | 2012-09-20 14:44:20 -0700 | [diff] [blame] | 465 |     ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 466 |     return OK; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 467 | } | 
 | 468 |  | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 469 | status_t Camera2Device::setNotifyCallback(NotificationListener *listener) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 470 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 471 |     status_t res; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 472 |     res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback, | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 473 |             reinterpret_cast<void*>(listener) ); | 
 | 474 |     if (res != OK) { | 
 | 475 |         ALOGE("%s: Unable to set notification callback!", __FUNCTION__); | 
 | 476 |     } | 
 | 477 |     return res; | 
 | 478 | } | 
 | 479 |  | 
| Eino-Ville Talvala | 46910bd | 2013-07-18 19:15:17 -0700 | [diff] [blame] | 480 | bool Camera2Device::willNotify3A() { | 
 | 481 |     return true; | 
 | 482 | } | 
 | 483 |  | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 484 | void Camera2Device::notificationCallback(int32_t msg_type, | 
 | 485 |         int32_t ext1, | 
 | 486 |         int32_t ext2, | 
 | 487 |         int32_t ext3, | 
 | 488 |         void *user) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 489 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 490 |     NotificationListener *listener = reinterpret_cast<NotificationListener*>(user); | 
 | 491 |     ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type, | 
 | 492 |             ext1, ext2, ext3); | 
 | 493 |     if (listener != NULL) { | 
 | 494 |         switch (msg_type) { | 
 | 495 |             case CAMERA2_MSG_ERROR: | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 496 |                 // TODO: This needs to be fixed. ext2 and ext3 need to be considered. | 
 | 497 |                 listener->notifyError( | 
 | 498 |                         ((ext1 == CAMERA2_MSG_ERROR_DEVICE) | 
 | 499 |                         || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ? | 
 | 500 |                                 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE : | 
 | 501 |                                 ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, | 
 | 502 |                         CaptureResultExtras()); | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 503 |                 break; | 
 | 504 |             case CAMERA2_MSG_SHUTTER: { | 
| Eino-Ville Talvala | f1e98d8 | 2013-09-06 09:32:43 -0700 | [diff] [blame] | 505 |                 // TODO: Only needed for camera2 API, which is unsupported | 
 | 506 |                 // by HAL2 directly. | 
 | 507 |                 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 ); | 
 | 508 |                 // listener->notifyShutter(requestId, timestamp); | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 509 |                 break; | 
 | 510 |             } | 
 | 511 |             case CAMERA2_MSG_AUTOFOCUS: | 
 | 512 |                 listener->notifyAutoFocus(ext1, ext2); | 
 | 513 |                 break; | 
 | 514 |             case CAMERA2_MSG_AUTOEXPOSURE: | 
 | 515 |                 listener->notifyAutoExposure(ext1, ext2); | 
 | 516 |                 break; | 
 | 517 |             case CAMERA2_MSG_AUTOWB: | 
 | 518 |                 listener->notifyAutoWhitebalance(ext1, ext2); | 
 | 519 |                 break; | 
 | 520 |             default: | 
 | 521 |                 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!", | 
 | 522 |                         __FUNCTION__, msg_type, ext1, ext2, ext3); | 
 | 523 |         } | 
 | 524 |     } | 
 | 525 | } | 
 | 526 |  | 
| Eino-Ville Talvala | c8474b6 | 2012-08-24 16:30:44 -0700 | [diff] [blame] | 527 | status_t Camera2Device::waitForNextFrame(nsecs_t timeout) { | 
 | 528 |     return mFrameQueue.waitForBuffer(timeout); | 
| Eino-Ville Talvala | 8ce89d9 | 2012-08-10 08:40:26 -0700 | [diff] [blame] | 529 | } | 
 | 530 |  | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 531 | status_t Camera2Device::getNextResult(CaptureResult *result) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 532 |     ATRACE_CALL(); | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 533 |     ALOGV("%s: get CaptureResult", __FUNCTION__); | 
 | 534 |     if (result == NULL) { | 
 | 535 |         ALOGE("%s: result pointer is NULL", __FUNCTION__); | 
 | 536 |         return BAD_VALUE; | 
 | 537 |     } | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 538 |     status_t res; | 
 | 539 |     camera_metadata_t *rawFrame; | 
 | 540 |     res = mFrameQueue.dequeue(&rawFrame); | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 541 |     if (rawFrame == NULL) { | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 542 |         return NOT_ENOUGH_DATA; | 
 | 543 |     } else if (res == OK) { | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 544 |         result->mMetadata.acquire(rawFrame); | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 545 |     } | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 546 |  | 
| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 547 |     return res; | 
| Eino-Ville Talvala | 8ce89d9 | 2012-08-10 08:40:26 -0700 | [diff] [blame] | 548 | } | 
 | 549 |  | 
| Eino-Ville Talvala | 174181e | 2012-08-03 13:53:39 -0700 | [diff] [blame] | 550 | status_t Camera2Device::triggerAutofocus(uint32_t id) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 551 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 174181e | 2012-08-03 13:53:39 -0700 | [diff] [blame] | 552 |     status_t res; | 
 | 553 |     ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id); | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 554 |     res = mHal2Device->ops->trigger_action(mHal2Device, | 
| Eino-Ville Talvala | 174181e | 2012-08-03 13:53:39 -0700 | [diff] [blame] | 555 |             CAMERA2_TRIGGER_AUTOFOCUS, id, 0); | 
 | 556 |     if (res != OK) { | 
 | 557 |         ALOGE("%s: Error triggering autofocus (id %d)", | 
 | 558 |                 __FUNCTION__, id); | 
 | 559 |     } | 
 | 560 |     return res; | 
 | 561 | } | 
 | 562 |  | 
 | 563 | status_t Camera2Device::triggerCancelAutofocus(uint32_t id) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 564 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 174181e | 2012-08-03 13:53:39 -0700 | [diff] [blame] | 565 |     status_t res; | 
 | 566 |     ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id); | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 567 |     res = mHal2Device->ops->trigger_action(mHal2Device, | 
| Eino-Ville Talvala | 174181e | 2012-08-03 13:53:39 -0700 | [diff] [blame] | 568 |             CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0); | 
 | 569 |     if (res != OK) { | 
 | 570 |         ALOGE("%s: Error canceling autofocus (id %d)", | 
 | 571 |                 __FUNCTION__, id); | 
 | 572 |     } | 
 | 573 |     return res; | 
 | 574 | } | 
 | 575 |  | 
 | 576 | status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 577 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 174181e | 2012-08-03 13:53:39 -0700 | [diff] [blame] | 578 |     status_t res; | 
 | 579 |     ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id); | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 580 |     res = mHal2Device->ops->trigger_action(mHal2Device, | 
| Eino-Ville Talvala | 174181e | 2012-08-03 13:53:39 -0700 | [diff] [blame] | 581 |             CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0); | 
 | 582 |     if (res != OK) { | 
 | 583 |         ALOGE("%s: Error triggering precapture metering (id %d)", | 
 | 584 |                 __FUNCTION__, id); | 
 | 585 |     } | 
 | 586 |     return res; | 
 | 587 | } | 
 | 588 |  | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 589 | status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId, | 
 | 590 |         buffer_handle_t *buffer, wp<BufferReleasedListener> listener) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 591 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 592 |     ALOGV("%s: E", __FUNCTION__); | 
 | 593 |     bool found = false; | 
 | 594 |     status_t res = OK; | 
 | 595 |     for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin(); | 
 | 596 |          streamI != mReprocessStreams.end(); streamI++) { | 
 | 597 |         if ((*streamI)->getId() == reprocessStreamId) { | 
 | 598 |             res = (*streamI)->pushIntoStream(buffer, listener); | 
 | 599 |             if (res != OK) { | 
 | 600 |                 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)", | 
 | 601 |                         __FUNCTION__, reprocessStreamId, strerror(-res), res); | 
 | 602 |                 return res; | 
 | 603 |             } | 
 | 604 |             found = true; | 
 | 605 |             break; | 
 | 606 |         } | 
 | 607 |     } | 
 | 608 |     if (!found) { | 
 | 609 |         ALOGE("%s: Camera %d: Unable to find reprocess stream %d", | 
 | 610 |                 __FUNCTION__, mId, reprocessStreamId); | 
 | 611 |         res = BAD_VALUE; | 
 | 612 |     } | 
 | 613 |     return res; | 
 | 614 | } | 
 | 615 |  | 
| Jianing Wei | cb0652e | 2014-03-12 18:29:36 -0700 | [diff] [blame] | 616 | status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) { | 
| Eino-Ville Talvala | abaa51d | 2013-08-14 11:37:00 -0700 | [diff] [blame] | 617 |     ATRACE_CALL(); | 
 | 618 |  | 
 | 619 |     mRequestQueue.clear(); | 
 | 620 |     return waitUntilDrained(); | 
 | 621 | } | 
 | 622 |  | 
| Eino-Ville Talvala | 4d44cad | 2015-04-11 13:15:45 -0700 | [diff] [blame] | 623 | status_t Camera2Device::prepare(int streamId) { | 
 | 624 |     ATRACE_CALL(); | 
 | 625 |     ALOGE("%s: Camera %d: unimplemented", __FUNCTION__, mId); | 
 | 626 |     return NO_INIT; | 
 | 627 | } | 
 | 628 |  | 
| Zhijun He | 204e329 | 2014-07-14 17:09:23 -0700 | [diff] [blame] | 629 | uint32_t Camera2Device::getDeviceVersion() { | 
 | 630 |     ATRACE_CALL(); | 
 | 631 |     return mDeviceVersion; | 
 | 632 | } | 
 | 633 |  | 
| Eino-Ville Talvala | 160d4af | 2012-08-03 09:40:16 -0700 | [diff] [blame] | 634 | /** | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 635 |  * Camera2Device::MetadataQueue | 
 | 636 |  */ | 
 | 637 |  | 
 | 638 | Camera2Device::MetadataQueue::MetadataQueue(): | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 639 |             mHal2Device(NULL), | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 640 |             mFrameCount(0), | 
| Eino-Ville Talvala | 4c9eb71 | 2012-10-02 13:30:28 -0700 | [diff] [blame] | 641 |             mLatestRequestId(0), | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 642 |             mCount(0), | 
 | 643 |             mStreamSlotCount(0), | 
| Eino-Ville Talvala | c8474b6 | 2012-08-24 16:30:44 -0700 | [diff] [blame] | 644 |             mSignalConsumer(true) | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 645 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 646 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 647 |     camera2_request_queue_src_ops::dequeue_request = consumer_dequeue; | 
 | 648 |     camera2_request_queue_src_ops::request_count = consumer_buffer_count; | 
 | 649 |     camera2_request_queue_src_ops::free_request = consumer_free; | 
 | 650 |  | 
 | 651 |     camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue; | 
 | 652 |     camera2_frame_queue_dst_ops::cancel_frame = producer_cancel; | 
 | 653 |     camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue; | 
 | 654 | } | 
 | 655 |  | 
 | 656 | Camera2Device::MetadataQueue::~MetadataQueue() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 657 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | abaa51d | 2013-08-14 11:37:00 -0700 | [diff] [blame] | 658 |     clear(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 659 | } | 
 | 660 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 661 | // Connect to camera2 HAL as consumer (input requests/reprocessing) | 
 | 662 | status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 663 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 664 |     status_t res; | 
 | 665 |     res = d->ops->set_request_queue_src_ops(d, | 
 | 666 |             this); | 
 | 667 |     if (res != OK) return res; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 668 |     mHal2Device = d; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 669 |     return OK; | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 670 | } | 
 | 671 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 672 | status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 673 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 674 |     status_t res; | 
 | 675 |     res = d->ops->set_frame_queue_dst_ops(d, | 
 | 676 |             this); | 
 | 677 |     return res; | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 678 | } | 
 | 679 |  | 
 | 680 | // Real interfaces | 
 | 681 | status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 682 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 2c08dc6 | 2012-06-15 12:49:21 -0700 | [diff] [blame] | 683 |     ALOGVV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 684 |     Mutex::Autolock l(mMutex); | 
 | 685 |  | 
 | 686 |     mCount++; | 
 | 687 |     mEntries.push_back(buf); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 688 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 689 |     return signalConsumerLocked(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 690 | } | 
 | 691 |  | 
 | 692 | int Camera2Device::MetadataQueue::getBufferCount() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 693 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 694 |     Mutex::Autolock l(mMutex); | 
 | 695 |     if (mStreamSlotCount > 0) { | 
 | 696 |         return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS; | 
 | 697 |     } | 
 | 698 |     return mCount; | 
 | 699 | } | 
 | 700 |  | 
 | 701 | status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf, | 
 | 702 |         bool incrementCount) | 
 | 703 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 704 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 2c08dc6 | 2012-06-15 12:49:21 -0700 | [diff] [blame] | 705 |     ALOGVV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 706 |     status_t res; | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 707 |     Mutex::Autolock l(mMutex); | 
 | 708 |  | 
 | 709 |     if (mCount == 0) { | 
 | 710 |         if (mStreamSlotCount == 0) { | 
| Eino-Ville Talvala | 2c08dc6 | 2012-06-15 12:49:21 -0700 | [diff] [blame] | 711 |             ALOGVV("%s: Empty", __FUNCTION__); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 712 |             *buf = NULL; | 
 | 713 |             mSignalConsumer = true; | 
 | 714 |             return OK; | 
 | 715 |         } | 
| Eino-Ville Talvala | 2c08dc6 | 2012-06-15 12:49:21 -0700 | [diff] [blame] | 716 |         ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__, | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 717 |               mStreamSlotCount); | 
 | 718 |  | 
 | 719 |         for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin(); | 
 | 720 |                 slotEntry != mStreamSlot.end(); | 
 | 721 |                 slotEntry++ ) { | 
 | 722 |             size_t entries = get_camera_metadata_entry_count(*slotEntry); | 
 | 723 |             size_t dataBytes = get_camera_metadata_data_count(*slotEntry); | 
 | 724 |  | 
 | 725 |             camera_metadata_t *copy = | 
 | 726 |                     allocate_camera_metadata(entries, dataBytes); | 
 | 727 |             append_camera_metadata(copy, *slotEntry); | 
 | 728 |             mEntries.push_back(copy); | 
 | 729 |         } | 
 | 730 |         mCount = mStreamSlotCount; | 
 | 731 |     } | 
| Eino-Ville Talvala | 2c08dc6 | 2012-06-15 12:49:21 -0700 | [diff] [blame] | 732 |     ALOGVV("MetadataQueue: deque (%d buffers)", mCount); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 733 |     camera_metadata_t *b = *(mEntries.begin()); | 
 | 734 |     mEntries.erase(mEntries.begin()); | 
 | 735 |  | 
 | 736 |     if (incrementCount) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 737 |         ATRACE_INT("cam2_request", mFrameCount); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 738 |         camera_metadata_entry_t frameCount; | 
 | 739 |         res = find_camera_metadata_entry(b, | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 740 |                 ANDROID_REQUEST_FRAME_COUNT, | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 741 |                 &frameCount); | 
 | 742 |         if (res != OK) { | 
 | 743 |             ALOGE("%s: Unable to add frame count: %s (%d)", | 
 | 744 |                     __FUNCTION__, strerror(-res), res); | 
 | 745 |         } else { | 
 | 746 |             *frameCount.data.i32 = mFrameCount; | 
 | 747 |         } | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 748 |         mFrameCount++; | 
 | 749 |     } | 
 | 750 |  | 
| Eino-Ville Talvala | 4c9eb71 | 2012-10-02 13:30:28 -0700 | [diff] [blame] | 751 |     // Check for request ID, and if present, signal waiters. | 
 | 752 |     camera_metadata_entry_t requestId; | 
 | 753 |     res = find_camera_metadata_entry(b, | 
 | 754 |             ANDROID_REQUEST_ID, | 
 | 755 |             &requestId); | 
 | 756 |     if (res == OK) { | 
 | 757 |         mLatestRequestId = requestId.data.i32[0]; | 
 | 758 |         mNewRequestId.signal(); | 
 | 759 |     } | 
 | 760 |  | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 761 |     *buf = b; | 
 | 762 |     mCount--; | 
 | 763 |  | 
 | 764 |     return OK; | 
 | 765 | } | 
 | 766 |  | 
 | 767 | status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout) | 
 | 768 | { | 
 | 769 |     Mutex::Autolock l(mMutex); | 
 | 770 |     status_t res; | 
 | 771 |     while (mCount == 0) { | 
 | 772 |         res = notEmpty.waitRelative(mMutex,timeout); | 
 | 773 |         if (res != OK) return res; | 
 | 774 |     } | 
 | 775 |     return OK; | 
 | 776 | } | 
 | 777 |  | 
| Eino-Ville Talvala | 4c9eb71 | 2012-10-02 13:30:28 -0700 | [diff] [blame] | 778 | status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id, | 
 | 779 |         nsecs_t timeout) { | 
 | 780 |     Mutex::Autolock l(mMutex); | 
 | 781 |     status_t res; | 
 | 782 |     while (mLatestRequestId != id) { | 
 | 783 |         nsecs_t startTime = systemTime(); | 
 | 784 |  | 
 | 785 |         res = mNewRequestId.waitRelative(mMutex, timeout); | 
 | 786 |         if (res != OK) return res; | 
 | 787 |  | 
 | 788 |         timeout -= (systemTime() - startTime); | 
 | 789 |     } | 
 | 790 |  | 
 | 791 |     return OK; | 
 | 792 | } | 
 | 793 |  | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 794 | status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf) | 
 | 795 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 796 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 797 |     ALOGV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 798 |     Mutex::Autolock l(mMutex); | 
 | 799 |     if (buf == NULL) { | 
 | 800 |         freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); | 
 | 801 |         mStreamSlotCount = 0; | 
 | 802 |         return OK; | 
 | 803 |     } | 
| Eino-Ville Talvala | 6ed1ed1 | 2012-06-07 10:46:38 -0700 | [diff] [blame] | 804 |  | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 805 |     if (mStreamSlotCount > 1) { | 
 | 806 |         List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin(); | 
 | 807 |         freeBuffers(++mStreamSlot.begin(), mStreamSlot.end()); | 
 | 808 |         mStreamSlotCount = 1; | 
 | 809 |     } | 
 | 810 |     if (mStreamSlotCount == 1) { | 
 | 811 |         free_camera_metadata( *(mStreamSlot.begin()) ); | 
| Chien-Yu Chen | 80de5dc | 2014-11-07 17:45:00 -0800 | [diff] [blame] | 812 |         *(mStreamSlot.begin()) = buf; | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 813 |     } else { | 
| Chien-Yu Chen | 80de5dc | 2014-11-07 17:45:00 -0800 | [diff] [blame] | 814 |         mStreamSlot.push_front(buf); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 815 |         mStreamSlotCount = 1; | 
 | 816 |     } | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 817 |     return signalConsumerLocked(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 818 | } | 
 | 819 |  | 
 | 820 | status_t Camera2Device::MetadataQueue::setStreamSlot( | 
 | 821 |         const List<camera_metadata_t*> &bufs) | 
 | 822 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 823 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 824 |     ALOGV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 825 |     Mutex::Autolock l(mMutex); | 
| Eino-Ville Talvala | 6ed1ed1 | 2012-06-07 10:46:38 -0700 | [diff] [blame] | 826 |  | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 827 |     if (mStreamSlotCount > 0) { | 
 | 828 |         freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); | 
 | 829 |     } | 
| Eino-Ville Talvala | 6ed1ed1 | 2012-06-07 10:46:38 -0700 | [diff] [blame] | 830 |     mStreamSlotCount = 0; | 
 | 831 |     for (List<camera_metadata_t*>::const_iterator r = bufs.begin(); | 
 | 832 |          r != bufs.end(); r++) { | 
| Chien-Yu Chen | 80de5dc | 2014-11-07 17:45:00 -0800 | [diff] [blame] | 833 |         mStreamSlot.push_back(*r); | 
| Eino-Ville Talvala | 6ed1ed1 | 2012-06-07 10:46:38 -0700 | [diff] [blame] | 834 |         mStreamSlotCount++; | 
 | 835 |     } | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 836 |     return signalConsumerLocked(); | 
 | 837 | } | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 838 |  | 
| Eino-Ville Talvala | abaa51d | 2013-08-14 11:37:00 -0700 | [diff] [blame] | 839 | status_t Camera2Device::MetadataQueue::clear() | 
 | 840 | { | 
 | 841 |     ATRACE_CALL(); | 
 | 842 |     ALOGV("%s: E", __FUNCTION__); | 
 | 843 |  | 
 | 844 |     Mutex::Autolock l(mMutex); | 
 | 845 |  | 
 | 846 |     // Clear streaming slot | 
 | 847 |     freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); | 
 | 848 |     mStreamSlotCount = 0; | 
 | 849 |  | 
 | 850 |     // Clear request queue | 
 | 851 |     freeBuffers(mEntries.begin(), mEntries.end()); | 
 | 852 |     mCount = 0; | 
 | 853 |     return OK; | 
 | 854 | } | 
 | 855 |  | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 856 | status_t Camera2Device::MetadataQueue::dump(int fd, | 
| Igor Murashkin | ebe3f69 | 2012-10-12 16:56:11 -0700 | [diff] [blame] | 857 |         const Vector<String16>& /*args*/) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 858 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 859 |     String8 result; | 
 | 860 |     status_t notLocked; | 
 | 861 |     notLocked = mMutex.tryLock(); | 
 | 862 |     if (notLocked) { | 
 | 863 |         result.append("    (Unable to lock queue mutex)\n"); | 
 | 864 |     } | 
 | 865 |     result.appendFormat("      Current frame number: %d\n", mFrameCount); | 
 | 866 |     if (mStreamSlotCount == 0) { | 
 | 867 |         result.append("      Stream slot: Empty\n"); | 
 | 868 |         write(fd, result.string(), result.size()); | 
 | 869 |     } else { | 
| Kévin PETIT | 377b2ec | 2014-02-03 12:35:36 +0000 | [diff] [blame] | 870 |         result.appendFormat("      Stream slot: %zu entries\n", | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 871 |                 mStreamSlot.size()); | 
 | 872 |         int i = 0; | 
 | 873 |         for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin(); | 
 | 874 |              r != mStreamSlot.end(); r++) { | 
 | 875 |             result = String8::format("       Stream slot buffer %d:\n", i); | 
 | 876 |             write(fd, result.string(), result.size()); | 
| Eino-Ville Talvala | 428b77a | 2012-07-30 09:55:30 -0700 | [diff] [blame] | 877 |             dump_indented_camera_metadata(*r, fd, 2, 10); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 878 |             i++; | 
 | 879 |         } | 
 | 880 |     } | 
 | 881 |     if (mEntries.size() == 0) { | 
 | 882 |         result = "      Main queue is empty\n"; | 
 | 883 |         write(fd, result.string(), result.size()); | 
 | 884 |     } else { | 
| Kévin PETIT | 377b2ec | 2014-02-03 12:35:36 +0000 | [diff] [blame] | 885 |         result = String8::format("      Main queue has %zu entries:\n", | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 886 |                 mEntries.size()); | 
 | 887 |         int i = 0; | 
 | 888 |         for (List<camera_metadata_t*>::iterator r = mEntries.begin(); | 
 | 889 |              r != mEntries.end(); r++) { | 
 | 890 |             result = String8::format("       Queue entry %d:\n", i); | 
 | 891 |             write(fd, result.string(), result.size()); | 
| Eino-Ville Talvala | 428b77a | 2012-07-30 09:55:30 -0700 | [diff] [blame] | 892 |             dump_indented_camera_metadata(*r, fd, 2, 10); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 893 |             i++; | 
 | 894 |         } | 
 | 895 |     } | 
 | 896 |  | 
 | 897 |     if (notLocked == 0) { | 
 | 898 |         mMutex.unlock(); | 
 | 899 |     } | 
 | 900 |  | 
 | 901 |     return OK; | 
 | 902 | } | 
 | 903 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 904 | status_t Camera2Device::MetadataQueue::signalConsumerLocked() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 905 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 906 |     status_t res = OK; | 
 | 907 |     notEmpty.signal(); | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 908 |     if (mSignalConsumer && mHal2Device != NULL) { | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 909 |         mSignalConsumer = false; | 
 | 910 |  | 
 | 911 |         mMutex.unlock(); | 
 | 912 |         ALOGV("%s: Signaling consumer", __FUNCTION__); | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 913 |         res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 914 |         mMutex.lock(); | 
 | 915 |     } | 
 | 916 |     return res; | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 917 | } | 
 | 918 |  | 
 | 919 | status_t Camera2Device::MetadataQueue::freeBuffers( | 
 | 920 |         List<camera_metadata_t*>::iterator start, | 
 | 921 |         List<camera_metadata_t*>::iterator end) | 
 | 922 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 923 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 924 |     while (start != end) { | 
 | 925 |         free_camera_metadata(*start); | 
 | 926 |         start = mStreamSlot.erase(start); | 
 | 927 |     } | 
 | 928 |     return OK; | 
 | 929 | } | 
 | 930 |  | 
 | 931 | Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance( | 
 | 932 |         const camera2_request_queue_src_ops_t *q) | 
 | 933 | { | 
 | 934 |     const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); | 
 | 935 |     return const_cast<MetadataQueue*>(cmq); | 
 | 936 | } | 
 | 937 |  | 
 | 938 | Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance( | 
 | 939 |         const camera2_frame_queue_dst_ops_t *q) | 
 | 940 | { | 
 | 941 |     const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); | 
 | 942 |     return const_cast<MetadataQueue*>(cmq); | 
 | 943 | } | 
 | 944 |  | 
 | 945 | int Camera2Device::MetadataQueue::consumer_buffer_count( | 
 | 946 |         const camera2_request_queue_src_ops_t *q) | 
 | 947 | { | 
 | 948 |     MetadataQueue *queue = getInstance(q); | 
 | 949 |     return queue->getBufferCount(); | 
 | 950 | } | 
 | 951 |  | 
 | 952 | int Camera2Device::MetadataQueue::consumer_dequeue( | 
 | 953 |         const camera2_request_queue_src_ops_t *q, | 
 | 954 |         camera_metadata_t **buffer) | 
 | 955 | { | 
 | 956 |     MetadataQueue *queue = getInstance(q); | 
 | 957 |     return queue->dequeue(buffer, true); | 
 | 958 | } | 
 | 959 |  | 
 | 960 | int Camera2Device::MetadataQueue::consumer_free( | 
 | 961 |         const camera2_request_queue_src_ops_t *q, | 
 | 962 |         camera_metadata_t *old_buffer) | 
 | 963 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 964 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 965 |     MetadataQueue *queue = getInstance(q); | 
| Igor Murashkin | ebe3f69 | 2012-10-12 16:56:11 -0700 | [diff] [blame] | 966 |     (void)queue; | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 967 |     free_camera_metadata(old_buffer); | 
 | 968 |     return OK; | 
 | 969 | } | 
 | 970 |  | 
 | 971 | int Camera2Device::MetadataQueue::producer_dequeue( | 
| Igor Murashkin | ebe3f69 | 2012-10-12 16:56:11 -0700 | [diff] [blame] | 972 |         const camera2_frame_queue_dst_ops_t * /*q*/, | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 973 |         size_t entries, size_t bytes, | 
 | 974 |         camera_metadata_t **buffer) | 
 | 975 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 976 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 977 |     camera_metadata_t *new_buffer = | 
 | 978 |             allocate_camera_metadata(entries, bytes); | 
 | 979 |     if (new_buffer == NULL) return NO_MEMORY; | 
 | 980 |     *buffer = new_buffer; | 
 | 981 |         return OK; | 
 | 982 | } | 
 | 983 |  | 
 | 984 | int Camera2Device::MetadataQueue::producer_cancel( | 
| Igor Murashkin | ebe3f69 | 2012-10-12 16:56:11 -0700 | [diff] [blame] | 985 |         const camera2_frame_queue_dst_ops_t * /*q*/, | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 986 |         camera_metadata_t *old_buffer) | 
 | 987 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 988 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | f69c70d | 2012-05-20 15:59:14 -0700 | [diff] [blame] | 989 |     free_camera_metadata(old_buffer); | 
 | 990 |     return OK; | 
 | 991 | } | 
 | 992 |  | 
 | 993 | int Camera2Device::MetadataQueue::producer_enqueue( | 
 | 994 |         const camera2_frame_queue_dst_ops_t *q, | 
 | 995 |         camera_metadata_t *filled_buffer) | 
 | 996 | { | 
 | 997 |     MetadataQueue *queue = getInstance(q); | 
 | 998 |     return queue->enqueue(filled_buffer); | 
 | 999 | } | 
 | 1000 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1001 | /** | 
 | 1002 |  * Camera2Device::StreamAdapter | 
 | 1003 |  */ | 
 | 1004 |  | 
 | 1005 | #ifndef container_of | 
 | 1006 | #define container_of(ptr, type, member) \ | 
 | 1007 |     (type *)((char*)(ptr) - offsetof(type, member)) | 
 | 1008 | #endif | 
 | 1009 |  | 
 | 1010 | Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d): | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1011 |         mState(RELEASED), | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 1012 |         mHal2Device(d), | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1013 |         mId(-1), | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1014 |         mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0), | 
 | 1015 |         mMaxProducerBuffers(0), mMaxConsumerBuffers(0), | 
 | 1016 |         mTotalBuffers(0), | 
 | 1017 |         mFormatRequested(0), | 
 | 1018 |         mActiveBuffers(0), | 
 | 1019 |         mFrameCount(0), | 
 | 1020 |         mLastTimestamp(0) | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1021 | { | 
 | 1022 |     camera2_stream_ops::dequeue_buffer = dequeue_buffer; | 
 | 1023 |     camera2_stream_ops::enqueue_buffer = enqueue_buffer; | 
 | 1024 |     camera2_stream_ops::cancel_buffer = cancel_buffer; | 
 | 1025 |     camera2_stream_ops::set_crop = set_crop; | 
 | 1026 | } | 
 | 1027 |  | 
 | 1028 | Camera2Device::StreamAdapter::~StreamAdapter() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1029 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1030 |     if (mState != RELEASED) { | 
 | 1031 |         release(); | 
 | 1032 |     } | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1033 | } | 
 | 1034 |  | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 1035 | status_t Camera2Device::StreamAdapter::connectToDevice( | 
 | 1036 |         sp<ANativeWindow> consumer, | 
 | 1037 |         uint32_t width, uint32_t height, int format, size_t size) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1038 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1039 |     status_t res; | 
| Eino-Ville Talvala | 9e4c3db | 2012-07-20 11:07:52 -0700 | [diff] [blame] | 1040 |     ALOGV("%s: E", __FUNCTION__); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1041 |  | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1042 |     if (mState != RELEASED) return INVALID_OPERATION; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1043 |     if (consumer == NULL) { | 
 | 1044 |         ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__); | 
 | 1045 |         return BAD_VALUE; | 
 | 1046 |     } | 
 | 1047 |  | 
| Colin Cross | e5729fa | 2014-03-21 15:04:25 -0700 | [diff] [blame] | 1048 |     ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu", | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1049 |             __FUNCTION__, width, height, format, size); | 
 | 1050 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1051 |     mConsumerInterface = consumer; | 
 | 1052 |     mWidth = width; | 
 | 1053 |     mHeight = height; | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 1054 |     mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1055 |     mFormatRequested = format; | 
 | 1056 |  | 
 | 1057 |     // Allocate device-side stream interface | 
 | 1058 |  | 
 | 1059 |     uint32_t id; | 
 | 1060 |     uint32_t formatActual; | 
 | 1061 |     uint32_t usage; | 
 | 1062 |     uint32_t maxBuffers = 2; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 1063 |     res = mHal2Device->ops->allocate_stream(mHal2Device, | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1064 |             mWidth, mHeight, mFormatRequested, getStreamOps(), | 
 | 1065 |             &id, &formatActual, &usage, &maxBuffers); | 
 | 1066 |     if (res != OK) { | 
 | 1067 |         ALOGE("%s: Device stream allocation failed: %s (%d)", | 
 | 1068 |                 __FUNCTION__, strerror(-res), res); | 
 | 1069 |         return res; | 
 | 1070 |     } | 
 | 1071 |  | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1072 |     ALOGV("%s: Allocated stream id %d, actual format 0x%x, " | 
 | 1073 |             "usage 0x%x, producer wants %d buffers", __FUNCTION__, | 
 | 1074 |             id, formatActual, usage, maxBuffers); | 
 | 1075 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1076 |     mId = id; | 
 | 1077 |     mFormat = formatActual; | 
 | 1078 |     mUsage = usage; | 
 | 1079 |     mMaxProducerBuffers = maxBuffers; | 
 | 1080 |  | 
 | 1081 |     mState = ALLOCATED; | 
 | 1082 |  | 
 | 1083 |     // Configure consumer-side ANativeWindow interface | 
 | 1084 |     res = native_window_api_connect(mConsumerInterface.get(), | 
 | 1085 |             NATIVE_WINDOW_API_CAMERA); | 
 | 1086 |     if (res != OK) { | 
 | 1087 |         ALOGE("%s: Unable to connect to native window for stream %d", | 
 | 1088 |                 __FUNCTION__, mId); | 
 | 1089 |  | 
 | 1090 |         return res; | 
 | 1091 |     } | 
 | 1092 |  | 
 | 1093 |     mState = CONNECTED; | 
 | 1094 |  | 
 | 1095 |     res = native_window_set_usage(mConsumerInterface.get(), mUsage); | 
 | 1096 |     if (res != OK) { | 
 | 1097 |         ALOGE("%s: Unable to configure usage %08x for stream %d", | 
 | 1098 |                 __FUNCTION__, mUsage, mId); | 
 | 1099 |         return res; | 
 | 1100 |     } | 
 | 1101 |  | 
| Eino-Ville Talvala | bd4976a | 2012-06-07 10:40:25 -0700 | [diff] [blame] | 1102 |     res = native_window_set_scaling_mode(mConsumerInterface.get(), | 
 | 1103 |             NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); | 
 | 1104 |     if (res != OK) { | 
 | 1105 |         ALOGE("%s: Unable to configure stream scaling: %s (%d)", | 
 | 1106 |                 __FUNCTION__, strerror(-res), res); | 
 | 1107 |         return res; | 
 | 1108 |     } | 
 | 1109 |  | 
| Eino-Ville Talvala | c94cd19 | 2012-06-15 12:47:42 -0700 | [diff] [blame] | 1110 |     res = setTransform(0); | 
| Eino-Ville Talvala | bd4976a | 2012-06-07 10:40:25 -0700 | [diff] [blame] | 1111 |     if (res != OK) { | 
| Eino-Ville Talvala | bd4976a | 2012-06-07 10:40:25 -0700 | [diff] [blame] | 1112 |         return res; | 
 | 1113 |     } | 
 | 1114 |  | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 1115 |     if (mFormat == HAL_PIXEL_FORMAT_BLOB) { | 
| Eino-Ville Talvala | 7d70c5e | 2014-07-24 18:10:23 -0700 | [diff] [blame] | 1116 |         res = native_window_set_buffers_dimensions(mConsumerInterface.get(), | 
 | 1117 |                 mSize, 1); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 1118 |         if (res != OK) { | 
| Eino-Ville Talvala | 7d70c5e | 2014-07-24 18:10:23 -0700 | [diff] [blame] | 1119 |             ALOGE("%s: Unable to configure compressed stream buffer dimensions" | 
| Colin Cross | e5729fa | 2014-03-21 15:04:25 -0700 | [diff] [blame] | 1120 |                     " %d x %d, size %zu for stream %d", | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 1121 |                     __FUNCTION__, mWidth, mHeight, mSize, mId); | 
 | 1122 |             return res; | 
 | 1123 |         } | 
 | 1124 |     } else { | 
| Eino-Ville Talvala | 7d70c5e | 2014-07-24 18:10:23 -0700 | [diff] [blame] | 1125 |         res = native_window_set_buffers_dimensions(mConsumerInterface.get(), | 
 | 1126 |                 mWidth, mHeight); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 1127 |         if (res != OK) { | 
| Eino-Ville Talvala | 7d70c5e | 2014-07-24 18:10:23 -0700 | [diff] [blame] | 1128 |             ALOGE("%s: Unable to configure stream buffer dimensions" | 
 | 1129 |                     " %d x %d for stream %d", | 
 | 1130 |                     __FUNCTION__, mWidth, mHeight, mId); | 
| Eino-Ville Talvala | d4bcfde | 2012-06-07 17:12:38 -0700 | [diff] [blame] | 1131 |             return res; | 
 | 1132 |         } | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1133 |     } | 
 | 1134 |  | 
| Eino-Ville Talvala | 7d70c5e | 2014-07-24 18:10:23 -0700 | [diff] [blame] | 1135 |     res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat); | 
 | 1136 |     if (res != OK) { | 
 | 1137 |         ALOGE("%s: Unable to configure stream buffer format" | 
 | 1138 |                 " %#x for stream %d", | 
 | 1139 |                 __FUNCTION__, mFormat, mId); | 
 | 1140 |         return res; | 
 | 1141 |     } | 
 | 1142 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1143 |     int maxConsumerBuffers; | 
 | 1144 |     res = mConsumerInterface->query(mConsumerInterface.get(), | 
 | 1145 |             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers); | 
 | 1146 |     if (res != OK) { | 
 | 1147 |         ALOGE("%s: Unable to query consumer undequeued" | 
 | 1148 |                 " buffer count for stream %d", __FUNCTION__, mId); | 
 | 1149 |         return res; | 
 | 1150 |     } | 
 | 1151 |     mMaxConsumerBuffers = maxConsumerBuffers; | 
 | 1152 |  | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1153 |     ALOGV("%s: Consumer wants %d buffers", __FUNCTION__, | 
 | 1154 |             mMaxConsumerBuffers); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1155 |  | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1156 |     mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers; | 
 | 1157 |     mActiveBuffers = 0; | 
 | 1158 |     mFrameCount = 0; | 
 | 1159 |     mLastTimestamp = 0; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1160 |  | 
 | 1161 |     res = native_window_set_buffer_count(mConsumerInterface.get(), | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1162 |             mTotalBuffers); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1163 |     if (res != OK) { | 
 | 1164 |         ALOGE("%s: Unable to set buffer count for stream %d", | 
 | 1165 |                 __FUNCTION__, mId); | 
 | 1166 |         return res; | 
 | 1167 |     } | 
 | 1168 |  | 
 | 1169 |     // Register allocated buffers with HAL device | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1170 |     buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers]; | 
 | 1171 |     ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers]; | 
 | 1172 |     uint32_t bufferIdx = 0; | 
 | 1173 |     for (; bufferIdx < mTotalBuffers; bufferIdx++) { | 
| Jamie Gennis | 1e5b2b3 | 2012-06-13 16:29:51 -0700 | [diff] [blame] | 1174 |         res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(), | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1175 |                 &anwBuffers[bufferIdx]); | 
 | 1176 |         if (res != OK) { | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1177 |             ALOGE("%s: Unable to dequeue buffer %d for initial registration for " | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1178 |                     "stream %d", __FUNCTION__, bufferIdx, mId); | 
 | 1179 |             goto cleanUpBuffers; | 
 | 1180 |         } | 
 | 1181 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1182 |         buffers[bufferIdx] = anwBuffers[bufferIdx]->handle; | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1183 |         ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1184 |     } | 
 | 1185 |  | 
| Eino-Ville Talvala | 750d74b | 2012-08-01 09:05:04 -0700 | [diff] [blame] | 1186 |     ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers); | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 1187 |     res = mHal2Device->ops->register_stream_buffers(mHal2Device, | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1188 |             mId, | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1189 |             mTotalBuffers, | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1190 |             buffers); | 
 | 1191 |     if (res != OK) { | 
 | 1192 |         ALOGE("%s: Unable to register buffers with HAL device for stream %d", | 
 | 1193 |                 __FUNCTION__, mId); | 
 | 1194 |     } else { | 
 | 1195 |         mState = ACTIVE; | 
 | 1196 |     } | 
 | 1197 |  | 
 | 1198 | cleanUpBuffers: | 
| Eino-Ville Talvala | 750d74b | 2012-08-01 09:05:04 -0700 | [diff] [blame] | 1199 |     ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1200 |     for (uint32_t i = 0; i < bufferIdx; i++) { | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1201 |         res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(), | 
| Jamie Gennis | 1e5b2b3 | 2012-06-13 16:29:51 -0700 | [diff] [blame] | 1202 |                 anwBuffers[i], -1); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1203 |         if (res != OK) { | 
 | 1204 |             ALOGE("%s: Unable to cancel buffer %d after registration", | 
 | 1205 |                     __FUNCTION__, i); | 
 | 1206 |         } | 
 | 1207 |     } | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1208 |     delete[] anwBuffers; | 
 | 1209 |     delete[] buffers; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1210 |  | 
 | 1211 |     return res; | 
 | 1212 | } | 
 | 1213 |  | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1214 | status_t Camera2Device::StreamAdapter::release() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1215 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1216 |     status_t res; | 
| Eino-Ville Talvala | 02f8457 | 2013-04-23 15:16:57 -0700 | [diff] [blame] | 1217 |     ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId, | 
 | 1218 |             mWidth, mHeight, mFormat); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1219 |     if (mState >= ALLOCATED) { | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 1220 |         res = mHal2Device->ops->release_stream(mHal2Device, mId); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1221 |         if (res != OK) { | 
 | 1222 |             ALOGE("%s: Unable to release stream %d", | 
 | 1223 |                     __FUNCTION__, mId); | 
 | 1224 |             return res; | 
 | 1225 |         } | 
 | 1226 |     } | 
 | 1227 |     if (mState >= CONNECTED) { | 
 | 1228 |         res = native_window_api_disconnect(mConsumerInterface.get(), | 
 | 1229 |                 NATIVE_WINDOW_API_CAMERA); | 
| Igor Murashkin | a1e5dcc | 2012-10-02 15:21:31 -0700 | [diff] [blame] | 1230 |  | 
 | 1231 |         /* this is not an error. if client calling process dies, | 
 | 1232 |            the window will also die and all calls to it will return | 
 | 1233 |            DEAD_OBJECT, thus it's already "disconnected" */ | 
 | 1234 |         if (res == DEAD_OBJECT) { | 
 | 1235 |             ALOGW("%s: While disconnecting stream %d from native window, the" | 
 | 1236 |                   " native window died from under us", __FUNCTION__, mId); | 
 | 1237 |         } | 
 | 1238 |         else if (res != OK) { | 
 | 1239 |             ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)", | 
 | 1240 |                     __FUNCTION__, mId, res, strerror(-res)); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1241 |             return res; | 
 | 1242 |         } | 
 | 1243 |     } | 
 | 1244 |     mId = -1; | 
| Eino-Ville Talvala | 9cca4c6 | 2012-06-15 15:41:44 -0700 | [diff] [blame] | 1245 |     mState = RELEASED; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1246 |     return OK; | 
 | 1247 | } | 
 | 1248 |  | 
| Eino-Ville Talvala | c94cd19 | 2012-06-15 12:47:42 -0700 | [diff] [blame] | 1249 | status_t Camera2Device::StreamAdapter::setTransform(int transform) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1250 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | c94cd19 | 2012-06-15 12:47:42 -0700 | [diff] [blame] | 1251 |     status_t res; | 
 | 1252 |     if (mState < CONNECTED) { | 
 | 1253 |         ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__); | 
 | 1254 |         return INVALID_OPERATION; | 
 | 1255 |     } | 
 | 1256 |     res = native_window_set_buffers_transform(mConsumerInterface.get(), | 
 | 1257 |                                               transform); | 
 | 1258 |     if (res != OK) { | 
 | 1259 |         ALOGE("%s: Unable to configure stream transform to %x: %s (%d)", | 
 | 1260 |                 __FUNCTION__, transform, strerror(-res), res); | 
 | 1261 |     } | 
 | 1262 |     return res; | 
 | 1263 | } | 
 | 1264 |  | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1265 | status_t Camera2Device::StreamAdapter::dump(int fd, | 
| Igor Murashkin | ebe3f69 | 2012-10-12 16:56:11 -0700 | [diff] [blame] | 1266 |         const Vector<String16>& /*args*/) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1267 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1268 |     String8 result = String8::format("      Stream %d: %d x %d, format 0x%x\n", | 
 | 1269 |             mId, mWidth, mHeight, mFormat); | 
| Kévin PETIT | 377b2ec | 2014-02-03 12:35:36 +0000 | [diff] [blame] | 1270 |     result.appendFormat("        size %zu, usage 0x%x, requested format 0x%x\n", | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1271 |             mSize, mUsage, mFormatRequested); | 
 | 1272 |     result.appendFormat("        total buffers: %d, dequeued buffers: %d\n", | 
 | 1273 |             mTotalBuffers, mActiveBuffers); | 
| Kévin PETIT | 377b2ec | 2014-02-03 12:35:36 +0000 | [diff] [blame] | 1274 |     result.appendFormat("        frame count: %d, last timestamp %" PRId64 "\n", | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1275 |             mFrameCount, mLastTimestamp); | 
 | 1276 |     write(fd, result.string(), result.size()); | 
 | 1277 |     return OK; | 
 | 1278 | } | 
 | 1279 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1280 | const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() { | 
 | 1281 |     return static_cast<camera2_stream_ops *>(this); | 
 | 1282 | } | 
 | 1283 |  | 
 | 1284 | ANativeWindow* Camera2Device::StreamAdapter::toANW( | 
 | 1285 |         const camera2_stream_ops_t *w) { | 
 | 1286 |     return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get(); | 
 | 1287 | } | 
 | 1288 |  | 
 | 1289 | int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w, | 
 | 1290 |         buffer_handle_t** buffer) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1291 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1292 |     int res; | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1293 |     StreamAdapter* stream = | 
 | 1294 |             const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); | 
 | 1295 |     if (stream->mState != ACTIVE) { | 
 | 1296 |         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1297 |         return INVALID_OPERATION; | 
 | 1298 |     } | 
 | 1299 |  | 
 | 1300 |     ANativeWindow *a = toANW(w); | 
 | 1301 |     ANativeWindowBuffer* anb; | 
| Jamie Gennis | 1e5b2b3 | 2012-06-13 16:29:51 -0700 | [diff] [blame] | 1302 |     res = native_window_dequeue_buffer_and_wait(a, &anb); | 
| Eino-Ville Talvala | 750d74b | 2012-08-01 09:05:04 -0700 | [diff] [blame] | 1303 |     if (res != OK) { | 
 | 1304 |         ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId, | 
 | 1305 |                 strerror(-res), res); | 
 | 1306 |         return res; | 
 | 1307 |     } | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1308 |  | 
 | 1309 |     *buffer = &(anb->handle); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1310 |     stream->mActiveBuffers++; | 
 | 1311 |  | 
| Eino-Ville Talvala | 750d74b | 2012-08-01 09:05:04 -0700 | [diff] [blame] | 1312 |     ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer)); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1313 |     return res; | 
 | 1314 | } | 
 | 1315 |  | 
 | 1316 | int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w, | 
 | 1317 |         int64_t timestamp, | 
 | 1318 |         buffer_handle_t* buffer) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1319 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1320 |     StreamAdapter *stream = | 
 | 1321 |             const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); | 
| Eino-Ville Talvala | 228a538 | 2012-08-13 12:16:06 -0700 | [diff] [blame] | 1322 |     stream->mFrameCount++; | 
 | 1323 |     ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns", | 
| James Dong | a289bf6 | 2012-09-05 16:46:36 -0700 | [diff] [blame] | 1324 |             stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp); | 
| Eino-Ville Talvala | bd4976a | 2012-06-07 10:40:25 -0700 | [diff] [blame] | 1325 |     int state = stream->mState; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1326 |     if (state != ACTIVE) { | 
 | 1327 |         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); | 
 | 1328 |         return INVALID_OPERATION; | 
 | 1329 |     } | 
 | 1330 |     ANativeWindow *a = toANW(w); | 
 | 1331 |     status_t err; | 
| Eino-Ville Talvala | 228a538 | 2012-08-13 12:16:06 -0700 | [diff] [blame] | 1332 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1333 |     err = native_window_set_buffers_timestamp(a, timestamp); | 
| Eino-Ville Talvala | bd4976a | 2012-06-07 10:40:25 -0700 | [diff] [blame] | 1334 |     if (err != OK) { | 
 | 1335 |         ALOGE("%s: Error setting timestamp on native window: %s (%d)", | 
 | 1336 |                 __FUNCTION__, strerror(-err), err); | 
 | 1337 |         return err; | 
 | 1338 |     } | 
 | 1339 |     err = a->queueBuffer(a, | 
| Jamie Gennis | 1e5b2b3 | 2012-06-13 16:29:51 -0700 | [diff] [blame] | 1340 |             container_of(buffer, ANativeWindowBuffer, handle), -1); | 
| Eino-Ville Talvala | bd4976a | 2012-06-07 10:40:25 -0700 | [diff] [blame] | 1341 |     if (err != OK) { | 
 | 1342 |         ALOGE("%s: Error queueing buffer to native window: %s (%d)", | 
 | 1343 |                 __FUNCTION__, strerror(-err), err); | 
| James Dong | 31d377b | 2012-08-09 17:43:46 -0700 | [diff] [blame] | 1344 |         return err; | 
| Eino-Ville Talvala | bd4976a | 2012-06-07 10:40:25 -0700 | [diff] [blame] | 1345 |     } | 
| James Dong | 31d377b | 2012-08-09 17:43:46 -0700 | [diff] [blame] | 1346 |  | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1347 |     stream->mActiveBuffers--; | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1348 |     stream->mLastTimestamp = timestamp; | 
| James Dong | 31d377b | 2012-08-09 17:43:46 -0700 | [diff] [blame] | 1349 |     return OK; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1350 | } | 
 | 1351 |  | 
 | 1352 | int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w, | 
 | 1353 |         buffer_handle_t* buffer) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1354 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1355 |     StreamAdapter *stream = | 
 | 1356 |             const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); | 
| Eino-Ville Talvala | 750d74b | 2012-08-01 09:05:04 -0700 | [diff] [blame] | 1357 |     ALOGVV("Stream %d cancel: Buffer %p", | 
 | 1358 |             stream->mId, (void*)(*buffer)); | 
| Eino-Ville Talvala | 3297daa | 2012-06-14 10:49:45 -0700 | [diff] [blame] | 1359 |     if (stream->mState != ACTIVE) { | 
 | 1360 |         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1361 |         return INVALID_OPERATION; | 
 | 1362 |     } | 
| James Dong | 31d377b | 2012-08-09 17:43:46 -0700 | [diff] [blame] | 1363 |  | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1364 |     ANativeWindow *a = toANW(w); | 
| James Dong | 31d377b | 2012-08-09 17:43:46 -0700 | [diff] [blame] | 1365 |     int err = a->cancelBuffer(a, | 
| Jamie Gennis | 1e5b2b3 | 2012-06-13 16:29:51 -0700 | [diff] [blame] | 1366 |             container_of(buffer, ANativeWindowBuffer, handle), -1); | 
| James Dong | 31d377b | 2012-08-09 17:43:46 -0700 | [diff] [blame] | 1367 |     if (err != OK) { | 
 | 1368 |         ALOGE("%s: Error canceling buffer to native window: %s (%d)", | 
 | 1369 |                 __FUNCTION__, strerror(-err), err); | 
 | 1370 |         return err; | 
 | 1371 |     } | 
 | 1372 |  | 
 | 1373 |     stream->mActiveBuffers--; | 
 | 1374 |     return OK; | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1375 | } | 
 | 1376 |  | 
 | 1377 | int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w, | 
 | 1378 |         int left, int top, int right, int bottom) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1379 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 6db981c | 2012-05-21 18:54:30 -0700 | [diff] [blame] | 1380 |     int state = static_cast<const StreamAdapter*>(w)->mState; | 
 | 1381 |     if (state != ACTIVE) { | 
 | 1382 |         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); | 
 | 1383 |         return INVALID_OPERATION; | 
 | 1384 |     } | 
 | 1385 |     ANativeWindow *a = toANW(w); | 
 | 1386 |     android_native_rect_t crop = { left, top, right, bottom }; | 
 | 1387 |     return native_window_set_crop(a, &crop); | 
 | 1388 | } | 
 | 1389 |  | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1390 | /** | 
 | 1391 |  * Camera2Device::ReprocessStreamAdapter | 
 | 1392 |  */ | 
 | 1393 |  | 
 | 1394 | #ifndef container_of | 
 | 1395 | #define container_of(ptr, type, member) \ | 
 | 1396 |     (type *)((char*)(ptr) - offsetof(type, member)) | 
 | 1397 | #endif | 
 | 1398 |  | 
 | 1399 | Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d): | 
 | 1400 |         mState(RELEASED), | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 1401 |         mHal2Device(d), | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1402 |         mId(-1), | 
 | 1403 |         mWidth(0), mHeight(0), mFormat(0), | 
 | 1404 |         mActiveBuffers(0), | 
 | 1405 |         mFrameCount(0) | 
 | 1406 | { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1407 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1408 |     camera2_stream_in_ops::acquire_buffer = acquire_buffer; | 
 | 1409 |     camera2_stream_in_ops::release_buffer = release_buffer; | 
 | 1410 | } | 
 | 1411 |  | 
 | 1412 | Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1413 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1414 |     if (mState != RELEASED) { | 
 | 1415 |         release(); | 
 | 1416 |     } | 
 | 1417 | } | 
 | 1418 |  | 
 | 1419 | status_t Camera2Device::ReprocessStreamAdapter::connectToDevice( | 
 | 1420 |         const sp<StreamAdapter> &outputStream) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1421 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1422 |     status_t res; | 
 | 1423 |     ALOGV("%s: E", __FUNCTION__); | 
 | 1424 |  | 
 | 1425 |     if (mState != RELEASED) return INVALID_OPERATION; | 
 | 1426 |     if (outputStream == NULL) { | 
 | 1427 |         ALOGE("%s: Null base stream passed to reprocess stream adapter", | 
 | 1428 |                 __FUNCTION__); | 
 | 1429 |         return BAD_VALUE; | 
 | 1430 |     } | 
 | 1431 |  | 
 | 1432 |     mBaseStream = outputStream; | 
 | 1433 |     mWidth = outputStream->getWidth(); | 
 | 1434 |     mHeight = outputStream->getHeight(); | 
 | 1435 |     mFormat = outputStream->getFormat(); | 
 | 1436 |  | 
 | 1437 |     ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x", | 
 | 1438 |             __FUNCTION__, mWidth, mHeight, mFormat); | 
 | 1439 |  | 
 | 1440 |     // Allocate device-side stream interface | 
 | 1441 |  | 
 | 1442 |     uint32_t id; | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 1443 |     res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device, | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1444 |             outputStream->getId(), getStreamOps(), | 
 | 1445 |             &id); | 
 | 1446 |     if (res != OK) { | 
 | 1447 |         ALOGE("%s: Device reprocess stream allocation failed: %s (%d)", | 
 | 1448 |                 __FUNCTION__, strerror(-res), res); | 
 | 1449 |         return res; | 
 | 1450 |     } | 
 | 1451 |  | 
 | 1452 |     ALOGV("%s: Allocated reprocess stream id %d based on stream %d", | 
 | 1453 |             __FUNCTION__, id, outputStream->getId()); | 
 | 1454 |  | 
 | 1455 |     mId = id; | 
 | 1456 |  | 
 | 1457 |     mState = ACTIVE; | 
 | 1458 |  | 
 | 1459 |     return OK; | 
 | 1460 | } | 
 | 1461 |  | 
 | 1462 | status_t Camera2Device::ReprocessStreamAdapter::release() { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1463 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1464 |     status_t res; | 
 | 1465 |     ALOGV("%s: Releasing stream %d", __FUNCTION__, mId); | 
 | 1466 |     if (mState >= ACTIVE) { | 
| Eino-Ville Talvala | 7fa43f3 | 2013-02-06 17:20:07 -0800 | [diff] [blame] | 1467 |         res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1468 |         if (res != OK) { | 
 | 1469 |             ALOGE("%s: Unable to release stream %d", | 
 | 1470 |                     __FUNCTION__, mId); | 
 | 1471 |             return res; | 
 | 1472 |         } | 
 | 1473 |     } | 
 | 1474 |  | 
 | 1475 |     List<QueueEntry>::iterator s; | 
 | 1476 |     for (s = mQueue.begin(); s != mQueue.end(); s++) { | 
 | 1477 |         sp<BufferReleasedListener> listener = s->releaseListener.promote(); | 
 | 1478 |         if (listener != 0) listener->onBufferReleased(s->handle); | 
 | 1479 |     } | 
 | 1480 |     for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) { | 
 | 1481 |         sp<BufferReleasedListener> listener = s->releaseListener.promote(); | 
 | 1482 |         if (listener != 0) listener->onBufferReleased(s->handle); | 
 | 1483 |     } | 
 | 1484 |     mQueue.clear(); | 
 | 1485 |     mInFlightQueue.clear(); | 
 | 1486 |  | 
 | 1487 |     mState = RELEASED; | 
 | 1488 |     return OK; | 
 | 1489 | } | 
 | 1490 |  | 
 | 1491 | status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream( | 
 | 1492 |     buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1493 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1494 |     // TODO: Some error checking here would be nice | 
 | 1495 |     ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle)); | 
 | 1496 |  | 
 | 1497 |     QueueEntry entry; | 
 | 1498 |     entry.handle = handle; | 
 | 1499 |     entry.releaseListener = releaseListener; | 
 | 1500 |     mQueue.push_back(entry); | 
 | 1501 |     return OK; | 
 | 1502 | } | 
 | 1503 |  | 
 | 1504 | status_t Camera2Device::ReprocessStreamAdapter::dump(int fd, | 
| Igor Murashkin | ebe3f69 | 2012-10-12 16:56:11 -0700 | [diff] [blame] | 1505 |         const Vector<String16>& /*args*/) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1506 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1507 |     String8 result = | 
 | 1508 |             String8::format("      Reprocess stream %d: %d x %d, fmt 0x%x\n", | 
 | 1509 |                     mId, mWidth, mHeight, mFormat); | 
 | 1510 |     result.appendFormat("        acquired buffers: %d\n", | 
 | 1511 |             mActiveBuffers); | 
 | 1512 |     result.appendFormat("        frame count: %d\n", | 
 | 1513 |             mFrameCount); | 
 | 1514 |     write(fd, result.string(), result.size()); | 
 | 1515 |     return OK; | 
 | 1516 | } | 
 | 1517 |  | 
 | 1518 | const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() { | 
 | 1519 |     return static_cast<camera2_stream_in_ops *>(this); | 
 | 1520 | } | 
 | 1521 |  | 
 | 1522 | int Camera2Device::ReprocessStreamAdapter::acquire_buffer( | 
 | 1523 |     const camera2_stream_in_ops_t *w, | 
 | 1524 |         buffer_handle_t** buffer) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1525 |     ATRACE_CALL(); | 
| Igor Murashkin | ebe3f69 | 2012-10-12 16:56:11 -0700 | [diff] [blame] | 1526 |  | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1527 |     ReprocessStreamAdapter* stream = | 
 | 1528 |             const_cast<ReprocessStreamAdapter*>( | 
 | 1529 |                 static_cast<const ReprocessStreamAdapter*>(w)); | 
 | 1530 |     if (stream->mState != ACTIVE) { | 
 | 1531 |         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState); | 
 | 1532 |         return INVALID_OPERATION; | 
 | 1533 |     } | 
 | 1534 |  | 
 | 1535 |     if (stream->mQueue.empty()) { | 
 | 1536 |         *buffer = NULL; | 
 | 1537 |         return OK; | 
 | 1538 |     } | 
 | 1539 |  | 
 | 1540 |     QueueEntry &entry = *(stream->mQueue.begin()); | 
 | 1541 |  | 
 | 1542 |     *buffer = entry.handle; | 
 | 1543 |  | 
 | 1544 |     stream->mInFlightQueue.push_back(entry); | 
 | 1545 |     stream->mQueue.erase(stream->mQueue.begin()); | 
 | 1546 |  | 
 | 1547 |     stream->mActiveBuffers++; | 
 | 1548 |  | 
 | 1549 |     ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId, | 
 | 1550 |             (void*)(**buffer)); | 
 | 1551 |     return OK; | 
 | 1552 | } | 
 | 1553 |  | 
 | 1554 | int Camera2Device::ReprocessStreamAdapter::release_buffer( | 
 | 1555 |     const camera2_stream_in_ops_t* w, | 
 | 1556 |     buffer_handle_t* buffer) { | 
| Eino-Ville Talvala | 852c381 | 2012-09-24 09:46:53 -0700 | [diff] [blame] | 1557 |     ATRACE_CALL(); | 
| Eino-Ville Talvala | 69230df | 2012-08-29 17:37:16 -0700 | [diff] [blame] | 1558 |     ReprocessStreamAdapter *stream = | 
 | 1559 |             const_cast<ReprocessStreamAdapter*>( | 
 | 1560 |                 static_cast<const ReprocessStreamAdapter*>(w) ); | 
 | 1561 |     stream->mFrameCount++; | 
 | 1562 |     ALOGV("Reprocess stream %d release: Frame %d (%p)", | 
 | 1563 |             stream->mId, stream->mFrameCount, (void*)*buffer); | 
 | 1564 |     int state = stream->mState; | 
 | 1565 |     if (state != ACTIVE) { | 
 | 1566 |         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); | 
 | 1567 |         return INVALID_OPERATION; | 
 | 1568 |     } | 
 | 1569 |     stream->mActiveBuffers--; | 
 | 1570 |  | 
 | 1571 |     List<QueueEntry>::iterator s; | 
 | 1572 |     for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) { | 
 | 1573 |         if ( s->handle == buffer ) break; | 
 | 1574 |     } | 
 | 1575 |     if (s == stream->mInFlightQueue.end()) { | 
 | 1576 |         ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__, | 
 | 1577 |                 buffer); | 
 | 1578 |         return INVALID_OPERATION; | 
 | 1579 |     } | 
 | 1580 |  | 
 | 1581 |     sp<BufferReleasedListener> listener = s->releaseListener.promote(); | 
 | 1582 |     if (listener != 0) { | 
 | 1583 |         listener->onBufferReleased(s->handle); | 
 | 1584 |     } else { | 
 | 1585 |         ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__); | 
 | 1586 |     } | 
 | 1587 |     stream->mInFlightQueue.erase(s); | 
 | 1588 |  | 
 | 1589 |     return OK; | 
 | 1590 | } | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 1591 |  | 
| Chien-Yu Chen | 618ff8a | 2015-03-13 11:27:17 -0700 | [diff] [blame] | 1592 | // camera 2 devices don't support reprocessing | 
 | 1593 | status_t Camera2Device::createInputStream( | 
 | 1594 |     uint32_t width, uint32_t height, int format, int *id) { | 
 | 1595 |     ALOGE("%s: camera 2 devices don't support reprocessing", __FUNCTION__); | 
 | 1596 |     return INVALID_OPERATION; | 
 | 1597 | } | 
 | 1598 |  | 
 | 1599 | // camera 2 devices don't support reprocessing | 
 | 1600 | status_t Camera2Device::getInputBufferProducer( | 
 | 1601 |         sp<IGraphicBufferProducer> *producer) { | 
 | 1602 |     ALOGE("%s: camera 2 devices don't support reprocessing", __FUNCTION__); | 
 | 1603 |     return INVALID_OPERATION; | 
 | 1604 | } | 
 | 1605 |  | 
| Eino-Ville Talvala | 61ab9f9 | 2012-05-17 10:30:54 -0700 | [diff] [blame] | 1606 | }; // namespace android |