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