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