StreamingProcessor.cpp revision 8cca0750a84c2d97224c0cfef7cf255308ee80b3
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    }
338    *needsUpdate = false;
339    return res;
340}
341
342status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
343    ATRACE_CALL();
344    status_t res;
345    Mutex::Autolock m(mMutex);
346
347    sp<CameraDeviceBase> device = mDevice.promote();
348    if (device == 0) {
349        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
350        return INVALID_OPERATION;
351    }
352
353    if (mRecordingStreamId != NO_STREAM) {
354        // Check if stream parameters have to change
355        uint32_t currentWidth, currentHeight;
356        uint32_t currentFormat;
357        android_dataspace currentDataSpace;
358        res = device->getStreamInfo(mRecordingStreamId,
359                &currentWidth, &currentHeight,
360                &currentFormat, &currentDataSpace);
361        if (res != OK) {
362            ALOGE("%s: Camera %d: Error querying recording output stream info: "
363                    "%s (%d)", __FUNCTION__, mId,
364                    strerror(-res), res);
365            return res;
366        }
367        if (currentWidth != (uint32_t)params.videoWidth ||
368                currentHeight != (uint32_t)params.videoHeight ||
369                currentFormat != (uint32_t)params.videoFormat ||
370                currentDataSpace != params.videoDataSpace) {
371            // TODO: Should wait to be sure previous recording has finished
372            res = device->deleteStream(mRecordingStreamId);
373
374            if (res == -EBUSY) {
375                ALOGV("%s: Camera %d: Device is busy, call "
376                      "updateRecordingStream after it becomes idle",
377                      __FUNCTION__, mId);
378                return res;
379            } else if (res != OK) {
380                ALOGE("%s: Camera %d: Unable to delete old output stream "
381                        "for recording: %s (%d)", __FUNCTION__,
382                        mId, strerror(-res), res);
383                return res;
384            }
385            mRecordingStreamId = NO_STREAM;
386        }
387    }
388
389    if (mRecordingStreamId == NO_STREAM) {
390        res = device->createStream(mRecordingWindow,
391                params.videoWidth, params.videoHeight,
392                params.videoFormat, params.videoDataSpace,
393                CAMERA3_STREAM_ROTATION_0, &mRecordingStreamId);
394        if (res != OK) {
395            ALOGE("%s: Camera %d: Can't create output stream for recording: "
396                    "%s (%d)", __FUNCTION__, mId,
397                    strerror(-res), res);
398            return res;
399        }
400    }
401
402    return OK;
403}
404
405status_t StreamingProcessor::deleteRecordingStream() {
406    ATRACE_CALL();
407    status_t res;
408
409    Mutex::Autolock m(mMutex);
410
411    if (mRecordingStreamId != NO_STREAM) {
412        sp<CameraDeviceBase> device = mDevice.promote();
413        if (device == 0) {
414            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
415            return INVALID_OPERATION;
416        }
417
418        res = device->waitUntilDrained();
419        if (res != OK) {
420            ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
421                    __FUNCTION__, strerror(-res), res);
422            return res;
423        }
424        res = device->deleteStream(mRecordingStreamId);
425        if (res != OK) {
426            ALOGE("%s: Unable to delete recording stream: %s (%d)",
427                    __FUNCTION__, strerror(-res), res);
428            return res;
429        }
430        mRecordingStreamId = NO_STREAM;
431    }
432    return OK;
433}
434
435int StreamingProcessor::getRecordingStreamId() const {
436    return mRecordingStreamId;
437}
438
439status_t StreamingProcessor::startStream(StreamType type,
440        const Vector<int32_t> &outputStreams) {
441    ATRACE_CALL();
442    status_t res;
443
444    if (type == NONE) return INVALID_OPERATION;
445
446    sp<CameraDeviceBase> device = mDevice.promote();
447    if (device == 0) {
448        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
449        return INVALID_OPERATION;
450    }
451
452    ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type);
453
454    Mutex::Autolock m(mMutex);
455
456    CameraMetadata &request = (type == PREVIEW) ?
457            mPreviewRequest : mRecordingRequest;
458
459    res = request.update(
460        ANDROID_REQUEST_OUTPUT_STREAMS,
461        outputStreams);
462    if (res != OK) {
463        ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
464                __FUNCTION__, mId, strerror(-res), res);
465        return res;
466    }
467
468    res = request.sort();
469    if (res != OK) {
470        ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
471                __FUNCTION__, mId, strerror(-res), res);
472        return res;
473    }
474
475    res = device->setStreamingRequest(request);
476    if (res != OK) {
477        ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
478                "%s (%d)",
479                __FUNCTION__, mId, strerror(-res), res);
480        return res;
481    }
482    mActiveRequest = type;
483    mPaused = false;
484    mActiveStreamIds = outputStreams;
485    return OK;
486}
487
488status_t StreamingProcessor::togglePauseStream(bool pause) {
489    ATRACE_CALL();
490    status_t res;
491
492    sp<CameraDeviceBase> device = mDevice.promote();
493    if (device == 0) {
494        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
495        return INVALID_OPERATION;
496    }
497
498    ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause);
499
500    Mutex::Autolock m(mMutex);
501
502    if (mActiveRequest == NONE) {
503        ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started",
504              __FUNCTION__, mId);
505        return INVALID_OPERATION;
506    }
507
508    if (mPaused == pause) {
509        return OK;
510    }
511
512    if (pause) {
513        res = device->clearStreamingRequest();
514        if (res != OK) {
515            ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
516                    __FUNCTION__, mId, strerror(-res), res);
517            return res;
518        }
519    } else {
520        CameraMetadata &request =
521                (mActiveRequest == PREVIEW) ? mPreviewRequest
522                                            : mRecordingRequest;
523        res = device->setStreamingRequest(request);
524        if (res != OK) {
525            ALOGE("%s: Camera %d: Unable to set preview request to resume: "
526                    "%s (%d)",
527                    __FUNCTION__, mId, strerror(-res), res);
528            return res;
529        }
530    }
531
532    mPaused = pause;
533    return OK;
534}
535
536status_t StreamingProcessor::stopStream() {
537    ATRACE_CALL();
538    status_t res;
539
540    Mutex::Autolock m(mMutex);
541
542    sp<CameraDeviceBase> device = mDevice.promote();
543    if (device == 0) {
544        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
545        return INVALID_OPERATION;
546    }
547
548    res = device->clearStreamingRequest();
549    if (res != OK) {
550        ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
551                __FUNCTION__, mId, strerror(-res), res);
552        return res;
553    }
554
555    mActiveRequest = NONE;
556    mActiveStreamIds.clear();
557    mPaused = false;
558
559    return OK;
560}
561
562int32_t StreamingProcessor::getActiveRequestId() const {
563    Mutex::Autolock m(mMutex);
564    switch (mActiveRequest) {
565        case NONE:
566            return 0;
567        case PREVIEW:
568            return mPreviewRequestId;
569        case RECORD:
570            return mRecordingRequestId;
571        default:
572            ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest);
573            return 0;
574    }
575}
576
577status_t StreamingProcessor::incrementStreamingIds() {
578    ATRACE_CALL();
579    Mutex::Autolock m(mMutex);
580
581    mPreviewRequestId++;
582    if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
583        mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
584    }
585    mRecordingRequestId++;
586    if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) {
587        mRecordingRequestId = Camera2Client::kRecordingRequestIdStart;
588    }
589    return OK;
590}
591
592status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
593    String8 result;
594
595    result.append("  Current requests:\n");
596    if (mPreviewRequest.entryCount() != 0) {
597        result.append("    Preview request:\n");
598        write(fd, result.string(), result.size());
599        mPreviewRequest.dump(fd, 2, 6);
600        result.clear();
601    } else {
602        result.append("    Preview request: undefined\n");
603    }
604
605    if (mRecordingRequest.entryCount() != 0) {
606        result = "    Recording request:\n";
607        write(fd, result.string(), result.size());
608        mRecordingRequest.dump(fd, 2, 6);
609        result.clear();
610    } else {
611        result = "    Recording request: undefined\n";
612    }
613
614    const char* streamTypeString[] = {
615        "none", "preview", "record"
616    };
617    result.append(String8::format("   Active request: %s (paused: %s)\n",
618                                  streamTypeString[mActiveRequest],
619                                  mPaused ? "yes" : "no"));
620
621    write(fd, result.string(), result.size());
622
623    return OK;
624}
625
626}; // namespace camera2
627}; // namespace android
628