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