• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Camera3SharedOutputStream(int id,const std::vector<sp<Surface>> & surfaces,uint32_t width,uint32_t height,int format,uint64_t consumerUsage,android_dataspace dataSpace,camera3_stream_rotation_t rotation,nsecs_t timestampOffset,int setId)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 
~Camera3SharedOutputStream()35 Camera3SharedOutputStream::~Camera3SharedOutputStream() {
36     disconnectLocked();
37 }
38 
connectStreamSplitterLocked()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 
notifyBufferReleased(ANativeWindowBuffer * anwBuffer)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 
isConsumerConfigurationDeferred(size_t surface_id) const69 bool Camera3SharedOutputStream::isConsumerConfigurationDeferred(size_t surface_id) const {
70     Mutex::Autolock l(mLock);
71     return (surface_id >= mSurfaces.size());
72 }
73 
setConsumers(const std::vector<sp<Surface>> & surfaces)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 
getBufferLocked(camera3_stream_buffer * buffer,const std::vector<size_t> & surface_ids)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 
queueBufferToConsumer(sp<ANativeWindow> & consumer,ANativeWindowBuffer * buffer,int anwReleaseFence)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 
configureQueueLocked()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 
disconnectLocked()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 
getEndpointUsage(uint64_t * usage) const194 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