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