StreamingProcessor.cpp revision 7fed0d95953a195c38b94e043f8e4418f90b846e
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        mRecordingFrameAvailable(false),
54        mRecordingHeapCount(kDefaultRecordingHeapCount),
55        mRecordingHeapFree(kDefaultRecordingHeapCount),
56        mRecordingFormat(kDefaultRecordingFormat),
57        mRecordingDataSpace(kDefaultRecordingDataSpace),
58        mRecordingGrallocUsage(kDefaultRecordingGrallocUsage)
59{
60}
61
62StreamingProcessor::~StreamingProcessor() {
63    deletePreviewStream();
64    deleteRecordingStream();
65}
66
67status_t StreamingProcessor::setPreviewWindow(sp<Surface> window) {
68    ATRACE_CALL();
69    status_t res;
70
71    res = deletePreviewStream();
72    if (res != OK) return res;
73
74    Mutex::Autolock m(mMutex);
75
76    mPreviewWindow = window;
77
78    return OK;
79}
80
81bool StreamingProcessor::haveValidPreviewWindow() const {
82    Mutex::Autolock m(mMutex);
83    return mPreviewWindow != 0;
84}
85
86status_t StreamingProcessor::updatePreviewRequest(const Parameters &params) {
87    ATRACE_CALL();
88    status_t res;
89    sp<CameraDeviceBase> device = mDevice.promote();
90    if (device == 0) {
91        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
92        return INVALID_OPERATION;
93    }
94
95    Mutex::Autolock m(mMutex);
96    if (mPreviewRequest.entryCount() == 0) {
97        sp<Camera2Client> client = mClient.promote();
98        if (client == 0) {
99            ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
100            return INVALID_OPERATION;
101        }
102
103        // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case.
104        if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
105            if (params.zslMode && !params.recordingHint) {
106                res = device->createDefaultRequest(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
107                        &mPreviewRequest);
108            } else {
109                res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW,
110                        &mPreviewRequest);
111            }
112        } else {
113            res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
114                    &mPreviewRequest);
115        }
116
117        if (res != OK) {
118            ALOGE("%s: Camera %d: Unable to create default preview request: "
119                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
120            return res;
121        }
122    }
123
124    res = params.updateRequest(&mPreviewRequest);
125    if (res != OK) {
126        ALOGE("%s: Camera %d: Unable to update common entries of preview "
127                "request: %s (%d)", __FUNCTION__, mId,
128                strerror(-res), res);
129        return res;
130    }
131
132    res = mPreviewRequest.update(ANDROID_REQUEST_ID,
133            &mPreviewRequestId, 1);
134    if (res != OK) {
135        ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)",
136                __FUNCTION__, mId, strerror(-res), res);
137        return res;
138    }
139
140    return OK;
141}
142
143status_t StreamingProcessor::updatePreviewStream(const Parameters &params) {
144    ATRACE_CALL();
145    Mutex::Autolock m(mMutex);
146
147    status_t res;
148    sp<CameraDeviceBase> device = mDevice.promote();
149    if (device == 0) {
150        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
151        return INVALID_OPERATION;
152    }
153
154    if (mPreviewStreamId != NO_STREAM) {
155        // Check if stream parameters have to change
156        uint32_t currentWidth, currentHeight;
157        res = device->getStreamInfo(mPreviewStreamId,
158                &currentWidth, &currentHeight, 0, 0);
159        if (res != OK) {
160            ALOGE("%s: Camera %d: Error querying preview stream info: "
161                    "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
162            return res;
163        }
164        if (currentWidth != (uint32_t)params.previewWidth ||
165                currentHeight != (uint32_t)params.previewHeight) {
166            ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
167                    __FUNCTION__, mId, currentWidth, currentHeight,
168                    params.previewWidth, params.previewHeight);
169            res = device->waitUntilDrained();
170            if (res != OK) {
171                ALOGE("%s: Camera %d: Error waiting for preview to drain: "
172                        "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
173                return res;
174            }
175            res = device->deleteStream(mPreviewStreamId);
176            if (res != OK) {
177                ALOGE("%s: Camera %d: Unable to delete old output stream "
178                        "for preview: %s (%d)", __FUNCTION__, mId,
179                        strerror(-res), res);
180                return res;
181            }
182            mPreviewStreamId = NO_STREAM;
183        }
184    }
185
186    if (mPreviewStreamId == NO_STREAM) {
187        res = device->createStream(mPreviewWindow,
188                params.previewWidth, params.previewHeight,
189                CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN,
190                CAMERA3_STREAM_ROTATION_0, &mPreviewStreamId);
191        if (res != OK) {
192            ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
193                    __FUNCTION__, mId, strerror(-res), res);
194            return res;
195        }
196    }
197
198    res = device->setStreamTransform(mPreviewStreamId,
199            params.previewTransform);
200    if (res != OK) {
201        ALOGE("%s: Camera %d: Unable to set preview stream transform: "
202                "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
203        return res;
204    }
205
206    return OK;
207}
208
209status_t StreamingProcessor::deletePreviewStream() {
210    ATRACE_CALL();
211    status_t res;
212
213    Mutex::Autolock m(mMutex);
214
215    if (mPreviewStreamId != NO_STREAM) {
216        sp<CameraDeviceBase> device = mDevice.promote();
217        if (device == 0) {
218            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
219            return INVALID_OPERATION;
220        }
221
222        ALOGV("%s: for cameraId %d on streamId %d",
223            __FUNCTION__, mId, mPreviewStreamId);
224
225        res = device->waitUntilDrained();
226        if (res != OK) {
227            ALOGE("%s: Error waiting for preview to drain: %s (%d)",
228                    __FUNCTION__, strerror(-res), res);
229            return res;
230        }
231        res = device->deleteStream(mPreviewStreamId);
232        if (res != OK) {
233            ALOGE("%s: Unable to delete old preview stream: %s (%d)",
234                    __FUNCTION__, strerror(-res), res);
235            return res;
236        }
237        mPreviewStreamId = NO_STREAM;
238    }
239    return OK;
240}
241
242int StreamingProcessor::getPreviewStreamId() const {
243    Mutex::Autolock m(mMutex);
244    return mPreviewStreamId;
245}
246
247status_t StreamingProcessor::setRecordingBufferCount(size_t count) {
248    ATRACE_CALL();
249    // Make sure we can support this many buffer slots
250    if (count > BufferQueue::NUM_BUFFER_SLOTS) {
251        ALOGE("%s: Camera %d: Too many recording buffers requested: %zu, max %d",
252                __FUNCTION__, mId, count, BufferQueue::NUM_BUFFER_SLOTS);
253        return BAD_VALUE;
254    }
255
256    Mutex::Autolock m(mMutex);
257
258    ALOGV("%s: Camera %d: New recording buffer count from encoder: %zu",
259            __FUNCTION__, mId, count);
260
261    // Need to re-size consumer and heap
262    if (mRecordingHeapCount != count) {
263        ALOGV("%s: Camera %d: Resetting recording heap and consumer",
264            __FUNCTION__, mId);
265
266        if (isStreamActive(mActiveStreamIds, mRecordingStreamId)) {
267            ALOGE("%s: Camera %d: Setting recording buffer count when "
268                    "recording stream is already active!", __FUNCTION__,
269                    mId);
270            return INVALID_OPERATION;
271        }
272
273        releaseAllRecordingFramesLocked();
274
275        if (mRecordingHeap != 0) {
276            mRecordingHeap.clear();
277        }
278        mRecordingHeapCount = count;
279        mRecordingHeapFree = count;
280
281        mRecordingConsumer.clear();
282    }
283
284    return OK;
285}
286
287status_t StreamingProcessor::setRecordingFormat(int format,
288        android_dataspace dataSpace) {
289    ATRACE_CALL();
290
291    Mutex::Autolock m(mMutex);
292
293    ALOGV("%s: Camera %d: New recording format/dataspace from encoder: %X, %X",
294            __FUNCTION__, mId, format, dataSpace);
295
296    mRecordingFormat = format;
297    mRecordingDataSpace = dataSpace;
298    int prevGrallocUsage = mRecordingGrallocUsage;
299    if (mRecordingFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
300        mRecordingGrallocUsage = GRALLOC_USAGE_HW_VIDEO_ENCODER;
301    } else {
302        mRecordingGrallocUsage = GRALLOC_USAGE_SW_READ_OFTEN;
303    }
304
305    ALOGV("%s: Camera %d: New recording gralloc usage: %08X", __FUNCTION__, mId,
306            mRecordingGrallocUsage);
307
308    if (prevGrallocUsage != mRecordingGrallocUsage) {
309        ALOGV("%s: Camera %d: Resetting recording consumer for new usage",
310            __FUNCTION__, mId);
311
312        if (isStreamActive(mActiveStreamIds, mRecordingStreamId)) {
313            ALOGE("%s: Camera %d: Changing recording format when "
314                    "recording stream is already active!", __FUNCTION__,
315                    mId);
316            return INVALID_OPERATION;
317        }
318
319        releaseAllRecordingFramesLocked();
320
321        mRecordingConsumer.clear();
322    }
323
324    return OK;
325}
326
327status_t StreamingProcessor::updateRecordingRequest(const Parameters &params) {
328    ATRACE_CALL();
329    status_t res;
330    Mutex::Autolock m(mMutex);
331
332    sp<CameraDeviceBase> device = mDevice.promote();
333    if (device == 0) {
334        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
335        return INVALID_OPERATION;
336    }
337
338    if (mRecordingRequest.entryCount() == 0) {
339        res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
340                &mRecordingRequest);
341        if (res != OK) {
342            ALOGE("%s: Camera %d: Unable to create default recording request:"
343                    " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
344            return res;
345        }
346    }
347
348    res = params.updateRequest(&mRecordingRequest);
349    if (res != OK) {
350        ALOGE("%s: Camera %d: Unable to update common entries of recording "
351                "request: %s (%d)", __FUNCTION__, mId,
352                strerror(-res), res);
353        return res;
354    }
355
356    res = mRecordingRequest.update(ANDROID_REQUEST_ID,
357            &mRecordingRequestId, 1);
358    if (res != OK) {
359        ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)",
360                __FUNCTION__, mId, strerror(-res), res);
361        return res;
362    }
363
364    return OK;
365}
366
367status_t StreamingProcessor::recordingStreamNeedsUpdate(
368        const Parameters &params, bool *needsUpdate) {
369    status_t res;
370
371    if (needsUpdate == 0) {
372        ALOGE("%s: Camera %d: invalid argument", __FUNCTION__, mId);
373        return INVALID_OPERATION;
374    }
375
376    if (mRecordingStreamId == NO_STREAM) {
377        *needsUpdate = true;
378        return OK;
379    }
380
381    sp<CameraDeviceBase> device = mDevice.promote();
382    if (device == 0) {
383        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
384        return INVALID_OPERATION;
385    }
386
387    uint32_t currentWidth, currentHeight, currentFormat;
388    android_dataspace currentDataSpace;
389    res = device->getStreamInfo(mRecordingStreamId,
390            &currentWidth, &currentHeight, &currentFormat, &currentDataSpace);
391    if (res != OK) {
392        ALOGE("%s: Camera %d: Error querying recording output stream info: "
393                "%s (%d)", __FUNCTION__, mId,
394                strerror(-res), res);
395        return res;
396    }
397
398    if (mRecordingConsumer == 0 ||
399            currentWidth != (uint32_t)params.videoWidth ||
400            currentHeight != (uint32_t)params.videoHeight ||
401            currentFormat != (uint32_t)mRecordingFormat ||
402            currentDataSpace != mRecordingDataSpace) {
403        *needsUpdate = true;
404        return res;
405    }
406    *needsUpdate = false;
407    return res;
408}
409
410status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
411    ATRACE_CALL();
412    status_t res;
413    Mutex::Autolock m(mMutex);
414
415    sp<CameraDeviceBase> device = mDevice.promote();
416    if (device == 0) {
417        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
418        return INVALID_OPERATION;
419    }
420
421    bool newConsumer = false;
422    if (mRecordingConsumer == 0) {
423        ALOGV("%s: Camera %d: Creating recording consumer with %zu + 1 "
424                "consumer-side buffers", __FUNCTION__, mId, mRecordingHeapCount);
425        // Create CPU buffer queue endpoint. We need one more buffer here so that we can
426        // always acquire and free a buffer when the heap is full; otherwise the consumer
427        // will have buffers in flight we'll never clear out.
428        sp<IGraphicBufferProducer> producer;
429        sp<IGraphicBufferConsumer> consumer;
430        BufferQueue::createBufferQueue(&producer, &consumer);
431        mRecordingConsumer = new BufferItemConsumer(consumer,
432                mRecordingGrallocUsage,
433                mRecordingHeapCount + 1);
434        mRecordingConsumer->setFrameAvailableListener(this);
435        mRecordingConsumer->setName(String8("Camera2-RecordingConsumer"));
436        mRecordingWindow = new Surface(producer);
437        newConsumer = true;
438        // Allocate memory later, since we don't know buffer size until receipt
439    }
440
441    if (mRecordingStreamId != NO_STREAM) {
442        // Check if stream parameters have to change
443        uint32_t currentWidth, currentHeight;
444        uint32_t currentFormat;
445        android_dataspace currentDataSpace;
446        res = device->getStreamInfo(mRecordingStreamId,
447                &currentWidth, &currentHeight,
448                &currentFormat, &currentDataSpace);
449        if (res != OK) {
450            ALOGE("%s: Camera %d: Error querying recording output stream info: "
451                    "%s (%d)", __FUNCTION__, mId,
452                    strerror(-res), res);
453            return res;
454        }
455        if (currentWidth != (uint32_t)params.videoWidth ||
456                currentHeight != (uint32_t)params.videoHeight ||
457                currentFormat != (uint32_t)mRecordingFormat ||
458                currentDataSpace != mRecordingDataSpace ||
459                newConsumer) {
460            // TODO: Should wait to be sure previous recording has finished
461            res = device->deleteStream(mRecordingStreamId);
462
463            if (res == -EBUSY) {
464                ALOGV("%s: Camera %d: Device is busy, call "
465                      "updateRecordingStream after it becomes idle",
466                      __FUNCTION__, mId);
467                return res;
468            } else if (res != OK) {
469                ALOGE("%s: Camera %d: Unable to delete old output stream "
470                        "for recording: %s (%d)", __FUNCTION__,
471                        mId, strerror(-res), res);
472                return res;
473            }
474            mRecordingStreamId = NO_STREAM;
475        }
476    }
477
478    if (mRecordingStreamId == NO_STREAM) {
479        mRecordingFrameCount = 0;
480        res = device->createStream(mRecordingWindow,
481                params.videoWidth, params.videoHeight,
482                mRecordingFormat, mRecordingDataSpace,
483                CAMERA3_STREAM_ROTATION_0, &mRecordingStreamId);
484        if (res != OK) {
485            ALOGE("%s: Camera %d: Can't create output stream for recording: "
486                    "%s (%d)", __FUNCTION__, mId,
487                    strerror(-res), res);
488            return res;
489        }
490    }
491
492    return OK;
493}
494
495status_t StreamingProcessor::deleteRecordingStream() {
496    ATRACE_CALL();
497    status_t res;
498
499    Mutex::Autolock m(mMutex);
500
501    if (mRecordingStreamId != NO_STREAM) {
502        sp<CameraDeviceBase> device = mDevice.promote();
503        if (device == 0) {
504            ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
505            return INVALID_OPERATION;
506        }
507
508        res = device->waitUntilDrained();
509        if (res != OK) {
510            ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
511                    __FUNCTION__, strerror(-res), res);
512            return res;
513        }
514        res = device->deleteStream(mRecordingStreamId);
515        if (res != OK) {
516            ALOGE("%s: Unable to delete recording stream: %s (%d)",
517                    __FUNCTION__, strerror(-res), res);
518            return res;
519        }
520        mRecordingStreamId = NO_STREAM;
521    }
522    return OK;
523}
524
525int StreamingProcessor::getRecordingStreamId() const {
526    return mRecordingStreamId;
527}
528
529status_t StreamingProcessor::startStream(StreamType type,
530        const Vector<int32_t> &outputStreams) {
531    ATRACE_CALL();
532    status_t res;
533
534    if (type == NONE) return INVALID_OPERATION;
535
536    sp<CameraDeviceBase> device = mDevice.promote();
537    if (device == 0) {
538        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
539        return INVALID_OPERATION;
540    }
541
542    ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type);
543
544    Mutex::Autolock m(mMutex);
545
546    // If a recording stream is being started up and no recording
547    // stream is active yet, free up any outstanding buffers left
548    // from the previous recording session. There should never be
549    // any, so if there are, warn about it.
550    bool isRecordingStreamIdle = !isStreamActive(mActiveStreamIds, mRecordingStreamId);
551    bool startRecordingStream = isStreamActive(outputStreams, mRecordingStreamId);
552    if (startRecordingStream && isRecordingStreamIdle) {
553        releaseAllRecordingFramesLocked();
554    }
555
556    ALOGV("%s: Camera %d: %s started, recording heap has %zu free of %zu",
557            __FUNCTION__, mId, (type == PREVIEW) ? "preview" : "recording",
558            mRecordingHeapFree, mRecordingHeapCount);
559
560    CameraMetadata &request = (type == PREVIEW) ?
561            mPreviewRequest : mRecordingRequest;
562
563    res = request.update(
564        ANDROID_REQUEST_OUTPUT_STREAMS,
565        outputStreams);
566    if (res != OK) {
567        ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
568                __FUNCTION__, mId, strerror(-res), res);
569        return res;
570    }
571
572    res = request.sort();
573    if (res != OK) {
574        ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
575                __FUNCTION__, mId, strerror(-res), res);
576        return res;
577    }
578
579    res = device->setStreamingRequest(request);
580    if (res != OK) {
581        ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
582                "%s (%d)",
583                __FUNCTION__, mId, strerror(-res), res);
584        return res;
585    }
586    mActiveRequest = type;
587    mPaused = false;
588    mActiveStreamIds = outputStreams;
589    return OK;
590}
591
592status_t StreamingProcessor::togglePauseStream(bool pause) {
593    ATRACE_CALL();
594    status_t res;
595
596    sp<CameraDeviceBase> device = mDevice.promote();
597    if (device == 0) {
598        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
599        return INVALID_OPERATION;
600    }
601
602    ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause);
603
604    Mutex::Autolock m(mMutex);
605
606    if (mActiveRequest == NONE) {
607        ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started",
608              __FUNCTION__, mId);
609        return INVALID_OPERATION;
610    }
611
612    if (mPaused == pause) {
613        return OK;
614    }
615
616    if (pause) {
617        res = device->clearStreamingRequest();
618        if (res != OK) {
619            ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
620                    __FUNCTION__, mId, strerror(-res), res);
621            return res;
622        }
623    } else {
624        CameraMetadata &request =
625                (mActiveRequest == PREVIEW) ? mPreviewRequest
626                                            : mRecordingRequest;
627        res = device->setStreamingRequest(request);
628        if (res != OK) {
629            ALOGE("%s: Camera %d: Unable to set preview request to resume: "
630                    "%s (%d)",
631                    __FUNCTION__, mId, strerror(-res), res);
632            return res;
633        }
634    }
635
636    mPaused = pause;
637    return OK;
638}
639
640status_t StreamingProcessor::stopStream() {
641    ATRACE_CALL();
642    status_t res;
643
644    Mutex::Autolock m(mMutex);
645
646    sp<CameraDeviceBase> device = mDevice.promote();
647    if (device == 0) {
648        ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
649        return INVALID_OPERATION;
650    }
651
652    res = device->clearStreamingRequest();
653    if (res != OK) {
654        ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
655                __FUNCTION__, mId, strerror(-res), res);
656        return res;
657    }
658
659    mActiveRequest = NONE;
660    mActiveStreamIds.clear();
661    mPaused = false;
662
663    return OK;
664}
665
666int32_t StreamingProcessor::getActiveRequestId() const {
667    Mutex::Autolock m(mMutex);
668    switch (mActiveRequest) {
669        case NONE:
670            return 0;
671        case PREVIEW:
672            return mPreviewRequestId;
673        case RECORD:
674            return mRecordingRequestId;
675        default:
676            ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest);
677            return 0;
678    }
679}
680
681status_t StreamingProcessor::incrementStreamingIds() {
682    ATRACE_CALL();
683    Mutex::Autolock m(mMutex);
684
685    mPreviewRequestId++;
686    if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
687        mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
688    }
689    mRecordingRequestId++;
690    if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) {
691        mRecordingRequestId = Camera2Client::kRecordingRequestIdStart;
692    }
693    return OK;
694}
695
696void StreamingProcessor::onFrameAvailable(const BufferItem& /*item*/) {
697    ATRACE_CALL();
698    Mutex::Autolock l(mMutex);
699    if (!mRecordingFrameAvailable) {
700        mRecordingFrameAvailable = true;
701        mRecordingFrameAvailableSignal.signal();
702    }
703
704}
705
706bool StreamingProcessor::threadLoop() {
707    status_t res;
708
709    {
710        Mutex::Autolock l(mMutex);
711        while (!mRecordingFrameAvailable) {
712            res = mRecordingFrameAvailableSignal.waitRelative(
713                mMutex, kWaitDuration);
714            if (res == TIMED_OUT) return true;
715        }
716        mRecordingFrameAvailable = false;
717    }
718
719    do {
720        res = processRecordingFrame();
721    } while (res == OK);
722
723    return true;
724}
725
726status_t StreamingProcessor::processRecordingFrame() {
727    ATRACE_CALL();
728    status_t res;
729    sp<Camera2Heap> recordingHeap;
730    size_t heapIdx = 0;
731    nsecs_t timestamp;
732
733    sp<Camera2Client> client = mClient.promote();
734    if (client == 0) {
735        // Discard frames during shutdown
736        BufferItem imgBuffer;
737        res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0);
738        if (res != OK) {
739            if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
740                ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
741                        __FUNCTION__, mId, strerror(-res), res);
742            }
743            return res;
744        }
745        mRecordingConsumer->releaseBuffer(imgBuffer);
746        return OK;
747    }
748
749    {
750        /* acquire SharedParameters before mMutex so we don't dead lock
751            with Camera2Client code calling into StreamingProcessor */
752        SharedParameters::Lock l(client->getParameters());
753        Mutex::Autolock m(mMutex);
754        BufferItem imgBuffer;
755        res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0);
756        if (res != OK) {
757            if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
758                ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
759                        __FUNCTION__, mId, strerror(-res), res);
760            }
761            return res;
762        }
763        timestamp = imgBuffer.mTimestamp;
764
765        mRecordingFrameCount++;
766        ALOGVV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
767
768        if (l.mParameters.state != Parameters::RECORD &&
769                l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
770            ALOGV("%s: Camera %d: Discarding recording image buffers "
771                    "received after recording done", __FUNCTION__,
772                    mId);
773            mRecordingConsumer->releaseBuffer(imgBuffer);
774            return INVALID_OPERATION;
775        }
776
777        if (mRecordingHeap == 0) {
778            size_t payloadSize = sizeof(VideoNativeMetadata);
779            ALOGV("%s: Camera %d: Creating recording heap with %zu buffers of "
780                    "size %zu bytes", __FUNCTION__, mId,
781                    mRecordingHeapCount, payloadSize);
782
783            mRecordingHeap = new Camera2Heap(payloadSize, mRecordingHeapCount,
784                    "Camera2Client::RecordingHeap");
785            if (mRecordingHeap->mHeap->getSize() == 0) {
786                ALOGE("%s: Camera %d: Unable to allocate memory for recording",
787                        __FUNCTION__, mId);
788                mRecordingConsumer->releaseBuffer(imgBuffer);
789                return NO_MEMORY;
790            }
791            for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
792                if (mRecordingBuffers[i].mBuf !=
793                        BufferItemConsumer::INVALID_BUFFER_SLOT) {
794                    ALOGE("%s: Camera %d: Non-empty recording buffers list!",
795                            __FUNCTION__, mId);
796                }
797            }
798            mRecordingBuffers.clear();
799            mRecordingBuffers.setCapacity(mRecordingHeapCount);
800            mRecordingBuffers.insertAt(0, mRecordingHeapCount);
801
802            mRecordingHeapHead = 0;
803            mRecordingHeapFree = mRecordingHeapCount;
804        }
805
806        if (mRecordingHeapFree == 0) {
807            ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
808                    __FUNCTION__, mId);
809            mRecordingConsumer->releaseBuffer(imgBuffer);
810            return NO_MEMORY;
811        }
812
813        heapIdx = mRecordingHeapHead;
814        mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
815        mRecordingHeapFree--;
816
817        ALOGVV("%s: Camera %d: Timestamp %lld",
818                __FUNCTION__, mId, timestamp);
819
820        ssize_t offset;
821        size_t size;
822        sp<IMemoryHeap> heap =
823                mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
824                        &size);
825
826        VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>(
827            (uint8_t*)heap->getBase() + offset);
828        payload->eType = kMetadataBufferTypeANWBuffer;
829        payload->pBuffer = imgBuffer.mGraphicBuffer->getNativeBuffer();
830        payload->nFenceFd = -1;
831
832        ALOGVV("%s: Camera %d: Sending out ANWBuffer %p",
833                __FUNCTION__, mId, payload->pBuffer);
834
835        mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
836        recordingHeap = mRecordingHeap;
837    }
838
839    // Call outside locked parameters to allow re-entrancy from notification
840    Camera2Client::SharedCameraCallbacks::Lock l(client->mSharedCameraCallbacks);
841    if (l.mRemoteCallback != 0) {
842        l.mRemoteCallback->dataCallbackTimestamp(timestamp,
843                CAMERA_MSG_VIDEO_FRAME,
844                recordingHeap->mBuffers[heapIdx]);
845    } else {
846        ALOGW("%s: Camera %d: Remote callback gone", __FUNCTION__, mId);
847    }
848
849    return OK;
850}
851
852void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) {
853    ATRACE_CALL();
854    status_t res;
855
856    Mutex::Autolock m(mMutex);
857    // Make sure this is for the current heap
858    ssize_t offset;
859    size_t size;
860    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
861    if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
862        ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
863                "(got %x, expected %x)", __FUNCTION__, mId,
864                heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
865        return;
866    }
867
868    VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>(
869        (uint8_t*)heap->getBase() + offset);
870
871    if (payload->eType != kMetadataBufferTypeANWBuffer) {
872        ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
873                __FUNCTION__, mId, payload->eType,
874                kMetadataBufferTypeANWBuffer);
875        return;
876    }
877
878    // Release the buffer back to the recording queue
879    size_t itemIndex;
880    for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
881        const BufferItem item = mRecordingBuffers[itemIndex];
882        if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
883                item.mGraphicBuffer->getNativeBuffer() == payload->pBuffer) {
884                break;
885        }
886    }
887
888    if (itemIndex == mRecordingBuffers.size()) {
889        ALOGE("%s: Camera %d: Can't find returned ANW Buffer %p in list of "
890                "outstanding buffers", __FUNCTION__, mId,
891                payload->pBuffer);
892        return;
893    }
894
895    ALOGVV("%s: Camera %d: Freeing returned ANW buffer %p index %d", __FUNCTION__,
896            mId, payload->pBuffer, itemIndex);
897
898    res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
899    if (res != OK) {
900        ALOGE("%s: Camera %d: Unable to free recording frame "
901                "(Returned ANW buffer: %p): %s (%d)", __FUNCTION__,
902                mId, payload->pBuffer, strerror(-res), res);
903        return;
904    }
905    mRecordingBuffers.replaceAt(itemIndex);
906
907    mRecordingHeapFree++;
908    ALOGV_IF(mRecordingHeapFree == mRecordingHeapCount,
909            "%s: Camera %d: All %d recording buffers returned",
910            __FUNCTION__, mId, mRecordingHeapCount);
911}
912
913void StreamingProcessor::releaseAllRecordingFramesLocked() {
914    ATRACE_CALL();
915    status_t res;
916
917    if (mRecordingConsumer == 0) {
918        return;
919    }
920
921    ALOGV("%s: Camera %d: Releasing all recording buffers", __FUNCTION__,
922            mId);
923
924    size_t releasedCount = 0;
925    for (size_t itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
926        const BufferItem item = mRecordingBuffers[itemIndex];
927        if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT) {
928            res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
929            if (res != OK) {
930                ALOGE("%s: Camera %d: Unable to free recording frame "
931                        "(buffer_handle_t: %p): %s (%d)", __FUNCTION__,
932                        mId, item.mGraphicBuffer->handle, strerror(-res), res);
933            }
934            mRecordingBuffers.replaceAt(itemIndex);
935            releasedCount++;
936        }
937    }
938
939    if (releasedCount > 0) {
940        ALOGW("%s: Camera %d: Force-freed %zu outstanding buffers "
941                "from previous recording session", __FUNCTION__, mId, releasedCount);
942        ALOGE_IF(releasedCount != mRecordingHeapCount - mRecordingHeapFree,
943            "%s: Camera %d: Force-freed %zu buffers, but expected %zu",
944            __FUNCTION__, mId, releasedCount, mRecordingHeapCount - mRecordingHeapFree);
945    }
946
947    mRecordingHeapHead = 0;
948    mRecordingHeapFree = mRecordingHeapCount;
949}
950
951bool StreamingProcessor::isStreamActive(const Vector<int32_t> &streams,
952        int32_t recordingStreamId) {
953    for (size_t i = 0; i < streams.size(); i++) {
954        if (streams[i] == recordingStreamId) {
955            return true;
956        }
957    }
958    return false;
959}
960
961
962status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
963    String8 result;
964
965    result.append("  Current requests:\n");
966    if (mPreviewRequest.entryCount() != 0) {
967        result.append("    Preview request:\n");
968        write(fd, result.string(), result.size());
969        mPreviewRequest.dump(fd, 2, 6);
970        result.clear();
971    } else {
972        result.append("    Preview request: undefined\n");
973    }
974
975    if (mRecordingRequest.entryCount() != 0) {
976        result = "    Recording request:\n";
977        write(fd, result.string(), result.size());
978        mRecordingRequest.dump(fd, 2, 6);
979        result.clear();
980    } else {
981        result = "    Recording request: undefined\n";
982    }
983
984    const char* streamTypeString[] = {
985        "none", "preview", "record"
986    };
987    result.append(String8::format("   Active request: %s (paused: %s)\n",
988                                  streamTypeString[mActiveRequest],
989                                  mPaused ? "yes" : "no"));
990
991    write(fd, result.string(), result.size());
992
993    return OK;
994}
995
996}; // namespace camera2
997}; // namespace android
998