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