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