• 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 "Camera3Stream.h"
24 
25 namespace android {
26 
27 namespace camera3 {
28 
~Camera3Stream()29 Camera3Stream::~Camera3Stream() {
30 }
31 
cast(camera3_stream * stream)32 Camera3Stream* Camera3Stream::cast(camera3_stream *stream) {
33     return static_cast<Camera3Stream*>(stream);
34 }
35 
cast(const camera3_stream * stream)36 const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) {
37     return static_cast<const Camera3Stream*>(stream);
38 }
39 
Camera3Stream(int id,camera3_stream_type type,uint32_t width,uint32_t height,size_t maxSize,int format)40 Camera3Stream::Camera3Stream(int id,
41         camera3_stream_type type,
42         uint32_t width, uint32_t height, size_t maxSize, int format) :
43     camera3_stream(),
44     mId(id),
45     mName(String8::format("Camera3Stream[%d]", id)),
46     mMaxSize(maxSize),
47     mState(STATE_CONSTRUCTED) {
48 
49     camera3_stream::stream_type = type;
50     camera3_stream::width = width;
51     camera3_stream::height = height;
52     camera3_stream::format = format;
53     camera3_stream::usage = 0;
54     camera3_stream::max_buffers = 0;
55     camera3_stream::priv = NULL;
56 
57     if (format == HAL_PIXEL_FORMAT_BLOB && maxSize == 0) {
58         ALOGE("%s: BLOB format with size == 0", __FUNCTION__);
59         mState = STATE_ERROR;
60     }
61 }
62 
getId() const63 int Camera3Stream::getId() const {
64     return mId;
65 }
66 
getWidth() const67 uint32_t Camera3Stream::getWidth() const {
68     return camera3_stream::width;
69 }
70 
getHeight() const71 uint32_t Camera3Stream::getHeight() const {
72     return camera3_stream::height;
73 }
74 
getFormat() const75 int Camera3Stream::getFormat() const {
76     return camera3_stream::format;
77 }
78 
startConfiguration()79 camera3_stream* Camera3Stream::startConfiguration() {
80     Mutex::Autolock l(mLock);
81 
82     switch (mState) {
83         case STATE_ERROR:
84             ALOGE("%s: In error state", __FUNCTION__);
85             return NULL;
86         case STATE_CONSTRUCTED:
87             // OK
88             break;
89         case STATE_IN_CONFIG:
90         case STATE_IN_RECONFIG:
91             // Can start config again with no trouble; but don't redo
92             // oldUsage/oldMaxBuffers
93             return this;
94         case STATE_CONFIGURED:
95             if (stream_type == CAMERA3_STREAM_INPUT) {
96                 ALOGE("%s: Cannot configure an input stream twice",
97                         __FUNCTION__);
98                 return NULL;
99             } else if (hasOutstandingBuffersLocked()) {
100                 ALOGE("%s: Cannot configure stream; has outstanding buffers",
101                         __FUNCTION__);
102                 return NULL;
103             }
104             break;
105         default:
106             ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
107             return NULL;
108     }
109 
110     oldUsage = usage;
111     oldMaxBuffers = max_buffers;
112 
113     if (mState == STATE_CONSTRUCTED) {
114         mState = STATE_IN_CONFIG;
115     } else { // mState == STATE_CONFIGURED
116         mState = STATE_IN_RECONFIG;
117     }
118 
119     return this;
120 }
121 
isConfiguring() const122 bool Camera3Stream::isConfiguring() const {
123     Mutex::Autolock l(mLock);
124     return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
125 }
126 
finishConfiguration(camera3_device * hal3Device)127 status_t Camera3Stream::finishConfiguration(camera3_device *hal3Device) {
128     Mutex::Autolock l(mLock);
129     switch (mState) {
130         case STATE_ERROR:
131             ALOGE("%s: In error state", __FUNCTION__);
132             return INVALID_OPERATION;
133         case STATE_IN_CONFIG:
134         case STATE_IN_RECONFIG:
135             // OK
136             break;
137         case STATE_CONSTRUCTED:
138         case STATE_CONFIGURED:
139             ALOGE("%s: Cannot finish configuration that hasn't been started",
140                     __FUNCTION__);
141             return INVALID_OPERATION;
142         default:
143             ALOGE("%s: Unknown state", __FUNCTION__);
144             return INVALID_OPERATION;
145     }
146 
147     // Check if the stream configuration is unchanged, and skip reallocation if
148     // so. As documented in hardware/camera3.h:configure_streams().
149     if (mState == STATE_IN_RECONFIG &&
150             oldUsage == usage &&
151             oldMaxBuffers == max_buffers) {
152         mState = STATE_CONFIGURED;
153         return OK;
154     }
155 
156     status_t res;
157     res = configureQueueLocked();
158     if (res != OK) {
159         ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
160                 __FUNCTION__, mId, strerror(-res), res);
161         mState = STATE_ERROR;
162         return res;
163     }
164 
165     res = registerBuffersLocked(hal3Device);
166     if (res != OK) {
167         ALOGE("%s: Unable to register stream buffers with HAL: %s (%d)",
168                 __FUNCTION__, strerror(-res), res);
169         mState = STATE_ERROR;
170         return res;
171     }
172 
173     mState = STATE_CONFIGURED;
174 
175     return res;
176 }
177 
getBuffer(camera3_stream_buffer * buffer)178 status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) {
179     ATRACE_CALL();
180     Mutex::Autolock l(mLock);
181 
182     status_t res = getBufferLocked(buffer);
183     if (res == OK) {
184         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
185     }
186 
187     return res;
188 }
189 
returnBuffer(const camera3_stream_buffer & buffer,nsecs_t timestamp)190 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
191         nsecs_t timestamp) {
192     ATRACE_CALL();
193     Mutex::Autolock l(mLock);
194 
195     status_t res = returnBufferLocked(buffer, timestamp);
196     if (res == OK) {
197         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
198     }
199 
200     return res;
201 }
202 
getInputBuffer(camera3_stream_buffer * buffer)203 status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) {
204     ATRACE_CALL();
205     Mutex::Autolock l(mLock);
206 
207     status_t res = getInputBufferLocked(buffer);
208     if (res == OK) {
209         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
210     }
211 
212     return res;
213 }
214 
returnInputBuffer(const camera3_stream_buffer & buffer)215 status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) {
216     ATRACE_CALL();
217     Mutex::Autolock l(mLock);
218 
219     status_t res = returnInputBufferLocked(buffer);
220     if (res == OK) {
221         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
222     }
223     return res;
224 }
225 
fireBufferListenersLocked(const camera3_stream_buffer &,bool acquired,bool output)226 void Camera3Stream::fireBufferListenersLocked(
227         const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) {
228     List<wp<Camera3StreamBufferListener> >::iterator it, end;
229 
230     // TODO: finish implementing
231 
232     Camera3StreamBufferListener::BufferInfo info =
233         Camera3StreamBufferListener::BufferInfo();
234     info.mOutput = output;
235     // TODO: rest of fields
236 
237     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
238          it != end;
239          ++it) {
240 
241         sp<Camera3StreamBufferListener> listener = it->promote();
242         if (listener != 0) {
243             if (acquired) {
244                 listener->onBufferAcquired(info);
245             } else {
246                 listener->onBufferReleased(info);
247             }
248         }
249     }
250 }
251 
hasOutstandingBuffers() const252 bool Camera3Stream::hasOutstandingBuffers() const {
253     ATRACE_CALL();
254     Mutex::Autolock l(mLock);
255     return hasOutstandingBuffersLocked();
256 }
257 
disconnect()258 status_t Camera3Stream::disconnect() {
259     ATRACE_CALL();
260     Mutex::Autolock l(mLock);
261     ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
262     status_t res = disconnectLocked();
263 
264     if (res == -ENOTCONN) {
265         // "Already disconnected" -- not an error
266         return OK;
267     } else {
268         return res;
269     }
270 }
271 
registerBuffersLocked(camera3_device * hal3Device)272 status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) {
273     ATRACE_CALL();
274     status_t res;
275 
276     size_t bufferCount = getBufferCountLocked();
277 
278     Vector<buffer_handle_t*> buffers;
279     buffers.insertAt(NULL, 0, bufferCount);
280 
281     camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set();
282     bufferSet.stream = this;
283     bufferSet.num_buffers = bufferCount;
284     bufferSet.buffers = buffers.editArray();
285 
286     Vector<camera3_stream_buffer_t> streamBuffers;
287     streamBuffers.insertAt(camera3_stream_buffer_t(), 0, bufferCount);
288 
289     // Register all buffers with the HAL. This means getting all the buffers
290     // from the stream, providing them to the HAL with the
291     // register_stream_buffers() method, and then returning them back to the
292     // stream in the error state, since they won't have valid data.
293     //
294     // Only registered buffers can be sent to the HAL.
295 
296     uint32_t bufferIdx = 0;
297     for (; bufferIdx < bufferCount; bufferIdx++) {
298         res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) );
299         if (res != OK) {
300             ALOGE("%s: Unable to get buffer %d for registration with HAL",
301                     __FUNCTION__, bufferIdx);
302             // Skip registering, go straight to cleanup
303             break;
304         }
305 
306         sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence);
307         fence->waitForever("Camera3Stream::registerBuffers");
308 
309         buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer;
310     }
311     if (bufferIdx == bufferCount) {
312         // Got all buffers, register with HAL
313         ALOGV("%s: Registering %d buffers with camera HAL",
314                 __FUNCTION__, bufferCount);
315         res = hal3Device->ops->register_stream_buffers(hal3Device,
316                 &bufferSet);
317     }
318 
319     // Return all valid buffers to stream, in ERROR state to indicate
320     // they weren't filled.
321     for (size_t i = 0; i < bufferIdx; i++) {
322         streamBuffers.editItemAt(i).release_fence = -1;
323         streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
324         returnBufferLocked(streamBuffers[i], 0);
325     }
326 
327     return res;
328 }
329 
getBufferLocked(camera3_stream_buffer *)330 status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) {
331     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
332     return INVALID_OPERATION;
333 }
returnBufferLocked(const camera3_stream_buffer &,nsecs_t)334 status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &,
335                                            nsecs_t) {
336     ALOGE("%s: This type of stream does not support output", __FUNCTION__);
337     return INVALID_OPERATION;
338 }
getInputBufferLocked(camera3_stream_buffer *)339 status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) {
340     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
341     return INVALID_OPERATION;
342 }
returnInputBufferLocked(const camera3_stream_buffer &)343 status_t Camera3Stream::returnInputBufferLocked(
344         const camera3_stream_buffer &) {
345     ALOGE("%s: This type of stream does not support input", __FUNCTION__);
346     return INVALID_OPERATION;
347 }
348 
addBufferListener(wp<Camera3StreamBufferListener> listener)349 void Camera3Stream::addBufferListener(
350         wp<Camera3StreamBufferListener> listener) {
351     Mutex::Autolock l(mLock);
352     mBufferListenerList.push_back(listener);
353 }
354 
removeBufferListener(const sp<Camera3StreamBufferListener> & listener)355 void Camera3Stream::removeBufferListener(
356         const sp<Camera3StreamBufferListener>& listener) {
357     Mutex::Autolock l(mLock);
358 
359     bool erased = true;
360     List<wp<Camera3StreamBufferListener> >::iterator it, end;
361     for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
362          it != end;
363          ) {
364 
365         if (*it == listener) {
366             it = mBufferListenerList.erase(it);
367             erased = true;
368         } else {
369             ++it;
370         }
371     }
372 
373     if (!erased) {
374         ALOGW("%s: Could not find listener to remove, already removed",
375               __FUNCTION__);
376     }
377 }
378 
379 }; // namespace camera3
380 
381 }; // namespace android
382