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