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