xref: /aosp_15_r20/frameworks/av/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2016-2018 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-SharedOuStrm"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 
21 #include <utils/Trace.h>
22 
23 #include "Flags.h"
24 
25 #include "Camera3SharedOutputStream.h"
26 
27 namespace android {
28 
29 namespace camera3 {
30 
31 const size_t Camera3SharedOutputStream::kMaxOutputs;
32 
Camera3SharedOutputStream(int id,const std::vector<SurfaceHolder> & surfaces,uint32_t width,uint32_t height,int format,uint64_t consumerUsage,android_dataspace dataSpace,camera_stream_rotation_t rotation,nsecs_t timestampOffset,const std::string & physicalCameraId,const std::unordered_set<int32_t> & sensorPixelModesUsed,IPCTransport transport,int setId,bool useHalBufManager,int64_t dynamicProfile,int64_t streamUseCase,bool deviceTimeBaseIsRealtime,int timestampBase,int32_t colorSpace,bool useReadoutTimestamp)33 Camera3SharedOutputStream::Camera3SharedOutputStream(int id,
34         const std::vector<SurfaceHolder>& surfaces,
35         uint32_t width, uint32_t height, int format,
36         uint64_t consumerUsage, android_dataspace dataSpace,
37         camera_stream_rotation_t rotation,
38         nsecs_t timestampOffset, const std::string& physicalCameraId,
39         const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
40         int setId, bool useHalBufManager, int64_t dynamicProfile,
41         int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
42         int32_t colorSpace, bool useReadoutTimestamp) :
43         Camera3OutputStream(id, CAMERA_STREAM_OUTPUT, width, height,
44                             format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
45                             transport, consumerUsage, timestampOffset, setId,
46                             /*isMultiResolution*/false, dynamicProfile, streamUseCase,
47                             deviceTimeBaseIsRealtime, timestampBase, colorSpace,
48                             useReadoutTimestamp),
49         mUseHalBufManager(useHalBufManager) {
50     size_t consumerCount = std::min(surfaces.size(), kMaxOutputs);
51     if (surfaces.size() > consumerCount) {
52         ALOGE("%s: Trying to add more consumers than the maximum ", __func__);
53     }
54     for (size_t i = 0; i < consumerCount; i++) {
55         mSurfaceUniqueIds[i] = SurfaceHolderUniqueId{surfaces[i], mNextUniqueSurfaceId++};
56     }
57 }
58 
~Camera3SharedOutputStream()59 Camera3SharedOutputStream::~Camera3SharedOutputStream() {
60     disconnectLocked();
61 }
62 
connectStreamSplitterLocked()63 status_t Camera3SharedOutputStream::connectStreamSplitterLocked() {
64     status_t res = OK;
65 
66 #if USE_NEW_STREAM_SPLITTER
67     mStreamSplitter = sp<Camera3StreamSplitter>::make(mUseHalBufManager);
68 #else
69     mStreamSplitter = sp<DeprecatedCamera3StreamSplitter>::make(mUseHalBufManager);
70 #endif  // USE_NEW_STREAM_SPLITTER
71 
72     uint64_t usage = 0;
73     getEndpointUsage(&usage);
74 
75     std::unordered_map<size_t, sp<Surface>> initialSurfaces;
76     for (size_t i = 0; i < kMaxOutputs; i++) {
77         if (mSurfaceUniqueIds[i].mSurfaceHolder.mSurface != nullptr) {
78             initialSurfaces.emplace(i, mSurfaceUniqueIds[i].mSurfaceHolder.mSurface);
79         }
80     }
81 
82     res = mStreamSplitter->connect(initialSurfaces, usage, mUsage, camera_stream::max_buffers,
83             getWidth(), getHeight(), getFormat(), &mConsumer, camera_stream::dynamic_range_profile);
84     if (res != OK) {
85         ALOGE("%s: Failed to connect to stream splitter: %s(%d)",
86                 __FUNCTION__, strerror(-res), res);
87         return res;
88     }
89 
90     return res;
91 }
92 
attachBufferToSplitterLocked(ANativeWindowBuffer * anb,const std::vector<size_t> & surface_ids)93 status_t Camera3SharedOutputStream::attachBufferToSplitterLocked(
94         ANativeWindowBuffer* anb,
95         const std::vector<size_t>& surface_ids) {
96     status_t res = OK;
97 
98     // Attach the buffer to the splitter output queues. This could block if
99     // the output queue doesn't have any empty slot. So unlock during the course
100     // of attachBufferToOutputs.
101 #if USE_NEW_STREAM_SPLITTER
102     sp<Camera3StreamSplitter> splitter = mStreamSplitter;
103 #else
104     sp<DeprecatedCamera3StreamSplitter> splitter = mStreamSplitter;
105 #endif  // USE_NEW_STREAM_SPLITTER
106     mLock.unlock();
107     res = splitter->attachBufferToOutputs(anb, surface_ids);
108     mLock.lock();
109     if (res != OK) {
110         ALOGE("%s: Stream %d: Cannot attach stream splitter buffer to outputs: %s (%d)",
111                 __FUNCTION__, mId, strerror(-res), res);
112         // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
113         // let prepareNextBuffer handle the error.)
114         if (res == NO_INIT && mState == STATE_CONFIGURED) {
115             mState = STATE_ABANDONED;
116         }
117     }
118     return res;
119 }
120 
setHalBufferManager(bool enabled)121 void Camera3SharedOutputStream::setHalBufferManager(bool enabled) {
122     Mutex::Autolock l(mLock);
123     mUseHalBufManager = enabled;
124     if (mStreamSplitter != nullptr) {
125         mStreamSplitter->setHalBufferManager(enabled);
126     }
127 }
128 
notifyBufferReleased(ANativeWindowBuffer * anwBuffer)129 status_t Camera3SharedOutputStream::notifyBufferReleased(ANativeWindowBuffer *anwBuffer) {
130     Mutex::Autolock l(mLock);
131     status_t res = OK;
132     const sp<GraphicBuffer> buffer(static_cast<GraphicBuffer*>(anwBuffer));
133 
134     if (mStreamSplitter != nullptr) {
135         res = mStreamSplitter->notifyBufferReleased(buffer);
136     }
137 
138     return res;
139 }
140 
isConsumerConfigurationDeferred(size_t surface_id) const141 bool Camera3SharedOutputStream::isConsumerConfigurationDeferred(size_t surface_id) const {
142     Mutex::Autolock l(mLock);
143     if (surface_id >= kMaxOutputs) {
144         return true;
145     }
146 
147     return (mSurfaceUniqueIds[surface_id].mSurfaceHolder.mSurface == nullptr);
148 }
149 
setConsumers(const std::vector<SurfaceHolder> & surfaceHolders)150 status_t Camera3SharedOutputStream::setConsumers(const std::vector<SurfaceHolder>& surfaceHolders) {
151     Mutex::Autolock l(mLock);
152     if (surfaceHolders.size() == 0) {
153         ALOGE("%s: it's illegal to set zero consumer surfaces!", __FUNCTION__);
154         return INVALID_OPERATION;
155     }
156 
157     status_t ret = OK;
158     for (auto& surfaceHolder : surfaceHolders) {
159         if (surfaceHolder.mSurface == nullptr) {
160             ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
161             return INVALID_OPERATION;
162         }
163 
164         ssize_t id = getNextSurfaceIdLocked();
165         if (id < 0) {
166             ALOGE("%s: No surface ids available!", __func__);
167             return NO_MEMORY;
168         }
169 
170         mSurfaceUniqueIds[id] = SurfaceHolderUniqueId{surfaceHolder, mNextUniqueSurfaceId++};
171 
172         // Only call addOutput if the splitter has been connected.
173         if (mStreamSplitter != nullptr) {
174             ret = mStreamSplitter->addOutput(id, surfaceHolder.mSurface);
175             if (ret != OK) {
176                 ALOGE("%s: addOutput failed with error code %d", __FUNCTION__, ret);
177                 return ret;
178 
179             }
180         }
181     }
182     return ret;
183 }
184 
getBufferLocked(camera_stream_buffer * buffer,const std::vector<size_t> & surfaceIds)185 status_t Camera3SharedOutputStream::getBufferLocked(camera_stream_buffer *buffer,
186         const std::vector<size_t>& surfaceIds) {
187     ANativeWindowBuffer* anb;
188     int fenceFd = -1;
189 
190     status_t res;
191     res = getBufferLockedCommon(&anb, &fenceFd);
192     if (res != OK) {
193         return res;
194     }
195 
196     if (!mUseHalBufManager) {
197         res = attachBufferToSplitterLocked(anb, surfaceIds);
198         if (res != OK) {
199             return res;
200         }
201     }
202 
203     /**
204      * FenceFD now owned by HAL except in case of error,
205      * in which case we reassign it to acquire_fence
206      */
207     handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
208                         /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true);
209 
210     return OK;
211 }
212 
queueBufferToConsumer(sp<ANativeWindow> & consumer,ANativeWindowBuffer * buffer,int anwReleaseFence,const std::vector<size_t> & uniqueSurfaceIds)213 status_t Camera3SharedOutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
214             ANativeWindowBuffer* buffer, int anwReleaseFence,
215             const std::vector<size_t>& uniqueSurfaceIds) {
216     status_t res = OK;
217     if (mUseHalBufManager) {
218         if (uniqueSurfaceIds.size() == 0) {
219             ALOGE("%s: uniqueSurfaceIds must not be empty!", __FUNCTION__);
220             return BAD_VALUE;
221         }
222         Mutex::Autolock l(mLock);
223         std::vector<size_t> surfaceIds;
224         for (const auto& uniqueId : uniqueSurfaceIds) {
225             bool uniqueIdFound = false;
226             for (size_t i = 0; i < kMaxOutputs; i++) {
227                 if (mSurfaceUniqueIds[i].mId == uniqueId) {
228                     surfaceIds.push_back(i);
229                     uniqueIdFound = true;
230                     break;
231                 }
232             }
233             if (!uniqueIdFound) {
234                 ALOGV("%s: unknown unique surface ID %zu for stream %d: "
235                         "output might have been removed.",
236                         __FUNCTION__, uniqueId, mId);
237             }
238         }
239         res = attachBufferToSplitterLocked(buffer, surfaceIds);
240         if (res != OK) {
241             return res;
242         }
243     }
244 
245     res = consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
246 
247     // After queuing buffer to the internal consumer queue, check whether the buffer is
248     // successfully queued to the output queues.
249     if (res == OK) {
250         res = mStreamSplitter->getOnFrameAvailableResult();
251         if (res != OK) {
252             ALOGE("%s: getOnFrameAvailable returns %d", __FUNCTION__, res);
253         }
254     } else {
255         ALOGE("%s: queueBufer failed %d", __FUNCTION__, res);
256     }
257 
258     return res;
259 }
260 
configureQueueLocked()261 status_t Camera3SharedOutputStream::configureQueueLocked() {
262     status_t res;
263 
264     if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
265         return res;
266     }
267 
268     res = connectStreamSplitterLocked();
269     if (res != OK) {
270         ALOGE("Cannot connect to stream splitter: %s(%d)", strerror(-res), res);
271         return res;
272     }
273 
274     res = configureConsumerQueueLocked(false/*allowPreviewRespace*/);
275     if (res != OK) {
276         ALOGE("Failed to configureConsumerQueueLocked: %s(%d)", strerror(-res), res);
277         return res;
278     }
279 
280     // Set buffer transform for all configured surfaces
281     for (const auto& surfaceUniqueId : mSurfaceUniqueIds) {
282         const sp<Surface>& surface = surfaceUniqueId.mSurfaceHolder.mSurface;
283         int surfaceId = surfaceUniqueId.mId;
284         int32_t transform = surfaceUniqueId.mTransform;
285         if (transform == -1 || surface == nullptr) {
286             continue;
287         }
288 
289         res = mStreamSplitter->setTransform(surfaceId, transform);
290         if (res != OK) {
291             ALOGE("%s: StreamSplitter failed to setTransform: %s(%d)",
292                     __FUNCTION__, strerror(-res), res);
293             return res;
294         }
295     }
296 
297     return OK;
298 }
299 
disconnectLocked()300 status_t Camera3SharedOutputStream::disconnectLocked() {
301     status_t res;
302     res = Camera3OutputStream::disconnectLocked();
303 
304     if (mStreamSplitter != nullptr) {
305         mStreamSplitter->disconnect();
306     }
307 
308     return res;
309 }
310 
getEndpointUsage(uint64_t * usage)311 status_t Camera3SharedOutputStream::getEndpointUsage(uint64_t *usage) {
312 
313     status_t res = OK;
314     uint64_t u = 0;
315 
316     if (mConsumer == nullptr) {
317         // Called before shared buffer queue is constructed.
318         *usage = getPresetConsumerUsage();
319 
320         for (size_t id = 0; id < kMaxOutputs; id++) {
321             const auto& surface = mSurfaceUniqueIds[id].mSurfaceHolder.mSurface;
322             if (surface != nullptr) {
323                 res = getEndpointUsageForSurface(&u, surface);
324                 *usage |= u;
325             }
326         }
327     } else {
328         // Called after shared buffer queue is constructed.
329         res = getEndpointUsageForSurface(&u, mConsumer);
330         *usage |= u;
331     }
332 
333     return res;
334 }
335 
getNextSurfaceIdLocked()336 ssize_t Camera3SharedOutputStream::getNextSurfaceIdLocked() {
337     ssize_t id = -1;
338     for (size_t i = 0; i < kMaxOutputs; i++) {
339         if (mSurfaceUniqueIds[i].mSurfaceHolder.mSurface == nullptr) {
340             id = i;
341             break;
342         }
343     }
344 
345     return id;
346 }
347 
getSurfaceId(const sp<Surface> & surface)348 ssize_t Camera3SharedOutputStream::getSurfaceId(const sp<Surface> &surface) {
349     Mutex::Autolock l(mLock);
350     ssize_t id = -1;
351     for (size_t i = 0; i < kMaxOutputs; i++) {
352         if (mSurfaceUniqueIds[i].mSurfaceHolder.mSurface == surface) {
353             id = i;
354             break;
355         }
356     }
357 
358     return id;
359 }
360 
getUniqueSurfaceIds(const std::vector<size_t> & surfaceIds,std::vector<size_t> * outUniqueIds)361 status_t Camera3SharedOutputStream::getUniqueSurfaceIds(
362         const std::vector<size_t>& surfaceIds,
363         /*out*/std::vector<size_t>* outUniqueIds) {
364     Mutex::Autolock l(mLock);
365     if (outUniqueIds == nullptr || surfaceIds.size() > kMaxOutputs) {
366         return BAD_VALUE;
367     }
368 
369     outUniqueIds->clear();
370     outUniqueIds->reserve(surfaceIds.size());
371 
372     for (const auto& surfaceId : surfaceIds) {
373         if (surfaceId >= kMaxOutputs) {
374             return BAD_VALUE;
375         }
376         outUniqueIds->push_back(mSurfaceUniqueIds[surfaceId].mId);
377     }
378     return OK;
379 }
380 
revertPartialUpdateLocked(const KeyedVector<size_t,SurfaceHolder> & removedSurfaces,const KeyedVector<sp<Surface>,size_t> & attachedSurfaces)381 status_t Camera3SharedOutputStream::revertPartialUpdateLocked(
382         const KeyedVector<size_t, SurfaceHolder> &removedSurfaces,
383         const KeyedVector<sp<Surface>, size_t> &attachedSurfaces) {
384     status_t ret = OK;
385 
386     for (size_t i = 0; i < attachedSurfaces.size(); i++) {
387         size_t index = attachedSurfaces.valueAt(i);
388         if (mStreamSplitter != nullptr) {
389             ret = mStreamSplitter->removeOutput(index);
390             if (ret != OK) {
391                 return UNKNOWN_ERROR;
392             }
393         }
394         mSurfaceUniqueIds[index] = SurfaceHolderUniqueId{mNextUniqueSurfaceId++};
395     }
396 
397     for (size_t i = 0; i < removedSurfaces.size(); i++) {
398         size_t index = removedSurfaces.keyAt(i);
399         if (mStreamSplitter != nullptr) {
400             ret = mStreamSplitter->addOutput(index, removedSurfaces.valueAt(i).mSurface);
401             if (ret != OK) {
402                 return UNKNOWN_ERROR;
403             }
404         }
405         mSurfaceUniqueIds[index] = SurfaceHolderUniqueId{removedSurfaces.valueAt(i),
406                 mNextUniqueSurfaceId++};
407     }
408 
409     return ret;
410 }
411 
updateStream(const std::vector<SurfaceHolder> & outputSurfaces,const std::vector<OutputStreamInfo> & outputInfo,const std::vector<size_t> & removedSurfaceIds,KeyedVector<sp<Surface>,size_t> * outputMap)412 status_t Camera3SharedOutputStream::updateStream(const std::vector<SurfaceHolder> &outputSurfaces,
413         const std::vector<OutputStreamInfo> &outputInfo,
414         const std::vector<size_t> &removedSurfaceIds,
415         KeyedVector<sp<Surface>, size_t> *outputMap) {
416     status_t ret = OK;
417     Mutex::Autolock l(mLock);
418 
419     if ((outputMap == nullptr) || (outputInfo.size() != outputSurfaces.size()) ||
420             (outputSurfaces.size() > kMaxOutputs)) {
421         return BAD_VALUE;
422     }
423 
424     uint64_t usage;
425     getEndpointUsage(&usage);
426     KeyedVector<size_t, SurfaceHolder> removedSurfaces;
427     //Check whether the new surfaces are compatible.
428     for (const auto &infoIt : outputInfo) {
429         bool imgReaderUsage = (infoIt.consumerUsage & GRALLOC_USAGE_SW_READ_OFTEN) ? true : false;
430         bool sizeMismatch = ((static_cast<uint32_t>(infoIt.width) != getWidth()) ||
431                                 (static_cast<uint32_t> (infoIt.height) != getHeight())) ?
432                                 true : false;
433         bool dynamicRangeMismatch = dynamic_range_profile != infoIt.dynamicRangeProfile;
434         if ((imgReaderUsage && sizeMismatch) || dynamicRangeMismatch ||
435                 (infoIt.format != getOriginalFormat() && infoIt.format != getFormat()) ||
436                 (infoIt.dataSpace != getDataSpace() &&
437                  infoIt.dataSpace != getOriginalDataSpace())) {
438             ALOGE("%s: Shared surface parameters format: 0x%x dataSpace: 0x%x dynamic range 0x%"
439                     PRIx64 " don't match source stream format: 0x%x  dataSpace: 0x%x dynamic"
440                     " range 0x%" PRIx64 , __FUNCTION__, infoIt.format, infoIt.dataSpace,
441                     infoIt.dynamicRangeProfile, getFormat(), getDataSpace(), dynamic_range_profile);
442             return BAD_VALUE;
443         }
444     }
445 
446     //First remove all absent outputs
447     for (const auto &it : removedSurfaceIds) {
448         if (mStreamSplitter != nullptr) {
449             ret = mStreamSplitter->removeOutput(it);
450             if (ret != OK) {
451                 ALOGE("%s: failed with error code %d", __FUNCTION__, ret);
452                 status_t res = revertPartialUpdateLocked(removedSurfaces, *outputMap);
453                 if (res != OK) {
454                     return res;
455                 }
456                 return ret;
457 
458             }
459         }
460         removedSurfaces.add(it, mSurfaceUniqueIds[it].mSurfaceHolder);
461         mSurfaceUniqueIds[it] = SurfaceHolderUniqueId{mNextUniqueSurfaceId++};
462     }
463 
464     //Next add the new outputs
465     for (const auto &it : outputSurfaces) {
466         ssize_t surfaceId = getNextSurfaceIdLocked();
467         if (surfaceId < 0) {
468             ALOGE("%s: No more available output slots!", __FUNCTION__);
469             status_t res = revertPartialUpdateLocked(removedSurfaces, *outputMap);
470             if (res != OK) {
471                 return res;
472             }
473             return NO_MEMORY;
474         }
475         if (mStreamSplitter != nullptr) {
476             ret = mStreamSplitter->addOutput(surfaceId, it.mSurface);
477             if (ret != OK) {
478                 ALOGE("%s: failed with error code %d", __FUNCTION__, ret);
479                 status_t res = revertPartialUpdateLocked(removedSurfaces, *outputMap);
480                 if (res != OK) {
481                     return res;
482                 }
483                 return ret;
484             }
485         }
486         mSurfaceUniqueIds[surfaceId] = SurfaceHolderUniqueId{it, mNextUniqueSurfaceId++};
487         outputMap->add(it.mSurface, surfaceId);
488     }
489 
490     return ret;
491 }
492 
setTransform(int transform,bool mayChangeMirror,int surfaceId)493 status_t Camera3SharedOutputStream::setTransform(
494         int transform, bool mayChangeMirror, int surfaceId) {
495     ATRACE_CALL();
496     Mutex::Autolock l(mLock);
497 
498     status_t res = OK;
499 
500     if (surfaceId < 0 || (size_t)surfaceId >= mSurfaceUniqueIds.size()) {
501         ALOGE("%s: Invalid surfaceId %d", __FUNCTION__, surfaceId);
502         return BAD_VALUE;
503     }
504     if (transform == -1) return res;
505 
506     if (mState == STATE_ERROR) {
507         ALOGE("%s: Stream in error state", __FUNCTION__);
508         return INVALID_OPERATION;
509     }
510 
511     auto& surfaceHolderForId = mSurfaceUniqueIds[surfaceId];
512     if (surfaceHolderForId.mSurfaceHolder.mMirrorMode != OutputConfiguration::MIRROR_MODE_AUTO &&
513             mayChangeMirror) {
514         // If the mirroring mode is not AUTO, do not allow transform update
515         // which may change mirror.
516         return OK;
517     }
518 
519     surfaceHolderForId.mTransform = transform;
520     if (mState == STATE_CONFIGURED) {
521         sp<Surface> surface = surfaceHolderForId.mSurfaceHolder.mSurface;
522         if (surface != nullptr) {
523             res = mStreamSplitter->setTransform(surfaceId, transform);
524             if (res != OK) {
525                 ALOGE("%s: StreamSplitter fails to setTransform: %s(%d)",
526                         __FUNCTION__, strerror(-res), res);
527                 return res;
528             }
529         }
530     }
531     return res;
532 }
533 
534 } // namespace camera3
535 
536 } // namespace android
537