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