• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
gfx_init(void)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 
gfx_alloc(uint32_t w,uint32_t h,int format,int usage,buffer_handle_t * handle,int32_t * stride)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 
gfx_free(buffer_handle_t handle)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 
gfx_lock(buffer_handle_t handle,int usage,int left,int top,int width,int height,void ** vaddr)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 
gfx_unlock(buffer_handle_t handle)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 
gfx_Blit(buffer_handle_t src,buffer_handle_t dest,int w,int h,int,int)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 
GetGfxBufferInfo(intptr_t handle,ValueInfo & vinfo)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
DumpGfx(intptr_t handle,char * filename)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 
VASurfaceMap(VADisplay display,int hwcap)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 
~VASurfaceMap()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 
doMapping()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 
MappingToVASurface()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 
MappingSurfaceID(intptr_t value)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 
MappingGfxHandle(intptr_t value)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 
MappingKbufHandle(intptr_t value)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 
MappingMallocPTR(intptr_t value)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
doActionCopy()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 
doActionColConv()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 
CreateSurfaceFromExternalBuf(intptr_t value,ValueInfo & vinfo)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 
CreateNewVASurface(VADisplay display,int32_t width,int32_t height)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