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 &params,
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            &params.jpegThumbQuality, 1);
559    if (res != OK) return res;
560    res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
561            &params.jpegQuality, 1);
562    if (res != OK) return res;
563    res = mCaptureRequest.update(
564            ANDROID_JPEG_ORIENTATION,
565            &params.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                &params.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