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 "NdkImage" 21 22 #include "NdkImagePriv.h" 23 #include "NdkImageReaderPriv.h" 24 25 #include <android_media_Utils.h> 26 #include <android_runtime/android_hardware_HardwareBuffer.h> 27 #include <utils/Log.h> 28 #include "hardware/camera3.h" 29 30 using namespace android; 31 32 #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 33 34 AImage::AImage(AImageReader* reader, int32_t format, uint64_t usage, BufferItem* buffer, 35 int64_t timestamp, int32_t width, int32_t height, int32_t numPlanes) : 36 mReader(reader), mFormat(format), mUsage(usage), mBuffer(buffer), mLockedBuffer(nullptr), 37 mTimestamp(timestamp), mWidth(width), mHeight(height), mNumPlanes(numPlanes) { 38 } 39 40 AImage::~AImage() { 41 Mutex::Autolock _l(mLock); 42 if (!mIsClosed) { 43 LOG_ALWAYS_FATAL( 44 "Error: AImage %p is deleted before returning buffer to AImageReader!", this); 45 } 46 } 47 48 bool 49 AImage::isClosed() const { 50 Mutex::Autolock _l(mLock); 51 return mIsClosed; 52 } 53 54 void 55 AImage::close(int releaseFenceFd) { 56 Mutex::Autolock _l(mLock); 57 if (mIsClosed) { 58 return; 59 } 60 sp<AImageReader> reader = mReader.promote(); 61 if (reader != nullptr) { 62 reader->releaseImageLocked(this, releaseFenceFd); 63 } else if (mBuffer != nullptr) { 64 LOG_ALWAYS_FATAL("%s: parent AImageReader closed without releasing image %p", 65 __FUNCTION__, this); 66 } 67 68 // Should have been set to nullptr in releaseImageLocked 69 // Set to nullptr here for extra safety only 70 mBuffer = nullptr; 71 mLockedBuffer = nullptr; 72 mIsClosed = true; 73 } 74 75 void 76 AImage::free() { 77 if (!isClosed()) { 78 ALOGE("Cannot free AImage before close!"); 79 return; 80 } 81 delete this; 82 } 83 84 void 85 AImage::lockReader() const { 86 sp<AImageReader> reader = mReader.promote(); 87 if (reader == nullptr) { 88 // Reader has been closed 89 return; 90 } 91 reader->mLock.lock(); 92 } 93 94 void 95 AImage::unlockReader() const { 96 sp<AImageReader> reader = mReader.promote(); 97 if (reader == nullptr) { 98 // Reader has been closed 99 return; 100 } 101 reader->mLock.unlock(); 102 } 103 104 media_status_t 105 AImage::getWidth(int32_t* width) const { 106 if (width == nullptr) { 107 return AMEDIA_ERROR_INVALID_PARAMETER; 108 } 109 *width = -1; 110 if (isClosed()) { 111 ALOGE("%s: image %p has been closed!", __FUNCTION__, this); 112 return AMEDIA_ERROR_INVALID_OBJECT; 113 } 114 *width = mWidth; 115 return AMEDIA_OK; 116 } 117 118 media_status_t 119 AImage::getHeight(int32_t* height) const { 120 if (height == nullptr) { 121 return AMEDIA_ERROR_INVALID_PARAMETER; 122 } 123 *height = -1; 124 if (isClosed()) { 125 ALOGE("%s: image %p has been closed!", __FUNCTION__, this); 126 return AMEDIA_ERROR_INVALID_OBJECT; 127 } 128 *height = mHeight; 129 return AMEDIA_OK; 130 } 131 132 media_status_t 133 AImage::getFormat(int32_t* format) const { 134 if (format == nullptr) { 135 return AMEDIA_ERROR_INVALID_PARAMETER; 136 } 137 *format = -1; 138 if (isClosed()) { 139 ALOGE("%s: image %p has been closed!", __FUNCTION__, this); 140 return AMEDIA_ERROR_INVALID_OBJECT; 141 } 142 *format = mFormat; 143 return AMEDIA_OK; 144 } 145 146 media_status_t 147 AImage::getNumPlanes(int32_t* numPlanes) const { 148 if (numPlanes == nullptr) { 149 return AMEDIA_ERROR_INVALID_PARAMETER; 150 } 151 *numPlanes = -1; 152 if (isClosed()) { 153 ALOGE("%s: image %p has been closed!", __FUNCTION__, this); 154 return AMEDIA_ERROR_INVALID_OBJECT; 155 } 156 *numPlanes = mNumPlanes; 157 return AMEDIA_OK; 158 } 159 160 media_status_t 161 AImage::getTimestamp(int64_t* timestamp) const { 162 if (timestamp == nullptr) { 163 return AMEDIA_ERROR_INVALID_PARAMETER; 164 } 165 *timestamp = -1; 166 if (isClosed()) { 167 ALOGE("%s: image %p has been closed!", __FUNCTION__, this); 168 return AMEDIA_ERROR_INVALID_OBJECT; 169 } 170 *timestamp = mTimestamp; 171 return AMEDIA_OK; 172 } 173 174 media_status_t AImage::lockImage() { 175 if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) { 176 LOG_ALWAYS_FATAL("%s: AImage %p has no buffer.", __FUNCTION__, this); 177 return AMEDIA_ERROR_INVALID_OBJECT; 178 } 179 180 if ((mUsage & AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN) == 0) { 181 ALOGE("%s: AImage %p does not have any software read usage bits set, usage=%" PRIu64 "", 182 __FUNCTION__, this, mUsage); 183 return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE; 184 } 185 186 if (mLockedBuffer != nullptr) { 187 // Return immediately if the image has already been locked. 188 return AMEDIA_OK; 189 } 190 191 auto lockedBuffer = std::make_unique<CpuConsumer::LockedBuffer>(); 192 193 uint64_t grallocUsage = android_hardware_HardwareBuffer_convertToGrallocUsageBits(mUsage); 194 195 status_t ret = 196 lockImageFromBuffer(mBuffer, grallocUsage, mBuffer->mFence->dup(), lockedBuffer.get()); 197 if (ret != OK) { 198 ALOGE("%s: AImage %p failed to lock, error=%d", __FUNCTION__, this, ret); 199 return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE; 200 } 201 202 ALOGV("%s: Successfully locked the image %p.", __FUNCTION__, this); 203 mLockedBuffer = std::move(lockedBuffer); 204 205 return AMEDIA_OK; 206 } 207 208 media_status_t AImage::unlockImageIfLocked(int* fenceFd) { 209 if (fenceFd == nullptr) { 210 LOG_ALWAYS_FATAL("%s: fenceFd cannot be null.", __FUNCTION__); 211 return AMEDIA_ERROR_INVALID_PARAMETER; 212 } 213 214 if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) { 215 LOG_ALWAYS_FATAL("%s: AImage %p has no buffer.", __FUNCTION__, this); 216 return AMEDIA_ERROR_INVALID_OBJECT; 217 } 218 219 if (mLockedBuffer == nullptr) { 220 // This image hasn't been locked yet, no need to unlock. 221 *fenceFd = -1; 222 return AMEDIA_OK; 223 } 224 225 // No fence by default. 226 int releaseFenceFd = -1; 227 status_t res = mBuffer->mGraphicBuffer->unlockAsync(&releaseFenceFd); 228 if (res != OK) { 229 ALOGE("%s unlock buffer failed on iamge %p.", __FUNCTION__, this); 230 *fenceFd = -1; 231 return AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE; 232 } 233 234 *fenceFd = releaseFenceFd; 235 return AMEDIA_OK; 236 } 237 238 media_status_t 239 AImage::getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const { 240 if (mLockedBuffer == nullptr) { 241 ALOGE("%s: buffer not locked.", __FUNCTION__); 242 return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED; 243 } 244 245 if (planeIdx < 0 || planeIdx >= mNumPlanes) { 246 ALOGE("Error: planeIdx %d out of bound [0,%d]", 247 planeIdx, mNumPlanes - 1); 248 return AMEDIA_ERROR_INVALID_PARAMETER; 249 } 250 if (pixelStride == nullptr) { 251 return AMEDIA_ERROR_INVALID_PARAMETER; 252 } 253 if (isClosed()) { 254 ALOGE("%s: image %p has been closed!", __FUNCTION__, this); 255 return AMEDIA_ERROR_INVALID_OBJECT; 256 } 257 int32_t fmt = mLockedBuffer->flexFormat; 258 switch (fmt) { 259 case HAL_PIXEL_FORMAT_YCbCr_420_888: 260 *pixelStride = (planeIdx == 0) ? 1 : mLockedBuffer->chromaStep; 261 return AMEDIA_OK; 262 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 263 *pixelStride = (planeIdx == 0) ? 1 : 2; 264 return AMEDIA_OK; 265 case HAL_PIXEL_FORMAT_Y8: 266 *pixelStride = 1; 267 return AMEDIA_OK; 268 case HAL_PIXEL_FORMAT_YV12: 269 *pixelStride = 1; 270 return AMEDIA_OK; 271 case HAL_PIXEL_FORMAT_Y16: 272 case HAL_PIXEL_FORMAT_RAW16: 273 case HAL_PIXEL_FORMAT_RGB_565: 274 // Single plane 16bpp data. 275 *pixelStride = 2; 276 return AMEDIA_OK; 277 case HAL_PIXEL_FORMAT_RGBA_8888: 278 case HAL_PIXEL_FORMAT_RGBX_8888: 279 *pixelStride = 4; 280 return AMEDIA_OK; 281 case HAL_PIXEL_FORMAT_RGB_888: 282 // Single plane, 24bpp. 283 *pixelStride = 3; 284 return AMEDIA_OK; 285 case HAL_PIXEL_FORMAT_BLOB: 286 case HAL_PIXEL_FORMAT_RAW10: 287 case HAL_PIXEL_FORMAT_RAW12: 288 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 289 // Blob is used for JPEG data, RAW10 and RAW12 is used for 10-bit and 12-bit raw data, 290 // those are single plane data without pixel stride defined 291 return AMEDIA_ERROR_UNSUPPORTED; 292 default: 293 ALOGE("Pixel format: 0x%x is unsupported", fmt); 294 return AMEDIA_ERROR_UNSUPPORTED; 295 } 296 } 297 298 media_status_t 299 AImage::getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const { 300 if (mLockedBuffer == nullptr) { 301 ALOGE("%s: buffer not locked.", __FUNCTION__); 302 return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED; 303 } 304 305 if (planeIdx < 0 || planeIdx >= mNumPlanes) { 306 ALOGE("Error: planeIdx %d out of bound [0,%d]", 307 planeIdx, mNumPlanes - 1); 308 return AMEDIA_ERROR_INVALID_PARAMETER; 309 } 310 if (rowStride == nullptr) { 311 return AMEDIA_ERROR_INVALID_PARAMETER; 312 } 313 if (isClosed()) { 314 ALOGE("%s: image %p has been closed!", __FUNCTION__, this); 315 return AMEDIA_ERROR_INVALID_OBJECT; 316 } 317 int32_t fmt = mLockedBuffer->flexFormat; 318 switch (fmt) { 319 case HAL_PIXEL_FORMAT_YCbCr_420_888: 320 *rowStride = (planeIdx == 0) ? mLockedBuffer->stride 321 : mLockedBuffer->chromaStride; 322 return AMEDIA_OK; 323 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 324 *rowStride = mLockedBuffer->width; 325 return AMEDIA_OK; 326 case HAL_PIXEL_FORMAT_YV12: 327 if (mLockedBuffer->stride % 16) { 328 ALOGE("Stride %d is not 16 pixel aligned!", mLockedBuffer->stride); 329 return AMEDIA_ERROR_UNKNOWN; 330 } 331 *rowStride = (planeIdx == 0) ? mLockedBuffer->stride 332 : ALIGN(mLockedBuffer->stride / 2, 16); 333 return AMEDIA_OK; 334 case HAL_PIXEL_FORMAT_RAW10: 335 case HAL_PIXEL_FORMAT_RAW12: 336 // RAW10 and RAW12 are used for 10-bit and 12-bit raw data, they are single plane 337 *rowStride = mLockedBuffer->stride; 338 return AMEDIA_OK; 339 case HAL_PIXEL_FORMAT_Y8: 340 if (mLockedBuffer->stride % 16) { 341 ALOGE("Stride %d is not 16 pixel aligned!", 342 mLockedBuffer->stride); 343 return AMEDIA_ERROR_UNKNOWN; 344 } 345 *rowStride = mLockedBuffer->stride; 346 return AMEDIA_OK; 347 case HAL_PIXEL_FORMAT_Y16: 348 case HAL_PIXEL_FORMAT_RAW16: 349 // In native side, strides are specified in pixels, not in bytes. 350 // Single plane 16bpp bayer data. even width/height, 351 // row stride multiple of 16 pixels (32 bytes) 352 if (mLockedBuffer->stride % 16) { 353 ALOGE("Stride %d is not 16 pixel aligned!", 354 mLockedBuffer->stride); 355 return AMEDIA_ERROR_UNKNOWN; 356 } 357 *rowStride = mLockedBuffer->stride * 2; 358 return AMEDIA_OK; 359 case HAL_PIXEL_FORMAT_RGB_565: 360 *rowStride = mLockedBuffer->stride * 2; 361 return AMEDIA_OK; 362 case HAL_PIXEL_FORMAT_RGBA_8888: 363 case HAL_PIXEL_FORMAT_RGBX_8888: 364 *rowStride = mLockedBuffer->stride * 4; 365 return AMEDIA_OK; 366 case HAL_PIXEL_FORMAT_RGB_888: 367 // Single plane, 24bpp. 368 *rowStride = mLockedBuffer->stride * 3; 369 return AMEDIA_OK; 370 case HAL_PIXEL_FORMAT_BLOB: 371 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 372 // Blob is used for JPEG/Raw opaque data. It is single plane and has 0 row stride and 373 // no row stride defined 374 return AMEDIA_ERROR_UNSUPPORTED; 375 default: 376 ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt); 377 return AMEDIA_ERROR_UNSUPPORTED; 378 } 379 } 380 381 uint32_t 382 AImage::getJpegSize() const { 383 if (mLockedBuffer == nullptr) { 384 LOG_ALWAYS_FATAL("Error: buffer is null"); 385 } 386 387 uint32_t size = 0; 388 uint32_t width = mLockedBuffer->width; 389 uint8_t* jpegBuffer = mLockedBuffer->data; 390 391 // First check for JPEG transport header at the end of the buffer 392 uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob)); 393 struct camera3_jpeg_blob* blob = (struct camera3_jpeg_blob*)(header); 394 if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) { 395 size = blob->jpeg_size; 396 ALOGV("%s: Jpeg size = %d", __FUNCTION__, size); 397 } 398 399 // failed to find size, default to whole buffer 400 if (size == 0) { 401 /* 402 * This is a problem because not including the JPEG header 403 * means that in certain rare situations a regular JPEG blob 404 * will be misidentified as having a header, in which case 405 * we will get a garbage size value. 406 */ 407 ALOGW("%s: No JPEG header detected, defaulting to size=width=%d", 408 __FUNCTION__, width); 409 size = width; 410 } 411 412 return size; 413 } 414 415 media_status_t 416 AImage::getPlaneData(int planeIdx,/*out*/uint8_t** data, /*out*/int* dataLength) const { 417 if (mLockedBuffer == nullptr) { 418 ALOGE("%s: buffer not locked.", __FUNCTION__); 419 return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED; 420 } 421 422 if (planeIdx < 0 || planeIdx >= mNumPlanes) { 423 ALOGE("Error: planeIdx %d out of bound [0,%d]", 424 planeIdx, mNumPlanes - 1); 425 return AMEDIA_ERROR_INVALID_PARAMETER; 426 } 427 if (data == nullptr || dataLength == nullptr) { 428 return AMEDIA_ERROR_INVALID_PARAMETER; 429 } 430 if (isClosed()) { 431 ALOGE("%s: image %p has been closed!", __FUNCTION__, this); 432 return AMEDIA_ERROR_INVALID_OBJECT; 433 } 434 435 uint32_t dataSize, ySize, cSize, cStride; 436 uint8_t* cb = nullptr; 437 uint8_t* cr = nullptr; 438 uint8_t* pData = nullptr; 439 int bytesPerPixel = 0; 440 int32_t fmt = mLockedBuffer->flexFormat; 441 442 switch (fmt) { 443 case HAL_PIXEL_FORMAT_YCbCr_420_888: 444 pData = (planeIdx == 0) ? mLockedBuffer->data 445 : (planeIdx == 1) ? mLockedBuffer->dataCb 446 : mLockedBuffer->dataCr; 447 // only map until last pixel 448 if (planeIdx == 0) { 449 dataSize = mLockedBuffer->stride * (mLockedBuffer->height - 1) + 450 mLockedBuffer->width; 451 } else { 452 dataSize = 453 mLockedBuffer->chromaStride * 454 (mLockedBuffer->height / 2 - 1) + 455 mLockedBuffer->chromaStep * (mLockedBuffer->width / 2 - 1) + 456 1; 457 } 458 break; 459 // NV21 460 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 461 cr = mLockedBuffer->data + 462 (mLockedBuffer->stride * mLockedBuffer->height); 463 cb = cr + 1; 464 // only map until last pixel 465 ySize = mLockedBuffer->width * (mLockedBuffer->height - 1) + 466 mLockedBuffer->width; 467 cSize = mLockedBuffer->width * (mLockedBuffer->height / 2 - 1) + 468 mLockedBuffer->width - 1; 469 pData = (planeIdx == 0) ? mLockedBuffer->data 470 : (planeIdx == 1) ? cb : cr; 471 dataSize = (planeIdx == 0) ? ySize : cSize; 472 break; 473 case HAL_PIXEL_FORMAT_YV12: 474 // Y and C stride need to be 16 pixel aligned. 475 if (mLockedBuffer->stride % 16) { 476 ALOGE("Stride %d is not 16 pixel aligned!", 477 mLockedBuffer->stride); 478 return AMEDIA_ERROR_UNKNOWN; 479 } 480 481 ySize = mLockedBuffer->stride * mLockedBuffer->height; 482 cStride = ALIGN(mLockedBuffer->stride / 2, 16); 483 cr = mLockedBuffer->data + ySize; 484 cSize = cStride * mLockedBuffer->height / 2; 485 cb = cr + cSize; 486 487 pData = (planeIdx == 0) ? mLockedBuffer->data 488 : (planeIdx == 1) ? cb : cr; 489 dataSize = (planeIdx == 0) ? ySize : cSize; 490 break; 491 case HAL_PIXEL_FORMAT_Y8: 492 // Single plane, 8bpp. 493 494 pData = mLockedBuffer->data; 495 dataSize = mLockedBuffer->stride * mLockedBuffer->height; 496 break; 497 case HAL_PIXEL_FORMAT_Y16: 498 bytesPerPixel = 2; 499 500 pData = mLockedBuffer->data; 501 dataSize = 502 mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel; 503 break; 504 case HAL_PIXEL_FORMAT_BLOB: 505 // Used for JPEG data, height must be 1, width == size, single plane. 506 if (mLockedBuffer->height != 1) { 507 ALOGE("Jpeg should have height value one but got %d", 508 mLockedBuffer->height); 509 return AMEDIA_ERROR_UNKNOWN; 510 } 511 512 pData = mLockedBuffer->data; 513 dataSize = getJpegSize(); 514 break; 515 case HAL_PIXEL_FORMAT_RAW16: 516 // Single plane 16bpp bayer data. 517 bytesPerPixel = 2; 518 pData = mLockedBuffer->data; 519 dataSize = 520 mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel; 521 break; 522 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 523 // Used for RAW_OPAQUE data, height must be 1, width == size, single plane. 524 if (mLockedBuffer->height != 1) { 525 ALOGE("RAW_OPAQUE should have height value one but got %d", 526 mLockedBuffer->height); 527 return AMEDIA_ERROR_UNKNOWN; 528 } 529 pData = mLockedBuffer->data; 530 dataSize = mLockedBuffer->width; 531 break; 532 case HAL_PIXEL_FORMAT_RAW10: 533 // Single plane 10bpp bayer data. 534 if (mLockedBuffer->width % 4) { 535 ALOGE("Width is not multiple of 4 %d", mLockedBuffer->width); 536 return AMEDIA_ERROR_UNKNOWN; 537 } 538 if (mLockedBuffer->height % 2) { 539 ALOGE("Height is not multiple of 2 %d", mLockedBuffer->height); 540 return AMEDIA_ERROR_UNKNOWN; 541 } 542 if (mLockedBuffer->stride < (mLockedBuffer->width * 10 / 8)) { 543 ALOGE("stride (%d) should be at least %d", 544 mLockedBuffer->stride, mLockedBuffer->width * 10 / 8); 545 return AMEDIA_ERROR_UNKNOWN; 546 } 547 pData = mLockedBuffer->data; 548 dataSize = mLockedBuffer->stride * mLockedBuffer->height; 549 break; 550 case HAL_PIXEL_FORMAT_RAW12: 551 // Single plane 10bpp bayer data. 552 if (mLockedBuffer->width % 4) { 553 ALOGE("Width is not multiple of 4 %d", mLockedBuffer->width); 554 return AMEDIA_ERROR_UNKNOWN; 555 } 556 if (mLockedBuffer->height % 2) { 557 ALOGE("Height is not multiple of 2 %d", mLockedBuffer->height); 558 return AMEDIA_ERROR_UNKNOWN; 559 } 560 if (mLockedBuffer->stride < (mLockedBuffer->width * 12 / 8)) { 561 ALOGE("stride (%d) should be at least %d", 562 mLockedBuffer->stride, mLockedBuffer->width * 12 / 8); 563 return AMEDIA_ERROR_UNKNOWN; 564 } 565 pData = mLockedBuffer->data; 566 dataSize = mLockedBuffer->stride * mLockedBuffer->height; 567 break; 568 case HAL_PIXEL_FORMAT_RGBA_8888: 569 case HAL_PIXEL_FORMAT_RGBX_8888: 570 // Single plane, 32bpp. 571 bytesPerPixel = 4; 572 pData = mLockedBuffer->data; 573 dataSize = 574 mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel; 575 break; 576 case HAL_PIXEL_FORMAT_RGB_565: 577 // Single plane, 16bpp. 578 bytesPerPixel = 2; 579 pData = mLockedBuffer->data; 580 dataSize = 581 mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel; 582 break; 583 case HAL_PIXEL_FORMAT_RGB_888: 584 // Single plane, 24bpp. 585 bytesPerPixel = 3; 586 pData = mLockedBuffer->data; 587 dataSize = mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel; 588 break; 589 default: 590 ALOGE("Pixel format: 0x%x is unsupported", fmt); 591 return AMEDIA_ERROR_UNSUPPORTED; 592 } 593 594 *data = pData; 595 *dataLength = dataSize; 596 return AMEDIA_OK; 597 } 598 599 media_status_t 600 AImage::getHardwareBuffer(/*out*/AHardwareBuffer** buffer) const { 601 if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) { 602 ALOGE("%s: AImage %p has no buffer.", __FUNCTION__, this); 603 return AMEDIA_ERROR_INVALID_OBJECT; 604 } 605 606 // TODO(jwcai) Someone from Android graphics team stating this should just be a static_cast. 607 *buffer = reinterpret_cast<AHardwareBuffer*>(mBuffer->mGraphicBuffer.get()); 608 return AMEDIA_OK; 609 } 610 611 EXPORT 612 void AImage_delete(AImage* image) { 613 ALOGV("%s", __FUNCTION__); 614 AImage_deleteAsync(image, -1); 615 return; 616 } 617 618 EXPORT 619 void AImage_deleteAsync(AImage* image, int releaseFenceFd) { 620 ALOGV("%s", __FUNCTION__); 621 if (image != nullptr) { 622 image->lockReader(); 623 image->close(releaseFenceFd); 624 image->unlockReader(); 625 if (!image->isClosed()) { 626 LOG_ALWAYS_FATAL("Image close failed!"); 627 } 628 image->free(); 629 } 630 return; 631 } 632 633 EXPORT 634 media_status_t AImage_getWidth(const AImage* image, /*out*/int32_t* width) { 635 ALOGV("%s", __FUNCTION__); 636 if (image == nullptr || width == nullptr) { 637 ALOGE("%s: bad argument. image %p width %p", 638 __FUNCTION__, image, width); 639 return AMEDIA_ERROR_INVALID_PARAMETER; 640 } 641 return image->getWidth(width); 642 } 643 644 EXPORT 645 media_status_t AImage_getHeight(const AImage* image, /*out*/int32_t* height) { 646 ALOGV("%s", __FUNCTION__); 647 if (image == nullptr || height == nullptr) { 648 ALOGE("%s: bad argument. image %p height %p", 649 __FUNCTION__, image, height); 650 return AMEDIA_ERROR_INVALID_PARAMETER; 651 } 652 return image->getHeight(height); 653 } 654 655 EXPORT 656 media_status_t AImage_getFormat(const AImage* image, /*out*/int32_t* format) { 657 ALOGV("%s", __FUNCTION__); 658 if (image == nullptr || format == nullptr) { 659 ALOGE("%s: bad argument. image %p format %p", 660 __FUNCTION__, image, format); 661 return AMEDIA_ERROR_INVALID_PARAMETER; 662 } 663 return image->getFormat(format); 664 } 665 666 EXPORT 667 media_status_t AImage_getCropRect(const AImage* image, /*out*/AImageCropRect* rect) { 668 ALOGV("%s", __FUNCTION__); 669 if (image == nullptr || rect == nullptr) { 670 ALOGE("%s: bad argument. image %p rect %p", 671 __FUNCTION__, image, rect); 672 return AMEDIA_ERROR_INVALID_PARAMETER; 673 } 674 // For now AImage only supports camera outputs where cropRect is always full window 675 int32_t width = -1; 676 media_status_t ret = image->getWidth(&width); 677 if (ret != AMEDIA_OK) { 678 return ret; 679 } 680 int32_t height = -1; 681 ret = image->getHeight(&height); 682 if (ret != AMEDIA_OK) { 683 return ret; 684 } 685 rect->left = 0; 686 rect->top = 0; 687 rect->right = width; 688 rect->bottom = height; 689 return AMEDIA_OK; 690 } 691 692 EXPORT 693 media_status_t AImage_getTimestamp(const AImage* image, /*out*/int64_t* timestampNs) { 694 ALOGV("%s", __FUNCTION__); 695 if (image == nullptr || timestampNs == nullptr) { 696 ALOGE("%s: bad argument. image %p timestampNs %p", 697 __FUNCTION__, image, timestampNs); 698 return AMEDIA_ERROR_INVALID_PARAMETER; 699 } 700 return image->getTimestamp(timestampNs); 701 } 702 703 EXPORT 704 media_status_t AImage_getNumberOfPlanes(const AImage* image, /*out*/int32_t* numPlanes) { 705 ALOGV("%s", __FUNCTION__); 706 if (image == nullptr || numPlanes == nullptr) { 707 ALOGE("%s: bad argument. image %p numPlanes %p", 708 __FUNCTION__, image, numPlanes); 709 return AMEDIA_ERROR_INVALID_PARAMETER; 710 } 711 return image->getNumPlanes(numPlanes); 712 } 713 714 EXPORT 715 media_status_t AImage_getPlanePixelStride( 716 const AImage* image, int planeIdx, /*out*/int32_t* pixelStride) { 717 ALOGV("%s", __FUNCTION__); 718 if (image == nullptr || pixelStride == nullptr) { 719 ALOGE("%s: bad argument. image %p pixelStride %p", 720 __FUNCTION__, image, pixelStride); 721 return AMEDIA_ERROR_INVALID_PARAMETER; 722 } 723 media_status_t ret = const_cast<AImage*>(image)->lockImage(); 724 if (ret != AMEDIA_OK) { 725 ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.", 726 __FUNCTION__, image, ret); 727 return ret; 728 } 729 return image->getPlanePixelStride(planeIdx, pixelStride); 730 } 731 732 EXPORT 733 media_status_t AImage_getPlaneRowStride( 734 const AImage* image, int planeIdx, /*out*/int32_t* rowStride) { 735 ALOGV("%s", __FUNCTION__); 736 if (image == nullptr || rowStride == nullptr) { 737 ALOGE("%s: bad argument. image %p rowStride %p", 738 __FUNCTION__, image, rowStride); 739 return AMEDIA_ERROR_INVALID_PARAMETER; 740 } 741 media_status_t ret = const_cast<AImage*>(image)->lockImage(); 742 if (ret != AMEDIA_OK) { 743 ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.", 744 __FUNCTION__, image, ret); 745 return ret; 746 } 747 return image->getPlaneRowStride(planeIdx, rowStride); 748 } 749 750 EXPORT 751 media_status_t AImage_getPlaneData( 752 const AImage* image, int planeIdx, 753 /*out*/uint8_t** data, /*out*/int* dataLength) { 754 ALOGV("%s", __FUNCTION__); 755 if (image == nullptr || data == nullptr || dataLength == nullptr) { 756 ALOGE("%s: bad argument. image %p data %p dataLength %p", 757 __FUNCTION__, image, data, dataLength); 758 return AMEDIA_ERROR_INVALID_PARAMETER; 759 } 760 media_status_t ret = const_cast<AImage*>(image)->lockImage(); 761 if (ret != AMEDIA_OK) { 762 ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.", 763 __FUNCTION__, image, ret); 764 return ret; 765 } 766 return image->getPlaneData(planeIdx, data, dataLength); 767 } 768 769 EXPORT 770 media_status_t AImage_getHardwareBuffer( 771 const AImage* image, /*out*/AHardwareBuffer** buffer) { 772 ALOGV("%s", __FUNCTION__); 773 774 if (image == nullptr || buffer == nullptr) { 775 ALOGE("%s: bad argument. image %p buffer %p", __FUNCTION__, image, buffer); 776 return AMEDIA_ERROR_INVALID_PARAMETER; 777 } 778 return image->getHardwareBuffer(buffer); 779 } 780