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