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