ZslProcessor.cpp revision cb0652e5a850b2fcd919e977247e87239efaf70e
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 "Camera2-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 <inttypes.h> 29 30#include <utils/Log.h> 31#include <utils/Trace.h> 32#include <gui/Surface.h> 33 34#include "common/CameraDeviceBase.h" 35#include "api1/Camera2Client.h" 36#include "api1/client2/CaptureSequencer.h" 37#include "api1/client2/ZslProcessor.h" 38 39namespace android { 40namespace camera2 { 41 42ZslProcessor::ZslProcessor( 43 sp<Camera2Client> client, 44 wp<CaptureSequencer> sequencer): 45 Thread(false), 46 mState(RUNNING), 47 mClient(client), 48 mDevice(client->getCameraDevice()), 49 mSequencer(sequencer), 50 mId(client->getCameraId()), 51 mZslBufferAvailable(false), 52 mZslStreamId(NO_STREAM), 53 mZslReprocessStreamId(NO_STREAM), 54 mFrameListHead(0), 55 mZslQueueHead(0), 56 mZslQueueTail(0) { 57 mZslQueue.insertAt(0, kZslBufferDepth); 58 mFrameList.insertAt(0, kFrameListDepth); 59 sp<CaptureSequencer> captureSequencer = mSequencer.promote(); 60 if (captureSequencer != 0) captureSequencer->setZslProcessor(this); 61} 62 63ZslProcessor::~ZslProcessor() { 64 ALOGV("%s: Exit", __FUNCTION__); 65 deleteStream(); 66} 67 68void ZslProcessor::onFrameAvailable() { 69 Mutex::Autolock l(mInputMutex); 70 if (!mZslBufferAvailable) { 71 mZslBufferAvailable = true; 72 mZslBufferAvailableSignal.signal(); 73 } 74} 75 76void ZslProcessor::onResultAvailable(const CaptureResult &result) { 77 ATRACE_CALL(); 78 ALOGV("%s:", __FUNCTION__); 79 Mutex::Autolock l(mInputMutex); 80 camera_metadata_ro_entry_t entry; 81 entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); 82 nsecs_t timestamp = entry.data.i64[0]; 83 (void)timestamp; 84 ALOGVV("Got preview frame for timestamp %" PRId64, timestamp); 85 86 if (mState != RUNNING) return; 87 88 mFrameList.editItemAt(mFrameListHead) = result.mMetadata; 89 mFrameListHead = (mFrameListHead + 1) % kFrameListDepth; 90 91 findMatchesLocked(); 92} 93 94void ZslProcessor::onBufferReleased(buffer_handle_t *handle) { 95 Mutex::Autolock l(mInputMutex); 96 97 // Verify that the buffer is in our queue 98 size_t i = 0; 99 for (; i < mZslQueue.size(); i++) { 100 if (&(mZslQueue[i].buffer.mGraphicBuffer->handle) == handle) break; 101 } 102 if (i == mZslQueue.size()) { 103 ALOGW("%s: Released buffer %p not found in queue", 104 __FUNCTION__, handle); 105 } 106 107 // Erase entire ZSL queue since we've now completed the capture and preview 108 // is stopped. 109 clearZslQueueLocked(); 110 111 mState = RUNNING; 112} 113 114status_t ZslProcessor::updateStream(const Parameters ¶ms) { 115 ATRACE_CALL(); 116 ALOGV("%s: Configuring ZSL streams", __FUNCTION__); 117 status_t res; 118 119 Mutex::Autolock l(mInputMutex); 120 121 sp<Camera2Client> client = mClient.promote(); 122 if (client == 0) { 123 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId); 124 return INVALID_OPERATION; 125 } 126 sp<CameraDeviceBase> device = mDevice.promote(); 127 if (device == 0) { 128 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 129 return INVALID_OPERATION; 130 } 131 132 if (mZslConsumer == 0) { 133 // Create CPU buffer queue endpoint 134 sp<IGraphicBufferProducer> producer; 135 sp<IGraphicBufferConsumer> consumer; 136 BufferQueue::createBufferQueue(&producer, &consumer); 137 mZslConsumer = new BufferItemConsumer(consumer, 138 GRALLOC_USAGE_HW_CAMERA_ZSL, 139 kZslBufferDepth); 140 mZslConsumer->setFrameAvailableListener(this); 141 mZslConsumer->setName(String8("Camera2Client::ZslConsumer")); 142 mZslWindow = new Surface(producer); 143 } 144 145 if (mZslStreamId != NO_STREAM) { 146 // Check if stream parameters have to change 147 uint32_t currentWidth, currentHeight; 148 res = device->getStreamInfo(mZslStreamId, 149 ¤tWidth, ¤tHeight, 0); 150 if (res != OK) { 151 ALOGE("%s: Camera %d: Error querying capture output stream info: " 152 "%s (%d)", __FUNCTION__, 153 mId, strerror(-res), res); 154 return res; 155 } 156 if (currentWidth != (uint32_t)params.fastInfo.arrayWidth || 157 currentHeight != (uint32_t)params.fastInfo.arrayHeight) { 158 res = device->deleteReprocessStream(mZslReprocessStreamId); 159 if (res != OK) { 160 ALOGE("%s: Camera %d: Unable to delete old reprocess stream " 161 "for ZSL: %s (%d)", __FUNCTION__, 162 mId, strerror(-res), res); 163 return res; 164 } 165 ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed", 166 __FUNCTION__, mId, mZslStreamId); 167 res = device->deleteStream(mZslStreamId); 168 if (res != OK) { 169 ALOGE("%s: Camera %d: Unable to delete old output stream " 170 "for ZSL: %s (%d)", __FUNCTION__, 171 mId, strerror(-res), res); 172 return res; 173 } 174 mZslStreamId = NO_STREAM; 175 } 176 } 177 178 if (mZslStreamId == NO_STREAM) { 179 // Create stream for HAL production 180 // TODO: Sort out better way to select resolution for ZSL 181 int streamType = params.quirks.useZslFormat ? 182 (int)CAMERA2_HAL_PIXEL_FORMAT_ZSL : 183 (int)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 184 res = device->createStream(mZslWindow, 185 params.fastInfo.arrayWidth, params.fastInfo.arrayHeight, 186 streamType, 0, 187 &mZslStreamId); 188 if (res != OK) { 189 ALOGE("%s: Camera %d: Can't create output stream for ZSL: " 190 "%s (%d)", __FUNCTION__, mId, 191 strerror(-res), res); 192 return res; 193 } 194 res = device->createReprocessStreamFromStream(mZslStreamId, 195 &mZslReprocessStreamId); 196 if (res != OK) { 197 ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: " 198 "%s (%d)", __FUNCTION__, mId, 199 strerror(-res), res); 200 return res; 201 } 202 } 203 client->registerFrameListener(Camera2Client::kPreviewRequestIdStart, 204 Camera2Client::kPreviewRequestIdEnd, 205 this); 206 207 return OK; 208} 209 210status_t ZslProcessor::deleteStream() { 211 ATRACE_CALL(); 212 status_t res; 213 214 Mutex::Autolock l(mInputMutex); 215 216 if (mZslStreamId != NO_STREAM) { 217 sp<CameraDeviceBase> device = mDevice.promote(); 218 if (device == 0) { 219 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 220 return INVALID_OPERATION; 221 } 222 223 clearZslQueueLocked(); 224 225 res = device->deleteReprocessStream(mZslReprocessStreamId); 226 if (res != OK) { 227 ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: " 228 "%s (%d)", __FUNCTION__, mId, 229 mZslReprocessStreamId, strerror(-res), res); 230 return res; 231 } 232 233 mZslReprocessStreamId = NO_STREAM; 234 res = device->deleteStream(mZslStreamId); 235 if (res != OK) { 236 ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: " 237 "%s (%d)", __FUNCTION__, mId, 238 mZslStreamId, strerror(-res), res); 239 return res; 240 } 241 242 mZslWindow.clear(); 243 mZslConsumer.clear(); 244 245 mZslStreamId = NO_STREAM; 246 } 247 return OK; 248} 249 250int ZslProcessor::getStreamId() const { 251 Mutex::Autolock l(mInputMutex); 252 return mZslStreamId; 253} 254 255status_t ZslProcessor::pushToReprocess(int32_t requestId) { 256 ALOGV("%s: Send in reprocess request with id %d", 257 __FUNCTION__, requestId); 258 Mutex::Autolock l(mInputMutex); 259 status_t res; 260 sp<Camera2Client> client = mClient.promote(); 261 262 if (client == 0) { 263 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId); 264 return INVALID_OPERATION; 265 } 266 267 IF_ALOGV() { 268 dumpZslQueue(-1); 269 } 270 271 if (mZslQueueTail != mZslQueueHead) { 272 CameraMetadata request; 273 size_t index = mZslQueueTail; 274 while (index != mZslQueueHead) { 275 if (!mZslQueue[index].frame.isEmpty()) { 276 request = mZslQueue[index].frame; 277 break; 278 } 279 index = (index + 1) % kZslBufferDepth; 280 } 281 if (index == mZslQueueHead) { 282 ALOGV("%s: ZSL queue has no valid frames to send yet.", 283 __FUNCTION__); 284 return NOT_ENOUGH_DATA; 285 } 286 // Verify that the frame is reasonable for reprocessing 287 288 camera_metadata_entry_t entry; 289 entry = request.find(ANDROID_CONTROL_AE_STATE); 290 if (entry.count == 0) { 291 ALOGE("%s: ZSL queue frame has no AE state field!", 292 __FUNCTION__); 293 return BAD_VALUE; 294 } 295 if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED && 296 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) { 297 ALOGV("%s: ZSL queue frame AE state is %d, need full capture", 298 __FUNCTION__, entry.data.u8[0]); 299 return NOT_ENOUGH_DATA; 300 } 301 302 buffer_handle_t *handle = 303 &(mZslQueue[index].buffer.mGraphicBuffer->handle); 304 305 uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS; 306 res = request.update(ANDROID_REQUEST_TYPE, 307 &requestType, 1); 308 int32_t inputStreams[1] = 309 { mZslReprocessStreamId }; 310 if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS, 311 inputStreams, 1); 312 int32_t outputStreams[1] = 313 { client->getCaptureStreamId() }; 314 if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS, 315 outputStreams, 1); 316 res = request.update(ANDROID_REQUEST_ID, 317 &requestId, 1); 318 319 if (res != OK ) { 320 ALOGE("%s: Unable to update frame to a reprocess request", __FUNCTION__); 321 return INVALID_OPERATION; 322 } 323 324 res = client->stopStream(); 325 if (res != OK) { 326 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: " 327 "%s (%d)", 328 __FUNCTION__, mId, strerror(-res), res); 329 return INVALID_OPERATION; 330 } 331 // TODO: have push-and-clear be atomic 332 res = client->getCameraDevice()->pushReprocessBuffer(mZslReprocessStreamId, 333 handle, this); 334 if (res != OK) { 335 ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)", 336 __FUNCTION__, strerror(-res), res); 337 return res; 338 } 339 340 // Update JPEG settings 341 { 342 SharedParameters::Lock l(client->getParameters()); 343 res = l.mParameters.updateRequestJpeg(&request); 344 if (res != OK) { 345 ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL " 346 "capture request: %s (%d)", __FUNCTION__, 347 mId, 348 strerror(-res), res); 349 return res; 350 } 351 } 352 353 mLatestCapturedRequest = request; 354 res = client->getCameraDevice()->capture(request); 355 if (res != OK ) { 356 ALOGE("%s: Unable to send ZSL reprocess request to capture: %s (%d)", 357 __FUNCTION__, strerror(-res), res); 358 return res; 359 } 360 361 mState = LOCKED; 362 } else { 363 ALOGV("%s: No ZSL buffers yet", __FUNCTION__); 364 return NOT_ENOUGH_DATA; 365 } 366 return OK; 367} 368 369status_t ZslProcessor::clearZslQueue() { 370 Mutex::Autolock l(mInputMutex); 371 // If in middle of capture, can't clear out queue 372 if (mState == LOCKED) return OK; 373 374 return clearZslQueueLocked(); 375} 376 377status_t ZslProcessor::clearZslQueueLocked() { 378 for (size_t i = 0; i < mZslQueue.size(); i++) { 379 if (mZslQueue[i].buffer.mTimestamp != 0) { 380 mZslConsumer->releaseBuffer(mZslQueue[i].buffer); 381 } 382 mZslQueue.replaceAt(i); 383 } 384 mZslQueueHead = 0; 385 mZslQueueTail = 0; 386 return OK; 387} 388 389void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const { 390 Mutex::Autolock l(mInputMutex); 391 if (!mLatestCapturedRequest.isEmpty()) { 392 String8 result(" Latest ZSL capture request:\n"); 393 write(fd, result.string(), result.size()); 394 mLatestCapturedRequest.dump(fd, 2, 6); 395 } else { 396 String8 result(" Latest ZSL capture request: none yet\n"); 397 write(fd, result.string(), result.size()); 398 } 399 dumpZslQueue(fd); 400} 401 402bool ZslProcessor::threadLoop() { 403 status_t res; 404 405 { 406 Mutex::Autolock l(mInputMutex); 407 while (!mZslBufferAvailable) { 408 res = mZslBufferAvailableSignal.waitRelative(mInputMutex, 409 kWaitDuration); 410 if (res == TIMED_OUT) return true; 411 } 412 mZslBufferAvailable = false; 413 } 414 415 do { 416 res = processNewZslBuffer(); 417 } while (res == OK); 418 419 return true; 420} 421 422status_t ZslProcessor::processNewZslBuffer() { 423 ATRACE_CALL(); 424 status_t res; 425 sp<BufferItemConsumer> zslConsumer; 426 { 427 Mutex::Autolock l(mInputMutex); 428 if (mZslConsumer == 0) return OK; 429 zslConsumer = mZslConsumer; 430 } 431 ALOGVV("Trying to get next buffer"); 432 BufferItemConsumer::BufferItem item; 433 res = zslConsumer->acquireBuffer(&item, 0); 434 if (res != OK) { 435 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { 436 ALOGE("%s: Camera %d: Error receiving ZSL image buffer: " 437 "%s (%d)", __FUNCTION__, 438 mId, strerror(-res), res); 439 } else { 440 ALOGVV(" No buffer"); 441 } 442 return res; 443 } 444 445 Mutex::Autolock l(mInputMutex); 446 447 if (mState == LOCKED) { 448 ALOGVV("In capture, discarding new ZSL buffers"); 449 zslConsumer->releaseBuffer(item); 450 return OK; 451 } 452 453 ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail); 454 455 if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) { 456 ALOGVV("Releasing oldest buffer"); 457 zslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer); 458 mZslQueue.replaceAt(mZslQueueTail); 459 mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth; 460 } 461 462 ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead); 463 464 queueHead.buffer = item; 465 queueHead.frame.release(); 466 467 mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth; 468 469 ALOGVV(" Acquired buffer, timestamp %" PRId64, queueHead.buffer.mTimestamp); 470 471 findMatchesLocked(); 472 473 return OK; 474} 475 476void ZslProcessor::findMatchesLocked() { 477 ALOGVV("Scanning"); 478 for (size_t i = 0; i < mZslQueue.size(); i++) { 479 ZslPair &queueEntry = mZslQueue.editItemAt(i); 480 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp; 481 IF_ALOGV() { 482 camera_metadata_entry_t entry; 483 nsecs_t frameTimestamp = 0; 484 if (!queueEntry.frame.isEmpty()) { 485 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP); 486 frameTimestamp = entry.data.i64[0]; 487 } 488 ALOGVV(" %d: b: %" PRId64 "\tf: %" PRId64, i, 489 bufferTimestamp, frameTimestamp ); 490 } 491 if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) { 492 // Have buffer, no matching frame. Look for one 493 for (size_t j = 0; j < mFrameList.size(); j++) { 494 bool match = false; 495 CameraMetadata &frame = mFrameList.editItemAt(j); 496 if (!frame.isEmpty()) { 497 camera_metadata_entry_t entry; 498 entry = frame.find(ANDROID_SENSOR_TIMESTAMP); 499 if (entry.count == 0) { 500 ALOGE("%s: Can't find timestamp in frame!", 501 __FUNCTION__); 502 continue; 503 } 504 nsecs_t frameTimestamp = entry.data.i64[0]; 505 if (bufferTimestamp == frameTimestamp) { 506 ALOGVV("%s: Found match %" PRId64, __FUNCTION__, 507 frameTimestamp); 508 match = true; 509 } else { 510 int64_t delta = abs(bufferTimestamp - frameTimestamp); 511 if ( delta < 1000000) { 512 ALOGVV("%s: Found close match %" PRId64 " (delta %" PRId64 ")", 513 __FUNCTION__, bufferTimestamp, delta); 514 match = true; 515 } 516 } 517 } 518 if (match) { 519 queueEntry.frame.acquire(frame); 520 break; 521 } 522 } 523 } 524 } 525} 526 527void ZslProcessor::dumpZslQueue(int fd) const { 528 String8 header("ZSL queue contents:"); 529 String8 indent(" "); 530 ALOGV("%s", header.string()); 531 if (fd != -1) { 532 header = indent + header + "\n"; 533 write(fd, header.string(), header.size()); 534 } 535 for (size_t i = 0; i < mZslQueue.size(); i++) { 536 const ZslPair &queueEntry = mZslQueue[i]; 537 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp; 538 camera_metadata_ro_entry_t entry; 539 nsecs_t frameTimestamp = 0; 540 int frameAeState = -1; 541 if (!queueEntry.frame.isEmpty()) { 542 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP); 543 if (entry.count > 0) frameTimestamp = entry.data.i64[0]; 544 entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE); 545 if (entry.count > 0) frameAeState = entry.data.u8[0]; 546 } 547 String8 result = 548 String8::format(" %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i, 549 bufferTimestamp, frameTimestamp, frameAeState); 550 ALOGV("%s", result.string()); 551 if (fd != -1) { 552 result = indent + result + "\n"; 553 write(fd, result.string(), result.size()); 554 } 555 556 } 557} 558 559}; // namespace camera2 560}; // namespace android 561