Home | History | Annotate | Download | only in camera2
      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 "StreamingProcessor.h"
     34 #include "Camera2Heap.h"
     35 #include "../Camera2Client.h"
     36 #include "../CameraDeviceBase.h"
     37 
     38 namespace android {
     39 namespace camera2 {
     40 
     41 StreamingProcessor::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 
     57 StreamingProcessor::~StreamingProcessor() {
     58     deletePreviewStream();
     59     deleteRecordingStream();
     60 }
     61 
     62 status_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 
     76 bool StreamingProcessor::haveValidPreviewWindow() const {
     77     Mutex::Autolock m(mMutex);
     78     return mPreviewWindow != 0;
     79 }
     80 
     81 status_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 
    120 status_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 
    186 status_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 
    219 int StreamingProcessor::getPreviewStreamId() const {
    220     Mutex::Autolock m(mMutex);
    221     return mPreviewStreamId;
    222 }
    223 
    224 status_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 
    264 status_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 
    304 status_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         mRecordingConsumer = new BufferItemConsumer(
    323                 GRALLOC_USAGE_HW_VIDEO_ENCODER,
    324                 mRecordingHeapCount + 1,
    325                 true);
    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 
    381 status_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 
    411 int StreamingProcessor::getRecordingStreamId() const {
    412     return mRecordingStreamId;
    413 }
    414 
    415 status_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 
    475 status_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 
    523 status_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 
    549 int32_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 
    564 status_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 
    579 void StreamingProcessor::onFrameAvailable() {
    580     ATRACE_CALL();
    581     Mutex::Autolock l(mMutex);
    582     if (!mRecordingFrameAvailable) {
    583         mRecordingFrameAvailable = true;
    584         mRecordingFrameAvailableSignal.signal();
    585     }
    586 
    587 }
    588 
    589 bool 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 
    609 status_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);
    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);
    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 
    733 void 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 
    795 void 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 
    834 bool 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 
    845 status_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