1 /*
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 //#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22 #ifdef LOG_NNDEBUG
23 #define ALOGVV(...) ALOGV(__VA_ARGS__)
24 #else
25 #define ALOGVV(...) ((void)0)
26 #endif
27
28 #include <cutils/properties.h>
29 #include <utils/Log.h>
30 #include <utils/Trace.h>
31 #include <gui/BufferItem.h>
32 #include <gui/Surface.h>
33 #include <media/hardware/HardwareAPI.h>
34
35 #include "common/CameraDeviceBase.h"
36 #include "api1/Camera2Client.h"
37 #include "api1/client2/StreamingProcessor.h"
38 #include "api1/client2/Camera2Heap.h"
39
40 namespace android {
41 namespace camera2 {
42
StreamingProcessor(sp<Camera2Client> client)43 StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
44 mClient(client),
45 mDevice(client->getCameraDevice()),
46 mId(client->getCameraId()),
47 mActiveRequest(NONE),
48 mPaused(false),
49 mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
50 mPreviewStreamId(NO_STREAM),
51 mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
52 mRecordingStreamId(NO_STREAM),
53 mRecordingFrameAvailable(false),
54 mRecordingHeapCount(kDefaultRecordingHeapCount),
55 mRecordingHeapFree(kDefaultRecordingHeapCount),
56 mRecordingFormat(kDefaultRecordingFormat),
57 mRecordingDataSpace(kDefaultRecordingDataSpace),
58 mRecordingGrallocUsage(kDefaultRecordingGrallocUsage)
59 {
60 }
61
~StreamingProcessor()62 StreamingProcessor::~StreamingProcessor() {
63 deletePreviewStream();
64 deleteRecordingStream();
65 }
66
setPreviewWindow(sp<Surface> window)67 status_t StreamingProcessor::setPreviewWindow(sp<Surface> window) {
68 ATRACE_CALL();
69 status_t res;
70
71 res = deletePreviewStream();
72 if (res != OK) return res;
73
74 Mutex::Autolock m(mMutex);
75
76 mPreviewWindow = window;
77
78 return OK;
79 }
80
haveValidPreviewWindow() const81 bool StreamingProcessor::haveValidPreviewWindow() const {
82 Mutex::Autolock m(mMutex);
83 return mPreviewWindow != 0;
84 }
85
updatePreviewRequest(const Parameters & params)86 status_t StreamingProcessor::updatePreviewRequest(const Parameters ¶ms) {
87 ATRACE_CALL();
88 status_t res;
89 sp<CameraDeviceBase> device = mDevice.promote();
90 if (device == 0) {
91 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
92 return INVALID_OPERATION;
93 }
94
95 Mutex::Autolock m(mMutex);
96 if (mPreviewRequest.entryCount() == 0) {
97 sp<Camera2Client> client = mClient.promote();
98 if (client == 0) {
99 ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
100 return INVALID_OPERATION;
101 }
102
103 // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case.
104 if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
105 if (params.zslMode && !params.recordingHint) {
106 res = device->createDefaultRequest(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
107 &mPreviewRequest);
108 } else {
109 res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW,
110 &mPreviewRequest);
111 }
112 } else {
113 res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
114 &mPreviewRequest);
115 }
116
117 if (res != OK) {
118 ALOGE("%s: Camera %d: Unable to create default preview request: "
119 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
120 return res;
121 }
122 }
123
124 res = params.updateRequest(&mPreviewRequest);
125 if (res != OK) {
126 ALOGE("%s: Camera %d: Unable to update common entries of preview "
127 "request: %s (%d)", __FUNCTION__, mId,
128 strerror(-res), res);
129 return res;
130 }
131
132 res = mPreviewRequest.update(ANDROID_REQUEST_ID,
133 &mPreviewRequestId, 1);
134 if (res != OK) {
135 ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)",
136 __FUNCTION__, mId, strerror(-res), res);
137 return res;
138 }
139
140 return OK;
141 }
142
updatePreviewStream(const Parameters & params)143 status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) {
144 ATRACE_CALL();
145 Mutex::Autolock m(mMutex);
146
147 status_t res;
148 sp<CameraDeviceBase> device = mDevice.promote();
149 if (device == 0) {
150 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
151 return INVALID_OPERATION;
152 }
153
154 if (mPreviewStreamId != NO_STREAM) {
155 // Check if stream parameters have to change
156 uint32_t currentWidth, currentHeight;
157 res = device->getStreamInfo(mPreviewStreamId,
158 ¤tWidth, ¤tHeight, 0, 0);
159 if (res != OK) {
160 ALOGE("%s: Camera %d: Error querying preview stream info: "
161 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
162 return res;
163 }
164 if (currentWidth != (uint32_t)params.previewWidth ||
165 currentHeight != (uint32_t)params.previewHeight) {
166 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
167 __FUNCTION__, mId, currentWidth, currentHeight,
168 params.previewWidth, params.previewHeight);
169 res = device->waitUntilDrained();
170 if (res != OK) {
171 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
172 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
173 return res;
174 }
175 res = device->deleteStream(mPreviewStreamId);
176 if (res != OK) {
177 ALOGE("%s: Camera %d: Unable to delete old output stream "
178 "for preview: %s (%d)", __FUNCTION__, mId,
179 strerror(-res), res);
180 return res;
181 }
182 mPreviewStreamId = NO_STREAM;
183 }
184 }
185
186 if (mPreviewStreamId == NO_STREAM) {
187 res = device->createStream(mPreviewWindow,
188 params.previewWidth, params.previewHeight,
189 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN,
190 CAMERA3_STREAM_ROTATION_0, &mPreviewStreamId);
191 if (res != OK) {
192 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
193 __FUNCTION__, mId, strerror(-res), res);
194 return res;
195 }
196 }
197
198 res = device->setStreamTransform(mPreviewStreamId,
199 params.previewTransform);
200 if (res != OK) {
201 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
202 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
203 return res;
204 }
205
206 return OK;
207 }
208
deletePreviewStream()209 status_t StreamingProcessor::deletePreviewStream() {
210 ATRACE_CALL();
211 status_t res;
212
213 Mutex::Autolock m(mMutex);
214
215 if (mPreviewStreamId != NO_STREAM) {
216 sp<CameraDeviceBase> device = mDevice.promote();
217 if (device == 0) {
218 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
219 return INVALID_OPERATION;
220 }
221
222 ALOGV("%s: for cameraId %d on streamId %d",
223 __FUNCTION__, mId, mPreviewStreamId);
224
225 res = device->waitUntilDrained();
226 if (res != OK) {
227 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
228 __FUNCTION__, strerror(-res), res);
229 return res;
230 }
231 res = device->deleteStream(mPreviewStreamId);
232 if (res != OK) {
233 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
234 __FUNCTION__, strerror(-res), res);
235 return res;
236 }
237 mPreviewStreamId = NO_STREAM;
238 }
239 return OK;
240 }
241
getPreviewStreamId() const242 int StreamingProcessor::getPreviewStreamId() const {
243 Mutex::Autolock m(mMutex);
244 return mPreviewStreamId;
245 }
246
setRecordingBufferCount(size_t count)247 status_t StreamingProcessor::setRecordingBufferCount(size_t count) {
248 ATRACE_CALL();
249 // Make sure we can support this many buffer slots
250 if (count > BufferQueue::NUM_BUFFER_SLOTS) {
251 ALOGE("%s: Camera %d: Too many recording buffers requested: %zu, max %d",
252 __FUNCTION__, mId, count, BufferQueue::NUM_BUFFER_SLOTS);
253 return BAD_VALUE;
254 }
255
256 Mutex::Autolock m(mMutex);
257
258 ALOGV("%s: Camera %d: New recording buffer count from encoder: %zu",
259 __FUNCTION__, mId, count);
260
261 // Need to re-size consumer and heap
262 if (mRecordingHeapCount != count) {
263 ALOGV("%s: Camera %d: Resetting recording heap and consumer",
264 __FUNCTION__, mId);
265
266 if (isStreamActive(mActiveStreamIds, mRecordingStreamId)) {
267 ALOGE("%s: Camera %d: Setting recording buffer count when "
268 "recording stream is already active!", __FUNCTION__,
269 mId);
270 return INVALID_OPERATION;
271 }
272
273 releaseAllRecordingFramesLocked();
274
275 if (mRecordingHeap != 0) {
276 mRecordingHeap.clear();
277 }
278 mRecordingHeapCount = count;
279 mRecordingHeapFree = count;
280
281 mRecordingConsumer.clear();
282 }
283
284 return OK;
285 }
286
setRecordingFormat(int format,android_dataspace dataSpace)287 status_t StreamingProcessor::setRecordingFormat(int format,
288 android_dataspace dataSpace) {
289 ATRACE_CALL();
290
291 Mutex::Autolock m(mMutex);
292
293 ALOGV("%s: Camera %d: New recording format/dataspace from encoder: %X, %X",
294 __FUNCTION__, mId, format, dataSpace);
295
296 mRecordingFormat = format;
297 mRecordingDataSpace = dataSpace;
298 int prevGrallocUsage = mRecordingGrallocUsage;
299 if (mRecordingFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
300 mRecordingGrallocUsage = GRALLOC_USAGE_HW_VIDEO_ENCODER;
301 } else {
302 mRecordingGrallocUsage = GRALLOC_USAGE_SW_READ_OFTEN;
303 }
304
305 ALOGV("%s: Camera %d: New recording gralloc usage: %08X", __FUNCTION__, mId,
306 mRecordingGrallocUsage);
307
308 if (prevGrallocUsage != mRecordingGrallocUsage) {
309 ALOGV("%s: Camera %d: Resetting recording consumer for new usage",
310 __FUNCTION__, mId);
311
312 if (isStreamActive(mActiveStreamIds, mRecordingStreamId)) {
313 ALOGE("%s: Camera %d: Changing recording format when "
314 "recording stream is already active!", __FUNCTION__,
315 mId);
316 return INVALID_OPERATION;
317 }
318
319 releaseAllRecordingFramesLocked();
320
321 mRecordingConsumer.clear();
322 }
323
324 return OK;
325 }
326
updateRecordingRequest(const Parameters & params)327 status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) {
328 ATRACE_CALL();
329 status_t res;
330 Mutex::Autolock m(mMutex);
331
332 sp<CameraDeviceBase> device = mDevice.promote();
333 if (device == 0) {
334 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
335 return INVALID_OPERATION;
336 }
337
338 if (mRecordingRequest.entryCount() == 0) {
339 res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
340 &mRecordingRequest);
341 if (res != OK) {
342 ALOGE("%s: Camera %d: Unable to create default recording request:"
343 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
344 return res;
345 }
346 }
347
348 res = params.updateRequest(&mRecordingRequest);
349 if (res != OK) {
350 ALOGE("%s: Camera %d: Unable to update common entries of recording "
351 "request: %s (%d)", __FUNCTION__, mId,
352 strerror(-res), res);
353 return res;
354 }
355
356 res = mRecordingRequest.update(ANDROID_REQUEST_ID,
357 &mRecordingRequestId, 1);
358 if (res != OK) {
359 ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)",
360 __FUNCTION__, mId, strerror(-res), res);
361 return res;
362 }
363
364 return OK;
365 }
366
recordingStreamNeedsUpdate(const Parameters & params,bool * needsUpdate)367 status_t StreamingProcessor::recordingStreamNeedsUpdate(
368 const Parameters ¶ms, bool *needsUpdate) {
369 status_t res;
370
371 if (needsUpdate == 0) {
372 ALOGE("%s: Camera %d: invalid argument", __FUNCTION__, mId);
373 return INVALID_OPERATION;
374 }
375
376 if (mRecordingStreamId == NO_STREAM) {
377 *needsUpdate = true;
378 return OK;
379 }
380
381 sp<CameraDeviceBase> device = mDevice.promote();
382 if (device == 0) {
383 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
384 return INVALID_OPERATION;
385 }
386
387 uint32_t currentWidth, currentHeight, currentFormat;
388 android_dataspace currentDataSpace;
389 res = device->getStreamInfo(mRecordingStreamId,
390 ¤tWidth, ¤tHeight, ¤tFormat, ¤tDataSpace);
391 if (res != OK) {
392 ALOGE("%s: Camera %d: Error querying recording output stream info: "
393 "%s (%d)", __FUNCTION__, mId,
394 strerror(-res), res);
395 return res;
396 }
397
398 if (mRecordingConsumer == 0 ||
399 currentWidth != (uint32_t)params.videoWidth ||
400 currentHeight != (uint32_t)params.videoHeight ||
401 currentFormat != (uint32_t)mRecordingFormat ||
402 currentDataSpace != mRecordingDataSpace) {
403 *needsUpdate = true;
404 }
405 *needsUpdate = false;
406 return res;
407 }
408
updateRecordingStream(const Parameters & params)409 status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) {
410 ATRACE_CALL();
411 status_t res;
412 Mutex::Autolock m(mMutex);
413
414 sp<CameraDeviceBase> device = mDevice.promote();
415 if (device == 0) {
416 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
417 return INVALID_OPERATION;
418 }
419
420 bool newConsumer = false;
421 if (mRecordingConsumer == 0) {
422 ALOGV("%s: Camera %d: Creating recording consumer with %zu + 1 "
423 "consumer-side buffers", __FUNCTION__, mId, mRecordingHeapCount);
424 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
425 // always acquire and free a buffer when the heap is full; otherwise the consumer
426 // will have buffers in flight we'll never clear out.
427 sp<IGraphicBufferProducer> producer;
428 sp<IGraphicBufferConsumer> consumer;
429 BufferQueue::createBufferQueue(&producer, &consumer);
430 mRecordingConsumer = new BufferItemConsumer(consumer,
431 mRecordingGrallocUsage,
432 mRecordingHeapCount + 1);
433 mRecordingConsumer->setFrameAvailableListener(this);
434 mRecordingConsumer->setName(String8("Camera2-RecordingConsumer"));
435 mRecordingWindow = new Surface(producer);
436 newConsumer = true;
437 // Allocate memory later, since we don't know buffer size until receipt
438 }
439
440 if (mRecordingStreamId != NO_STREAM) {
441 // Check if stream parameters have to change
442 uint32_t currentWidth, currentHeight;
443 uint32_t currentFormat;
444 android_dataspace currentDataSpace;
445 res = device->getStreamInfo(mRecordingStreamId,
446 ¤tWidth, ¤tHeight,
447 ¤tFormat, ¤tDataSpace);
448 if (res != OK) {
449 ALOGE("%s: Camera %d: Error querying recording output stream info: "
450 "%s (%d)", __FUNCTION__, mId,
451 strerror(-res), res);
452 return res;
453 }
454 if (currentWidth != (uint32_t)params.videoWidth ||
455 currentHeight != (uint32_t)params.videoHeight ||
456 currentFormat != (uint32_t)mRecordingFormat ||
457 currentDataSpace != mRecordingDataSpace ||
458 newConsumer) {
459 // TODO: Should wait to be sure previous recording has finished
460 res = device->deleteStream(mRecordingStreamId);
461
462 if (res == -EBUSY) {
463 ALOGV("%s: Camera %d: Device is busy, call "
464 "updateRecordingStream after it becomes idle",
465 __FUNCTION__, mId);
466 return res;
467 } else if (res != OK) {
468 ALOGE("%s: Camera %d: Unable to delete old output stream "
469 "for recording: %s (%d)", __FUNCTION__,
470 mId, strerror(-res), res);
471 return res;
472 }
473 mRecordingStreamId = NO_STREAM;
474 }
475 }
476
477 if (mRecordingStreamId == NO_STREAM) {
478 mRecordingFrameCount = 0;
479 res = device->createStream(mRecordingWindow,
480 params.videoWidth, params.videoHeight,
481 mRecordingFormat, mRecordingDataSpace,
482 CAMERA3_STREAM_ROTATION_0, &mRecordingStreamId);
483 if (res != OK) {
484 ALOGE("%s: Camera %d: Can't create output stream for recording: "
485 "%s (%d)", __FUNCTION__, mId,
486 strerror(-res), res);
487 return res;
488 }
489 }
490
491 return OK;
492 }
493
deleteRecordingStream()494 status_t StreamingProcessor::deleteRecordingStream() {
495 ATRACE_CALL();
496 status_t res;
497
498 Mutex::Autolock m(mMutex);
499
500 if (mRecordingStreamId != NO_STREAM) {
501 sp<CameraDeviceBase> device = mDevice.promote();
502 if (device == 0) {
503 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
504 return INVALID_OPERATION;
505 }
506
507 res = device->waitUntilDrained();
508 if (res != OK) {
509 ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
510 __FUNCTION__, strerror(-res), res);
511 return res;
512 }
513 res = device->deleteStream(mRecordingStreamId);
514 if (res != OK) {
515 ALOGE("%s: Unable to delete recording stream: %s (%d)",
516 __FUNCTION__, strerror(-res), res);
517 return res;
518 }
519 mRecordingStreamId = NO_STREAM;
520 }
521 return OK;
522 }
523
getRecordingStreamId() const524 int StreamingProcessor::getRecordingStreamId() const {
525 return mRecordingStreamId;
526 }
527
startStream(StreamType type,const Vector<int32_t> & outputStreams)528 status_t StreamingProcessor::startStream(StreamType type,
529 const Vector<int32_t> &outputStreams) {
530 ATRACE_CALL();
531 status_t res;
532
533 if (type == NONE) return INVALID_OPERATION;
534
535 sp<CameraDeviceBase> device = mDevice.promote();
536 if (device == 0) {
537 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
538 return INVALID_OPERATION;
539 }
540
541 ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type);
542
543 Mutex::Autolock m(mMutex);
544
545 // If a recording stream is being started up and no recording
546 // stream is active yet, free up any outstanding buffers left
547 // from the previous recording session. There should never be
548 // any, so if there are, warn about it.
549 bool isRecordingStreamIdle = !isStreamActive(mActiveStreamIds, mRecordingStreamId);
550 bool startRecordingStream = isStreamActive(outputStreams, mRecordingStreamId);
551 if (startRecordingStream && isRecordingStreamIdle) {
552 releaseAllRecordingFramesLocked();
553 }
554
555 ALOGV("%s: Camera %d: %s started, recording heap has %zu free of %zu",
556 __FUNCTION__, mId, (type == PREVIEW) ? "preview" : "recording",
557 mRecordingHeapFree, mRecordingHeapCount);
558
559 CameraMetadata &request = (type == PREVIEW) ?
560 mPreviewRequest : mRecordingRequest;
561
562 res = request.update(
563 ANDROID_REQUEST_OUTPUT_STREAMS,
564 outputStreams);
565 if (res != OK) {
566 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
567 __FUNCTION__, mId, strerror(-res), res);
568 return res;
569 }
570
571 res = request.sort();
572 if (res != OK) {
573 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
574 __FUNCTION__, mId, strerror(-res), res);
575 return res;
576 }
577
578 res = device->setStreamingRequest(request);
579 if (res != OK) {
580 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
581 "%s (%d)",
582 __FUNCTION__, mId, strerror(-res), res);
583 return res;
584 }
585 mActiveRequest = type;
586 mPaused = false;
587 mActiveStreamIds = outputStreams;
588 return OK;
589 }
590
togglePauseStream(bool pause)591 status_t StreamingProcessor::togglePauseStream(bool pause) {
592 ATRACE_CALL();
593 status_t res;
594
595 sp<CameraDeviceBase> device = mDevice.promote();
596 if (device == 0) {
597 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
598 return INVALID_OPERATION;
599 }
600
601 ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause);
602
603 Mutex::Autolock m(mMutex);
604
605 if (mActiveRequest == NONE) {
606 ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started",
607 __FUNCTION__, mId);
608 return INVALID_OPERATION;
609 }
610
611 if (mPaused == pause) {
612 return OK;
613 }
614
615 if (pause) {
616 res = device->clearStreamingRequest();
617 if (res != OK) {
618 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
619 __FUNCTION__, mId, strerror(-res), res);
620 return res;
621 }
622 } else {
623 CameraMetadata &request =
624 (mActiveRequest == PREVIEW) ? mPreviewRequest
625 : mRecordingRequest;
626 res = device->setStreamingRequest(request);
627 if (res != OK) {
628 ALOGE("%s: Camera %d: Unable to set preview request to resume: "
629 "%s (%d)",
630 __FUNCTION__, mId, strerror(-res), res);
631 return res;
632 }
633 }
634
635 mPaused = pause;
636 return OK;
637 }
638
stopStream()639 status_t StreamingProcessor::stopStream() {
640 ATRACE_CALL();
641 status_t res;
642
643 Mutex::Autolock m(mMutex);
644
645 sp<CameraDeviceBase> device = mDevice.promote();
646 if (device == 0) {
647 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
648 return INVALID_OPERATION;
649 }
650
651 res = device->clearStreamingRequest();
652 if (res != OK) {
653 ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
654 __FUNCTION__, mId, strerror(-res), res);
655 return res;
656 }
657
658 mActiveRequest = NONE;
659 mActiveStreamIds.clear();
660 mPaused = false;
661
662 return OK;
663 }
664
getActiveRequestId() const665 int32_t StreamingProcessor::getActiveRequestId() const {
666 Mutex::Autolock m(mMutex);
667 switch (mActiveRequest) {
668 case NONE:
669 return 0;
670 case PREVIEW:
671 return mPreviewRequestId;
672 case RECORD:
673 return mRecordingRequestId;
674 default:
675 ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest);
676 return 0;
677 }
678 }
679
incrementStreamingIds()680 status_t StreamingProcessor::incrementStreamingIds() {
681 ATRACE_CALL();
682 Mutex::Autolock m(mMutex);
683
684 mPreviewRequestId++;
685 if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
686 mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
687 }
688 mRecordingRequestId++;
689 if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) {
690 mRecordingRequestId = Camera2Client::kRecordingRequestIdStart;
691 }
692 return OK;
693 }
694
onFrameAvailable(const BufferItem &)695 void StreamingProcessor::onFrameAvailable(const BufferItem& /*item*/) {
696 ATRACE_CALL();
697 Mutex::Autolock l(mMutex);
698 if (!mRecordingFrameAvailable) {
699 mRecordingFrameAvailable = true;
700 mRecordingFrameAvailableSignal.signal();
701 }
702
703 }
704
threadLoop()705 bool StreamingProcessor::threadLoop() {
706 status_t res;
707
708 {
709 Mutex::Autolock l(mMutex);
710 while (!mRecordingFrameAvailable) {
711 res = mRecordingFrameAvailableSignal.waitRelative(
712 mMutex, kWaitDuration);
713 if (res == TIMED_OUT) return true;
714 }
715 mRecordingFrameAvailable = false;
716 }
717
718 do {
719 res = processRecordingFrame();
720 } while (res == OK);
721
722 return true;
723 }
724
processRecordingFrame()725 status_t StreamingProcessor::processRecordingFrame() {
726 ATRACE_CALL();
727 status_t res;
728 sp<Camera2Heap> recordingHeap;
729 size_t heapIdx = 0;
730 nsecs_t timestamp;
731
732 sp<Camera2Client> client = mClient.promote();
733 if (client == 0) {
734 // Discard frames during shutdown
735 BufferItem imgBuffer;
736 res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0);
737 if (res != OK) {
738 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
739 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
740 __FUNCTION__, mId, strerror(-res), res);
741 }
742 return res;
743 }
744 mRecordingConsumer->releaseBuffer(imgBuffer);
745 return OK;
746 }
747
748 {
749 /* acquire SharedParameters before mMutex so we don't dead lock
750 with Camera2Client code calling into StreamingProcessor */
751 SharedParameters::Lock l(client->getParameters());
752 Mutex::Autolock m(mMutex);
753 BufferItem imgBuffer;
754 res = mRecordingConsumer->acquireBuffer(&imgBuffer, 0);
755 if (res != OK) {
756 if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
757 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
758 __FUNCTION__, mId, strerror(-res), res);
759 }
760 return res;
761 }
762 timestamp = imgBuffer.mTimestamp;
763
764 mRecordingFrameCount++;
765 ALOGVV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
766
767 if (l.mParameters.state != Parameters::RECORD &&
768 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
769 ALOGV("%s: Camera %d: Discarding recording image buffers "
770 "received after recording done", __FUNCTION__,
771 mId);
772 mRecordingConsumer->releaseBuffer(imgBuffer);
773 return INVALID_OPERATION;
774 }
775
776 if (mRecordingHeap == 0) {
777 size_t payloadSize = sizeof(VideoNativeMetadata);
778 ALOGV("%s: Camera %d: Creating recording heap with %zu buffers of "
779 "size %zu bytes", __FUNCTION__, mId,
780 mRecordingHeapCount, payloadSize);
781
782 mRecordingHeap = new Camera2Heap(payloadSize, mRecordingHeapCount,
783 "Camera2Client::RecordingHeap");
784 if (mRecordingHeap->mHeap->getSize() == 0) {
785 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
786 __FUNCTION__, mId);
787 mRecordingConsumer->releaseBuffer(imgBuffer);
788 return NO_MEMORY;
789 }
790 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
791 if (mRecordingBuffers[i].mBuf !=
792 BufferItemConsumer::INVALID_BUFFER_SLOT) {
793 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
794 __FUNCTION__, mId);
795 }
796 }
797 mRecordingBuffers.clear();
798 mRecordingBuffers.setCapacity(mRecordingHeapCount);
799 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
800
801 mRecordingHeapHead = 0;
802 mRecordingHeapFree = mRecordingHeapCount;
803 }
804
805 if (mRecordingHeapFree == 0) {
806 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
807 __FUNCTION__, mId);
808 mRecordingConsumer->releaseBuffer(imgBuffer);
809 return NO_MEMORY;
810 }
811
812 heapIdx = mRecordingHeapHead;
813 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
814 mRecordingHeapFree--;
815
816 ALOGVV("%s: Camera %d: Timestamp %lld",
817 __FUNCTION__, mId, timestamp);
818
819 ssize_t offset;
820 size_t size;
821 sp<IMemoryHeap> heap =
822 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
823 &size);
824
825 VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>(
826 (uint8_t*)heap->getBase() + offset);
827 payload->eType = kMetadataBufferTypeANWBuffer;
828 payload->pBuffer = imgBuffer.mGraphicBuffer->getNativeBuffer();
829 payload->nFenceFd = -1;
830
831 ALOGVV("%s: Camera %d: Sending out ANWBuffer %p",
832 __FUNCTION__, mId, payload->pBuffer);
833
834 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
835 recordingHeap = mRecordingHeap;
836 }
837
838 // Call outside locked parameters to allow re-entrancy from notification
839 Camera2Client::SharedCameraCallbacks::Lock l(client->mSharedCameraCallbacks);
840 if (l.mRemoteCallback != 0) {
841 l.mRemoteCallback->dataCallbackTimestamp(timestamp,
842 CAMERA_MSG_VIDEO_FRAME,
843 recordingHeap->mBuffers[heapIdx]);
844 } else {
845 ALOGW("%s: Camera %d: Remote callback gone", __FUNCTION__, mId);
846 }
847
848 return OK;
849 }
850
releaseRecordingFrame(const sp<IMemory> & mem)851 void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) {
852 ATRACE_CALL();
853 status_t res;
854
855 Mutex::Autolock m(mMutex);
856 // Make sure this is for the current heap
857 ssize_t offset;
858 size_t size;
859 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
860 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
861 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
862 "(got %x, expected %x)", __FUNCTION__, mId,
863 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
864 return;
865 }
866
867 VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>(
868 (uint8_t*)heap->getBase() + offset);
869
870 if (payload->eType != kMetadataBufferTypeANWBuffer) {
871 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
872 __FUNCTION__, mId, payload->eType,
873 kMetadataBufferTypeANWBuffer);
874 return;
875 }
876
877 // Release the buffer back to the recording queue
878 size_t itemIndex;
879 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
880 const BufferItem item = mRecordingBuffers[itemIndex];
881 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
882 item.mGraphicBuffer->getNativeBuffer() == payload->pBuffer) {
883 break;
884 }
885 }
886
887 if (itemIndex == mRecordingBuffers.size()) {
888 ALOGE("%s: Camera %d: Can't find returned ANW Buffer %p in list of "
889 "outstanding buffers", __FUNCTION__, mId,
890 payload->pBuffer);
891 return;
892 }
893
894 ALOGVV("%s: Camera %d: Freeing returned ANW buffer %p index %d", __FUNCTION__,
895 mId, payload->pBuffer, itemIndex);
896
897 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
898 if (res != OK) {
899 ALOGE("%s: Camera %d: Unable to free recording frame "
900 "(Returned ANW buffer: %p): %s (%d)", __FUNCTION__,
901 mId, payload->pBuffer, strerror(-res), res);
902 return;
903 }
904 mRecordingBuffers.replaceAt(itemIndex);
905
906 mRecordingHeapFree++;
907 ALOGV_IF(mRecordingHeapFree == mRecordingHeapCount,
908 "%s: Camera %d: All %d recording buffers returned",
909 __FUNCTION__, mId, mRecordingHeapCount);
910 }
911
releaseAllRecordingFramesLocked()912 void StreamingProcessor::releaseAllRecordingFramesLocked() {
913 ATRACE_CALL();
914 status_t res;
915
916 if (mRecordingConsumer == 0) {
917 return;
918 }
919
920 ALOGV("%s: Camera %d: Releasing all recording buffers", __FUNCTION__,
921 mId);
922
923 size_t releasedCount = 0;
924 for (size_t itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
925 const BufferItem item = mRecordingBuffers[itemIndex];
926 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT) {
927 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
928 if (res != OK) {
929 ALOGE("%s: Camera %d: Unable to free recording frame "
930 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__,
931 mId, item.mGraphicBuffer->handle, strerror(-res), res);
932 }
933 mRecordingBuffers.replaceAt(itemIndex);
934 releasedCount++;
935 }
936 }
937
938 if (releasedCount > 0) {
939 ALOGW("%s: Camera %d: Force-freed %zu outstanding buffers "
940 "from previous recording session", __FUNCTION__, mId, releasedCount);
941 ALOGE_IF(releasedCount != mRecordingHeapCount - mRecordingHeapFree,
942 "%s: Camera %d: Force-freed %zu buffers, but expected %zu",
943 __FUNCTION__, mId, releasedCount, mRecordingHeapCount - mRecordingHeapFree);
944 }
945
946 mRecordingHeapHead = 0;
947 mRecordingHeapFree = mRecordingHeapCount;
948 }
949
isStreamActive(const Vector<int32_t> & streams,int32_t recordingStreamId)950 bool StreamingProcessor::isStreamActive(const Vector<int32_t> &streams,
951 int32_t recordingStreamId) {
952 for (size_t i = 0; i < streams.size(); i++) {
953 if (streams[i] == recordingStreamId) {
954 return true;
955 }
956 }
957 return false;
958 }
959
960
dump(int fd,const Vector<String16> &)961 status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
962 String8 result;
963
964 result.append(" Current requests:\n");
965 if (mPreviewRequest.entryCount() != 0) {
966 result.append(" Preview request:\n");
967 write(fd, result.string(), result.size());
968 mPreviewRequest.dump(fd, 2, 6);
969 result.clear();
970 } else {
971 result.append(" Preview request: undefined\n");
972 }
973
974 if (mRecordingRequest.entryCount() != 0) {
975 result = " Recording request:\n";
976 write(fd, result.string(), result.size());
977 mRecordingRequest.dump(fd, 2, 6);
978 result.clear();
979 } else {
980 result = " Recording request: undefined\n";
981 }
982
983 const char* streamTypeString[] = {
984 "none", "preview", "record"
985 };
986 result.append(String8::format(" Active request: %s (paused: %s)\n",
987 streamTypeString[mActiveRequest],
988 mPaused ? "yes" : "no"));
989
990 write(fd, result.string(), result.size());
991
992 return OK;
993 }
994
995 }; // namespace camera2
996 }; // namespace android
997