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