1 /* 2 * Copyright (C) 2016 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 #include <inttypes.h> 18 19 //#define LOG_NDEBUG 0 20 #define LOG_TAG "NdkImageReader" 21 22 #include "NdkImagePriv.h" 23 #include "NdkImageReaderPriv.h" 24 25 #include <utils/Log.h> 26 #include <android_runtime/android_view_Surface.h> 27 28 using namespace android; 29 30 namespace { 31 // Get an ID that's unique within this process. 32 static int32_t createProcessUniqueId() { 33 static volatile int32_t globalCounter = 0; 34 return android_atomic_inc(&globalCounter); 35 } 36 } 37 38 const char* AImageReader::kCallbackFpKey = "Callback"; 39 const char* AImageReader::kContextKey = "Context"; 40 41 bool 42 AImageReader::isSupportedFormat(int32_t format) { 43 switch (format) { 44 case AIMAGE_FORMAT_YUV_420_888: 45 case AIMAGE_FORMAT_JPEG: 46 case AIMAGE_FORMAT_RAW16: 47 case AIMAGE_FORMAT_RAW_PRIVATE: 48 case AIMAGE_FORMAT_RAW10: 49 case AIMAGE_FORMAT_RAW12: 50 case AIMAGE_FORMAT_DEPTH16: 51 case AIMAGE_FORMAT_DEPTH_POINT_CLOUD: 52 return true; 53 default: 54 return false; 55 } 56 } 57 58 int 59 AImageReader::getNumPlanesForFormat(int32_t format) { 60 switch (format) { 61 case AIMAGE_FORMAT_YUV_420_888: 62 return 3; 63 case AIMAGE_FORMAT_JPEG: 64 case AIMAGE_FORMAT_RAW16: 65 case AIMAGE_FORMAT_RAW_PRIVATE: 66 case AIMAGE_FORMAT_RAW10: 67 case AIMAGE_FORMAT_RAW12: 68 case AIMAGE_FORMAT_DEPTH16: 69 case AIMAGE_FORMAT_DEPTH_POINT_CLOUD: 70 return 1; 71 default: 72 return -1; 73 } 74 } 75 76 void 77 AImageReader::FrameListener::onFrameAvailable(const BufferItem& /*item*/) { 78 Mutex::Autolock _l(mLock); 79 sp<AImageReader> reader = mReader.promote(); 80 if (reader == nullptr) { 81 ALOGW("A frame is available after AImageReader closed!"); 82 return; // reader has been closed 83 } 84 if (mListener.onImageAvailable == nullptr) { 85 return; // No callback registered 86 } 87 88 sp<AMessage> msg = new AMessage(AImageReader::kWhatImageAvailable, reader->mHandler); 89 msg->setPointer(AImageReader::kCallbackFpKey, (void *) mListener.onImageAvailable); 90 msg->setPointer(AImageReader::kContextKey, mListener.context); 91 msg->post(); 92 } 93 94 media_status_t 95 AImageReader::FrameListener::setImageListener(AImageReader_ImageListener* listener) { 96 Mutex::Autolock _l(mLock); 97 if (listener == nullptr) { 98 mListener.context = nullptr; 99 mListener.onImageAvailable = nullptr; 100 } else { 101 mListener = *listener; 102 } 103 return AMEDIA_OK; 104 } 105 106 media_status_t 107 AImageReader::setImageListenerLocked(AImageReader_ImageListener* listener) { 108 return mFrameListener->setImageListener(listener); 109 } 110 111 media_status_t 112 AImageReader::setImageListener(AImageReader_ImageListener* listener) { 113 Mutex::Autolock _l(mLock); 114 return setImageListenerLocked(listener); 115 } 116 117 void AImageReader::CallbackHandler::onMessageReceived( 118 const sp<AMessage> &msg) { 119 switch (msg->what()) { 120 case kWhatImageAvailable: 121 { 122 AImageReader_ImageCallback onImageAvailable; 123 void* context; 124 bool found = msg->findPointer(kCallbackFpKey, (void**) &onImageAvailable); 125 if (!found || onImageAvailable == nullptr) { 126 ALOGE("%s: Cannot find onImageAvailable callback fp!", __FUNCTION__); 127 return; 128 } 129 found = msg->findPointer(kContextKey, &context); 130 if (!found) { 131 ALOGE("%s: Cannot find callback context!", __FUNCTION__); 132 return; 133 } 134 (*onImageAvailable)(context, mReader); 135 break; 136 } 137 default: 138 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what()); 139 break; 140 } 141 } 142 143 AImageReader::AImageReader(int32_t width, int32_t height, int32_t format, int32_t maxImages) : 144 mWidth(width), mHeight(height), mFormat(format), mMaxImages(maxImages), 145 mNumPlanes(getNumPlanesForFormat(format)), 146 mFrameListener(new FrameListener(this)) {} 147 148 media_status_t 149 AImageReader::init() { 150 PublicFormat publicFormat = static_cast<PublicFormat>(mFormat); 151 mHalFormat = android_view_Surface_mapPublicFormatToHalFormat(publicFormat); 152 mHalDataSpace = android_view_Surface_mapPublicFormatToHalDataspace(publicFormat); 153 154 sp<IGraphicBufferProducer> gbProducer; 155 sp<IGraphicBufferConsumer> gbConsumer; 156 BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 157 158 sp<CpuConsumer> cpuConsumer; 159 String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d", 160 mWidth, mHeight, mFormat, mMaxImages, getpid(), 161 createProcessUniqueId()); 162 163 cpuConsumer = new CpuConsumer(gbConsumer, mMaxImages, /*controlledByApp*/true); 164 if (cpuConsumer == nullptr) { 165 ALOGE("Failed to allocate CpuConsumer"); 166 return AMEDIA_ERROR_UNKNOWN; 167 } 168 169 mCpuConsumer = cpuConsumer; 170 mCpuConsumer->setName(consumerName); 171 mProducer = gbProducer; 172 173 sp<ConsumerBase> consumer = cpuConsumer; 174 consumer->setFrameAvailableListener(mFrameListener); 175 176 status_t res; 177 res = cpuConsumer->setDefaultBufferSize(mWidth, mHeight); 178 if (res != OK) { 179 ALOGE("Failed to set CpuConsumer buffer size"); 180 return AMEDIA_ERROR_UNKNOWN; 181 } 182 res = cpuConsumer->setDefaultBufferFormat(mHalFormat); 183 if (res != OK) { 184 ALOGE("Failed to set CpuConsumer buffer format"); 185 return AMEDIA_ERROR_UNKNOWN; 186 } 187 res = cpuConsumer->setDefaultBufferDataSpace(mHalDataSpace); 188 if (res != OK) { 189 ALOGE("Failed to set CpuConsumer buffer dataSpace"); 190 return AMEDIA_ERROR_UNKNOWN; 191 } 192 193 mSurface = new Surface(mProducer, /*controlledByApp*/true); 194 if (mSurface == nullptr) { 195 ALOGE("Failed to create surface"); 196 return AMEDIA_ERROR_UNKNOWN; 197 } 198 mWindow = static_cast<ANativeWindow*>(mSurface.get()); 199 200 for (int i = 0; i < mMaxImages; i++) { 201 CpuConsumer::LockedBuffer* buffer = new CpuConsumer::LockedBuffer; 202 mBuffers.push_back(buffer); 203 } 204 205 mCbLooper = new ALooper; 206 mCbLooper->setName(consumerName.string()); 207 res = mCbLooper->start( 208 /*runOnCallingThread*/false, 209 /*canCallJava*/ true, 210 PRIORITY_DEFAULT); 211 if (res != OK) { 212 ALOGE("Failed to start the looper"); 213 return AMEDIA_ERROR_UNKNOWN; 214 } 215 mHandler = new CallbackHandler(this); 216 mCbLooper->registerHandler(mHandler); 217 218 return AMEDIA_OK; 219 } 220 221 AImageReader::~AImageReader() { 222 Mutex::Autolock _l(mLock); 223 AImageReader_ImageListener nullListener = {nullptr, nullptr}; 224 setImageListenerLocked(&nullListener); 225 226 if (mCbLooper != nullptr) { 227 mCbLooper->unregisterHandler(mHandler->id()); 228 mCbLooper->stop(); 229 } 230 mCbLooper.clear(); 231 mHandler.clear(); 232 233 // Close all previously acquired images 234 for (auto it = mAcquiredImages.begin(); 235 it != mAcquiredImages.end(); it++) { 236 AImage* image = *it; 237 image->close(); 238 } 239 240 // Delete LockedBuffers 241 for (auto it = mBuffers.begin(); 242 it != mBuffers.end(); it++) { 243 delete *it; 244 } 245 246 if (mCpuConsumer != nullptr) { 247 mCpuConsumer->abandon(); 248 mCpuConsumer->setFrameAvailableListener(nullptr); 249 } 250 } 251 252 media_status_t 253 AImageReader::acquireCpuConsumerImageLocked(/*out*/AImage** image) { 254 *image = nullptr; 255 CpuConsumer::LockedBuffer* buffer = getLockedBufferLocked(); 256 if (buffer == nullptr) { 257 ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than" 258 " maxImages buffers"); 259 return AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED; 260 } 261 262 status_t res = mCpuConsumer->lockNextBuffer(buffer); 263 if (res != NO_ERROR) { 264 returnLockedBufferLocked(buffer); 265 if (res != BAD_VALUE /*no buffers*/) { 266 if (res == NOT_ENOUGH_DATA) { 267 return AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED; 268 } else { 269 ALOGE("%s Fail to lockNextBuffer with error: %d ", 270 __FUNCTION__, res); 271 return AMEDIA_ERROR_UNKNOWN; 272 } 273 } 274 return AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE; 275 } 276 277 if (buffer->flexFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) { 278 ALOGE("NV21 format is not supported by AImageReader"); 279 return AMEDIA_ERROR_UNSUPPORTED; 280 } 281 282 // Check if the left-top corner of the crop rect is origin, we currently assume this point is 283 // zero, will revist this once this assumption turns out problematic. 284 Point lt = buffer->crop.leftTop(); 285 if (lt.x != 0 || lt.y != 0) { 286 ALOGE("crop left top corner [%d, %d] need to be at origin", lt.x, lt.y); 287 return AMEDIA_ERROR_UNKNOWN; 288 } 289 290 // Check if the producer buffer configurations match what ImageReader configured. 291 int outputWidth = getBufferWidth(buffer); 292 int outputHeight = getBufferHeight(buffer); 293 294 int readerFmt = mHalFormat; 295 int readerWidth = mWidth; 296 int readerHeight = mHeight; 297 298 if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (readerFmt != HAL_PIXEL_FORMAT_BLOB) && 299 (readerWidth != outputWidth || readerHeight != outputHeight)) { 300 ALOGW("%s: Producer buffer size: %dx%d, doesn't match AImageReader configured size: %dx%d", 301 __FUNCTION__, outputWidth, outputHeight, readerWidth, readerHeight); 302 } 303 304 int bufFmt = buffer->format; 305 if (readerFmt == HAL_PIXEL_FORMAT_YCbCr_420_888) { 306 bufFmt = buffer->flexFormat; 307 } 308 309 if (readerFmt != bufFmt) { 310 if (readerFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && (bufFmt == 311 HAL_PIXEL_FORMAT_YCrCb_420_SP || bufFmt == HAL_PIXEL_FORMAT_YV12)) { 312 // Special casing for when producer switches to a format compatible with flexible YUV 313 // (HAL_PIXEL_FORMAT_YCbCr_420_888). 314 mHalFormat = bufFmt; 315 ALOGD("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt); 316 } else { 317 // Return the buffer to the queue. 318 mCpuConsumer->unlockBuffer(*buffer); 319 returnLockedBufferLocked(buffer); 320 321 ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x", 322 buffer->format, readerFmt); 323 324 return AMEDIA_ERROR_UNKNOWN; 325 } 326 } 327 328 if (mHalFormat == HAL_PIXEL_FORMAT_BLOB) { 329 *image = new AImage(this, mFormat, buffer, buffer->timestamp, 330 readerWidth, readerHeight, mNumPlanes); 331 } else { 332 *image = new AImage(this, mFormat, buffer, buffer->timestamp, 333 outputWidth, outputHeight, mNumPlanes); 334 } 335 mAcquiredImages.push_back(*image); 336 return AMEDIA_OK; 337 } 338 339 CpuConsumer::LockedBuffer* 340 AImageReader::getLockedBufferLocked() { 341 if (mBuffers.empty()) { 342 return nullptr; 343 } 344 // Return a LockedBuffer pointer and remove it from the list 345 auto it = mBuffers.begin(); 346 CpuConsumer::LockedBuffer* buffer = *it; 347 mBuffers.erase(it); 348 return buffer; 349 } 350 351 void 352 AImageReader::returnLockedBufferLocked(CpuConsumer::LockedBuffer* buffer) { 353 mBuffers.push_back(buffer); 354 } 355 356 void 357 AImageReader::releaseImageLocked(AImage* image) { 358 CpuConsumer::LockedBuffer* buffer = image->mBuffer; 359 if (buffer == nullptr) { 360 // This should not happen, but is not fatal 361 ALOGW("AImage %p has no buffer!", image); 362 return; 363 } 364 365 mCpuConsumer->unlockBuffer(*buffer); 366 returnLockedBufferLocked(buffer); 367 image->mBuffer = nullptr; 368 369 bool found = false; 370 // cleanup acquired image list 371 for (auto it = mAcquiredImages.begin(); 372 it != mAcquiredImages.end(); it++) { 373 AImage* readerCopy = *it; 374 if (readerCopy == image) { 375 found = true; 376 mAcquiredImages.erase(it); 377 break; 378 } 379 } 380 if (!found) { 381 ALOGE("Error: AImage %p is not generated by AImageReader %p", 382 image, this); 383 } 384 } 385 386 int 387 AImageReader::getBufferWidth(CpuConsumer::LockedBuffer* buffer) { 388 if (buffer == nullptr) return -1; 389 390 if (!buffer->crop.isEmpty()) { 391 return buffer->crop.getWidth(); 392 } 393 return buffer->width; 394 } 395 396 int 397 AImageReader::getBufferHeight(CpuConsumer::LockedBuffer* buffer) { 398 if (buffer == nullptr) return -1; 399 400 if (!buffer->crop.isEmpty()) { 401 return buffer->crop.getHeight(); 402 } 403 return buffer->height; 404 } 405 406 media_status_t 407 AImageReader::acquireNextImage(/*out*/AImage** image) { 408 Mutex::Autolock _l(mLock); 409 return acquireCpuConsumerImageLocked(image); 410 } 411 412 media_status_t 413 AImageReader::acquireLatestImage(/*out*/AImage** image) { 414 if (image == nullptr) { 415 return AMEDIA_ERROR_INVALID_PARAMETER; 416 } 417 Mutex::Autolock _l(mLock); 418 *image = nullptr; 419 AImage* prevImage = nullptr; 420 AImage* nextImage = nullptr; 421 media_status_t ret = acquireCpuConsumerImageLocked(&prevImage); 422 if (prevImage == nullptr) { 423 return ret; 424 } 425 for (;;) { 426 ret = acquireCpuConsumerImageLocked(&nextImage); 427 if (nextImage == nullptr) { 428 *image = prevImage; 429 return AMEDIA_OK; 430 } 431 prevImage->close(); 432 prevImage->free(); 433 prevImage = nextImage; 434 nextImage = nullptr; 435 } 436 } 437 438 EXPORT 439 media_status_t AImageReader_new( 440 int32_t width, int32_t height, int32_t format, int32_t maxImages, 441 /*out*/AImageReader** reader) { 442 ALOGV("%s", __FUNCTION__); 443 444 if (width < 1 || height < 1) { 445 ALOGE("%s: image dimension must be positive: w:%d h:%d", 446 __FUNCTION__, width, height); 447 return AMEDIA_ERROR_INVALID_PARAMETER; 448 } 449 450 if (maxImages < 1) { 451 ALOGE("%s: max outstanding image count must be at least 1 (%d)", 452 __FUNCTION__, maxImages); 453 return AMEDIA_ERROR_INVALID_PARAMETER; 454 } 455 456 if (!AImageReader::isSupportedFormat(format)) { 457 ALOGE("%s: format %d is not supported by AImageReader", 458 __FUNCTION__, format); 459 return AMEDIA_ERROR_INVALID_PARAMETER; 460 } 461 462 if (reader == nullptr) { 463 ALOGE("%s: reader argument is null", __FUNCTION__); 464 return AMEDIA_ERROR_INVALID_PARAMETER; 465 } 466 467 //*reader = new AImageReader(width, height, format, maxImages); 468 AImageReader* tmpReader = new AImageReader(width, height, format, maxImages); 469 if (tmpReader == nullptr) { 470 ALOGE("%s: AImageReader allocation failed", __FUNCTION__); 471 return AMEDIA_ERROR_UNKNOWN; 472 } 473 media_status_t ret = tmpReader->init(); 474 if (ret != AMEDIA_OK) { 475 ALOGE("%s: AImageReader initialization failed!", __FUNCTION__); 476 delete tmpReader; 477 return ret; 478 } 479 *reader = tmpReader; 480 (*reader)->incStrong((void*) AImageReader_new); 481 return AMEDIA_OK; 482 } 483 484 EXPORT 485 void AImageReader_delete(AImageReader* reader) { 486 ALOGV("%s", __FUNCTION__); 487 if (reader != nullptr) { 488 reader->decStrong((void*) AImageReader_delete); 489 } 490 return; 491 } 492 493 EXPORT 494 media_status_t AImageReader_getWindow(AImageReader* reader, /*out*/ANativeWindow** window) { 495 ALOGE("%s", __FUNCTION__); 496 if (reader == nullptr || window == nullptr) { 497 ALOGE("%s: invalid argument. reader %p, window %p", 498 __FUNCTION__, reader, window); 499 return AMEDIA_ERROR_INVALID_PARAMETER; 500 } 501 *window = reader->getWindow(); 502 return AMEDIA_OK; 503 } 504 505 EXPORT 506 media_status_t AImageReader_getWidth(const AImageReader* reader, /*out*/int32_t* width) { 507 ALOGV("%s", __FUNCTION__); 508 if (reader == nullptr || width == nullptr) { 509 ALOGE("%s: invalid argument. reader %p, width %p", 510 __FUNCTION__, reader, width); 511 return AMEDIA_ERROR_INVALID_PARAMETER; 512 } 513 *width = reader->getWidth(); 514 return AMEDIA_OK; 515 } 516 517 EXPORT 518 media_status_t AImageReader_getHeight(const AImageReader* reader, /*out*/int32_t* height) { 519 ALOGV("%s", __FUNCTION__); 520 if (reader == nullptr || height == nullptr) { 521 ALOGE("%s: invalid argument. reader %p, height %p", 522 __FUNCTION__, reader, height); 523 return AMEDIA_ERROR_INVALID_PARAMETER; 524 } 525 *height = reader->getHeight(); 526 return AMEDIA_OK; 527 } 528 529 EXPORT 530 media_status_t AImageReader_getFormat(const AImageReader* reader, /*out*/int32_t* format) { 531 ALOGV("%s", __FUNCTION__); 532 if (reader == nullptr || format == nullptr) { 533 ALOGE("%s: invalid argument. reader %p, format %p", 534 __FUNCTION__, reader, format); 535 return AMEDIA_ERROR_INVALID_PARAMETER; 536 } 537 *format = reader->getFormat(); 538 return AMEDIA_OK; 539 } 540 541 EXPORT 542 media_status_t AImageReader_getMaxImages(const AImageReader* reader, /*out*/int32_t* maxImages) { 543 ALOGV("%s", __FUNCTION__); 544 if (reader == nullptr || maxImages == nullptr) { 545 ALOGE("%s: invalid argument. reader %p, maxImages %p", 546 __FUNCTION__, reader, maxImages); 547 return AMEDIA_ERROR_INVALID_PARAMETER; 548 } 549 *maxImages = reader->getMaxImages(); 550 return AMEDIA_OK; 551 } 552 553 EXPORT 554 media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image) { 555 ALOGV("%s", __FUNCTION__); 556 if (reader == nullptr || image == nullptr) { 557 ALOGE("%s: invalid argument. reader %p, maxImages %p", 558 __FUNCTION__, reader, image); 559 return AMEDIA_ERROR_INVALID_PARAMETER; 560 } 561 return reader->acquireNextImage(image); 562 } 563 564 EXPORT 565 media_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image) { 566 ALOGV("%s", __FUNCTION__); 567 if (reader == nullptr || image == nullptr) { 568 ALOGE("%s: invalid argument. reader %p, maxImages %p", 569 __FUNCTION__, reader, image); 570 return AMEDIA_ERROR_INVALID_PARAMETER; 571 } 572 return reader->acquireLatestImage(image); 573 } 574 575 EXPORT 576 media_status_t AImageReader_setImageListener( 577 AImageReader* reader, AImageReader_ImageListener* listener) { 578 ALOGV("%s", __FUNCTION__); 579 if (reader == nullptr) { 580 ALOGE("%s: invalid argument! reader %p", __FUNCTION__, reader); 581 return AMEDIA_ERROR_INVALID_PARAMETER; 582 } 583 584 reader->setImageListener(listener); 585 return AMEDIA_OK; 586 } 587