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