blob: c9498c2c7168c70f18a63536f356148b2b8f4db9 [file] [log] [blame]
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001/*
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
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070017#define LOG_TAG "Camera2-CaptureSequencer"
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070018#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"
James Painterc3dbf1a2012-09-05 18:02:32 -070026#include "BurstCapture.h"
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070027#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) {
James Painterc3dbf1a2012-09-05 18:02:32 -070048 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070049}
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() {
James Painterc3dbf1a2012-09-05 18:02:32 -070061 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070062 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) {
James Painterc3dbf1a2012-09-05 18:02:32 -070088 ALOGV("%s: Listener found new frame", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070089 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
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -070099void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
100 sp<MemoryBase> captureBuffer) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700101 ATRACE_CALL();
James Painterc3dbf1a2012-09-05 18:02:32 -0700102 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700103 Mutex::Autolock l(mInputMutex);
104 mCaptureTimestamp = timestamp;
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700105 mCaptureBuffer = captureBuffer;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700106 if (!mNewCaptureReceived) {
107 mNewCaptureReceived = true;
108 mNewCaptureSignal.signal();
109 }
110}
111
112
113void CaptureSequencer::dump(int fd, const Vector<String16>& args) {
114 String8 result;
115 if (mCaptureRequest.entryCount() != 0) {
116 result = " Capture request:\n";
117 write(fd, result.string(), result.size());
118 mCaptureRequest.dump(fd, 2, 6);
119 } else {
120 result = " Capture request: undefined\n";
121 write(fd, result.string(), result.size());
122 }
123 result = String8::format(" Current capture state: %s\n",
124 kStateNames[mCaptureState]);
125 result.append(" Latest captured frame:\n");
126 write(fd, result.string(), result.size());
127 mNewFrame.dump(fd, 2, 6);
128}
129
130/** Private members */
131
132const char* CaptureSequencer::kStateNames[CaptureSequencer::NUM_CAPTURE_STATES+1] =
133{
134 "IDLE",
135 "START",
136 "ZSL_START",
137 "ZSL_WAITING",
138 "ZSL_REPROCESSING",
139 "STANDARD_START",
140 "STANDARD_PRECAPTURE",
141 "STANDARD_CAPTURING",
James Painterc3dbf1a2012-09-05 18:02:32 -0700142 "BURST_CAPTURE_START",
143 "BURST_CAPTURE_WAIT",
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700144 "DONE",
145 "ERROR",
146 "UNKNOWN"
147};
148
149const CaptureSequencer::StateManager
150 CaptureSequencer::kStateManagers[CaptureSequencer::NUM_CAPTURE_STATES-1] = {
151 &CaptureSequencer::manageIdle,
152 &CaptureSequencer::manageStart,
153 &CaptureSequencer::manageZslStart,
154 &CaptureSequencer::manageZslWaiting,
155 &CaptureSequencer::manageZslReprocessing,
156 &CaptureSequencer::manageStandardStart,
157 &CaptureSequencer::manageStandardPrecaptureWait,
158 &CaptureSequencer::manageStandardCapture,
159 &CaptureSequencer::manageStandardCaptureWait,
James Painterc3dbf1a2012-09-05 18:02:32 -0700160 &CaptureSequencer::manageBurstCaptureStart,
161 &CaptureSequencer::manageBurstCaptureWait,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700162 &CaptureSequencer::manageDone,
163};
164
165bool CaptureSequencer::threadLoop() {
166 status_t res;
167
168 sp<Camera2Client> client = mClient.promote();
169 if (client == 0) return false;
170
171 if (mCaptureState < ERROR) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700172 CaptureState oldState = mCaptureState;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700173 mCaptureState = (this->*kStateManagers[mCaptureState])(client);
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700174 if (ATRACE_ENABLED() && oldState != mCaptureState) {
175 ATRACE_INT("cam2_capt_state", mCaptureState);
176 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700177 } else {
178 ALOGE("%s: Bad capture state: %s",
179 __FUNCTION__, kStateNames[mCaptureState]);
180 return false;
181 }
182
183 return true;
184}
185
186CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) {
187 status_t res;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700188 Mutex::Autolock l(mInputMutex);
189 while (!mStartCapture) {
190 res = mStartCaptureSignal.waitRelative(mInputMutex,
191 kWaitDuration);
192 if (res == TIMED_OUT) break;
193 }
194 if (mStartCapture) {
195 mStartCapture = false;
196 mBusy = true;
197 return START;
198 }
199 return IDLE;
200}
201
202CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700203 status_t res = OK;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700204 ATRACE_CALL();
205 mCaptureId++;
206
207 {
208 Mutex::Autolock l(mInputMutex);
209 mBusy = false;
210 }
211
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700212 {
213 SharedParameters::Lock l(client->getParameters());
214 switch (l.mParameters.state) {
215 case Parameters::STILL_CAPTURE:
216 l.mParameters.state = Parameters::STOPPED;
217 break;
218 case Parameters::VIDEO_SNAPSHOT:
219 l.mParameters.state = Parameters::RECORD;
220 break;
221 default:
222 ALOGE("%s: Camera %d: Still image produced unexpectedly "
223 "in state %s!",
224 __FUNCTION__, client->getCameraId(),
225 Parameters::getStateName(l.mParameters.state));
226 res = INVALID_OPERATION;
227 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700228 }
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700229 sp<ZslProcessor> processor = mZslProcessor.promote();
230 if (processor != 0) {
231 processor->clearZslQueue();
232 }
233
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700234 if (mCaptureBuffer != 0 && res == OK) {
235 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
236 ALOGV("%s: Sending still image to client", __FUNCTION__);
237 if (l.mCameraClient != 0) {
238 l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
239 mCaptureBuffer, NULL);
240 } else {
241 ALOGV("%s: No client!", __FUNCTION__);
242 }
243 }
244 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700245
246 return IDLE;
247}
248
249CaptureSequencer::CaptureState CaptureSequencer::manageStart(
250 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700251 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700252 status_t res;
253 ATRACE_CALL();
254 SharedParameters::Lock l(client->getParameters());
255 CaptureState nextState = DONE;
256
257 res = updateCaptureRequest(l.mParameters, client);
258 if (res != OK ) {
259 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
260 __FUNCTION__, client->getCameraId(), strerror(-res), res);
261 return DONE;
262 }
263
James Painterc3dbf1a2012-09-05 18:02:32 -0700264 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
265 l.mParameters.state == Parameters::STILL_CAPTURE) {
266 nextState = BURST_CAPTURE_START;
267 }
268 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700269 l.mParameters.state == Parameters::STILL_CAPTURE &&
270 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700271 nextState = ZSL_START;
272 } else {
273 nextState = STANDARD_START;
274 }
275
276 return nextState;
277}
278
279CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
280 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700281 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700282 status_t res;
283 sp<ZslProcessor> processor = mZslProcessor.promote();
284 if (processor == 0) {
285 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
286 return DONE;
287 }
288
289 client->registerFrameListener(mCaptureId,
290 this);
291
292 res = client->getCameraDevice()->clearStreamingRequest();
293 if (res != OK) {
294 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
295 "%s (%d)",
296 __FUNCTION__, client->getCameraId(), strerror(-res), res);
297 return DONE;
298 }
299 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700300 res = processor->pushToReprocess(mCaptureId);
301 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700302 if (res == NOT_ENOUGH_DATA) {
303 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
304 "falling back to normal capture", __FUNCTION__,
305 client->getCameraId());
306 } else {
307 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
308 __FUNCTION__, client->getCameraId(), strerror(-res), res);
309 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700310 return STANDARD_START;
311 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700312
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700313 SharedParameters::Lock l(client->getParameters());
Igor Murashkin707c3e32012-09-20 15:18:50 -0700314 /* warning: this also locks a SharedCameraClient */
315 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700316
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700317 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
318 return STANDARD_CAPTURE_WAIT;
319}
320
321CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
322 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700323 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700324 return DONE;
325}
326
327CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
328 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700329 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700330 return START;
331}
332
333CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
334 sp<Camera2Client> &client) {
335 ATRACE_CALL();
336 client->registerFrameListener(mCaptureId,
337 this);
338 {
339 SharedParameters::Lock l(client->getParameters());
340 mTriggerId = l.mParameters.precaptureTriggerCounter++;
341 }
342 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
343
344 mAeInPrecapture = false;
345 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
346 return STANDARD_PRECAPTURE_WAIT;
347}
348
349CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
350 sp<Camera2Client> &client) {
351 status_t res;
352 ATRACE_CALL();
353 Mutex::Autolock l(mInputMutex);
354 while (!mNewAEState) {
355 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
356 if (res == TIMED_OUT) {
357 mTimeoutCount--;
358 break;
359 }
360 }
361 if (mTimeoutCount <= 0) {
362 ALOGW("Timed out waiting for precapture %s",
363 mAeInPrecapture ? "end" : "start");
364 return STANDARD_CAPTURE;
365 }
366 if (mNewAEState) {
367 if (!mAeInPrecapture) {
368 // Waiting to see PRECAPTURE state
369 if (mAETriggerId == mTriggerId &&
370 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
371 ALOGV("%s: Got precapture start", __FUNCTION__);
372 mAeInPrecapture = true;
373 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
374 }
375 } else {
376 // Waiting to see PRECAPTURE state end
377 if (mAETriggerId == mTriggerId &&
378 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
379 ALOGV("%s: Got precapture end", __FUNCTION__);
380 return STANDARD_CAPTURE;
381 }
382 }
383 mNewAEState = false;
384 }
385 return STANDARD_PRECAPTURE_WAIT;
386}
387
388CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
389 sp<Camera2Client> &client) {
390 status_t res;
391 ATRACE_CALL();
392 SharedParameters::Lock l(client->getParameters());
393 Vector<uint8_t> outputStreams;
394
395 outputStreams.push(client->getPreviewStreamId());
396 outputStreams.push(client->getCaptureStreamId());
397
398 if (l.mParameters.previewCallbackFlags &
399 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
400 outputStreams.push(client->getCallbackStreamId());
401 }
402
403 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
404 outputStreams.push(client->getRecordingStreamId());
405 }
406
407 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
408 outputStreams);
409 if (res == OK) {
410 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
411 &mCaptureId, 1);
412 }
413 if (res == OK) {
414 res = mCaptureRequest.sort();
415 }
416
417 if (res != OK) {
418 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
419 __FUNCTION__, client->getCameraId(), strerror(-res), res);
420 return DONE;
421 }
422
423 CameraMetadata captureCopy = mCaptureRequest;
424 if (captureCopy.entryCount() == 0) {
425 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
426 __FUNCTION__, client->getCameraId());
427 return DONE;
428 }
429
430 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
431 res = client->getCameraDevice()->clearStreamingRequest();
432 if (res != OK) {
433 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
434 "%s (%d)",
435 __FUNCTION__, client->getCameraId(), strerror(-res), res);
436 return DONE;
437 }
438 }
439 // TODO: Capture should be atomic with setStreamingRequest here
440 res = client->getCameraDevice()->capture(captureCopy);
441 if (res != OK) {
442 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
443 "%s (%d)",
444 __FUNCTION__, client->getCameraId(), strerror(-res), res);
445 return DONE;
446 }
447
Igor Murashkin707c3e32012-09-20 15:18:50 -0700448 /* warning: this also locks a SharedCameraClient */
449 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvala33578832012-09-06 18:26:58 -0700450
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700451 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
452 return STANDARD_CAPTURE_WAIT;
453}
454
455CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
456 sp<Camera2Client> &client) {
457 status_t res;
458 ATRACE_CALL();
459 Mutex::Autolock l(mInputMutex);
460 while (!mNewFrameReceived) {
461 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
462 if (res == TIMED_OUT) {
463 mTimeoutCount--;
464 break;
465 }
466 }
467 while (!mNewCaptureReceived) {
468 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
469 if (res == TIMED_OUT) {
470 mTimeoutCount--;
471 break;
472 }
473 }
474 if (mTimeoutCount <= 0) {
475 ALOGW("Timed out waiting for capture to complete");
476 return DONE;
477 }
478 if (mNewFrameReceived && mNewCaptureReceived) {
479 if (mNewFrameId != mCaptureId) {
480 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
481 mCaptureId, mNewFrameId);
482 }
483 camera_metadata_entry_t entry;
484 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
485 if (entry.count == 0) {
486 ALOGE("No timestamp field in capture frame!");
487 }
488 if (entry.data.i64[0] != mCaptureTimestamp) {
489 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
490 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp);
491 }
492 client->removeFrameListener(mCaptureId);
493
494 mNewFrameReceived = false;
495 mNewCaptureReceived = false;
496 return DONE;
497 }
498 return STANDARD_CAPTURE_WAIT;
499}
500
James Painterc3dbf1a2012-09-05 18:02:32 -0700501CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
502 sp<Camera2Client> &client) {
503 ALOGV("%s", __FUNCTION__);
504 status_t res;
505 ATRACE_CALL();
506
507 // check which burst mode is set, create respective burst object
508 {
509 SharedParameters::Lock l(client->getParameters());
510
511 res = updateCaptureRequest(l.mParameters, client);
512 if(res != OK) {
513 return DONE;
514 }
515
516 //
517 // check for burst mode type in mParameters here
518 //
519 mBurstCapture = new BurstCapture(client, this);
520 }
521
522 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
523 if (res == OK) {
524 res = mCaptureRequest.sort();
525 }
526 if (res != OK) {
527 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
528 __FUNCTION__, client->getCameraId(), strerror(-res), res);
529 return DONE;
530 }
531
532 CameraMetadata captureCopy = mCaptureRequest;
533 if (captureCopy.entryCount() == 0) {
534 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
535 __FUNCTION__, client->getCameraId());
536 return DONE;
537 }
538
539 Vector<CameraMetadata> requests;
540 requests.push(mCaptureRequest);
541 res = mBurstCapture->start(requests, mCaptureId);
542 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
543 return BURST_CAPTURE_WAIT;
544}
545
546CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
547 sp<Camera2Client> &client) {
548 status_t res;
549 ATRACE_CALL();
550
551 while (!mNewCaptureReceived) {
552 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
553 if (res == TIMED_OUT) {
554 mTimeoutCount--;
555 break;
556 }
557 }
558
559 if (mTimeoutCount <= 0) {
560 ALOGW("Timed out waiting for burst capture to complete");
561 return DONE;
562 }
563 if (mNewCaptureReceived) {
564 mNewCaptureReceived = false;
565 // TODO: update mCaptureId to last burst's capture ID + 1?
566 return DONE;
567 }
568
569 return BURST_CAPTURE_WAIT;
570}
571
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700572status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
573 sp<Camera2Client> &client) {
574 ATRACE_CALL();
575 status_t res;
576 if (mCaptureRequest.entryCount() == 0) {
577 res = client->getCameraDevice()->createDefaultRequest(
578 CAMERA2_TEMPLATE_STILL_CAPTURE,
579 &mCaptureRequest);
580 if (res != OK) {
581 ALOGE("%s: Camera %d: Unable to create default still image request:"
582 " %s (%d)", __FUNCTION__, client->getCameraId(),
583 strerror(-res), res);
584 return res;
585 }
586 }
587
588 res = params.updateRequest(&mCaptureRequest);
589 if (res != OK) {
590 ALOGE("%s: Camera %d: Unable to update common entries of capture "
591 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
592 strerror(-res), res);
593 return res;
594 }
595
596 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE,
597 params.jpegThumbSize, 2);
598 if (res != OK) return res;
599 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
600 &params.jpegThumbQuality, 1);
601 if (res != OK) return res;
602 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
603 &params.jpegQuality, 1);
604 if (res != OK) return res;
605 res = mCaptureRequest.update(
606 ANDROID_JPEG_ORIENTATION,
607 &params.jpegRotation, 1);
608 if (res != OK) return res;
609
610 if (params.gpsEnabled) {
611 res = mCaptureRequest.update(
612 ANDROID_JPEG_GPS_COORDINATES,
613 params.gpsCoordinates, 3);
614 if (res != OK) return res;
615 res = mCaptureRequest.update(
616 ANDROID_JPEG_GPS_TIMESTAMP,
617 &params.gpsTimestamp, 1);
618 if (res != OK) return res;
619 res = mCaptureRequest.update(
620 ANDROID_JPEG_GPS_PROCESSING_METHOD,
621 params.gpsProcessingMethod);
622 if (res != OK) return res;
623 } else {
624 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES);
625 if (res != OK) return res;
626 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP);
627 if (res != OK) return res;
628 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
629 if (res != OK) return res;
630 }
631
632 return OK;
633}
634
Igor Murashkin707c3e32012-09-20 15:18:50 -0700635/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
636 sp<Camera2Client> client) {
637 ATRACE_CALL();
638
639 if (params.state == Parameters::STILL_CAPTURE && params.playShutterSound) {
640 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
641 }
642
643 {
644 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
645
646 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
647 if (l.mCameraClient != 0) {
648 // ShutterCallback
649 l.mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER,
650 /*ext1*/0, /*ext2*/0);
651
652 // RawCallback with null buffer
653 l.mCameraClient->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
654 /*ext1*/0, /*ext2*/0);
655 } else {
656 ALOGV("%s: No client!", __FUNCTION__);
657 }
658 }
659}
660
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700661
662}; // namespace camera2
663}; // namespace android