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