ZslProcessor.cpp revision beb1416afd1d331b8e7e93d626f39267acce289a
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Camera2Client::ZslProcessor" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20//#define LOG_NNDEBUG 0 21 22#ifdef LOG_NNDEBUG 23#define ALOGVV(...) ALOGV(__VA_ARGS__) 24#else 25#define ALOGVV(...) ((void)0) 26#endif 27 28#include <utils/Log.h> 29#include <utils/Trace.h> 30 31#include "ZslProcessor.h" 32#include <gui/SurfaceTextureClient.h> 33#include "../Camera2Device.h" 34#include "../Camera2Client.h" 35 36 37namespace android { 38namespace camera2 { 39 40ZslProcessor::ZslProcessor( 41 wp<Camera2Client> client, 42 wp<CaptureSequencer> sequencer): 43 Thread(false), 44 mState(RUNNING), 45 mClient(client), 46 mSequencer(sequencer), 47 mZslBufferAvailable(false), 48 mZslStreamId(NO_STREAM), 49 mZslReprocessStreamId(NO_STREAM), 50 mFrameListHead(0), 51 mZslQueueHead(0), 52 mZslQueueTail(0) { 53 mZslQueue.insertAt(0, kZslBufferDepth); 54 mFrameList.insertAt(0, kFrameListDepth); 55 sp<CaptureSequencer> captureSequencer = mSequencer.promote(); 56 if (captureSequencer != 0) captureSequencer->setZslProcessor(this); 57} 58 59ZslProcessor::~ZslProcessor() { 60 ALOGV("%s: Exit", __FUNCTION__); 61 deleteStream(); 62} 63 64void ZslProcessor::onFrameAvailable() { 65 Mutex::Autolock l(mInputMutex); 66 if (!mZslBufferAvailable) { 67 mZslBufferAvailable = true; 68 mZslBufferAvailableSignal.signal(); 69 } 70} 71 72void ZslProcessor::onFrameAvailable(int32_t frameId, CameraMetadata &frame) { 73 Mutex::Autolock l(mInputMutex); 74 camera_metadata_entry_t entry; 75 entry = frame.find(ANDROID_SENSOR_TIMESTAMP); 76 nsecs_t timestamp = entry.data.i64[0]; 77 ALOGVV("Got preview frame for timestamp %lld", timestamp); 78 79 if (mState != RUNNING) return; 80 81 mFrameList.editItemAt(mFrameListHead).acquire(frame); 82 mFrameListHead = (mFrameListHead + 1) % kFrameListDepth; 83 84 findMatchesLocked(); 85} 86 87void ZslProcessor::onBufferReleased(buffer_handle_t *handle) { 88 Mutex::Autolock l(mInputMutex); 89 90 buffer_handle_t *expectedHandle = 91 &(mZslQueue[mZslQueueTail].buffer.mGraphicBuffer->handle); 92 93 if (handle != expectedHandle) { 94 ALOGE("%s: Expected buffer %p, got buffer %p", 95 __FUNCTION__, expectedHandle, handle); 96 } 97 98 mState = RUNNING; 99} 100 101status_t ZslProcessor::updateStream(const Parameters ¶ms) { 102 ATRACE_CALL(); 103 ALOGV("%s: Configuring ZSL streams", __FUNCTION__); 104 status_t res; 105 106 Mutex::Autolock l(mInputMutex); 107 108 sp<Camera2Client> client = mClient.promote(); 109 if (client == 0) return OK; 110 sp<Camera2Device> device = client->getCameraDevice(); 111 112 if (mZslConsumer == 0) { 113 // Create CPU buffer queue endpoint 114 mZslConsumer = new BufferItemConsumer( 115 GRALLOC_USAGE_HW_CAMERA_ZSL, 116 kZslBufferDepth, 117 true); 118 mZslConsumer->setFrameAvailableListener(this); 119 mZslConsumer->setName(String8("Camera2Client::ZslConsumer")); 120 mZslWindow = new SurfaceTextureClient( 121 mZslConsumer->getProducerInterface()); 122 } 123 124 if (mZslStreamId != NO_STREAM) { 125 // Check if stream parameters have to change 126 uint32_t currentWidth, currentHeight; 127 res = device->getStreamInfo(mZslStreamId, 128 ¤tWidth, ¤tHeight, 0); 129 if (res != OK) { 130 ALOGE("%s: Camera %d: Error querying capture output stream info: " 131 "%s (%d)", __FUNCTION__, 132 client->getCameraId(), strerror(-res), res); 133 return res; 134 } 135 if (currentWidth != (uint32_t)params.fastInfo.arrayWidth || 136 currentHeight != (uint32_t)params.fastInfo.arrayHeight) { 137 res = device->deleteReprocessStream(mZslReprocessStreamId); 138 if (res != OK) { 139 ALOGE("%s: Camera %d: Unable to delete old reprocess stream " 140 "for ZSL: %s (%d)", __FUNCTION__, 141 client->getCameraId(), strerror(-res), res); 142 return res; 143 } 144 res = device->deleteStream(mZslStreamId); 145 if (res != OK) { 146 ALOGE("%s: Camera %d: Unable to delete old output stream " 147 "for ZSL: %s (%d)", __FUNCTION__, 148 client->getCameraId(), strerror(-res), res); 149 return res; 150 } 151 mZslStreamId = NO_STREAM; 152 } 153 } 154 155 if (mZslStreamId == NO_STREAM) { 156 // Create stream for HAL production 157 // TODO: Sort out better way to select resolution for ZSL 158 res = device->createStream(mZslWindow, 159 params.fastInfo.arrayWidth, params.fastInfo.arrayHeight, 160 CAMERA2_HAL_PIXEL_FORMAT_ZSL, 0, 161 &mZslStreamId); 162 if (res != OK) { 163 ALOGE("%s: Camera %d: Can't create output stream for ZSL: " 164 "%s (%d)", __FUNCTION__, client->getCameraId(), 165 strerror(-res), res); 166 return res; 167 } 168 res = device->createReprocessStreamFromStream(mZslStreamId, 169 &mZslReprocessStreamId); 170 if (res != OK) { 171 ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: " 172 "%s (%d)", __FUNCTION__, client->getCameraId(), 173 strerror(-res), res); 174 return res; 175 } 176 } 177 client->registerFrameListener(Camera2Client::kPreviewRequestId, this); 178 179 return OK; 180} 181 182status_t ZslProcessor::deleteStream() { 183 ATRACE_CALL(); 184 status_t res; 185 186 Mutex::Autolock l(mInputMutex); 187 188 if (mZslStreamId != NO_STREAM) { 189 sp<Camera2Client> client = mClient.promote(); 190 if (client == 0) return OK; 191 sp<Camera2Device> device = client->getCameraDevice(); 192 193 res = device->deleteReprocessStream(mZslReprocessStreamId); 194 if (res != OK) { 195 ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: " 196 "%s (%d)", __FUNCTION__, client->getCameraId(), 197 mZslReprocessStreamId, strerror(-res), res); 198 return res; 199 } 200 201 mZslReprocessStreamId = NO_STREAM; 202 res = device->deleteStream(mZslStreamId); 203 if (res != OK) { 204 ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: " 205 "%s (%d)", __FUNCTION__, client->getCameraId(), 206 mZslStreamId, strerror(-res), res); 207 return res; 208 } 209 210 mZslWindow.clear(); 211 mZslConsumer.clear(); 212 213 mZslStreamId = NO_STREAM; 214 } 215 return OK; 216} 217 218int ZslProcessor::getStreamId() const { 219 Mutex::Autolock l(mInputMutex); 220 return mZslStreamId; 221} 222 223int ZslProcessor::getReprocessStreamId() const { 224 Mutex::Autolock l(mInputMutex); 225 return mZslReprocessStreamId; 226} 227 228status_t ZslProcessor::pushToReprocess(int32_t requestId) { 229 ALOGV("%s: Send in reprocess request with id %d", 230 __FUNCTION__, requestId); 231 Mutex::Autolock l(mInputMutex); 232 status_t res; 233 sp<Camera2Client> client = mClient.promote(); 234 235 if (client == 0) return false; 236 237 if (mZslQueueTail != mZslQueueHead) { 238 CameraMetadata request; 239 size_t index = mZslQueueTail; 240 while (request.isEmpty() && index != mZslQueueHead) { 241 request = mZslQueue[index].frame; 242 index = (index + 1) % kZslBufferDepth; 243 } 244 if (request.isEmpty()) { 245 ALOGE("No request in ZSL queue to send!"); 246 return BAD_VALUE; 247 } 248 buffer_handle_t *handle = 249 &(mZslQueue[index].buffer.mGraphicBuffer->handle); 250 251 uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS; 252 res = request.update(ANDROID_REQUEST_TYPE, 253 &requestType, 1); 254 uint8_t inputStreams[1] = { mZslReprocessStreamId }; 255 if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS, 256 inputStreams, 1); 257 uint8_t outputStreams[1] = { client->getCaptureStreamId() }; 258 if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS, 259 outputStreams, 1); 260 res = request.update(ANDROID_REQUEST_ID, 261 &requestId, 1); 262 263 if (res != OK ) { 264 ALOGE("%s: Unable to update frame to a reprocess request", __FUNCTION__); 265 return INVALID_OPERATION; 266 } 267 268 res = client->getCameraDevice()->pushReprocessBuffer(mZslReprocessStreamId, 269 handle, this); 270 if (res != OK) { 271 ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)", 272 __FUNCTION__, strerror(-res), res); 273 return res; 274 } 275 276 res = client->getCameraDevice()->capture(request); 277 if (res != OK ) { 278 ALOGE("%s: Unable to send ZSL reprocess request to capture: %s (%d)", 279 __FUNCTION__, strerror(-res), res); 280 return res; 281 } 282 283 mState = LOCKED; 284 } else { 285 ALOGE("%s: Nothing to push", __FUNCTION__); 286 return BAD_VALUE; 287 } 288 return OK; 289} 290 291void ZslProcessor::dump(int fd, const Vector<String16>& args) const { 292} 293 294bool ZslProcessor::threadLoop() { 295 status_t res; 296 297 { 298 Mutex::Autolock l(mInputMutex); 299 while (!mZslBufferAvailable) { 300 res = mZslBufferAvailableSignal.waitRelative(mInputMutex, 301 kWaitDuration); 302 if (res == TIMED_OUT) return true; 303 } 304 mZslBufferAvailable = false; 305 } 306 307 do { 308 sp<Camera2Client> client = mClient.promote(); 309 if (client == 0) return false; 310 res = processNewZslBuffer(client); 311 } while (res == OK); 312 313 return true; 314} 315 316status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) { 317 ATRACE_CALL(); 318 status_t res; 319 320 ALOGVV("Trying to get next buffer"); 321 BufferItemConsumer::BufferItem item; 322 res = mZslConsumer->acquireBuffer(&item); 323 if (res != OK) { 324 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { 325 ALOGE("%s: Camera %d: Error receiving ZSL image buffer: " 326 "%s (%d)", __FUNCTION__, 327 client->getCameraId(), strerror(-res), res); 328 } else { 329 ALOGVV(" No buffer"); 330 } 331 return res; 332 } 333 334 Mutex::Autolock l(mInputMutex); 335 336 if (mState == LOCKED) { 337 ALOGVV("In capture, discarding new ZSL buffers"); 338 mZslConsumer->releaseBuffer(item); 339 return OK; 340 } 341 342 ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail); 343 344 if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) { 345 ALOGVV("Releasing oldest buffer"); 346 mZslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer); 347 mZslQueue.replaceAt(mZslQueueTail); 348 mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth; 349 } 350 351 ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead); 352 353 queueHead.buffer = item; 354 queueHead.frame.release(); 355 356 mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth; 357 358 ALOGVV(" Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp); 359 360 findMatchesLocked(); 361 362 return OK; 363} 364 365void ZslProcessor::findMatchesLocked() { 366 ALOGVV("Scanning"); 367 for (size_t i = 0; i < mZslQueue.size(); i++) { 368 ZslPair &queueEntry = mZslQueue.editItemAt(i); 369 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp; 370 IF_ALOGV() { 371 camera_metadata_entry_t entry; 372 nsecs_t frameTimestamp = 0; 373 if (!queueEntry.frame.isEmpty()) { 374 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP); 375 frameTimestamp = entry.data.i64[0]; 376 } 377 ALOGVV(" %d: b: %lld\tf: %lld", i, 378 bufferTimestamp, frameTimestamp ); 379 } 380 if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) { 381 // Have buffer, no matching frame. Look for one 382 for (size_t j = 0; j < mFrameList.size(); j++) { 383 bool match = false; 384 CameraMetadata &frame = mFrameList.editItemAt(j); 385 if (!frame.isEmpty()) { 386 camera_metadata_entry_t entry; 387 entry = frame.find(ANDROID_SENSOR_TIMESTAMP); 388 if (entry.count == 0) { 389 ALOGE("%s: Can't find timestamp in frame!", 390 __FUNCTION__); 391 continue; 392 } 393 nsecs_t frameTimestamp = entry.data.i64[0]; 394 if (bufferTimestamp == frameTimestamp) { 395 ALOGVV("%s: Found match %lld", __FUNCTION__, 396 frameTimestamp); 397 match = true; 398 } else { 399 int64_t delta = abs(bufferTimestamp - frameTimestamp); 400 if ( delta < 1000000) { 401 ALOGVV("%s: Found close match %lld (delta %lld)", 402 __FUNCTION__, bufferTimestamp, delta); 403 match = true; 404 } 405 } 406 } 407 if (match) { 408 queueEntry.frame.acquire(frame); 409 break; 410 } 411 } 412 } 413 } 414} 415 416}; // namespace camera2 417}; // namespace android 418