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