• 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-Stream"
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 "device3/Camera3Stream.h"
24 #include "device3/StatusTracker.h"
25 
26 #include <cutils/properties.h>
27 
28 namespace android {
29 
30 namespace camera3 {
31 
~Camera3Stream()32 Camera3Stream::~Camera3Stream() {
33     sp<StatusTracker> statusTracker = mStatusTracker.promote();
34     if (statusTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
35         statusTracker->removeComponent(mStatusId);
36     }
37 }
38 
cast(camera3_stream * stream)39 Camera3Stream* Camera3Stream::cast(camera3_stream *stream) {
40     return static_cast<Camera3Stream*>(stream);
41 }
42 
cast(const camera3_stream * stream)43 const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) {
44     return static_cast<const Camera3Stream*>(stream);
45 }
46 
Camera3Stream(int id,camera3_stream_type type,uint32_t width,uint32_t height,size_t maxSize,int format)47 Camera3Stream::Camera3Stream(int id,
48         camera3_stream_type type,
49         uint32_t width, uint32_t height, size_t maxSize, int format) :
50     camera3_stream(),
51     mId(id),
52     mName(String8::format("Camera3Stream[%d]", id)),
53     mMaxSize(maxSize),
54     mState(STATE_CONSTRUCTED),
55     mStatusId(StatusTracker::NO_STATUS_ID) {
56 
57     camera3_stream::stream_type = type;
58     camera3_stream::width = width;
59     camera3_stream::height = height;
60     camera3_stream::format = format;
61     camera3_stream::usage = 0;
62     camera3_stream::max_buffers = 0;
63     camera3_stream::priv = NULL;
64 
65     if (format == HAL_PIXEL_FORMAT_BLOB && maxSize == 0) {
66         ALOGE("%s: BLOB format with size == 0", __FUNCTION__);
67         mState = STATE_ERROR;
68     }
69 }
70 
getId() const71 int Camera3Stream::getId() const {
72     return mId;
73 }
74 
getWidth() const75 uint32_t Camera3Stream::getWidth() const {
76     return camera3_stream::width;
77 }
78 
getHeight() const79 uint32_t Camera3Stream::getHeight() const {
80     return camera3_stream::height;
81 }
82 
getFormat() const83 int Camera3Stream::getFormat() const {
84     return camera3_stream::format;
85 }
86 
startConfiguration()87 camera3_stream* Camera3Stream::startConfiguration() {
88     ATRACE_CALL();
89     Mutex::Autolock l(mLock);
90     status_t res;
91 
92     switch (mState) {
93         case STATE_ERROR:
94             ALOGE("%s: In error state", __FUNCTION__);
95             return NULL;
96         case STATE_CONSTRUCTED:
97             // OK
98             break;
99         case STATE_IN_CONFIG:
100         case STATE_IN_RECONFIG:
101             // Can start config again with no trouble; but don't redo
102             // oldUsage/oldMaxBuffers
103             return this;
104         case STATE_CONFIGURED:
105             if (stream_type == CAMERA3_STREAM_INPUT) {
106                 ALOGE("%s: Cannot configure an input stream twice",
107                         __FUNCTION__);
108                 return NULL;
109             } else if (hasOutstandingBuffersLocked()) {
110                 ALOGE("%s: Cannot configure stream; has outstanding buffers",
111                         __FUNCTION__);
112                 return NULL;
113             }
114             break;
115         default:
116             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
117             return NULL;
118     }
119 
120     oldUsage = camera3_stream::usage;
121     oldMaxBuffers = camera3_stream::max_buffers;
122 
123     res = getEndpointUsage(&(camera3_stream::usage));
124     if (res != OK) {
125         ALOGE("%s: Cannot query consumer endpoint usage!",
126                 __FUNCTION__);
127         return NULL;
128     }
129 
130     // Stop tracking if currently doing so
131     if (mStatusId != StatusTracker::NO_STATUS_ID) {
132         sp<StatusTracker> statusTracker = mStatusTracker.promote();
133         if (statusTracker != 0) {
134             statusTracker->removeComponent(mStatusId);
135         }
136         mStatusId = StatusTracker::NO_STATUS_ID;
137     }
138 
139     if (mState == STATE_CONSTRUCTED) {
140         mState = STATE_IN_CONFIG;
141     } else { // mState == STATE_CONFIGURED
142         LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState);
143         mState = STATE_IN_RECONFIG;
144     }
145 
146     return this;
147 }
148 
isConfiguring() const149 bool Camera3Stream::isConfiguring() const {
150     Mutex::Autolock l(mLock);
151     return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
152 }
153 
finishConfiguration(camera3_device * hal3Device)154 status_t Camera3Stream::finishConfiguration(camera3_device *hal3Device) {
155     ATRACE_CALL();
156     Mutex::Autolock l(mLock);
157     switch (mState) {
158         case STATE_ERROR:
159             ALOGE("%s: In error state", __FUNCTION__);
160             return INVALID_OPERATION;
161         case STATE_IN_CONFIG:
162         case STATE_IN_RECONFIG:
163             // OK
164             break;
165         case STATE_CONSTRUCTED:
166         case STATE_CONFIGURED:
167             ALOGE("%s: Cannot finish configuration that hasn't been started",
168                     __FUNCTION__);
169             return INVALID_OPERATION;
170         default:
171             ALOGE("%s: Unknown state", __FUNCTION__);
172             return INVALID_OPERATION;
173     }
174 
175     // Register for idle tracking
176     sp<StatusTracker> statusTracker = mStatusTracker.promote();
177     if (statusTracker != 0) {
178         mStatusId = statusTracker->addComponent();
179     }
180 
181     // Check if the stream configuration is unchanged, and skip reallocation if
182     // so. As documented in hardware/camera3.h:configure_streams().
183     if (mState == STATE_IN_RECONFIG &&
184             oldUsage == camera3_stream::usage &&
185             oldMaxBuffers == camera3_stream::max_buffers) {
186         mState = STATE_CONFIGURED;
187         return OK;
188     }
189 
190     status_t res;
191     res = configureQueueLocked();
192     if (res != OK) {
193         ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
194                 __FUNCTION__, mId, strerror(-res), res);
195         mState = STATE_ERROR;
196         return res;
197     }
198 
199     res = registerBuffersLocked(hal3Device);
200     if (res != OK) {
201         ALOGE("%s: Unable to register stream buffers with HAL: %s (%d)",
202                 __FUNCTION__, strerror(-res), res);
203         mState = STATE_ERROR;
204         return res;
205     }
206 
207     mState = STATE_CONFIGURED;
208 
209     return res;
210 }
211 
cancelConfiguration()212 status_t Camera3Stream::cancelConfiguration() {
213     ATRACE_CALL();
214     Mutex::Autolock l(mLock);
215     switch (mState) {
216         case STATE_ERROR:
217             ALOGE("%s: In error state", __FUNCTION__);
218             return INVALID_OPERATION;
219         case STATE_IN_CONFIG:
220         case STATE_IN_RECONFIG:
221             // OK
222             break;
223         case STATE_CONSTRUCTED:
224         case STATE_CONFIGURED:
225             ALOGE("%s: Cannot cancel configuration that hasn't been started",
226                     __FUNCTION__);
227             return INVALID_OPERATION;
228         default:
229             ALOGE("%s: Unknown state", __FUNCTION__);
230             return INVALID_OPERATION;
231     }
232 
233     camera3_stream::usage = oldUsage;
234     camera3_stream::max_buffers = oldMaxBuffers;
235 
236     mState = (mState == STATE_IN_RECONFIG) ? STATE_CONFIGURED : STATE_CONSTRUCTED;
237     return OK;
238 }
239 
getBuffer(camera3_stream_buffer * buffer)240 status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) {
241     ATRACE_CALL();
242     Mutex::Autolock l(mLock);
243     status_t res = OK;
244 
245     // This function should be only called when the stream is configured already.
246     if (mState != STATE_CONFIGURED) {
247         ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
248                 __FUNCTION__, mId, mState);
249         return INVALID_OPERATION;
250     }
251 
252     // Wait for new buffer returned back if we are running into the limit.
253     if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) {
254         ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.",
255                 __FUNCTION__, camera3_stream::max_buffers);
256         res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
257         if (res != OK) {
258             if (res == TIMED_OUT) {
259                 ALOGE("%s: wait for output buffer return timed out after %lldms", __FUNCTION__,
260                         kWaitForBufferDuration / 1000000LL);
261             }
262             return res;
263         }
264     }
265 
266     res = getBufferLocked(buffer);
267     if (res == OK) {
268         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
269     }
270 
271     return res;
272 }
273 
returnBuffer(const camera3_stream_buffer & buffer,nsecs_t timestamp)274 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
275         nsecs_t timestamp) {
276     ATRACE_CALL();
277     Mutex::Autolock l(mLock);
278 
279     /**
280      * TODO: Check that the state is valid first.
281      *
282      * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED.
283      * >= HAL3.2 CONFIGURED only
284      *
285      * Do this for getBuffer as well.
286      */
287     status_t res = returnBufferLocked(buffer, timestamp);
288     if (res == OK) {
289         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
290         mOutputBufferReturnedSignal.signal();
291     }
292 
293     return res;
294 }
295 
getInputBuffer(camera3_stream_buffer * buffer)296 status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) {
297     ATRACE_CALL();
298     Mutex::Autolock l(mLock);
299     status_t res = OK;
300 
301     // This function should be only called when the stream is configured already.
302     if (mState != STATE_CONFIGURED) {
303         ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
304                 __FUNCTION__, mId, mState);
305         return INVALID_OPERATION;
306     }
307 
308     // Wait for new buffer returned back if we are running into the limit.
309     if (getHandoutInputBufferCountLocked() == camera3_stream::max_buffers) {
310         ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
311                 __FUNCTION__, camera3_stream::max_buffers);
312         res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
313         if (res != OK) {
314             if (res == TIMED_OUT) {
315                 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__,
316                         kWaitForBufferDuration / 1000000LL);
317             }
318             return res;
319         }
320     }
321 
322     res = getInputBufferLocked(buffer);
323     if (res == OK) {
324         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
325     }
326 
327     return res;
328 }
329 
returnInputBuffer(const camera3_stream_buffer & buffer)330 status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) {
331     ATRACE_CALL();
332     Mutex::Autolock l(mLock);
333 
334     status_t res = returnInputBufferLocked(buffer);
335     if (res == OK) {
336         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
337         mInputBufferReturnedSignal.signal();
338     }
339     return res;
340 }
341 
fireBufferListenersLocked(const camera3_stream_buffer &,bool acquired,bool output)342 void Camera3Stream::fireBufferListenersLocked(
343         const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) {
344     List<wp<Camera3StreamBufferListener> >::iterator it, end;
345 
346     // TODO: finish implementing
347 
348     Camera3StreamBufferListener::BufferInfo info =
349         Camera3StreamBufferListener::BufferInfo();
350     info.mOutput = output;
351     // TODO: rest of fields
352 
353     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
354          it != end;
355          ++it) {
356 
357         sp<Camera3StreamBufferListener> listener = it->promote();
358         if (listener != 0) {
359             if (acquired) {
360                 listener->onBufferAcquired(info);
361             } else {
362                 listener->onBufferReleased(info);
363             }
364         }
365     }
366 }
367 
hasOutstandingBuffers() const368 bool Camera3Stream::hasOutstandingBuffers() const {
369     ATRACE_CALL();
370     Mutex::Autolock l(mLock);
371     return hasOutstandingBuffersLocked();
372 }
373 
setStatusTracker(sp<StatusTracker> statusTracker)374 status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
375     Mutex::Autolock l(mLock);
376     sp<StatusTracker> oldTracker = mStatusTracker.promote();
377     if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
378         oldTracker->removeComponent(mStatusId);
379     }
380     mStatusId = StatusTracker::NO_STATUS_ID;
381     mStatusTracker = statusTracker;
382 
383     return OK;
384 }
385 
disconnect()386 status_t Camera3Stream::disconnect() {
387     ATRACE_CALL();
388     Mutex::Autolock l(mLock);
389     ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
390     status_t res = disconnectLocked();
391 
392     if (res == -ENOTCONN) {
393         // "Already disconnected" -- not an error
394         return OK;
395     } else {
396         return res;
397     }
398 }
399 
registerBuffersLocked(camera3_device * hal3Device)400 status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) {
401     ATRACE_CALL();
402 
403     /**
404      * >= CAMERA_DEVICE_API_VERSION_3_2:
405      *
406      * camera3_device_t->ops->register_stream_buffers() is not called and must
407      * be NULL.
408      */
409     if (hal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_2) {
410         ALOGV("%s: register_stream_buffers unused as of HAL3.2", __FUNCTION__);
411 
412         if (hal3Device->ops->register_stream_buffers != NULL) {
413             ALOGE("%s: register_stream_buffers is deprecated in HAL3.2; "
414                     "must be set to NULL in camera3_device::ops", __FUNCTION__);
415             return INVALID_OPERATION;
416         } else {
417             ALOGD("%s: Skipping NULL check for deprecated register_stream_buffers", __FUNCTION__);
418         }
419 
420         return OK;
421     } else {
422         ALOGV("%s: register_stream_buffers using deprecated code path", __FUNCTION__);
423     }
424 
425     status_t res;
426 
427     size_t bufferCount = getBufferCountLocked();
428 
429     Vector<buffer_handle_t*> buffers;
430     buffers.insertAt(/*prototype_item*/NULL, /*index*/0, bufferCount);
431 
432     camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set();
433     bufferSet.stream = this;
434     bufferSet.num_buffers = bufferCount;
435     bufferSet.buffers = buffers.editArray();
436 
437     Vector<camera3_stream_buffer_t> streamBuffers;
438     streamBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount);
439 
440     // Register all buffers with the HAL. This means getting all the buffers
441     // from the stream, providing them to the HAL with the
442     // register_stream_buffers() method, and then returning them back to the
443     // stream in the error state, since they won't have valid data.
444     //
445     // Only registered buffers can be sent to the HAL.
446 
447     uint32_t bufferIdx = 0;
448     for (; bufferIdx < bufferCount; bufferIdx++) {
449         res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) );
450         if (res != OK) {
451             ALOGE("%s: Unable to get buffer %d for registration with HAL",
452                     __FUNCTION__, bufferIdx);
453             // Skip registering, go straight to cleanup
454             break;
455         }
456 
457         sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence);
458         fence->waitForever("Camera3Stream::registerBuffers");
459 
460         buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer;
461     }
462     if (bufferIdx == bufferCount) {
463         // Got all buffers, register with HAL
464         ALOGV("%s: Registering %zu buffers with camera HAL",
465                 __FUNCTION__, bufferCount);
466         ATRACE_BEGIN("camera3->register_stream_buffers");
467         res = hal3Device->ops->register_stream_buffers(hal3Device,
468                 &bufferSet);
469         ATRACE_END();
470     }
471 
472     // Return all valid buffers to stream, in ERROR state to indicate
473     // they weren't filled.
474     for (size_t i = 0; i < bufferIdx; i++) {
475         streamBuffers.editItemAt(i).release_fence = -1;
476         streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
477         returnBufferLocked(streamBuffers[i], 0);
478     }
479 
480     return res;
481 }
482 
getBufferLocked(camera3_stream_buffer *)483 status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) {
484     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
485     return INVALID_OPERATION;
486 }
returnBufferLocked(const camera3_stream_buffer &,nsecs_t)487 status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &,
488                                            nsecs_t) {
489     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
490     return INVALID_OPERATION;
491 }
getInputBufferLocked(camera3_stream_buffer *)492 status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) {
493     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
494     return INVALID_OPERATION;
495 }
returnInputBufferLocked(const camera3_stream_buffer &)496 status_t Camera3Stream::returnInputBufferLocked(
497         const camera3_stream_buffer &) {
498     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
499     return INVALID_OPERATION;
500 }
501 
addBufferListener(wp<Camera3StreamBufferListener> listener)502 void Camera3Stream::addBufferListener(
503         wp<Camera3StreamBufferListener> listener) {
504     Mutex::Autolock l(mLock);
505 
506     List<wp<Camera3StreamBufferListener> >::iterator it, end;
507     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
508          it != end;
509          ) {
510         if (*it == listener) {
511             ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__);
512             return;
513         }
514         it++;
515     }
516 
517     mBufferListenerList.push_back(listener);
518 }
519 
removeBufferListener(const sp<Camera3StreamBufferListener> & listener)520 void Camera3Stream::removeBufferListener(
521         const sp<Camera3StreamBufferListener>& listener) {
522     Mutex::Autolock l(mLock);
523 
524     bool erased = true;
525     List<wp<Camera3StreamBufferListener> >::iterator it, end;
526     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
527          it != end;
528          ) {
529 
530         if (*it == listener) {
531             it = mBufferListenerList.erase(it);
532             erased = true;
533         } else {
534             ++it;
535         }
536     }
537 
538     if (!erased) {
539         ALOGW("%s: Could not find listener to remove, already removed",
540               __FUNCTION__);
541     }
542 }
543 
544 }; // namespace camera3
545 
546 }; // namespace android
547