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