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