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
75typedef enum {
76    PICT_NONE,
77    PICT_FRAME,
78    PICT_TOP,
79    PICT_BOTTOM,
80    PICT_PAIR
81} PICTYPE;
82
83typedef enum {
84    H264_BASELINE_PROFILE = 0,
85    H264_MAIN_PROFILE = 1,
86    H264_HIGH_PROFILE = 2
87} PROFILE;
88
89static const char *profile2str[] = {
90    "H264_BASELINE_PROFILE",
91    "H264_MAIN_PROFILE",
92    "H264_HIGH_PROFILE"
93};
94
95typedef enum {
96    ST_P,
97    ST_B ,
98    ST_I ,
99    ST_SP ,
100    ST_SI
101} SLICE_TYPE;
102
103static IMG_UINT8 aSliceTypeVAtoMsvdx[] = { 1 , 2 , 0, 1, 0 };
104
105static const char *slice2str[] = {
106    "ST_P",
107    "ST_B",
108    "ST_I",
109    "ST_SP",
110    "ST_SI"
111};
112
113typedef enum {
114    DEBLOCK_NONE,
115    DEBLOCK_STD,
116    DEBLOCK_INTRA_OOLD
117} DEBLOCK_MODE_2NDPASS;
118
119struct 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
198typedef 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)
210typedef struct {
211    IMG_UINT8           ui8Address[MAX_PRELOAD_CMDS]; /* Address = (ui8Address << 1 | 0x400 ) */
212    IMG_UINT32          ui32Value[MAX_PRELOAD_CMDS];
213} ADDRDATA;
214
215typedef struct {
216    IMG_UINT32          ui32ContextId;
217    IMG_UINT32          ui32PreloadBufferSize;
218    ADDRDATA            aData;
219} PRELOAD;
220
221
222
223/* **************************************************************************************************************** */
224/* Prepacked H264 VLC Tables */
225/* **************************************************************************************************************** */
226static 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 */
295static 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
308static 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
340static 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
360static 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
400static void pnw_H264_DestroyContext(object_context_p obj_context);
401static void psb__H264_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param);
402static void psb__H264_end_slice(context_DEC_p dec_ctx);
403static void psb__H264_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param);
404static VAStatus pnw_H264_process_buffer(context_DEC_p dec_ctx, object_buffer_p buffer);
405
406static 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
503static 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)
529static 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
547static 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
580static 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
771static 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
793static 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
809static 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
925static 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
967static 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
1015static 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
1120static 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
1155static 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
1543static 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/* **************************************************************************************************************** */
1599static 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
1625static 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
1650static 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
1673static 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
1682static 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
1709static 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
1734static 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
1758static 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
1798static 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
1942struct format_vtable_s pnw_H264_vtable = {
1943queryConfigAttributes:
1944    pnw_H264_QueryConfigAttributes,
1945validateConfig:
1946    pnw_H264_ValidateConfig,
1947createContext:
1948    pnw_H264_CreateContext,
1949destroyContext:
1950    pnw_H264_DestroyContext,
1951beginPicture:
1952    pnw_H264_BeginPicture,
1953renderPicture:
1954    vld_dec_RenderPicture,
1955endPicture:
1956    pnw_H264_EndPicture
1957};
1958