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