1 /* 2 * Copyright 2011, 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_NDEBUG 0 18 #define LOG_TAG "AndroidMediaUtils" 19 20 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h> 21 #include <ui/GraphicBufferMapper.h> 22 #include <ui/GraphicTypes.h> 23 #include <utils/Log.h> 24 25 #include "android_media_Utils.h" 26 27 #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) 28 29 // Must be in sync with the value in HeicCompositeStream.cpp 30 #define CAMERA3_HEIC_BLOB_ID 0x00FE 31 32 namespace android { 33 34 // -----------Utility functions used by ImageReader/Writer JNI----------------- 35 36 enum { 37 IMAGE_MAX_NUM_PLANES = 3, 38 }; 39 usingRGBAToJpegOverride(int32_t imageFormat,int32_t containerFormat)40 bool usingRGBAToJpegOverride(int32_t imageFormat, 41 int32_t containerFormat) { 42 return containerFormat == HAL_PIXEL_FORMAT_BLOB && imageFormat == HAL_PIXEL_FORMAT_RGBA_8888; 43 } 44 applyFormatOverrides(int32_t imageFormat,int32_t containerFormat)45 int32_t applyFormatOverrides(int32_t imageFormat, int32_t containerFormat) { 46 // Using HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers containing JPEGs to get around SW 47 // write limitations for some platforms (b/17379185). 48 if (usingRGBAToJpegOverride(imageFormat, containerFormat)) { 49 return HAL_PIXEL_FORMAT_BLOB; 50 } 51 return containerFormat; 52 } 53 isFormatOpaque(int format)54 bool isFormatOpaque(int format) { 55 // This is the only opaque format exposed in the ImageFormat public API. 56 // Note that we do support CPU access for HAL_PIXEL_FORMAT_RAW_OPAQUE 57 // (ImageFormat#RAW_PRIVATE) so it doesn't count as opaque here. 58 return format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 59 } 60 isPossiblyYUV(PixelFormat format)61 bool isPossiblyYUV(PixelFormat format) { 62 switch (static_cast<int>(format)) { 63 case HAL_PIXEL_FORMAT_RGBA_8888: 64 case HAL_PIXEL_FORMAT_RGBX_8888: 65 case HAL_PIXEL_FORMAT_RGB_888: 66 case HAL_PIXEL_FORMAT_RGB_565: 67 case HAL_PIXEL_FORMAT_BGRA_8888: 68 case HAL_PIXEL_FORMAT_Y8: 69 case HAL_PIXEL_FORMAT_Y16: 70 case HAL_PIXEL_FORMAT_RAW16: 71 case HAL_PIXEL_FORMAT_RAW12: 72 case HAL_PIXEL_FORMAT_RAW10: 73 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 74 case HAL_PIXEL_FORMAT_BLOB: 75 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 76 case HAL_PIXEL_FORMAT_YCBCR_P010: 77 return false; 78 79 case HAL_PIXEL_FORMAT_YV12: 80 case HAL_PIXEL_FORMAT_YCbCr_420_888: 81 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 82 default: 83 return true; 84 } 85 } 86 isPossibly10BitYUV(PixelFormat format)87 bool isPossibly10BitYUV(PixelFormat format) { 88 switch (static_cast<int>(format)) { 89 case HAL_PIXEL_FORMAT_RGBA_8888: 90 case HAL_PIXEL_FORMAT_RGBX_8888: 91 case HAL_PIXEL_FORMAT_RGB_888: 92 case HAL_PIXEL_FORMAT_RGB_565: 93 case HAL_PIXEL_FORMAT_BGRA_8888: 94 case HAL_PIXEL_FORMAT_Y8: 95 case HAL_PIXEL_FORMAT_Y16: 96 case HAL_PIXEL_FORMAT_RAW16: 97 case HAL_PIXEL_FORMAT_RAW12: 98 case HAL_PIXEL_FORMAT_RAW10: 99 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 100 case HAL_PIXEL_FORMAT_BLOB: 101 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 102 case HAL_PIXEL_FORMAT_YV12: 103 case HAL_PIXEL_FORMAT_YCbCr_420_888: 104 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 105 return false; 106 107 case HAL_PIXEL_FORMAT_YCBCR_P010: 108 default: 109 return true; 110 } 111 } 112 Image_getBlobSize(LockedImage * buffer,bool usingRGBAOverride)113 uint32_t Image_getBlobSize(LockedImage* buffer, bool usingRGBAOverride) { 114 ALOGV("%s", __FUNCTION__); 115 LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!"); 116 uint32_t size = 0; 117 uint32_t width = buffer->width; 118 uint8_t* blobBuffer = buffer->data; 119 120 if (usingRGBAOverride) { 121 width = (buffer->width + buffer->stride * (buffer->height - 1)) * 4; 122 } 123 124 // First check for BLOB transport header at the end of the buffer 125 uint8_t* header = blobBuffer + (width - sizeof(struct camera3_jpeg_blob_v2)); 126 127 // read camera3_jpeg_blob_v2 from the end of the passed buffer. 128 // requires memcpy because 'header' might not be properly aligned. 129 struct camera3_jpeg_blob_v2 blob; 130 memcpy(&blob, header, sizeof(struct camera3_jpeg_blob_v2)); 131 132 if (blob.jpeg_blob_id == CAMERA3_JPEG_BLOB_ID || 133 blob.jpeg_blob_id == CAMERA3_HEIC_BLOB_ID) { 134 size = blob.jpeg_size; 135 ALOGV("%s: Jpeg/Heic size = %d", __FUNCTION__, size); 136 } 137 138 // failed to find size, default to whole buffer 139 if (size == 0) { 140 /* 141 * This is a problem because not including the JPEG/BLOB header 142 * means that in certain rare situations a regular JPEG/HEIC blob 143 * will be mis-identified as having a header, in which case 144 * we will get a garbage size value. 145 */ 146 ALOGW("%s: No JPEG/HEIC header detected, defaulting to size=width=%d", 147 __FUNCTION__, width); 148 size = width; 149 } 150 151 return size; 152 } 153 getLockedImageInfo(LockedImage * buffer,int idx,int32_t containerFormat,uint8_t ** base,uint32_t * size,int * pixelStride,int * rowStride)154 status_t getLockedImageInfo(LockedImage* buffer, int idx, 155 int32_t containerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) { 156 ALOGV("%s", __FUNCTION__); 157 LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!"); 158 LOG_ALWAYS_FATAL_IF(base == NULL, "base is NULL!!!"); 159 LOG_ALWAYS_FATAL_IF(size == NULL, "size is NULL!!!"); 160 LOG_ALWAYS_FATAL_IF(pixelStride == NULL, "pixelStride is NULL!!!"); 161 LOG_ALWAYS_FATAL_IF(rowStride == NULL, "rowStride is NULL!!!"); 162 LOG_ALWAYS_FATAL_IF((idx >= IMAGE_MAX_NUM_PLANES) || (idx < 0), "idx (%d) is illegal", idx); 163 164 ALOGV("%s: buffer: %p", __FUNCTION__, buffer); 165 166 uint32_t dataSize, ySize, cSize, cStride; 167 uint32_t pStride = 0, rStride = 0; 168 uint8_t *cb, *cr; 169 uint8_t *pData = NULL; 170 int bytesPerPixel = 0; 171 172 dataSize = ySize = cSize = cStride = 0; 173 int32_t fmt = buffer->flexFormat; 174 175 bool usingRGBAOverride = usingRGBAToJpegOverride(fmt, containerFormat); 176 fmt = applyFormatOverrides(fmt, containerFormat); 177 switch (fmt) { 178 case HAL_PIXEL_FORMAT_YCbCr_420_888: 179 // Width and height should be multiple of 2. Wrong dataSize would be returned otherwise. 180 if (buffer->width % 2 != 0) { 181 ALOGE("YCbCr_420_888: width (%d) should be a multiple of 2", buffer->width); 182 return BAD_VALUE; 183 } 184 185 if (buffer->height % 2 != 0) { 186 ALOGE("YCbCr_420_888: height (%d) should be a multiple of 2", buffer->height); 187 return BAD_VALUE; 188 } 189 190 if (buffer->width <= 0) { 191 ALOGE("YCbCr_420_888: width (%d) should be a > 0", buffer->width); 192 return BAD_VALUE; 193 } 194 195 if (buffer->height <= 0) { 196 ALOGE("YCbCr_420_888: height (%d) should be a > 0", buffer->height); 197 return BAD_VALUE; 198 } 199 200 pData = 201 (idx == 0) ? 202 buffer->data : 203 (idx == 1) ? 204 buffer->dataCb : 205 buffer->dataCr; 206 // only map until last pixel 207 if (idx == 0) { 208 pStride = 1; 209 rStride = buffer->stride; 210 dataSize = buffer->stride * (buffer->height - 1) + buffer->width; 211 } else { 212 pStride = buffer->chromaStep; 213 rStride = buffer->chromaStride; 214 dataSize = buffer->chromaStride * (buffer->height / 2 - 1) + 215 buffer->chromaStep * (buffer->width / 2 - 1) + 1; 216 } 217 break; 218 // NV21 219 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 220 // Width and height should be multiple of 2. Wrong dataSize would be returned otherwise. 221 if (buffer->width % 2 != 0) { 222 ALOGE("YCrCb_420_SP: width (%d) should be a multiple of 2", buffer->width); 223 return BAD_VALUE; 224 } 225 226 if (buffer->height % 2 != 0) { 227 ALOGE("YCrCb_420_SP: height (%d) should be a multiple of 2", buffer->height); 228 return BAD_VALUE; 229 } 230 231 if (buffer->width <= 0) { 232 ALOGE("YCrCb_420_SP: width (%d) should be a > 0", buffer->width); 233 return BAD_VALUE; 234 } 235 236 if (buffer->height <= 0) { 237 ALOGE("YCrCb_420_SP: height (%d) should be a > 0", buffer->height); 238 return BAD_VALUE; 239 } 240 241 cr = buffer->data + (buffer->stride * buffer->height); 242 cb = cr + 1; 243 // only map until last pixel 244 ySize = buffer->width * (buffer->height - 1) + buffer->width; 245 cSize = buffer->width * (buffer->height / 2 - 1) + buffer->width - 1; 246 247 pData = 248 (idx == 0) ? 249 buffer->data : 250 (idx == 1) ? 251 cb: 252 cr; 253 254 dataSize = (idx == 0) ? ySize : cSize; 255 pStride = (idx == 0) ? 1 : 2; 256 rStride = buffer->width; 257 break; 258 case HAL_PIXEL_FORMAT_YV12: 259 // Width and height should be multiple of 2. Wrong dataSize would be returned otherwise. 260 if (buffer->width % 2 != 0) { 261 ALOGE("YV12: width (%d) should be a multiple of 2", buffer->width); 262 return BAD_VALUE; 263 } 264 265 if (buffer->height % 2 != 0) { 266 ALOGE("YV12: height (%d) should be a multiple of 2", buffer->height); 267 return BAD_VALUE; 268 } 269 270 if (buffer->width <= 0) { 271 ALOGE("YV12: width (%d) should be a > 0", buffer->width); 272 return BAD_VALUE; 273 } 274 275 if (buffer->height <= 0) { 276 ALOGE("YV12: height (%d) should be a > 0", buffer->height); 277 return BAD_VALUE; 278 } 279 280 // Y and C stride need to be 16 pixel aligned. 281 LOG_ALWAYS_FATAL_IF(buffer->stride % 16, 282 "Stride is not 16 pixel aligned %d", buffer->stride); 283 284 ySize = buffer->stride * buffer->height; 285 cStride = ALIGN(buffer->stride / 2, 16); 286 cr = buffer->data + ySize; 287 cSize = cStride * buffer->height / 2; 288 cb = cr + cSize; 289 290 pData = 291 (idx == 0) ? 292 buffer->data : 293 (idx == 1) ? 294 cb : 295 cr; 296 dataSize = (idx == 0) ? ySize : cSize; 297 pStride = 1; 298 rStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16); 299 break; 300 case HAL_PIXEL_FORMAT_YCBCR_P010: 301 if (buffer->height % 2 != 0) { 302 ALOGE("YCBCR_P010: height (%d) should be a multiple of 2", buffer->height); 303 return BAD_VALUE; 304 } 305 306 if (buffer->width <= 0) { 307 ALOGE("YCBCR_P010: width (%d) should be a > 0", buffer->width); 308 return BAD_VALUE; 309 } 310 311 if (buffer->height <= 0) { 312 ALOGE("YCBCR_P010: height (%d) should be a > 0", buffer->height); 313 return BAD_VALUE; 314 } 315 316 if (buffer->dataCb && buffer->dataCr) { 317 pData = 318 (idx == 0) ? 319 buffer->data : 320 (idx == 1) ? 321 buffer->dataCb : 322 buffer->dataCr; 323 // only map until last pixel 324 if (idx == 0) { 325 pStride = 2; 326 rStride = buffer->stride; 327 dataSize = buffer->stride * (buffer->height - 1) + buffer->width * 2; 328 } else { 329 pStride = buffer->chromaStep; 330 rStride = buffer->chromaStride; 331 dataSize = buffer->chromaStride * (buffer->height / 2 - 1) + 332 buffer->chromaStep * (buffer->width / 2); 333 } 334 break; 335 } 336 337 ySize = (buffer->stride * 2) * buffer->height; 338 cSize = ySize / 2; 339 pStride = (idx == 0) ? 2 : 4; 340 cb = buffer->data + ySize; 341 cr = cb + 2; 342 343 pData = (idx == 0) ? buffer->data : (idx == 1) ? cb : cr; 344 dataSize = (idx == 0) ? ySize : cSize; 345 rStride = buffer->stride * 2; 346 break; 347 case HAL_PIXEL_FORMAT_Y8: 348 // Single plane, 8bpp. 349 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 350 351 pData = buffer->data; 352 dataSize = buffer->stride * buffer->height; 353 pStride = 1; 354 rStride = buffer->stride; 355 break; 356 case HAL_PIXEL_FORMAT_Y16: 357 bytesPerPixel = 2; 358 // Single plane, 16bpp, strides are specified in pixels, not in bytes 359 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 360 361 pData = buffer->data; 362 dataSize = buffer->stride * buffer->height * bytesPerPixel; 363 pStride = bytesPerPixel; 364 rStride = buffer->stride * 2; 365 break; 366 case HAL_PIXEL_FORMAT_BLOB: 367 // Used for JPEG data, height must be 1, width == size, single plane. 368 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 369 // When RGBA override is being used, buffer height will be equal to width 370 if (usingRGBAOverride) { 371 LOG_ALWAYS_FATAL_IF(buffer->height != buffer->width, 372 "RGBA override BLOB format buffer should have height == width"); 373 } else { 374 LOG_ALWAYS_FATAL_IF(buffer->height != 1, 375 "BLOB format buffer should have height value 1"); 376 } 377 378 379 pData = buffer->data; 380 dataSize = Image_getBlobSize(buffer, usingRGBAOverride); 381 pStride = 0; 382 rStride = 0; 383 break; 384 case HAL_PIXEL_FORMAT_RAW16: 385 // Single plane 16bpp bayer data. 386 bytesPerPixel = 2; 387 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 388 pData = buffer->data; 389 dataSize = buffer->stride * buffer->height * bytesPerPixel; 390 pStride = bytesPerPixel; 391 rStride = buffer->stride * 2; 392 break; 393 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 394 // Used for RAW_OPAQUE data, height must be 1, width == size, single plane. 395 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 396 LOG_ALWAYS_FATAL_IF(buffer->height != 1, 397 "RAW_PRIVATE should has height value one but got %d", buffer->height); 398 pData = buffer->data; 399 dataSize = buffer->width; 400 pStride = 0; // RAW OPAQUE doesn't have pixel stride 401 rStride = 0; // RAW OPAQUE doesn't have row stride 402 break; 403 case HAL_PIXEL_FORMAT_RAW10: 404 // Single plane 10bpp bayer data. 405 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 406 LOG_ALWAYS_FATAL_IF(buffer->width % 4, 407 "Width is not multiple of 4 %d", buffer->width); 408 LOG_ALWAYS_FATAL_IF(buffer->height % 2, 409 "Height is not even %d", buffer->height); 410 LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 10 / 8), 411 "stride (%d) should be at least %d", 412 buffer->stride, buffer->width * 10 / 8); 413 pData = buffer->data; 414 dataSize = buffer->stride * buffer->height; 415 pStride = 0; 416 rStride = buffer->stride; 417 break; 418 case HAL_PIXEL_FORMAT_RAW12: 419 // Single plane 10bpp bayer data. 420 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 421 LOG_ALWAYS_FATAL_IF(buffer->width % 4, 422 "Width is not multiple of 4 %d", buffer->width); 423 LOG_ALWAYS_FATAL_IF(buffer->height % 2, 424 "Height is not even %d", buffer->height); 425 LOG_ALWAYS_FATAL_IF(buffer->stride < (buffer->width * 12 / 8), 426 "stride (%d) should be at least %d", 427 buffer->stride, buffer->width * 12 / 8); 428 pData = buffer->data; 429 dataSize = buffer->stride * buffer->height; 430 pStride = 0; 431 rStride = buffer->stride; 432 break; 433 case HAL_PIXEL_FORMAT_RGBA_8888: 434 case HAL_PIXEL_FORMAT_RGBX_8888: 435 // Single plane, 32bpp. 436 bytesPerPixel = 4; 437 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 438 pData = buffer->data; 439 dataSize = buffer->stride * buffer->height * bytesPerPixel; 440 pStride = bytesPerPixel; 441 rStride = buffer->stride * 4; 442 break; 443 case HAL_PIXEL_FORMAT_RGB_565: 444 // Single plane, 16bpp. 445 bytesPerPixel = 2; 446 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 447 pData = buffer->data; 448 dataSize = buffer->stride * buffer->height * bytesPerPixel; 449 pStride = bytesPerPixel; 450 rStride = buffer->stride * 2; 451 break; 452 case HAL_PIXEL_FORMAT_RGB_888: 453 // Single plane, 24bpp. 454 bytesPerPixel = 3; 455 LOG_ALWAYS_FATAL_IF(idx != 0, "Wrong index: %d", idx); 456 pData = buffer->data; 457 dataSize = buffer->stride * buffer->height * bytesPerPixel; 458 pStride = bytesPerPixel; 459 rStride = buffer->stride * 3; 460 break; 461 default: 462 ALOGV("%s: unrecognized format 0x%x", __FUNCTION__, fmt); 463 return BAD_VALUE; 464 } 465 466 *base = pData; 467 *size = dataSize; 468 *pixelStride = pStride; 469 *rowStride = rStride; 470 471 return OK; 472 } 473 extractP010Gralloc4PlaneLayout(sp<GraphicBuffer> buffer,void * pData,int format,LockedImage * outputImage)474 static status_t extractP010Gralloc4PlaneLayout( 475 sp<GraphicBuffer> buffer, void *pData, int format, LockedImage *outputImage) { 476 using aidl::android::hardware::graphics::common::PlaneLayoutComponent; 477 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; 478 479 GraphicBufferMapper& mapper = GraphicBufferMapper::get(); 480 std::vector<ui::PlaneLayout> planeLayouts; 481 status_t res = mapper.getPlaneLayouts(buffer->handle, &planeLayouts); 482 if (res != OK) { 483 return res; 484 } 485 constexpr int64_t Y_PLANE_COMPONENTS = int64_t(PlaneLayoutComponentType::Y); 486 constexpr int64_t CBCR_PLANE_COMPONENTS = 487 int64_t(PlaneLayoutComponentType::CB) | int64_t(PlaneLayoutComponentType::CR); 488 uint8_t *dataY = nullptr; 489 uint8_t *dataCb = nullptr; 490 uint8_t *dataCr = nullptr; 491 uint32_t strideY = 0; 492 uint32_t strideCbCr = 0; 493 for (const ui::PlaneLayout &layout : planeLayouts) { 494 ALOGV("gralloc4 plane: %s", layout.toString().c_str()); 495 int64_t components = 0; 496 for (const PlaneLayoutComponent &component : layout.components) { 497 if (component.sizeInBits != 10) { 498 return BAD_VALUE; 499 } 500 components |= component.type.value; 501 } 502 if (components == Y_PLANE_COMPONENTS) { 503 if (layout.sampleIncrementInBits != 16) { 504 return BAD_VALUE; 505 } 506 if (layout.components[0].offsetInBits != 6) { 507 return BAD_VALUE; 508 } 509 dataY = (uint8_t *)pData + layout.offsetInBytes; 510 strideY = layout.strideInBytes; 511 } else if (components == CBCR_PLANE_COMPONENTS) { 512 if (layout.sampleIncrementInBits != 32) { 513 return BAD_VALUE; 514 } 515 for (const PlaneLayoutComponent &component : layout.components) { 516 if (component.type.value == int64_t(PlaneLayoutComponentType::CB) 517 && component.offsetInBits != 6) { 518 return BAD_VALUE; 519 } 520 if (component.type.value == int64_t(PlaneLayoutComponentType::CR) 521 && component.offsetInBits != 22) { 522 return BAD_VALUE; 523 } 524 } 525 dataCb = (uint8_t *)pData + layout.offsetInBytes; 526 dataCr = (uint8_t *)pData + layout.offsetInBytes + 2; 527 strideCbCr = layout.strideInBytes; 528 } else { 529 return BAD_VALUE; 530 } 531 } 532 533 outputImage->data = dataY; 534 outputImage->width = buffer->getWidth(); 535 outputImage->height = buffer->getHeight(); 536 outputImage->format = format; 537 outputImage->flexFormat = HAL_PIXEL_FORMAT_YCBCR_P010; 538 outputImage->stride = strideY; 539 540 outputImage->dataCb = dataCb; 541 outputImage->dataCr = dataCr; 542 outputImage->chromaStride = strideCbCr; 543 outputImage->chromaStep = 4; 544 return OK; 545 } 546 lockImageFromBuffer(sp<GraphicBuffer> buffer,uint32_t inUsage,const Rect & rect,int fenceFd,LockedImage * outputImage)547 status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage, 548 const Rect& rect, int fenceFd, LockedImage* outputImage) { 549 ALOGV("%s: Try to lock the GraphicBuffer", __FUNCTION__); 550 551 if (buffer == nullptr || outputImage == nullptr) { 552 ALOGE("Input BufferItem or output LockedImage is NULL!"); 553 return BAD_VALUE; 554 } 555 if (isFormatOpaque(buffer->getPixelFormat())) { 556 ALOGE("Opaque format buffer is not lockable!"); 557 return BAD_VALUE; 558 } 559 560 void* pData = NULL; 561 android_ycbcr ycbcr = android_ycbcr(); 562 status_t res; 563 int format = buffer->getPixelFormat(); 564 int flexFormat = format; 565 566 if (isPossiblyYUV(format)) { 567 res = buffer->lockAsyncYCbCr(inUsage, rect, &ycbcr, fenceFd); 568 569 if (res != OK) { 570 ALOGW("lockAsyncYCbCr failed with error %d (format = 0x%x)", res, format); 571 } 572 573 pData = ycbcr.y; 574 flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; 575 } 576 577 // lockAsyncYCbCr for YUV is unsuccessful. 578 if (pData == NULL) { 579 res = buffer->lockAsync(inUsage, rect, &pData, fenceFd); 580 if (res != OK) { 581 ALOGE("Lock buffer failed!"); 582 return res; 583 } 584 if (isPossibly10BitYUV(format) 585 && OK == extractP010Gralloc4PlaneLayout(buffer, pData, format, outputImage)) { 586 ALOGV("%s: Successfully locked the P010 image", __FUNCTION__); 587 return OK; 588 } 589 } 590 591 outputImage->data = reinterpret_cast<uint8_t*>(pData); 592 outputImage->width = buffer->getWidth(); 593 outputImage->height = buffer->getHeight(); 594 outputImage->format = format; 595 outputImage->flexFormat = flexFormat; 596 outputImage->stride = 597 (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : buffer->getStride(); 598 599 outputImage->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); 600 outputImage->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); 601 outputImage->chromaStride = static_cast<uint32_t>(ycbcr.cstride); 602 outputImage->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); 603 ALOGV("%s: Successfully locked the image from the GraphicBuffer", __FUNCTION__); 604 // Crop, transform, scalingMode, timestamp, and frameNumber should be set by caller, 605 // and cann't be set them here. 606 return OK; 607 } 608 lockImageFromBuffer(BufferItem * bufferItem,uint32_t inUsage,int fenceFd,LockedImage * outputImage)609 status_t lockImageFromBuffer(BufferItem* bufferItem, uint32_t inUsage, 610 int fenceFd, LockedImage* outputImage) { 611 ALOGV("%s: Try to lock the BufferItem", __FUNCTION__); 612 if (bufferItem == nullptr || outputImage == nullptr) { 613 ALOGE("Input BufferItem or output LockedImage is NULL!"); 614 return BAD_VALUE; 615 } 616 617 status_t res = lockImageFromBuffer(bufferItem->mGraphicBuffer, inUsage, bufferItem->mCrop, 618 fenceFd, outputImage); 619 if (res != OK) { 620 ALOGE("%s: lock graphic buffer failed", __FUNCTION__); 621 return res; 622 } 623 624 outputImage->crop = bufferItem->mCrop; 625 outputImage->transform = bufferItem->mTransform; 626 outputImage->scalingMode = bufferItem->mScalingMode; 627 outputImage->timestamp = bufferItem->mTimestamp; 628 outputImage->dataSpace = bufferItem->mDataSpace; 629 outputImage->frameNumber = bufferItem->mFrameNumber; 630 ALOGV("%s: Successfully locked the image from the BufferItem", __FUNCTION__); 631 return OK; 632 } 633 getBufferWidth(BufferItem * buffer)634 int getBufferWidth(BufferItem* buffer) { 635 if (buffer == NULL) return -1; 636 637 if (!buffer->mCrop.isEmpty()) { 638 return buffer->mCrop.getWidth(); 639 } 640 641 ALOGV("%s: buffer->mGraphicBuffer: %p", __FUNCTION__, buffer->mGraphicBuffer.get()); 642 return buffer->mGraphicBuffer->getWidth(); 643 } 644 getBufferHeight(BufferItem * buffer)645 int getBufferHeight(BufferItem* buffer) { 646 if (buffer == NULL) return -1; 647 648 if (!buffer->mCrop.isEmpty()) { 649 return buffer->mCrop.getHeight(); 650 } 651 652 ALOGV("%s: buffer->mGraphicBuffer: %p", __FUNCTION__, buffer->mGraphicBuffer.get()); 653 return buffer->mGraphicBuffer->getHeight(); 654 } 655 656 } // namespace android 657 658