1 /*
2 * Copyright (C) 2012-2018 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-CallbackProcessor"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20
21 #include <com_android_graphics_libgui_flags.h>
22 #include <gui/CpuConsumer.h>
23 #include <gui/Surface.h>
24 #include <utils/Log.h>
25 #include <utils/Trace.h>
26
27 #include "common/CameraDeviceBase.h"
28 #include "api1/Camera2Client.h"
29 #include "api1/client2/CallbackProcessor.h"
30
31 #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
32
33 namespace android {
34 namespace camera2 {
35
36 using android::camera3::CAMERA_STREAM_ROTATION_0;
37
CallbackProcessor(sp<Camera2Client> client)38 CallbackProcessor::CallbackProcessor(sp<Camera2Client> client):
39 Thread(false),
40 mClient(client),
41 mDevice(client->getCameraDevice()),
42 mId(client->getCameraId()),
43 mCallbackAvailable(false),
44 mCallbackPaused(true),
45 mCallbackToApp(false),
46 mCallbackStreamId(NO_STREAM) {
47 }
48
~CallbackProcessor()49 CallbackProcessor::~CallbackProcessor() {
50 ALOGV("%s: Exit", __FUNCTION__);
51 deleteStream();
52 }
53
onFrameAvailable(const BufferItem &)54 void CallbackProcessor::onFrameAvailable(const BufferItem& /*item*/) {
55 Mutex::Autolock l(mInputMutex);
56 if (!mCallbackAvailable) {
57 mCallbackAvailable = true;
58 mCallbackAvailableSignal.signal();
59 }
60 }
61
setCallbackWindow(const sp<Surface> & callbackWindow)62 status_t CallbackProcessor::setCallbackWindow(
63 const sp<Surface>& callbackWindow) {
64 ATRACE_CALL();
65 status_t res;
66
67 Mutex::Autolock l(mInputMutex);
68
69 sp<Camera2Client> client = mClient.promote();
70 if (client == 0) return OK;
71 sp<CameraDeviceBase> device = client->getCameraDevice();
72
73 // If the window is changing, clear out stream if it already exists
74 if (mCallbackWindow != callbackWindow && mCallbackStreamId != NO_STREAM) {
75 res = device->deleteStream(mCallbackStreamId);
76 if (res != OK) {
77 ALOGE("%s: Camera %d: Unable to delete old stream "
78 "for callbacks: %s (%d)", __FUNCTION__,
79 client->getCameraId(), strerror(-res), res);
80 return res;
81 }
82 mCallbackStreamId = NO_STREAM;
83 mCallbackConsumer.clear();
84 }
85 mCallbackWindow = callbackWindow;
86 mCallbackToApp = (mCallbackWindow != NULL);
87
88 return OK;
89 }
90
updateStream(const Parameters & params)91 status_t CallbackProcessor::updateStream(const Parameters ¶ms) {
92 ATRACE_CALL();
93 status_t res;
94
95 Mutex::Autolock l(mInputMutex);
96
97 sp<CameraDeviceBase> device = mDevice.promote();
98 if (device == 0) {
99 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
100 return INVALID_OPERATION;
101 }
102
103 // If possible, use the flexible YUV format
104 int32_t callbackFormat = params.previewFormat;
105 if (mCallbackToApp) {
106 // TODO: etalvala: This should use the flexible YUV format as well, but
107 // need to reconcile HAL2/HAL3 requirements.
108 callbackFormat = HAL_PIXEL_FORMAT_YV12;
109 } else if(params.fastInfo.useFlexibleYuv &&
110 (params.previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
111 params.previewFormat == HAL_PIXEL_FORMAT_YV12) ) {
112 callbackFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
113 }
114
115 if (!mCallbackToApp && mCallbackConsumer == 0) {
116 // Create CPU buffer queue endpoint, since app hasn't given us one
117 // Make it async to avoid disconnect deadlocks
118 std::tie(mCallbackConsumer, mCallbackWindow) = CpuConsumer::create(kCallbackHeapCount);
119 mCallbackConsumer->setFrameAvailableListener(this);
120 mCallbackConsumer->setName(String8("Camera2-CallbackConsumer"));
121 }
122
123 if (mCallbackStreamId != NO_STREAM) {
124 // Check if stream parameters have to change
125 CameraDeviceBase::StreamInfo streamInfo;
126 res = device->getStreamInfo(mCallbackStreamId, &streamInfo);
127 if (res != OK) {
128 ALOGE("%s: Camera %d: Error querying callback output stream info: "
129 "%s (%d)", __FUNCTION__, mId,
130 strerror(-res), res);
131 return res;
132 }
133 if (streamInfo.width != (uint32_t)params.previewWidth ||
134 streamInfo.height != (uint32_t)params.previewHeight ||
135 !streamInfo.matchFormat((uint32_t)callbackFormat)) {
136 // Since size should only change while preview is not running,
137 // assuming that all existing use of old callback stream is
138 // completed.
139 ALOGV("%s: Camera %d: Deleting stream %d since the buffer "
140 "parameters changed", __FUNCTION__, mId, mCallbackStreamId);
141 res = device->deleteStream(mCallbackStreamId);
142 if (res != OK) {
143 ALOGE("%s: Camera %d: Unable to delete old output stream "
144 "for callbacks: %s (%d)", __FUNCTION__,
145 mId, strerror(-res), res);
146 return res;
147 }
148 mCallbackStreamId = NO_STREAM;
149 }
150 }
151
152 if (mCallbackStreamId == NO_STREAM) {
153 ALOGV("Creating callback stream: %d x %d, format 0x%x, API format 0x%x",
154 params.previewWidth, params.previewHeight,
155 callbackFormat, params.previewFormat);
156 res = device->createStream(mCallbackWindow,
157 params.previewWidth, params.previewHeight, callbackFormat,
158 HAL_DATASPACE_V0_JFIF, CAMERA_STREAM_ROTATION_0, &mCallbackStreamId,
159 std::string(), std::unordered_set<int32_t>{ANDROID_SENSOR_PIXEL_MODE_DEFAULT});
160 if (res != OK) {
161 ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
162 "%s (%d)", __FUNCTION__, mId,
163 strerror(-res), res);
164 return res;
165 }
166 }
167
168 return OK;
169 }
170
deleteStream()171 status_t CallbackProcessor::deleteStream() {
172 ATRACE_CALL();
173 sp<CameraDeviceBase> device;
174 status_t res;
175 {
176 Mutex::Autolock l(mInputMutex);
177
178 if (mCallbackStreamId == NO_STREAM) {
179 return OK;
180 }
181 device = mDevice.promote();
182 if (device == 0) {
183 ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
184 return INVALID_OPERATION;
185 }
186 }
187 res = device->waitUntilDrained();
188 if (res != OK) {
189 ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
190 __FUNCTION__, strerror(-res), res);
191 return res;
192 }
193
194 res = device->deleteStream(mCallbackStreamId);
195 if (res != OK) {
196 ALOGE("%s: Unable to delete callback stream: %s (%d)",
197 __FUNCTION__, strerror(-res), res);
198 return res;
199 }
200
201 {
202 Mutex::Autolock l(mInputMutex);
203
204 mCallbackHeap.clear();
205 mCallbackWindow.clear();
206 mCallbackConsumer.clear();
207
208 mCallbackStreamId = NO_STREAM;
209 }
210 return OK;
211 }
212
getStreamId() const213 int CallbackProcessor::getStreamId() const {
214 Mutex::Autolock l(mInputMutex);
215 return mCallbackStreamId;
216 }
217
unpauseCallback()218 void CallbackProcessor::unpauseCallback() {
219 mCallbackPaused = false;
220 }
221
pauseCallback()222 void CallbackProcessor::pauseCallback() {
223 mCallbackPaused = true;
224 }
225
dump(int,const Vector<String16> &) const226 void CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const {
227 }
228
threadLoop()229 bool CallbackProcessor::threadLoop() {
230 status_t res;
231
232 {
233 Mutex::Autolock l(mInputMutex);
234 while (!mCallbackAvailable) {
235 res = mCallbackAvailableSignal.waitRelative(mInputMutex,
236 kWaitDuration);
237 if (res == TIMED_OUT) return true;
238 }
239 mCallbackAvailable = false;
240 }
241
242 do {
243 sp<Camera2Client> client = mClient.promote();
244 if (client == 0 || mCallbackPaused) {
245 res = discardNewCallback();
246 } else {
247 res = processNewCallback(client);
248 }
249 } while (res == OK);
250
251 return true;
252 }
253
discardNewCallback()254 status_t CallbackProcessor::discardNewCallback() {
255 ATRACE_CALL();
256 status_t res;
257 CpuConsumer::LockedBuffer imgBuffer;
258 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
259 if (res != OK) {
260 if (res != BAD_VALUE) {
261 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
262 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
263 }
264 return res;
265 }
266 mCallbackConsumer->unlockBuffer(imgBuffer);
267 return OK;
268 }
269
processNewCallback(sp<Camera2Client> & client)270 status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) {
271 ATRACE_CALL();
272 status_t res;
273
274 sp<Camera2Heap> callbackHeap;
275 bool useFlexibleYuv = false;
276 int32_t previewFormat = 0;
277 size_t heapIdx;
278
279 {
280 /* acquire SharedParameters before mMutex so we don't dead lock
281 with Camera2Client code calling into StreamingProcessor */
282 SharedParameters::Lock l(client->getParameters());
283 Mutex::Autolock m(mInputMutex);
284 CpuConsumer::LockedBuffer imgBuffer;
285 if (mCallbackStreamId == NO_STREAM) {
286 ALOGV("%s: Camera %d:No stream is available"
287 , __FUNCTION__, mId);
288 return INVALID_OPERATION;
289 }
290
291 ALOGV("%s: Getting buffer", __FUNCTION__);
292 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
293 if (res != OK) {
294 if (res != BAD_VALUE) {
295 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
296 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
297 }
298 return res;
299 }
300 ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__,
301 mId);
302
303 if ( l.mParameters.state != Parameters::PREVIEW
304 && l.mParameters.state != Parameters::RECORD
305 && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
306 ALOGV("%s: Camera %d: No longer streaming",
307 __FUNCTION__, mId);
308 mCallbackConsumer->unlockBuffer(imgBuffer);
309 return OK;
310 }
311
312 if (! (l.mParameters.previewCallbackFlags &
313 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
314 ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
315 mCallbackConsumer->unlockBuffer(imgBuffer);
316 return OK;
317 }
318 if ((l.mParameters.previewCallbackFlags &
319 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
320 !l.mParameters.previewCallbackOneShot) {
321 ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
322 mCallbackConsumer->unlockBuffer(imgBuffer);
323 return OK;
324 }
325
326 if (imgBuffer.width != static_cast<uint32_t>(l.mParameters.previewWidth) ||
327 imgBuffer.height != static_cast<uint32_t>(l.mParameters.previewHeight)) {
328 ALOGW("%s: The preview size has changed to %d x %d from %d x %d, this buffer is"
329 " no longer valid, dropping",__FUNCTION__,
330 l.mParameters.previewWidth, l.mParameters.previewHeight,
331 imgBuffer.width, imgBuffer.height);
332 mCallbackConsumer->unlockBuffer(imgBuffer);
333 return OK;
334 }
335
336 previewFormat = l.mParameters.previewFormat;
337 useFlexibleYuv = l.mParameters.fastInfo.useFlexibleYuv &&
338 (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
339 previewFormat == HAL_PIXEL_FORMAT_YV12);
340
341 int32_t expectedFormat = useFlexibleYuv ?
342 HAL_PIXEL_FORMAT_YCbCr_420_888 : previewFormat;
343
344 if (imgBuffer.format != expectedFormat) {
345 ALOGE("%s: Camera %d: Unexpected format for callback: "
346 "0x%x, expected 0x%x", __FUNCTION__, mId,
347 imgBuffer.format, expectedFormat);
348 mCallbackConsumer->unlockBuffer(imgBuffer);
349 return INVALID_OPERATION;
350 }
351
352 // In one-shot mode, stop sending callbacks after the first one
353 if (l.mParameters.previewCallbackFlags &
354 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
355 ALOGV("%s: clearing oneshot", __FUNCTION__);
356 l.mParameters.previewCallbackOneShot = false;
357 }
358
359 uint32_t destYStride = 0;
360 uint32_t destCStride = 0;
361 if (useFlexibleYuv) {
362 if (previewFormat == HAL_PIXEL_FORMAT_YV12) {
363 // Strides must align to 16 for YV12
364 destYStride = ALIGN(imgBuffer.width, 16);
365 destCStride = ALIGN(destYStride / 2, 16);
366 } else {
367 // No padding for NV21
368 ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP,
369 "Unexpected preview format 0x%x", previewFormat);
370 destYStride = imgBuffer.width;
371 destCStride = destYStride / 2;
372 }
373 } else {
374 destYStride = imgBuffer.stride;
375 // don't care about cStride
376 }
377
378 size_t bufferSize = Camera2Client::calculateBufferSize(
379 imgBuffer.width, imgBuffer.height,
380 previewFormat, destYStride);
381 size_t currentBufferSize = (mCallbackHeap == 0) ?
382 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
383 if (bufferSize != currentBufferSize) {
384 mCallbackHeap.clear();
385 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
386 "Camera2Client::CallbackHeap");
387 if (mCallbackHeap->mHeap->getSize() == 0) {
388 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
389 __FUNCTION__, mId);
390 mCallbackConsumer->unlockBuffer(imgBuffer);
391 return INVALID_OPERATION;
392 }
393
394 mCallbackHeapHead = 0;
395 mCallbackHeapFree = kCallbackHeapCount;
396 }
397
398 if (mCallbackHeapFree == 0) {
399 ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
400 __FUNCTION__, mId);
401 mCallbackConsumer->unlockBuffer(imgBuffer);
402 return OK;
403 }
404
405 heapIdx = mCallbackHeapHead;
406
407 mCallbackHeapHead = (mCallbackHeapHead + 1) % kCallbackHeapCount;
408 mCallbackHeapFree--;
409
410 // TODO: Get rid of this copy by passing the gralloc queue all the way
411 // to app
412
413 ssize_t offset;
414 size_t size;
415 sp<IMemoryHeap> heap =
416 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
417 &size);
418 uint8_t *data = (uint8_t*)heap->getBase() + offset;
419
420 if (!useFlexibleYuv) {
421 // Can just memcpy when HAL format matches API format
422 memcpy(data, imgBuffer.data, bufferSize);
423 } else {
424 res = convertFromFlexibleYuv(previewFormat, data, imgBuffer,
425 destYStride, destCStride);
426 if (res != OK) {
427 ALOGE("%s: Camera %d: Can't convert between 0x%x and 0x%x formats!",
428 __FUNCTION__, mId, imgBuffer.format, previewFormat);
429 mCallbackConsumer->unlockBuffer(imgBuffer);
430 return BAD_VALUE;
431 }
432 }
433
434 ALOGV("%s: Freeing buffer", __FUNCTION__);
435 mCallbackConsumer->unlockBuffer(imgBuffer);
436
437 // mCallbackHeap may get freed up once input mutex is released
438 callbackHeap = mCallbackHeap;
439 }
440
441 // Call outside parameter lock to allow re-entrancy from notification
442 {
443 Camera2Client::SharedCameraCallbacks::Lock
444 l(client->mSharedCameraCallbacks);
445 if (l.mRemoteCallback != 0) {
446 ALOGV("%s: Camera %d: Invoking client data callback",
447 __FUNCTION__, mId);
448 l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
449 callbackHeap->mBuffers[heapIdx], NULL);
450 }
451 }
452
453 // Only increment free if we're still using the same heap
454 mCallbackHeapFree++;
455
456 ALOGV("%s: exit", __FUNCTION__);
457
458 return OK;
459 }
460
convertFromFlexibleYuv(int32_t previewFormat,uint8_t * dst,const CpuConsumer::LockedBuffer & src,uint32_t dstYStride,uint32_t dstCStride) const461 status_t CallbackProcessor::convertFromFlexibleYuv(int32_t previewFormat,
462 uint8_t *dst,
463 const CpuConsumer::LockedBuffer &src,
464 uint32_t dstYStride,
465 uint32_t dstCStride) const {
466
467 if (previewFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP &&
468 previewFormat != HAL_PIXEL_FORMAT_YV12) {
469 ALOGE("%s: Camera %d: Unexpected preview format when using "
470 "flexible YUV: 0x%x", __FUNCTION__, mId, previewFormat);
471 return INVALID_OPERATION;
472 }
473
474 // Copy Y plane, adjusting for stride
475 const uint8_t *ySrc = src.data;
476 uint8_t *yDst = dst;
477 for (size_t row = 0; row < src.height; row++) {
478 memcpy(yDst, ySrc, src.width);
479 ySrc += src.stride;
480 yDst += dstYStride;
481 }
482
483 // Copy/swizzle chroma planes, 4:2:0 subsampling
484 const uint8_t *cbSrc = src.dataCb;
485 const uint8_t *crSrc = src.dataCr;
486 size_t chromaHeight = src.height / 2;
487 size_t chromaWidth = src.width / 2;
488 ssize_t chromaGap = src.chromaStride -
489 (chromaWidth * src.chromaStep);
490 size_t dstChromaGap = dstCStride - chromaWidth;
491
492 if (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
493 // Flexible YUV chroma to NV21 chroma
494 uint8_t *crcbDst = yDst;
495 // Check for shortcuts
496 if (cbSrc == crSrc + 1 && src.chromaStep == 2) {
497 ALOGV("%s: Fast NV21->NV21", __FUNCTION__);
498 // Source has semiplanar CrCb chroma layout, can copy by rows
499 for (size_t row = 0; row < chromaHeight; row++) {
500 memcpy(crcbDst, crSrc, src.width);
501 crcbDst += src.width;
502 crSrc += src.chromaStride;
503 }
504 } else {
505 ALOGV("%s: Generic->NV21", __FUNCTION__);
506 // Generic copy, always works but not very efficient
507 for (size_t row = 0; row < chromaHeight; row++) {
508 for (size_t col = 0; col < chromaWidth; col++) {
509 *(crcbDst++) = *crSrc;
510 *(crcbDst++) = *cbSrc;
511 crSrc += src.chromaStep;
512 cbSrc += src.chromaStep;
513 }
514 crSrc += chromaGap;
515 cbSrc += chromaGap;
516 }
517 }
518 } else {
519 // flexible YUV chroma to YV12 chroma
520 ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YV12,
521 "Unexpected preview format 0x%x", previewFormat);
522 uint8_t *crDst = yDst;
523 uint8_t *cbDst = yDst + chromaHeight * dstCStride;
524 if (src.chromaStep == 1) {
525 ALOGV("%s: Fast YV12->YV12", __FUNCTION__);
526 // Source has planar chroma layout, can copy by row
527 for (size_t row = 0; row < chromaHeight; row++) {
528 memcpy(crDst, crSrc, chromaWidth);
529 crDst += dstCStride;
530 crSrc += src.chromaStride;
531 }
532 for (size_t row = 0; row < chromaHeight; row++) {
533 memcpy(cbDst, cbSrc, chromaWidth);
534 cbDst += dstCStride;
535 cbSrc += src.chromaStride;
536 }
537 } else {
538 ALOGV("%s: Generic->YV12", __FUNCTION__);
539 // Generic copy, always works but not very efficient
540 for (size_t row = 0; row < chromaHeight; row++) {
541 for (size_t col = 0; col < chromaWidth; col++) {
542 *(crDst++) = *crSrc;
543 *(cbDst++) = *cbSrc;
544 crSrc += src.chromaStep;
545 cbSrc += src.chromaStep;
546 }
547 crSrc += chromaGap;
548 cbSrc += chromaGap;
549 crDst += dstChromaGap;
550 cbDst += dstChromaGap;
551 }
552 }
553 }
554
555 return OK;
556 }
557
558 }; // namespace camera2
559 }; // namespace android
560