ZslProcessor3.cpp revision e5729fac81c8a984e984fefc90afc64135817d4f
1/* 2 * Copyright (C) 2013 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-ZslProcessor3" 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/ZslProcessor3.h" 38#include "device3/Camera3Device.h" 39 40namespace android { 41namespace camera2 { 42 43ZslProcessor3::ZslProcessor3( 44 sp<Camera2Client> client, 45 wp<CaptureSequencer> sequencer): 46 Thread(false), 47 mState(RUNNING), 48 mClient(client), 49 mSequencer(sequencer), 50 mId(client->getCameraId()), 51 mZslStreamId(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 61ZslProcessor3::~ZslProcessor3() { 62 ALOGV("%s: Exit", __FUNCTION__); 63 deleteStream(); 64} 65 66void ZslProcessor3::onFrameAvailable(int32_t /*requestId*/, 67 const CameraMetadata &frame) { 68 Mutex::Autolock l(mInputMutex); 69 camera_metadata_ro_entry_t entry; 70 entry = frame.find(ANDROID_SENSOR_TIMESTAMP); 71 nsecs_t timestamp = entry.data.i64[0]; 72 (void)timestamp; 73 ALOGVV("Got preview metadata for timestamp %" PRId64, timestamp); 74 75 if (mState != RUNNING) return; 76 77 mFrameList.editItemAt(mFrameListHead) = frame; 78 mFrameListHead = (mFrameListHead + 1) % kFrameListDepth; 79} 80 81status_t ZslProcessor3::updateStream(const Parameters ¶ms) { 82 ATRACE_CALL(); 83 ALOGV("%s: Configuring ZSL streams", __FUNCTION__); 84 status_t res; 85 86 Mutex::Autolock l(mInputMutex); 87 88 sp<Camera2Client> client = mClient.promote(); 89 if (client == 0) { 90 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId); 91 return INVALID_OPERATION; 92 } 93 sp<Camera3Device> device = 94 static_cast<Camera3Device*>(client->getCameraDevice().get()); 95 if (device == 0) { 96 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 97 return INVALID_OPERATION; 98 } 99 100 if (mZslStreamId != NO_STREAM) { 101 // Check if stream parameters have to change 102 uint32_t currentWidth, currentHeight; 103 res = device->getStreamInfo(mZslStreamId, 104 ¤tWidth, ¤tHeight, 0); 105 if (res != OK) { 106 ALOGE("%s: Camera %d: Error querying capture output stream info: " 107 "%s (%d)", __FUNCTION__, 108 client->getCameraId(), strerror(-res), res); 109 return res; 110 } 111 if (currentWidth != (uint32_t)params.fastInfo.arrayWidth || 112 currentHeight != (uint32_t)params.fastInfo.arrayHeight) { 113 ALOGV("%s: Camera %d: Deleting stream %d since the buffer " 114 "dimensions changed", 115 __FUNCTION__, client->getCameraId(), mZslStreamId); 116 res = device->deleteStream(mZslStreamId); 117 if (res == -EBUSY) { 118 ALOGV("%s: Camera %d: Device is busy, call updateStream again " 119 " after it becomes idle", __FUNCTION__, mId); 120 return res; 121 } else if(res != OK) { 122 ALOGE("%s: Camera %d: Unable to delete old output stream " 123 "for ZSL: %s (%d)", __FUNCTION__, 124 client->getCameraId(), strerror(-res), res); 125 return res; 126 } 127 mZslStreamId = NO_STREAM; 128 } 129 } 130 131 if (mZslStreamId == NO_STREAM) { 132 // Create stream for HAL production 133 // TODO: Sort out better way to select resolution for ZSL 134 135 // Note that format specified internally in Camera3ZslStream 136 res = device->createZslStream( 137 params.fastInfo.arrayWidth, params.fastInfo.arrayHeight, 138 kZslBufferDepth, 139 &mZslStreamId, 140 &mZslStream); 141 if (res != OK) { 142 ALOGE("%s: Camera %d: Can't create ZSL stream: " 143 "%s (%d)", __FUNCTION__, client->getCameraId(), 144 strerror(-res), res); 145 return res; 146 } 147 } 148 client->registerFrameListener(Camera2Client::kPreviewRequestIdStart, 149 Camera2Client::kPreviewRequestIdEnd, 150 this); 151 152 return OK; 153} 154 155status_t ZslProcessor3::deleteStream() { 156 ATRACE_CALL(); 157 status_t res; 158 159 Mutex::Autolock l(mInputMutex); 160 161 if (mZslStreamId != NO_STREAM) { 162 sp<Camera2Client> client = mClient.promote(); 163 if (client == 0) { 164 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId); 165 return INVALID_OPERATION; 166 } 167 168 sp<Camera3Device> device = 169 reinterpret_cast<Camera3Device*>(client->getCameraDevice().get()); 170 if (device == 0) { 171 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); 172 return INVALID_OPERATION; 173 } 174 175 res = device->deleteStream(mZslStreamId); 176 if (res != OK) { 177 ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: " 178 "%s (%d)", __FUNCTION__, client->getCameraId(), 179 mZslStreamId, strerror(-res), res); 180 return res; 181 } 182 183 mZslStreamId = NO_STREAM; 184 } 185 return OK; 186} 187 188int ZslProcessor3::getStreamId() const { 189 Mutex::Autolock l(mInputMutex); 190 return mZslStreamId; 191} 192 193status_t ZslProcessor3::pushToReprocess(int32_t requestId) { 194 ALOGV("%s: Send in reprocess request with id %d", 195 __FUNCTION__, requestId); 196 Mutex::Autolock l(mInputMutex); 197 status_t res; 198 sp<Camera2Client> client = mClient.promote(); 199 200 if (client == 0) { 201 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId); 202 return INVALID_OPERATION; 203 } 204 205 IF_ALOGV() { 206 dumpZslQueue(-1); 207 } 208 209 size_t metadataIdx; 210 nsecs_t candidateTimestamp = getCandidateTimestampLocked(&metadataIdx); 211 212 if (candidateTimestamp == -1) { 213 ALOGE("%s: Could not find good candidate for ZSL reprocessing", 214 __FUNCTION__); 215 return NOT_ENOUGH_DATA; 216 } 217 218 res = mZslStream->enqueueInputBufferByTimestamp(candidateTimestamp, 219 /*actualTimestamp*/NULL); 220 221 if (res == mZslStream->NO_BUFFER_AVAILABLE) { 222 ALOGV("%s: No ZSL buffers yet", __FUNCTION__); 223 return NOT_ENOUGH_DATA; 224 } else if (res != OK) { 225 ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)", 226 __FUNCTION__, strerror(-res), res); 227 return res; 228 } 229 230 { 231 CameraMetadata request = mFrameList[metadataIdx]; 232 233 // Verify that the frame is reasonable for reprocessing 234 235 camera_metadata_entry_t entry; 236 entry = request.find(ANDROID_CONTROL_AE_STATE); 237 if (entry.count == 0) { 238 ALOGE("%s: ZSL queue frame has no AE state field!", 239 __FUNCTION__); 240 return BAD_VALUE; 241 } 242 if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED && 243 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) { 244 ALOGV("%s: ZSL queue frame AE state is %d, need full capture", 245 __FUNCTION__, entry.data.u8[0]); 246 return NOT_ENOUGH_DATA; 247 } 248 249 uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS; 250 res = request.update(ANDROID_REQUEST_TYPE, 251 &requestType, 1); 252 int32_t inputStreams[1] = 253 { mZslStreamId }; 254 if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS, 255 inputStreams, 1); 256 // TODO: Shouldn't we also update the latest preview frame? 257 int32_t outputStreams[1] = 258 { client->getCaptureStreamId() }; 259 if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS, 260 outputStreams, 1); 261 res = request.update(ANDROID_REQUEST_ID, 262 &requestId, 1); 263 264 if (res != OK ) { 265 ALOGE("%s: Unable to update frame to a reprocess request", 266 __FUNCTION__); 267 return INVALID_OPERATION; 268 } 269 270 res = client->stopStream(); 271 if (res != OK) { 272 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: " 273 "%s (%d)", 274 __FUNCTION__, client->getCameraId(), strerror(-res), res); 275 return INVALID_OPERATION; 276 } 277 278 // Update JPEG settings 279 { 280 SharedParameters::Lock l(client->getParameters()); 281 res = l.mParameters.updateRequestJpeg(&request); 282 if (res != OK) { 283 ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL " 284 "capture request: %s (%d)", __FUNCTION__, 285 client->getCameraId(), 286 strerror(-res), res); 287 return res; 288 } 289 } 290 291 mLatestCapturedRequest = request; 292 res = client->getCameraDevice()->capture(request); 293 if (res != OK ) { 294 ALOGE("%s: Unable to send ZSL reprocess request to capture: %s" 295 " (%d)", __FUNCTION__, strerror(-res), res); 296 return res; 297 } 298 299 mState = LOCKED; 300 } 301 302 return OK; 303} 304 305status_t ZslProcessor3::clearZslQueue() { 306 Mutex::Autolock l(mInputMutex); 307 // If in middle of capture, can't clear out queue 308 if (mState == LOCKED) return OK; 309 310 return clearZslQueueLocked(); 311} 312 313status_t ZslProcessor3::clearZslQueueLocked() { 314 if (mZslStream != 0) { 315 return mZslStream->clearInputRingBuffer(); 316 } 317 return OK; 318} 319 320void ZslProcessor3::dump(int fd, const Vector<String16>& /*args*/) const { 321 Mutex::Autolock l(mInputMutex); 322 if (!mLatestCapturedRequest.isEmpty()) { 323 String8 result(" Latest ZSL capture request:\n"); 324 write(fd, result.string(), result.size()); 325 mLatestCapturedRequest.dump(fd, 2, 6); 326 } else { 327 String8 result(" Latest ZSL capture request: none yet\n"); 328 write(fd, result.string(), result.size()); 329 } 330 dumpZslQueue(fd); 331} 332 333bool ZslProcessor3::threadLoop() { 334 // TODO: remove dependency on thread. For now, shut thread down right 335 // away. 336 return false; 337} 338 339void ZslProcessor3::dumpZslQueue(int fd) const { 340 String8 header("ZSL queue contents:"); 341 String8 indent(" "); 342 ALOGV("%s", header.string()); 343 if (fd != -1) { 344 header = indent + header + "\n"; 345 write(fd, header.string(), header.size()); 346 } 347 for (size_t i = 0; i < mZslQueue.size(); i++) { 348 const ZslPair &queueEntry = mZslQueue[i]; 349 nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp; 350 camera_metadata_ro_entry_t entry; 351 nsecs_t frameTimestamp = 0; 352 int frameAeState = -1; 353 if (!queueEntry.frame.isEmpty()) { 354 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP); 355 if (entry.count > 0) frameTimestamp = entry.data.i64[0]; 356 entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE); 357 if (entry.count > 0) frameAeState = entry.data.u8[0]; 358 } 359 String8 result = 360 String8::format(" %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i, 361 bufferTimestamp, frameTimestamp, frameAeState); 362 ALOGV("%s", result.string()); 363 if (fd != -1) { 364 result = indent + result + "\n"; 365 write(fd, result.string(), result.size()); 366 } 367 368 } 369} 370 371nsecs_t ZslProcessor3::getCandidateTimestampLocked(size_t* metadataIdx) const { 372 /** 373 * Find the smallest timestamp we know about so far 374 * - ensure that aeState is either converged or locked 375 */ 376 377 size_t idx = 0; 378 nsecs_t minTimestamp = -1; 379 380 size_t emptyCount = mFrameList.size(); 381 382 for (size_t j = 0; j < mFrameList.size(); j++) { 383 const CameraMetadata &frame = mFrameList[j]; 384 if (!frame.isEmpty()) { 385 386 emptyCount--; 387 388 camera_metadata_ro_entry_t entry; 389 entry = frame.find(ANDROID_SENSOR_TIMESTAMP); 390 if (entry.count == 0) { 391 ALOGE("%s: Can't find timestamp in frame!", 392 __FUNCTION__); 393 continue; 394 } 395 nsecs_t frameTimestamp = entry.data.i64[0]; 396 if (minTimestamp > frameTimestamp || minTimestamp == -1) { 397 398 entry = frame.find(ANDROID_CONTROL_AE_STATE); 399 400 if (entry.count == 0) { 401 /** 402 * This is most likely a HAL bug. The aeState field is 403 * mandatory, so it should always be in a metadata packet. 404 */ 405 ALOGW("%s: ZSL queue frame has no AE state field!", 406 __FUNCTION__); 407 continue; 408 } 409 if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED && 410 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) { 411 ALOGVV("%s: ZSL queue frame AE state is %d, need " 412 "full capture", __FUNCTION__, entry.data.u8[0]); 413 continue; 414 } 415 416 minTimestamp = frameTimestamp; 417 idx = j; 418 } 419 420 ALOGVV("%s: Saw timestamp %" PRId64, __FUNCTION__, frameTimestamp); 421 } 422 } 423 424 if (emptyCount == mFrameList.size()) { 425 /** 426 * This could be mildly bad and means our ZSL was triggered before 427 * there were any frames yet received by the camera framework. 428 * 429 * This is a fairly corner case which can happen under: 430 * + a user presses the shutter button real fast when the camera starts 431 * (startPreview followed immediately by takePicture). 432 * + burst capture case (hitting shutter button as fast possible) 433 * 434 * If this happens in steady case (preview running for a while, call 435 * a single takePicture) then this might be a fwk bug. 436 */ 437 ALOGW("%s: ZSL queue has no metadata frames", __FUNCTION__); 438 } 439 440 ALOGV("%s: Candidate timestamp %" PRId64 " (idx %zu), empty frames: %zu", 441 __FUNCTION__, minTimestamp, idx, emptyCount); 442 443 if (metadataIdx) { 444 *metadataIdx = idx; 445 } 446 447 return minTimestamp; 448} 449 450void ZslProcessor3::onBufferAcquired(const BufferInfo& /*bufferInfo*/) { 451 // Intentionally left empty 452 // Although theoretically we could use this to get better dump info 453} 454 455void ZslProcessor3::onBufferReleased(const BufferInfo& bufferInfo) { 456 Mutex::Autolock l(mInputMutex); 457 458 // ignore output buffers 459 if (bufferInfo.mOutput) { 460 return; 461 } 462 463 // TODO: Verify that the buffer is in our queue by looking at timestamp 464 // theoretically unnecessary unless we change the following assumptions: 465 // -- only 1 buffer reprocessed at a time (which is the case now) 466 467 // Erase entire ZSL queue since we've now completed the capture and preview 468 // is stopped. 469 // 470 // We need to guarantee that if we do two back-to-back captures, 471 // the second won't use a buffer that's older/the same as the first, which 472 // is theoretically possible if we don't clear out the queue and the 473 // selection criteria is something like 'newest'. Clearing out the queue 474 // on a completed capture ensures we'll only use new data. 475 ALOGV("%s: Memory optimization, clearing ZSL queue", 476 __FUNCTION__); 477 clearZslQueueLocked(); 478 479 // Required so we accept more ZSL requests 480 mState = RUNNING; 481} 482 483}; // namespace camera2 484}; // namespace android 485