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-ZslProcessor"
     18 #define ATRACE_TAG ATRACE_TAG_CAMERA
     19 //#define LOG_NDEBUG 0
     20 //#define LOG_NNDEBUG 0
     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 
     32 #include "common/CameraDeviceBase.h"
     33 #include "api1/Camera2Client.h"
     34 #include "api1/client2/CaptureSequencer.h"
     35 #include "api1/client2/ZslProcessor.h"
     36 
     37 namespace android {
     38 namespace camera2 {
     39 
     40 ZslProcessor::ZslProcessor(
     41     sp<Camera2Client> client,
     42     wp<CaptureSequencer> sequencer):
     43         Thread(false),
     44         mState(RUNNING),
     45         mClient(client),
     46         mDevice(client->getCameraDevice()),
     47         mSequencer(sequencer),
     48         mId(client->getCameraId()),
     49         mZslBufferAvailable(false),
     50         mZslStreamId(NO_STREAM),
     51         mZslReprocessStreamId(NO_STREAM),
     52         mFrameListHead(0),
     53         mZslQueueHead(0),
     54         mZslQueueTail(0) {
     55     mZslQueue.insertAt(0, kZslBufferDepth);
     56     mFrameList.insertAt(0, kFrameListDepth);
     57     sp<CaptureSequencer> captureSequencer = mSequencer.promote();
     58     if (captureSequencer != 0) captureSequencer->setZslProcessor(this);
     59 }
     60 
     61 ZslProcessor::~ZslProcessor() {
     62     ALOGV("%s: Exit", __FUNCTION__);
     63     deleteStream();
     64 }
     65 
     66 void ZslProcessor::onFrameAvailable() {
     67     Mutex::Autolock l(mInputMutex);
     68     if (!mZslBufferAvailable) {
     69         mZslBufferAvailable = true;
     70         mZslBufferAvailableSignal.signal();
     71     }
     72 }
     73 
     74 void ZslProcessor::onFrameAvailable(int32_t /*requestId*/,
     75         const CameraMetadata &frame) {
     76     Mutex::Autolock l(mInputMutex);
     77     camera_metadata_ro_entry_t entry;
     78     entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
     79     nsecs_t timestamp = entry.data.i64[0];
     80     (void)timestamp;
     81     ALOGVV("Got preview frame for timestamp %lld", timestamp);
     82 
     83     if (mState != RUNNING) return;
     84 
     85     mFrameList.editItemAt(mFrameListHead) = frame;
     86     mFrameListHead = (mFrameListHead + 1) % kFrameListDepth;
     87 
     88     findMatchesLocked();
     89 }
     90 
     91 void ZslProcessor::onBufferReleased(buffer_handle_t *handle) {
     92     Mutex::Autolock l(mInputMutex);
     93 
     94     // Verify that the buffer is in our queue
     95     size_t i = 0;
     96     for (; i < mZslQueue.size(); i++) {
     97         if (&(mZslQueue[i].buffer.mGraphicBuffer->handle) == handle) break;
     98     }
     99     if (i == mZslQueue.size()) {
    100         ALOGW("%s: Released buffer %p not found in queue",
    101                 __FUNCTION__, handle);
    102     }
    103 
    104     // Erase entire ZSL queue since we've now completed the capture and preview
    105     // is stopped.
    106     clearZslQueueLocked();
    107 
    108     mState = RUNNING;
    109 }
    110 
    111 status_t ZslProcessor::updateStream(const Parameters &params) {
    112     ATRACE_CALL();
    113     ALOGV("%s: Configuring ZSL streams", __FUNCTION__);
    114     status_t res;
    115 
    116     Mutex::Autolock l(mInputMutex);
    117 
    118     sp<Camera2Client> client = mClient.promote();
    119     if (client == 0) {
    120         ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
    121         return INVALID_OPERATION;
    122     }
    123     sp<CameraDeviceBase> device = mDevice.promote();
    124     if (device == 0) {
    125         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
    126         return INVALID_OPERATION;
    127     }
    128 
    129     if (mZslConsumer == 0) {
    130         // Create CPU buffer queue endpoint
    131         sp<BufferQueue> bq = new BufferQueue();
    132         mZslConsumer = new BufferItemConsumer(bq,
    133             GRALLOC_USAGE_HW_CAMERA_ZSL,
    134             kZslBufferDepth);
    135         mZslConsumer->setFrameAvailableListener(this);
    136         mZslConsumer->setName(String8("Camera2Client::ZslConsumer"));
    137         mZslWindow = new Surface(bq);
    138     }
    139 
    140     if (mZslStreamId != NO_STREAM) {
    141         // Check if stream parameters have to change
    142         uint32_t currentWidth, currentHeight;
    143         res = device->getStreamInfo(mZslStreamId,
    144                 &currentWidth, &currentHeight, 0);
    145         if (res != OK) {
    146             ALOGE("%s: Camera %d: Error querying capture output stream info: "
    147                     "%s (%d)", __FUNCTION__,
    148                     mId, strerror(-res), res);
    149             return res;
    150         }
    151         if (currentWidth != (uint32_t)params.fastInfo.arrayWidth ||
    152                 currentHeight != (uint32_t)params.fastInfo.arrayHeight) {
    153             res = device->deleteReprocessStream(mZslReprocessStreamId);
    154             if (res != OK) {
    155                 ALOGE("%s: Camera %d: Unable to delete old reprocess stream "
    156                         "for ZSL: %s (%d)", __FUNCTION__,
    157                         mId, strerror(-res), res);
    158                 return res;
    159             }
    160             ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed",
    161                 __FUNCTION__, mId, mZslStreamId);
    162             res = device->deleteStream(mZslStreamId);
    163             if (res != OK) {
    164                 ALOGE("%s: Camera %d: Unable to delete old output stream "
    165                         "for ZSL: %s (%d)", __FUNCTION__,
    166                         mId, strerror(-res), res);
    167                 return res;
    168             }
    169             mZslStreamId = NO_STREAM;
    170         }
    171     }
    172 
    173     if (mZslStreamId == NO_STREAM) {
    174         // Create stream for HAL production
    175         // TODO: Sort out better way to select resolution for ZSL
    176         int streamType = params.quirks.useZslFormat ?
    177                 (int)CAMERA2_HAL_PIXEL_FORMAT_ZSL :
    178                 (int)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
    179         res = device->createStream(mZslWindow,
    180                 params.fastInfo.arrayWidth, params.fastInfo.arrayHeight,
    181                 streamType, 0,
    182                 &mZslStreamId);
    183         if (res != OK) {
    184             ALOGE("%s: Camera %d: Can't create output stream for ZSL: "
    185                     "%s (%d)", __FUNCTION__, mId,
    186                     strerror(-res), res);
    187             return res;
    188         }
    189         res = device->createReprocessStreamFromStream(mZslStreamId,
    190                 &mZslReprocessStreamId);
    191         if (res != OK) {
    192             ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: "
    193                     "%s (%d)", __FUNCTION__, mId,
    194                     strerror(-res), res);
    195             return res;
    196         }
    197     }
    198     client->registerFrameListener(Camera2Client::kPreviewRequestIdStart,
    199             Camera2Client::kPreviewRequestIdEnd,
    200             this);
    201 
    202     return OK;
    203 }
    204 
    205 status_t ZslProcessor::deleteStream() {
    206     ATRACE_CALL();
    207     status_t res;
    208 
    209     Mutex::Autolock l(mInputMutex);
    210 
    211     if (mZslStreamId != NO_STREAM) {
    212         sp<CameraDeviceBase> device = mDevice.promote();
    213         if (device == 0) {
    214             ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
    215             return INVALID_OPERATION;
    216         }
    217 
    218         clearZslQueueLocked();
    219 
    220         res = device->deleteReprocessStream(mZslReprocessStreamId);
    221         if (res != OK) {
    222             ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: "
    223                     "%s (%d)", __FUNCTION__, mId,
    224                     mZslReprocessStreamId, strerror(-res), res);
    225             return res;
    226         }
    227 
    228         mZslReprocessStreamId = NO_STREAM;
    229         res = device->deleteStream(mZslStreamId);
    230         if (res != OK) {
    231             ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: "
    232                     "%s (%d)", __FUNCTION__, mId,
    233                     mZslStreamId, strerror(-res), res);
    234             return res;
    235         }
    236 
    237         mZslWindow.clear();
    238         mZslConsumer.clear();
    239 
    240         mZslStreamId = NO_STREAM;
    241     }
    242     return OK;
    243 }
    244 
    245 int ZslProcessor::getStreamId() const {
    246     Mutex::Autolock l(mInputMutex);
    247     return mZslStreamId;
    248 }
    249 
    250 status_t ZslProcessor::pushToReprocess(int32_t requestId) {
    251     ALOGV("%s: Send in reprocess request with id %d",
    252             __FUNCTION__, requestId);
    253     Mutex::Autolock l(mInputMutex);
    254     status_t res;
    255     sp<Camera2Client> client = mClient.promote();
    256 
    257     if (client == 0) {
    258         ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
    259         return INVALID_OPERATION;
    260     }
    261 
    262     IF_ALOGV() {
    263         dumpZslQueue(-1);
    264     }
    265 
    266     if (mZslQueueTail != mZslQueueHead) {
    267         CameraMetadata request;
    268         size_t index = mZslQueueTail;
    269         while (index != mZslQueueHead) {
    270             if (!mZslQueue[index].frame.isEmpty()) {
    271                 request = mZslQueue[index].frame;
    272                 break;
    273             }
    274             index = (index + 1) % kZslBufferDepth;
    275         }
    276         if (index == mZslQueueHead) {
    277             ALOGV("%s: ZSL queue has no valid frames to send yet.",
    278                   __FUNCTION__);
    279             return NOT_ENOUGH_DATA;
    280         }
    281         // Verify that the frame is reasonable for reprocessing
    282 
    283         camera_metadata_entry_t entry;
    284         entry = request.find(ANDROID_CONTROL_AE_STATE);
    285         if (entry.count == 0) {
    286             ALOGE("%s: ZSL queue frame has no AE state field!",
    287                     __FUNCTION__);
    288             return BAD_VALUE;
    289         }
    290         if (entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_CONVERGED &&
    291                 entry.data.u8[0] != ANDROID_CONTROL_AE_STATE_LOCKED) {
    292             ALOGV("%s: ZSL queue frame AE state is %d, need full capture",
    293                     __FUNCTION__, entry.data.u8[0]);
    294             return NOT_ENOUGH_DATA;
    295         }
    296 
    297         buffer_handle_t *handle =
    298             &(mZslQueue[index].buffer.mGraphicBuffer->handle);
    299 
    300         uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
    301         res = request.update(ANDROID_REQUEST_TYPE,
    302                 &requestType, 1);
    303         int32_t inputStreams[1] =
    304                 { mZslReprocessStreamId };
    305         if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS,
    306                 inputStreams, 1);
    307         int32_t outputStreams[1] =
    308                 { client->getCaptureStreamId() };
    309         if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
    310                 outputStreams, 1);
    311         res = request.update(ANDROID_REQUEST_ID,
    312                 &requestId, 1);
    313 
    314         if (res != OK ) {
    315             ALOGE("%s: Unable to update frame to a reprocess request", __FUNCTION__);
    316             return INVALID_OPERATION;
    317         }
    318 
    319         res = client->stopStream();
    320         if (res != OK) {
    321             ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: "
    322                 "%s (%d)",
    323                 __FUNCTION__, mId, strerror(-res), res);
    324             return INVALID_OPERATION;
    325         }
    326         // TODO: have push-and-clear be atomic
    327         res = client->getCameraDevice()->pushReprocessBuffer(mZslReprocessStreamId,
    328                 handle, this);
    329         if (res != OK) {
    330             ALOGE("%s: Unable to push buffer for reprocessing: %s (%d)",
    331                     __FUNCTION__, strerror(-res), res);
    332             return res;
    333         }
    334 
    335         // Update JPEG settings
    336         {
    337             SharedParameters::Lock l(client->getParameters());
    338             res = l.mParameters.updateRequestJpeg(&request);
    339             if (res != OK) {
    340                 ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL "
    341                         "capture request: %s (%d)", __FUNCTION__,
    342                         mId,
    343                         strerror(-res), res);
    344                 return res;
    345             }
    346         }
    347 
    348         mLatestCapturedRequest = request;
    349         res = client->getCameraDevice()->capture(request);
    350         if (res != OK ) {
    351             ALOGE("%s: Unable to send ZSL reprocess request to capture: %s (%d)",
    352                     __FUNCTION__, strerror(-res), res);
    353             return res;
    354         }
    355 
    356         mState = LOCKED;
    357     } else {
    358         ALOGV("%s: No ZSL buffers yet", __FUNCTION__);
    359         return NOT_ENOUGH_DATA;
    360     }
    361     return OK;
    362 }
    363 
    364 status_t ZslProcessor::clearZslQueue() {
    365     Mutex::Autolock l(mInputMutex);
    366     // If in middle of capture, can't clear out queue
    367     if (mState == LOCKED) return OK;
    368 
    369     return clearZslQueueLocked();
    370 }
    371 
    372 status_t ZslProcessor::clearZslQueueLocked() {
    373     for (size_t i = 0; i < mZslQueue.size(); i++) {
    374         if (mZslQueue[i].buffer.mTimestamp != 0) {
    375             mZslConsumer->releaseBuffer(mZslQueue[i].buffer);
    376         }
    377         mZslQueue.replaceAt(i);
    378     }
    379     mZslQueueHead = 0;
    380     mZslQueueTail = 0;
    381     return OK;
    382 }
    383 
    384 void ZslProcessor::dump(int fd, const Vector<String16>& /*args*/) const {
    385     Mutex::Autolock l(mInputMutex);
    386     if (!mLatestCapturedRequest.isEmpty()) {
    387         String8 result("    Latest ZSL capture request:\n");
    388         write(fd, result.string(), result.size());
    389         mLatestCapturedRequest.dump(fd, 2, 6);
    390     } else {
    391         String8 result("    Latest ZSL capture request: none yet\n");
    392         write(fd, result.string(), result.size());
    393     }
    394     dumpZslQueue(fd);
    395 }
    396 
    397 bool ZslProcessor::threadLoop() {
    398     status_t res;
    399 
    400     {
    401         Mutex::Autolock l(mInputMutex);
    402         while (!mZslBufferAvailable) {
    403             res = mZslBufferAvailableSignal.waitRelative(mInputMutex,
    404                     kWaitDuration);
    405             if (res == TIMED_OUT) return true;
    406         }
    407         mZslBufferAvailable = false;
    408     }
    409 
    410     do {
    411         res = processNewZslBuffer();
    412     } while (res == OK);
    413 
    414     return true;
    415 }
    416 
    417 status_t ZslProcessor::processNewZslBuffer() {
    418     ATRACE_CALL();
    419     status_t res;
    420     sp<BufferItemConsumer> zslConsumer;
    421     {
    422         Mutex::Autolock l(mInputMutex);
    423         if (mZslConsumer == 0) return OK;
    424         zslConsumer = mZslConsumer;
    425     }
    426     ALOGVV("Trying to get next buffer");
    427     BufferItemConsumer::BufferItem item;
    428     res = zslConsumer->acquireBuffer(&item, 0);
    429     if (res != OK) {
    430         if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
    431             ALOGE("%s: Camera %d: Error receiving ZSL image buffer: "
    432                     "%s (%d)", __FUNCTION__,
    433                     mId, strerror(-res), res);
    434         } else {
    435             ALOGVV("  No buffer");
    436         }
    437         return res;
    438     }
    439 
    440     Mutex::Autolock l(mInputMutex);
    441 
    442     if (mState == LOCKED) {
    443         ALOGVV("In capture, discarding new ZSL buffers");
    444         zslConsumer->releaseBuffer(item);
    445         return OK;
    446     }
    447 
    448     ALOGVV("Got ZSL buffer: head: %d, tail: %d", mZslQueueHead, mZslQueueTail);
    449 
    450     if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) {
    451         ALOGVV("Releasing oldest buffer");
    452         zslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer);
    453         mZslQueue.replaceAt(mZslQueueTail);
    454         mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth;
    455     }
    456 
    457     ZslPair &queueHead = mZslQueue.editItemAt(mZslQueueHead);
    458 
    459     queueHead.buffer = item;
    460     queueHead.frame.release();
    461 
    462     mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;
    463 
    464     ALOGVV("  Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp);
    465 
    466     findMatchesLocked();
    467 
    468     return OK;
    469 }
    470 
    471 void ZslProcessor::findMatchesLocked() {
    472     ALOGVV("Scanning");
    473     for (size_t i = 0; i < mZslQueue.size(); i++) {
    474         ZslPair &queueEntry = mZslQueue.editItemAt(i);
    475         nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
    476         IF_ALOGV() {
    477             camera_metadata_entry_t entry;
    478             nsecs_t frameTimestamp = 0;
    479             if (!queueEntry.frame.isEmpty()) {
    480                 entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
    481                 frameTimestamp = entry.data.i64[0];
    482             }
    483             ALOGVV("   %d: b: %lld\tf: %lld", i,
    484                     bufferTimestamp, frameTimestamp );
    485         }
    486         if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
    487             // Have buffer, no matching frame. Look for one
    488             for (size_t j = 0; j < mFrameList.size(); j++) {
    489                 bool match = false;
    490                 CameraMetadata &frame = mFrameList.editItemAt(j);
    491                 if (!frame.isEmpty()) {
    492                     camera_metadata_entry_t entry;
    493                     entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
    494                     if (entry.count == 0) {
    495                         ALOGE("%s: Can't find timestamp in frame!",
    496                                 __FUNCTION__);
    497                         continue;
    498                     }
    499                     nsecs_t frameTimestamp = entry.data.i64[0];
    500                     if (bufferTimestamp == frameTimestamp) {
    501                         ALOGVV("%s: Found match %lld", __FUNCTION__,
    502                                 frameTimestamp);
    503                         match = true;
    504                     } else {
    505                         int64_t delta = abs(bufferTimestamp - frameTimestamp);
    506                         if ( delta < 1000000) {
    507                             ALOGVV("%s: Found close match %lld (delta %lld)",
    508                                     __FUNCTION__, bufferTimestamp, delta);
    509                             match = true;
    510                         }
    511                     }
    512                 }
    513                 if (match) {
    514                     queueEntry.frame.acquire(frame);
    515                     break;
    516                 }
    517             }
    518         }
    519     }
    520 }
    521 
    522 void ZslProcessor::dumpZslQueue(int fd) const {
    523     String8 header("ZSL queue contents:");
    524     String8 indent("    ");
    525     ALOGV("%s", header.string());
    526     if (fd != -1) {
    527         header = indent + header + "\n";
    528         write(fd, header.string(), header.size());
    529     }
    530     for (size_t i = 0; i < mZslQueue.size(); i++) {
    531         const ZslPair &queueEntry = mZslQueue[i];
    532         nsecs_t bufferTimestamp = queueEntry.buffer.mTimestamp;
    533         camera_metadata_ro_entry_t entry;
    534         nsecs_t frameTimestamp = 0;
    535         int frameAeState = -1;
    536         if (!queueEntry.frame.isEmpty()) {
    537             entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
    538             if (entry.count > 0) frameTimestamp = entry.data.i64[0];
    539             entry = queueEntry.frame.find(ANDROID_CONTROL_AE_STATE);
    540             if (entry.count > 0) frameAeState = entry.data.u8[0];
    541         }
    542         String8 result =
    543                 String8::format("   %d: b: %lld\tf: %lld, AE state: %d", i,
    544                         bufferTimestamp, frameTimestamp, frameAeState);
    545         ALOGV("%s", result.string());
    546         if (fd != -1) {
    547             result = indent + result + "\n";
    548             write(fd, result.string(), result.size());
    549         }
    550 
    551     }
    552 }
    553 
    554 }; // namespace camera2
    555 }; // namespace android
    556