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