CallbackProcessor.cpp revision deeef54487a34034dc0cfaab20b20d557224c07c
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 31namespace android { 32namespace camera2 { 33 34CallbackProcessor::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 44CallbackProcessor::~CallbackProcessor() { 45 ALOGV("%s: Exit", __FUNCTION__); 46 deleteStream(); 47} 48 49void CallbackProcessor::onFrameAvailable() { 50 Mutex::Autolock l(mInputMutex); 51 if (!mCallbackAvailable) { 52 mCallbackAvailable = true; 53 mCallbackAvailableSignal.signal(); 54 } 55} 56 57status_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 86status_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 168status_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 210int CallbackProcessor::getStreamId() const { 211 Mutex::Autolock l(mInputMutex); 212 return mCallbackStreamId; 213} 214 215void CallbackProcessor::dump(int /*fd*/, const Vector<String16>& /*args*/) const { 216} 217 218bool 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 243status_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 259status_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 previewFormat = l.mParameters.previewFormat; 316 useFlexibleYuv = l.mParameters.fastInfo.useFlexibleYuv && 317 (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP || 318 previewFormat == HAL_PIXEL_FORMAT_YV12); 319 320 int32_t expectedFormat = useFlexibleYuv ? 321 HAL_PIXEL_FORMAT_YCbCr_420_888 : previewFormat; 322 323 if (imgBuffer.format != expectedFormat) { 324 ALOGE("%s: Camera %d: Unexpected format for callback: " 325 "0x%x, expected 0x%x", __FUNCTION__, mId, 326 imgBuffer.format, expectedFormat); 327 mCallbackConsumer->unlockBuffer(imgBuffer); 328 return INVALID_OPERATION; 329 } 330 331 // In one-shot mode, stop sending callbacks after the first one 332 if (l.mParameters.previewCallbackFlags & 333 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) { 334 ALOGV("%s: clearing oneshot", __FUNCTION__); 335 l.mParameters.previewCallbackOneShot = false; 336 } 337 338 uint32_t destYStride = 0; 339 uint32_t destCStride = 0; 340 if (useFlexibleYuv) { 341 if (previewFormat == HAL_PIXEL_FORMAT_YV12) { 342 // Strides must align to 16 for YV12 343 destYStride = ALIGN(imgBuffer.width, 16); 344 destCStride = ALIGN(destYStride / 2, 16); 345 } else { 346 // No padding for NV21 347 ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP, 348 "Unexpected preview format 0x%x", previewFormat); 349 destYStride = imgBuffer.width; 350 destCStride = destYStride / 2; 351 } 352 } else { 353 destYStride = imgBuffer.stride; 354 // don't care about cStride 355 } 356 357 size_t bufferSize = Camera2Client::calculateBufferSize( 358 imgBuffer.width, imgBuffer.height, 359 previewFormat, destYStride); 360 size_t currentBufferSize = (mCallbackHeap == 0) ? 361 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount); 362 if (bufferSize != currentBufferSize) { 363 mCallbackHeap.clear(); 364 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount, 365 "Camera2Client::CallbackHeap"); 366 if (mCallbackHeap->mHeap->getSize() == 0) { 367 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks", 368 __FUNCTION__, mId); 369 mCallbackConsumer->unlockBuffer(imgBuffer); 370 return INVALID_OPERATION; 371 } 372 373 mCallbackHeapHead = 0; 374 mCallbackHeapFree = kCallbackHeapCount; 375 } 376 377 if (mCallbackHeapFree == 0) { 378 ALOGE("%s: Camera %d: No free callback buffers, dropping frame", 379 __FUNCTION__, mId); 380 mCallbackConsumer->unlockBuffer(imgBuffer); 381 return OK; 382 } 383 384 heapIdx = mCallbackHeapHead; 385 386 mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount; 387 mCallbackHeapFree--; 388 389 // TODO: Get rid of this copy by passing the gralloc queue all the way 390 // to app 391 392 ssize_t offset; 393 size_t size; 394 sp<IMemoryHeap> heap = 395 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset, 396 &size); 397 uint8_t *data = (uint8_t*)heap->getBase() + offset; 398 399 if (!useFlexibleYuv) { 400 // Can just memcpy when HAL format matches API format 401 memcpy(data, imgBuffer.data, bufferSize); 402 } else { 403 res = convertFromFlexibleYuv(previewFormat, data, imgBuffer, 404 destYStride, destCStride); 405 if (res != OK) { 406 ALOGE("%s: Camera %d: Can't convert between 0x%x and 0x%x formats!", 407 __FUNCTION__, mId, imgBuffer.format, previewFormat); 408 mCallbackConsumer->unlockBuffer(imgBuffer); 409 return BAD_VALUE; 410 } 411 } 412 413 ALOGV("%s: Freeing buffer", __FUNCTION__); 414 mCallbackConsumer->unlockBuffer(imgBuffer); 415 416 // mCallbackHeap may get freed up once input mutex is released 417 callbackHeap = mCallbackHeap; 418 } 419 420 // Call outside parameter lock to allow re-entrancy from notification 421 { 422 Camera2Client::SharedCameraCallbacks::Lock 423 l(client->mSharedCameraCallbacks); 424 if (l.mRemoteCallback != 0) { 425 ALOGV("%s: Camera %d: Invoking client data callback", 426 __FUNCTION__, mId); 427 l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_FRAME, 428 callbackHeap->mBuffers[heapIdx], NULL); 429 } 430 } 431 432 // Only increment free if we're still using the same heap 433 mCallbackHeapFree++; 434 435 ALOGV("%s: exit", __FUNCTION__); 436 437 return OK; 438} 439 440status_t CallbackProcessor::convertFromFlexibleYuv(int32_t previewFormat, 441 uint8_t *dst, 442 const CpuConsumer::LockedBuffer &src, 443 uint32_t dstYStride, 444 uint32_t dstCStride) const { 445 446 if (previewFormat != HAL_PIXEL_FORMAT_YCrCb_420_SP && 447 previewFormat != HAL_PIXEL_FORMAT_YV12) { 448 ALOGE("%s: Camera %d: Unexpected preview format when using " 449 "flexible YUV: 0x%x", __FUNCTION__, mId, previewFormat); 450 return INVALID_OPERATION; 451 } 452 453 // Copy Y plane, adjusting for stride 454 const uint8_t *ySrc = src.data; 455 uint8_t *yDst = dst; 456 for (size_t row = 0; row < src.height; row++) { 457 memcpy(yDst, ySrc, src.width); 458 ySrc += src.stride; 459 yDst += dstYStride; 460 } 461 462 // Copy/swizzle chroma planes, 4:2:0 subsampling 463 const uint8_t *cbSrc = src.dataCb; 464 const uint8_t *crSrc = src.dataCr; 465 size_t chromaHeight = src.height / 2; 466 size_t chromaWidth = src.width / 2; 467 ssize_t chromaGap = src.chromaStride - 468 (chromaWidth * src.chromaStep); 469 size_t dstChromaGap = dstCStride - chromaWidth; 470 471 if (previewFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) { 472 // Flexible YUV chroma to NV21 chroma 473 uint8_t *crcbDst = yDst; 474 // Check for shortcuts 475 if (cbSrc == crSrc + 1 && src.chromaStep == 2) { 476 ALOGV("%s: Fast NV21->NV21", __FUNCTION__); 477 // Source has semiplanar CrCb chroma layout, can copy by rows 478 for (size_t row = 0; row < chromaHeight; row++) { 479 memcpy(crcbDst, crSrc, src.width); 480 crcbDst += src.width; 481 crSrc += src.chromaStride; 482 } 483 } else { 484 ALOGV("%s: Generic->NV21", __FUNCTION__); 485 // Generic copy, always works but not very efficient 486 for (size_t row = 0; row < chromaHeight; row++) { 487 for (size_t col = 0; col < chromaWidth; col++) { 488 *(crcbDst++) = *crSrc; 489 *(crcbDst++) = *cbSrc; 490 crSrc += src.chromaStep; 491 cbSrc += src.chromaStep; 492 } 493 crSrc += chromaGap; 494 cbSrc += chromaGap; 495 } 496 } 497 } else { 498 // flexible YUV chroma to YV12 chroma 499 ALOG_ASSERT(previewFormat == HAL_PIXEL_FORMAT_YV12, 500 "Unexpected preview format 0x%x", previewFormat); 501 uint8_t *crDst = yDst; 502 uint8_t *cbDst = yDst + chromaHeight * dstCStride; 503 if (src.chromaStep == 1) { 504 ALOGV("%s: Fast YV12->YV12", __FUNCTION__); 505 // Source has planar chroma layout, can copy by row 506 for (size_t row = 0; row < chromaHeight; row++) { 507 memcpy(crDst, crSrc, chromaWidth); 508 crDst += dstCStride; 509 crSrc += src.chromaStride; 510 } 511 for (size_t row = 0; row < chromaHeight; row++) { 512 memcpy(cbDst, cbSrc, chromaWidth); 513 cbDst += dstCStride; 514 cbSrc += src.chromaStride; 515 } 516 } else { 517 ALOGV("%s: Generic->YV12", __FUNCTION__); 518 // Generic copy, always works but not very efficient 519 for (size_t row = 0; row < chromaHeight; row++) { 520 for (size_t col = 0; col < chromaWidth; col++) { 521 *(crDst++) = *crSrc; 522 *(cbDst++) = *cbSrc; 523 crSrc += src.chromaStep; 524 cbSrc += src.chromaStep; 525 } 526 crSrc += chromaGap; 527 cbSrc += chromaGap; 528 crDst += dstChromaGap; 529 cbDst += dstChromaGap; 530 } 531 } 532 } 533 534 return OK; 535} 536 537}; // namespace camera2 538}; // namespace android 539