blob: a6872aafa52baff15dc7192c7b86e857fa569681 [file] [log] [blame]
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -08001/*
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
25namespace android {
26
27namespace camera3 {
28
29Camera3Stream::~Camera3Stream() {
30}
31
32Camera3Stream* Camera3Stream::cast(camera3_stream *stream) {
33 return static_cast<Camera3Stream*>(stream);
34}
35
36const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) {
37 return static_cast<const Camera3Stream*>(stream);
38}
39
40Camera3Stream::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
63int Camera3Stream::getId() const {
64 return mId;
65}
66
67uint32_t Camera3Stream::getWidth() const {
68 return camera3_stream::width;
69}
70
71uint32_t Camera3Stream::getHeight() const {
72 return camera3_stream::height;
73}
74
75int Camera3Stream::getFormat() const {
76 return camera3_stream::format;
77}
78
79camera3_stream* Camera3Stream::startConfiguration() {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -070080 ATRACE_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080081 Mutex::Autolock l(mLock);
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -070082 status_t res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080083
84 switch (mState) {
85 case STATE_ERROR:
86 ALOGE("%s: In error state", __FUNCTION__);
87 return NULL;
88 case STATE_CONSTRUCTED:
89 // OK
90 break;
91 case STATE_IN_CONFIG:
92 case STATE_IN_RECONFIG:
93 // Can start config again with no trouble; but don't redo
94 // oldUsage/oldMaxBuffers
95 return this;
96 case STATE_CONFIGURED:
97 if (stream_type == CAMERA3_STREAM_INPUT) {
98 ALOGE("%s: Cannot configure an input stream twice",
99 __FUNCTION__);
100 return NULL;
101 } else if (hasOutstandingBuffersLocked()) {
102 ALOGE("%s: Cannot configure stream; has outstanding buffers",
103 __FUNCTION__);
104 return NULL;
105 }
106 break;
107 default:
108 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
109 return NULL;
110 }
111
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700112 oldUsage = camera3_stream::usage;
113 oldMaxBuffers = camera3_stream::max_buffers;
114
115 res = getEndpointUsage(&(camera3_stream::usage));
116 if (res != OK) {
117 ALOGE("%s: Cannot query consumer endpoint usage!",
118 __FUNCTION__);
119 return NULL;
120 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800121
122 if (mState == STATE_CONSTRUCTED) {
123 mState = STATE_IN_CONFIG;
124 } else { // mState == STATE_CONFIGURED
125 mState = STATE_IN_RECONFIG;
126 }
127
128 return this;
129}
130
131bool Camera3Stream::isConfiguring() const {
132 Mutex::Autolock l(mLock);
133 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
134}
135
136status_t Camera3Stream::finishConfiguration(camera3_device *hal3Device) {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700137 ATRACE_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800138 Mutex::Autolock l(mLock);
139 switch (mState) {
140 case STATE_ERROR:
141 ALOGE("%s: In error state", __FUNCTION__);
142 return INVALID_OPERATION;
143 case STATE_IN_CONFIG:
144 case STATE_IN_RECONFIG:
145 // OK
146 break;
147 case STATE_CONSTRUCTED:
148 case STATE_CONFIGURED:
149 ALOGE("%s: Cannot finish configuration that hasn't been started",
150 __FUNCTION__);
151 return INVALID_OPERATION;
152 default:
153 ALOGE("%s: Unknown state", __FUNCTION__);
154 return INVALID_OPERATION;
155 }
156
157 // Check if the stream configuration is unchanged, and skip reallocation if
158 // so. As documented in hardware/camera3.h:configure_streams().
159 if (mState == STATE_IN_RECONFIG &&
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700160 oldUsage == camera3_stream::usage &&
161 oldMaxBuffers == camera3_stream::max_buffers) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800162 mState = STATE_CONFIGURED;
163 return OK;
164 }
165
166 status_t res;
167 res = configureQueueLocked();
168 if (res != OK) {
169 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
170 __FUNCTION__, mId, strerror(-res), res);
171 mState = STATE_ERROR;
172 return res;
173 }
174
175 res = registerBuffersLocked(hal3Device);
176 if (res != OK) {
177 ALOGE("%s: Unable to register stream buffers with HAL: %s (%d)",
178 __FUNCTION__, strerror(-res), res);
179 mState = STATE_ERROR;
180 return res;
181 }
182
183 mState = STATE_CONFIGURED;
184
185 return res;
186}
187
188status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) {
189 ATRACE_CALL();
190 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700191
192 status_t res = getBufferLocked(buffer);
193 if (res == OK) {
194 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
195 }
196
197 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800198}
199
200status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
201 nsecs_t timestamp) {
202 ATRACE_CALL();
203 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700204
205 status_t res = returnBufferLocked(buffer, timestamp);
206 if (res == OK) {
207 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
208 }
209
210 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800211}
212
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700213status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) {
214 ATRACE_CALL();
215 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700216
217 status_t res = getInputBufferLocked(buffer);
218 if (res == OK) {
219 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
220 }
221
222 return res;
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700223}
224
225status_t Camera3Stream::returnInputBuffer(const camera3_stream_buffer &buffer) {
226 ATRACE_CALL();
227 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700228
229 status_t res = returnInputBufferLocked(buffer);
230 if (res == OK) {
231 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
232 }
233 return res;
234}
235
236void Camera3Stream::fireBufferListenersLocked(
237 const camera3_stream_buffer& /*buffer*/, bool acquired, bool output) {
238 List<wp<Camera3StreamBufferListener> >::iterator it, end;
239
240 // TODO: finish implementing
241
242 Camera3StreamBufferListener::BufferInfo info =
243 Camera3StreamBufferListener::BufferInfo();
244 info.mOutput = output;
245 // TODO: rest of fields
246
247 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
248 it != end;
249 ++it) {
250
251 sp<Camera3StreamBufferListener> listener = it->promote();
252 if (listener != 0) {
253 if (acquired) {
254 listener->onBufferAcquired(info);
255 } else {
256 listener->onBufferReleased(info);
257 }
258 }
259 }
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700260}
261
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800262bool Camera3Stream::hasOutstandingBuffers() const {
263 ATRACE_CALL();
264 Mutex::Autolock l(mLock);
265 return hasOutstandingBuffersLocked();
266}
267
268status_t Camera3Stream::disconnect() {
269 ATRACE_CALL();
270 Mutex::Autolock l(mLock);
Igor Murashkine2172be2013-05-28 15:31:39 -0700271 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
272 status_t res = disconnectLocked();
273
274 if (res == -ENOTCONN) {
275 // "Already disconnected" -- not an error
276 return OK;
277 } else {
278 return res;
279 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800280}
281
282status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) {
283 ATRACE_CALL();
284 status_t res;
285
286 size_t bufferCount = getBufferCountLocked();
287
288 Vector<buffer_handle_t*> buffers;
289 buffers.insertAt(NULL, 0, bufferCount);
290
291 camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set();
292 bufferSet.stream = this;
293 bufferSet.num_buffers = bufferCount;
294 bufferSet.buffers = buffers.editArray();
295
296 Vector<camera3_stream_buffer_t> streamBuffers;
297 streamBuffers.insertAt(camera3_stream_buffer_t(), 0, bufferCount);
298
299 // Register all buffers with the HAL. This means getting all the buffers
300 // from the stream, providing them to the HAL with the
301 // register_stream_buffers() method, and then returning them back to the
302 // stream in the error state, since they won't have valid data.
303 //
304 // Only registered buffers can be sent to the HAL.
305
306 uint32_t bufferIdx = 0;
307 for (; bufferIdx < bufferCount; bufferIdx++) {
308 res = getBufferLocked( &streamBuffers.editItemAt(bufferIdx) );
309 if (res != OK) {
310 ALOGE("%s: Unable to get buffer %d for registration with HAL",
311 __FUNCTION__, bufferIdx);
312 // Skip registering, go straight to cleanup
313 break;
314 }
315
316 sp<Fence> fence = new Fence(streamBuffers[bufferIdx].acquire_fence);
Mathias Agopiand7644242013-05-16 18:07:35 -0700317 fence->waitForever("Camera3Stream::registerBuffers");
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800318
319 buffers.editItemAt(bufferIdx) = streamBuffers[bufferIdx].buffer;
320 }
321 if (bufferIdx == bufferCount) {
322 // Got all buffers, register with HAL
323 ALOGV("%s: Registering %d buffers with camera HAL",
324 __FUNCTION__, bufferCount);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700325 ATRACE_BEGIN("camera3->register_stream_buffers");
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800326 res = hal3Device->ops->register_stream_buffers(hal3Device,
327 &bufferSet);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700328 ATRACE_END();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800329 }
330
331 // Return all valid buffers to stream, in ERROR state to indicate
332 // they weren't filled.
333 for (size_t i = 0; i < bufferIdx; i++) {
334 streamBuffers.editItemAt(i).release_fence = -1;
335 streamBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
336 returnBufferLocked(streamBuffers[i], 0);
337 }
338
339 return res;
340}
341
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700342status_t Camera3Stream::getBufferLocked(camera3_stream_buffer *) {
343 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
344 return INVALID_OPERATION;
345}
346status_t Camera3Stream::returnBufferLocked(const camera3_stream_buffer &,
347 nsecs_t) {
348 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
349 return INVALID_OPERATION;
350}
351status_t Camera3Stream::getInputBufferLocked(camera3_stream_buffer *) {
352 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
353 return INVALID_OPERATION;
354}
355status_t Camera3Stream::returnInputBufferLocked(
356 const camera3_stream_buffer &) {
357 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
358 return INVALID_OPERATION;
359}
360
Igor Murashkin2fba5842013-04-22 14:03:54 -0700361void Camera3Stream::addBufferListener(
362 wp<Camera3StreamBufferListener> listener) {
363 Mutex::Autolock l(mLock);
364 mBufferListenerList.push_back(listener);
365}
366
367void Camera3Stream::removeBufferListener(
368 const sp<Camera3StreamBufferListener>& listener) {
369 Mutex::Autolock l(mLock);
370
371 bool erased = true;
372 List<wp<Camera3StreamBufferListener> >::iterator it, end;
373 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
374 it != end;
375 ) {
376
377 if (*it == listener) {
378 it = mBufferListenerList.erase(it);
379 erased = true;
380 } else {
381 ++it;
382 }
383 }
384
385 if (!erased) {
386 ALOGW("%s: Could not find listener to remove, already removed",
387 __FUNCTION__);
388 }
389}
390
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800391}; // namespace camera3
392
393}; // namespace android