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 
     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