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