• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-OutputStream"
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 "Camera3OutputStream.h"
24 
25 #ifndef container_of
26 #define container_of(ptr, type, member) \
27     (type *)((char*)(ptr) - offsetof(type, member))
28 #endif
29 
30 namespace android {
31 
32 namespace camera3 {
33 
Camera3OutputStream(int id,sp<Surface> consumer,uint32_t width,uint32_t height,int format,android_dataspace dataSpace,camera3_stream_rotation_t rotation,nsecs_t timestampOffset,int setId)34 Camera3OutputStream::Camera3OutputStream(int id,
35         sp<Surface> consumer,
36         uint32_t width, uint32_t height, int format,
37         android_dataspace dataSpace, camera3_stream_rotation_t rotation,
38         nsecs_t timestampOffset, int setId) :
39         Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
40                             /*maxSize*/0, format, dataSpace, rotation, setId),
41         mConsumer(consumer),
42         mTransform(0),
43         mTraceFirstBuffer(true),
44         mUseBufferManager(false),
45         mTimestampOffset(timestampOffset),
46         mConsumerUsage(0),
47         mDequeueBufferLatency(kDequeueLatencyBinSize) {
48 
49     if (mConsumer == NULL) {
50         ALOGE("%s: Consumer is NULL!", __FUNCTION__);
51         mState = STATE_ERROR;
52     }
53 
54     if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
55         mBufferReleasedListener = new BufferReleasedListener(this);
56     }
57 }
58 
Camera3OutputStream(int id,sp<Surface> consumer,uint32_t width,uint32_t height,size_t maxSize,int format,android_dataspace dataSpace,camera3_stream_rotation_t rotation,nsecs_t timestampOffset,int setId)59 Camera3OutputStream::Camera3OutputStream(int id,
60         sp<Surface> consumer,
61         uint32_t width, uint32_t height, size_t maxSize, int format,
62         android_dataspace dataSpace, camera3_stream_rotation_t rotation,
63         nsecs_t timestampOffset, int setId) :
64         Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize,
65                             format, dataSpace, rotation, setId),
66         mConsumer(consumer),
67         mTransform(0),
68         mTraceFirstBuffer(true),
69         mUseMonoTimestamp(false),
70         mUseBufferManager(false),
71         mTimestampOffset(timestampOffset),
72         mConsumerUsage(0),
73         mDequeueBufferLatency(kDequeueLatencyBinSize) {
74 
75     if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
76         ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
77                 format);
78         mState = STATE_ERROR;
79     }
80 
81     if (mConsumer == NULL) {
82         ALOGE("%s: Consumer is NULL!", __FUNCTION__);
83         mState = STATE_ERROR;
84     }
85 
86     if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
87         mBufferReleasedListener = new BufferReleasedListener(this);
88     }
89 }
90 
Camera3OutputStream(int id,uint32_t width,uint32_t height,int format,uint64_t consumerUsage,android_dataspace dataSpace,camera3_stream_rotation_t rotation,nsecs_t timestampOffset,int setId)91 Camera3OutputStream::Camera3OutputStream(int id,
92         uint32_t width, uint32_t height, int format,
93         uint64_t consumerUsage, android_dataspace dataSpace,
94         camera3_stream_rotation_t rotation, nsecs_t timestampOffset, int setId) :
95         Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
96                             /*maxSize*/0, format, dataSpace, rotation, setId),
97         mConsumer(nullptr),
98         mTransform(0),
99         mTraceFirstBuffer(true),
100         mUseBufferManager(false),
101         mTimestampOffset(timestampOffset),
102         mConsumerUsage(consumerUsage),
103         mDequeueBufferLatency(kDequeueLatencyBinSize) {
104     // Deferred consumer only support preview surface format now.
105     if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
106         ALOGE("%s: Deferred consumer only supports IMPLEMENTATION_DEFINED format now!",
107                 __FUNCTION__);
108         mState = STATE_ERROR;
109     }
110 
111     // Sanity check for the consumer usage flag.
112     if ((consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) == 0 &&
113             (consumerUsage & GraphicBuffer::USAGE_HW_COMPOSER) == 0) {
114         ALOGE("%s: Deferred consumer usage flag is illegal %" PRIu64 "!",
115               __FUNCTION__, consumerUsage);
116         mState = STATE_ERROR;
117     }
118 
119     mConsumerName = String8("Deferred");
120     if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
121         mBufferReleasedListener = new BufferReleasedListener(this);
122     }
123 
124 }
125 
Camera3OutputStream(int id,camera3_stream_type_t type,uint32_t width,uint32_t height,int format,android_dataspace dataSpace,camera3_stream_rotation_t rotation,uint64_t consumerUsage,nsecs_t timestampOffset,int setId)126 Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
127                                          uint32_t width, uint32_t height,
128                                          int format,
129                                          android_dataspace dataSpace,
130                                          camera3_stream_rotation_t rotation,
131                                          uint64_t consumerUsage, nsecs_t timestampOffset,
132                                          int setId) :
133         Camera3IOStreamBase(id, type, width, height,
134                             /*maxSize*/0,
135                             format, dataSpace, rotation, setId),
136         mTransform(0),
137         mTraceFirstBuffer(true),
138         mUseMonoTimestamp(false),
139         mUseBufferManager(false),
140         mTimestampOffset(timestampOffset),
141         mConsumerUsage(consumerUsage),
142         mDequeueBufferLatency(kDequeueLatencyBinSize) {
143 
144     if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
145         mBufferReleasedListener = new BufferReleasedListener(this);
146     }
147 
148     // Subclasses expected to initialize mConsumer themselves
149 }
150 
151 
~Camera3OutputStream()152 Camera3OutputStream::~Camera3OutputStream() {
153     disconnectLocked();
154 }
155 
getBufferLocked(camera3_stream_buffer * buffer,const std::vector<size_t> &)156 status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer,
157         const std::vector<size_t>&) {
158     ATRACE_CALL();
159 
160     ANativeWindowBuffer* anb;
161     int fenceFd = -1;
162 
163     status_t res;
164     res = getBufferLockedCommon(&anb, &fenceFd);
165     if (res != OK) {
166         return res;
167     }
168 
169     /**
170      * FenceFD now owned by HAL except in case of error,
171      * in which case we reassign it to acquire_fence
172      */
173     handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
174                         /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
175 
176     return OK;
177 }
178 
queueBufferToConsumer(sp<ANativeWindow> & consumer,ANativeWindowBuffer * buffer,int anwReleaseFence)179 status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
180             ANativeWindowBuffer* buffer, int anwReleaseFence) {
181     return consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
182 }
183 
returnBufferLocked(const camera3_stream_buffer & buffer,nsecs_t timestamp)184 status_t Camera3OutputStream::returnBufferLocked(
185         const camera3_stream_buffer &buffer,
186         nsecs_t timestamp) {
187     ATRACE_CALL();
188 
189     status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true);
190 
191     if (res != OK) {
192         return res;
193     }
194 
195     mLastTimestamp = timestamp;
196     mFrameCount++;
197 
198     return OK;
199 }
200 
returnBufferCheckedLocked(const camera3_stream_buffer & buffer,nsecs_t timestamp,bool output,sp<Fence> * releaseFenceOut)201 status_t Camera3OutputStream::returnBufferCheckedLocked(
202             const camera3_stream_buffer &buffer,
203             nsecs_t timestamp,
204             bool output,
205             /*out*/
206             sp<Fence> *releaseFenceOut) {
207 
208     (void)output;
209     ALOG_ASSERT(output, "Expected output to be true");
210 
211     status_t res;
212 
213     // Fence management - always honor release fence from HAL
214     sp<Fence> releaseFence = new Fence(buffer.release_fence);
215     int anwReleaseFence = releaseFence->dup();
216 
217     /**
218      * Release the lock briefly to avoid deadlock with
219      * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this
220      * thread will go into StreamingProcessor::onFrameAvailable) during
221      * queueBuffer
222      */
223     sp<ANativeWindow> currentConsumer = mConsumer;
224     mLock.unlock();
225 
226     ANativeWindowBuffer *anwBuffer = container_of(buffer.buffer, ANativeWindowBuffer, handle);
227     /**
228      * Return buffer back to ANativeWindow
229      */
230     if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
231         // Cancel buffer
232         ALOGW("A frame is dropped for stream %d", mId);
233         res = currentConsumer->cancelBuffer(currentConsumer.get(),
234                 anwBuffer,
235                 anwReleaseFence);
236         if (res != OK) {
237             ALOGE("%s: Stream %d: Error cancelling buffer to native window:"
238                   " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
239         }
240 
241         notifyBufferReleased(anwBuffer);
242         if (mUseBufferManager) {
243             // Return this buffer back to buffer manager.
244             mBufferReleasedListener->onBufferReleased();
245         }
246     } else {
247         if (mTraceFirstBuffer && (stream_type == CAMERA3_STREAM_OUTPUT)) {
248             {
249                 char traceLog[48];
250                 snprintf(traceLog, sizeof(traceLog), "Stream %d: first full buffer\n", mId);
251                 ATRACE_NAME(traceLog);
252             }
253             mTraceFirstBuffer = false;
254         }
255 
256         /* Certain consumers (such as AudioSource or HardwareComposer) use
257          * MONOTONIC time, causing time misalignment if camera timestamp is
258          * in BOOTTIME. Do the conversion if necessary. */
259         res = native_window_set_buffers_timestamp(mConsumer.get(),
260                 mUseMonoTimestamp ? timestamp - mTimestampOffset : timestamp);
261         if (res != OK) {
262             ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
263                   __FUNCTION__, mId, strerror(-res), res);
264             return res;
265         }
266 
267         res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence);
268         if (res != OK) {
269             ALOGE("%s: Stream %d: Error queueing buffer to native window: "
270                   "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
271         }
272     }
273     mLock.lock();
274 
275     // Once a valid buffer has been returned to the queue, can no longer
276     // dequeue all buffers for preallocation.
277     if (buffer.status != CAMERA3_BUFFER_STATUS_ERROR) {
278         mStreamUnpreparable = true;
279     }
280 
281     if (res != OK) {
282         close(anwReleaseFence);
283     }
284 
285     *releaseFenceOut = releaseFence;
286 
287     return res;
288 }
289 
dump(int fd,const Vector<String16> & args) const290 void Camera3OutputStream::dump(int fd, const Vector<String16> &args) const {
291     (void) args;
292     String8 lines;
293     lines.appendFormat("    Stream[%d]: Output\n", mId);
294     lines.appendFormat("      Consumer name: %s\n", mConsumerName.string());
295     write(fd, lines.string(), lines.size());
296 
297     Camera3IOStreamBase::dump(fd, args);
298 
299     mDequeueBufferLatency.dump(fd,
300         "      DequeueBuffer latency histogram:");
301 }
302 
setTransform(int transform)303 status_t Camera3OutputStream::setTransform(int transform) {
304     ATRACE_CALL();
305     Mutex::Autolock l(mLock);
306     return setTransformLocked(transform);
307 }
308 
setTransformLocked(int transform)309 status_t Camera3OutputStream::setTransformLocked(int transform) {
310     status_t res = OK;
311     if (mState == STATE_ERROR) {
312         ALOGE("%s: Stream in error state", __FUNCTION__);
313         return INVALID_OPERATION;
314     }
315 
316     mTransform = transform;
317     if (mState == STATE_CONFIGURED) {
318         res = native_window_set_buffers_transform(mConsumer.get(),
319                 transform);
320         if (res != OK) {
321             ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
322                     __FUNCTION__, transform, strerror(-res), res);
323         }
324     }
325     return res;
326 }
327 
configureQueueLocked()328 status_t Camera3OutputStream::configureQueueLocked() {
329     status_t res;
330 
331     mTraceFirstBuffer = true;
332     if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
333         return res;
334     }
335 
336     if ((res = configureConsumerQueueLocked()) != OK) {
337         return res;
338     }
339 
340     // Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture.
341     // We need skip these cases as timeout will disable the non-blocking (async) mode.
342     if (!(isConsumedByHWComposer() || isConsumedByHWTexture())) {
343         mConsumer->setDequeueTimeout(kDequeueBufferTimeout);
344     }
345 
346     return OK;
347 }
348 
configureConsumerQueueLocked()349 status_t Camera3OutputStream::configureConsumerQueueLocked() {
350     status_t res;
351 
352     mTraceFirstBuffer = true;
353 
354     ALOG_ASSERT(mConsumer != 0, "mConsumer should never be NULL");
355 
356     // Configure consumer-side ANativeWindow interface. The listener may be used
357     // to notify buffer manager (if it is used) of the returned buffers.
358     res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA,
359             /*listener*/mBufferReleasedListener,
360             /*reportBufferRemoval*/true);
361     if (res != OK) {
362         ALOGE("%s: Unable to connect to native window for stream %d",
363                 __FUNCTION__, mId);
364         return res;
365     }
366 
367     mConsumerName = mConsumer->getConsumerName();
368 
369     res = native_window_set_usage(mConsumer.get(), mUsage);
370     if (res != OK) {
371         ALOGE("%s: Unable to configure usage %" PRIu64 " for stream %d",
372                 __FUNCTION__, mUsage, mId);
373         return res;
374     }
375 
376     res = native_window_set_scaling_mode(mConsumer.get(),
377             NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
378     if (res != OK) {
379         ALOGE("%s: Unable to configure stream scaling: %s (%d)",
380                 __FUNCTION__, strerror(-res), res);
381         return res;
382     }
383 
384     if (mMaxSize == 0) {
385         // For buffers of known size
386         res = native_window_set_buffers_dimensions(mConsumer.get(),
387                 camera3_stream::width, camera3_stream::height);
388     } else {
389         // For buffers with bounded size
390         res = native_window_set_buffers_dimensions(mConsumer.get(),
391                 mMaxSize, 1);
392     }
393     if (res != OK) {
394         ALOGE("%s: Unable to configure stream buffer dimensions"
395                 " %d x %d (maxSize %zu) for stream %d",
396                 __FUNCTION__, camera3_stream::width, camera3_stream::height,
397                 mMaxSize, mId);
398         return res;
399     }
400     res = native_window_set_buffers_format(mConsumer.get(),
401             camera3_stream::format);
402     if (res != OK) {
403         ALOGE("%s: Unable to configure stream buffer format %#x for stream %d",
404                 __FUNCTION__, camera3_stream::format, mId);
405         return res;
406     }
407 
408     res = native_window_set_buffers_data_space(mConsumer.get(),
409             camera3_stream::data_space);
410     if (res != OK) {
411         ALOGE("%s: Unable to configure stream dataspace %#x for stream %d",
412                 __FUNCTION__, camera3_stream::data_space, mId);
413         return res;
414     }
415 
416     int maxConsumerBuffers;
417     res = static_cast<ANativeWindow*>(mConsumer.get())->query(
418             mConsumer.get(),
419             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
420     if (res != OK) {
421         ALOGE("%s: Unable to query consumer undequeued"
422                 " buffer count for stream %d", __FUNCTION__, mId);
423         return res;
424     }
425 
426     ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__,
427             maxConsumerBuffers, camera3_stream::max_buffers);
428     if (camera3_stream::max_buffers == 0) {
429         ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1",
430                 __FUNCTION__, camera3_stream::max_buffers);
431         return INVALID_OPERATION;
432     }
433 
434     mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers;
435     mHandoutTotalBufferCount = 0;
436     mFrameCount = 0;
437     mLastTimestamp = 0;
438     mUseMonoTimestamp = (isConsumedByHWComposer() | isVideoStream());
439 
440     res = native_window_set_buffer_count(mConsumer.get(),
441             mTotalBufferCount);
442     if (res != OK) {
443         ALOGE("%s: Unable to set buffer count for stream %d",
444                 __FUNCTION__, mId);
445         return res;
446     }
447 
448     res = native_window_set_buffers_transform(mConsumer.get(),
449             mTransform);
450     if (res != OK) {
451         ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
452                 __FUNCTION__, mTransform, strerror(-res), res);
453         return res;
454     }
455 
456     /**
457      * Camera3 Buffer manager is only supported by HAL3.3 onwards, as the older HALs requires
458      * buffers to be statically allocated for internal static buffer registration, while the
459      * buffers provided by buffer manager are really dynamically allocated. Camera3Device only
460      * sets the mBufferManager if device version is > HAL3.2, which guarantees that the buffer
461      * manager setup is skipped in below code. Note that HAL3.2 is also excluded here, as some
462      * HAL3.2 devices may not support the dynamic buffer registeration.
463      */
464     if (mBufferManager != 0 && mSetId > CAMERA3_STREAM_SET_ID_INVALID) {
465         uint64_t consumerUsage = 0;
466         getEndpointUsage(&consumerUsage);
467         StreamInfo streamInfo(
468                 getId(), getStreamSetId(), getWidth(), getHeight(), getFormat(), getDataSpace(),
469                 mUsage | consumerUsage, mTotalBufferCount,
470                 /*isConfigured*/true);
471         wp<Camera3OutputStream> weakThis(this);
472         res = mBufferManager->registerStream(weakThis,
473                 streamInfo);
474         if (res == OK) {
475             // Disable buffer allocation for this BufferQueue, buffer manager will take over
476             // the buffer allocation responsibility.
477             mConsumer->getIGraphicBufferProducer()->allowAllocation(false);
478             mUseBufferManager = true;
479         } else {
480             ALOGE("%s: Unable to register stream %d to camera3 buffer manager, "
481                   "(error %d %s), fall back to BufferQueue for buffer management!",
482                   __FUNCTION__, mId, res, strerror(-res));
483         }
484     }
485 
486     return OK;
487 }
488 
getBufferLockedCommon(ANativeWindowBuffer ** anb,int * fenceFd)489 status_t Camera3OutputStream::getBufferLockedCommon(ANativeWindowBuffer** anb, int* fenceFd) {
490     ATRACE_CALL();
491     status_t res;
492 
493     if ((res = getBufferPreconditionCheckLocked()) != OK) {
494         return res;
495     }
496 
497     bool gotBufferFromManager = false;
498 
499     if (mUseBufferManager) {
500         sp<GraphicBuffer> gb;
501         res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, fenceFd);
502         if (res == OK) {
503             // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a
504             // successful return.
505             *anb = gb.get();
506             res = mConsumer->attachBuffer(*anb);
507             if (res != OK) {
508                 ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)",
509                         __FUNCTION__, mId, strerror(-res), res);
510                 return res;
511             }
512             gotBufferFromManager = true;
513             ALOGV("Stream %d: Attached new buffer", getId());
514         } else if (res == ALREADY_EXISTS) {
515             // Have sufficient free buffers already attached, can just
516             // dequeue from buffer queue
517             ALOGV("Stream %d: Reusing attached buffer", getId());
518             gotBufferFromManager = false;
519         } else if (res != OK) {
520             ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)",
521                     __FUNCTION__, mId, strerror(-res), res);
522             return res;
523         }
524     }
525     if (!gotBufferFromManager) {
526         /**
527          * Release the lock briefly to avoid deadlock for below scenario:
528          * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
529          * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
530          * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
531          * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
532          * StreamingProcessor lock.
533          * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
534          * and try to lock bufferQueue lock.
535          * Then there is circular locking dependency.
536          */
537         sp<ANativeWindow> currentConsumer = mConsumer;
538         mLock.unlock();
539 
540         nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC);
541         res = currentConsumer->dequeueBuffer(currentConsumer.get(), anb, fenceFd);
542         nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC);
543         mDequeueBufferLatency.add(dequeueStart, dequeueEnd);
544 
545         mLock.lock();
546         if (res != OK) {
547             ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
548                     __FUNCTION__, mId, strerror(-res), res);
549 
550             // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
551             // let prepareNextBuffer handle the error.)
552             if (res == NO_INIT && mState == STATE_CONFIGURED) {
553                 mState = STATE_ABANDONED;
554             }
555 
556             return res;
557         }
558     }
559 
560     if (res == OK) {
561         std::vector<sp<GraphicBuffer>> removedBuffers;
562         res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
563         if (res == OK) {
564             onBuffersRemovedLocked(removedBuffers);
565 
566             if (mUseBufferManager && removedBuffers.size() > 0) {
567                 mBufferManager->onBuffersRemoved(getId(), getStreamSetId(), removedBuffers.size());
568             }
569         }
570     }
571 
572     return res;
573 }
574 
disconnectLocked()575 status_t Camera3OutputStream::disconnectLocked() {
576     status_t res;
577 
578     if ((res = Camera3IOStreamBase::disconnectLocked()) != OK) {
579         return res;
580     }
581 
582     // Stream configuration was not finished (can only be in STATE_IN_CONFIG or STATE_CONSTRUCTED
583     // state), don't need change the stream state, return OK.
584     if (mConsumer == nullptr) {
585         return OK;
586     }
587 
588     ALOGV("%s: disconnecting stream %d from native window", __FUNCTION__, getId());
589 
590     res = native_window_api_disconnect(mConsumer.get(),
591                                        NATIVE_WINDOW_API_CAMERA);
592     /**
593      * This is not an error. if client calling process dies, the window will
594      * also die and all calls to it will return DEAD_OBJECT, thus it's already
595      * "disconnected"
596      */
597     if (res == DEAD_OBJECT) {
598         ALOGW("%s: While disconnecting stream %d from native window, the"
599                 " native window died from under us", __FUNCTION__, mId);
600     }
601     else if (res != OK) {
602         ALOGE("%s: Unable to disconnect stream %d from native window "
603               "(error %d %s)",
604               __FUNCTION__, mId, res, strerror(-res));
605         mState = STATE_ERROR;
606         return res;
607     }
608 
609     // Since device is already idle, there is no getBuffer call to buffer manager, unregister the
610     // stream at this point should be safe.
611     if (mUseBufferManager) {
612         res = mBufferManager->unregisterStream(getId(), getStreamSetId());
613         if (res != OK) {
614             ALOGE("%s: Unable to unregister stream %d from buffer manager "
615                     "(error %d %s)", __FUNCTION__, mId, res, strerror(-res));
616             mState = STATE_ERROR;
617             return res;
618         }
619         // Note that, to make prepare/teardown case work, we must not mBufferManager.clear(), as
620         // the stream is still in usable state after this call.
621         mUseBufferManager = false;
622     }
623 
624     mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG
625                                            : STATE_CONSTRUCTED;
626 
627     mDequeueBufferLatency.log("Stream %d dequeueBuffer latency histogram", mId);
628     mDequeueBufferLatency.reset();
629     return OK;
630 }
631 
getEndpointUsage(uint64_t * usage) const632 status_t Camera3OutputStream::getEndpointUsage(uint64_t *usage) const {
633 
634     status_t res;
635 
636     if (mConsumer == nullptr) {
637         // mConsumerUsage was sanitized before the Camera3OutputStream was constructed.
638         *usage = mConsumerUsage;
639         return OK;
640     }
641 
642     res = getEndpointUsageForSurface(usage, mConsumer);
643 
644     return res;
645 }
646 
getEndpointUsageForSurface(uint64_t * usage,const sp<Surface> & surface) const647 status_t Camera3OutputStream::getEndpointUsageForSurface(uint64_t *usage,
648         const sp<Surface>& surface) const {
649     status_t res;
650     uint64_t u = 0;
651 
652     res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(surface.get()), &u);
653     // If an opaque output stream's endpoint is ImageReader, add
654     // GRALLOC_USAGE_HW_CAMERA_ZSL to the usage so HAL knows it will be used
655     // for the ZSL use case.
656     // Assume it's for ImageReader if the consumer usage doesn't have any of these bits set:
657     //     1. GRALLOC_USAGE_HW_TEXTURE
658     //     2. GRALLOC_USAGE_HW_RENDER
659     //     3. GRALLOC_USAGE_HW_COMPOSER
660     //     4. GRALLOC_USAGE_HW_VIDEO_ENCODER
661     if (camera3_stream::format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
662             (u & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
663             GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) == 0) {
664         u |= GRALLOC_USAGE_HW_CAMERA_ZSL;
665     }
666 
667     *usage = u;
668     return res;
669 }
670 
isVideoStream() const671 bool Camera3OutputStream::isVideoStream() const {
672     uint64_t usage = 0;
673     status_t res = getEndpointUsage(&usage);
674     if (res != OK) {
675         ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
676         return false;
677     }
678 
679     return (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) != 0;
680 }
681 
setBufferManager(sp<Camera3BufferManager> bufferManager)682 status_t Camera3OutputStream::setBufferManager(sp<Camera3BufferManager> bufferManager) {
683     Mutex::Autolock l(mLock);
684     if (mState != STATE_CONSTRUCTED) {
685         ALOGE("%s: this method can only be called when stream in CONSTRUCTED state.",
686                 __FUNCTION__);
687         return INVALID_OPERATION;
688     }
689     mBufferManager = bufferManager;
690 
691     return OK;
692 }
693 
onBufferReleased()694 void Camera3OutputStream::BufferReleasedListener::onBufferReleased() {
695     sp<Camera3OutputStream> stream = mParent.promote();
696     if (stream == nullptr) {
697         ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__);
698         return;
699     }
700 
701     Mutex::Autolock l(stream->mLock);
702     if (!(stream->mUseBufferManager)) {
703         return;
704     }
705 
706     ALOGV("Stream %d: Buffer released", stream->getId());
707     bool shouldFreeBuffer = false;
708     status_t res = stream->mBufferManager->onBufferReleased(
709         stream->getId(), stream->getStreamSetId(), &shouldFreeBuffer);
710     if (res != OK) {
711         ALOGE("%s: signaling buffer release to buffer manager failed: %s (%d).", __FUNCTION__,
712                 strerror(-res), res);
713         stream->mState = STATE_ERROR;
714     }
715 
716     if (shouldFreeBuffer) {
717         sp<GraphicBuffer> buffer;
718         // Detach and free a buffer (when buffer goes out of scope)
719         stream->detachBufferLocked(&buffer, /*fenceFd*/ nullptr);
720         if (buffer.get() != nullptr) {
721             stream->mBufferManager->notifyBufferRemoved(
722                     stream->getId(), stream->getStreamSetId());
723         }
724     }
725 }
726 
onBuffersRemovedLocked(const std::vector<sp<GraphicBuffer>> & removedBuffers)727 void Camera3OutputStream::onBuffersRemovedLocked(
728         const std::vector<sp<GraphicBuffer>>& removedBuffers) {
729     sp<Camera3StreamBufferFreedListener> callback = mBufferFreedListener.promote();
730     if (callback != nullptr) {
731         for (auto gb : removedBuffers) {
732             callback->onBufferFreed(mId, gb->handle);
733         }
734     }
735 }
736 
detachBuffer(sp<GraphicBuffer> * buffer,int * fenceFd)737 status_t Camera3OutputStream::detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd) {
738     Mutex::Autolock l(mLock);
739     return detachBufferLocked(buffer, fenceFd);
740 }
741 
detachBufferLocked(sp<GraphicBuffer> * buffer,int * fenceFd)742 status_t Camera3OutputStream::detachBufferLocked(sp<GraphicBuffer>* buffer, int* fenceFd) {
743     ALOGV("Stream %d: detachBuffer", getId());
744     if (buffer == nullptr) {
745         return BAD_VALUE;
746     }
747 
748     sp<Fence> fence;
749     status_t res = mConsumer->detachNextBuffer(buffer, &fence);
750     if (res == NO_MEMORY) {
751         // This may rarely happen, which indicates that the released buffer was freed by other
752         // call (e.g., attachBuffer, dequeueBuffer etc.) before reaching here. We should notify the
753         // buffer manager that this buffer has been freed. It's not fatal, but should be avoided,
754         // therefore log a warning.
755         *buffer = 0;
756         ALOGW("%s: the released buffer has already been freed by the buffer queue!", __FUNCTION__);
757     } else if (res != OK) {
758         // Treat other errors as abandonment
759         ALOGE("%s: detach next buffer failed: %s (%d).", __FUNCTION__, strerror(-res), res);
760         mState = STATE_ABANDONED;
761         return res;
762     }
763 
764     if (fenceFd != nullptr) {
765         if (fence!= 0 && fence->isValid()) {
766             *fenceFd = fence->dup();
767         } else {
768             *fenceFd = -1;
769         }
770     }
771 
772     std::vector<sp<GraphicBuffer>> removedBuffers;
773     res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
774     if (res == OK) {
775         onBuffersRemovedLocked(removedBuffers);
776     }
777     return res;
778 }
779 
notifyBufferReleased(ANativeWindowBuffer *)780 status_t Camera3OutputStream::notifyBufferReleased(ANativeWindowBuffer* /*anwBuffer*/) {
781     return OK;
782 }
783 
isConsumerConfigurationDeferred(size_t surface_id) const784 bool Camera3OutputStream::isConsumerConfigurationDeferred(size_t surface_id) const {
785     Mutex::Autolock l(mLock);
786 
787     if (surface_id != 0) {
788         ALOGE("%s: surface_id %zu for Camera3OutputStream should be 0!", __FUNCTION__, surface_id);
789     }
790     return mConsumer == nullptr;
791 }
792 
setConsumers(const std::vector<sp<Surface>> & consumers)793 status_t Camera3OutputStream::setConsumers(const std::vector<sp<Surface>>& consumers) {
794     Mutex::Autolock l(mLock);
795     if (consumers.size() != 1) {
796         ALOGE("%s: it's illegal to set %zu consumer surfaces!",
797                   __FUNCTION__, consumers.size());
798         return INVALID_OPERATION;
799     }
800     if (consumers[0] == nullptr) {
801         ALOGE("%s: it's illegal to set null consumer surface!", __FUNCTION__);
802         return INVALID_OPERATION;
803     }
804 
805     if (mConsumer != nullptr) {
806         ALOGE("%s: consumer surface was already set!", __FUNCTION__);
807         return INVALID_OPERATION;
808     }
809 
810     mConsumer = consumers[0];
811     return OK;
812 }
813 
isConsumedByHWComposer() const814 bool Camera3OutputStream::isConsumedByHWComposer() const {
815     uint64_t usage = 0;
816     status_t res = getEndpointUsage(&usage);
817     if (res != OK) {
818         ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
819         return false;
820     }
821 
822     return (usage & GRALLOC_USAGE_HW_COMPOSER) != 0;
823 }
824 
isConsumedByHWTexture() const825 bool Camera3OutputStream::isConsumedByHWTexture() const {
826     uint64_t usage = 0;
827     status_t res = getEndpointUsage(&usage);
828     if (res != OK) {
829         ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
830         return false;
831     }
832 
833     return (usage & GRALLOC_USAGE_HW_TEXTURE) != 0;
834 }
835 
836 }; // namespace camera3
837 
838 }; // namespace android
839