CaptureSequencer.cpp revision bdde5f884eaf270ab4b806849f3122a46cd872ce
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::CaptureSequencer" 18#define ATRACE_TAG ATRACE_TAG_CAMERA 19//#define LOG_NDEBUG 0 20 21#include <utils/Log.h> 22#include <utils/Trace.h> 23#include <utils/Vector.h> 24 25#include "CaptureSequencer.h" 26#include "BurstCapture.h" 27#include "../Camera2Device.h" 28#include "../Camera2Client.h" 29#include "Parameters.h" 30 31namespace android { 32namespace camera2 { 33 34/** Public members */ 35 36CaptureSequencer::CaptureSequencer(wp<Camera2Client> client): 37 Thread(false), 38 mStartCapture(false), 39 mBusy(false), 40 mNewAEState(false), 41 mNewFrameReceived(false), 42 mNewCaptureReceived(false), 43 mClient(client), 44 mCaptureState(IDLE), 45 mTriggerId(0), 46 mTimeoutCount(0), 47 mCaptureId(Camera2Client::kFirstCaptureRequestId) { 48 ALOGV("%s", __FUNCTION__); 49} 50 51CaptureSequencer::~CaptureSequencer() { 52 ALOGV("%s: Exit", __FUNCTION__); 53} 54 55void CaptureSequencer::setZslProcessor(wp<ZslProcessor> processor) { 56 Mutex::Autolock l(mInputMutex); 57 mZslProcessor = processor; 58} 59 60status_t CaptureSequencer::startCapture() { 61 ALOGV("%s", __FUNCTION__); 62 ATRACE_CALL(); 63 Mutex::Autolock l(mInputMutex); 64 if (mBusy) { 65 ALOGE("%s: Already busy capturing!", __FUNCTION__); 66 return INVALID_OPERATION; 67 } 68 if (!mStartCapture) { 69 mStartCapture = true; 70 mStartCaptureSignal.signal(); 71 } 72 return OK; 73} 74 75void CaptureSequencer::notifyAutoExposure(uint8_t newState, int triggerId) { 76 ATRACE_CALL(); 77 Mutex::Autolock l(mInputMutex); 78 mAEState = newState; 79 mAETriggerId = triggerId; 80 if (!mNewAEState) { 81 mNewAEState = true; 82 mNewNotifySignal.signal(); 83 } 84} 85 86void CaptureSequencer::onFrameAvailable(int32_t frameId, 87 CameraMetadata &frame) { 88 ALOGV("%s: Listener found new frame", __FUNCTION__); 89 ATRACE_CALL(); 90 Mutex::Autolock l(mInputMutex); 91 mNewFrameId = frameId; 92 mNewFrame.acquire(frame); 93 if (!mNewFrameReceived) { 94 mNewFrameReceived = true; 95 mNewFrameSignal.signal(); 96 } 97} 98 99void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp) { 100 ATRACE_CALL(); 101 ALOGV("%s", __FUNCTION__); 102 Mutex::Autolock l(mInputMutex); 103 mCaptureTimestamp = timestamp; 104 if (!mNewCaptureReceived) { 105 mNewCaptureReceived = true; 106 mNewCaptureSignal.signal(); 107 } 108} 109 110 111void CaptureSequencer::dump(int fd, const Vector<String16>& args) { 112 String8 result; 113 if (mCaptureRequest.entryCount() != 0) { 114 result = " Capture request:\n"; 115 write(fd, result.string(), result.size()); 116 mCaptureRequest.dump(fd, 2, 6); 117 } else { 118 result = " Capture request: undefined\n"; 119 write(fd, result.string(), result.size()); 120 } 121 result = String8::format(" Current capture state: %s\n", 122 kStateNames[mCaptureState]); 123 result.append(" Latest captured frame:\n"); 124 write(fd, result.string(), result.size()); 125 mNewFrame.dump(fd, 2, 6); 126} 127 128/** Private members */ 129 130const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] = 131{ 132 "IDLE", 133 "START", 134 "ZSL_START", 135 "ZSL_WAITING", 136 "ZSL_REPROCESSING", 137 "STANDARD_START", 138 "STANDARD_PRECAPTURE", 139 "STANDARD_CAPTURING", 140 "BURST_CAPTURE_START", 141 "BURST_CAPTURE_WAIT", 142 "DONE", 143 "ERROR", 144 "UNKNOWN" 145}; 146 147const CaptureSequencer::StateManager 148 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = { 149 &CaptureSequencer::manageIdle, 150 &CaptureSequencer::manageStart, 151 &CaptureSequencer::manageZslStart, 152 &CaptureSequencer::manageZslWaiting, 153 &CaptureSequencer::manageZslReprocessing, 154 &CaptureSequencer::manageStandardStart, 155 &CaptureSequencer::manageStandardPrecaptureWait, 156 &CaptureSequencer::manageStandardCapture, 157 &CaptureSequencer::manageStandardCaptureWait, 158 &CaptureSequencer::manageBurstCaptureStart, 159 &CaptureSequencer::manageBurstCaptureWait, 160 &CaptureSequencer::manageDone, 161}; 162 163bool CaptureSequencer::threadLoop() { 164 status_t res; 165 166 sp<Camera2Client> client = mClient.promote(); 167 if (client == 0) return false; 168 169 if (mCaptureState < ERROR) { 170 mCaptureState = (this->*kStateManagers[mCaptureState])(client); 171 } else { 172 ALOGE("%s: Bad capture state: %s", 173 __FUNCTION__, kStateNames[mCaptureState]); 174 return false; 175 } 176 177 return true; 178} 179 180CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) { 181 status_t res; 182 ATRACE_CALL(); 183 Mutex::Autolock l(mInputMutex); 184 while (!mStartCapture) { 185 res = mStartCaptureSignal.waitRelative(mInputMutex, 186 kWaitDuration); 187 if (res == TIMED_OUT) break; 188 } 189 if (mStartCapture) { 190 mStartCapture = false; 191 mBusy = true; 192 return START; 193 } 194 return IDLE; 195} 196 197CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) { 198 status_t res; 199 ATRACE_CALL(); 200 mCaptureId++; 201 202 { 203 Mutex::Autolock l(mInputMutex); 204 mBusy = false; 205 } 206 207 SharedParameters::Lock l(client->getParameters()); 208 switch (l.mParameters.state) { 209 case Parameters::STILL_CAPTURE: 210 l.mParameters.state = Parameters::STOPPED; 211 break; 212 case Parameters::VIDEO_SNAPSHOT: 213 l.mParameters.state = Parameters::RECORD; 214 break; 215 default: 216 ALOGE("%s: Camera %d: Still image produced unexpectedly " 217 "in state %s!", 218 __FUNCTION__, client->getCameraId(), 219 Parameters::getStateName(l.mParameters.state)); 220 } 221 222 return IDLE; 223} 224 225CaptureSequencer::CaptureState CaptureSequencer::manageStart( 226 sp<Camera2Client> &client) { 227 ALOGV("%s", __FUNCTION__); 228 status_t res; 229 ATRACE_CALL(); 230 SharedParameters::Lock l(client->getParameters()); 231 CaptureState nextState = DONE; 232 233 res = updateCaptureRequest(l.mParameters, client); 234 if (res != OK ) { 235 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)", 236 __FUNCTION__, client->getCameraId(), strerror(-res), res); 237 return DONE; 238 } 239 240 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE && 241 l.mParameters.state == Parameters::STILL_CAPTURE) { 242 nextState = BURST_CAPTURE_START; 243 } 244 else if (l.mParameters.zslMode && 245 l.mParameters.state == Parameters::STILL_CAPTURE) { 246 nextState = ZSL_START; 247 } else { 248 nextState = STANDARD_START; 249 } 250 251 return nextState; 252} 253 254CaptureSequencer::CaptureState CaptureSequencer::manageZslStart( 255 sp<Camera2Client> &client) { 256 ALOGV("%s", __FUNCTION__); 257 status_t res; 258 sp<ZslProcessor> processor = mZslProcessor.promote(); 259 if (processor == 0) { 260 ALOGE("%s: No ZSL queue to use!", __FUNCTION__); 261 return DONE; 262 } 263 264 client->registerFrameListener(mCaptureId, 265 this); 266 267 res = client->getCameraDevice()->clearStreamingRequest(); 268 if (res != OK) { 269 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: " 270 "%s (%d)", 271 __FUNCTION__, client->getCameraId(), strerror(-res), res); 272 return DONE; 273 } 274 // TODO: Actually select the right thing here. 275 res = processor->pushToReprocess(mCaptureId); 276 if (res != OK) { 277 ALOGW("%s: Camera %d: Failed to use ZSL queue, falling back to standard capture", 278 __FUNCTION__, client->getCameraId()); 279 return STANDARD_START; 280 } 281 282 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 283 return STANDARD_CAPTURE_WAIT; 284} 285 286CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting( 287 sp<Camera2Client> &client) { 288 ALOGV("%s", __FUNCTION__); 289 return DONE; 290} 291 292CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing( 293 sp<Camera2Client> &client) { 294 ALOGV("%s", __FUNCTION__); 295 return START; 296} 297 298CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart( 299 sp<Camera2Client> &client) { 300 ATRACE_CALL(); 301 client->registerFrameListener(mCaptureId, 302 this); 303 { 304 SharedParameters::Lock l(client->getParameters()); 305 mTriggerId = l.mParameters.precaptureTriggerCounter++; 306 } 307 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId); 308 309 mAeInPrecapture = false; 310 mTimeoutCount = kMaxTimeoutsForPrecaptureStart; 311 return STANDARD_PRECAPTURE_WAIT; 312} 313 314CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait( 315 sp<Camera2Client> &client) { 316 status_t res; 317 ATRACE_CALL(); 318 Mutex::Autolock l(mInputMutex); 319 while (!mNewAEState) { 320 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration); 321 if (res == TIMED_OUT) { 322 mTimeoutCount--; 323 break; 324 } 325 } 326 if (mTimeoutCount <= 0) { 327 ALOGW("Timed out waiting for precapture %s", 328 mAeInPrecapture ? "end" : "start"); 329 return STANDARD_CAPTURE; 330 } 331 if (mNewAEState) { 332 if (!mAeInPrecapture) { 333 // Waiting to see PRECAPTURE state 334 if (mAETriggerId == mTriggerId && 335 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 336 ALOGV("%s: Got precapture start", __FUNCTION__); 337 mAeInPrecapture = true; 338 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd; 339 } 340 } else { 341 // Waiting to see PRECAPTURE state end 342 if (mAETriggerId == mTriggerId && 343 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 344 ALOGV("%s: Got precapture end", __FUNCTION__); 345 return STANDARD_CAPTURE; 346 } 347 } 348 mNewAEState = false; 349 } 350 return STANDARD_PRECAPTURE_WAIT; 351} 352 353CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture( 354 sp<Camera2Client> &client) { 355 status_t res; 356 ATRACE_CALL(); 357 SharedParameters::Lock l(client->getParameters()); 358 Vector<uint8_t> outputStreams; 359 360 outputStreams.push(client->getPreviewStreamId()); 361 outputStreams.push(client->getCaptureStreamId()); 362 363 if (l.mParameters.previewCallbackFlags & 364 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { 365 outputStreams.push(client->getCallbackStreamId()); 366 } 367 368 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) { 369 outputStreams.push(client->getRecordingStreamId()); 370 } 371 372 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS, 373 outputStreams); 374 if (res == OK) { 375 res = mCaptureRequest.update(ANDROID_REQUEST_ID, 376 &mCaptureId, 1); 377 } 378 if (res == OK) { 379 res = mCaptureRequest.sort(); 380 } 381 382 if (res != OK) { 383 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 384 __FUNCTION__, client->getCameraId(), strerror(-res), res); 385 return DONE; 386 } 387 388 CameraMetadata captureCopy = mCaptureRequest; 389 if (captureCopy.entryCount() == 0) { 390 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 391 __FUNCTION__, client->getCameraId()); 392 return DONE; 393 } 394 395 if (l.mParameters.state == Parameters::STILL_CAPTURE) { 396 res = client->getCameraDevice()->clearStreamingRequest(); 397 if (res != OK) { 398 ALOGE("%s: Camera %d: Unable to stop preview for still capture: " 399 "%s (%d)", 400 __FUNCTION__, client->getCameraId(), strerror(-res), res); 401 return DONE; 402 } 403 } 404 // TODO: Capture should be atomic with setStreamingRequest here 405 res = client->getCameraDevice()->capture(captureCopy); 406 if (res != OK) { 407 ALOGE("%s: Camera %d: Unable to submit still image capture request: " 408 "%s (%d)", 409 __FUNCTION__, client->getCameraId(), strerror(-res), res); 410 return DONE; 411 } 412 413 if (l.mParameters.playShutterSound) { 414 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); 415 } 416 417 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 418 return STANDARD_CAPTURE_WAIT; 419} 420 421CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( 422 sp<Camera2Client> &client) { 423 status_t res; 424 ATRACE_CALL(); 425 Mutex::Autolock l(mInputMutex); 426 while (!mNewFrameReceived) { 427 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration); 428 if (res == TIMED_OUT) { 429 mTimeoutCount--; 430 break; 431 } 432 } 433 while (!mNewCaptureReceived) { 434 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 435 if (res == TIMED_OUT) { 436 mTimeoutCount--; 437 break; 438 } 439 } 440 if (mTimeoutCount <= 0) { 441 ALOGW("Timed out waiting for capture to complete"); 442 return DONE; 443 } 444 if (mNewFrameReceived && mNewCaptureReceived) { 445 if (mNewFrameId != mCaptureId) { 446 ALOGW("Mismatched capture frame IDs: Expected %d, got %d", 447 mCaptureId, mNewFrameId); 448 } 449 camera_metadata_entry_t entry; 450 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP); 451 if (entry.count == 0) { 452 ALOGE("No timestamp field in capture frame!"); 453 } 454 if (entry.data.i64[0] != mCaptureTimestamp) { 455 ALOGW("Mismatched capture timestamps: Metadata frame %lld," 456 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp); 457 } 458 client->removeFrameListener(mCaptureId); 459 460 mNewFrameReceived = false; 461 mNewCaptureReceived = false; 462 return DONE; 463 } 464 return STANDARD_CAPTURE_WAIT; 465} 466 467CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart( 468 sp<Camera2Client> &client) { 469 ALOGV("%s", __FUNCTION__); 470 status_t res; 471 ATRACE_CALL(); 472 473 // check which burst mode is set, create respective burst object 474 { 475 SharedParameters::Lock l(client->getParameters()); 476 477 res = updateCaptureRequest(l.mParameters, client); 478 if(res != OK) { 479 return DONE; 480 } 481 482 // 483 // check for burst mode type in mParameters here 484 // 485 mBurstCapture = new BurstCapture(client, this); 486 } 487 488 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1); 489 if (res == OK) { 490 res = mCaptureRequest.sort(); 491 } 492 if (res != OK) { 493 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 494 __FUNCTION__, client->getCameraId(), strerror(-res), res); 495 return DONE; 496 } 497 498 CameraMetadata captureCopy = mCaptureRequest; 499 if (captureCopy.entryCount() == 0) { 500 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 501 __FUNCTION__, client->getCameraId()); 502 return DONE; 503 } 504 505 Vector<CameraMetadata> requests; 506 requests.push(mCaptureRequest); 507 res = mBurstCapture->start(requests, mCaptureId); 508 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10; 509 return BURST_CAPTURE_WAIT; 510} 511 512CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait( 513 sp<Camera2Client> &client) { 514 status_t res; 515 ATRACE_CALL(); 516 517 while (!mNewCaptureReceived) { 518 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 519 if (res == TIMED_OUT) { 520 mTimeoutCount--; 521 break; 522 } 523 } 524 525 if (mTimeoutCount <= 0) { 526 ALOGW("Timed out waiting for burst capture to complete"); 527 return DONE; 528 } 529 if (mNewCaptureReceived) { 530 mNewCaptureReceived = false; 531 // TODO: update mCaptureId to last burst's capture ID + 1? 532 return DONE; 533 } 534 535 return BURST_CAPTURE_WAIT; 536} 537 538status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms, 539 sp<Camera2Client> &client) { 540 ATRACE_CALL(); 541 status_t res; 542 if (mCaptureRequest.entryCount() == 0) { 543 res = client->getCameraDevice()->createDefaultRequest( 544 CAMERA2_TEMPLATE_STILL_CAPTURE, 545 &mCaptureRequest); 546 if (res != OK) { 547 ALOGE("%s: Camera %d: Unable to create default still image request:" 548 " %s (%d)", __FUNCTION__, client->getCameraId(), 549 strerror(-res), res); 550 return res; 551 } 552 } 553 554 res = params.updateRequest(&mCaptureRequest); 555 if (res != OK) { 556 ALOGE("%s: Camera %d: Unable to update common entries of capture " 557 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 558 strerror(-res), res); 559 return res; 560 } 561 562 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE, 563 params.jpegThumbSize, 2); 564 if (res != OK) return res; 565 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY, 566 ¶ms.jpegThumbQuality, 1); 567 if (res != OK) return res; 568 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY, 569 ¶ms.jpegQuality, 1); 570 if (res != OK) return res; 571 res = mCaptureRequest.update( 572 ANDROID_JPEG_ORIENTATION, 573 ¶ms.jpegRotation, 1); 574 if (res != OK) return res; 575 576 if (params.gpsEnabled) { 577 res = mCaptureRequest.update( 578 ANDROID_JPEG_GPS_COORDINATES, 579 params.gpsCoordinates, 3); 580 if (res != OK) return res; 581 res = mCaptureRequest.update( 582 ANDROID_JPEG_GPS_TIMESTAMP, 583 ¶ms.gpsTimestamp, 1); 584 if (res != OK) return res; 585 res = mCaptureRequest.update( 586 ANDROID_JPEG_GPS_PROCESSING_METHOD, 587 params.gpsProcessingMethod); 588 if (res != OK) return res; 589 } else { 590 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES); 591 if (res != OK) return res; 592 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP); 593 if (res != OK) return res; 594 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD); 595 if (res != OK) return res; 596 } 597 598 return OK; 599} 600 601 602}; // namespace camera2 603}; // namespace android 604