StreamingProcessor.cpp revision 855c20283de5eab6798c76ffd4ea86bd6754a7fb
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 "Camera2-StreamingProcessor"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20//#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
27
28#include <cutils/properties.h>
29#include <utils/Log.h>
30#include <utils/Trace.h>
31#include <gui/BufferItem.h>
32#include <gui/Surface.h>
33#include <media/hardware/HardwareAPI.h>
34
35#include "common/CameraDeviceBase.h"
36#include "api1/Camera2Client.h"
37#include "api1/client2/StreamingProcessor.h"
38#include "api1/client2/Camera2Heap.h"
39
40namespace android {
41namespace camera2 {
42
43StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
44        mClient(client),
45        mDevice(client->getCameraDevice()),
46        mId(client->getCameraId()),
47        mActiveRequest(NONE),
48        mPaused(false),
49        mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
50        mPreviewStreamId(NO_STREAM),
51        mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
52        mRecordingStreamId(NO_STREAM)
53{
54}
55
56StreamingProcessor::~StreamingProcessor() {
57    deletePreviewStream();
58    deleteRecordingStream();
59}
60
61status_t StreamingProcessor::setPreviewWindow(sp<Surface> window) {
62    ATRACE_CALL();
63    status_t res;
64
65    res = deletePreviewStream();
66    if (res != OK) return res;
67
68    Mutex::Autolock m(mMutex);
69
70    mPreviewWindow = window;
71
72    return OK;
73}
74
75status_t StreamingProcessor::setRecordingWindow(sp<Surface> window) {
76    ATRACE_CALL();
77    status_t res;
78
79    res = deleteRecordingStream();
80    if (res != OK) return res;
81
82    Mutex::Autolock m(mMutex);
83
84    mRecordingWindow = window;
85
86    return OK;
87}
88
89bool StreamingProcessor::haveValidPreviewWindow() const {
90    Mutex::Autolock m(mMutex);
91    return mPreviewWindow != 0;
92}
93
94bool StreamingProcessor::haveValidRecordingWindow() const {
95    Mutex::Autolock m(mMutex);
96    return mRecordingWindow != nullptr;
97}
98
99status_t StreamingProcessor::updatePreviewRequest(const Parameters &params) {
100    ATRACE_CALL();
101    status_t res;
102    sp<CameraDeviceBase> device = mDevice.promote();
103    if (device == 0) {
104        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
105        return INVALID_OPERATION;
106    }
107
108    Mutex::Autolock m(mMutex);
109    if (mPreviewRequest.entryCount() == 0) {
110        sp<Camera2Client> client = mClient.promote();
111        if (client == 0) {
112            ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
113            return INVALID_OPERATION;
114        }
115
116        // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case.
117        if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
118            if (params.zslMode && !params.recordingHint) {
119                res = device->createDefaultRequest(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
120                        &mPreviewRequest);
121            } else {
122                res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW,
123                        &mPreviewRequest);
124            }
125        } else {
126            res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
127                    &mPreviewRequest);
128        }
129
130        if (res != OK) {
131            ALOGE("%s: Camera %d: Unable to create default preview request: "
132                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
133            return res;
134        }
135    }
136
137    res = params.updateRequest(&mPreviewRequest);
138    if (res != OK) {
139        ALOGE("%s: Camera %d: Unable to update common entries of preview "
140                "request: %s (%d)", __FUNCTION__, mId,
141                strerror(-res), res);
142        return res;
143    }
144
145    res = mPreviewRequest.update(ANDROID_REQUEST_ID,
146            &mPreviewRequestId, 1);
147    if (res != OK) {
148        ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)",
149                __FUNCTION__, mId, strerror(-res), res);
150        return res;
151    }
152
153    return OK;
154}
155
156status_t StreamingProcessor::updatePreviewStream(const Parameters &params) {
157    ATRACE_CALL();
158    Mutex::Autolock m(mMutex);
159
160    status_t res;
161    sp<CameraDeviceBase> device = mDevice.promote();
162    if (device == 0) {
163        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
164        return INVALID_OPERATION;
165    }
166
167    if (mPreviewStreamId != NO_STREAM) {
168        // Check if stream parameters have to change
169        uint32_t currentWidth, currentHeight;
170        res = device->getStreamInfo(mPreviewStreamId,
171                &currentWidth, &currentHeight, 0, 0);
172        if (res != OK) {
173            ALOGE("%s: Camera %d: Error querying preview stream info: "
174                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
175            return res;
176        }
177        if (currentWidth != (uint32_t)params.previewWidth ||
178                currentHeight != (uint32_t)params.previewHeight) {
179            ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
180                    __FUNCTION__, mId, currentWidth, currentHeight,
181                    params.previewWidth, params.previewHeight);
182            res = device->waitUntilDrained();
183            if (res != OK) {
184                ALOGE("%s: Camera %d: Error waiting for preview to drain: "
185                        "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
186                return res;
187            }
188            res = device->deleteStream(mPreviewStreamId);
189            if (res != OK) {
190                ALOGE("%s: Camera %d: Unable to delete old output stream "
191                        "for preview: %s (%d)", __FUNCTION__, mId,
192                        strerror(-res), res);
193                return res;
194            }
195            mPreviewStreamId = NO_STREAM;
196        }
197    }
198
199    if (mPreviewStreamId == NO_STREAM) {
200        res = device->createStream(mPreviewWindow,
201                params.previewWidth, params.previewHeight,
202                CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN,
203                CAMERA3_STREAM_ROTATION_0, &mPreviewStreamId);
204        if (res != OK) {
205            ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
206                    __FUNCTION__, mId, strerror(-res), res);
207            return res;
208        }
209    }
210
211    res = device->setStreamTransform(mPreviewStreamId,
212            params.previewTransform);
213    if (res != OK) {
214        ALOGE("%s: Camera %d: Unable to set preview stream transform: "
215                "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
216        return res;
217    }
218
219    return OK;
220}
221
222status_t StreamingProcessor::deletePreviewStream() {
223    ATRACE_CALL();
224    status_t res;
225
226    Mutex::Autolock m(mMutex);
227
228    if (mPreviewStreamId != NO_STREAM) {
229        sp<CameraDeviceBase> device = mDevice.promote();
230        if (device == 0) {
231            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
232            return INVALID_OPERATION;
233        }
234
235        ALOGV("%s: for cameraId %d on streamId %d",
236            __FUNCTION__, mId, mPreviewStreamId);
237
238        res = device->waitUntilDrained();
239        if (res != OK) {
240            ALOGE("%s: Error waiting for preview to drain: %s (%d)",
241                    __FUNCTION__, strerror(-res), res);
242            return res;
243        }
244        res = device->deleteStream(mPreviewStreamId);
245        if (res != OK) {
246            ALOGE("%s: Unable to delete old preview stream: %s (%d)",
247                    __FUNCTION__, strerror(-res), res);
248            return res;
249        }
250        mPreviewStreamId = NO_STREAM;
251    }
252    return OK;
253}
254
255int StreamingProcessor::getPreviewStreamId() const {
256    Mutex::Autolock m(mMutex);
257    return mPreviewStreamId;
258}
259
260status_t StreamingProcessor::updateRecordingRequest(const Parameters &params) {
261    ATRACE_CALL();
262    status_t res;
263    Mutex::Autolock m(mMutex);
264
265    sp<CameraDeviceBase> device = mDevice.promote();
266    if (device == 0) {
267        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
268        return INVALID_OPERATION;
269    }
270
271    if (mRecordingRequest.entryCount() == 0) {
272        res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
273                &mRecordingRequest);
274        if (res != OK) {
275            ALOGE("%s: Camera %d: Unable to create default recording request:"
276                    " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
277            return res;
278        }
279    }
280
281    res = params.updateRequest(&mRecordingRequest);
282    if (res != OK) {
283        ALOGE("%s: Camera %d: Unable to update common entries of recording "
284                "request: %s (%d)", __FUNCTION__, mId,
285                strerror(-res), res);
286        return res;
287    }
288
289    res = mRecordingRequest.update(ANDROID_REQUEST_ID,
290            &mRecordingRequestId, 1);
291    if (res != OK) {
292        ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)",
293                __FUNCTION__, mId, strerror(-res), res);
294        return res;
295    }
296
297    return OK;
298}
299
300status_t StreamingProcessor::recordingStreamNeedsUpdate(
301        const Parameters &params, bool *needsUpdate) {
302    status_t res;
303
304    if (needsUpdate == 0) {
305        ALOGE("%s: Camera %d: invalid argument", __FUNCTION__, mId);
306        return INVALID_OPERATION;
307    }
308
309    if (mRecordingStreamId == NO_STREAM) {
310        *needsUpdate = true;
311        return OK;
312    }
313
314    sp<CameraDeviceBase> device = mDevice.promote();
315    if (device == 0) {
316        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
317        return INVALID_OPERATION;
318    }
319
320    uint32_t currentWidth, currentHeight, currentFormat;
321    android_dataspace currentDataSpace;
322    res = device->getStreamInfo(mRecordingStreamId,
323            &currentWidth, &currentHeight, &currentFormat, &currentDataSpace);
324    if (res != OK) {
325        ALOGE("%s: Camera %d: Error querying recording output stream info: "
326                "%s (%d)", __FUNCTION__, mId,
327                strerror(-res), res);
328        return res;
329    }
330
331    if (mRecordingWindow == nullptr ||
332            currentWidth != (uint32_t)params.videoWidth ||
333            currentHeight != (uint32_t)params.videoHeight ||
334            currentFormat != (uint32_t)params.videoFormat ||
335            currentDataSpace != params.videoDataSpace) {
336        *needsUpdate = true;
337        return res;
338    }
339    *needsUpdate = false;
340    return res;
341}
342
343status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
344    ATRACE_CALL();
345    status_t res;
346    Mutex::Autolock m(mMutex);
347
348    sp<CameraDeviceBase> device = mDevice.promote();
349    if (device == 0) {
350        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
351        return INVALID_OPERATION;
352    }
353
354    if (mRecordingStreamId != NO_STREAM) {
355        // Check if stream parameters have to change
356        uint32_t currentWidth, currentHeight;
357        uint32_t currentFormat;
358        android_dataspace currentDataSpace;
359        res = device->getStreamInfo(mRecordingStreamId,
360                &currentWidth, &currentHeight,
361                &currentFormat, &currentDataSpace);
362        if (res != OK) {
363            ALOGE("%s: Camera %d: Error querying recording output stream info: "
364                    "%s (%d)", __FUNCTION__, mId,
365                    strerror(-res), res);
366            return res;
367        }
368        if (currentWidth != (uint32_t)params.videoWidth ||
369                currentHeight != (uint32_t)params.videoHeight ||
370                currentFormat != (uint32_t)params.videoFormat ||
371                currentDataSpace != params.videoDataSpace) {
372            // TODO: Should wait to be sure previous recording has finished
373            res = device->deleteStream(mRecordingStreamId);
374
375            if (res == -EBUSY) {
376                ALOGV("%s: Camera %d: Device is busy, call "
377                      "updateRecordingStream after it becomes idle",
378                      __FUNCTION__, mId);
379                return res;
380            } else if (res != OK) {
381                ALOGE("%s: Camera %d: Unable to delete old output stream "
382                        "for recording: %s (%d)", __FUNCTION__,
383                        mId, strerror(-res), res);
384                return res;
385            }
386            mRecordingStreamId = NO_STREAM;
387        }
388    }
389
390    if (mRecordingStreamId == NO_STREAM) {
391        res = device->createStream(mRecordingWindow,
392                params.videoWidth, params.videoHeight,
393                params.videoFormat, params.videoDataSpace,
394                CAMERA3_STREAM_ROTATION_0, &mRecordingStreamId);
395        if (res != OK) {
396            ALOGE("%s: Camera %d: Can't create output stream for recording: "
397                    "%s (%d)", __FUNCTION__, mId,
398                    strerror(-res), res);
399            return res;
400        }
401    }
402
403    return OK;
404}
405
406status_t StreamingProcessor::deleteRecordingStream() {
407    ATRACE_CALL();
408    status_t res;
409
410    Mutex::Autolock m(mMutex);
411
412    if (mRecordingStreamId != NO_STREAM) {
413        sp<CameraDeviceBase> device = mDevice.promote();
414        if (device == 0) {
415            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
416            return INVALID_OPERATION;
417        }
418
419        res = device->waitUntilDrained();
420        if (res != OK) {
421            ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
422                    __FUNCTION__, strerror(-res), res);
423            return res;
424        }
425        res = device->deleteStream(mRecordingStreamId);
426        if (res != OK) {
427            ALOGE("%s: Unable to delete recording stream: %s (%d)",
428                    __FUNCTION__, strerror(-res), res);
429            return res;
430        }
431        mRecordingStreamId = NO_STREAM;
432    }
433    return OK;
434}
435
436int StreamingProcessor::getRecordingStreamId() const {
437    return mRecordingStreamId;
438}
439
440status_t StreamingProcessor::startStream(StreamType type,
441        const Vector<int32_t> &outputStreams) {
442    ATRACE_CALL();
443    status_t res;
444
445    if (type == NONE) return INVALID_OPERATION;
446
447    sp<CameraDeviceBase> device = mDevice.promote();
448    if (device == 0) {
449        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
450        return INVALID_OPERATION;
451    }
452
453    ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type);
454
455    Mutex::Autolock m(mMutex);
456
457    CameraMetadata &request = (type == PREVIEW) ?
458            mPreviewRequest : mRecordingRequest;
459
460    res = request.update(
461        ANDROID_REQUEST_OUTPUT_STREAMS,
462        outputStreams);
463    if (res != OK) {
464        ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
465                __FUNCTION__, mId, strerror(-res), res);
466        return res;
467    }
468
469    res = request.sort();
470    if (res != OK) {
471        ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
472                __FUNCTION__, mId, strerror(-res), res);
473        return res;
474    }
475
476    res = device->setStreamingRequest(request);
477    if (res != OK) {
478        ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
479                "%s (%d)",
480                __FUNCTION__, mId, strerror(-res), res);
481        return res;
482    }
483    mActiveRequest = type;
484    mPaused = false;
485    mActiveStreamIds = outputStreams;
486    return OK;
487}
488
489status_t StreamingProcessor::togglePauseStream(bool pause) {
490    ATRACE_CALL();
491    status_t res;
492
493    sp<CameraDeviceBase> device = mDevice.promote();
494    if (device == 0) {
495        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
496        return INVALID_OPERATION;
497    }
498
499    ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause);
500
501    Mutex::Autolock m(mMutex);
502
503    if (mActiveRequest == NONE) {
504        ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started",
505              __FUNCTION__, mId);
506        return INVALID_OPERATION;
507    }
508
509    if (mPaused == pause) {
510        return OK;
511    }
512
513    if (pause) {
514        res = device->clearStreamingRequest();
515        if (res != OK) {
516            ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
517                    __FUNCTION__, mId, strerror(-res), res);
518            return res;
519        }
520    } else {
521        CameraMetadata &request =
522                (mActiveRequest == PREVIEW) ? mPreviewRequest
523                                            : mRecordingRequest;
524        res = device->setStreamingRequest(request);
525        if (res != OK) {
526            ALOGE("%s: Camera %d: Unable to set preview request to resume: "
527                    "%s (%d)",
528                    __FUNCTION__, mId, strerror(-res), res);
529            return res;
530        }
531    }
532
533    mPaused = pause;
534    return OK;
535}
536
537status_t StreamingProcessor::stopStream() {
538    ATRACE_CALL();
539    status_t res;
540
541    Mutex::Autolock m(mMutex);
542
543    sp<CameraDeviceBase> device = mDevice.promote();
544    if (device == 0) {
545        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
546        return INVALID_OPERATION;
547    }
548
549    res = device->clearStreamingRequest();
550    if (res != OK) {
551        ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
552                __FUNCTION__, mId, strerror(-res), res);
553        return res;
554    }
555
556    mActiveRequest = NONE;
557    mActiveStreamIds.clear();
558    mPaused = false;
559
560    return OK;
561}
562
563int32_t StreamingProcessor::getActiveRequestId() const {
564    Mutex::Autolock m(mMutex);
565    switch (mActiveRequest) {
566        case NONE:
567            return 0;
568        case PREVIEW:
569            return mPreviewRequestId;
570        case RECORD:
571            return mRecordingRequestId;
572        default:
573            ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest);
574            return 0;
575    }
576}
577
578status_t StreamingProcessor::incrementStreamingIds() {
579    ATRACE_CALL();
580    Mutex::Autolock m(mMutex);
581
582    mPreviewRequestId++;
583    if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
584        mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
585    }
586    mRecordingRequestId++;
587    if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) {
588        mRecordingRequestId = Camera2Client::kRecordingRequestIdStart;
589    }
590    return OK;
591}
592
593status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
594    String8 result;
595
596    result.append("  Current requests:\n");
597    if (mPreviewRequest.entryCount() != 0) {
598        result.append("    Preview request:\n");
599        write(fd, result.string(), result.size());
600        mPreviewRequest.dump(fd, 2, 6);
601        result.clear();
602    } else {
603        result.append("    Preview request: undefined\n");
604    }
605
606    if (mRecordingRequest.entryCount() != 0) {
607        result = "    Recording request:\n";
608        write(fd, result.string(), result.size());
609        mRecordingRequest.dump(fd, 2, 6);
610        result.clear();
611    } else {
612        result = "    Recording request: undefined\n";
613    }
614
615    const char* streamTypeString[] = {
616        "none", "preview", "record"
617    };
618    result.append(String8::format("   Active request: %s (paused: %s)\n",
619                                  streamTypeString[mActiveRequest],
620                                  mPaused ? "yes" : "no"));
621
622    write(fd, result.string(), result.size());
623
624    return OK;
625}
626
627}; // namespace camera2
628}; // namespace android
629