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