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