• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,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                            unsigned int flags
210                           )
211 {
212     VAStatus vaStatus = VA_STATUS_SUCCESS;
213     int allignment;
214     uint32_t placement;
215     int ret;
216 
217     /* reset rar_handle to NULL */
218     buf->rar_handle = 0;
219     buf->buffer_ofs = 0;
220 
221     buf->type = type;
222     buf->driver_data = driver_data; /* only for RAR buffers */
223     buf->user_ptr = vaddr;
224 
225     /* Xvideo will share surface buffer, set SHARED flag
226     */
227     placement =  DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED ;
228 
229     ret = LOCK_HARDWARE(driver_data);
230     if (ret) {
231         UNLOCK_HARDWARE(driver_data);
232         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
233         DEBUG_FAILURE_RET;
234         return vaStatus;
235     }
236 
237     allignment = 4096; /* temporily more safe */
238 #ifdef PSBVIDEO_MSVDX_DEC_TILING
239     if (type == psb_bt_mmu_tiling) {
240         placement =  DRM_PSB_FLAG_MEM_MMU_TILING | WSBM_PL_FLAG_SHARED ;
241         allignment = 2048 * 16; /* Tiled row aligned */
242     }
243 #endif
244 
245     if (flags & PSB_USER_BUFFER_WC)
246 	placement |= WSBM_PL_FLAG_WC;
247     else if (flags & PSB_USER_BUFFER_UNCACHED)
248 	placement |= WSBM_PL_FLAG_UNCACHED;
249     else
250 	placement |= WSBM_PL_FLAG_CACHED;
251 
252     //drv_debug_msg(VIDEO_DEBUG_ERROR, "FIXME: should use geetpagesize() ?\n");
253     ret = wsbmGenBuffers(driver_data->main_pool, 1, &buf->drm_buf,
254     allignment, placement);
255     if (!buf->drm_buf) {
256         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
257         UNLOCK_HARDWARE(driver_data);
258         return VA_STATUS_ERROR_ALLOCATION_FAILED;
259     }
260 
261     /* here use the placement when gen buffer setted */
262     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create BO from user buffer %p, size=%d\n", vaddr, size);
263 
264     ret = wsbmBODataUB(buf->drm_buf, size, NULL, NULL, 0, vaddr);
265     if (ret) {
266         drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to alloc wsbm buffers, buf->drm_buf is 0x%x, size is %d, vaddr is 0x%x\n", buf->drm_buf, size, vaddr);
267         return 1;
268     }
269 
270     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create BO from user buffer 0x%08x (%d byte),BO GPU offset hint=0x%08x\n",
271     vaddr, size, wsbmBOOffsetHint(buf->drm_buf));
272 
273     buf->pl_flags = placement;
274     buf->status = psb_bs_ready;
275     buf->wsbm_synccpu_flag = 0;
276 
277     return VA_STATUS_SUCCESS;
278 }
279 
280 #if 0
281 /*
282  * buffer setstatus
283  *
284  * Returns 0 on success
285  */
286 int psb_buffer_setstatus(psb_buffer_p buf, uint32_t set_placement, uint32_t clr_placement)
287 {
288     int ret = 0;
289 
290     ASSERT(buf);
291     ASSERT(buf->driver_data);
292 
293     ret = wsbmBOSetStatus(buf->drm_buf, set_placement, clr_placement);
294     if (ret == 0)
295         buf->pl_flags = set_placement;
296 
297     return ret;
298 }
299 #endif
300 
psb_buffer_reference(psb_driver_data_p driver_data,psb_buffer_p buf,psb_buffer_p reference_buf)301 VAStatus psb_buffer_reference(psb_driver_data_p driver_data,
302                               psb_buffer_p buf,
303                               psb_buffer_p reference_buf
304                              )
305 {
306     int ret = 0;
307     VAStatus vaStatus = VA_STATUS_SUCCESS;
308 
309     memcpy(buf, reference_buf, sizeof(*buf));
310     buf->drm_buf = NULL;
311 
312     ret = LOCK_HARDWARE(driver_data);
313     if (ret) {
314         UNLOCK_HARDWARE(driver_data);
315         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
316         DEBUG_FAILURE_RET;
317         return vaStatus;
318     }
319 
320     ret = wsbmGenBuffers(driver_data->main_pool,
321                          1,
322                          &buf->drm_buf,
323                          4096,  /* page alignment */
324                          0);
325     if (!buf->drm_buf) {
326         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
327         UNLOCK_HARDWARE(driver_data);
328         return VA_STATUS_ERROR_ALLOCATION_FAILED;
329     }
330 
331     ret = wsbmBOSetReferenced(buf->drm_buf, wsbmKBufHandle(wsbmKBuf(reference_buf->drm_buf)));
332     UNLOCK_HARDWARE(driver_data);
333     if (ret) {
334         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc wsbm buffers\n");
335         return VA_STATUS_ERROR_ALLOCATION_FAILED;
336     }
337 
338     return VA_STATUS_SUCCESS;
339 }
340 
psb_kbuffer_reference(psb_driver_data_p driver_data,psb_buffer_p buf,int kbuf_handle)341 VAStatus psb_kbuffer_reference(psb_driver_data_p driver_data,
342                                psb_buffer_p buf,
343                                int kbuf_handle
344                               )
345 {
346     int ret = 0;
347     VAStatus vaStatus = VA_STATUS_SUCCESS;
348 
349     buf->drm_buf = NULL;
350 
351     ret = LOCK_HARDWARE(driver_data);
352     if (ret) {
353         UNLOCK_HARDWARE(driver_data);
354         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
355         DEBUG_FAILURE_RET;
356         return vaStatus;
357     }
358 
359     ret = wsbmGenBuffers(driver_data->main_pool,
360                          1,
361                          &buf->drm_buf,
362                          4096,  /* page alignment */
363                          0);
364     if (!buf->drm_buf) {
365         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
366         UNLOCK_HARDWARE(driver_data);
367         return VA_STATUS_ERROR_ALLOCATION_FAILED;
368     }
369 
370     ret = wsbmBOSetReferenced(buf->drm_buf, kbuf_handle);
371     UNLOCK_HARDWARE(driver_data);
372     if (ret) {
373         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc wsbm buffers\n");
374         return VA_STATUS_ERROR_ALLOCATION_FAILED;
375     }
376     buf->pl_flags = wsbmBOPlacementHint(buf->drm_buf);
377     buf->type = psb_bt_surface;
378     buf->status = psb_bs_ready;
379 
380     return VA_STATUS_SUCCESS;
381 }
382 /*
383  * Destroy buffer
384  */
psb_buffer_destroy(psb_buffer_p buf)385 void psb_buffer_destroy(psb_buffer_p buf)
386 {
387     ASSERT(buf);
388     if (buf->drm_buf == NULL)
389         return;
390     if (psb_bs_unfinished != buf->status) {
391         ASSERT(buf->driver_data);
392         wsbmBOUnreference(&buf->drm_buf);
393         if (buf->rar_handle)
394             buf->rar_handle = 0;
395         buf->driver_data = NULL;
396         buf->status = psb_bs_unfinished;
397     }
398 }
399 
400 /*
401  * Map buffer
402  *
403  * Returns 0 on success
404  */
psb_buffer_map(psb_buffer_p buf,unsigned char ** address)405 int psb_buffer_map(psb_buffer_p buf, unsigned char **address /* out */)
406 {
407     int ret;
408 
409     ASSERT(buf);
410     ASSERT(buf->driver_data);
411 
412     /* multiple mapping not allowed */
413     if (buf->wsbm_synccpu_flag) {
414         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Multiple mapping request detected, unmap previous mapping\n");
415         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Need to fix application to unmap at first, then request second mapping request\n");
416 
417         psb_buffer_unmap(buf);
418     }
419 
420     /* don't think TG deal with READ/WRITE differently */
421     buf->wsbm_synccpu_flag = WSBM_SYNCCPU_READ | WSBM_SYNCCPU_WRITE;
422     if (psb_video_trace_fp) {
423         wsbmBOWaitIdle(buf->drm_buf, 0);
424     } else {
425         ret = wsbmBOSyncForCpu(buf->drm_buf, buf->wsbm_synccpu_flag);
426         if (ret) {
427             drv_debug_msg(VIDEO_DEBUG_ERROR, "faild to sync bo for cpu\n");
428             return ret;
429         }
430     }
431 
432     if (buf->user_ptr) /* user mode buffer */
433         *address = buf->user_ptr;
434     else
435         *address = wsbmBOMap(buf->drm_buf, buf->wsbm_synccpu_flag);
436 
437     if (*address == NULL) {
438         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to map buffer\n");
439         return -1;
440     }
441 
442     return 0;
443 }
444 
445 /*
446  * Unmap buffer
447  *
448  * Returns 0 on success
449  */
psb_buffer_unmap(psb_buffer_p buf)450 int psb_buffer_unmap(psb_buffer_p buf)
451 {
452     ASSERT(buf);
453     ASSERT(buf->driver_data);
454 
455     if (buf->wsbm_synccpu_flag)
456         (void) wsbmBOReleaseFromCpu(buf->drm_buf, buf->wsbm_synccpu_flag);
457 
458     buf->wsbm_synccpu_flag = 0;
459 
460     if ((buf->type != psb_bt_user_buffer) && !buf->handle)
461         wsbmBOUnmap(buf->drm_buf);
462 
463     return 0;
464 }
465 
466 #define _MRFL_DEBUG_CODED_
467 
468 #ifdef _MRFL_DEBUG_CODED_
psb__trace_coded(VACodedBufferSegment * vaCodedBufSeg)469 static void psb__trace_coded(VACodedBufferSegment *vaCodedBufSeg)
470 {
471     int i, j;
472     int uiPipeIndex = -1;
473     unsigned int *pBuf = NULL;
474     do {
475         ++uiPipeIndex;
476         drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: pipe num %d, size = %d\n", __FUNCTION__, uiPipeIndex, vaCodedBufSeg[uiPipeIndex].size);
477         pBuf = (unsigned int *)(vaCodedBufSeg[uiPipeIndex].buf);
478         pBuf -= 16;
479         for (i = 0; i < 6; i++) {
480             for (j = 0; j < 4; j++) {
481                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: 0x%08x\n", __FUNCTION__, pBuf[(i*4) + j]);
482             }
483          }
484         drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: \n", __FUNCTION__);
485     } while (vaCodedBufSeg[uiPipeIndex].next);
486 
487 	return ;
488 }
489 #endif
490 
491 #define PROFILE_H264(profile) ((profile>=VAProfileH264Baseline && profile <=VAProfileH264High) || \
492                                (profile == VAProfileH264ConstrainedBaseline))
tng_get_coded_data(object_buffer_p obj_buffer,unsigned char * raw_codedbuf)493 static void tng_get_coded_data(
494     object_buffer_p obj_buffer,
495     unsigned char *raw_codedbuf
496 )
497 {
498     object_context_p obj_context = obj_buffer->context;
499     VACodedBufferSegment *vaCodedBufSeg = &obj_buffer->codedbuf_mapinfo[0];
500     int iPipeIndex = 0;
501     unsigned int uiPipeNum = tng_get_pipe_number(obj_context);
502     unsigned int uiBufOffset = tng_align_KB(obj_buffer->size >> 1);
503     unsigned long *ptmp = NULL;
504     int tmp;
505 
506     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s pipenum = 0x%x\n", __FUNCTION__, uiPipeNum);
507     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s offset  = 0x%x\n", __FUNCTION__, uiBufOffset);
508 
509     tmp = vaCodedBufSeg[iPipeIndex].size = *(unsigned int *)((unsigned long)raw_codedbuf);
510 
511     /*
512      * This is used for DRM over WiDi which only uses H264 BP
513      * Tangier IED encryption operates on the chunks with 16bytes, and we must include
514      * the extra bytes beyond slice data as a whole chunk for decrption
515      * We simply include the padding bytes regardless of IED enable or disable
516      */
517     if (PROFILE_H264(obj_context->profile) && (tmp % 16 != 0)) {
518 	tmp = (tmp + 15) & (~15);
519 	drv_debug_msg(VIDEO_DEBUG_GENERAL, "Force slice size from %d to %d\n",
520                       vaCodedBufSeg[iPipeIndex].size, tmp);
521 	vaCodedBufSeg[iPipeIndex].size  = tmp;
522     }
523 
524     vaCodedBufSeg[iPipeIndex].buf = (unsigned char *)(((unsigned int *)((unsigned long)raw_codedbuf)) + 16); /* skip 4DWs */
525 
526     ptmp = (unsigned long *)((unsigned long)raw_codedbuf);
527     vaCodedBufSeg[iPipeIndex].reserved = (ptmp[1] >> 6) & 0xf;
528     vaCodedBufSeg[iPipeIndex].next = NULL;
529 
530 
531     if (uiPipeNum == 2) {
532         /*The second part of coded buffer which generated by core 2 is the
533          * first part of encoded clip, while the first part of coded buffer
534          * is the second part of encoded clip.*/
535         ++iPipeIndex;
536         vaCodedBufSeg[iPipeIndex - 1].next = &vaCodedBufSeg[iPipeIndex];
537         tmp = vaCodedBufSeg[iPipeIndex].size = *(unsigned int *)((unsigned long)raw_codedbuf + uiBufOffset);
538 
539         /*
540          * This is used for DRM over WiDi which only uses H264 BP
541          * Tangier IED encryption operates on the chunks with 16bytes, and we must include
542          * the extra bytes beyond slice data as a whole chunk for decryption
543          * We simply include the padding bytes regardless of IED enable or disable
544          */
545         if (PROFILE_H264(obj_context->profile) && (tmp % 16 != 0)) {
546             tmp = (tmp + 15) & (~15);
547             drv_debug_msg(VIDEO_DEBUG_GENERAL,"Force slice size from %d to %d\n",
548                           vaCodedBufSeg[iPipeIndex].size, tmp);
549 
550             vaCodedBufSeg[iPipeIndex].size  = tmp;
551         }
552 
553         vaCodedBufSeg[iPipeIndex].buf = (unsigned char *)(((unsigned int *)((unsigned long)raw_codedbuf + uiBufOffset)) + 16); /* skip 4DWs */
554         vaCodedBufSeg[iPipeIndex].reserved = vaCodedBufSeg[iPipeIndex - 1].reserved;
555         vaCodedBufSeg[iPipeIndex].next = NULL;
556     }
557 
558 #ifdef _MRFL_DEBUG_CODED_
559     psb__trace_coded(vaCodedBufSeg);
560 #endif
561 
562     return ;
563 }
564 
565 /*
566  * Return special data structure for codedbuffer
567  *
568  * Returns 0 on success
569  */
570 #define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
571 #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)572 int psb_codedbuf_map_mangle(
573     VADriverContextP ctx,
574     object_buffer_p obj_buffer,
575     void **pbuf /* out */
576 )
577 {
578     object_context_p obj_context = obj_buffer->context;
579     INIT_DRIVER_DATA;
580     VACodedBufferSegment *p = &obj_buffer->codedbuf_mapinfo[0];
581     unsigned char *raw_codedbuf;
582     VAStatus vaStatus = VA_STATUS_SUCCESS;
583     unsigned int next_buf_off;
584     uint32_t i;
585 
586     CHECK_INVALID_PARAM(pbuf == NULL);
587 
588     if (NULL == obj_context) {
589         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
590         DEBUG_FAILURE;
591 
592         psb_buffer_unmap(obj_buffer->psb_buffer);
593         obj_buffer->buffer_data = NULL;
594 
595         return vaStatus;
596     }
597 
598     raw_codedbuf = *pbuf;
599     /* reset the mapinfo */
600     memset(obj_buffer->codedbuf_mapinfo, 0, sizeof(obj_buffer->codedbuf_mapinfo));
601 
602     *pbuf = p = &obj_buffer->codedbuf_mapinfo[0];
603 #ifdef PSBVIDEO_MRFL
604     if (IS_MRFL(driver_data)) {
605         object_config_p obj_config = CONFIG(obj_context->config_id);
606         if (NULL == obj_config) {
607             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
608             DEBUG_FAILURE;
609 
610             psb_buffer_unmap(obj_buffer->psb_buffer);
611             obj_buffer->buffer_data = NULL;
612 
613             return vaStatus;
614         }
615 
616         if (VAProfileJPEGBaseline != obj_config->profile
617             && (*((unsigned long *) raw_codedbuf + 1) & SKIP_NEXT_FRAME) != 0) {
618             /*Set frame skip flag*/
619             tng_set_frame_skip_flag(obj_context);
620         }
621         switch (obj_config->profile) {
622             case VAProfileMPEG4Simple:
623             case VAProfileMPEG4AdvancedSimple:
624             case VAProfileMPEG4Main:
625 
626             case VAProfileH264Baseline:
627             case VAProfileH264Main:
628             case VAProfileH264High:
629             case VAProfileH264StereoHigh:
630             case VAProfileH264ConstrainedBaseline:
631             case VAProfileH263Baseline:
632                 /* 1st segment */
633                 tng_get_coded_data(obj_buffer, raw_codedbuf);
634 #if 0
635                 p->size = *((unsigned long *) raw_codedbuf);
636                 p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 16); /* skip 16DWs */
637                 p->next = NULL;
638 #ifdef _MRFL_DEBUG_CODED_
639                 psb__trace_coded((unsigned int*)raw_codedbuf);
640                 psb__trace_coded(p);
641 #endif
642 #endif
643                 break;
644             case VAProfileVP8Version0_3:
645             {
646                 /* multi segments*/
647 		struct VssVp8encEncodedFrame *t = (struct VssVp8encEncodedFrame *) (raw_codedbuf);
648 		int concatenate = 1;
649 #if 0
650 		for (i = 0; i < t->partitions - 1; i++) {
651                     if (t->partition_start[i+1] != t->partition_start[i] + t->partition_size[i])
652                         concatenate = 0;
653 		}
654 #endif
655 		/* reference frame surface_id */
656                 /* default is recon_buffer_mode ==0 */
657                 p->reserved = t->surfaceId_of_ref_frame[3];
658 
659 		if (concatenate) {
660                     /* partitions are concatenate */
661                     p->buf = t->coded_data;
662                     p->size = t->frame_size;
663                     if(t->frame_size == 0){
664                         drv_debug_msg(VIDEO_DEBUG_ERROR,"Frame size is zero, Force it to 3, encoder status is 0x%x\n", t->status);
665                         p->size = 3;
666                         t->coded_data[0]=0;
667                     }
668                     p->next = NULL;
669 		} else {
670                     for (i = 0; i < t->partitions; i++) {
671                         /* partition not consecutive */
672                         p->buf = t->coded_data + t->partition_start[i] - t->partition_start[0];
673                         p->size += t->partition_size[i];
674                         p->next = &p[1];
675                         p++;
676 		    }
677 		    p--;
678 		    p->next = NULL;
679 		}
680 
681 		break;
682             }
683             case VAProfileJPEGBaseline:
684                 /* 3~6 segment */
685                 tng_jpeg_AppendMarkers(obj_context, raw_codedbuf);
686                 next_buf_off = 0;
687                 /*Max resolution 4096x4096 use 6 segments*/
688                 for (i = 0; i < PTG_JPEG_MAX_SCAN_NUM + 1; i++) {
689                     p->size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off);  /* ui32BytesUsed in HEADER_BUFFER*/
690                     p->buf = (unsigned char *)((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 4);  /* skip 4DWs (HEADER_BUFFER) */
691                     next_buf_off = *((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 3);  /* ui32Reserved3 in HEADER_BUFFER*/
692 
693                     drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer segment %d size: %d\n", i, p->size);
694                     drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer next segment %d offset: %d\n", i + 1, next_buf_off);
695 
696                     if (next_buf_off == 0) {
697                         p->next = NULL;
698                         break;
699                     } else
700                         p->next = &p[1];
701                     p++;
702                 }
703                 break;
704 
705             default:
706                 drv_debug_msg(VIDEO_DEBUG_ERROR, "unexpected case\n");
707 
708                 psb_buffer_unmap(obj_buffer->psb_buffer);
709                 obj_buffer->buffer_data = NULL;
710                 break;
711         }
712     }
713 #endif
714 #ifdef PSBVIDEO_MFLD
715     if (IS_MFLD(driver_data)){ /* MFLD */
716         object_config_p obj_config = CONFIG(obj_context->config_id);
717 
718         if (NULL == obj_config) {
719             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
720             DEBUG_FAILURE;
721 
722             psb_buffer_unmap(obj_buffer->psb_buffer);
723             obj_buffer->buffer_data = NULL;
724 
725             return vaStatus;
726         }
727 
728         if (VAProfileJPEGBaseline != obj_config->profile
729             && (*((unsigned long *) raw_codedbuf + 1) & SKIP_NEXT_FRAME) != 0) {
730             /*Set frame skip flag*/
731             pnw_set_frame_skip_flag(obj_context);
732         }
733         switch (obj_config->profile) {
734         case VAProfileMPEG4Simple:
735         case VAProfileMPEG4AdvancedSimple:
736         case VAProfileMPEG4Main:
737             /* one segment */
738             p->size = *((unsigned long *) raw_codedbuf);
739             p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
740             drv_debug_msg(VIDEO_DEBUG_GENERAL, "coded buffer size %d\n", p->size);
741             break;
742 
743         case VAProfileH264Baseline:
744         case VAProfileH264Main:
745         case VAProfileH264High:
746         case VAProfileH264ConstrainedBaseline:
747             i = 0;
748             next_buf_off = ~0xf & (obj_buffer->size / pnw_get_parallel_core_number(obj_context));
749             if (pnw_get_parallel_core_number(obj_context) == 2) {
750                 /*The second part of coded buffer which generated by core 2 is the
751                  * first part of encoded clip, while the first part of coded buffer
752                  * is the second part of encoded clip.*/
753                 p[i].next = &p[i + 1];
754                 p[i].size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off);
755                 p[i].buf = (unsigned char *)(((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off)) + 4); /* skip 4DWs */
756 
757                 if (GET_CODEDBUF_INFO(SLICE_NUM, obj_buffer->codedbuf_aux_info) <= 2 &&
758                         GET_CODEDBUF_INFO(NONE_VCL_NUM, obj_buffer->codedbuf_aux_info) == 0) {
759                     p[i].status =  VA_CODED_BUF_STATUS_SINGLE_NALU;
760                     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Only VCL NAL in this segment %i of coded buffer\n",
761                             i);
762                 }
763                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "2nd segment coded buffer offset: 0x%08x,  size: %d\n",
764                         next_buf_off, p[i].size);
765 
766               i++;
767 
768             }
769             /* 1st segment */
770             p[i].size = *((unsigned long *) raw_codedbuf);
771             p[i].buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
772             drv_debug_msg(VIDEO_DEBUG_GENERAL, "1st segment coded buffer size %d\n", p[i].size);
773             if (GET_CODEDBUF_INFO(SLICE_NUM, obj_buffer->codedbuf_aux_info) <= 2 &&
774                     GET_CODEDBUF_INFO(NONE_VCL_NUM, obj_buffer->codedbuf_aux_info) == 0) {
775                 p[i].status =  VA_CODED_BUF_STATUS_SINGLE_NALU;
776                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Only VCL NAL in this segment %i of coded buffer\n",
777                         i);
778             }
779             for (i = 0; i < pnw_get_parallel_core_number(obj_context); i++) {
780                 if (p[i].size > (next_buf_off - sizeof(unsigned long) * 4)) {
781                     drv_debug_msg(VIDEO_DEBUG_ERROR, "Coded segment %d is too large(%d)"
782                             " and exceed segment boundary(offset %d)", i, p[i].size, next_buf_off);
783                     p[i].size = next_buf_off - sizeof(unsigned long) * 4;
784                 }
785             }
786 
787             break;
788 
789         case VAProfileH263Baseline:
790                 /* one segment */
791             p->size = *((unsigned long *) raw_codedbuf);
792             p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
793             drv_debug_msg(VIDEO_DEBUG_GENERAL, "coded buffer size %d\n", p->size);
794             break;
795 
796         case VAProfileJPEGBaseline:
797             /* 3~6 segment
798                  */
799             pnw_jpeg_AppendMarkers(obj_context, raw_codedbuf);
800             next_buf_off = 0;
801             /*Max resolution 4096x4096 use 6 segments*/
802             for (i = 0; i < PNW_JPEG_MAX_SCAN_NUM + 1; i++) {
803                 p->size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off);
804                 p->buf = (unsigned char *)((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 4);  /* skip 4DWs */
805                 next_buf_off = *((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 3);
806 
807                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer segment %d size: %d\n", i, p->size);
808                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer next segment %d offset: %d\n", i + 1, next_buf_off);
809 
810                 if (next_buf_off == 0) {
811                     p->next = NULL;
812                     break;
813                 } else
814                     p->next = &p[1];
815                 p++;
816             }
817             break;
818 
819         default:
820             drv_debug_msg(VIDEO_DEBUG_ERROR, "unexpected case\n");
821 
822             psb_buffer_unmap(obj_buffer->psb_buffer);
823             obj_buffer->buffer_data = NULL;
824             break;
825         }
826     }
827 #endif
828 
829     return 0;
830 }
831 
832