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