Home | History | Annotate | Download | only in device3
      1 /*
      2  * Copyright (C) 2016 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 #include "Camera3SharedOutputStream.h"
     18 
     19 namespace android {
     20 
     21 namespace camera3 {
     22 
     23 Camera3SharedOutputStream::Camera3SharedOutputStream(int id,
     24         const std::vector<sp<Surface>>& surfaces,
     25         uint32_t width, uint32_t height, int format,
     26         uint64_t consumerUsage, android_dataspace dataSpace,
     27         camera3_stream_rotation_t rotation,
     28         nsecs_t timestampOffset, int setId) :
     29         Camera3OutputStream(id, CAMERA3_STREAM_OUTPUT, width, height,
     30                             format, dataSpace, rotation, consumerUsage,
     31                             timestampOffset, setId),
     32         mSurfaces(surfaces) {
     33 }
     34 
     35 Camera3SharedOutputStream::~Camera3SharedOutputStream() {
     36     disconnectLocked();
     37 }
     38 
     39 status_t Camera3SharedOutputStream::connectStreamSplitterLocked() {
     40     status_t res = OK;
     41 
     42     mStreamSplitter = new Camera3StreamSplitter();
     43 
     44     uint64_t usage;
     45     getEndpointUsage(&usage);
     46 
     47     res = mStreamSplitter->connect(mSurfaces, usage, camera3_stream::max_buffers, &mConsumer);
     48     if (res != OK) {
     49         ALOGE("%s: Failed to connect to stream splitter: %s(%d)",
     50                 __FUNCTION__, strerror(-res), res);
     51         return res;
     52     }
     53 
     54     return res;
     55 }
     56 
     57 status_t Camera3SharedOutputStream::notifyBufferReleased(ANativeWindowBuffer *anwBuffer) {
     58     Mutex::Autolock l(mLock);
     59     status_t res = OK;
     60     const sp<GraphicBuffer> buffer(static_cast<GraphicBuffer*>(anwBuffer));
     61 
     62     if (mStreamSplitter != nullptr) {
     63         res = mStreamSplitter->notifyBufferReleased(buffer);
     64     }
     65 
     66     return res;
     67 }
     68 
     69 bool Camera3SharedOutputStream::isConsumerConfigurationDeferred(size_t surface_id) const {
     70     Mutex::Autolock l(mLock);
     71     return (surface_id >= mSurfaces.size());
     72 }
     73 
     74 status_t Camera3SharedOutputStream::setConsumers(const std::vector<sp<Surface>>& surfaces) {
     75     Mutex::Autolock l(mLock);
     76     if (surfaces.size() == 0) {
     77         ALOGE("%s: it's illegal to set zero consumer surfaces!", __FUNCTION__);
     78         return INVALID_OPERATION;
     79     }
     80 
     81     status_t ret = OK;
     82     for (auto& surface : surfaces) {
     83         if (surface == nullptr) {
     84             ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
     85             return INVALID_OPERATION;
     86         }
     87 
     88         mSurfaces.push_back(surface);
     89 
     90         // Only call addOutput if the splitter has been connected.
     91         if (mStreamSplitter != nullptr) {
     92             ret = mStreamSplitter->addOutput(surface);
     93             if (ret != OK) {
     94                 ALOGE("%s: addOutput failed with error code %d", __FUNCTION__, ret);
     95                 return ret;
     96 
     97             }
     98         }
     99     }
    100     return ret;
    101 }
    102 
    103 status_t Camera3SharedOutputStream::getBufferLocked(camera3_stream_buffer *buffer,
    104         const std::vector<size_t>& surface_ids) {
    105     ANativeWindowBuffer* anb;
    106     int fenceFd = -1;
    107 
    108     status_t res;
    109     res = getBufferLockedCommon(&anb, &fenceFd);
    110     if (res != OK) {
    111         return res;
    112     }
    113 
    114     // Attach the buffer to the splitter output queues. This could block if
    115     // the output queue doesn't have any empty slot. So unlock during the course
    116     // of attachBufferToOutputs.
    117     sp<Camera3StreamSplitter> splitter = mStreamSplitter;
    118     mLock.unlock();
    119     res = splitter->attachBufferToOutputs(anb, surface_ids);
    120     mLock.lock();
    121     if (res != OK) {
    122         ALOGE("%s: Stream %d: Cannot attach stream splitter buffer to outputs: %s (%d)",
    123                 __FUNCTION__, mId, strerror(-res), res);
    124         // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
    125         // let prepareNextBuffer handle the error.)
    126         if (res == NO_INIT && mState == STATE_CONFIGURED) {
    127             mState = STATE_ABANDONED;
    128         }
    129 
    130         return res;
    131     }
    132 
    133     /**
    134      * FenceFD now owned by HAL except in case of error,
    135      * in which case we reassign it to acquire_fence
    136      */
    137     handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
    138                         /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
    139 
    140     return OK;
    141 }
    142 
    143 status_t Camera3SharedOutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
    144             ANativeWindowBuffer* buffer, int anwReleaseFence) {
    145     status_t res = consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
    146 
    147     // After queuing buffer to the internal consumer queue, check whether the buffer is
    148     // successfully queued to the output queues.
    149     if (res == OK) {
    150         res = mStreamSplitter->getOnFrameAvailableResult();
    151         if (res != OK) {
    152             ALOGE("%s: getOnFrameAvailable returns %d", __FUNCTION__, res);
    153         }
    154     } else {
    155         ALOGE("%s: queueBufer failed %d", __FUNCTION__, res);
    156     }
    157 
    158     return res;
    159 }
    160 
    161 status_t Camera3SharedOutputStream::configureQueueLocked() {
    162     status_t res;
    163 
    164     if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
    165         return res;
    166     }
    167 
    168     res = connectStreamSplitterLocked();
    169     if (res != OK) {
    170         ALOGE("Cannot connect to stream splitter: %s(%d)", strerror(-res), res);
    171         return res;
    172     }
    173 
    174     res = configureConsumerQueueLocked();
    175     if (res != OK) {
    176         ALOGE("Failed to configureConsumerQueueLocked: %s(%d)", strerror(-res), res);
    177         return res;
    178     }
    179 
    180     return OK;
    181 }
    182 
    183 status_t Camera3SharedOutputStream::disconnectLocked() {
    184     status_t res;
    185     res = Camera3OutputStream::disconnectLocked();
    186 
    187     if (mStreamSplitter != nullptr) {
    188         mStreamSplitter->disconnect();
    189     }
    190 
    191     return res;
    192 }
    193 
    194 status_t Camera3SharedOutputStream::getEndpointUsage(uint64_t *usage) const {
    195 
    196     status_t res = OK;
    197     uint64_t u = 0;
    198 
    199     if (mConsumer == nullptr) {
    200         // Called before shared buffer queue is constructed.
    201         *usage = getPresetConsumerUsage();
    202 
    203         for (auto surface : mSurfaces) {
    204             if (surface != nullptr) {
    205                 res = getEndpointUsageForSurface(&u, surface);
    206                 *usage |= u;
    207             }
    208         }
    209     } else {
    210         // Called after shared buffer queue is constructed.
    211         res = getEndpointUsageForSurface(&u, mConsumer);
    212         *usage |= u;
    213     }
    214 
    215     return res;
    216 }
    217 
    218 } // namespace camera3
    219 
    220 } // namespace android
    221