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