blob: 6d7c54fb205b52db86242fb0e627eacad7be41bb [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
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"
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) {
172 mCaptureState = (this->*kStateManagers[mCaptureState])(client);
173 } else {
174 ALOGE("%s: Bad capture state: %s",
175 __FUNCTION__, kStateNames[mCaptureState]);
176 return false;
177 }
178
179 return true;
180}
181
182CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &client) {
183 status_t res;
184 ATRACE_CALL();
185 Mutex::Autolock l(mInputMutex);
186 while (!mStartCapture) {
187 res = mStartCaptureSignal.waitRelative(mInputMutex,
188 kWaitDuration);
189 if (res == TIMED_OUT) break;
190 }
191 if (mStartCapture) {
192 mStartCapture = false;
193 mBusy = true;
194 return START;
195 }
196 return IDLE;
197}
198
199CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700200 status_t res = OK;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700201 ATRACE_CALL();
202 mCaptureId++;
203
204 {
205 Mutex::Autolock l(mInputMutex);
206 mBusy = false;
207 }
208
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700209 {
210 SharedParameters::Lock l(client->getParameters());
211 switch (l.mParameters.state) {
212 case Parameters::STILL_CAPTURE:
213 l.mParameters.state = Parameters::STOPPED;
214 break;
215 case Parameters::VIDEO_SNAPSHOT:
216 l.mParameters.state = Parameters::RECORD;
217 break;
218 default:
219 ALOGE("%s: Camera %d: Still image produced unexpectedly "
220 "in state %s!",
221 __FUNCTION__, client->getCameraId(),
222 Parameters::getStateName(l.mParameters.state));
223 res = INVALID_OPERATION;
224 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700225 }
Eino-Ville Talvala5a8fed02012-09-19 17:11:04 -0700226 sp<ZslProcessor> processor = mZslProcessor.promote();
227 if (processor != 0) {
228 processor->clearZslQueue();
229 }
230
Eino-Ville Talvala52e9ad42012-09-19 17:09:15 -0700231 if (mCaptureBuffer != 0 && res == OK) {
232 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
233 ALOGV("%s: Sending still image to client", __FUNCTION__);
234 if (l.mCameraClient != 0) {
235 l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
236 mCaptureBuffer, NULL);
237 } else {
238 ALOGV("%s: No client!", __FUNCTION__);
239 }
240 }
241 mCaptureBuffer.clear();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700242
243 return IDLE;
244}
245
246CaptureSequencer::CaptureState CaptureSequencer::manageStart(
247 sp<Camera2Client> &client) {
James Painterc3dbf1a2012-09-05 18:02:32 -0700248 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700249 status_t res;
250 ATRACE_CALL();
251 SharedParameters::Lock l(client->getParameters());
252 CaptureState nextState = DONE;
253
254 res = updateCaptureRequest(l.mParameters, client);
255 if (res != OK ) {
256 ALOGE("%s: Camera %d: Can't update still image capture request: %s (%d)",
257 __FUNCTION__, client->getCameraId(), strerror(-res), res);
258 return DONE;
259 }
260
James Painterc3dbf1a2012-09-05 18:02:32 -0700261 if(l.mParameters.lightFx != Parameters::LIGHTFX_NONE &&
262 l.mParameters.state == Parameters::STILL_CAPTURE) {
263 nextState = BURST_CAPTURE_START;
264 }
265 else if (l.mParameters.zslMode &&
Eino-Ville Talvala5a07a622012-09-21 16:30:42 -0700266 l.mParameters.state == Parameters::STILL_CAPTURE &&
267 l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700268 nextState = ZSL_START;
269 } else {
270 nextState = STANDARD_START;
271 }
272
273 return nextState;
274}
275
276CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
277 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700278 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700279 status_t res;
280 sp<ZslProcessor> processor = mZslProcessor.promote();
281 if (processor == 0) {
282 ALOGE("%s: No ZSL queue to use!", __FUNCTION__);
283 return DONE;
284 }
285
286 client->registerFrameListener(mCaptureId,
287 this);
288
289 res = client->getCameraDevice()->clearStreamingRequest();
290 if (res != OK) {
291 ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
292 "%s (%d)",
293 __FUNCTION__, client->getCameraId(), strerror(-res), res);
294 return DONE;
295 }
296 // TODO: Actually select the right thing here.
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700297 res = processor->pushToReprocess(mCaptureId);
298 if (res != OK) {
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700299 if (res == NOT_ENOUGH_DATA) {
300 ALOGV("%s: Camera %d: ZSL queue doesn't have good frame, "
301 "falling back to normal capture", __FUNCTION__,
302 client->getCameraId());
303 } else {
304 ALOGE("%s: Camera %d: Error in ZSL queue: %s (%d)",
305 __FUNCTION__, client->getCameraId(), strerror(-res), res);
306 }
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700307 return STANDARD_START;
308 }
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700309
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700310 SharedParameters::Lock l(client->getParameters());
Igor Murashkin707c3e32012-09-20 15:18:50 -0700311 /* warning: this also locks a SharedCameraClient */
312 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvalaa4247b82012-09-19 17:12:50 -0700313
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700314 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
315 return STANDARD_CAPTURE_WAIT;
316}
317
318CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
319 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700320 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700321 return DONE;
322}
323
324CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
325 sp<Camera2Client> &client) {
Eino-Ville Talvala2954fe92012-09-12 10:42:10 -0700326 ALOGV("%s", __FUNCTION__);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700327 return START;
328}
329
330CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
331 sp<Camera2Client> &client) {
332 ATRACE_CALL();
333 client->registerFrameListener(mCaptureId,
334 this);
335 {
336 SharedParameters::Lock l(client->getParameters());
337 mTriggerId = l.mParameters.precaptureTriggerCounter++;
338 }
339 client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
340
341 mAeInPrecapture = false;
342 mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
343 return STANDARD_PRECAPTURE_WAIT;
344}
345
346CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
347 sp<Camera2Client> &client) {
348 status_t res;
349 ATRACE_CALL();
350 Mutex::Autolock l(mInputMutex);
351 while (!mNewAEState) {
352 res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
353 if (res == TIMED_OUT) {
354 mTimeoutCount--;
355 break;
356 }
357 }
358 if (mTimeoutCount <= 0) {
359 ALOGW("Timed out waiting for precapture %s",
360 mAeInPrecapture ? "end" : "start");
361 return STANDARD_CAPTURE;
362 }
363 if (mNewAEState) {
364 if (!mAeInPrecapture) {
365 // Waiting to see PRECAPTURE state
366 if (mAETriggerId == mTriggerId &&
367 mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
368 ALOGV("%s: Got precapture start", __FUNCTION__);
369 mAeInPrecapture = true;
370 mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
371 }
372 } else {
373 // Waiting to see PRECAPTURE state end
374 if (mAETriggerId == mTriggerId &&
375 mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
376 ALOGV("%s: Got precapture end", __FUNCTION__);
377 return STANDARD_CAPTURE;
378 }
379 }
380 mNewAEState = false;
381 }
382 return STANDARD_PRECAPTURE_WAIT;
383}
384
385CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
386 sp<Camera2Client> &client) {
387 status_t res;
388 ATRACE_CALL();
389 SharedParameters::Lock l(client->getParameters());
390 Vector<uint8_t> outputStreams;
391
392 outputStreams.push(client->getPreviewStreamId());
393 outputStreams.push(client->getCaptureStreamId());
394
395 if (l.mParameters.previewCallbackFlags &
396 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
397 outputStreams.push(client->getCallbackStreamId());
398 }
399
400 if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
401 outputStreams.push(client->getRecordingStreamId());
402 }
403
404 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
405 outputStreams);
406 if (res == OK) {
407 res = mCaptureRequest.update(ANDROID_REQUEST_ID,
408 &mCaptureId, 1);
409 }
410 if (res == OK) {
411 res = mCaptureRequest.sort();
412 }
413
414 if (res != OK) {
415 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
416 __FUNCTION__, client->getCameraId(), strerror(-res), res);
417 return DONE;
418 }
419
420 CameraMetadata captureCopy = mCaptureRequest;
421 if (captureCopy.entryCount() == 0) {
422 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
423 __FUNCTION__, client->getCameraId());
424 return DONE;
425 }
426
427 if (l.mParameters.state == Parameters::STILL_CAPTURE) {
428 res = client->getCameraDevice()->clearStreamingRequest();
429 if (res != OK) {
430 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
431 "%s (%d)",
432 __FUNCTION__, client->getCameraId(), strerror(-res), res);
433 return DONE;
434 }
435 }
436 // TODO: Capture should be atomic with setStreamingRequest here
437 res = client->getCameraDevice()->capture(captureCopy);
438 if (res != OK) {
439 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
440 "%s (%d)",
441 __FUNCTION__, client->getCameraId(), strerror(-res), res);
442 return DONE;
443 }
444
Igor Murashkin707c3e32012-09-20 15:18:50 -0700445 /* warning: this also locks a SharedCameraClient */
446 shutterNotifyLocked(l.mParameters, client);
Eino-Ville Talvala33578832012-09-06 18:26:58 -0700447
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700448 mTimeoutCount = kMaxTimeoutsForCaptureEnd;
449 return STANDARD_CAPTURE_WAIT;
450}
451
452CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
453 sp<Camera2Client> &client) {
454 status_t res;
455 ATRACE_CALL();
456 Mutex::Autolock l(mInputMutex);
457 while (!mNewFrameReceived) {
458 res = mNewFrameSignal.waitRelative(mInputMutex, kWaitDuration);
459 if (res == TIMED_OUT) {
460 mTimeoutCount--;
461 break;
462 }
463 }
464 while (!mNewCaptureReceived) {
465 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
466 if (res == TIMED_OUT) {
467 mTimeoutCount--;
468 break;
469 }
470 }
471 if (mTimeoutCount <= 0) {
472 ALOGW("Timed out waiting for capture to complete");
473 return DONE;
474 }
475 if (mNewFrameReceived && mNewCaptureReceived) {
476 if (mNewFrameId != mCaptureId) {
477 ALOGW("Mismatched capture frame IDs: Expected %d, got %d",
478 mCaptureId, mNewFrameId);
479 }
480 camera_metadata_entry_t entry;
481 entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
482 if (entry.count == 0) {
483 ALOGE("No timestamp field in capture frame!");
484 }
485 if (entry.data.i64[0] != mCaptureTimestamp) {
486 ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
487 " captured buffer %lld", entry.data.i64[0], mCaptureTimestamp);
488 }
489 client->removeFrameListener(mCaptureId);
490
491 mNewFrameReceived = false;
492 mNewCaptureReceived = false;
493 return DONE;
494 }
495 return STANDARD_CAPTURE_WAIT;
496}
497
James Painterc3dbf1a2012-09-05 18:02:32 -0700498CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureStart(
499 sp<Camera2Client> &client) {
500 ALOGV("%s", __FUNCTION__);
501 status_t res;
502 ATRACE_CALL();
503
504 // check which burst mode is set, create respective burst object
505 {
506 SharedParameters::Lock l(client->getParameters());
507
508 res = updateCaptureRequest(l.mParameters, client);
509 if(res != OK) {
510 return DONE;
511 }
512
513 //
514 // check for burst mode type in mParameters here
515 //
516 mBurstCapture = new BurstCapture(client, this);
517 }
518
519 res = mCaptureRequest.update(ANDROID_REQUEST_ID, &mCaptureId, 1);
520 if (res == OK) {
521 res = mCaptureRequest.sort();
522 }
523 if (res != OK) {
524 ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
525 __FUNCTION__, client->getCameraId(), strerror(-res), res);
526 return DONE;
527 }
528
529 CameraMetadata captureCopy = mCaptureRequest;
530 if (captureCopy.entryCount() == 0) {
531 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
532 __FUNCTION__, client->getCameraId());
533 return DONE;
534 }
535
536 Vector<CameraMetadata> requests;
537 requests.push(mCaptureRequest);
538 res = mBurstCapture->start(requests, mCaptureId);
539 mTimeoutCount = kMaxTimeoutsForCaptureEnd * 10;
540 return BURST_CAPTURE_WAIT;
541}
542
543CaptureSequencer::CaptureState CaptureSequencer::manageBurstCaptureWait(
544 sp<Camera2Client> &client) {
545 status_t res;
546 ATRACE_CALL();
547
548 while (!mNewCaptureReceived) {
549 res = mNewCaptureSignal.waitRelative(mInputMutex, kWaitDuration);
550 if (res == TIMED_OUT) {
551 mTimeoutCount--;
552 break;
553 }
554 }
555
556 if (mTimeoutCount <= 0) {
557 ALOGW("Timed out waiting for burst capture to complete");
558 return DONE;
559 }
560 if (mNewCaptureReceived) {
561 mNewCaptureReceived = false;
562 // TODO: update mCaptureId to last burst's capture ID + 1?
563 return DONE;
564 }
565
566 return BURST_CAPTURE_WAIT;
567}
568
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700569status_t CaptureSequencer::updateCaptureRequest(const Parameters &params,
570 sp<Camera2Client> &client) {
571 ATRACE_CALL();
572 status_t res;
573 if (mCaptureRequest.entryCount() == 0) {
574 res = client->getCameraDevice()->createDefaultRequest(
575 CAMERA2_TEMPLATE_STILL_CAPTURE,
576 &mCaptureRequest);
577 if (res != OK) {
578 ALOGE("%s: Camera %d: Unable to create default still image request:"
579 " %s (%d)", __FUNCTION__, client->getCameraId(),
580 strerror(-res), res);
581 return res;
582 }
583 }
584
585 res = params.updateRequest(&mCaptureRequest);
586 if (res != OK) {
587 ALOGE("%s: Camera %d: Unable to update common entries of capture "
588 "request: %s (%d)", __FUNCTION__, client->getCameraId(),
589 strerror(-res), res);
590 return res;
591 }
592
593 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE,
594 params.jpegThumbSize, 2);
595 if (res != OK) return res;
596 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
597 &params.jpegThumbQuality, 1);
598 if (res != OK) return res;
599 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
600 &params.jpegQuality, 1);
601 if (res != OK) return res;
602 res = mCaptureRequest.update(
603 ANDROID_JPEG_ORIENTATION,
604 &params.jpegRotation, 1);
605 if (res != OK) return res;
606
607 if (params.gpsEnabled) {
608 res = mCaptureRequest.update(
609 ANDROID_JPEG_GPS_COORDINATES,
610 params.gpsCoordinates, 3);
611 if (res != OK) return res;
612 res = mCaptureRequest.update(
613 ANDROID_JPEG_GPS_TIMESTAMP,
614 &params.gpsTimestamp, 1);
615 if (res != OK) return res;
616 res = mCaptureRequest.update(
617 ANDROID_JPEG_GPS_PROCESSING_METHOD,
618 params.gpsProcessingMethod);
619 if (res != OK) return res;
620 } else {
621 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES);
622 if (res != OK) return res;
623 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP);
624 if (res != OK) return res;
625 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
626 if (res != OK) return res;
627 }
628
629 return OK;
630}
631
Igor Murashkin707c3e32012-09-20 15:18:50 -0700632/*static*/ void CaptureSequencer::shutterNotifyLocked(const Parameters &params,
633 sp<Camera2Client> client) {
634 ATRACE_CALL();
635
636 if (params.state == Parameters::STILL_CAPTURE && params.playShutterSound) {
637 client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
638 }
639
640 {
641 Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
642
643 ALOGV("%s: Notifying of shutter close to client", __FUNCTION__);
644 if (l.mCameraClient != 0) {
645 // ShutterCallback
646 l.mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER,
647 /*ext1*/0, /*ext2*/0);
648
649 // RawCallback with null buffer
650 l.mCameraClient->notifyCallback(CAMERA_MSG_RAW_IMAGE_NOTIFY,
651 /*ext1*/0, /*ext2*/0);
652 } else {
653 ALOGV("%s: No client!", __FUNCTION__);
654 }
655 }
656}
657
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700658
659}; // namespace camera2
660}; // namespace android