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