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