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