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