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