1 /*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 * Copyright (c) Imagination Technologies Limited, UK
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Waldo Bastian <waldo.bastian@intel.com>
27 *
28 */
29
30 #include <sys/types.h>
31 #include "psb_buffer.h"
32
33 #include <errno.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <wsbm/wsbm_manager.h>
37
38 #ifdef ANDROID
39 #ifdef BAYTRAIL
40 #include <linux/vxd_drm.h>
41 #else
42 #include <drm/ttm/ttm_placement.h>
43 #include <linux/psb_drm.h>
44 #endif
45 #else
46 #include <psb_drm.h>
47 #endif
48
49 #include "psb_def.h"
50 #include "psb_drv_debug.h"
51 #include "tng_cmdbuf.h"
52
53 #ifndef BAYTRAIL
54 #include <pnw_cmdbuf.h>
55 #include "pnw_jpeg.h"
56 #include "pnw_H264ES.h"
57 #include "tng_jpegES.h"
58 #endif
59
60 #include "vsp_fw.h"
61 /*
62 * Create buffer
63 */
psb_buffer_create(psb_driver_data_p driver_data,unsigned int size,psb_buffer_type_t type,psb_buffer_p buf)64 VAStatus psb_buffer_create(psb_driver_data_p driver_data,
65 unsigned int size,
66 psb_buffer_type_t type,
67 psb_buffer_p buf
68 )
69 {
70 VAStatus vaStatus = VA_STATUS_SUCCESS;
71 int allignment;
72 uint32_t placement;
73 int ret;
74
75 /* reset rar_handle to NULL */
76 buf->rar_handle = 0;
77 buf->buffer_ofs = 0;
78
79 buf->type = type;
80 buf->driver_data = driver_data; /* only for RAR buffers */
81 buf->size = size;
82 /* TODO: Mask values are a guess */
83 switch (type) {
84 case psb_bt_cpu_vpu:
85 allignment = 1;
86 placement = DRM_PSB_FLAG_MEM_MMU;
87 break;
88 case psb_bt_cpu_vpu_shared:
89 allignment = 1;
90 placement = DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED;
91 break;
92 case psb_bt_surface:
93 allignment = 0;
94 placement = DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED;
95 if (IS_CTP(driver_data)) /* CTP support cache snoop */
96 placement |= WSBM_PL_FLAG_CACHED;
97 break;
98 case psb_bt_surface_tt:
99 allignment = 0;
100 placement = WSBM_PL_FLAG_TT | WSBM_PL_FLAG_NO_EVICT | WSBM_PL_FLAG_SHARED;
101 break;
102 #ifdef PSBVIDEO_MSVDX_DEC_TILING
103 case psb_bt_surface_tiling:
104 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate tiled surface from TT heap\n");
105 placement = WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED;
106 allignment = 2048 * 16; /* Tiled row aligned */
107 break;
108 case psb_bt_mmu_tiling:
109 placement = DRM_PSB_FLAG_MEM_MMU_TILING | WSBM_PL_FLAG_SHARED;
110 allignment = 2048 * 16; /* Tiled row aligned */
111 break;
112 #endif
113 case psb_bt_cpu_vpu_cached:
114 allignment = 1;
115 placement = DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_CACHED;
116 break;
117 case psb_bt_vpu_only:
118 allignment = 1;
119 placement = DRM_PSB_FLAG_MEM_MMU;
120 break;
121 case psb_bt_cpu_only:
122 allignment = 1;
123 placement = WSBM_PL_FLAG_SYSTEM | WSBM_PL_FLAG_CACHED;
124 break;
125 #if PSB_MFLD_DUMMY_CODE
126 case psb_bt_camera:
127 allignment = 1;
128 placement = WSBM_PL_FLAG_SHARED;
129 break;
130 #endif
131 #ifdef ANDROID
132 #ifndef BAYTRAIL
133 case psb_bt_imr:
134 allignment = 1;
135 placement = TTM_PL_FLAG_IMR | WSBM_PL_FLAG_SHARED;
136 break;
137 #endif
138 #endif
139 default:
140 vaStatus = VA_STATUS_ERROR_UNKNOWN;
141 DEBUG_FAILURE;
142 return vaStatus;
143 }
144 ret = LOCK_HARDWARE(driver_data);
145 if (ret) {
146 UNLOCK_HARDWARE(driver_data);
147 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
148 DEBUG_FAILURE_RET;
149 return vaStatus;
150 }
151
152 #ifdef VA_EMULATOR
153 placement |= WSBM_PL_FLAG_SHARED;
154 #endif
155
156 #ifndef ANDROID
157 if(!(placement & WSBM_PL_FLAG_SYSTEM)) {
158 //drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: buffer->pl_flags 0x%08x\n", __func__, placement);
159 placement &= ~WSBM_PL_MASK_MEM;
160 placement &= ~WSBM_PL_FLAG_NO_EVICT;
161 placement |= TTM_PL_FLAG_VRAM;
162 //drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: repleace buffer->pl_flags 0x%08x\n", __func__, placement);
163 }
164 #endif
165
166 #ifdef MSVDX_VA_EMULATOR
167 placement |= WSBM_PL_FLAG_SHARED;
168 #endif
169
170 if(allignment < 4096)
171 allignment = 4096; /* temporily more safe */
172
173 //drv_debug_msg(VIDEO_DEBUG_ERROR, "FIXME: should use geetpagesize() ?\n");
174 ret = wsbmGenBuffers(driver_data->main_pool, 1, &buf->drm_buf,
175 allignment, placement);
176 if (!buf->drm_buf) {
177 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
178 UNLOCK_HARDWARE(driver_data);
179 return VA_STATUS_ERROR_ALLOCATION_FAILED;
180 }
181
182 /* here use the placement when gen buffer setted */
183 ret = wsbmBOData(buf->drm_buf, size, NULL, NULL, 0);
184 UNLOCK_HARDWARE(driver_data);
185 if (ret) {
186 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc wsbm buffers\n");
187 return VA_STATUS_ERROR_ALLOCATION_FAILED;
188 }
189
190 if (placement & WSBM_PL_FLAG_TT)
191 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create BO with TT placement (%d byte),BO GPU offset hint=0x%08x\n",
192 size, wsbmBOOffsetHint(buf->drm_buf));
193
194 buf->pl_flags = placement;
195 buf->status = psb_bs_ready;
196 buf->wsbm_synccpu_flag = 0;
197
198 return VA_STATUS_SUCCESS;
199 }
200
201 /*
202 * Create buffer
203 */
psb_buffer_create_from_ub(psb_driver_data_p driver_data,unsigned int size,psb_buffer_type_t type,psb_buffer_p buf,void * vaddr,int fd,unsigned int flags)204 VAStatus psb_buffer_create_from_ub(psb_driver_data_p driver_data,
205 unsigned int size,
206 psb_buffer_type_t type,
207 psb_buffer_p buf,
208 void * vaddr,
209 int fd,
210 unsigned int flags
211 )
212 {
213 VAStatus vaStatus = VA_STATUS_SUCCESS;
214 int allignment;
215 uint32_t placement;
216 int ret;
217
218 /* reset rar_handle to NULL */
219 buf->rar_handle = 0;
220 buf->buffer_ofs = 0;
221
222 buf->type = type;
223 buf->driver_data = driver_data; /* only for RAR buffers */
224 buf->user_ptr = vaddr;
225 buf->fd = fd;
226
227 /* Xvideo will share surface buffer, set SHARED flag
228 */
229 placement = DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED ;
230
231 ret = LOCK_HARDWARE(driver_data);
232 if (ret) {
233 UNLOCK_HARDWARE(driver_data);
234 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
235 DEBUG_FAILURE_RET;
236 return vaStatus;
237 }
238
239 allignment = 4096; /* temporily more safe */
240 #ifdef PSBVIDEO_MSVDX_DEC_TILING
241 if (type == psb_bt_mmu_tiling) {
242 placement = DRM_PSB_FLAG_MEM_MMU_TILING | WSBM_PL_FLAG_SHARED ;
243 allignment = 2048 * 16; /* Tiled row aligned */
244 }
245 #endif
246
247 if (flags & PSB_USER_BUFFER_WC)
248 placement |= WSBM_PL_FLAG_WC;
249 else if (flags & PSB_USER_BUFFER_UNCACHED)
250 placement |= WSBM_PL_FLAG_UNCACHED;
251 else
252 placement |= WSBM_PL_FLAG_CACHED;
253
254 //drv_debug_msg(VIDEO_DEBUG_ERROR, "FIXME: should use geetpagesize() ?\n");
255 ret = wsbmGenBuffers(driver_data->main_pool, 1, &buf->drm_buf,
256 allignment, placement);
257 if (!buf->drm_buf) {
258 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
259 UNLOCK_HARDWARE(driver_data);
260 return VA_STATUS_ERROR_ALLOCATION_FAILED;
261 }
262
263 /* here use the placement when gen buffer setted */
264 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create BO from user buffer %p, size=%d, fd = %d\n", vaddr, size, fd);
265
266 ret = wsbmBODataUB(buf->drm_buf, size, NULL, NULL, 0, vaddr, fd);
267 if (ret) {
268 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to alloc wsbm buffers, buf->drm_buf is 0x%x, size is %d, vaddr is 0x%x, fd=%d\n", buf->drm_buf, size, vaddr, fd);
269 UNLOCK_HARDWARE(driver_data);
270 return 1;
271 }
272
273 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create BO from user buffer 0x%08x (%d byte), fd=%d, BO GPU offset hint=0x%08x\n",
274 vaddr, size, fd, wsbmBOOffsetHint(buf->drm_buf));
275
276 buf->pl_flags = placement;
277 buf->status = psb_bs_ready;
278 buf->wsbm_synccpu_flag = 0;
279
280 UNLOCK_HARDWARE(driver_data);
281 return VA_STATUS_SUCCESS;
282 }
283
284 #if 0
285 /*
286 * buffer setstatus
287 *
288 * Returns 0 on success
289 */
290 int psb_buffer_setstatus(psb_buffer_p buf, uint32_t set_placement, uint32_t clr_placement)
291 {
292 int ret = 0;
293
294 ASSERT(buf);
295 ASSERT(buf->driver_data);
296
297 ret = wsbmBOSetStatus(buf->drm_buf, set_placement, clr_placement);
298 if (ret == 0)
299 buf->pl_flags = set_placement;
300
301 return ret;
302 }
303 #endif
304
psb_buffer_reference(psb_driver_data_p driver_data,psb_buffer_p buf,psb_buffer_p reference_buf)305 VAStatus psb_buffer_reference(psb_driver_data_p driver_data,
306 psb_buffer_p buf,
307 psb_buffer_p reference_buf
308 )
309 {
310 int ret = 0;
311 VAStatus vaStatus = VA_STATUS_SUCCESS;
312
313 memcpy(buf, reference_buf, sizeof(*buf));
314 buf->drm_buf = NULL;
315
316 ret = LOCK_HARDWARE(driver_data);
317 if (ret) {
318 UNLOCK_HARDWARE(driver_data);
319 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
320 DEBUG_FAILURE_RET;
321 return vaStatus;
322 }
323
324 ret = wsbmGenBuffers(driver_data->main_pool,
325 1,
326 &buf->drm_buf,
327 4096, /* page alignment */
328 0);
329 if (!buf->drm_buf) {
330 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
331 UNLOCK_HARDWARE(driver_data);
332 return VA_STATUS_ERROR_ALLOCATION_FAILED;
333 }
334
335 ret = wsbmBOSetReferenced(buf->drm_buf, wsbmKBufHandle(wsbmKBuf(reference_buf->drm_buf)));
336 UNLOCK_HARDWARE(driver_data);
337 if (ret) {
338 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc wsbm buffers\n");
339 return VA_STATUS_ERROR_ALLOCATION_FAILED;
340 }
341
342 return VA_STATUS_SUCCESS;
343 }
344
psb_kbuffer_reference(psb_driver_data_p driver_data,psb_buffer_p buf,int kbuf_handle)345 VAStatus psb_kbuffer_reference(psb_driver_data_p driver_data,
346 psb_buffer_p buf,
347 int kbuf_handle
348 )
349 {
350 int ret = 0;
351 VAStatus vaStatus = VA_STATUS_SUCCESS;
352
353 buf->drm_buf = NULL;
354
355 ret = LOCK_HARDWARE(driver_data);
356 if (ret) {
357 UNLOCK_HARDWARE(driver_data);
358 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
359 DEBUG_FAILURE_RET;
360 return vaStatus;
361 }
362
363 ret = wsbmGenBuffers(driver_data->main_pool,
364 1,
365 &buf->drm_buf,
366 4096, /* page alignment */
367 0);
368 if (!buf->drm_buf) {
369 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
370 UNLOCK_HARDWARE(driver_data);
371 return VA_STATUS_ERROR_ALLOCATION_FAILED;
372 }
373
374 ret = wsbmBOSetReferenced(buf->drm_buf, kbuf_handle);
375 UNLOCK_HARDWARE(driver_data);
376 if (ret) {
377 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc wsbm buffers\n");
378 return VA_STATUS_ERROR_ALLOCATION_FAILED;
379 }
380 buf->pl_flags = wsbmBOPlacementHint(buf->drm_buf);
381 buf->type = psb_bt_surface;
382 buf->status = psb_bs_ready;
383
384 return VA_STATUS_SUCCESS;
385 }
386 /*
387 * Destroy buffer
388 */
psb_buffer_destroy(psb_buffer_p buf)389 void psb_buffer_destroy(psb_buffer_p buf)
390 {
391 ASSERT(buf);
392 if (buf->drm_buf == NULL)
393 return;
394 if (psb_bs_unfinished != buf->status) {
395 ASSERT(buf->driver_data);
396 wsbmBOUnreference(&buf->drm_buf);
397 if (buf->rar_handle)
398 buf->rar_handle = 0;
399 buf->driver_data = NULL;
400 buf->status = psb_bs_unfinished;
401 }
402 }
403
404 /*
405 * Map buffer
406 *
407 * Returns 0 on success
408 */
psb_buffer_map(psb_buffer_p buf,unsigned char ** address)409 int psb_buffer_map(psb_buffer_p buf, unsigned char **address /* out */)
410 {
411 int ret;
412
413 ASSERT(buf);
414 ASSERT(buf->driver_data);
415
416 /* multiple mapping not allowed */
417 if (buf->wsbm_synccpu_flag) {
418 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Multiple mapping request detected, unmap previous mapping\n");
419 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Need to fix application to unmap at first, then request second mapping request\n");
420
421 psb_buffer_unmap(buf);
422 }
423
424 /* don't think TG deal with READ/WRITE differently */
425 buf->wsbm_synccpu_flag = WSBM_SYNCCPU_READ | WSBM_SYNCCPU_WRITE;
426 if (psb_video_trace_fp) {
427 wsbmBOWaitIdle(buf->drm_buf, 0);
428 } else {
429 ret = wsbmBOSyncForCpu(buf->drm_buf, buf->wsbm_synccpu_flag);
430 if (ret) {
431 drv_debug_msg(VIDEO_DEBUG_ERROR, "faild to sync bo for cpu\n");
432 return ret;
433 }
434 }
435
436 if (buf->user_ptr) /* user mode buffer */
437 *address = buf->user_ptr;
438 else
439 *address = wsbmBOMap(buf->drm_buf, buf->wsbm_synccpu_flag);
440
441 if (*address == NULL) {
442 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to map buffer\n");
443 return -1;
444 }
445
446 return 0;
447 }
448
449 /*
450 * Unmap buffer
451 *
452 * Returns 0 on success
453 */
psb_buffer_unmap(psb_buffer_p buf)454 int psb_buffer_unmap(psb_buffer_p buf)
455 {
456 ASSERT(buf);
457 ASSERT(buf->driver_data);
458
459 if (buf->wsbm_synccpu_flag)
460 (void) wsbmBOReleaseFromCpu(buf->drm_buf, buf->wsbm_synccpu_flag);
461
462 buf->wsbm_synccpu_flag = 0;
463
464 if ((buf->type != psb_bt_user_buffer) && !buf->handle)
465 wsbmBOUnmap(buf->drm_buf);
466
467 return 0;
468 }
469
470 #define _MRFL_DEBUG_CODED_
471
472 #ifdef _MRFL_DEBUG_CODED_
psb__trace_coded(VACodedBufferSegment * vaCodedBufSeg)473 static void psb__trace_coded(VACodedBufferSegment *vaCodedBufSeg)
474 {
475 int i, j;
476 int uiPipeIndex = -1;
477 unsigned int *pBuf = NULL;
478 do {
479 ++uiPipeIndex;
480 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: pipe num %d, size = %d\n", __FUNCTION__, uiPipeIndex, vaCodedBufSeg[uiPipeIndex].size);
481 pBuf = (unsigned int *)(vaCodedBufSeg[uiPipeIndex].buf);
482 pBuf -= 16;
483 for (i = 0; i < 6; i++) {
484 for (j = 0; j < 4; j++) {
485 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: 0x%08x\n", __FUNCTION__, pBuf[(i*4) + j]);
486 }
487 }
488 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: \n", __FUNCTION__);
489 } while (vaCodedBufSeg[uiPipeIndex].next);
490
491 return ;
492 }
493 #endif
494
495 #define PROFILE_H264(profile) ((profile>=VAProfileH264Baseline && profile <=VAProfileH264High) || \
496 (profile == VAProfileH264ConstrainedBaseline))
tng_get_coded_data(object_buffer_p obj_buffer,unsigned char * raw_codedbuf)497 static void tng_get_coded_data(
498 object_buffer_p obj_buffer,
499 unsigned char *raw_codedbuf
500 )
501 {
502 object_context_p obj_context = obj_buffer->context;
503 VACodedBufferSegment *vaCodedBufSeg = &obj_buffer->codedbuf_mapinfo[0];
504 int iPipeIndex = 0;
505 unsigned int uiPipeNum = tng_get_pipe_number(obj_context);
506 unsigned int uiBufOffset = tng_align_KB(obj_buffer->size >> 1);
507 unsigned long *ptmp = NULL;
508 int tmp;
509
510 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s pipenum = 0x%x\n", __FUNCTION__, uiPipeNum);
511 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s offset = 0x%x\n", __FUNCTION__, uiBufOffset);
512
513 tmp = vaCodedBufSeg[iPipeIndex].size = *(unsigned int *)((unsigned long)raw_codedbuf);
514
515 /*
516 * This is used for DRM over WiDi which only uses H264 BP
517 * Tangier IED encryption operates on the chunks with 16bytes, and we must include
518 * the extra bytes beyond slice data as a whole chunk for decrption
519 * We simply include the padding bytes regardless of IED enable or disable
520 */
521 if (PROFILE_H264(obj_context->profile) && (tmp % 16 != 0)) {
522 tmp = (tmp + 15) & (~15);
523 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Force slice size from %d to %d\n",
524 vaCodedBufSeg[iPipeIndex].size, tmp);
525 vaCodedBufSeg[iPipeIndex].size = tmp;
526 }
527
528 vaCodedBufSeg[iPipeIndex].buf = (unsigned char *)(((unsigned int *)((unsigned long)raw_codedbuf)) + 16); /* skip 4DWs */
529
530 ptmp = (unsigned long *)((unsigned long)raw_codedbuf);
531 vaCodedBufSeg[iPipeIndex].reserved = (ptmp[1] >> 6) & 0xf;
532 vaCodedBufSeg[iPipeIndex].next = NULL;
533
534
535 if (uiPipeNum == 2) {
536 /*The second part of coded buffer which generated by core 2 is the
537 * first part of encoded clip, while the first part of coded buffer
538 * is the second part of encoded clip.*/
539 ++iPipeIndex;
540 vaCodedBufSeg[iPipeIndex - 1].next = &vaCodedBufSeg[iPipeIndex];
541 tmp = vaCodedBufSeg[iPipeIndex].size = *(unsigned int *)((unsigned long)raw_codedbuf + uiBufOffset);
542
543 /*
544 * This is used for DRM over WiDi which only uses H264 BP
545 * Tangier IED encryption operates on the chunks with 16bytes, and we must include
546 * the extra bytes beyond slice data as a whole chunk for decryption
547 * We simply include the padding bytes regardless of IED enable or disable
548 */
549 if (PROFILE_H264(obj_context->profile) && (tmp % 16 != 0)) {
550 tmp = (tmp + 15) & (~15);
551 drv_debug_msg(VIDEO_DEBUG_GENERAL,"Force slice size from %d to %d\n",
552 vaCodedBufSeg[iPipeIndex].size, tmp);
553
554 vaCodedBufSeg[iPipeIndex].size = tmp;
555 }
556
557 vaCodedBufSeg[iPipeIndex].buf = (unsigned char *)(((unsigned int *)((unsigned long)raw_codedbuf + uiBufOffset)) + 16); /* skip 4DWs */
558 vaCodedBufSeg[iPipeIndex].reserved = vaCodedBufSeg[iPipeIndex - 1].reserved;
559 vaCodedBufSeg[iPipeIndex].next = NULL;
560 }
561
562 #ifdef _MRFL_DEBUG_CODED_
563 psb__trace_coded(vaCodedBufSeg);
564 #endif
565
566 return ;
567 }
568
569 /*
570 * Return special data structure for codedbuffer
571 *
572 * Returns 0 on success
573 */
574 #define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
575 #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
psb_codedbuf_map_mangle(VADriverContextP ctx,object_buffer_p obj_buffer,void ** pbuf)576 int psb_codedbuf_map_mangle(
577 VADriverContextP ctx,
578 object_buffer_p obj_buffer,
579 void **pbuf /* out */
580 )
581 {
582 object_context_p obj_context = obj_buffer->context;
583 INIT_DRIVER_DATA;
584 VACodedBufferSegment *p = &obj_buffer->codedbuf_mapinfo[0];
585 unsigned char *raw_codedbuf;
586 VAStatus vaStatus = VA_STATUS_SUCCESS;
587 unsigned int next_buf_off;
588 uint32_t i;
589
590 CHECK_INVALID_PARAM(pbuf == NULL);
591
592 if (NULL == obj_context) {
593 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
594 DEBUG_FAILURE;
595
596 psb_buffer_unmap(obj_buffer->psb_buffer);
597 obj_buffer->buffer_data = NULL;
598
599 return vaStatus;
600 }
601
602 raw_codedbuf = *pbuf;
603 /* reset the mapinfo */
604 memset(obj_buffer->codedbuf_mapinfo, 0, sizeof(obj_buffer->codedbuf_mapinfo));
605
606 *pbuf = p = &obj_buffer->codedbuf_mapinfo[0];
607 #ifdef PSBVIDEO_MRFL
608 if (IS_MRFL(driver_data)) {
609 object_config_p obj_config = CONFIG(obj_context->config_id);
610 if (NULL == obj_config) {
611 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
612 DEBUG_FAILURE;
613
614 psb_buffer_unmap(obj_buffer->psb_buffer);
615 obj_buffer->buffer_data = NULL;
616
617 return vaStatus;
618 }
619
620 if (VAProfileJPEGBaseline != obj_config->profile
621 && (*((unsigned long *) raw_codedbuf + 1) & SKIP_NEXT_FRAME) != 0) {
622 /*Set frame skip flag*/
623 tng_set_frame_skip_flag(obj_context);
624 }
625 switch (obj_config->profile) {
626 case VAProfileMPEG4Simple:
627 case VAProfileMPEG4AdvancedSimple:
628 case VAProfileMPEG4Main:
629
630 case VAProfileH264Baseline:
631 case VAProfileH264Main:
632 case VAProfileH264High:
633 case VAProfileH264StereoHigh:
634 case VAProfileH264ConstrainedBaseline:
635 case VAProfileH263Baseline:
636 /* 1st segment */
637 tng_get_coded_data(obj_buffer, raw_codedbuf);
638 #if 0
639 p->size = *((unsigned long *) raw_codedbuf);
640 p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 16); /* skip 16DWs */
641 p->next = NULL;
642 #ifdef _MRFL_DEBUG_CODED_
643 psb__trace_coded((unsigned int*)raw_codedbuf);
644 psb__trace_coded(p);
645 #endif
646 #endif
647 break;
648 case VAProfileVP8Version0_3:
649 {
650 /* multi segments*/
651 struct VssVp8encEncodedFrame *t = (struct VssVp8encEncodedFrame *) (raw_codedbuf);
652 int concatenate = 1;
653 #if 0
654 for (i = 0; i < t->partitions - 1; i++) {
655 if (t->partition_start[i+1] != t->partition_start[i] + t->partition_size[i])
656 concatenate = 0;
657 }
658 #endif
659 /* reference frame surface_id */
660 /* default is recon_buffer_mode ==0 */
661 p->reserved = t->surfaceId_of_ref_frame[3];
662
663 if (concatenate) {
664 /* partitions are concatenate */
665 p->buf = t->coded_data;
666 p->size = t->frame_size;
667 if(t->frame_size == 0){
668 drv_debug_msg(VIDEO_DEBUG_ERROR,"Frame size is zero, Force it to 3, encoder status is 0x%x\n", t->status);
669 p->size = 3;
670 t->coded_data[0]=0;
671 }
672 p->next = NULL;
673 } else {
674 for (i = 0; i < t->partitions; i++) {
675 /* partition not consecutive */
676 p->buf = t->coded_data + t->partition_start[i] - t->partition_start[0];
677 p->size += t->partition_size[i];
678 p->next = &p[1];
679 p++;
680 }
681 p--;
682 p->next = NULL;
683 }
684
685 break;
686 }
687 case VAProfileJPEGBaseline:
688 /* 3~6 segment */
689 tng_jpeg_AppendMarkers(obj_context, raw_codedbuf);
690 next_buf_off = 0;
691 /*Max resolution 4096x4096 use 6 segments*/
692 for (i = 0; i < PTG_JPEG_MAX_SCAN_NUM + 1; i++) {
693 p->size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off); /* ui32BytesUsed in HEADER_BUFFER*/
694 p->buf = (unsigned char *)((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 4); /* skip 4DWs (HEADER_BUFFER) */
695 next_buf_off = *((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 3); /* ui32Reserved3 in HEADER_BUFFER*/
696
697 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer segment %d size: %d\n", i, p->size);
698 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer next segment %d offset: %d\n", i + 1, next_buf_off);
699
700 if (next_buf_off == 0) {
701 p->next = NULL;
702 break;
703 } else
704 p->next = &p[1];
705 p++;
706 }
707 break;
708
709 default:
710 drv_debug_msg(VIDEO_DEBUG_ERROR, "unexpected case\n");
711
712 psb_buffer_unmap(obj_buffer->psb_buffer);
713 obj_buffer->buffer_data = NULL;
714 break;
715 }
716 }
717 #endif
718 #ifdef PSBVIDEO_MFLD
719 if (IS_MFLD(driver_data)){ /* MFLD */
720 object_config_p obj_config = CONFIG(obj_context->config_id);
721
722 if (NULL == obj_config) {
723 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
724 DEBUG_FAILURE;
725
726 psb_buffer_unmap(obj_buffer->psb_buffer);
727 obj_buffer->buffer_data = NULL;
728
729 return vaStatus;
730 }
731
732 if (VAProfileJPEGBaseline != obj_config->profile
733 && (*((unsigned long *) raw_codedbuf + 1) & SKIP_NEXT_FRAME) != 0) {
734 /*Set frame skip flag*/
735 pnw_set_frame_skip_flag(obj_context);
736 }
737 switch (obj_config->profile) {
738 case VAProfileMPEG4Simple:
739 case VAProfileMPEG4AdvancedSimple:
740 case VAProfileMPEG4Main:
741 /* one segment */
742 p->size = *((unsigned long *) raw_codedbuf);
743 p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
744 drv_debug_msg(VIDEO_DEBUG_GENERAL, "coded buffer size %d\n", p->size);
745 break;
746
747 case VAProfileH264Baseline:
748 case VAProfileH264Main:
749 case VAProfileH264High:
750 case VAProfileH264ConstrainedBaseline:
751 i = 0;
752 next_buf_off = ~0xf & (obj_buffer->size / pnw_get_parallel_core_number(obj_context));
753 if (pnw_get_parallel_core_number(obj_context) == 2) {
754 /*The second part of coded buffer which generated by core 2 is the
755 * first part of encoded clip, while the first part of coded buffer
756 * is the second part of encoded clip.*/
757 p[i].next = &p[i + 1];
758 p[i].size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off);
759 p[i].buf = (unsigned char *)(((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off)) + 4); /* skip 4DWs */
760
761 if (GET_CODEDBUF_INFO(SLICE_NUM, obj_buffer->codedbuf_aux_info) <= 2 &&
762 GET_CODEDBUF_INFO(NONE_VCL_NUM, obj_buffer->codedbuf_aux_info) == 0) {
763 p[i].status = VA_CODED_BUF_STATUS_SINGLE_NALU;
764 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Only VCL NAL in this segment %i of coded buffer\n",
765 i);
766 }
767 drv_debug_msg(VIDEO_DEBUG_GENERAL, "2nd segment coded buffer offset: 0x%08x, size: %d\n",
768 next_buf_off, p[i].size);
769
770 i++;
771
772 }
773 /* 1st segment */
774 p[i].size = *((unsigned long *) raw_codedbuf);
775 p[i].buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
776 drv_debug_msg(VIDEO_DEBUG_GENERAL, "1st segment coded buffer size %d\n", p[i].size);
777 if (GET_CODEDBUF_INFO(SLICE_NUM, obj_buffer->codedbuf_aux_info) <= 2 &&
778 GET_CODEDBUF_INFO(NONE_VCL_NUM, obj_buffer->codedbuf_aux_info) == 0) {
779 p[i].status = VA_CODED_BUF_STATUS_SINGLE_NALU;
780 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Only VCL NAL in this segment %i of coded buffer\n",
781 i);
782 }
783 for (i = 0; i < pnw_get_parallel_core_number(obj_context); i++) {
784 if (p[i].size > (next_buf_off - sizeof(unsigned long) * 4)) {
785 drv_debug_msg(VIDEO_DEBUG_ERROR, "Coded segment %d is too large(%d)"
786 " and exceed segment boundary(offset %d)", i, p[i].size, next_buf_off);
787 p[i].size = next_buf_off - sizeof(unsigned long) * 4;
788 }
789 }
790
791 break;
792
793 case VAProfileH263Baseline:
794 /* one segment */
795 p->size = *((unsigned long *) raw_codedbuf);
796 p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
797 drv_debug_msg(VIDEO_DEBUG_GENERAL, "coded buffer size %d\n", p->size);
798 break;
799
800 case VAProfileJPEGBaseline:
801 /* 3~6 segment
802 */
803 pnw_jpeg_AppendMarkers(obj_context, raw_codedbuf);
804 next_buf_off = 0;
805 /*Max resolution 4096x4096 use 6 segments*/
806 for (i = 0; i < PNW_JPEG_MAX_SCAN_NUM + 1; i++) {
807 p->size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off);
808 p->buf = (unsigned char *)((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 4); /* skip 4DWs */
809 next_buf_off = *((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 3);
810
811 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer segment %d size: %d\n", i, p->size);
812 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer next segment %d offset: %d\n", i + 1, next_buf_off);
813
814 if (next_buf_off == 0) {
815 p->next = NULL;
816 break;
817 } else
818 p->next = &p[1];
819 p++;
820 }
821 break;
822
823 default:
824 drv_debug_msg(VIDEO_DEBUG_ERROR, "unexpected case\n");
825
826 psb_buffer_unmap(obj_buffer->psb_buffer);
827 obj_buffer->buffer_data = NULL;
828 break;
829 }
830 }
831 #endif
832
833 return 0;
834 }
835
836