• 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  *    Li Zeng <li.zeng@intel.com>
28  *
29  */
30 
31 #include "pnw_H264.h"
32 #include "tng_vld_dec.h"
33 #include "psb_def.h"
34 #include "psb_drv_debug.h"
35 #include "pnw_rotate.h"
36 
37 #include "hwdefs/reg_io2.h"
38 #include "hwdefs/msvdx_offsets.h"
39 #include "hwdefs/msvdx_cmds_io2.h"
40 #include "hwdefs/msvdx_core_regs_io2.h"
41 #include "hwdefs/msvdx_vec_reg_io2.h"
42 #include "hwdefs/msvdx_vec_h264_reg_io2.h"
43 #include "hwdefs/dxva_fw_ctrl.h"
44 #ifdef SLICE_HEADER_PARSING
45 #include "hwdefs/dxva_cmdseq_msg.h"
46 #include "hwdefs/dxva_msg.h"
47 #endif
48 #include <stdlib.h>
49 #include <stdint.h>
50 #include <string.h>
51 
52 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &ctx->obj_context->driver_data->buffer_heap, id ))
53 
54 #define GET_SURFACE_INFO_is_used(psb_surface) ((int) (psb_surface->extra_info[0]))
55 #define SET_SURFACE_INFO_is_used(psb_surface, val) psb_surface->extra_info[0] = (uint32_t) val;
56 #define GET_SURFACE_INFO_col_pic_params(psb_surface) (psb_surface->extra_info[1])
57 #define SET_SURFACE_INFO_col_pic_params(psb_surface, val) psb_surface->extra_info[1] = val;
58 #define GET_SURFACE_INFO_dpb_idx(psb_surface) (psb_surface->extra_info[2])
59 #define SET_SURFACE_INFO_dpb_idx(psb_surface, val) psb_surface->extra_info[2] = val;
60 
61 #define IS_USED_AS_REFERENCE(pic_flags)         ( pic_flags & (VA_PICTURE_H264_SHORT_TERM_REFERENCE | VA_PICTURE_H264_LONG_TERM_REFERENCE) )
62 
63 /* Truncates a signed integer to 17 bits */
64 #define SIGNTRUNC( x ) ((( (x)  >> 15) & 0x10000) | ( (x) & 0xffff))
65 
66 #define MSVDX_VEC_REGS_BASE_MTX 0x0800
67 #define MSVDX_COMMANDS_BASE_MTX 0x1000
68 #define MSVDX_IQRAM_BASE_MTX    0x700
69 
70 #define HW_SUPPORTED_MAX_PICTURE_WIDTH_H264   4096
71 #define HW_SUPPORTED_MAX_PICTURE_HEIGHT_H264  4096
72 
73 #define SLICEDATA_BUFFER_TYPE(type) ((type==VASliceDataBufferType)?"VASliceDataBufferType":"VAProtectedSliceDataBufferType")
74 
75 typedef enum {
76     PICT_NONE,
77     PICT_FRAME,
78     PICT_TOP,
79     PICT_BOTTOM,
80     PICT_PAIR
81 } PICTYPE;
82 
83 typedef enum {
84     H264_BASELINE_PROFILE = 0,
85     H264_MAIN_PROFILE = 1,
86     H264_HIGH_PROFILE = 2
87 } PROFILE;
88 
89 static const char *profile2str[] = {
90     "H264_BASELINE_PROFILE",
91     "H264_MAIN_PROFILE",
92     "H264_HIGH_PROFILE"
93 };
94 
95 typedef enum {
96     ST_P,
97     ST_B ,
98     ST_I ,
99     ST_SP ,
100     ST_SI
101 } SLICE_TYPE;
102 
103 static IMG_UINT8 aSliceTypeVAtoMsvdx[] = { 1 , 2 , 0, 1, 0 };
104 
105 static const char *slice2str[] = {
106     "ST_P",
107     "ST_B",
108     "ST_I",
109     "ST_SP",
110     "ST_SI"
111 };
112 
113 typedef enum {
114     DEBLOCK_NONE,
115     DEBLOCK_STD,
116     DEBLOCK_INTRA_OOLD
117 } DEBLOCK_MODE_2NDPASS;
118 
119 struct context_H264_s {
120     struct context_DEC_s dec_ctx;
121     object_context_p obj_context; /* back reference */
122 
123     uint32_t profile; // ENTDEC BE_PROFILE & FE_PROFILE
124     uint32_t profile_idc; // BE_PROFILEIDC
125 
126     /* Picture parameters */
127     VAPictureParameterBufferH264 *pic_params;
128     object_surface_p forward_ref_surface;
129     object_surface_p backward_ref_surface;
130 
131     uint32_t coded_picture_width;    /* in pixels */
132     uint32_t coded_picture_height;    /* in pixels */
133 
134     uint32_t picture_width_mb;        /* in macroblocks */
135     uint32_t picture_height_mb;        /* in macroblocks */
136     uint32_t size_mb;                /* in macroblocks */
137 
138     uint32_t first_mb_x;
139     uint32_t first_mb_y;
140 
141     uint32_t mb_width_c;                /* Chroma macroblock width */
142     uint32_t mb_height_c;               /* Chroma macroblock height */
143 
144     uint32_t bit_depth_l;               /* Luma bit depth */
145     uint32_t qp_bd_offset_l;
146     uint32_t bit_depth_c;               /* Chroma bit depth */
147     uint32_t qp_bd_offset_c;
148 
149     uint32_t raw_mb_bits;               /* Number of bits per macroblock */
150 
151     uint32_t picture_width_samples_l;
152     uint32_t picture_height_samples_l;
153     uint32_t picture_width_samples_c;
154     uint32_t picture_height_samples_c;
155 
156     uint32_t picture_height_map_units;
157     uint32_t picture_size_map_units;
158 
159     PICTYPE pic_type;
160     uint32_t field_type;
161 
162     uint32_t long_term_frame_flags;
163     uint32_t two_pass_mode;
164     uint32_t deblock_mode;
165     uint32_t slice_count;
166 
167     /* Registers */
168     uint32_t reg_SPS0;
169     uint32_t reg_PPS0;
170     uint32_t reg_PIC0;
171 
172     uint32_t slice0_params;
173     uint32_t slice1_params;
174 
175     /* VLC packed data */
176     struct psb_buffer_s vlc_packed_table;
177 
178     /* Preload buffer */
179     struct psb_buffer_s preload_buffer;
180 
181     /* Slice Group Map buffer */
182     psb_buffer_p slice_group_map_buffer;
183 
184     /* IQ matrix */
185     VAIQMatrixBufferH264 *iq_matrix;
186     VASliceParameterBufferH264 *slice_param;
187 
188     /* Reference Cache */
189     struct psb_buffer_s reference_cache;
190 
191     /* map picture_id to dpbidx consistently between pictures */
192     uint32_t dpbidx_not_used_cnt[16];
193     uint32_t map_picture_id_to_dpbidx[16];
194     uint32_t dpbidx_used_this_pic_flags;
195 
196 };
197 
198 typedef struct context_H264_s *context_H264_p;
199 
200 #define INIT_CONTEXT_H264    context_H264_p ctx = (context_H264_p) obj_context->format_data;
201 
202 #define SURFACE(id)    ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
203 
204 #define CACHE_REF_OFFSET        72
205 #define CACHE_ROW_OFFSET        4
206 
207 #define REFERENCE_CACHE_SIZE    (512 * 1024)
208 
209 #define MAX_PRELOAD_CMDS                                (40*2)
210 typedef struct {
211     IMG_UINT8           ui8Address[MAX_PRELOAD_CMDS]; /* Address = (ui8Address << 1 | 0x400 ) */
212     IMG_UINT32          ui32Value[MAX_PRELOAD_CMDS];
213 } ADDRDATA;
214 
215 typedef struct {
216     IMG_UINT32          ui32ContextId;
217     IMG_UINT32          ui32PreloadBufferSize;
218     ADDRDATA            aData;
219 } PRELOAD;
220 
221 
222 
223 /* **************************************************************************************************************** */
224 /* Prepacked H264 VLC Tables */
225 /* **************************************************************************************************************** */
226 static const IMG_UINT16 ui16H264VLCTableData[] = {
227     0x4000, 0x4205, 0x440a, 0x2204, 0x2206, 0x0208, 0x040b, 0x400f,
228     0x4204, 0x4209, 0x4013, 0x420e, 0x4217, 0x421b, 0x4212, 0x420d,
229     0x4208, 0x2a08, 0x0232, 0x0035, 0x0036, 0x441f, 0x4416, 0x4411,
230     0x440c, 0x0407, 0x040e, 0x0415, 0x041c, 0x0223, 0x4a35, 0x3a00,
231     0x4420, 0x4426, 0x4421, 0x441c, 0x442b, 0x4422, 0x441d, 0x4418,
232     0x4433, 0x442e, 0x4429, 0x4428, 0x442f, 0x442a, 0x4425, 0x4424,
233     0x443b, 0x4436, 0x4431, 0x4430, 0x4437, 0x4432, 0x442d, 0x442c,
234     0x4443, 0x443e, 0x443d, 0x4438, 0x443f, 0x443a, 0x4439, 0x4434,
235     0x4240, 0x4242, 0x4241, 0x423c, 0x4227, 0x421e, 0x4219, 0x4214,
236     0x4023, 0x401a, 0x4015, 0x4010, 0x0410, 0x0249, 0x024c, 0x004f,
237     0x4613, 0x460f, 0x440a, 0x440a, 0x4205, 0x4205, 0x4205, 0x4205,
238     0x4200, 0x4200, 0x4200, 0x4200, 0x2a08, 0x0231, 0x0034, 0x0035,
239     0x4423, 0x4416, 0x4415, 0x440c, 0x0407, 0x040e, 0x0415, 0x121c,
240     0x0222, 0x4a3f, 0x3a00, 0x442f, 0x4426, 0x4425, 0x4420, 0x442b,
241     0x4422, 0x4421, 0x441c, 0x442c, 0x442e, 0x442d, 0x4428, 0x4433,
242     0x442a, 0x4429, 0x4424, 0x443b, 0x4436, 0x4435, 0x4434, 0x4437,
243     0x4432, 0x4431, 0x4430, 0x0203, 0x423a, 0x4238, 0x423d, 0x423c,
244     0x423e, 0x4239, 0x4243, 0x4242, 0x4241, 0x4240, 0x4227, 0x421e,
245     0x421d, 0x4218, 0x4014, 0x401a, 0x4019, 0x4010, 0x421f, 0x4212,
246     0x4211, 0x4208, 0x421b, 0x420e, 0x420d, 0x4204, 0x4017, 0x4009,
247     0x2210, 0x0432, 0x0239, 0x023c, 0x600a, 0x6008, 0x003d, 0x003e,
248     0x461f, 0x461b, 0x4617, 0x4613, 0x460f, 0x460a, 0x4605, 0x4600,
249     0x0403, 0x040a, 0x0611, 0x4433, 0x442e, 0x4429, 0x4424, 0x442f,
250     0x442a, 0x4425, 0x4420, 0x4430, 0x4436, 0x4431, 0x442c, 0x4437,
251     0x4432, 0x442d, 0x4428, 0x3600, 0x4640, 0x4643, 0x4642, 0x4641,
252     0x463c, 0x463f, 0x463e, 0x463d, 0x4638, 0x463b, 0x463a, 0x4639,
253     0x4634, 0x4435, 0x4435, 0x441c, 0x4418, 0x4426, 0x4414, 0x442b,
254     0x4422, 0x4421, 0x4410, 0x420c, 0x421e, 0x421d, 0x4208, 0x4227,
255     0x421a, 0x4219, 0x4204, 0x400d, 0x4023, 0x400e, 0x4009, 0x2208,
256     0x5406, 0x540a, 0x540e, 0x5412, 0x5416, 0x541a, 0x541e, 0x5204,
257     0x0002, 0x5002, 0x3000, 0x4000, 0x4005, 0x4200, 0x440a, 0x0401,
258     0x1208, 0x000a, 0x4410, 0x440c, 0x4408, 0x440f, 0x4409, 0x4404,
259     0x4013, 0x4212, 0x4211, 0x400e, 0x400d, 0x4000, 0x4205, 0x440a,
260     0x0404, 0x480f, 0x4a13, 0x2609, 0x441b, 0x4417, 0x4412, 0x440e,
261     0x440d, 0x4409, 0x4408, 0x4404, 0x0205, 0x0208, 0x020b, 0x020e,
262     0x1411, 0x4216, 0x4211, 0x4210, 0x420c, 0x421f, 0x421a, 0x4215,
263     0x4214, 0x4223, 0x421e, 0x4219, 0x4218, 0x4222, 0x4221, 0x421d,
264     0x421c, 0x3400, 0x3400, 0x3400, 0x4420, 0x4000, 0x0006, 0x0007,
265     0x0008, 0x0009, 0x000a, 0x040b, 0x4002, 0x4001, 0x4004, 0x4003,
266     0x4006, 0x4005, 0x4008, 0x4007, 0x400a, 0x4009, 0x3400, 0x440f,
267     0x440e, 0x440d, 0x420c, 0x420c, 0x420b, 0x420b, 0x1208, 0x000e,
268     0x000f, 0x4404, 0x4403, 0x4402, 0x4401, 0x4400, 0x0203, 0x420a,
269     0x4209, 0x420e, 0x420d, 0x420c, 0x420b, 0x4008, 0x4007, 0x4006,
270     0x4005, 0x0208, 0x000d, 0x000e, 0x4407, 0x4406, 0x4403, 0x4402,
271     0x4401, 0x0004, 0x420c, 0x420a, 0x4209, 0x400d, 0x400b, 0x4008,
272     0x4005, 0x4004, 0x4000, 0x0208, 0x000b, 0x000c, 0x4408, 0x4406,
273     0x4405, 0x4404, 0x4401, 0x420c, 0x420b, 0x420a, 0x4200, 0x4009,
274     0x4007, 0x4003, 0x4002, 0x2208, 0x000a, 0x000b, 0x4407, 0x4406,
275     0x4405, 0x4404, 0x4403, 0x400a, 0x4209, 0x420b, 0x4008, 0x4002,
276     0x4001, 0x4000, 0x2408, 0x4409, 0x4407, 0x4406, 0x4405, 0x4404,
277     0x4403, 0x4402, 0x4008, 0x4201, 0x4400, 0x440a, 0x2408, 0x4408,
278     0x4406, 0x4404, 0x4403, 0x4402, 0x4205, 0x4205, 0x4007, 0x4201,
279     0x4400, 0x4409, 0x2604, 0x0008, 0x4205, 0x4204, 0x4007, 0x4201,
280     0x4402, 0x4600, 0x4608, 0x4006, 0x4003, 0x2604, 0x4206, 0x4204,
281     0x4203, 0x4005, 0x4202, 0x4407, 0x4600, 0x4601, 0x2404, 0x4205,
282     0x4204, 0x4203, 0x4002, 0x4206, 0x4400, 0x4401, 0x4004, 0x0003,
283     0x4402, 0x5000, 0x4003, 0x4005, 0x4003, 0x4202, 0x4404, 0x5000,
284     0x4002, 0x4203, 0x5000, 0x5000, 0x4002, 0x4000, 0x4001, 0x4000,
285     0x4201, 0x4402, 0x4403, 0x4000, 0x4201, 0x4202, 0x4001, 0x4000,
286     0x4001, 0x4000, 0x4000, 0x4201, 0x4202, 0x4203, 0x4202, 0x4201,
287     0x4200, 0x0004, 0x4202, 0x4201, 0x4200, 0x4004, 0x4003, 0x0203,
288     0x4201, 0x4200, 0x4205, 0x4204, 0x4203, 0x4202, 0x4401, 0x4402,
289     0x4404, 0x4403, 0x4406, 0x4405, 0x4200, 0x4200, 0x2a08, 0x4406,
290     0x4405, 0x4404, 0x4403, 0x4402, 0x4401, 0x4400, 0x4007, 0x4208,
291     0x4409, 0x460a, 0x480b, 0x4a0c, 0x2201, 0x400d, 0x420e, 0x3200,
292 };
293 
294 /* Set bottom field flag in bit 7 and DPB index in bits 0:3 */
PICTURE2INDEX(context_H264_p ctx,VAPictureH264 * pic)295 static uint32_t PICTURE2INDEX(context_H264_p ctx, VAPictureH264 *pic)
296 {
297     uint32_t result = 0xff; /* unused */
298     object_surface_p ref_surface = SURFACE(pic->picture_id);
299     if (ref_surface) {
300         result = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface);
301     }
302     if (pic->flags & VA_PICTURE_H264_BOTTOM_FIELD) {
303         result |= 0x80; /* Set bit 7 */
304     }
305     return result;
306 }
307 
pnw_H264_QueryConfigAttributes(VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs)308 static void pnw_H264_QueryConfigAttributes(
309     VAProfile profile,
310     VAEntrypoint entrypoint,
311     VAConfigAttrib *attrib_list,
312     int num_attribs)
313 {
314     int i;
315     drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_QueryConfigAttributes\n");
316 
317     for (i = 0; i < num_attribs; i++) {
318         switch (attrib_list[i].type) {
319         case VAConfigAttribMaxPictureWidth:
320             if ((entrypoint == VAEntrypointVLD) &&
321                 (profile == VAProfileH264High))
322                 attrib_list[i].value = HW_SUPPORTED_MAX_PICTURE_WIDTH_H264;
323             else
324                 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
325             break;
326         case VAConfigAttribMaxPictureHeight:
327             if ((entrypoint == VAEntrypointVLD) &&
328                 (profile == VAProfileH264High))
329                 attrib_list[i].value = HW_SUPPORTED_MAX_PICTURE_HEIGHT_H264;
330             else
331                 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
332             break;
333         default:
334             break;
335         }
336     }
337 
338 }
339 
pnw_H264_ValidateConfig(object_config_p obj_config)340 static VAStatus pnw_H264_ValidateConfig(
341     object_config_p obj_config)
342 {
343     int i;
344     /* Check all attributes */
345     for (i = 0; i < obj_config->attrib_count; i++) {
346         switch (obj_config->attrib_list[i].type) {
347         case VAConfigAttribRTFormat:
348         case VAConfigAttribDecSliceMode:
349             /* Ignore */
350             break;
351 
352         default:
353             return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
354         }
355     }
356 
357     return VA_STATUS_SUCCESS;
358 }
359 
psb__H264_check_legal_picture(object_context_p obj_context,object_config_p obj_config)360 static VAStatus psb__H264_check_legal_picture(object_context_p obj_context, object_config_p obj_config)
361 {
362     VAStatus vaStatus = VA_STATUS_SUCCESS;
363 
364     CHECK_CONTEXT(obj_context);
365 
366     CHECK_CONFIG(obj_config);
367 
368     /* MSVDX decode capability for H.264:
369      *     BP@L3
370      *     MP@L4.1
371      *     HP@L4.1
372      *
373      * Refer to Table A-6 (Maximum frame rates for some example frame sizes) of ISO/IEC 14496-10:2005 (E).
374      */
375     switch (obj_config->profile) {
376     case VAProfileH264Baseline:
377         if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 720)
378             || (obj_context->picture_height <= 0) || (obj_context->picture_height > 576)) {
379             vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
380         }
381         break;
382 
383     case VAProfileH264Main:
384     case VAProfileH264High:
385     case VAProfileH264ConstrainedBaseline:
386         if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 1920)
387             || (obj_context->picture_height <= 0) || (obj_context->picture_height > 1088)) {
388             vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
389         }
390         break;
391 
392     default:
393         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
394         break;
395     }
396 
397     return vaStatus;
398 }
399 
400 static void pnw_H264_DestroyContext(object_context_p obj_context);
401 static void psb__H264_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param);
402 static void psb__H264_end_slice(context_DEC_p dec_ctx);
403 static void psb__H264_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param);
404 static VAStatus pnw_H264_process_buffer(context_DEC_p dec_ctx, object_buffer_p buffer);
405 
pnw_H264_CreateContext(object_context_p obj_context,object_config_p obj_config)406 static VAStatus pnw_H264_CreateContext(
407     object_context_p obj_context,
408     object_config_p obj_config)
409 {
410     VAStatus vaStatus = VA_STATUS_SUCCESS;
411     context_H264_p ctx;
412     /* Validate flag */
413     /* Validate picture dimensions */
414     //vaStatus = psb__H264_check_legal_picture(obj_context, obj_config);
415     CHECK_VASTATUS();
416 
417     ctx = (context_H264_p) calloc(1, sizeof(struct context_H264_s));
418     CHECK_ALLOCATION(ctx);
419 
420     obj_context->format_data = (void*) ctx;
421     ctx->obj_context = obj_context;
422     ctx->pic_params = NULL;
423 
424     ctx->dec_ctx.begin_slice = psb__H264_begin_slice;
425     ctx->dec_ctx.process_slice = psb__H264_process_slice_data;
426     ctx->dec_ctx.end_slice = psb__H264_end_slice;
427     ctx->dec_ctx.process_buffer = pnw_H264_process_buffer;
428 
429     ctx->dpbidx_used_this_pic_flags = 0;
430     memset(ctx->dpbidx_not_used_cnt, 0, sizeof(ctx->dpbidx_not_used_cnt));
431     memset(ctx->map_picture_id_to_dpbidx, 0xff, sizeof(ctx->map_picture_id_to_dpbidx));
432 
433     switch (obj_config->profile) {
434     case VAProfileH264Baseline:
435         ctx->profile = H264_BASELINE_PROFILE;
436         ctx->profile_idc = 0;
437         break;
438 
439     case VAProfileH264Main:
440         ctx->profile = H264_MAIN_PROFILE;
441         ctx->profile_idc = 1;
442         break;
443 
444     case VAProfileH264High:
445     case VAProfileH264ConstrainedBaseline:
446         ctx->profile = H264_HIGH_PROFILE;
447         ctx->profile_idc = 3;
448         break;
449 
450     default:
451         ASSERT(0);
452         vaStatus = VA_STATUS_ERROR_UNKNOWN;
453     }
454 
455     // TODO
456     if (vaStatus == VA_STATUS_SUCCESS) {
457         vaStatus = psb_buffer_create(obj_context->driver_data,
458                                      sizeof(PRELOAD),
459                                      psb_bt_vpu_only,
460                                      &ctx->preload_buffer);
461         DEBUG_FAILURE;
462     }
463     ctx->dec_ctx.preload_buffer = &ctx->preload_buffer;
464 
465     if (vaStatus == VA_STATUS_SUCCESS) {
466         vaStatus = psb_buffer_create(obj_context->driver_data,
467                                      REFERENCE_CACHE_SIZE,
468                                      psb_bt_vpu_only,
469                                      &ctx->reference_cache);
470         DEBUG_FAILURE;
471     }
472 
473     if (vaStatus == VA_STATUS_SUCCESS) {
474         vaStatus = psb_buffer_create(obj_context->driver_data,
475                                      sizeof(ui16H264VLCTableData),
476                                      psb_bt_cpu_vpu,
477                                      &ctx->vlc_packed_table);
478         DEBUG_FAILURE;
479     }
480     if (vaStatus == VA_STATUS_SUCCESS) {
481         unsigned char *vlc_packed_data_address;
482         if (0 ==  psb_buffer_map(&ctx->vlc_packed_table, &vlc_packed_data_address)) {
483             memcpy(vlc_packed_data_address, ui16H264VLCTableData, sizeof(ui16H264VLCTableData));
484             psb_buffer_unmap(&ctx->vlc_packed_table);
485         } else {
486             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
487             DEBUG_FAILURE;
488         }
489     }
490 
491     if (vaStatus == VA_STATUS_SUCCESS) {
492         vaStatus = vld_dec_CreateContext(&ctx->dec_ctx, obj_context);
493         DEBUG_FAILURE;
494     }
495 
496     if (vaStatus != VA_STATUS_SUCCESS) {
497         pnw_H264_DestroyContext(obj_context);
498     }
499 
500     return vaStatus;
501 }
502 
pnw_H264_DestroyContext(object_context_p obj_context)503 static void pnw_H264_DestroyContext(
504     object_context_p obj_context)
505 {
506     INIT_CONTEXT_H264
507     int i;
508 
509     vld_dec_DestroyContext(&ctx->dec_ctx);
510 
511     psb_buffer_destroy(&ctx->reference_cache);
512     psb_buffer_destroy(&ctx->preload_buffer);
513     psb_buffer_destroy(&ctx->vlc_packed_table);
514 
515     if (ctx->pic_params) {
516         free(ctx->pic_params);
517         ctx->pic_params = NULL;
518     }
519     if (ctx->iq_matrix) {
520         free(ctx->iq_matrix);
521         ctx->iq_matrix = NULL;
522     }
523 
524     free(obj_context->format_data);
525     obj_context->format_data = NULL;
526 }
527 
528 #define P(x)    psb__trace_message("PARAMS: " #x "\t= %08x (%d)\n", p->x, p->x)
psb__H264_trace_pic_params(VAPictureParameterBufferH264 * p)529 static void psb__H264_trace_pic_params(VAPictureParameterBufferH264 *p)
530 {
531     P(CurrPic);
532     P(picture_width_in_mbs_minus1);
533     P(picture_height_in_mbs_minus1);
534     P(bit_depth_luma_minus8);
535     P(bit_depth_chroma_minus8);
536     P(num_ref_frames);
537     P(seq_fields);
538     P(num_slice_groups_minus1);
539     P(slice_group_map_type);
540     P(pic_init_qp_minus26);
541     P(chroma_qp_index_offset);
542     P(second_chroma_qp_index_offset);
543     P(pic_fields);
544     P(frame_num);
545 }
546 
get_interpic_dpbidx(context_H264_p ctx,uint32_t picture_id)547 static uint32_t get_interpic_dpbidx(context_H264_p ctx, uint32_t picture_id)
548 {
549     uint32_t dpbidx, i ,max_count;
550 
551     /* check if picture_id is already allocated a dpbidx */
552     for (dpbidx = 0; dpbidx < 16; dpbidx++)
553         if (ctx->map_picture_id_to_dpbidx[dpbidx] == picture_id)
554             break;
555 
556     /* assign a new picture_id to a new/recycled dpbidx */
557     if (16 == dpbidx)
558     {
559         dpbidx = 0;
560         max_count = ctx->dpbidx_not_used_cnt[0];
561         for (i = 1; i < 16; i++)
562         {
563             if (ctx->dpbidx_not_used_cnt[i] > max_count)
564             {
565                 dpbidx = i;
566                 max_count = ctx->dpbidx_not_used_cnt[i];
567             }
568         }
569         ctx->map_picture_id_to_dpbidx[dpbidx] = picture_id;
570         ctx->dpbidx_not_used_cnt[dpbidx] = 0;
571     }
572 
573     /* record this dpbidx is used this pic to update the dpbidx_not_used_cnt later */
574     ctx->dpbidx_used_this_pic_flags |= (1 << dpbidx);
575 
576     return dpbidx;
577 }
578 
579 
psb__H264_process_picture_param(context_H264_p ctx,object_buffer_p obj_buffer)580 static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffer_p obj_buffer)
581 {
582     psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
583     object_surface_p obj_surface = ctx->obj_context->current_render_target;
584     uint32_t reg_value;
585     VAStatus vaStatus;
586 
587     ASSERT(obj_buffer->type == VAPictureParameterBufferType);
588     ASSERT(obj_buffer->num_elements == 1);
589     ASSERT(obj_buffer->size == sizeof(VAPictureParameterBufferH264));
590     ASSERT(target_surface);
591 
592     if ((obj_buffer->num_elements != 1) ||
593         (obj_buffer->size != sizeof(VAPictureParameterBufferH264)) ||
594         (NULL == target_surface)) {
595         return VA_STATUS_ERROR_UNKNOWN;
596     }
597 
598     /* Transfer ownership of VAPictureParameterBufferH264 data */
599     VAPictureParameterBufferH264 *pic_params = (VAPictureParameterBufferH264 *) obj_buffer->buffer_data;
600     if (ctx->pic_params) {
601         free(ctx->pic_params);
602     }
603     ctx->pic_params = pic_params;
604     obj_buffer->buffer_data = NULL;
605     obj_buffer->size = 0;
606 
607     if (psb_video_trace_fp && (psb_video_trace_level & VABUF_TRACE))
608         psb__H264_trace_pic_params(pic_params);
609 
610     /* Table 6-1 */
611     uint32_t sub_width_c  = (pic_params->seq_fields.bits.chroma_format_idc > 2) ? 1 : 2;
612     uint32_t sub_height_c = (pic_params->seq_fields.bits.chroma_format_idc > 1) ? 1 : 2;
613 
614     if (pic_params->seq_fields.bits.chroma_format_idc == 0) {
615         ctx->mb_width_c = 0;
616         ctx->mb_height_c = 0;
617     } else {
618         ctx->mb_width_c = 16 / sub_width_c;             /* 6-1 */
619         ctx->mb_height_c = 16 / sub_height_c;           /* 6-2 */
620     }
621 
622     ctx->bit_depth_l = 8 + pic_params->bit_depth_luma_minus8;                   /* (7-1) */
623     ctx->qp_bd_offset_l = 6 * pic_params->bit_depth_luma_minus8;                /* (7-2) */
624 
625     ctx->bit_depth_c = 8 + pic_params->bit_depth_chroma_minus8;                 /* (7-3) */
626     ctx->qp_bd_offset_c = 6 * (pic_params->bit_depth_chroma_minus8 + pic_params->seq_fields.bits.residual_colour_transform_flag);       /* (7-4) */
627 
628     ctx->picture_width_mb = pic_params->picture_width_in_mbs_minus1 + 1;
629     ctx->picture_height_mb = pic_params->picture_height_in_mbs_minus1 + 1;
630 
631     ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb;              /* (7-25) */
632 
633     //uint32_t colocated_size = (ctx->picture_width_mb + extra_size) * (ctx->picture_height_mb + extra_size) * 192;
634     uint32_t colocated_size = ((ctx->size_mb + 100) * 128 + 0xfff) & ~0xfff;
635 
636     vaStatus = vld_dec_allocate_colocated_buffer(&ctx->dec_ctx, ctx->obj_context->current_render_target, colocated_size);
637     CHECK_VASTATUS();
638 
639     ctx->raw_mb_bits = 256 * ctx->bit_depth_l + 2 * ctx->mb_width_c * ctx->mb_height_c * ctx->bit_depth_c;      /* (7-5) */
640 
641     ctx->picture_width_samples_l = ctx->picture_width_mb * 16;
642     ctx->picture_width_samples_c = ctx->picture_width_mb * ctx->mb_width_c;
643 
644     ctx->picture_height_samples_l = ctx->picture_height_mb * 16;
645     ctx->picture_height_samples_c = ctx->picture_height_mb * ctx->mb_height_c;
646 
647     if (obj_surface->share_info) {
648         obj_surface->share_info->coded_width = ctx->picture_width_samples_l;
649         obj_surface->share_info->coded_height = ctx->picture_height_samples_l;
650     }
651 
652     // BECAUSE OF
653     //  sps->FrameHeightInMbs   = ( 2 - sps->seq_fields.bits.frame_mbs_only_flag ) * sps->PicHeightInMapUnits;  /* (7-15) */
654     ctx->picture_height_map_units = 1 + ctx->picture_height_mb / (2 - pic_params->seq_fields.bits.frame_mbs_only_flag);
655     ctx->picture_size_map_units = ctx->picture_width_mb * ctx->picture_height_map_units;/* (7-14) */
656 
657     pic_params->seq_fields.bits.mb_adaptive_frame_field_flag = (pic_params->seq_fields.bits.mb_adaptive_frame_field_flag &&
658                                                                !pic_params->pic_fields.bits.field_pic_flag);
659     /* record just what type of picture we are */
660     if (pic_params->pic_fields.bits.field_pic_flag) {
661         if (pic_params->CurrPic.flags & VA_PICTURE_H264_BOTTOM_FIELD) {
662             ctx->pic_type = PICT_BOTTOM;
663             ctx->field_type = 1;
664         } else {
665             ctx->pic_type = PICT_TOP;
666             ctx->field_type = 0;
667         }
668     } else {
669         ctx->pic_type = PICT_FRAME;
670         ctx->field_type = pic_params->seq_fields.bits.mb_adaptive_frame_field_flag ? 3 : 2;
671     }
672 
673     uint32_t i;
674     /* update the not_used_cnt from the last picture data */
675     for (i = 0; i < 16; i++) {
676         if (!(ctx->dpbidx_used_this_pic_flags & (1 << i)))
677             ctx->dpbidx_not_used_cnt[i]++;
678     }
679 
680     ctx->dpbidx_used_this_pic_flags = 0;
681     ctx->long_term_frame_flags = 0;
682 
683     if (pic_params->num_ref_frames == 0) {
684         ctx->dpbidx_used_this_pic_flags = 0;
685         memset(ctx->dpbidx_not_used_cnt, 0, sizeof(ctx->dpbidx_not_used_cnt));
686         memset(ctx->map_picture_id_to_dpbidx, 0xff, sizeof(ctx->map_picture_id_to_dpbidx));
687     }
688     /* We go from high to low so that we are left with the lowest index */
689     for (i = pic_params->num_ref_frames; i--;) {
690         uint32_t dpbidx;
691         if (pic_params->ReferenceFrames[i].flags == VA_PICTURE_H264_INVALID) {
692             continue;
693         }
694         object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[i].picture_id);
695         if (ref_surface) {
696             dpbidx = get_interpic_dpbidx(ctx, pic_params->ReferenceFrames[i].picture_id);
697             if (pic_params->ReferenceFrames[i].flags & VA_PICTURE_H264_BOTTOM_FIELD) {
698                 ctx->long_term_frame_flags |= 0x01 << dpbidx;
699             }
700             SET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface, dpbidx);
701         }
702     }
703 
704     /* If the MB are not guarenteed to be consecutive - we must do a 2pass */
705     ctx->two_pass_mode = (pic_params->num_slice_groups_minus1 > 0) && (!ctx->pic_params->seq_fields.bits.mb_adaptive_frame_field_flag);
706 
707     ctx->reg_SPS0 = 0;
708     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, H264_BE_SPS0_DEFAULT_MATRIX_FLAG, (ctx->profile == H264_BASELINE_PROFILE));    /* Always use suplied matrix non baseline otherwise use default*/
709     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, H264_BE_SPS0_2PASS_FLAG,         ctx->two_pass_mode);                    /* Always 0 for VA - we cant handle otherwise yet */
710     /* Assume SGM_8BIT */
711     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, H264_FE_SPS0_4BIT_SGM_FLAG,      0);
712     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, BE_PROFILEIDC,                   ctx->profile_idc);
713     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, MIN_LUMA_BIPRED_SIZE_8X8, (ctx->picture_width_mb > 80));
714     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, DIRECT_8X8_INFERENCE_FLAG,       pic_params->seq_fields.bits.direct_8x8_inference_flag);
715     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, CHROMA_FORMAT_IDC,               pic_params->seq_fields.bits.chroma_format_idc);
716     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, FRAME_MBS_ONLY_FLAG,             pic_params->seq_fields.bits.frame_mbs_only_flag);
717     REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, PICWIDTHINMBSLESS1,              ctx->picture_width_mb - 1);
718 
719     ctx->reg_PPS0 = 0;
720     REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0, TRANSFORM_8X8_MODE_FLAG,         pic_params->pic_fields.bits.transform_8x8_mode_flag);
721     REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0, CONSTRAINED_INTRA_PRED_FLAG,     pic_params->pic_fields.bits.constrained_intra_pred_flag);
722     REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0, ENTROPY_CODING_MODE_FLAG,        pic_params->pic_fields.bits.entropy_coding_mode_flag);
723     REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0, NUM_SLICE_GROUPS_MINUS1,         pic_params->num_slice_groups_minus1);
724     REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_PPS0, BE_WEIGHTED_BIPRED_IDC,          pic_params->pic_fields.bits.weighted_bipred_idc);
725     REGIO_WRITE_FIELD_MASKEDLITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_PPS0, BE_CHROMA_QP_INDEX_OFFSET, pic_params->chroma_qp_index_offset);
726     REGIO_WRITE_FIELD_MASKEDLITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_PPS0, BE_SECOND_CHROMA_QP_INDEX_OFFSET,  pic_params->second_chroma_qp_index_offset);
727 
728     uint32_t PicHeightInMbs     = ctx->picture_height_mb >> pic_params->pic_fields.bits.field_pic_flag;         /* (7-23) */
729     uint32_t PicSizeInMbs       = ctx->picture_width_mb * PicHeightInMbs;                       /* (7-26) */
730 
731     ctx->reg_PIC0 = 0;
732     REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, PICSIZEINMBSLESS1,           PicSizeInMbs - 1);
733     REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, PICHEIGHTINMBSLESS1,         PicHeightInMbs - 1);
734     /* TODO */
735     REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_BE_CUR_PIC0, BE_REFERENCE_FLAG,           IS_USED_AS_REFERENCE(pic_params->CurrPic.flags) ? 1 : 0);
736     REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, MBAFFFRAMEFLAG,              pic_params->seq_fields.bits.mb_adaptive_frame_field_flag);
737     REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, FIELD_PIC_FLAG,              pic_params->pic_fields.bits.field_pic_flag);
738     REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, BOTTOM_FIELD_FLAG,           pic_params->CurrPic.flags & VA_PICTURE_H264_BOTTOM_FIELD ? 1 : 0);
739 
740     /* Record some info about current picture */
741     reg_value = 0;
742     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_COL_PIC0, COL_NOTFRAMEFLAG, (PICT_FRAME != ctx->pic_type) ? 1 : 0);
743     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_COL_PIC0, COL_MBAFFFRAMEFLAG, pic_params->seq_fields.bits.mb_adaptive_frame_field_flag);
744     SET_SURFACE_INFO_col_pic_params(target_surface, reg_value);
745 
746     if (pic_params->seq_fields.bits.chroma_format_idc == 0) {
747         vaStatus = psb_surface_set_chroma(target_surface, 128);
748         CHECK_VASTATUS();
749     }
750 
751     psb_CheckInterlaceRotate(ctx->obj_context, (unsigned char *)pic_params);
752 
753 
754 #ifdef PSBVIDEO_MSVDX_EC
755     /* tell the driver to save the frame info for Error Concealment */
756     /*
757     if (driver_data->ec_enabled) {
758         psb_context_get_next_cmdbuf(ctx->obj_context);
759         psb_context_submit_frame_info(ctx->obj_context, &target_surface->buf,
760                                       target_surface->stride, target_surface->size,
761                                       ctx->picture_width_mb, ctx->size_mb);
762     }
763     */
764 #endif
765     if ((ctx->picture_width_mb * 16) > 2048)
766         ctx->obj_context->driver_data->ec_enabled = 0;
767 
768     return VA_STATUS_SUCCESS;
769 }
770 
psb__H264_process_iq_matrix(context_H264_p ctx,object_buffer_p obj_buffer)771 static VAStatus psb__H264_process_iq_matrix(context_H264_p ctx, object_buffer_p obj_buffer)
772 {
773     ASSERT(obj_buffer->type == VAIQMatrixBufferType);
774     ASSERT(obj_buffer->num_elements == 1);
775     ASSERT(obj_buffer->size == sizeof(VAIQMatrixBufferH264));
776 
777     if ((obj_buffer->num_elements != 1) ||
778         (obj_buffer->size != sizeof(VAIQMatrixBufferH264))) {
779         return VA_STATUS_ERROR_UNKNOWN;
780     }
781 
782     /* Transfer ownership of VAIQMatrixBufferH264 data */
783     if (ctx->iq_matrix) {
784         free(ctx->iq_matrix);
785     }
786     ctx->iq_matrix = (VAIQMatrixBufferH264 *) obj_buffer->buffer_data;
787     obj_buffer->buffer_data = NULL;
788     obj_buffer->size = 0;
789 
790     return VA_STATUS_SUCCESS;
791 }
792 
psb__H264_process_slice_group_map(context_H264_p ctx,object_buffer_p obj_buffer)793 static VAStatus psb__H264_process_slice_group_map(context_H264_p ctx, object_buffer_p obj_buffer)
794 {
795     ASSERT(obj_buffer->type == VASliceGroupMapBufferType);
796     ASSERT(obj_buffer->num_elements == 1);
797 //    ASSERT(obj_buffer->size == ...);
798 
799     if (obj_buffer->num_elements != 1) {
800         return VA_STATUS_ERROR_UNKNOWN;
801     }
802 
803     ctx->slice_group_map_buffer = obj_buffer->psb_buffer;
804 
805     return VA_STATUS_SUCCESS;
806 }
807 
808 #ifdef SLICE_HEADER_PARSING
psb__H264_process_slice_header_group(context_H264_p ctx,object_buffer_p obj_buffer)809 static VAStatus psb__H264_process_slice_header_group(context_H264_p ctx, object_buffer_p obj_buffer)
810 {
811     ASSERT(obj_buffer->type == VAParsePictureParameterBufferType);
812     object_context_p obj_context = ctx->obj_context;
813     VAStatus vaStatus = VA_STATUS_SUCCESS;
814     /* Transfer ownership of VAPictureParameterBufferH264 data */
815     VAParsePictureParameterBuffer *pic_param_buf = (VAParsePictureParameterBuffer *) obj_buffer->buffer_data;
816     psb_driver_data_p driver_data = obj_context->driver_data;
817 
818     object_buffer_p frame_obj_buffer = BUFFER(pic_param_buf->frame_buf_id);
819     if (NULL == frame_obj_buffer) {
820         vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
821         DEBUG_FAILURE;
822         return vaStatus;
823     }
824 
825     object_buffer_p slice_header_obj_buffer = BUFFER(pic_param_buf->slice_headers_buf_id);
826     if (NULL == slice_header_obj_buffer) {
827         vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
828         DEBUG_FAILURE;
829         return vaStatus;
830     }
831 
832     psb_context_get_next_cmdbuf(obj_context);
833     psb_cmdbuf_p cmdbuf = obj_context->cmdbuf;
834 
835     uint32_t msg_size = sizeof(struct fw_slice_header_extract_msg);
836     uint32_t *msg = (uint32_t *)cmdbuf->MTX_msg;
837     memset(msg, 0, msg_size);
838     struct fw_slice_header_extract_msg *extract_msg;
839 
840     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Send nal parse cmd\n");
841     if (cmdbuf->cmd_count) {
842         drv_debug_msg(VIDEO_DEBUG_GENERAL, "nal parse cmdbuf has other msgs!\n");
843     }
844     extract_msg = (struct fw_slice_header_extract_msg *)msg;
845     extract_msg->header.bits.msg_size = sizeof(struct fw_slice_header_extract_msg);
846     extract_msg->header.bits.msg_type = VA_MSGID_SLICE_HEADER_EXTRACT;
847     extract_msg->flags.bits.flags = FW_VA_RENDER_HOST_INT;
848 
849     extract_msg->src_size = pic_param_buf->frame_size;
850     extract_msg->dst_size = pic_param_buf->slice_headers_size;
851     extract_msg->flag_bitfield.bits.expected_pps_id =
852         pic_param_buf->expected_pic_parameter_set_id;
853 
854     if (obj_context->modular_drm) {
855         extract_msg->flag_bitfield.bits.nalu_header_unit_type =
856             pic_param_buf->nalu_header.bits.nalu_header_unit_type;
857         extract_msg->flag_bitfield.bits.nalu_header_ref_idc =
858             pic_param_buf->nalu_header.bits.nalu_header_ref_idc;
859         extract_msg->header.bits.msg_type = VA_MSGID_MODULAR_SLICE_HEADER_EXTRACT;
860     }
861 
862     extract_msg->flag_bitfield.bits.continue_parse_flag = 0;
863     extract_msg->flag_bitfield.bits.frame_mbs_only_flag =
864         pic_param_buf->flags.bits.frame_mbs_only_flag;
865     extract_msg->flag_bitfield.bits.pic_order_present_flag =
866         pic_param_buf->flags.bits.pic_order_present_flag;
867     extract_msg->flag_bitfield.bits.delta_pic_order_always_zero_flag =
868         pic_param_buf->flags.bits.delta_pic_order_always_zero_flag;
869     extract_msg->flag_bitfield.bits.redundant_pic_cnt_present_flag =
870         pic_param_buf->flags.bits.redundant_pic_cnt_present_flag;
871     extract_msg->flag_bitfield.bits.weighted_pred_flag =
872         pic_param_buf->flags.bits.weighted_pred_flag;
873     extract_msg->flag_bitfield.bits.entropy_coding_mode_flag =
874         pic_param_buf->flags.bits.entropy_coding_mode_flag;
875     extract_msg->flag_bitfield.bits.deblocking_filter_control_present_flag =
876         pic_param_buf->flags.bits.deblocking_filter_control_present_flag;
877     extract_msg->flag_bitfield.bits.weighted_bipred_idc =
878         pic_param_buf->flags.bits.weighted_bipred_idc;
879     extract_msg->flag_bitfield.bits.residual_colour_transform_flag =
880         pic_param_buf->residual_colour_transform_flag;
881     extract_msg->flag_bitfield.bits.chroma_format_idc =
882         pic_param_buf->chroma_format_idc;
883     extract_msg->flag_bitfield.bits.idr_flag =
884         pic_param_buf->idr_flag;
885     extract_msg->flag_bitfield.bits.pic_order_cnt_type =
886         pic_param_buf->pic_order_cnt_type;
887 
888     extract_msg->pic_param0.bits.num_slice_groups_minus1 =
889         pic_param_buf->num_slice_groups_minus1;
890     extract_msg->pic_param0.bits.slice_group_map_type =
891         pic_param_buf->slice_group_map_type;
892     extract_msg->pic_param0.bits.log2_slice_group_change_cycle =
893         pic_param_buf->log2_slice_group_change_cycle;
894     extract_msg->pic_param0.bits.num_ref_idc_l0_active_minus1 =
895         pic_param_buf->num_ref_idc_l0_active_minus1;
896 
897     extract_msg->pic_param0.bits.log2_max_pic_order_cnt_lsb_minus4 =
898         pic_param_buf->log2_max_pic_order_cnt_lsb_minus4;
899     extract_msg->pic_param0.bits.log2_max_frame_num_minus4 =
900         pic_param_buf->log2_max_frame_num_minus4;
901     extract_msg->pic_param0.bits.num_ref_idc_l1_active_minus1 =
902         pic_param_buf->num_ref_idc_l1_active_minus1;
903     extract_msg->pic_param0.bits.slice_header_bit_offset =
904         pic_param_buf->slice_offset;
905 
906 
907     RELOC_MSG(extract_msg->src, frame_obj_buffer->psb_buffer->buffer_ofs, frame_obj_buffer->psb_buffer);
908     RELOC_MSG(extract_msg->dst, slice_header_obj_buffer->psb_buffer->buffer_ofs, slice_header_obj_buffer->psb_buffer);
909 
910     cmdbuf->parse_count++;
911 
912     psb__suspend_buffer(driver_data, frame_obj_buffer);
913     psb__suspend_buffer(driver_data, slice_header_obj_buffer);
914 
915     if (psb_context_flush_cmdbuf(obj_context))
916         drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_H264: flush parse cmdbuf error\n");
917 
918     return vaStatus;
919 }
920 #endif
921 
922 #define SCALING_LIST_4x4_SIZE   ((4*4))
923 #define SCALING_LIST_8x8_SIZE   ((8*8))
924 
psb__H264_build_SCA_chunk(context_H264_p ctx)925 static void psb__H264_build_SCA_chunk(context_H264_p ctx)
926 {
927     VAIQMatrixBufferH264 dummy_iq_matrix;
928     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
929 
930     VAIQMatrixBufferH264 *iq_matrix = ctx->iq_matrix;
931 
932     if (!iq_matrix) {
933         drv_debug_msg(VIDEO_DEBUG_GENERAL, "H264: No IQ matrix received for frame. Sending dummy IQ matrix.\n");
934         iq_matrix = &dummy_iq_matrix;
935         memset(iq_matrix, 0, sizeof(VAIQMatrixBufferH264));
936     }
937 
938     psb_cmdbuf_rendec_start(cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET);
939 
940     /* 8x8 Inter Y */
941     psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList8x8[1], SCALING_LIST_8x8_SIZE);
942 
943     /* 8x8 Intra Y */
944     psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList8x8[0], SCALING_LIST_8x8_SIZE);
945 
946     /* 4x4 Intra Y */
947     psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[0], SCALING_LIST_4x4_SIZE);
948 
949     /* 4x4 Inter Y */
950     psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[3], SCALING_LIST_4x4_SIZE);
951 
952     /* 4x4 Inter Cb */
953     psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[4], SCALING_LIST_4x4_SIZE);
954 
955     /* 4x4 Intra Cb */
956     psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[1], SCALING_LIST_4x4_SIZE);
957 
958     /* 4x4 Inter Cr */
959     psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[5], SCALING_LIST_4x4_SIZE);
960 
961     /* 4x4 Intra Cr */
962     psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[2], SCALING_LIST_4x4_SIZE);
963 
964     psb_cmdbuf_rendec_end(cmdbuf);
965 }
966 
psb__H264_build_picture_order_chunk(context_H264_p ctx,uint32_t * map)967 static void psb__H264_build_picture_order_chunk(context_H264_p ctx, uint32_t * map)
968 {
969     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
970     VAPictureParameterBufferH264 *pic_params = ctx->pic_params;
971     uint32_t reg_value;
972     int i;
973 
974     /* CHUNK: POC */
975     /* send Picture Order Counts (b frame only?) */
976     /* maybe need a state variable to track if this has already been sent for the frame */
977     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_FOC0));
978 
979     reg_value = 0;
980     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_FOC0, TOPFIELDORDERCNT_CURR,
981                            SIGNTRUNC(pic_params->CurrPic.TopFieldOrderCnt));
982     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
983 
984     reg_value = 0;
985     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_FOC1, BOTTOMFIELDORDERCNT_CURR,
986                            SIGNTRUNC(pic_params->CurrPic.BottomFieldOrderCnt));
987     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
988 
989     if (pic_params->num_ref_frames > 16) {
990         drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid reference number %d, set to 16\n", pic_params->num_ref_frames);
991         pic_params->num_ref_frames = 16;
992     }
993 
994     for (i = 0; i < 16; i++) {
995         if (map[i] < 16) {
996             reg_value = 0;
997             REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_TOP_FOC, TOPFIELDORDERCNT,
998                                    SIGNTRUNC(pic_params->ReferenceFrames[map[i]].TopFieldOrderCnt));
999             psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1000 
1001             reg_value = 0;
1002             REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_BOT_FOC, BOTTOMFIELDORDERCNT,
1003                                SIGNTRUNC(pic_params->ReferenceFrames[map[i]].BottomFieldOrderCnt));
1004             psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1005         }
1006         else {
1007             psb_cmdbuf_rendec_write(cmdbuf, 0);
1008             psb_cmdbuf_rendec_write(cmdbuf, 0);
1009         }
1010     }
1011 
1012     psb_cmdbuf_rendec_end(cmdbuf);
1013 }
1014 
psb__H264_build_B_slice_chunk(context_H264_p ctx,VASliceParameterBufferH264 * slice_param)1015 static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBufferH264 *slice_param)
1016 {
1017     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1018     VAPictureParameterBufferH264 *pic_params = ctx->pic_params;
1019     uint32_t reg_value;
1020     int i;
1021 
1022     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_COL_PIC0));
1023 
1024     /* Colocated picture is picture 0 in list 1*/
1025     object_surface_p colocated_surface = SURFACE(slice_param->RefPicList1[0].picture_id);
1026     if (colocated_surface) {
1027         uint32_t bottom_field_flag;
1028         if (pic_params->pic_fields.bits.field_pic_flag) {
1029             bottom_field_flag  = (slice_param->RefPicList1[0].flags & VA_PICTURE_H264_BOTTOM_FIELD) ? 1 : 0;
1030         } else {
1031             /* when current pic is a frame col bottom field flag is different */
1032             IMG_INT32   i32Cur;
1033             IMG_INT32   i32Top, i32Bot;
1034             IMG_INT32   i32TopAbsDiffPoc, i32BotAbsDiffPoc;
1035 
1036             /* current pic */
1037             i32Top = pic_params->CurrPic.TopFieldOrderCnt;
1038             i32Bot = pic_params->CurrPic.BottomFieldOrderCnt;
1039             i32Cur = (i32Top < i32Bot) ? i32Top : i32Bot;
1040 
1041             /* col pic */
1042             i32Top = slice_param->RefPicList1[0].TopFieldOrderCnt;
1043             i32Bot = slice_param->RefPicList1[0].BottomFieldOrderCnt;
1044 
1045             i32TopAbsDiffPoc = (i32Cur < i32Top) ? i32Top - i32Cur : i32Cur - i32Top;
1046             i32BotAbsDiffPoc = (i32Cur < i32Bot) ? i32Bot - i32Cur : i32Cur - i32Bot;
1047 
1048             bottom_field_flag = (i32TopAbsDiffPoc < i32BotAbsDiffPoc) ? 0 : 1;
1049         }
1050 
1051         reg_value = GET_SURFACE_INFO_col_pic_params(colocated_surface->psb_surface);
1052         REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_COL_PIC0, COL_BOTTOM_FIELD_FLAG, bottom_field_flag);
1053         psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1054 
1055         psb_buffer_p colocated_target_buffer = vld_dec_lookup_colocated_buffer(&ctx->dec_ctx, colocated_surface->psb_surface);
1056         ASSERT(colocated_target_buffer);
1057         if (colocated_target_buffer) {
1058             psb_cmdbuf_rendec_write_address(cmdbuf, colocated_target_buffer, 0);
1059         } else {
1060             /* This is an error */
1061             psb_cmdbuf_rendec_write(cmdbuf, 0);
1062         }
1063     } else {
1064         /* Need some better error handling here */
1065         psb_cmdbuf_rendec_write(cmdbuf, 0);
1066         psb_cmdbuf_rendec_write(cmdbuf, 0xDEADBEEF);
1067     }
1068 
1069     /* Calculate inverse index for reference pictures */
1070     {
1071         IMG_UINT8 list0_inverse[32];
1072         memset(list0_inverse, 0xff, 32); /* Unused entries get 0xff */
1073 
1074         if (slice_param->num_ref_idx_l0_active_minus1 + 1 > 32) {
1075             drv_debug_msg(VIDEO_DEBUG_ERROR, "num_ref_idx_l0_active_minus1(%d) is too big. Set it with 31\n",
1076                                slice_param->num_ref_idx_l0_active_minus1);
1077             slice_param->num_ref_idx_l0_active_minus1 = 31;
1078         }
1079 
1080         if (slice_param->num_ref_idx_l0_active_minus1 > 30)
1081             slice_param->num_ref_idx_l0_active_minus1 = 30;
1082         for (i = slice_param->num_ref_idx_l0_active_minus1 + 1; i--;) {
1083             object_surface_p surface = SURFACE(slice_param->RefPicList0[i].picture_id);
1084             if (surface) {
1085                 uint32_t dpb_idx = GET_SURFACE_INFO_dpb_idx(surface->psb_surface);
1086                 if (dpb_idx < 16) {
1087                     if (slice_param->RefPicList0[i].flags & VA_PICTURE_H264_BOTTOM_FIELD) {
1088                         dpb_idx |= 0x10;
1089                     }
1090                     list0_inverse[dpb_idx] = i;
1091                 }
1092             }
1093         }
1094         for (i = 0; i < 32; i += 4) {
1095             reg_value = 0;
1096             reg_value |= list0_inverse[i];
1097             reg_value |= list0_inverse[i+1] << 8;
1098             reg_value |= list0_inverse[i+2] << 16;
1099             reg_value |= list0_inverse[i+3] << 24;
1100             psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1101         }
1102     }
1103 
1104     if (slice_param->num_ref_idx_l1_active_minus1 > 28)
1105         slice_param->num_ref_idx_l1_active_minus1 = 28;
1106 
1107     /* Write Ref List 1 - but only need the valid ones */
1108     for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i += 4) {
1109         reg_value = 0;
1110         reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i]);
1111         reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i+1]) << 8;
1112         reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i+2]) << 16;
1113         reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i+3]) << 24;
1114         psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1115     }
1116 
1117     psb_cmdbuf_rendec_end(cmdbuf);
1118 }
1119 
psb__H264_build_register(context_H264_p ctx,VASliceParameterBufferH264 * slice_param)1120 static void psb__H264_build_register(context_H264_p ctx, VASliceParameterBufferH264 *slice_param)
1121 {
1122     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1123     uint32_t reg_value;
1124 
1125     psb_cmdbuf_reg_start_block(cmdbuf, 0);
1126 
1127     reg_value = 0;
1128     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_PROFILE, ctx->profile);
1129     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_MODE, 1); /* 1 - H.264 */
1130 
1131     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL), reg_value);
1132 
1133     /* write the FE registers */
1134     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0),    ctx->reg_SPS0);
1135     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0),    ctx->reg_PPS0);
1136     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0),        ctx->reg_PIC0);
1137     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE0),  ctx->slice0_params);
1138     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1),  ctx->slice1_params);
1139 
1140     reg_value = 0;
1141     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE2, FIRST_MB_IN_SLICE, slice_param->first_mb_in_slice);
1142     psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE2), reg_value);
1143 
1144     if (ctx->pic_params->num_slice_groups_minus1 >= 1) {
1145         ctx->obj_context->driver_data->ec_enabled = 0;
1146         ASSERT(ctx->slice_group_map_buffer);
1147         if (ctx->slice_group_map_buffer) {
1148             psb_cmdbuf_reg_set_address(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_BASE_ADDR_SGM),
1149                                        ctx->slice_group_map_buffer, 0);
1150         }
1151     }
1152     psb_cmdbuf_reg_end_block(cmdbuf);
1153 }
1154 
psb__H264_build_rendec_params(context_H264_p ctx,VASliceParameterBufferH264 * slice_param)1155 static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBufferH264 *slice_param)
1156 {
1157     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1158     psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
1159     VAPictureParameterBufferH264 *pic_params = ctx->pic_params;
1160     uint32_t reg_value;
1161     unsigned int i;
1162 
1163     int picture_id = ctx->obj_context->current_render_target->surface_id;
1164     for(i = 0; i < 16; i++) {
1165         if (ctx->map_picture_id_to_dpbidx[i] == (unsigned int)picture_id)
1166             break;
1167     }
1168 
1169     if (i < 16) {
1170         ctx->map_picture_id_to_dpbidx[i] = 0xff;
1171         ctx->dpbidx_not_used_cnt[i] = 0xff00;
1172     }
1173 
1174     /* get the dpbidx for the ref pictures */
1175         uint32_t map_dpbidx_to_refidx[16];
1176         memset(map_dpbidx_to_refidx, 0xff, sizeof(map_dpbidx_to_refidx));
1177 
1178        if (pic_params->num_ref_frames > 16)
1179            pic_params->num_ref_frames = 16;
1180        for (i = 0; i < pic_params->num_ref_frames; i++) {
1181             if (pic_params->ReferenceFrames[i].flags == VA_PICTURE_H264_INVALID) {
1182                 continue;
1183             }
1184             object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[i].picture_id);
1185             if (ref_surface) {
1186                 uint32_t idx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface);
1187                 if (idx < 16) {
1188                     map_dpbidx_to_refidx[idx] = i;
1189                 }
1190             }
1191         }
1192 
1193     /* psb_cmdbuf_rendec_start_block( cmdbuf ); */
1194 
1195     /* CHUNK: Entdec back-end profile and level */
1196     {
1197         psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL));
1198 
1199         reg_value = 0;
1200         REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_PROFILE, ctx->profile);
1201         REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 1); /* 1 - H.264 */
1202         psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1203 
1204         psb_cmdbuf_rendec_end(cmdbuf);
1205     }
1206 
1207     /* CHUNK: SEQ Registers */
1208     /* send Slice Data for every slice */
1209     /* MUST be the last slice sent */
1210     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_SPS0));
1211 
1212     psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_SPS0);
1213     psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_PPS0);
1214     psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_PIC0);
1215     psb_cmdbuf_rendec_write(cmdbuf, ctx->slice0_params);
1216     psb_cmdbuf_rendec_write(cmdbuf, ctx->slice1_params);
1217 
1218     /* 5.5.75. VEC_H264_BE_BASE_ADDR_CUR_PIC */
1219     psb_buffer_p colocated_target_buffer = vld_dec_lookup_colocated_buffer(&ctx->dec_ctx, target_surface);
1220     ASSERT(colocated_target_buffer);
1221     if (colocated_target_buffer) {
1222         psb_cmdbuf_rendec_write_address(cmdbuf, colocated_target_buffer, colocated_target_buffer->buffer_ofs);
1223     } else {
1224         /* This is an error */
1225         psb_cmdbuf_rendec_write(cmdbuf, 0);
1226     }
1227 
1228     reg_value = 0;
1229     REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_REF0, BE_LONGTERMFRAMEFLAG, ctx->long_term_frame_flags);
1230     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1231 
1232     psb_cmdbuf_rendec_end(cmdbuf);
1233 
1234     //#warning "TODO: MUST be done after fe slice1 (which gives MB address) "
1235     /*          REGIO_WRITE_REGISTER(0, MSVDX_VEC_H264, CR_VEC_H264_FE_BASE_ADDR_SGM, gui32SliceGroupType6BaseAddressHack); */
1236 
1237     /* CHUNK: SCA */
1238     /* send Scaling Lists in High Profile for first slice*/
1239     if (ctx->profile == H264_HIGH_PROFILE) {
1240         psb__H264_build_SCA_chunk(ctx);
1241     }
1242 
1243     /* CHUNK: POC */
1244     /* send Picture Order Counts (b frame only?) */
1245     /* maybe need a state variable to track if this has already been sent for the frame */
1246     if (slice_param->slice_type == ST_B) {
1247         psb__H264_build_picture_order_chunk(ctx, map_dpbidx_to_refidx);
1248     }
1249 
1250     /* CHUNK: BIN */
1251     /* send B-slice information for B-slices */
1252     if (slice_param->slice_type == ST_B) {
1253         psb__H264_build_B_slice_chunk(ctx, slice_param);
1254     }
1255 
1256     /* CHUNK: PIN */
1257     /* send P+B-slice information for P and B slices */
1258     if (slice_param->slice_type == ST_B ||  slice_param->slice_type == ST_P) {
1259         psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_LIST0));
1260 
1261         if (slice_param->num_ref_idx_l0_active_minus1 > 31) {
1262             drv_debug_msg(VIDEO_DEBUG_ERROR, "num_ref_idx_l0_active_minus1(%d) is too big, limit it to 31.\n",
1263                                slice_param->num_ref_idx_l0_active_minus1);
1264             slice_param->num_ref_idx_l0_active_minus1 = 28;
1265         }
1266 
1267         for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i += 4) {
1268             reg_value = 0;
1269             reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i]);
1270             reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+1]) << 8;
1271             reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+2]) << 16;
1272             reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+3]) << 24;
1273             psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1274         }
1275 
1276         psb_cmdbuf_rendec_end(cmdbuf);
1277     }
1278 
1279     /* CHUNK: DPB */
1280     /* send DPB information (for P and B slices?) only needed once per frame */
1281 //      if ( sh->slice_type == ST_B || sh->slice_type == ST_P )
1282     if (pic_params->num_ref_frames > 0 && (slice_param->slice_type == ST_B || slice_param->slice_type == ST_P)) {
1283         IMG_BOOL is_used[16];
1284         psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES));
1285 
1286         /* Mark all surfaces as unused */
1287         memset(is_used, 0, sizeof(is_used));
1288 
1289         if (slice_param->num_ref_idx_l0_active_minus1 > 31)
1290             slice_param->num_ref_idx_l0_active_minus1 = 31;
1291         /* Mark onlys frame that are actualy used */
1292         for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
1293             object_surface_p ref_surface = SURFACE(slice_param->RefPicList0[i].picture_id);
1294             if (ref_surface) {
1295                 uint32_t idx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface);
1296                 if (idx < 16) {
1297                     is_used[idx] = IMG_TRUE;
1298                 }
1299             }
1300         }
1301 
1302         if (slice_param->num_ref_idx_l1_active_minus1 > 31)
1303             slice_param->num_ref_idx_l1_active_minus1 = 31;
1304 
1305         /* Mark onlys frame that are actualy used */
1306         for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
1307             object_surface_p ref_surface = SURFACE(slice_param->RefPicList1[i].picture_id);
1308             if (ref_surface) {
1309                 uint32_t idx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface);
1310                 if (idx < 16) {
1311                     is_used[idx] = IMG_TRUE;
1312                 }
1313             }
1314         }
1315 
1316          /* Only load used surfaces */
1317         for (i = 0; i < 16; i++) {
1318             if (map_dpbidx_to_refidx[i] < 16) {
1319 //              if (pic_params->ReferenceFrames[map_dpbidx_to_refidx[i]].flags == VA_PICTURE_H264_INVALID) {
1320 //                  continue;
1321 //              }
1322                 object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[map_dpbidx_to_refidx[i]].picture_id);
1323                 psb_buffer_p buffer;
1324 
1325                 if (NULL == ref_surface) {
1326                     drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalide reference surface handle\n",
1327                                        __FUNCTION__, __LINE__);
1328                     return;
1329                 }
1330 
1331                 buffer = ref_surface->psb_surface->ref_buf;
1332             /*
1333             drv_debug_msg(VIDEO_DEBUG_GENERAL, "pic_params->ReferenceFrames[%d] = %08x --> %08x frame_idx:0x%08x flags:%02x TopFieldOrderCnt: 0x%08x BottomFieldOrderCnt: 0x%08x %s\n",
1334                                      i,
1335                                      pic_params->ReferenceFrames[i].picture_id,
1336                                      ref_surface,
1337                                      pic_params->ReferenceFrames[i].frame_idx,
1338                                      pic_params->ReferenceFrames[i].flags,
1339                                      pic_params->ReferenceFrames[i].TopFieldOrderCnt,
1340                                      pic_params->ReferenceFrames[i].BottomFieldOrderCnt,
1341                                      is_used[i] ? "used" : "");
1342             */
1343                 if (ref_surface && is_used[i] && buffer) {
1344                     psb_cmdbuf_rendec_write_address(cmdbuf, buffer,
1345                                                     buffer->buffer_ofs);
1346                     psb_cmdbuf_rendec_write_address(cmdbuf, buffer,
1347                                                     buffer->buffer_ofs +
1348                                                     ref_surface->psb_surface->chroma_offset);
1349                     buffer->unfence_flag = 1;
1350                 } else {
1351                     psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
1352                     psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
1353                 }
1354             } else {
1355             psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
1356             psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef);
1357         }
1358         }
1359         psb_cmdbuf_rendec_end(cmdbuf);
1360     }
1361 
1362     /** fixed partial crc error in h264 case **/
1363     target_surface->buf.unfence_flag = 0;
1364 
1365     /* CHUNK: MVA and MVB */
1366     /* works as long as weighted factors A and B commands remain the same */
1367     if ((pic_params->pic_fields.bits.weighted_pred_flag && (slice_param->slice_type == ST_P)) ||
1368         ((pic_params->pic_fields.bits.weighted_bipred_idc != 0) && (slice_param->slice_type == ST_B))) {
1369         IMG_UINT32 num_ref_0 = slice_param->num_ref_idx_l0_active_minus1;
1370 
1371         psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, H264_WEIGHTED_FACTORS_A));
1372 
1373         if (num_ref_0 > 31)
1374             num_ref_0 = 31;
1375 
1376         /* weighted factors */
1377         for (i = 0; i <= num_ref_0; i++) {
1378             reg_value = 0;
1379             REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_A, CR_WEIGHT_A,   slice_param->chroma_weight_l0[i][1]);/* Cr - 1 */
1380             REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_A, CB_WEIGHT_A,   slice_param->chroma_weight_l0[i][0]);/* Cb - 0 */
1381             REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_A, Y_WEIGHT_A,    slice_param->luma_weight_l0[i]);
1382 
1383             psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1384         }
1385         /* pad remainder */
1386         for (; i < 32; i++) {
1387             psb_cmdbuf_rendec_write(cmdbuf, 0);
1388         }
1389 
1390         /* weighted offsets */
1391         for (i = 0; i <= num_ref_0; i++) {
1392             reg_value = 0;
1393             REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_A, CR_OFFSET_A,    slice_param->chroma_offset_l0[i][1]);/* Cr - 1 */
1394             REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_A, CB_OFFSET_A,    slice_param->chroma_offset_l0[i][0]);/* Cb - 0 */
1395             REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_A, Y_OFFSET_A,     slice_param->luma_offset_l0[i]);
1396 
1397             psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1398         }
1399         /* pad remainder */
1400         for (; i < 32; i++) {
1401             psb_cmdbuf_rendec_write(cmdbuf, 0);
1402         }
1403         psb_cmdbuf_rendec_end(cmdbuf);
1404 
1405         if (slice_param->slice_type == ST_B) {
1406             IMG_UINT32 num_ref_1 = slice_param->num_ref_idx_l1_active_minus1;
1407 
1408             psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, H264_WEIGHTED_FACTORS_B));
1409 
1410             if (num_ref_1 > 31) {
1411                 drv_debug_msg(VIDEO_DEBUG_ERROR, "num_ref_1 shouldn't be larger than 31\n");
1412                 num_ref_1 = 31;
1413             }
1414 
1415             /* weighted factors */
1416             for (i = 0; i <= num_ref_1; i++) {
1417                 reg_value = 0;
1418                 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_B, CR_WEIGHT_B,       slice_param->chroma_weight_l1[i][1]);/* Cr - 1 */
1419                 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_B, CB_WEIGHT_B,       slice_param->chroma_weight_l1[i][0]);/* Cb - 0 */
1420                 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_B, Y_WEIGHT_B,        slice_param->luma_weight_l1[i]);
1421 
1422                 psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1423             }
1424             /* pad remainder */
1425             for (; i < 32; i++) {
1426                 psb_cmdbuf_rendec_write(cmdbuf, 0);
1427             }
1428 
1429             /* weighted offsets */
1430             for (i = 0; i <= num_ref_1; i++) {
1431                 reg_value = 0;
1432                 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_B, CR_OFFSET_B,        slice_param->chroma_offset_l1[i][1]);/* Cr - 1 */
1433                 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_B, CB_OFFSET_B,        slice_param->chroma_offset_l1[i][0]);/* Cb - 0 */
1434                 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_B, Y_OFFSET_B, slice_param->luma_offset_l1[i]);
1435 
1436                 psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1437             }
1438             /* pad remainder */
1439             for (; i < 32; i++) {
1440                 psb_cmdbuf_rendec_write(cmdbuf, 0);
1441             }
1442             psb_cmdbuf_rendec_end(cmdbuf);
1443         }
1444     }
1445 
1446 
1447     /* CHUNK: SEQ Commands 1 */
1448     /* send Slice Data for every slice */
1449     /* MUST be the last slice sent */
1450     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE));
1451 
1452     reg_value = 0;
1453     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, (ctx->picture_height_mb * 16) - 1);
1454     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, (ctx->picture_width_mb * 16) - 1);
1455     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1456 
1457     reg_value = 0;
1458     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_HEIGHT, (ctx->picture_height_mb * 16) - 1);
1459     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_WIDTH, (ctx->picture_width_mb * 16) - 1);
1460     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1461 
1462     reg_value = 0;
1463     // TODO: Must check how these should be set
1464     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CHROMA_INTERLEAVED, 0);
1465     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, target_surface->stride_mode);
1466     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, ctx->profile);
1467     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 1);       /* H.264 */
1468     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, (ctx->two_pass_mode && !ctx->pic_params->seq_fields.bits.mb_adaptive_frame_field_flag));
1469     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, pic_params->seq_fields.bits.chroma_format_idc);
1470     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1471 
1472     ctx->obj_context->operating_mode = reg_value;
1473 
1474     if ((ctx->deblock_mode ==  DEBLOCK_INTRA_OOLD) && ctx->two_pass_mode) { /* Need to mark which buf is to be used as ref*/
1475         /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */
1476         psb_cmdbuf_rendec_write_address(cmdbuf, target_surface->in_loop_buf, target_surface->in_loop_buf->buffer_ofs);
1477 
1478         /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */
1479         psb_cmdbuf_rendec_write_address(cmdbuf, target_surface->in_loop_buf, target_surface->in_loop_buf->buffer_ofs + target_surface->chroma_offset);
1480         target_surface->ref_buf = target_surface->in_loop_buf;
1481         //target_surface->in_loop_buf->unfence_flag |= 2;
1482     } else {
1483         psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs);
1484         psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset);
1485         target_surface->ref_buf = &target_surface->buf;
1486         //target_surface->buf.unfence_flag = 2;
1487     }
1488 
1489     /* Aux Msb Buffer base address: H.264 does not use this command */
1490     reg_value = 0;
1491     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1492 
1493     /* Intra Reference Cache */
1494     psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->reference_cache, 0);
1495 
1496     reg_value = 0;
1497     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, MC_CACHE_CONFIGURATION, CONFIG_REF_OFFSET, CACHE_REF_OFFSET);
1498     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, MC_CACHE_CONFIGURATION, CONFIG_ROW_OFFSET, CACHE_ROW_OFFSET);
1499     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1500 
1501     /* Vc1 Intensity compensation: H.264 does not use this command */
1502     reg_value = 0;
1503     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1504 
1505     reg_value = 0;
1506     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTOR_DENOMINATOR, C_LOG2_WEIGHT_DENOM, slice_param->chroma_log2_weight_denom);
1507     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTOR_DENOMINATOR, Y_LOG2_WEIGHT_DENOM, slice_param->luma_log2_weight_denom);
1508     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1509 
1510     psb_cmdbuf_rendec_end(cmdbuf);
1511 
1512     /* CHUNK: SEQ Commands 2 */
1513     /* send Slice Data for every slice */
1514     /* MUST be the last slice sent */
1515     {
1516         IMG_UINT32 ui32Mode  = pic_params->pic_fields.bits.weighted_pred_flag | (pic_params->pic_fields.bits.weighted_bipred_idc << 1);
1517 
1518         psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS));
1519 
1520         reg_value = 0;
1521         REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, CONSTRAINED_INTRA_PRED, pic_params->pic_fields.bits.constrained_intra_pred_flag);
1522         REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, MODE_CONFIG, ui32Mode);
1523         REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, DISABLE_DEBLOCK_FILTER_IDC, slice_param->disable_deblocking_filter_idc);
1524         REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_ALPHA_CO_OFFSET_DIV2, slice_param->slice_alpha_c0_offset_div2);
1525         REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_BETA_OFFSET_DIV2, slice_param->slice_beta_offset_div2);
1526         REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE, ctx->field_type);
1527         REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, aSliceTypeVAtoMsvdx[slice_param->slice_type % 5]);
1528         psb_cmdbuf_rendec_write(cmdbuf, reg_value);
1529 
1530         /* Store slice parameters in header */
1531         *(ctx->dec_ctx.p_slice_params) = reg_value;
1532 
1533         psb_cmdbuf_rendec_end(cmdbuf);
1534     }
1535 
1536     /*          If this a two pass mode deblock, then we will perform the rotation as part of the
1537      *          2nd pass deblock procedure
1538      */
1539     if (!ctx->two_pass_mode)
1540         vld_dec_setup_alternative_frame(ctx->obj_context);
1541 }
1542 
psb__H264_preprocess_slice(context_H264_p ctx,VASliceParameterBufferH264 * slice_param)1543 static void psb__H264_preprocess_slice(context_H264_p ctx,
1544                                        VASliceParameterBufferH264 *slice_param)
1545 {
1546     VAPictureParameterBufferH264 *pic_params = ctx->pic_params;
1547     uint32_t slice_qpy;
1548 
1549     ctx->first_mb_x = slice_param->first_mb_in_slice % ctx->picture_width_mb;
1550     ctx->first_mb_y = slice_param->first_mb_in_slice / ctx->picture_width_mb;
1551     ctx->slice0_params = 0;
1552     ctx->slice1_params = 0;
1553 
1554     ASSERT(pic_params);
1555     if (!pic_params) {
1556         /* This is an error */
1557         return;
1558     }
1559 
1560     if (!pic_params->pic_fields.bits.field_pic_flag && pic_params->seq_fields.bits.mb_adaptive_frame_field_flag) {
1561         /* If in MBAFF mode multiply MB y-address by 2 */
1562         ctx->first_mb_y *= 2;
1563     }
1564 
1565     slice_qpy = 26 + pic_params->pic_init_qp_minus26 + slice_param->slice_qp_delta;     /* (7-27) */
1566 
1567     REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, BE_DIRECT_SPATIAL_MV_PRED_FLAG,                   slice_param->direct_spatial_mv_pred_flag);
1568     REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, H264_BE_SLICE0_DISABLE_DEBLOCK_FILTER_IDC,        slice_param->disable_deblocking_filter_idc);
1569     REGIO_WRITE_FIELD_MASKEDLITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, H264_BE_SLICE0_ALPHA_CO_OFFSET_DIV2,        slice_param->slice_alpha_c0_offset_div2);
1570     REGIO_WRITE_FIELD_MASKEDLITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, H264_BE_SLICE0_BETA_OFFSET_DIV2,            slice_param->slice_beta_offset_div2);
1571     REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, H264_BE_SLICE0_FIELD_TYPE,                        ctx->field_type);
1572     REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE0, SLICETYPE,                                        aSliceTypeVAtoMsvdx[ slice_param->slice_type % 5]);
1573     REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE0, CABAC_INIT_IDC,                                   slice_param->cabac_init_idc);
1574     REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE0, SLICECOUNT,                                       ctx->slice_count);
1575 
1576     REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, FIRST_MB_IN_SLICE_X,      ctx->first_mb_x);
1577     REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, FIRST_MB_IN_SLICE_Y,      ctx->first_mb_y);
1578     REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, SLICEQPY,                 slice_qpy);
1579     REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, NUM_REF_IDX_L0_ACTIVE_MINUS1, slice_param->num_ref_idx_l0_active_minus1);
1580     REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, NUM_REF_IDX_L1_ACTIVE_MINUS1, slice_param->num_ref_idx_l1_active_minus1);
1581 
1582     IMG_BOOL deblocker_disable = (slice_param->disable_deblocking_filter_idc  == 1);
1583 
1584     if (deblocker_disable) {
1585         if (ctx->obj_context->is_oold) {
1586             ctx->deblock_mode = DEBLOCK_INTRA_OOLD;
1587             ctx->two_pass_mode = 1;
1588             REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, H264_BE_SPS0_2PASS_FLAG, ctx->two_pass_mode);
1589         } else
1590             ctx->deblock_mode = DEBLOCK_STD;
1591     } else {
1592         ctx->deblock_mode = DEBLOCK_STD;
1593     }
1594 }
1595 
1596 /* **************************************************************************************************************** */
1597 /* Prepacked calculates VLC table offsets and reg address                                                           */
1598 /* **************************************************************************************************************** */
1599 static const  IMG_UINT32 ui32H264VLCTableRegValPair[] = {
1600     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000000), 0x00026000,
1601     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000004), 0x000738a0,
1602     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000008), 0x000828f4,
1603     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000000c), 0x000a312d,
1604     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000010), 0x000b5959,
1605     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000014), 0x000c517b,
1606     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000018), 0x000d1196,
1607     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000001c), 0x000db1ad,
1608     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000020), 0x000e21be,
1609     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000024), 0x000e59c8,
1610     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000028), 0x000e79cd,
1611     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000002c), 0x000eb1d3,
1612     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000030), 0x000ed1d8,
1613     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000034), 0x000f09dd,
1614     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000038), 0x000f71e7,
1615     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000003c), 0x000001f6,
1616     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000040), 0x1256a4dd,
1617     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000044), 0x01489292,
1618     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000048), 0x11248050,
1619     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000004c), 0x00000002,
1620     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000050), 0x00002a02,
1621     (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000054), 0x0108282a,
1622 };
1623 
1624 
psb__H264_write_VLC_tables(context_H264_p ctx)1625 static void psb__H264_write_VLC_tables(context_H264_p ctx)
1626 {
1627     psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1628     unsigned int i;
1629 
1630     psb_cmdbuf_skip_start_block(cmdbuf, SKIP_ON_CONTEXT_SWITCH);
1631 
1632     /* VLC Table */
1633     /* Write a LLDMA Cmd to transfer VLD Table data */
1634     psb_cmdbuf_dma_write_cmdbuf(cmdbuf, &ctx->vlc_packed_table, 0,
1635                                   sizeof(ui16H264VLCTableData), 0,
1636                                   DMA_TYPE_VLC_TABLE);
1637 
1638     /* Writes the VLD offsets.  mtx need only do this on context switch*/
1639     psb_cmdbuf_reg_start_block(cmdbuf, 0);
1640 
1641     for (i = 0; i < (sizeof(ui32H264VLCTableRegValPair) / sizeof(ui32H264VLCTableRegValPair[0])) ; i += 2) {
1642         psb_cmdbuf_reg_set(cmdbuf, ui32H264VLCTableRegValPair[i] , ui32H264VLCTableRegValPair[i + 1]);
1643     }
1644 
1645     psb_cmdbuf_reg_end_block(cmdbuf);
1646 
1647     psb_cmdbuf_skip_end_block(cmdbuf);
1648 }
1649 
psb__H264_begin_slice(context_DEC_p dec_ctx,VASliceParameterBufferBase * vld_slice_param)1650 static void psb__H264_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param)
1651 {
1652     VASliceParameterBufferH264 *slice_param = (VASliceParameterBufferH264 *) vld_slice_param;
1653     context_H264_p ctx = (context_H264_p)dec_ctx;
1654 #ifdef SLICE_HEADER_PARSING
1655     if (dec_ctx->parse_enabled == 1)
1656         dec_ctx->parse_key = slice_param->slice_data_bit_offset;
1657 #endif
1658     psb__H264_preprocess_slice(ctx, slice_param);
1659     psb__H264_write_VLC_tables(ctx);
1660 
1661     dec_ctx->bits_offset = slice_param->slice_data_bit_offset;
1662 
1663     /* CMD_SR_VERIFY_STARTCODE, clean this flag to work when no start code in slice data */
1664 #ifdef SLICE_HEADER_PARSING
1665     if (dec_ctx->parse_enabled == 1)
1666         dec_ctx->SR_flags = CMD_ENABLE_RBDU_EXTRACTION | CMD_SR_BITSTR_PARSE_KEY;
1667     else
1668 #endif
1669         dec_ctx->SR_flags = CMD_ENABLE_RBDU_EXTRACTION;
1670     ctx->slice_param = slice_param;
1671 }
1672 
psb__H264_process_slice_data(context_DEC_p dec_ctx,VASliceParameterBufferBase * vld_slice_param)1673 static void psb__H264_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param)
1674 {
1675     VASliceParameterBufferH264 *slice_param = (VASliceParameterBufferH264 *) vld_slice_param;
1676     context_H264_p ctx = (context_H264_p)dec_ctx;
1677 
1678     psb__H264_build_register(ctx, slice_param);
1679     psb__H264_build_rendec_params(ctx, slice_param);
1680 }
1681 
psb__H264_end_slice(context_DEC_p dec_ctx)1682 static void psb__H264_end_slice(context_DEC_p dec_ctx)
1683 {
1684     context_H264_p ctx = (context_H264_p)dec_ctx;
1685     if (ctx->slice_count == 0) {
1686         ctx->obj_context->flags |= FW_VA_RENDER_IS_FIRST_SLICE;
1687     }
1688     if (ctx->pic_params->seq_fields.bits.mb_adaptive_frame_field_flag) {
1689         ctx->obj_context->flags |= FW_VA_RENDER_IS_H264_MBAFF;
1690     }
1691     if (ctx->two_pass_mode) {
1692         ctx->obj_context->flags |= FW_VA_RENDER_IS_TWO_PASS_DEBLOCK;
1693     }
1694     ctx->obj_context->flags |= FW_VA_RENDER_IS_VLD_NOT_MC; /* FW_ERROR_DETECTION_AND_RECOVERY */
1695 
1696 #ifdef PSBVIDEO_MSVDX_EC
1697     if (ctx->obj_context->driver_data->ec_enabled)
1698         ctx->obj_context->flags |= (FW_ERROR_DETECTION_AND_RECOVERY); /* FW_ERROR_DETECTION_AND_RECOVERY */
1699 #endif
1700 
1701     ctx->obj_context->first_mb = (ctx->first_mb_y << 8) | ctx->first_mb_x;
1702     ctx->obj_context->last_mb = (((ctx->picture_height_mb >> ctx->pic_params->pic_fields.bits.field_pic_flag) - 1) << 8) | (ctx->picture_width_mb - 1);
1703     *(dec_ctx->slice_first_pic_last) = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb);
1704 
1705     ctx->slice_count++;
1706 }
1707 
1708 #ifdef PSBVIDEO_MSVDX_EC
psb__H264_choose_ec_frames(context_H264_p ctx)1709 static void psb__H264_choose_ec_frames(context_H264_p ctx)
1710 {
1711     ctx->obj_context->ec_target = NULL;
1712     if (ctx->slice_param == NULL)
1713         return;
1714     /* If reference picture list has a valid entry, this is a P or B frame and we conceal from the frame that is at the top of the list*/
1715     object_surface_p ref_surface = SURFACE(ctx->slice_param->RefPicList0[0].picture_id);
1716     ctx->obj_context->ec_target = ref_surface;
1717 
1718     /* Otherwise we conceal from the previous I or P frame*/
1719     if (!ctx->obj_context->ec_target)
1720     {
1721         ctx->obj_context->ec_target = ctx->obj_context->ec_candidate;
1722     }
1723 
1724     if (ctx->slice_param->slice_type != ST_B)
1725     {
1726         ctx->obj_context->ec_candidate = ctx->obj_context->current_render_target; /* in case the next frame is an I frame we will need this */
1727     }
1728     if (!ctx->obj_context->ec_target) {
1729         ctx->obj_context->ec_target = ctx->obj_context->current_render_target;
1730     }
1731 }
1732 #endif
1733 
pnw_H264_BeginPicture(object_context_p obj_context)1734 static VAStatus pnw_H264_BeginPicture(
1735     object_context_p obj_context)
1736 {
1737     INIT_CONTEXT_H264
1738 
1739 #ifdef SLICE_HEADER_PARSING
1740     obj_context->msvdx_frame_end = 0;
1741 #endif
1742 
1743     if (ctx->pic_params) {
1744         free(ctx->pic_params);
1745         ctx->pic_params = NULL;
1746     }
1747     if (ctx->iq_matrix) {
1748         free(ctx->iq_matrix);
1749         ctx->iq_matrix = NULL;
1750     }
1751     ctx->slice_count = 0;
1752     ctx->slice_group_map_buffer = NULL;
1753     ctx->deblock_mode = DEBLOCK_NONE;
1754 
1755     return VA_STATUS_SUCCESS;
1756 }
1757 
pnw_H264_process_buffer(context_DEC_p dec_ctx,object_buffer_p buffer)1758 static VAStatus pnw_H264_process_buffer(
1759     context_DEC_p dec_ctx,
1760     object_buffer_p buffer)
1761 {
1762     context_H264_p ctx = (context_H264_p)dec_ctx;
1763     VAStatus vaStatus = VA_STATUS_SUCCESS;
1764     object_buffer_p obj_buffer = buffer;
1765 
1766     {
1767         switch (obj_buffer->type) {
1768         case VAPictureParameterBufferType:
1769             vaStatus = psb__H264_process_picture_param(ctx, obj_buffer);
1770             DEBUG_FAILURE;
1771             break;
1772 
1773         case VAIQMatrixBufferType:
1774             vaStatus = psb__H264_process_iq_matrix(ctx, obj_buffer);
1775             DEBUG_FAILURE;
1776             break;
1777 
1778         case VASliceGroupMapBufferType:
1779             vaStatus = psb__H264_process_slice_group_map(ctx, obj_buffer);
1780             DEBUG_FAILURE;
1781             break;
1782 #ifdef SLICE_HEADER_PARSING
1783         case VAParsePictureParameterBufferType:
1784             dec_ctx->parse_enabled = 1;
1785             vaStatus = psb__H264_process_slice_header_group(ctx, obj_buffer);
1786             DEBUG_FAILURE;
1787             break;
1788 #endif
1789         default:
1790             vaStatus = VA_STATUS_ERROR_UNKNOWN;
1791             DEBUG_FAILURE;
1792         }
1793     }
1794 
1795     return vaStatus;
1796 }
1797 
pnw_H264_EndPicture(object_context_p obj_context)1798 static VAStatus pnw_H264_EndPicture(
1799     object_context_p obj_context)
1800 {
1801     INIT_CONTEXT_H264
1802     psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
1803     psb_driver_data_p driver_data = obj_context->driver_data;
1804     VAStatus vaStatus = VA_STATUS_SUCCESS;
1805 
1806     if (ctx->two_pass_mode) {
1807         psb_buffer_p colocated_target_buffer = vld_dec_lookup_colocated_buffer(&ctx->dec_ctx, target_surface);
1808         psb_surface_p rotate_surface = ctx->obj_context->current_render_target->out_loop_surface;
1809         uint32_t rotation_flags = 0;
1810         uint32_t ext_stride_a = 0;
1811 
1812         drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_EndPicture got two pass mode frame\n");
1813         CHECK_BUFFER(colocated_target_buffer);
1814         if (CONTEXT_ROTATE(ctx->obj_context)) {
1815             ASSERT(rotate_surface);
1816             REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1);
1817             REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, rotate_surface->stride_mode);
1818             REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */
1819             REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(rotate_surface));
1820         }
1821 
1822         REGIO_WRITE_FIELD_LITE(ext_stride_a, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, target_surface->stride / 64);
1823 
1824         /* Issue two pass deblock cmd, HW can handle deblock instead of host when using DE2.x firmware */
1825         if (ctx->deblock_mode == DEBLOCK_STD) {
1826             if (psb_context_submit_hw_deblock(ctx->obj_context,
1827                                               &target_surface->buf,
1828                                               rotate_surface ? (&rotate_surface->buf) : NULL,
1829                                               colocated_target_buffer,
1830                                               ctx->picture_width_mb,
1831                                               ctx->picture_height_mb,
1832                                               rotation_flags,
1833                                               ctx->field_type,
1834                                               ext_stride_a,
1835                                               target_surface->chroma_offset + target_surface->buf.buffer_ofs,
1836                                               rotate_surface ? (rotate_surface->chroma_offset + rotate_surface->buf.buffer_ofs) : 0,
1837                                               ctx->deblock_mode == DEBLOCK_INTRA_OOLD)) {
1838                 return VA_STATUS_ERROR_UNKNOWN;
1839             }
1840         } else if (ctx->deblock_mode == DEBLOCK_INTRA_OOLD) {
1841             psb_buffer_p buffer_dst;
1842             uint32_t chroma_offset_dst;
1843 
1844             if (CONTEXT_ROTATE(ctx->obj_context) == 0) {
1845                 buffer_dst = &target_surface->buf;
1846                 chroma_offset_dst = target_surface->chroma_offset;
1847             } else {
1848                 if (!rotate_surface) {
1849                     return VA_STATUS_ERROR_UNKNOWN;
1850                 }
1851 
1852                 buffer_dst = &rotate_surface->buf;
1853                 chroma_offset_dst = rotate_surface->chroma_offset;
1854             }
1855 
1856             if (psb_context_submit_hw_deblock(ctx->obj_context,
1857                                               target_surface->in_loop_buf,
1858                                               buffer_dst,
1859                                               colocated_target_buffer,
1860                                               ctx->picture_width_mb,
1861                                               ctx->picture_height_mb,
1862                                               rotation_flags,
1863                                               ctx->field_type,
1864                                               ext_stride_a,
1865                                               target_surface->chroma_offset + target_surface->buf.buffer_ofs,
1866                                               chroma_offset_dst,
1867                                               ctx->deblock_mode == DEBLOCK_INTRA_OOLD)) {
1868                 return VA_STATUS_ERROR_UNKNOWN;
1869             }
1870         }
1871     }
1872 
1873 #ifdef PSBVIDEO_MSVDX_EC
1874     /* Sent the HOST_BE_OPP command to detect slice error */
1875     if (driver_data->ec_enabled) {
1876         uint32_t rotation_flags = 0;
1877         uint32_t ext_stride_a = 0;
1878         object_surface_p ec_target;
1879 
1880         psb__H264_choose_ec_frames(ctx);
1881         ec_target = ctx->obj_context->ec_target;
1882         REGIO_WRITE_FIELD_LITE(ext_stride_a, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, target_surface->stride / 64);
1883 
1884     /* FIXME ec ignor rotate condition */
1885         if(ec_target) {
1886 	    if (psb_context_get_next_cmdbuf(ctx->obj_context)) {
1887                 vaStatus = VA_STATUS_ERROR_UNKNOWN;
1888                 DEBUG_FAILURE;
1889                 return vaStatus;
1890             }
1891 
1892             if (psb_context_submit_host_be_opp(ctx->obj_context,
1893                                           &target_surface->buf,
1894                                           &ec_target->psb_surface->buf,
1895                                           NULL,
1896                                           ctx->picture_width_mb,
1897                                           ctx->picture_height_mb,
1898                                           rotation_flags,
1899                                           ctx->field_type,
1900                                           ext_stride_a,
1901                                           target_surface->chroma_offset + target_surface->buf.buffer_ofs,
1902                                           ec_target->psb_surface->chroma_offset + ec_target->psb_surface->buf.buffer_ofs)) {
1903                 return VA_STATUS_ERROR_UNKNOWN;
1904             }
1905         }
1906     }
1907 #endif
1908 #ifdef SLICE_HEADER_PARSING
1909     if (driver_data->protected)
1910         obj_context->msvdx_frame_end = 1;
1911 #endif
1912 
1913     if (psb_context_flush_cmdbuf(ctx->obj_context)) {
1914         return VA_STATUS_ERROR_UNKNOWN;
1915     }
1916 
1917     if (CONTEXT_ROTATE(obj_context) && CONTEXT_SCALING(obj_context))
1918     {
1919         CONTEXT_SCALING(obj_context) = 0;
1920         vld_dec_yuv_rotate(obj_context);
1921         CONTEXT_SCALING(obj_context) = 1;
1922         ctx->dec_ctx.process_buffer = pnw_H264_process_buffer;
1923 
1924         if (psb_context_flush_cmdbuf(ctx->obj_context)) {
1925             return VA_STATUS_ERROR_UNKNOWN;
1926         }
1927     }
1928 
1929     if (ctx->pic_params) {
1930         free(ctx->pic_params);
1931         ctx->pic_params = NULL;
1932     }
1933 
1934     if (ctx->iq_matrix) {
1935         free(ctx->iq_matrix);
1936         ctx->iq_matrix = NULL;
1937     }
1938 
1939     return VA_STATUS_SUCCESS;
1940 }
1941 
1942 struct format_vtable_s pnw_H264_vtable = {
1943 queryConfigAttributes:
1944     pnw_H264_QueryConfigAttributes,
1945 validateConfig:
1946     pnw_H264_ValidateConfig,
1947 createContext:
1948     pnw_H264_CreateContext,
1949 destroyContext:
1950     pnw_H264_DestroyContext,
1951 beginPicture:
1952     pnw_H264_BeginPicture,
1953 renderPicture:
1954     vld_dec_RenderPicture,
1955 endPicture:
1956     pnw_H264_EndPicture
1957 };
1958