blob: c36cf87ae8922be083268b26501cb95a1f44f5ef [file] [log] [blame]
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -07001/*
2 * Copyright (C) 2012 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 "Camera2-StreamingProcessor"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <utils/Log.h>
22#include <utils/Trace.h>
Mathias Agopian1a2952a2013-02-14 17:11:27 -080023#include <gui/Surface.h>
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070024#include <media/hardware/MetadataBufferType.h>
25
26#include "StreamingProcessor.h"
27#include "Camera2Heap.h"
28#include "../Camera2Client.h"
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080029#include "../CameraDeviceBase.h"
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070030
31namespace android {
32namespace camera2 {
33
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070034StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070035 mClient(client),
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070036 mDevice(client->getCameraDevice()),
37 mId(client->getCameraId()),
Eino-Ville Talvala4865c522012-10-02 13:30:28 -070038 mActiveRequest(NONE),
39 mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070040 mPreviewStreamId(NO_STREAM),
Eino-Ville Talvala4865c522012-10-02 13:30:28 -070041 mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070042 mRecordingStreamId(NO_STREAM),
43 mRecordingHeapCount(kDefaultRecordingHeapCount)
44{
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070045}
46
47StreamingProcessor::~StreamingProcessor() {
48 deletePreviewStream();
49 deleteRecordingStream();
50}
51
52status_t StreamingProcessor::setPreviewWindow(sp<ANativeWindow> window) {
53 ATRACE_CALL();
54 status_t res;
55
56 res = deletePreviewStream();
57 if (res != OK) return res;
58
59 Mutex::Autolock m(mMutex);
60
61 mPreviewWindow = window;
62
63 return OK;
64}
65
66bool StreamingProcessor::haveValidPreviewWindow() const {
67 Mutex::Autolock m(mMutex);
68 return mPreviewWindow != 0;
69}
70
71status_t StreamingProcessor::updatePreviewRequest(const Parameters &params) {
72 ATRACE_CALL();
73 status_t res;
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070074 sp<CameraDeviceBase> device = mDevice.promote();
75 if (device == 0) {
76 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
77 return INVALID_OPERATION;
78 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070079
80 Mutex::Autolock m(mMutex);
81 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070082 res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070083 &mPreviewRequest);
84 if (res != OK) {
85 ALOGE("%s: Camera %d: Unable to create default preview request: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070086 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070087 return res;
88 }
89 }
90
91 res = params.updateRequest(&mPreviewRequest);
92 if (res != OK) {
93 ALOGE("%s: Camera %d: Unable to update common entries of preview "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -070094 "request: %s (%d)", __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -070095 strerror(-res), res);
96 return res;
97 }
98
99 res = mPreviewRequest.update(ANDROID_REQUEST_ID,
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700100 &mPreviewRequestId, 1);
101 if (res != OK) {
102 ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700103 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700104 return res;
105 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700106
107 return OK;
108}
109
110status_t StreamingProcessor::updatePreviewStream(const Parameters &params) {
111 ATRACE_CALL();
112 Mutex::Autolock m(mMutex);
113
114 status_t res;
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700115 sp<CameraDeviceBase> device = mDevice.promote();
116 if (device == 0) {
117 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
118 return INVALID_OPERATION;
119 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700120
121 if (mPreviewStreamId != NO_STREAM) {
122 // Check if stream parameters have to change
123 uint32_t currentWidth, currentHeight;
124 res = device->getStreamInfo(mPreviewStreamId,
125 &currentWidth, &currentHeight, 0);
126 if (res != OK) {
127 ALOGE("%s: Camera %d: Error querying preview stream info: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700128 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700129 return res;
130 }
131 if (currentWidth != (uint32_t)params.previewWidth ||
132 currentHeight != (uint32_t)params.previewHeight) {
133 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700134 __FUNCTION__, mId, currentWidth, currentHeight,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700135 params.previewWidth, params.previewHeight);
136 res = device->waitUntilDrained();
137 if (res != OK) {
138 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700139 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700140 return res;
141 }
142 res = device->deleteStream(mPreviewStreamId);
143 if (res != OK) {
144 ALOGE("%s: Camera %d: Unable to delete old output stream "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700145 "for preview: %s (%d)", __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700146 strerror(-res), res);
147 return res;
148 }
149 mPreviewStreamId = NO_STREAM;
150 }
151 }
152
153 if (mPreviewStreamId == NO_STREAM) {
154 res = device->createStream(mPreviewWindow,
155 params.previewWidth, params.previewHeight,
156 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
157 &mPreviewStreamId);
158 if (res != OK) {
159 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700160 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700161 return res;
162 }
163 }
164
165 res = device->setStreamTransform(mPreviewStreamId,
166 params.previewTransform);
167 if (res != OK) {
168 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700169 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700170 return res;
171 }
172
173 return OK;
174}
175
176status_t StreamingProcessor::deletePreviewStream() {
177 ATRACE_CALL();
178 status_t res;
179
180 Mutex::Autolock m(mMutex);
181
182 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700183 sp<CameraDeviceBase> device = mDevice.promote();
184 if (device == 0) {
185 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
186 return INVALID_OPERATION;
187 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700188
Igor Murashkinecf17e82012-10-02 16:05:11 -0700189 ALOGV("%s: for cameraId %d on streamId %d",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700190 __FUNCTION__, mId, mPreviewStreamId);
Igor Murashkinecf17e82012-10-02 16:05:11 -0700191
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700192 res = device->waitUntilDrained();
193 if (res != OK) {
194 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
195 __FUNCTION__, strerror(-res), res);
196 return res;
197 }
198 res = device->deleteStream(mPreviewStreamId);
199 if (res != OK) {
200 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
201 __FUNCTION__, strerror(-res), res);
202 return res;
203 }
204 mPreviewStreamId = NO_STREAM;
205 }
206 return OK;
207}
208
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700209int StreamingProcessor::getPreviewStreamId() const {
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700210 Mutex::Autolock m(mMutex);
211 return mPreviewStreamId;
212}
213
214status_t StreamingProcessor::setRecordingBufferCount(size_t count) {
215 ATRACE_CALL();
216 // 32 is the current upper limit on the video buffer count for BufferQueue
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700217 if (count > 32) {
218 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700219 __FUNCTION__, mId, count);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700220 return BAD_VALUE;
221 }
222
223 Mutex::Autolock m(mMutex);
224
225 // Need to reallocate memory for heap
226 if (mRecordingHeapCount != count) {
227 if (mRecordingHeap != 0) {
228 mRecordingHeap.clear();
229 mRecordingHeap = NULL;
230 }
231 mRecordingHeapCount = count;
232 }
233
234 return OK;
235}
236
237status_t StreamingProcessor::updateRecordingRequest(const Parameters &params) {
238 ATRACE_CALL();
239 status_t res;
240 Mutex::Autolock m(mMutex);
241
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700242 sp<CameraDeviceBase> device = mDevice.promote();
243 if (device == 0) {
244 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
245 return INVALID_OPERATION;
246 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700247
248 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700249 res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700250 &mRecordingRequest);
251 if (res != OK) {
252 ALOGE("%s: Camera %d: Unable to create default recording request:"
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700253 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700254 return res;
255 }
256 }
257
258 res = params.updateRequest(&mRecordingRequest);
259 if (res != OK) {
260 ALOGE("%s: Camera %d: Unable to update common entries of recording "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700261 "request: %s (%d)", __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700262 strerror(-res), res);
263 return res;
264 }
265
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700266 res = mRecordingRequest.update(ANDROID_REQUEST_ID,
267 &mRecordingRequestId, 1);
268 if (res != OK) {
269 ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700270 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700271 return res;
272 }
273
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700274 return OK;
275}
276
277status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
278 ATRACE_CALL();
279 status_t res;
280 Mutex::Autolock m(mMutex);
281
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700282 sp<CameraDeviceBase> device = mDevice.promote();
283 if (device == 0) {
284 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
285 return INVALID_OPERATION;
286 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700287
288 if (mRecordingConsumer == 0) {
289 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
290 // always acquire and free a buffer when the heap is full; otherwise the consumer
291 // will have buffers in flight we'll never clear out.
292 mRecordingConsumer = new BufferItemConsumer(
293 GRALLOC_USAGE_HW_VIDEO_ENCODER,
294 mRecordingHeapCount + 1,
295 true);
296 mRecordingConsumer->setFrameAvailableListener(this);
297 mRecordingConsumer->setName(String8("Camera2-RecordingConsumer"));
Mathias Agopian1a2952a2013-02-14 17:11:27 -0800298 mRecordingWindow = new Surface(
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700299 mRecordingConsumer->getProducerInterface());
300 // Allocate memory later, since we don't know buffer size until receipt
301 }
302
303 if (mRecordingStreamId != NO_STREAM) {
304 // Check if stream parameters have to change
305 uint32_t currentWidth, currentHeight;
306 res = device->getStreamInfo(mRecordingStreamId,
307 &currentWidth, &currentHeight, 0);
308 if (res != OK) {
309 ALOGE("%s: Camera %d: Error querying recording output stream info: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700310 "%s (%d)", __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700311 strerror(-res), res);
312 return res;
313 }
314 if (currentWidth != (uint32_t)params.videoWidth ||
315 currentHeight != (uint32_t)params.videoHeight) {
316 // TODO: Should wait to be sure previous recording has finished
317 res = device->deleteStream(mRecordingStreamId);
318 if (res != OK) {
319 ALOGE("%s: Camera %d: Unable to delete old output stream "
320 "for recording: %s (%d)", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700321 mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700322 return res;
323 }
324 mRecordingStreamId = NO_STREAM;
325 }
326 }
327
328 if (mRecordingStreamId == NO_STREAM) {
329 mRecordingFrameCount = 0;
330 res = device->createStream(mRecordingWindow,
331 params.videoWidth, params.videoHeight,
332 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
333 if (res != OK) {
334 ALOGE("%s: Camera %d: Can't create output stream for recording: "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700335 "%s (%d)", __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700336 strerror(-res), res);
337 return res;
338 }
339 }
340
341 return OK;
342}
343
344status_t StreamingProcessor::deleteRecordingStream() {
345 ATRACE_CALL();
346 status_t res;
347
348 Mutex::Autolock m(mMutex);
349
350 if (mRecordingStreamId != NO_STREAM) {
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700351 sp<CameraDeviceBase> device = mDevice.promote();
352 if (device == 0) {
353 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
354 return INVALID_OPERATION;
355 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700356
357 res = device->waitUntilDrained();
358 if (res != OK) {
359 ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
360 __FUNCTION__, strerror(-res), res);
361 return res;
362 }
363 res = device->deleteStream(mRecordingStreamId);
364 if (res != OK) {
365 ALOGE("%s: Unable to delete recording stream: %s (%d)",
366 __FUNCTION__, strerror(-res), res);
367 return res;
368 }
369 mRecordingStreamId = NO_STREAM;
370 }
371 return OK;
372}
373
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700374int StreamingProcessor::getRecordingStreamId() const {
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700375 return mRecordingStreamId;
376}
377
378status_t StreamingProcessor::startStream(StreamType type,
379 const Vector<uint8_t> &outputStreams) {
380 ATRACE_CALL();
381 status_t res;
382
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700383 if (type == NONE) return INVALID_OPERATION;
384
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700385 sp<CameraDeviceBase> device = mDevice.promote();
386 if (device == 0) {
387 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
388 return INVALID_OPERATION;
389 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700390
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700391 ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type);
Igor Murashkin22d58d32012-10-02 19:07:14 -0700392
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700393 Mutex::Autolock m(mMutex);
394
395 CameraMetadata &request = (type == PREVIEW) ?
396 mPreviewRequest : mRecordingRequest;
397
398 res = request.update(
399 ANDROID_REQUEST_OUTPUT_STREAMS,
400 outputStreams);
401 if (res != OK) {
402 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700403 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700404 return res;
405 }
406
407 res = request.sort();
408 if (res != OK) {
409 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700410 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700411 return res;
412 }
413
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700414 res = device->setStreamingRequest(request);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700415 if (res != OK) {
416 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
417 "%s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700418 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700419 return res;
420 }
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700421 mActiveRequest = type;
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700422
423 return OK;
424}
425
426status_t StreamingProcessor::stopStream() {
427 ATRACE_CALL();
428 status_t res;
429
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700430 Mutex::Autolock m(mMutex);
431
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700432 sp<CameraDeviceBase> device = mDevice.promote();
433 if (device == 0) {
434 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
435 return INVALID_OPERATION;
436 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700437
438 res = device->clearStreamingRequest();
439 if (res != OK) {
440 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700441 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700442 return res;
443 }
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700444
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700445 mActiveRequest = NONE;
446
447 return OK;
448}
449
450int32_t StreamingProcessor::getActiveRequestId() const {
451 Mutex::Autolock m(mMutex);
452 switch (mActiveRequest) {
453 case NONE:
454 return 0;
455 case PREVIEW:
456 return mPreviewRequestId;
457 case RECORD:
458 return mRecordingRequestId;
459 default:
460 ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest);
461 return 0;
462 }
463}
464
465status_t StreamingProcessor::incrementStreamingIds() {
466 ATRACE_CALL();
467 Mutex::Autolock m(mMutex);
468
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700469 mPreviewRequestId++;
470 if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
471 mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
472 }
473 mRecordingRequestId++;
474 if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) {
475 mRecordingRequestId = Camera2Client::kRecordingRequestIdStart;
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700476 }
477 return OK;
478}
479
480void StreamingProcessor::onFrameAvailable() {
481 ATRACE_CALL();
482 status_t res;
483 sp<Camera2Heap> recordingHeap;
484 size_t heapIdx = 0;
485 nsecs_t timestamp;
486
487 sp<Camera2Client> client = mClient.promote();
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700488 if (client == 0) {
489 // Discard frames during shutdown
490 BufferItemConsumer::BufferItem imgBuffer;
491 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
492 if (res != OK) {
493 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
494 __FUNCTION__, mId, strerror(-res), res);
495 return;
496 }
497 mRecordingConsumer->releaseBuffer(imgBuffer);
498 return;
499 }
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700500
501 {
Igor Murashkin04273cb2012-10-03 16:02:09 -0700502 /* acquire SharedParameters before mMutex so we don't dead lock
503 with Camera2Client code calling into StreamingProcessor */
504 SharedParameters::Lock l(client->getParameters());
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700505 Mutex::Autolock m(mMutex);
506 BufferItemConsumer::BufferItem imgBuffer;
507 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
508 if (res != OK) {
509 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700510 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700511 return;
512 }
513 timestamp = imgBuffer.mTimestamp;
514
515 mRecordingFrameCount++;
516 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
517
Igor Murashkin04273cb2012-10-03 16:02:09 -0700518 // TODO: Signal errors here upstream
519 if (l.mParameters.state != Parameters::RECORD &&
520 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
521 ALOGV("%s: Camera %d: Discarding recording image buffers "
522 "received after recording done", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700523 mId);
Igor Murashkin04273cb2012-10-03 16:02:09 -0700524 mRecordingConsumer->releaseBuffer(imgBuffer);
525 return;
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700526 }
527
528 if (mRecordingHeap == 0) {
529 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
530 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700531 "size %d bytes", __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700532 mRecordingHeapCount, bufferSize);
533
534 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
535 "Camera2Client::RecordingHeap");
536 if (mRecordingHeap->mHeap->getSize() == 0) {
537 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700538 __FUNCTION__, mId);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700539 mRecordingConsumer->releaseBuffer(imgBuffer);
540 return;
541 }
542 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
543 if (mRecordingBuffers[i].mBuf !=
544 BufferItemConsumer::INVALID_BUFFER_SLOT) {
545 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700546 __FUNCTION__, mId);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700547 }
548 }
549 mRecordingBuffers.clear();
550 mRecordingBuffers.setCapacity(mRecordingHeapCount);
551 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
552
553 mRecordingHeapHead = 0;
554 mRecordingHeapFree = mRecordingHeapCount;
555 }
556
557 if ( mRecordingHeapFree == 0) {
558 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700559 __FUNCTION__, mId);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700560 mRecordingConsumer->releaseBuffer(imgBuffer);
561 return;
562 }
563
564 heapIdx = mRecordingHeapHead;
565 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
566 mRecordingHeapFree--;
567
568 ALOGV("%s: Camera %d: Timestamp %lld",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700569 __FUNCTION__, mId, timestamp);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700570
571 ssize_t offset;
572 size_t size;
573 sp<IMemoryHeap> heap =
574 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
575 &size);
576
577 uint8_t *data = (uint8_t*)heap->getBase() + offset;
578 uint32_t type = kMetadataBufferTypeGrallocSource;
579 *((uint32_t*)data) = type;
580 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
581 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700582 __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700583 imgBuffer.mGraphicBuffer->handle);
584 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
585 recordingHeap = mRecordingHeap;
586 }
587
588 // Call outside locked parameters to allow re-entrancy from notification
Igor Murashkin44cfcf02013-03-01 16:22:28 -0800589 Camera2Client::SharedCameraCallbacks::Lock l(client->mSharedCameraCallbacks);
590 if (l.mRemoteCallback != 0) {
591 l.mRemoteCallback->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700592 CAMERA_MSG_VIDEO_FRAME,
593 recordingHeap->mBuffers[heapIdx]);
594 }
595}
596
597void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) {
598 ATRACE_CALL();
599 status_t res;
600
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700601 Mutex::Autolock m(mMutex);
602 // Make sure this is for the current heap
603 ssize_t offset;
604 size_t size;
605 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
606 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
607 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700608 "(got %x, expected %x)", __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700609 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
610 return;
611 }
612 uint8_t *data = (uint8_t*)heap->getBase() + offset;
613 uint32_t type = *(uint32_t*)data;
614 if (type != kMetadataBufferTypeGrallocSource) {
615 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700616 __FUNCTION__, mId, type,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700617 kMetadataBufferTypeGrallocSource);
618 return;
619 }
620
621 // Release the buffer back to the recording queue
622
623 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
624
625 size_t itemIndex;
626 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
627 const BufferItemConsumer::BufferItem item =
628 mRecordingBuffers[itemIndex];
629 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
630 item.mGraphicBuffer->handle == imgHandle) {
631 break;
632 }
633 }
634 if (itemIndex == mRecordingBuffers.size()) {
635 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700636 "outstanding buffers", __FUNCTION__, mId,
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700637 imgHandle);
638 return;
639 }
640
641 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700642 mId, imgHandle);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700643
644 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
645 if (res != OK) {
646 ALOGE("%s: Camera %d: Unable to free recording frame "
647 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__,
Eino-Ville Talvalad09801b2013-04-23 15:16:57 -0700648 mId, imgHandle, strerror(-res), res);
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700649 return;
650 }
651 mRecordingBuffers.replaceAt(itemIndex);
652
653 mRecordingHeapFree++;
654}
655
656
Igor Murashkinddf3c502012-10-12 16:56:11 -0700657status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
Eino-Ville Talvala73bbd1f2012-09-26 10:45:47 -0700658 String8 result;
659
660 result.append(" Current requests:\n");
661 if (mPreviewRequest.entryCount() != 0) {
662 result.append(" Preview request:\n");
663 write(fd, result.string(), result.size());
664 mPreviewRequest.dump(fd, 2, 6);
665 } else {
666 result.append(" Preview request: undefined\n");
667 write(fd, result.string(), result.size());
668 }
669
670 if (mRecordingRequest.entryCount() != 0) {
671 result = " Recording request:\n";
672 write(fd, result.string(), result.size());
673 mRecordingRequest.dump(fd, 2, 6);
674 } else {
675 result = " Recording request: undefined\n";
676 write(fd, result.string(), result.size());
677 }
678
679 return OK;
680}
681
682}; // namespace camera2
683}; // namespace android