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