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