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