1 /* 2 * Copyright (c) 2009-2011 Intel Corporation. All rights reserved. 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 "VideoEncoderLog.h" 18 #include "VideoEncoderUtils.h" 19 #include <va/va_android.h> 20 #include <va/va_drmcommon.h> 21 22 #ifdef IMG_GFX 23 #include "hal_public.h" 24 #include <sync/sync.h> 25 26 //#define GFX_DUMP 27 28 #define OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar 0x7FA00E00 29 30 static const hw_device_t *gGralloc; 31 32 static int gfx_init(void) { 33 34 int err = gralloc_open_img(&gGralloc); 35 if (err) { 36 LOG_E("FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); 37 return -1; 38 } else 39 LOG_V("hw_get_module returned\n"); 40 41 return 0; 42 } 43 44 static int gfx_alloc(uint32_t w, uint32_t h, int format, 45 int usage, buffer_handle_t* handle, int32_t* stride) { 46 47 int err; 48 49 if (!gGralloc) { 50 if (gfx_init()) { 51 LOG_E("can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); 52 return -1; 53 } 54 } 55 56 err = gralloc_device_alloc_img(gGralloc, w, h, format, usage, handle, 57 stride); 58 if (err) { 59 LOG_E("alloc(%u, %u, %d, %08x, ...) failed %d (%s)\n", 60 w, h, format, usage, err, strerror(-err)); 61 } 62 63 return err; 64 } 65 66 static int gfx_free(buffer_handle_t handle) { 67 68 int err; 69 70 if (!gGralloc) { 71 if (gfx_init()) { 72 LOG_E("can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); 73 return -1; 74 } 75 } 76 77 err = gralloc_device_free_img(gGralloc, handle); 78 if (err) { 79 LOG_E("free(...) failed %d (%s)\n", err, strerror(-err)); 80 } 81 82 return err; 83 } 84 85 static int gfx_lock(buffer_handle_t handle, int usage, 86 int left, int top, int width, int height, void** vaddr) { 87 88 int err; 89 90 if (!gGralloc) { 91 if (gfx_init()) { 92 LOG_E("can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); 93 return -1; 94 } 95 } 96 97 const gralloc1_rect_t r = { 98 .left = left, 99 .top = top, 100 .width = width, 101 .height = height 102 }; 103 104 err = gralloc_lock_async_img(gGralloc, handle, usage, &r, vaddr, -1); 105 106 LOG_V("gfx_lock: handle is %x, usage is %x, vaddr is %x.\n", 107 (unsigned int)handle, usage, (unsigned int)*vaddr); 108 109 if (err) { 110 LOG_E("lock(...) failed %d (%s).\n", err, strerror(-err)); 111 return -1; 112 } else 113 LOG_V("lock returned with address %p\n", *vaddr); 114 115 return err; 116 } 117 118 static int gfx_unlock(buffer_handle_t handle) { 119 120 int err, releaseFence = -1; 121 122 if (!gGralloc) { 123 if (gfx_init()) { 124 LOG_E("can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); 125 return -1; 126 } 127 } 128 129 err = gralloc_unlock_async_img(gGralloc, handle, &releaseFence); 130 if (releaseFence >= 0) { 131 sync_wait(releaseFence, -1); 132 close(releaseFence); 133 } 134 if (err) { 135 LOG_E("unlock(...) failed %d (%s)", err, strerror(-err)); 136 return -1; 137 } else 138 LOG_V("unlock returned\n"); 139 140 return err; 141 } 142 143 static int gfx_Blit(buffer_handle_t src, buffer_handle_t dest, 144 int w, int h, int , int ) 145 { 146 int err, releaseFence = -1; 147 148 if (!gGralloc) { 149 if (gfx_init()) { 150 LOG_E("can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); 151 return -1; 152 } 153 } 154 155 err = gralloc_blit_handle_to_handle_img(gGralloc, src, dest, w, h, 0, 0, 156 0, -1, &releaseFence); 157 if (releaseFence >= 0) { 158 sync_wait(releaseFence, -1); 159 close(releaseFence); 160 } 161 if (err) { 162 LOG_E("Blit failed %d (%s)", err, strerror(-err)); 163 return -1; 164 } else 165 LOG_V("Blit returned\n"); 166 167 return err; 168 } 169 170 Encode_Status GetGfxBufferInfo(intptr_t handle, ValueInfo& vinfo){ 171 172 /* only support OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar 173 HAL_PIXEL_FORMAT_NV12 174 HAL_PIXEL_FORMAT_BGRA_8888 175 HAL_PIXEL_FORMAT_RGBA_8888 176 HAL_PIXEL_FORMAT_RGBX_8888 177 HAL_PIXEL_FORMAT_BGRX_8888 */ 178 IMG_native_handle_t* h = (IMG_native_handle_t*) handle; 179 180 vinfo.width = h->iWidth; 181 vinfo.height = h->iHeight; 182 vinfo.lumaStride = h->iWidth; 183 184 LOG_V("GetGfxBufferInfo: gfx iWidth=%d, iHeight=%d, iFormat=%x in handle structure\n", h->iWidth, h->iHeight, h->iFormat); 185 186 if (h->iFormat == HAL_PIXEL_FORMAT_NV12) { 187 #ifdef MRFLD_GFX 188 vinfo.lumaStride = (h->iWidth + 63) & ~63; //64 aligned 189 #else //on CTP 190 if (h->iWidth > 512) 191 vinfo.lumaStride = (h->iWidth + 63) & ~63; //64 aligned 192 else 193 vinfo.lumaStride = 512; 194 #endif 195 } else if ((h->iFormat == HAL_PIXEL_FORMAT_BGRA_8888)|| 196 (h->iFormat == HAL_PIXEL_FORMAT_RGBA_8888)|| 197 (h->iFormat == HAL_PIXEL_FORMAT_RGBX_8888)|| 198 (h->iFormat == HAL_PIXEL_FORMAT_BGRX_8888)) { 199 vinfo.lumaStride = (h->iWidth + 31) & ~31; 200 } else if (h->iFormat == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar) { 201 //nothing to do 202 } else 203 return ENCODE_NOT_SUPPORTED; 204 205 vinfo.format = h->iFormat; 206 207 LOG_V("Actual Width=%d, Height=%d, Stride=%d\n\n", vinfo.width, vinfo.height, vinfo.lumaStride); 208 return ENCODE_SUCCESS; 209 } 210 211 #ifdef GFX_DUMP 212 void DumpGfx(intptr_t handle, char* filename) { 213 ValueInfo vinfo; 214 void* vaddr[3]; 215 FILE* fp; 216 int usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN; 217 218 GetGfxBufferInfo(handle, vinfo); 219 if (gfx_lock((buffer_handle_t)handle, usage, 0, 0, vinfo.width, vinfo.height, &vaddr[0]) != 0) 220 return ENCODE_DRIVER_FAIL; 221 fp = fopen(filename, "wb"); 222 fwrite(vaddr[0], 1, vinfo.lumaStride * vinfo.height * 4, fp); 223 fclose(fp); 224 LOG_I("dump %d bytes data to %s\n", vinfo.lumaStride * vinfo.height * 4, filename); 225 gfx_unlock((buffer_handle_t)handle); 226 227 return; 228 } 229 #endif 230 231 #endif 232 233 extern "C" { 234 VAStatus vaLockSurface(VADisplay dpy, 235 VASurfaceID surface, 236 unsigned int *fourcc, 237 unsigned int *luma_stride, 238 unsigned int *chroma_u_stride, 239 unsigned int *chroma_v_stride, 240 unsigned int *luma_offset, 241 unsigned int *chroma_u_offset, 242 unsigned int *chroma_v_offset, 243 unsigned int *buffer_name, 244 void **buffer 245 ); 246 247 VAStatus vaUnlockSurface(VADisplay dpy, 248 VASurfaceID surface 249 ); 250 } 251 252 VASurfaceMap::VASurfaceMap(VADisplay display, int hwcap) { 253 254 mVADisplay = display; 255 mSupportedSurfaceMemType = hwcap; 256 mValue = 0; 257 mVASurface = VA_INVALID_SURFACE; 258 mTracked = false; 259 mAction = 0; 260 memset(&mVinfo, 0, sizeof(ValueInfo)); 261 #ifdef IMG_GFX 262 mGfxHandle = NULL; 263 #endif 264 } 265 266 VASurfaceMap::~VASurfaceMap() { 267 268 if (!mTracked && (mVASurface != VA_INVALID_SURFACE)) 269 vaDestroySurfaces(mVADisplay, &mVASurface, 1); 270 271 #ifdef IMG_GFX 272 if (mGfxHandle) 273 gfx_free(mGfxHandle); 274 #endif 275 } 276 277 Encode_Status VASurfaceMap::doMapping() { 278 279 Encode_Status ret = ENCODE_SUCCESS; 280 281 if (mVASurface == VA_INVALID_SURFACE) { 282 283 int width = mVASurfaceWidth = mVinfo.width; 284 int height = mVASurfaceHeight = mVinfo.height; 285 int stride = mVASurfaceStride = mVinfo.lumaStride; 286 287 if (mAction & MAP_ACTION_COLORCONVERT) { 288 289 //only support gfx buffer 290 if (mVinfo.mode != MEM_MODE_GFXHANDLE) 291 return ENCODE_NOT_SUPPORTED; 292 293 #ifdef IMG_GFX //only enable on IMG chip 294 295 //do not trust valueinfo for gfx case, directly get from structure 296 ValueInfo tmp; 297 298 ret = GetGfxBufferInfo(mValue, tmp); 299 CHECK_ENCODE_STATUS_RETURN("GetGfxBufferInfo"); 300 width = tmp.width; 301 height = tmp.height; 302 stride = tmp.lumaStride; 303 304 if (HAL_PIXEL_FORMAT_NV12 == tmp.format || OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar == tmp.format) 305 mAction &= ~MAP_ACTION_COLORCONVERT; 306 else { 307 //allocate new gfx buffer if format is not NV12 308 int usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; 309 310 //use same size with original and HAL_PIXEL_FORMAT_NV12 format 311 if (gfx_alloc(width, height, HAL_PIXEL_FORMAT_NV12, usage, &mGfxHandle, &stride) != 0) 312 return ENCODE_DRIVER_FAIL; 313 314 LOG_V("Create an new gfx buffer handle 0x%p for color convert, width=%d, height=%d, stride=%d\n", 315 mGfxHandle, width, height, stride); 316 } 317 318 #else 319 return ENCODE_NOT_SUPPORTED; 320 #endif 321 } 322 323 if (mAction & MAP_ACTION_ALIGN64 && stride % 64 != 0) { 324 //check if stride is not 64 aligned, must allocate new 64 aligned vasurface 325 stride = (stride + 63 ) & ~63; 326 mAction |= MAP_ACTION_COPY; 327 } 328 329 if(mAction & MAP_ACTION_ALIGN64 && width <= 320 && height <= 240) { 330 mAction |= MAP_ACTION_COPY; 331 } 332 333 if (mAction & MAP_ACTION_COPY) { //must allocate new vasurface(EXternalMemoryNULL, uncached) 334 //allocate new vasurface 335 mVASurface = CreateNewVASurface(mVADisplay, stride, height); 336 if (mVASurface == VA_INVALID_SURFACE) 337 return ENCODE_DRIVER_FAIL; 338 mVASurfaceWidth = mVASurfaceStride = stride; 339 mVASurfaceHeight = height; 340 LOGI("create new vaSurface for MAP_ACTION_COPY\n"); 341 } else { 342 #ifdef IMG_GFX 343 if (mGfxHandle != NULL) { 344 //map new gfx handle to vasurface 345 ret = MappingGfxHandle((intptr_t)mGfxHandle); 346 CHECK_ENCODE_STATUS_RETURN("MappingGfxHandle"); 347 LOGV("map new allocated gfx handle to vaSurface\n"); 348 } else 349 #endif 350 { 351 //map original value to vasurface 352 ret = MappingToVASurface(); 353 CHECK_ENCODE_STATUS_RETURN("MappingToVASurface"); 354 } 355 } 356 } 357 358 if (mAction & MAP_ACTION_COLORCONVERT) { 359 ret = doActionColConv(); 360 CHECK_ENCODE_STATUS_RETURN("doActionColConv"); 361 } 362 363 if (mAction & MAP_ACTION_COPY) { 364 //keep src color format is NV12, then do copy 365 ret = doActionCopy(); 366 CHECK_ENCODE_STATUS_RETURN("doActionCopy"); 367 } 368 369 return ENCODE_SUCCESS; 370 } 371 372 Encode_Status VASurfaceMap::MappingToVASurface() { 373 374 Encode_Status ret = ENCODE_SUCCESS; 375 376 if (mVASurface != VA_INVALID_SURFACE) { 377 LOG_I("VASurface is already set before, nothing to do here\n"); 378 return ENCODE_SUCCESS; 379 } 380 LOG_V("MappingToVASurface mode=%d, value=%p\n", mVinfo.mode, (void*)mValue); 381 382 const char *mode = NULL; 383 switch (mVinfo.mode) { 384 case MEM_MODE_SURFACE: 385 mode = "SURFACE"; 386 ret = MappingSurfaceID(mValue); 387 break; 388 case MEM_MODE_GFXHANDLE: 389 mode = "GFXHANDLE"; 390 ret = MappingGfxHandle(mValue); 391 break; 392 case MEM_MODE_KBUFHANDLE: 393 mode = "KBUFHANDLE"; 394 ret = MappingKbufHandle(mValue); 395 break; 396 case MEM_MODE_MALLOC: 397 case MEM_MODE_NONECACHE_USRPTR: 398 mode = "MALLOC or NONCACHE_USRPTR"; 399 ret = MappingMallocPTR(mValue); 400 break; 401 case MEM_MODE_ION: 402 case MEM_MODE_V4L2: 403 case MEM_MODE_USRPTR: 404 case MEM_MODE_CI: 405 default: 406 LOG_I("UnSupported memory mode 0x%08x", mVinfo.mode); 407 return ENCODE_NOT_SUPPORTED; 408 } 409 410 LOG_V("%s: Format=%x, lumaStride=%d, width=%d, height=%d\n", mode, mVinfo.format, mVinfo.lumaStride, mVinfo.width, mVinfo.height); 411 LOG_V("vaSurface 0x%08x is created for value = 0x%p\n", mVASurface, (void*)mValue); 412 413 return ret; 414 } 415 416 Encode_Status VASurfaceMap::MappingSurfaceID(intptr_t value) { 417 418 VAStatus vaStatus = VA_STATUS_SUCCESS; 419 420 //try to get kbufhandle from SurfaceID 421 uint32_t fourCC = 0; 422 uint32_t lumaStride = 0; 423 uint32_t chromaUStride = 0; 424 uint32_t chromaVStride = 0; 425 uint32_t lumaOffset = 0; 426 uint32_t chromaUOffset = 0; 427 uint32_t chromaVOffset = 0; 428 uint32_t kBufHandle = 0; 429 430 vaStatus = vaLockSurface( 431 (VADisplay)mVinfo.handle, (VASurfaceID)value, 432 &fourCC, &lumaStride, &chromaUStride, &chromaVStride, 433 &lumaOffset, &chromaUOffset, &chromaVOffset, &kBufHandle, NULL); 434 435 CHECK_VA_STATUS_RETURN("vaLockSurface"); 436 LOG_V("Surface incoming = 0x%p\n", (void*)value); 437 LOG_V("lumaStride = %d, chromaUStride = %d, chromaVStride=%d\n", lumaStride, chromaUStride, chromaVStride); 438 LOG_V("lumaOffset = %d, chromaUOffset = %d, chromaVOffset = %d\n", lumaOffset, chromaUOffset, chromaVOffset); 439 LOG_V("kBufHandle = 0x%08x, fourCC = %d\n", kBufHandle, fourCC); 440 441 vaStatus = vaUnlockSurface((VADisplay)mVinfo.handle, (VASurfaceID)value); 442 CHECK_VA_STATUS_RETURN("vaUnlockSurface"); 443 444 mVinfo.mode = MEM_MODE_KBUFHANDLE; 445 mVinfo.size = mVinfo.lumaStride * mVinfo.height * 1.5; 446 447 mVASurface = CreateSurfaceFromExternalBuf(kBufHandle, mVinfo); 448 if (mVASurface == VA_INVALID_SURFACE) 449 return ENCODE_INVALID_SURFACE; 450 451 mVASurfaceWidth = mVinfo.width; 452 mVASurfaceHeight = mVinfo.height; 453 mVASurfaceStride = mVinfo.lumaStride; 454 return ENCODE_SUCCESS; 455 } 456 457 Encode_Status VASurfaceMap::MappingGfxHandle(intptr_t value) { 458 459 LOG_V("MappingGfxHandle %p......\n", (void*)value); 460 LOG_V("format = 0x%08x, lumaStride = %d in ValueInfo\n", mVinfo.format, mVinfo.lumaStride); 461 462 //default value for all HW platforms, maybe not accurate 463 mVASurfaceWidth = mVinfo.width; 464 mVASurfaceHeight = mVinfo.height; 465 mVASurfaceStride = mVinfo.lumaStride; 466 467 #ifdef IMG_GFX 468 Encode_Status ret; 469 ValueInfo tmp; 470 471 ret = GetGfxBufferInfo(value, tmp); 472 CHECK_ENCODE_STATUS_RETURN("GetGfxBufferInfo"); 473 mVASurfaceWidth = tmp.width; 474 mVASurfaceHeight = tmp.height; 475 mVASurfaceStride = tmp.lumaStride; 476 #endif 477 478 LOG_V("Mapping vasurface Width=%d, Height=%d, Stride=%d\n", mVASurfaceWidth, mVASurfaceHeight, mVASurfaceStride); 479 480 ValueInfo vinfo; 481 memset(&vinfo, 0, sizeof(ValueInfo)); 482 vinfo.mode = MEM_MODE_GFXHANDLE; 483 vinfo.width = mVASurfaceWidth; 484 vinfo.height = mVASurfaceHeight; 485 vinfo.lumaStride = mVASurfaceStride; 486 mVASurface = CreateSurfaceFromExternalBuf(value, vinfo); 487 if (mVASurface == VA_INVALID_SURFACE) 488 return ENCODE_INVALID_SURFACE; 489 490 return ENCODE_SUCCESS; 491 } 492 493 Encode_Status VASurfaceMap::MappingKbufHandle(intptr_t value) { 494 495 LOG_V("MappingKbufHandle value=%p\n", (void*)value); 496 497 mVinfo.size = mVinfo.lumaStride * mVinfo.height * 1.5; 498 mVASurface = CreateSurfaceFromExternalBuf(value, mVinfo); 499 if (mVASurface == VA_INVALID_SURFACE) 500 return ENCODE_INVALID_SURFACE; 501 502 mVASurfaceWidth = mVinfo.width; 503 mVASurfaceHeight = mVinfo.height; 504 mVASurfaceStride = mVinfo.lumaStride; 505 506 return ENCODE_SUCCESS; 507 } 508 509 Encode_Status VASurfaceMap::MappingMallocPTR(intptr_t value) { 510 511 mVASurface = CreateSurfaceFromExternalBuf(value, mVinfo); 512 if (mVASurface == VA_INVALID_SURFACE) 513 return ENCODE_INVALID_SURFACE; 514 515 mVASurfaceWidth = mVinfo.width; 516 mVASurfaceHeight = mVinfo.height; 517 mVASurfaceStride = mVinfo.lumaStride; 518 519 return ENCODE_SUCCESS; 520 } 521 522 //always copy with same color format NV12 523 Encode_Status VASurfaceMap::doActionCopy() { 524 525 VAStatus vaStatus = VA_STATUS_SUCCESS; 526 527 uint32_t width = 0, height = 0, stride = 0; 528 uint8_t *pSrcBuffer, *pDestBuffer; 529 intptr_t handle = 0; 530 531 LOG_V("Copying Src Buffer data to VASurface\n"); 532 533 if (mVinfo.mode != MEM_MODE_MALLOC && mVinfo.mode != MEM_MODE_GFXHANDLE) { 534 LOG_E("Not support copy in mode %d", mVinfo.mode); 535 return ENCODE_NOT_SUPPORTED; 536 } 537 538 LOG_V("Src Buffer information\n"); 539 LOG_V("Mode = %d, width = %d, stride = %d, height = %d\n", 540 mVinfo.mode, mVinfo.width, mVinfo.lumaStride, mVinfo.height); 541 542 uint32_t srcY_offset, srcUV_offset; 543 uint32_t srcY_pitch, srcUV_pitch; 544 545 if (mVinfo.mode == MEM_MODE_MALLOC) { 546 width = mVinfo.width; 547 height = mVinfo.height; 548 stride = mVinfo.lumaStride; 549 pSrcBuffer = (uint8_t*) mValue; 550 srcY_offset = 0; 551 srcUV_offset = stride * height; 552 srcY_pitch = stride; 553 srcUV_pitch = stride; 554 } else { 555 556 #ifdef IMG_GFX //only enable on IMG chips 557 int usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN; 558 559 //do not trust valueinfo, directly get from structure 560 Encode_Status ret; 561 ValueInfo tmp; 562 563 if (mGfxHandle) 564 handle = (intptr_t) mGfxHandle; 565 else 566 handle = mValue; 567 568 ret = GetGfxBufferInfo(handle, tmp); 569 CHECK_ENCODE_STATUS_RETURN("GetGfxBufferInfo"); 570 width = tmp.width; 571 height = tmp.height; 572 stride = tmp.lumaStride; 573 574 //only support HAL_PIXEL_FORMAT_NV12 & OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar 575 if (HAL_PIXEL_FORMAT_NV12 != tmp.format && OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar != tmp.format) { 576 LOG_E("Not support gfx buffer format %x", tmp.format); 577 return ENCODE_NOT_SUPPORTED; 578 } 579 580 srcY_offset = 0; 581 srcUV_offset = stride * height; 582 srcY_pitch = stride; 583 srcUV_pitch = stride; 584 585 //lock gfx handle with buffer real size 586 void* vaddr[3]; 587 if (gfx_lock((buffer_handle_t) handle, usage, 0, 0, width, height, &vaddr[0]) != 0) 588 return ENCODE_DRIVER_FAIL; 589 pSrcBuffer = (uint8_t*)vaddr[0]; 590 #else 591 592 return ENCODE_NOT_SUPPORTED; 593 #endif 594 } 595 596 597 VAImage destImage; 598 vaStatus = vaDeriveImage(mVADisplay, mVASurface, &destImage); 599 CHECK_VA_STATUS_RETURN("vaDeriveImage"); 600 vaStatus = vaMapBuffer(mVADisplay, destImage.buf, (void **)&pDestBuffer); 601 CHECK_VA_STATUS_RETURN("vaMapBuffer"); 602 603 LOG_V("\nDest VASurface information\n"); 604 LOG_V("pitches[0] = %d\n", destImage.pitches[0]); 605 LOG_V("pitches[1] = %d\n", destImage.pitches[1]); 606 LOG_V("offsets[0] = %d\n", destImage.offsets[0]); 607 LOG_V("offsets[1] = %d\n", destImage.offsets[1]); 608 LOG_V("num_planes = %d\n", destImage.num_planes); 609 LOG_V("width = %d\n", destImage.width); 610 LOG_V("height = %d\n", destImage.height); 611 612 if (width > destImage.width || height > destImage.height) { 613 LOG_E("src buffer is bigger than destination buffer\n"); 614 return ENCODE_INVALID_PARAMS; 615 } 616 617 uint8_t *srcY, *dstY; 618 uint8_t *srcUV, *dstUV; 619 620 srcY = pSrcBuffer + srcY_offset; 621 dstY = pDestBuffer + destImage.offsets[0]; 622 srcUV = pSrcBuffer + srcUV_offset; 623 dstUV = pDestBuffer + destImage.offsets[1]; 624 625 for (uint32_t i = 0; i < height; i++) { 626 memcpy(dstY, srcY, width); 627 srcY += srcY_pitch; 628 dstY += destImage.pitches[0]; 629 } 630 631 for (uint32_t i = 0; i < height / 2; i++) { 632 memcpy(dstUV, srcUV, width); 633 srcUV += srcUV_pitch; 634 dstUV += destImage.pitches[1]; 635 } 636 637 vaStatus = vaUnmapBuffer(mVADisplay, destImage.buf); 638 CHECK_VA_STATUS_RETURN("vaUnmapBuffer"); 639 vaStatus = vaDestroyImage(mVADisplay, destImage.image_id); 640 CHECK_VA_STATUS_RETURN("vaDestroyImage"); 641 642 #ifdef IMG_GFX 643 if (mVinfo.mode == MEM_MODE_GFXHANDLE) { 644 //unlock gfx handle 645 gfx_unlock((buffer_handle_t) handle); 646 } 647 #endif 648 LOG_V("Copying Src Buffer data to VASurface Complete\n"); 649 650 return ENCODE_SUCCESS; 651 } 652 653 Encode_Status VASurfaceMap::doActionColConv() { 654 655 #ifdef IMG_GFX 656 if (mGfxHandle == NULL) { 657 LOG_E("something wrong, why new gfxhandle is not allocated? \n"); 658 return ENCODE_FAIL; 659 } 660 661 LOG_V("doActionColConv gfx_Blit width=%d, height=%d\n", mVinfo.width, mVinfo.height); 662 if (gfx_Blit((buffer_handle_t)mValue, mGfxHandle, 663 mVinfo.width, mVinfo.height, 0, 0) != 0) 664 return ENCODE_DRIVER_FAIL; 665 666 #ifdef GFX_DUMP 667 LOG_I("dumpping gfx data.....\n"); 668 DumpGfx(mValue, "/data/dump.rgb"); 669 DumpGfx((intptr_t)mGfxHandle, "/data/dump.yuv"); 670 #endif 671 return ENCODE_SUCCESS; 672 673 #else 674 return ENCODE_NOT_SUPPORTED; 675 #endif 676 } 677 678 VASurfaceID VASurfaceMap::CreateSurfaceFromExternalBuf(intptr_t value, ValueInfo& vinfo) { 679 680 VAStatus vaStatus; 681 VASurfaceAttribExternalBuffers extbuf; 682 VASurfaceAttrib attribs[2]; 683 VASurfaceID surface = VA_INVALID_SURFACE; 684 int type; 685 unsigned long data = value; 686 687 extbuf.pixel_format = VA_FOURCC_NV12; 688 extbuf.width = vinfo.width; 689 extbuf.height = vinfo.height; 690 extbuf.data_size = vinfo.size; 691 if (extbuf.data_size == 0) 692 extbuf.data_size = vinfo.lumaStride * vinfo.height * 1.5; 693 extbuf.num_buffers = 1; 694 extbuf.num_planes = 3; 695 extbuf.pitches[0] = vinfo.lumaStride; 696 extbuf.pitches[1] = vinfo.lumaStride; 697 extbuf.pitches[2] = vinfo.lumaStride; 698 extbuf.pitches[3] = 0; 699 extbuf.offsets[0] = 0; 700 extbuf.offsets[1] = vinfo.lumaStride * vinfo.height; 701 extbuf.offsets[2] = extbuf.offsets[1]; 702 extbuf.offsets[3] = 0; 703 extbuf.buffers = &data; 704 extbuf.flags = 0; 705 extbuf.private_data = NULL; 706 707 switch(vinfo.mode) { 708 case MEM_MODE_GFXHANDLE: 709 type = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; 710 break; 711 case MEM_MODE_KBUFHANDLE: 712 type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; 713 break; 714 case MEM_MODE_MALLOC: 715 type = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR; 716 break; 717 case MEM_MODE_NONECACHE_USRPTR: 718 type = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR; 719 extbuf.flags |= VA_SURFACE_EXTBUF_DESC_UNCACHED; 720 break; 721 case MEM_MODE_SURFACE: 722 case MEM_MODE_ION: 723 case MEM_MODE_V4L2: 724 case MEM_MODE_USRPTR: 725 case MEM_MODE_CI: 726 default: 727 //not support 728 return VA_INVALID_SURFACE; 729 } 730 731 if (!(mSupportedSurfaceMemType & type)) 732 return VA_INVALID_SURFACE; 733 734 attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType; 735 attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; 736 attribs[0].value.type = VAGenericValueTypeInteger; 737 attribs[0].value.value.i = type; 738 739 attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor; 740 attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; 741 attribs[1].value.type = VAGenericValueTypePointer; 742 attribs[1].value.value.p = (void *)&extbuf; 743 744 vaStatus = vaCreateSurfaces(mVADisplay, VA_RT_FORMAT_YUV420, vinfo.width, 745 vinfo.height, &surface, 1, attribs, 2); 746 if (vaStatus != VA_STATUS_SUCCESS){ 747 LOG_E("vaCreateSurfaces failed. vaStatus = %d\n", vaStatus); 748 surface = VA_INVALID_SURFACE; 749 } 750 return surface; 751 } 752 753 VASurfaceID CreateNewVASurface(VADisplay display, int32_t width, int32_t height) { 754 755 VAStatus vaStatus; 756 VASurfaceID surface = VA_INVALID_SURFACE; 757 VASurfaceAttrib attribs[2]; 758 VASurfaceAttribExternalBuffers extbuf; 759 unsigned long data; 760 761 extbuf.pixel_format = VA_FOURCC_NV12; 762 extbuf.width = width; 763 extbuf.height = height; 764 extbuf.data_size = width * height * 3 / 2; 765 extbuf.num_buffers = 1; 766 extbuf.num_planes = 3; 767 extbuf.pitches[0] = width; 768 extbuf.pitches[1] = width; 769 extbuf.pitches[2] = width; 770 extbuf.pitches[3] = 0; 771 extbuf.offsets[0] = 0; 772 extbuf.offsets[1] = width * height; 773 extbuf.offsets[2] = extbuf.offsets[1]; 774 extbuf.offsets[3] = 0; 775 extbuf.buffers = &data; 776 extbuf.flags = 0; 777 extbuf.private_data = NULL; 778 779 attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType; 780 attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; 781 attribs[0].value.type = VAGenericValueTypeInteger; 782 attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA; 783 784 attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor; 785 attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; 786 attribs[1].value.type = VAGenericValueTypePointer; 787 attribs[1].value.value.p = (void *)&extbuf; 788 789 vaStatus = vaCreateSurfaces(display, VA_RT_FORMAT_YUV420, width, 790 height, &surface, 1, attribs, 2); 791 if (vaStatus != VA_STATUS_SUCCESS) 792 LOG_E("vaCreateSurfaces failed. vaStatus = %d\n", vaStatus); 793 794 return surface; 795 } 796