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