CaptureSequencer.cpp revision 6b367f2a2bddfed60d63fa4da5e19ca13352a454
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        sp<MemoryBase> captureBuffer) {
101    ATRACE_CALL();
102    ALOGV("%s", __FUNCTION__);
103    Mutex::Autolock l(mInputMutex);
104    mCaptureTimestamp = timestamp;
105    mCaptureBuffer = captureBuffer;
106    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",
142    "BURST_CAPTURE_START",
143    "BURST_CAPTURE_WAIT",
144    "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,
160    &CaptureSequencer::manageBurstCaptureStart,
161    &CaptureSequencer::manageBurstCaptureWait,
162    &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) {
200    status_t res = OK;
201    ATRACE_CALL();
202    mCaptureId++;
203
204    {
205        Mutex::Autolock l(mInputMutex);
206        mBusy = false;
207    }
208
209    {
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        }
225    }
226    sp<ZslProcessor> processor = mZslProcessor.promote();
227    if (processor != 0) {
228        processor->clearZslQueue();
229    }
230
231    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();
242
243    return IDLE;
244}
245
246CaptureSequencer::CaptureState CaptureSequencer::manageStart(
247        sp<Camera2Client> &client) {
248    ALOGV("%s", __FUNCTION__);
249    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
261    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 &&
266            l.mParameters.state == Parameters::STILL_CAPTURE &&
267            l.mParameters.flashMode != Parameters::FLASH_MODE_ON) {
268        nextState = ZSL_START;
269    } else {
270        nextState = STANDARD_START;
271    }
272
273    return nextState;
274}
275
276CaptureSequencer::CaptureState CaptureSequencer::manageZslStart(
277        sp<Camera2Client> &client) {
278    ALOGV("%s", __FUNCTION__);
279    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.
297    res = processor->pushToReprocess(mCaptureId);
298    if (res != OK) {
299        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        }
307        return STANDARD_START;
308    }
309
310    SharedParameters::Lock l(client->getParameters());
311    if (l.mParameters.playShutterSound) {
312        client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
313    }
314
315    mTimeoutCount = kMaxTimeoutsForCaptureEnd;
316    return STANDARD_CAPTURE_WAIT;
317}
318
319CaptureSequencer::CaptureState CaptureSequencer::manageZslWaiting(
320        sp<Camera2Client> &client) {
321    ALOGV("%s", __FUNCTION__);
322    return DONE;
323}
324
325CaptureSequencer::CaptureState CaptureSequencer::manageZslReprocessing(
326        sp<Camera2Client> &client) {
327    ALOGV("%s", __FUNCTION__);
328    return START;
329}
330
331CaptureSequencer::CaptureState CaptureSequencer::manageStandardStart(
332        sp<Camera2Client> &client) {
333    ATRACE_CALL();
334    client->registerFrameListener(mCaptureId,
335            this);
336    {
337        SharedParameters::Lock l(client->getParameters());
338        mTriggerId = l.mParameters.precaptureTriggerCounter++;
339    }
340    client->getCameraDevice()->triggerPrecaptureMetering(mTriggerId);
341
342    mAeInPrecapture = false;
343    mTimeoutCount = kMaxTimeoutsForPrecaptureStart;
344    return STANDARD_PRECAPTURE_WAIT;
345}
346
347CaptureSequencer::CaptureState CaptureSequencer::manageStandardPrecaptureWait(
348        sp<Camera2Client> &client) {
349    status_t res;
350    ATRACE_CALL();
351    Mutex::Autolock l(mInputMutex);
352    while (!mNewAEState) {
353        res = mNewNotifySignal.waitRelative(mInputMutex, kWaitDuration);
354        if (res == TIMED_OUT) {
355            mTimeoutCount--;
356            break;
357        }
358    }
359    if (mTimeoutCount <= 0) {
360        ALOGW("Timed out waiting for precapture %s",
361                mAeInPrecapture ? "end" : "start");
362        return STANDARD_CAPTURE;
363    }
364    if (mNewAEState) {
365        if (!mAeInPrecapture) {
366            // Waiting to see PRECAPTURE state
367            if (mAETriggerId == mTriggerId &&
368                    mAEState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
369                ALOGV("%s: Got precapture start", __FUNCTION__);
370                mAeInPrecapture = true;
371                mTimeoutCount = kMaxTimeoutsForPrecaptureEnd;
372            }
373        } else {
374            // Waiting to see PRECAPTURE state end
375            if (mAETriggerId == mTriggerId &&
376                    mAEState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) {
377                ALOGV("%s: Got precapture end", __FUNCTION__);
378                return STANDARD_CAPTURE;
379            }
380        }
381        mNewAEState = false;
382    }
383    return STANDARD_PRECAPTURE_WAIT;
384}
385
386CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture(
387        sp<Camera2Client> &client) {
388    status_t res;
389    ATRACE_CALL();
390    SharedParameters::Lock l(client->getParameters());
391    Vector<uint8_t> outputStreams;
392
393    outputStreams.push(client->getPreviewStreamId());
394    outputStreams.push(client->getCaptureStreamId());
395
396    if (l.mParameters.previewCallbackFlags &
397            CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
398        outputStreams.push(client->getCallbackStreamId());
399    }
400
401    if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
402        outputStreams.push(client->getRecordingStreamId());
403    }
404
405    res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
406            outputStreams);
407    if (res == OK) {
408        res = mCaptureRequest.update(ANDROID_REQUEST_ID,
409                &mCaptureId, 1);
410    }
411    if (res == OK) {
412        res = mCaptureRequest.sort();
413    }
414
415    if (res != OK) {
416        ALOGE("%s: Camera %d: Unable to set up still capture request: %s (%d)",
417                __FUNCTION__, client->getCameraId(), strerror(-res), res);
418        return DONE;
419    }
420
421    CameraMetadata captureCopy = mCaptureRequest;
422    if (captureCopy.entryCount() == 0) {
423        ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
424                __FUNCTION__, client->getCameraId());
425        return DONE;
426    }
427
428    if (l.mParameters.state == Parameters::STILL_CAPTURE) {
429        res = client->getCameraDevice()->clearStreamingRequest();
430        if (res != OK) {
431            ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
432                    "%s (%d)",
433                    __FUNCTION__, client->getCameraId(), strerror(-res), res);
434            return DONE;
435        }
436    }
437    // TODO: Capture should be atomic with setStreamingRequest here
438    res = client->getCameraDevice()->capture(captureCopy);
439    if (res != OK) {
440        ALOGE("%s: Camera %d: Unable to submit still image capture request: "
441                "%s (%d)",
442                __FUNCTION__, client->getCameraId(), strerror(-res), res);
443        return DONE;
444    }
445
446    if (l.mParameters.playShutterSound &&
447            l.mParameters.state == Parameters::STILL_CAPTURE) {
448        client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
449    }
450
451    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
501CaptureSequencer::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
572status_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
635
636}; // namespace camera2
637}; // namespace android
638