Home | History | Annotate | Download | only in camera3
      1 /*
      2  * Copyright (C) 2013 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 "Camera3-Stream"
     18 #define ATRACE_TAG ATRACE_TAG_CAMERA
     19 //#define LOG_NDEBUG 0
     20 
     21 #include <utils/Log.h>
     22 #include <utils/Trace.h>
     23 #include "Camera3Stream.h"
     24 
     25 namespace android {
     26 
     27 namespace camera3 {
     28 
     29 Camera3Stream::~Camera3Stream() {
     30 }
     31 
     32 Camera3Stream* Camera3Stream::cast(camera3_stream *stream) {
     33     return static_cast<Camera3Stream*>(stream);
     34 }
     35 
     36 const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) {
     37     return static_cast<const Camera3Stream*>(stream);
     38 }
     39 
     40 Camera3Stream::Camera3Stream(int id,
     41         camera3_stream_type type,
     42         uint32_t width, uint32_t height, size_t maxSize, int format) :
     43     camera3_stream(),
     44     mId(id),
     45     mName(String8::format("Camera3Stream[%d]", id)),
     46     mMaxSize(maxSize),
     47     mState(STATE_CONSTRUCTED) {
     48 
     49     camera3_stream::stream_type = type;
     50     camera3_stream::width = width;
     51     camera3_stream::height = height;
     52     camera3_stream::format = format;
     53     camera3_stream::usage = 0;
     54     camera3_stream::max_buffers = 0;
     55     camera3_stream::priv = NULL;
     56 
     57     if (format == HAL_PIXEL_FORMAT_BLOB && maxSize == 0) {
     58         ALOGE("%s: BLOB format with size == 0", __FUNCTION__);
     59         mState = STATE_ERROR;
     60     }
     61 }
     62 
     63 int Camera3Stream::getId() const {
     64     return mId;
     65 }
     66 
     67 uint32_t Camera3Stream::getWidth() const {
     68     return camera3_stream::width;
     69 }
     70 
     71 uint32_t Camera3Stream::getHeight() const {
     72     return camera3_stream::height;
     73 }
     74 
     75 int Camera3Stream::getFormat() const {
     76     return camera3_stream::format;
     77 }
     78 
     79 camera3_stream* Camera3Stream::startConfiguration() {
     80     Mutex::Autolock l(mLock);
     81 
     82     switch (mState) {
     83         case STATE_ERROR:
     84             ALOGE("%s: In error state", __FUNCTION__);
     85             return NULL;
     86         case STATE_CONSTRUCTED:
     87             // OK
     88             break;
     89         case STATE_IN_CONFIG:
     90         case STATE_IN_RECONFIG:
     91             // Can start config again with no trouble; but don't redo
     92             // oldUsage/oldMaxBuffers
     93             return this;
     94         case STATE_CONFIGURED:
     95             if (stream_type == CAMERA3_STREAM_INPUT) {
     96                 ALOGE("%s: Cannot configure an input stream twice",
     97                         __FUNCTION__);
     98                 return NULL;
     99             } else if (hasOutstandingBuffersLocked()) {
    100                 ALOGE("%s: Cannot configure stream; has outstanding buffers",
    101                         __FUNCTION__);
    102                 return NULL;
    103             }
    104             break;
    105         default:
    106             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
    107             return NULL;
    108     }
    109 
    110     oldUsage = usage;
    111     oldMaxBuffers = max_buffers;
    112 
    113     if (mState == STATE_CONSTRUCTED) {
    114         mState = STATE_IN_CONFIG;
    115     } else { // mState == STATE_CONFIGURED
    116         mState = STATE_IN_RECONFIG;
    117     }
    118 
    119     return this;
    120 }
    121 
    122 bool Camera3Stream::isConfiguring() const {
    123     Mutex::Autolock l(mLock);
    124     return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
    125 }
    126 
    127 status_t Camera3Stream::finishConfiguration(camera3_device *hal3Device) {
    128     Mutex::Autolock l(mLock);
    129     switch (mState) {
    130         case STATE_ERROR:
    131             ALOGE("%s: In error state", __FUNCTION__);
    132             return INVALID_OPERATION;
    133         case STATE_IN_CONFIG:
    134         case STATE_IN_RECONFIG:
    135             // OK
    136             break;
    137         case STATE_CONSTRUCTED:
    138         case STATE_CONFIGURED:
    139             ALOGE("%s: Cannot finish configuration that hasn't been started",
    140                     __FUNCTION__);
    141             return INVALID_OPERATION;
    142         default:
    143             ALOGE("%s: Unknown state", __FUNCTION__);
    144             return INVALID_OPERATION;
    145     }
    146 
    147     // Check if the stream configuration is unchanged, and skip reallocation if
    148     // so. As documented in hardware/camera3.h:configure_streams().
    149     if (mState == STATE_IN_RECONFIG &&
    150             oldUsage == usage &&
    151             oldMaxBuffers == max_buffers) {
    152         mState = STATE_CONFIGURED;
    153         return OK;
    154     }
    155 
    156     status_t res;
    157     res = configureQueueLocked();
    158     if (res != OK) {
    159         ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
    160                 __FUNCTION__, mId, strerror(-res), res);
    161         mState = STATE_ERROR;
    162         return res;
    163     }
    164 
    165     res = registerBuffersLocked(hal3Device);
    166     if (res != OK) {
    167         ALOGE("%s: Unable to register stream buffers with HAL: %s (%d)",
    168                 __FUNCTION__, strerror(-res), res);
    169         mState = STATE_ERROR;
    170         return res;
    171     }
    172 
    173     mState = STATE_CONFIGURED;
    174 
    175     return res;
    176 }
    177 
    178 status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) {
    179     ATRACE_CALL();
    180     Mutex::Autolock l(mLock);
    181 
    182     status_t res = getBufferLocked(buffer);
    183     if (res == OK) {
    184         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
    185     }
    186 
    187     return res;
    188 }
    189 
    190 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
    191         nsecs_t timestamp) {
    192     ATRACE_CALL();
    193     Mutex::Autolock l(mLock);
    194 
    195     status_t res = returnBufferLocked(buffer, timestamp);
    196     if (res == OK) {
    197         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
    198     }
    199 
    200     return res;
    201 }
    202 
    203 status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) {
    204     ATRACE_CALL();
    205     Mutex::Autolock l(mLock);
    206 
    207     status_t res = getInputBufferLocked(buffer);
    208     if (res == OK) {
    209         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
    210     }
    211 
    212     return res;
    213 }
    214 
    215 status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) {
    216     ATRACE_CALL();
    217     Mutex::Autolock l(mLock);
    218 
    219     status_t res = returnInputBufferLocked(buffer);
    220     if (res == OK) {
    221         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
    222     }
    223     return res;
    224 }
    225 
    226 void Camera3Stream::fireBufferListenersLocked(
    227         const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) {
    228     List<wp<Camera3StreamBufferListener> >::iterator it, end;
    229 
    230     // TODO: finish implementing
    231 
    232     Camera3StreamBufferListener::BufferInfo info =
    233         Camera3StreamBufferListener::BufferInfo();
    234     info.mOutput = output;
    235     // TODO: rest of fields
    236 
    237     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
    238          it != end;
    239          ++it) {
    240 
    241         sp<Camera3StreamBufferListener> listener = it->promote();
    242         if (listener != 0) {
    243             if (acquired) {
    244                 listener->onBufferAcquired(info);
    245             } else {
    246                 listener->onBufferReleased(info);
    247             }
    248         }
    249     }
    250 }
    251 
    252 bool Camera3Stream::hasOutstandingBuffers() const {
    253     ATRACE_CALL();
    254     Mutex::Autolock l(mLock);
    255     return hasOutstandingBuffersLocked();
    256 }
    257 
    258 status_t Camera3Stream::disconnect() {
    259     ATRACE_CALL();
    260     Mutex::Autolock l(mLock);
    261     ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
    262     status_t res = disconnectLocked();
    263 
    264     if (res == -ENOTCONN) {
    265         // "Already disconnected" -- not an error
    266         return OK;
    267     } else {
    268         return res;
    269     }
    270 }
    271 
    272 status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) {
    273     ATRACE_CALL();
    274     status_t res;
    275 
    276     size_t bufferCount = getBufferCountLocked();
    277 
    278     Vector<buffer_handle_t*> buffers;
    279     buffers.insertAt(NULL, 0, bufferCount);
    280 
    281     camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set();
    282     bufferSet.stream = this;
    283     bufferSet.num_buffers = bufferCount;
    284     bufferSet.buffers = buffers.editArray();
    285 
    286     Vector<camera3_stream_buffer_t> streamBuffers;
    287     streamBuffers.insertAt(camera3_stream_buffer_t(), 0, bufferCount);
    288 
    289     // Register all buffers with the HAL. This means getting all the buffers
    290     // from the stream, providing them to the HAL with the
    291     // register_stream_buffers() method, and then returning them back to the
    292     // stream in the error state, since they won't have valid data.
    293     //
    294     // Only registered buffers can be sent to the HAL.
    295 
    296     uint32_t bufferIdx = 0;
    297     for (; bufferIdx < bufferCount; bufferIdx++) {
    298         res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) );
    299         if (res != OK) {
    300             ALOGE("%s: Unable to get buffer %d for registration with HAL",
    301                     __FUNCTION__, bufferIdx);
    302             // Skip registering, go straight to cleanup
    303             break;
    304         }
    305 
    306         sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence);
    307         fence->waitForever("Camera3Stream::registerBuffers");
    308 
    309         buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer;
    310     }
    311     if (bufferIdx == bufferCount) {
    312         // Got all buffers, register with HAL
    313         ALOGV("%s: Registering %d buffers with camera HAL",
    314                 __FUNCTION__, bufferCount);
    315         res = hal3Device->ops->register_stream_buffers(hal3Device,
    316                 &bufferSet);
    317     }
    318 
    319     // Return all valid buffers to stream, in ERROR state to indicate
    320     // they weren't filled.
    321     for (size_t i = 0; i < bufferIdx; i++) {
    322         streamBuffers.editItemAt(i).release_fence = -1;
    323         streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
    324         returnBufferLocked(streamBuffers[i], 0);
    325     }
    326 
    327     return res;
    328 }
    329 
    330 status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) {
    331     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
    332     return INVALID_OPERATION;
    333 }
    334 status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &,
    335                                            nsecs_t) {
    336     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
    337     return INVALID_OPERATION;
    338 }
    339 status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) {
    340     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
    341     return INVALID_OPERATION;
    342 }
    343 status_t Camera3Stream::returnInputBufferLocked(
    344         const camera3_stream_buffer &) {
    345     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
    346     return INVALID_OPERATION;
    347 }
    348 
    349 void Camera3Stream::addBufferListener(
    350         wp<Camera3StreamBufferListener> listener) {
    351     Mutex::Autolock l(mLock);
    352     mBufferListenerList.push_back(listener);
    353 }
    354 
    355 void Camera3Stream::removeBufferListener(
    356         const sp<Camera3StreamBufferListener>& listener) {
    357     Mutex::Autolock l(mLock);
    358 
    359     bool erased = true;
    360     List<wp<Camera3StreamBufferListener> >::iterator it, end;
    361     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
    362          it != end;
    363          ) {
    364 
    365         if (*it == listener) {
    366             it = mBufferListenerList.erase(it);
    367             erased = true;
    368         } else {
    369             ++it;
    370         }
    371     }
    372 
    373     if (!erased) {
    374         ALOGW("%s: Could not find listener to remove, already removed",
    375               __FUNCTION__);
    376     }
    377 }
    378 
    379 }; // namespace camera3
    380 
    381 }; // namespace android
    382