CaptureSequencer.cpp revision e538206d15282afbc5b168d60b1026a5dfcd13c0
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 status_t res; 257 sp<ZslProcessor> processor = mZslProcessor.promote(); 258 if (processor == 0) { 259 ALOGE("%s: No ZSL queue to use!", __FUNCTION__); 260 return DONE; 261 } 262 263 client->registerFrameListener(mCaptureId, 264 this); 265 266 res = client->getCameraDevice()->clearStreamingRequest(); 267 if (res != OK) { 268 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: " 269 "%s (%d)", 270 __FUNCTION__, client->getCameraId(), strerror(-res), res); 271 return DONE; 272 } 273 // TODO: Actually select the right thing here. 274 processor->pushToReprocess(mCaptureId); 275 276 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 277 return STANDARD_CAPTURE_WAIT; 278} 279 280CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting( 281 sp<Camera2Client> &client) { 282 return DONE; 283} 284 285CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing( 286 sp<Camera2Client> &client) { 287 return START; 288} 289 290CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart( 291 sp<Camera2Client> &client) { 292 ATRACE_CALL(); 293 client->registerFrameListener(mCaptureId, 294 this); 295 { 296 SharedParameters::Lock l(client->getParameters()); 297 mTriggerId = l.mParameters.precaptureTriggerCounter++; 298 } 299 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId); 300 301 mAeInPrecapture = false; 302 mTimeoutCount = kMaxTimeoutsForPrecaptureStart; 303 return STANDARD_PRECAPTURE_WAIT; 304} 305 306CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait( 307 sp<Camera2Client> &client) { 308 status_t res; 309 ATRACE_CALL(); 310 Mutex::Autolock l(mInputMutex); 311 while (!mNewAEState) { 312 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration); 313 if (res == TIMED_OUT) { 314 mTimeoutCount--; 315 break; 316 } 317 } 318 if (mTimeoutCount <= 0) { 319 ALOGW("Timed out waiting for precapture %s", 320 mAeInPrecapture ? "end" : "start"); 321 return STANDARD_CAPTURE; 322 } 323 if (mNewAEState) { 324 if (!mAeInPrecapture) { 325 // Waiting to see PRECAPTURE state 326 if (mAETriggerId == mTriggerId && 327 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 328 ALOGV("%s: Got precapture start", __FUNCTION__); 329 mAeInPrecapture = true; 330 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd; 331 } 332 } else { 333 // Waiting to see PRECAPTURE state end 334 if (mAETriggerId == mTriggerId && 335 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { 336 ALOGV("%s: Got precapture end", __FUNCTION__); 337 return STANDARD_CAPTURE; 338 } 339 } 340 mNewAEState = false; 341 } 342 return STANDARD_PRECAPTURE_WAIT; 343} 344 345CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture( 346 sp<Camera2Client> &client) { 347 status_t res; 348 ATRACE_CALL(); 349 SharedParameters::Lock l(client->getParameters()); 350 Vector<uint8_t> outputStreams; 351 352 outputStreams.push(client->getPreviewStreamId()); 353 outputStreams.push(client->getCaptureStreamId()); 354 355 if (l.mParameters.previewCallbackFlags & 356 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { 357 outputStreams.push(client->getCallbackStreamId()); 358 } 359 360 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) { 361 outputStreams.push(client->getRecordingStreamId()); 362 } 363 364 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS, 365 outputStreams); 366 if (res == OK) { 367 res = mCaptureRequest.update(ANDROID_REQUEST_ID, 368 &mCaptureId, 1); 369 } 370 if (res == OK) { 371 res = mCaptureRequest.sort(); 372 } 373 374 if (res != OK) { 375 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 376 __FUNCTION__, client->getCameraId(), strerror(-res), res); 377 return DONE; 378 } 379 380 CameraMetadata captureCopy = mCaptureRequest; 381 if (captureCopy.entryCount() == 0) { 382 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 383 __FUNCTION__, client->getCameraId()); 384 return DONE; 385 } 386 387 if (l.mParameters.state == Parameters::STILL_CAPTURE) { 388 res = client->getCameraDevice()->clearStreamingRequest(); 389 if (res != OK) { 390 ALOGE("%s: Camera %d: Unable to stop preview for still capture: " 391 "%s (%d)", 392 __FUNCTION__, client->getCameraId(), strerror(-res), res); 393 return DONE; 394 } 395 } 396 // TODO: Capture should be atomic with setStreamingRequest here 397 res = client->getCameraDevice()->capture(captureCopy); 398 if (res != OK) { 399 ALOGE("%s: Camera %d: Unable to submit still image capture request: " 400 "%s (%d)", 401 __FUNCTION__, client->getCameraId(), strerror(-res), res); 402 return DONE; 403 } 404 405 if (l.mParameters.playShutterSound) { 406 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER); 407 } 408 409 mTimeoutCount = kMaxTimeoutsForCaptureEnd; 410 return STANDARD_CAPTURE_WAIT; 411} 412 413CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait( 414 sp<Camera2Client> &client) { 415 status_t res; 416 ATRACE_CALL(); 417 Mutex::Autolock l(mInputMutex); 418 while (!mNewFrameReceived) { 419 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration); 420 if (res == TIMED_OUT) { 421 mTimeoutCount--; 422 break; 423 } 424 } 425 while (!mNewCaptureReceived) { 426 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 427 if (res == TIMED_OUT) { 428 mTimeoutCount--; 429 break; 430 } 431 } 432 if (mTimeoutCount <= 0) { 433 ALOGW("Timed out waiting for capture to complete"); 434 return DONE; 435 } 436 if (mNewFrameReceived && mNewCaptureReceived) { 437 if (mNewFrameId != mCaptureId) { 438 ALOGW("Mismatched capture frame IDs: Expected %d, got %d", 439 mCaptureId, mNewFrameId); 440 } 441 camera_metadata_entry_t entry; 442 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP); 443 if (entry.count == 0) { 444 ALOGE("No timestamp field in capture frame!"); 445 } 446 if (entry.data.i64[0] != mCaptureTimestamp) { 447 ALOGW("Mismatched capture timestamps: Metadata frame %lld," 448 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp); 449 } 450 client->removeFrameListener(mCaptureId); 451 452 mNewFrameReceived = false; 453 mNewCaptureReceived = false; 454 return DONE; 455 } 456 return STANDARD_CAPTURE_WAIT; 457} 458 459CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart( 460 sp<Camera2Client> &client) { 461 ALOGV("%s", __FUNCTION__); 462 status_t res; 463 ATRACE_CALL(); 464 465 // check which burst mode is set, create respective burst object 466 { 467 SharedParameters::Lock l(client->getParameters()); 468 469 res = updateCaptureRequest(l.mParameters, client); 470 if(res != OK) { 471 return DONE; 472 } 473 474 // 475 // check for burst mode type in mParameters here 476 // 477 mBurstCapture = new BurstCapture(client, this); 478 } 479 480 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1); 481 if (res == OK) { 482 res = mCaptureRequest.sort(); 483 } 484 if (res != OK) { 485 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)", 486 __FUNCTION__, client->getCameraId(), strerror(-res), res); 487 return DONE; 488 } 489 490 CameraMetadata captureCopy = mCaptureRequest; 491 if (captureCopy.entryCount() == 0) { 492 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device", 493 __FUNCTION__, client->getCameraId()); 494 return DONE; 495 } 496 497 Vector<CameraMetadata> requests; 498 requests.push(mCaptureRequest); 499 res = mBurstCapture->start(requests, mCaptureId); 500 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10; 501 return BURST_CAPTURE_WAIT; 502} 503 504CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait( 505 sp<Camera2Client> &client) { 506 status_t res; 507 ATRACE_CALL(); 508 509 while (!mNewCaptureReceived) { 510 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration); 511 if (res == TIMED_OUT) { 512 mTimeoutCount--; 513 break; 514 } 515 } 516 517 if (mTimeoutCount <= 0) { 518 ALOGW("Timed out waiting for burst capture to complete"); 519 return DONE; 520 } 521 if (mNewCaptureReceived) { 522 mNewCaptureReceived = false; 523 // TODO: update mCaptureId to last burst's capture ID + 1? 524 return DONE; 525 } 526 527 return BURST_CAPTURE_WAIT; 528} 529 530status_t CaptureSequencer::updateCaptureRequest(const Parameters ¶ms, 531 sp<Camera2Client> &client) { 532 ATRACE_CALL(); 533 status_t res; 534 if (mCaptureRequest.entryCount() == 0) { 535 res = client->getCameraDevice()->createDefaultRequest( 536 CAMERA2_TEMPLATE_STILL_CAPTURE, 537 &mCaptureRequest); 538 if (res != OK) { 539 ALOGE("%s: Camera %d: Unable to create default still image request:" 540 " %s (%d)", __FUNCTION__, client->getCameraId(), 541 strerror(-res), res); 542 return res; 543 } 544 } 545 546 res = params.updateRequest(&mCaptureRequest); 547 if (res != OK) { 548 ALOGE("%s: Camera %d: Unable to update common entries of capture " 549 "request: %s (%d)", __FUNCTION__, client->getCameraId(), 550 strerror(-res), res); 551 return res; 552 } 553 554 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE, 555 params.jpegThumbSize, 2); 556 if (res != OK) return res; 557 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY, 558 ¶ms.jpegThumbQuality, 1); 559 if (res != OK) return res; 560 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY, 561 ¶ms.jpegQuality, 1); 562 if (res != OK) return res; 563 res = mCaptureRequest.update( 564 ANDROID_JPEG_ORIENTATION, 565 ¶ms.jpegRotation, 1); 566 if (res != OK) return res; 567 568 if (params.gpsEnabled) { 569 res = mCaptureRequest.update( 570 ANDROID_JPEG_GPS_COORDINATES, 571 params.gpsCoordinates, 3); 572 if (res != OK) return res; 573 res = mCaptureRequest.update( 574 ANDROID_JPEG_GPS_TIMESTAMP, 575 ¶ms.gpsTimestamp, 1); 576 if (res != OK) return res; 577 res = mCaptureRequest.update( 578 ANDROID_JPEG_GPS_PROCESSING_METHOD, 579 params.gpsProcessingMethod); 580 if (res != OK) return res; 581 } else { 582 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES); 583 if (res != OK) return res; 584 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP); 585 if (res != OK) return res; 586 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD); 587 if (res != OK) return res; 588 } 589 590 return OK; 591} 592 593 594}; // namespace camera2 595}; // namespace android 596