Home | History | Annotate | Download | only in videoencoder
      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