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