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 * Zeng Li <zeng.li (at) intel.com> 27 * 28 */ 29 30 #include "psb_cmdbuf.h" 31 32 #include <unistd.h> 33 #include <stdio.h> 34 35 #include "hwdefs/mem_io.h" 36 #include "hwdefs/msvdx_offsets.h" 37 #include "hwdefs/reg_io2.h" 38 #include "hwdefs/msvdx_vec_reg_io2.h" 39 #include "hwdefs/msvdx_vdmc_reg_io2.h" 40 #include "hwdefs/msvdx_mtx_reg_io2.h" 41 #include "hwdefs/msvdx_dmac_linked_list.h" 42 #include "hwdefs/msvdx_rendec_mtx_slice_cntrl_reg_io2.h" 43 #include "hwdefs/msvdx_core_regs_io2.h" 44 #include "hwdefs/h264_macroblock_mem_io.h" 45 #include "hwdefs/dxva_cmdseq_msg.h" 46 #include "hwdefs/dxva_fw_ctrl.h" 47 #include "hwdefs/fwrk_msg_mem_io.h" 48 #include "hwdefs/dxva_msg.h" 49 #include "hwdefs/msvdx_cmds_io2.h" 50 #include <stdlib.h> 51 #include <errno.h> 52 #include <string.h> 53 54 #include "psb_def.h" 55 #include "psb_drv_debug.h" 56 57 #define H264_MACROBLOCK_DATA_SIZE 0x80 58 59 #define MSVDX_CMDS_BASE 0x1000 60 #define MSVDX_CORE_BASE 0x600 61 #define MSVDX_VEC_BASE 0x800 62 63 #define MSVDX_DEBLOCK_REG_SET 0x10000000 64 #define MSVDX_DEBLOCK_REG_GET 0x20000000 65 #define MSVDX_DEBLOCK_REG_POLLn 0x30000000 66 #define MSVDX_DEBLOCK_REG_POLLx 0x40000000 67 68 static int reg_set_count = 0; 69 static int reg_get_count = 0; 70 static int reg_poll_x = 0; 71 static int reg_poll_n = 0; 72 73 #define psb_deblock_reg_set(group, reg, value) \ 74 *cmdbuf->regio_idx++ = (group##_##reg##_##OFFSET + group##_##BASE) | MSVDX_DEBLOCK_REG_SET; \ 75 *cmdbuf->regio_idx++ = value; reg_set_count++; 76 77 #define psb_deblock_reg_set_RELOC( group, reg, buffer, buffer_offset, dst) \ 78 *cmdbuf->regio_idx++ = (group##_##reg##_##OFFSET + group##_##BASE) | MSVDX_DEBLOCK_REG_SET; \ 79 RELOC_REGIO(*cmdbuf->regio_idx++, buffer_offset, buffer, dst); reg_set_count++; 80 81 #define psb_deblock_reg_table_set(group, reg, index, value) \ 82 *cmdbuf->regio_idx++ = ( (group##_##reg##_OFFSET + group##_##BASE + index*group##_##reg##_STRIDE) | MSVDX_DEBLOCK_REG_SET); \ 83 *cmdbuf->regio_idx++ = value; reg_set_count++; 84 85 #define psb_deblock_reg_get(group, reg) \ 86 *cmdbuf->regio_idx++ = (group##_##reg##_##OFFSET + group##_##BASE) | MSVDX_DEBLOCK_REG_GET; reg_get_count++; 87 88 #if 1 89 #define h264_pollForSpaceForNCommands(NumCommands)\ 90 *cmdbuf->regio_idx++ = (MSVDX_CORE_CR_MSVDX_COMMAND_SPACE_OFFSET + MSVDX_CORE_BASE) | MSVDX_DEBLOCK_REG_POLLn; \ 91 *cmdbuf->regio_idx++ = NumCommands; reg_poll_n++; 92 #else 93 #define h264_pollForSpaceForNCommands(NumCommands) /* Seems not needed, so just define it null */ 94 #endif 95 96 #define PollForSpaceForXCommands \ 97 *cmdbuf->regio_idx++ = (MSVDX_CORE_CR_MSVDX_COMMAND_SPACE_OFFSET + MSVDX_CORE_BASE) | MSVDX_DEBLOCK_REG_POLLx; reg_poll_x++; 98 99 typedef enum { 100 H264_BLOCKSIZE_16X16 = 0, /* 1 block */ 101 H264_BLOCKSIZE_16X8 = 1, /* 2 blocks */ 102 H264_BLOCKSIZE_8X16 = 2, 103 H264_BLOCKSIZE_8X8 = 3, /* 4 blocks */ 104 H264_BLOCKSIZE_8X4 = 4, 105 H264_BLOCKSIZE_4X8 = 5, 106 H264_BLOCKSIZE_4X4 = 6 107 108 } h264_eBlockSize; 109 110 static uint32_t BlockDownsizeMap[] = { 111 1, 1, 3, 3, 3, 5, 5 112 }; 113 114 static uint32_t BlocksToSendMap[] = { 115 1, 2, 2, 4, 4, 4, 4 116 }; 117 118 static uint32_t BlockAddressMap[7][4] = { 119 { 0 }, /* 16x16 */ 120 { 0, 2 }, /* 16x8 */ 121 { 0, 1 }, /* 8x16 */ 122 { 0, 1, 2, 3 }, /* 8x8 */ 123 { 0, 1, 2, 3 }, /* 8x4 */ 124 { 0, 1, 2, 3 }, /* 4x8 */ 125 { 0, 1, 2, 3 } /* 4x4 */ 126 }; 127 128 static uint32_t VectorsToSendMap[] = { 129 1, 1, 1, 1, 2, 2, 4 130 }; 131 132 static uint32_t VectorOffsetMap[7][4] = { 133 { 0 }, /* 16x16 */ 134 { 0 }, /* 16x8 */ 135 { 0 }, /* 8x16 */ 136 { 0 }, /* 8x8 */ 137 { 0, 2 }, /* 8x4 */ 138 { 0, 1 }, /* 4x8 */ 139 { 0, 1, 2, 3 } /* 4x4 */ 140 }; 141 142 143 static uint32_t Above1AboveTileMap[] = { 144 /* 9, 12, 8, 13 */ 145 13, 12, 9, 8 146 }; 147 148 static uint32_t CurrentAboveTileMap[] = { 149 /* 11, 14, 10, 15 */ 150 15, 14, 11, 10 151 }; 152 153 static uint32_t CurrentColTileMap[] = { 154 10, 15, 0, 5, 8, 13, 2, 7, 1, 4, 3, 6, 9, 12 155 }; 156 157 158 static uint32_t ColBlockMap[] = { 159 2, 3, 0, 1 160 }; 161 162 void 163 h264_above1InterBlockSequence(psb_cmdbuf_p cmdbuf, uint8_t* MbData) 164 { 165 uint32_t i, BlockNum, Mv, MvAddr, Value; 166 uint32_t Block8x8, blockType; 167 uint32_t InterBlockCmd; 168 uint32_t MotionVecCmd[16]; 169 uint32_t BlockType[4] = {0}; 170 uint32_t DpbIdx[4]; 171 172 /* set MV vars to 0 */ 173 for (i = 0; i < 16; i++) { 174 MotionVecCmd[i] = 0; 175 } 176 177 /* Read the size of blocks 2 and 3 and resize them so they are all ?x8 */ 178 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK2_PREDICTION_SIZE); 179 if (Value > (sizeof(BlockDownsizeMap) / sizeof(uint32_t) - 1)) 180 Value = sizeof(BlockDownsizeMap) / sizeof(uint32_t) - 1; 181 BlockType[2] = BlockDownsizeMap[Value]; 182 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK3_PREDICTION_SIZE); 183 if (Value > (sizeof(BlockDownsizeMap) / sizeof(uint32_t) - 1)) 184 Value = sizeof(BlockDownsizeMap) / sizeof(uint32_t) - 1; 185 BlockType[3] = BlockDownsizeMap[Value]; 186 187 /* read motion vectors for the bottom row, but store them in the correct locn. for ?x8 blocks */ 188 for (i = 0; i < 4; i++) { 189 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_X_ABOVE, i); 190 REGIO_WRITE_FIELD(MotionVecCmd[Above1AboveTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_X, Value); 191 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_Y_ABOVE, i); 192 REGIO_WRITE_FIELD(MotionVecCmd[Above1AboveTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_Y, Value); 193 } 194 195 /* read DPB index for blocks 2 and 3 */ 196 for (i = 0; i < 2; i++) { 197 DpbIdx[ColBlockMap[i]] = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_DPB_IDX_COL, i); 198 } 199 200 /* Send commands required blocks */ 201 for (BlockNum = BlocksToSendMap[BlockType[2]] / 2; 202 BlockNum < BlocksToSendMap[BlockType[2]]; 203 BlockNum++) { 204 /* block address */ 205 Block8x8 = BlockAddressMap[BlockType[2]][BlockNum]; 206 /* block type */ 207 blockType = BlockType[Block8x8]; 208 209 InterBlockCmd = 0; 210 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, INTER_PRED_BLOCK_SIZE, blockType); 211 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, REF_INDEX_A_VALID, 1); 212 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, REF_INDEX_A, DpbIdx[Block8x8]); 213 214 /* send commands */ 215 h264_pollForSpaceForNCommands(1 + VectorsToSendMap[blockType]); 216 psb_deblock_reg_table_set(MSVDX_CMDS, INTER_BLOCK_PREDICTION_ABOVE1, Block8x8, InterBlockCmd); 217 218 for (i = 0; i < VectorsToSendMap[blockType]; i++) { 219 /* only send forward MVs in baseline */ 220 MvAddr = (2 * 4 * Block8x8) + VectorOffsetMap[blockType][i]; 221 Mv = (4 * Block8x8) + VectorOffsetMap[blockType][i]; 222 psb_deblock_reg_table_set(MSVDX_CMDS, MOTION_VECTOR_ABOVE1, MvAddr, MotionVecCmd[Mv]); 223 } 224 } 225 } 226 227 void 228 h264_currentInterBlockSequence(psb_cmdbuf_p cmdbuf, uint8_t * MbData) 229 { 230 uint32_t i, BlockNum, Mv, MvAddr, Value; 231 uint32_t Block8x8, blockType; 232 uint32_t InterBlockCmd; 233 uint32_t MotionVecCmd[16]; 234 uint32_t BlockType[4]; 235 uint32_t DpbIdx[4]; 236 237 /* set MV vars to 0 */ 238 for (i = 0; i < 16; i++) { 239 MotionVecCmd[i] = 0; 240 } 241 242 /* read block size */ 243 BlockType[0] = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK0_PREDICTION_SIZE); 244 BlockType[1] = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK1_PREDICTION_SIZE); 245 BlockType[2] = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK2_PREDICTION_SIZE); 246 BlockType[3] = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK3_PREDICTION_SIZE); 247 248 /* read motion vectors in all 16 4x4 sub-blocks*/ 249 for (i = 1; i < 3; i++) { /* get blocks 11 and 14 */ 250 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_X_ABOVE, i); 251 REGIO_WRITE_FIELD(MotionVecCmd[CurrentAboveTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_X, Value); 252 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_Y_ABOVE, i); 253 REGIO_WRITE_FIELD(MotionVecCmd[CurrentAboveTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_Y, Value); 254 } 255 for (i = 0; i < 14; i++) { 256 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_X_COL, i); 257 REGIO_WRITE_FIELD(MotionVecCmd[CurrentColTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_X, Value); 258 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_Y_COL, i); 259 REGIO_WRITE_FIELD(MotionVecCmd[CurrentColTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_Y, Value); 260 } 261 262 /* read DPB index for all 4 blocks */ 263 for (i = 0; i < 4; i++) { 264 DpbIdx[ColBlockMap[i]] = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_DPB_IDX_COL, i); 265 } 266 267 /* Send commands required blocks */ 268 for (BlockNum = 0; 269 BlockNum < BlocksToSendMap[BlockType[0]]; 270 BlockNum++) { 271 /* block address */ 272 Block8x8 = BlockAddressMap[BlockType[0]][BlockNum]; 273 /* block type */ 274 blockType = BlockType[Block8x8]; 275 276 InterBlockCmd = 0; 277 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, INTER_PRED_BLOCK_SIZE, blockType); 278 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, REF_INDEX_A_VALID, 1); 279 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, REF_INDEX_A, DpbIdx[Block8x8]); 280 281 /* send commands */ 282 h264_pollForSpaceForNCommands(1 + VectorsToSendMap[blockType]); 283 psb_deblock_reg_table_set(MSVDX_CMDS, INTER_BLOCK_PREDICTION, Block8x8, InterBlockCmd); 284 285 for (i = 0; i < VectorsToSendMap[blockType]; i++) { 286 /* only send forward MVs in baseline */ 287 MvAddr = (2 * 4 * Block8x8) + VectorOffsetMap[blockType][i]; 288 Mv = (4 * Block8x8) + VectorOffsetMap[blockType][i]; 289 psb_deblock_reg_table_set(MSVDX_CMDS, MOTION_VECTOR, MvAddr, MotionVecCmd[Mv]); 290 } 291 } 292 } 293 294 void 295 h264_currentIntraBlockPrediction(psb_cmdbuf_p cmdbuf, uint8_t * MbData, int bMbIsIPCM) 296 { 297 uint32_t BlockSizeY, BlockSizeC; 298 uint32_t IntraCmdY, IntraCmdC; 299 300 /* select block size I_PCM or I_16x16 */ 301 BlockSizeY = (1 == bMbIsIPCM) ? 3 : 0; 302 /* select block size I_PCM or I_8x8 */ 303 BlockSizeC = (1 == bMbIsIPCM) ? 3 : 1; 304 305 IntraCmdY = IntraCmdC = 0; 306 307 REGIO_WRITE_FIELD( 308 IntraCmdY, 309 MSVDX_CMDS, INTRA_BLOCK_PREDICTION, 310 INTRA_PRED_BLOCK_SIZE, 311 BlockSizeY); 312 REGIO_WRITE_FIELD( 313 IntraCmdC, 314 MSVDX_CMDS, INTRA_BLOCK_PREDICTION, 315 INTRA_PRED_BLOCK_SIZE, 316 BlockSizeC); 317 318 h264_pollForSpaceForNCommands(2); 319 psb_deblock_reg_table_set(MSVDX_CMDS, INTRA_BLOCK_PREDICTION, 0, IntraCmdY); 320 psb_deblock_reg_table_set(MSVDX_CMDS, INTRA_BLOCK_PREDICTION, 4, IntraCmdC); 321 } 322 323 void 324 h264_above1IntraBlockPrediction(psb_cmdbuf_p cmdbuf, uint8_t * MbData, int bMbIsIPCM) 325 { 326 uint32_t BlockSizeY; 327 uint32_t IntraCmdY; 328 329 /* select block size I_PCM or I_16x16 */ 330 BlockSizeY = (1 == bMbIsIPCM) ? 3 : 0; 331 IntraCmdY = 0; 332 333 REGIO_WRITE_FIELD( 334 IntraCmdY, 335 MSVDX_CMDS, INTRA_BLOCK_PREDICTION_ABOVE1, 336 INTRA_PRED_BLOCK_SIZE_ABOVE1, 337 BlockSizeY); 338 339 h264_pollForSpaceForNCommands(1); 340 psb_deblock_reg_table_set(MSVDX_CMDS, INTRA_BLOCK_PREDICTION_ABOVE1, 0, IntraCmdY); 341 } 342 343 void 344 h264_macroblockCmdSequence(psb_cmdbuf_p cmdbuf, uint8_t * MbData, uint32_t X, uint32_t Y, int bCurrent) 345 { 346 int bMbIsIPCM; 347 uint32_t MbType; 348 uint32_t Value; 349 uint32_t MbNumberCmd, MbQuantCmd, MbTransZeroCmd; 350 351 /* Macroblock Type */ 352 MbType = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_MBTYPE); 353 354 /* Macroblock Number */ 355 /* no need for MB_ERROR_FLAG as error info is not stored */ 356 /* no need for MB_FIELD_CODE as basline is always frame based */ 357 MbNumberCmd = 0; 358 359 Value = (3 == MbType) ? 0 : MbType; 360 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_CODE_TYPE, Value); 361 362 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_NO_Y, Y); 363 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_NO_X, X); 364 365 /* H264 Quant */ 366 /* TRANSFORM_SIZE_8X8 always false in basline */ 367 MbQuantCmd = 0; 368 369 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_QP_CR); 370 REGIO_WRITE_FIELD(MbQuantCmd, MSVDX_CMDS, MACROBLOCK_H264_QUANT, MB_QUANT_CHROMA_CR, Value); 371 372 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_QP_CB); 373 REGIO_WRITE_FIELD(MbQuantCmd, MSVDX_CMDS, MACROBLOCK_H264_QUANT, MB_QUANT_CHROMA_CB, Value); 374 375 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_QP); 376 REGIO_WRITE_FIELD(MbQuantCmd, MSVDX_CMDS, MACROBLOCK_H264_QUANT, MB_QUANT_LUMA, Value); 377 378 /* send 2 commands */ 379 h264_pollForSpaceForNCommands(2); 380 if (1 == bCurrent) { 381 /* Top and Left available flags are only sent for current MB */ 382 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_MB_AVAILABLE_TOP_FLAG); 383 Value = (1 == Value) ? 0 : 1; 384 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_SLICE_TOP, Value); 385 386 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_MB_AVAILABLE_LEFT_FLAG); 387 Value = (1 == Value) ? 0 : 1; 388 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_SLICE_LHS, Value); 389 390 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_NUMBER, MbNumberCmd); 391 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_H264_QUANT, MbQuantCmd); 392 } else { 393 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_NUMBER_ABOVE1, MbNumberCmd); 394 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_H264_QUANT_ABOVE1, MbQuantCmd); 395 } 396 397 /* Prediction Block Sequence */ 398 bMbIsIPCM = 0; 399 switch (MbType) { 400 case 3: /* IPCM */ 401 bMbIsIPCM = 1; 402 /* deliberate drop through */ 403 case 0: /* I */ 404 if (1 == bCurrent) { 405 h264_currentIntraBlockPrediction(cmdbuf, MbData, bMbIsIPCM); 406 } else { 407 h264_above1IntraBlockPrediction(cmdbuf, MbData, bMbIsIPCM); 408 } 409 break; 410 case 1: /* P */ 411 if (1 == bCurrent) { 412 h264_currentInterBlockSequence(cmdbuf, MbData); 413 } else { 414 h264_above1InterBlockSequence(cmdbuf, MbData); 415 } 416 break; 417 case 2: /* B */ 418 default: 419 /* invalid MB type */ 420 //IMG_ASSERT( 0 ); 421 break; 422 } 423 424 /* Trasform Zero */ 425 MbTransZeroCmd = 0; 426 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_MB_TRANSFORM_ZERO); 427 REGIO_WRITE_FIELD(MbTransZeroCmd, MSVDX_CMDS, MACROBLOCK_BLOCK_TRANSFORM_ZERO, MB_BLOCK_TRANSFORM_ZERO, Value); 428 429 /* write last command */ 430 h264_pollForSpaceForNCommands(1); 431 if (1 == bCurrent) { 432 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_BLOCK_TRANSFORM_ZERO, MbTransZeroCmd); 433 } else { 434 MbTransZeroCmd &= 0x0000CC00; /* only send for sub-blocks 10,11,14 and 15 */ 435 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_BLOCK_TRANSFORM_ZERO_ABOVE1, MbTransZeroCmd); 436 } 437 } 438 439 uint32_t 440 h264_getCurrentSliceCmd(uint8_t* MbData) 441 { 442 uint32_t Value, Cmd; 443 444 Cmd = 0; 445 446 /* unpack data from stored MB + repack in command */ 447 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_DISABLE_DEBLOCK_FILTER_IDC); 448 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, DISABLE_DEBLOCK_FILTER_IDC, Value); 449 450 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_H264_BE_SLICE0_ALPHA_CO_OFFSET_DIV2); 451 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_ALPHA_CO_OFFSET_DIV2, Value); 452 453 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_H264_BE_SLICE0_BETA_OFFSET_DIV2); 454 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_BETA_OFFSET_DIV2, Value); 455 456 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_H264_BE_SLICE0_FIELD_TYPE); 457 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE, Value); 458 459 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_H264_BE_SLICE0_CODE_TYPE); 460 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, Value); 461 462 return Cmd; 463 } 464 465 int h264_secondPass( 466 psb_cmdbuf_p cmdbuf, 467 uint8_t * MbData, 468 uint32_t OperatingModeCmd, 469 uint32_t Width, 470 uint32_t Height 471 ) 472 { 473 uint32_t i, PicSize; 474 uint32_t EndOfPictureCmd; 475 uint32_t EndOfSliceCmd; 476 uint32_t SliceCmd, OldSliceCmd; 477 uint32_t EnableReg; 478 uint8_t * CurrMb; 479 uint8_t * Above1Mb; 480 int bRetCode = 0; 481 482 PicSize = Width * Height; 483 484 /* End of Slice command */ 485 EndOfSliceCmd = 0; 486 REGIO_WRITE_FIELD(EndOfSliceCmd, MSVDX_CMDS, END_SLICE_PICTURE, PICTURE_END, 0); 487 488 489 /* put vdeb into second pass mode */ 490 /* send operating mode command for VDEB only */ 491 REGIO_WRITE_FIELD(OperatingModeCmd, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 2); /* VDEB only */ 492 h264_pollForSpaceForNCommands(1); 493 psb_deblock_reg_get(MSVDX_CORE, CR_MSVDX_COMMAND_SPACE); 494 psb_deblock_reg_set(MSVDX_CMDS, OPERATING_MODE, OperatingModeCmd); 495 496 PollForSpaceForXCommands; 497 498 /* Send Slice Command */ 499 SliceCmd = h264_getCurrentSliceCmd(MbData); 500 h264_pollForSpaceForNCommands(2); 501 psb_deblock_reg_set(MSVDX_CMDS, SLICE_PARAMS, SliceCmd); 502 psb_deblock_reg_set(MSVDX_CMDS, SLICE_PARAMS_ABOVE1, SliceCmd); 503 /* process top row */ 504 for (i = 0, CurrMb = MbData; 505 i < Width; 506 i++, CurrMb += H264_MACROBLOCK_DATA_SIZE) { 507 OldSliceCmd = SliceCmd; 508 SliceCmd = h264_getCurrentSliceCmd(CurrMb); 509 if (OldSliceCmd != SliceCmd) { 510 h264_pollForSpaceForNCommands(2); 511 psb_deblock_reg_set(MSVDX_CMDS, END_SLICE_PICTURE, EndOfSliceCmd); 512 psb_deblock_reg_set(MSVDX_CMDS, SLICE_PARAMS, SliceCmd); 513 } 514 515 h264_macroblockCmdSequence(cmdbuf, CurrMb, i, 0, 1); 516 } 517 518 /* process rest of picture */ 519 for (Above1Mb = MbData; 520 i < PicSize; 521 i++, CurrMb += H264_MACROBLOCK_DATA_SIZE, Above1Mb += H264_MACROBLOCK_DATA_SIZE) { 522 OldSliceCmd = SliceCmd; 523 SliceCmd = h264_getCurrentSliceCmd(CurrMb); 524 if (OldSliceCmd != SliceCmd) { 525 h264_pollForSpaceForNCommands(2); 526 psb_deblock_reg_set(MSVDX_CMDS, END_SLICE_PICTURE, EndOfSliceCmd); 527 psb_deblock_reg_set(MSVDX_CMDS, SLICE_PARAMS, SliceCmd); 528 } 529 530 h264_macroblockCmdSequence(cmdbuf, Above1Mb, (i % Width), (i / Width) - 1, 0); 531 h264_macroblockCmdSequence(cmdbuf, CurrMb, (i % Width), (i / Width), 1); 532 } 533 534 /* send end of pic + restart back end */ 535 EndOfPictureCmd = 0; 536 EnableReg = 0; 537 REGIO_WRITE_FIELD(EndOfPictureCmd, MSVDX_CMDS, END_SLICE_PICTURE, PICTURE_END, 1); 538 REGIO_WRITE_FIELD(EnableReg, MSVDX_VEC, CR_VEC_CONTROL, ENTDEC_ENABLE_BE, 1); 539 540 h264_pollForSpaceForNCommands(2); 541 psb_deblock_reg_set(MSVDX_CMDS, END_SLICE_PICTURE, EndOfSliceCmd); 542 psb_deblock_reg_set(MSVDX_CMDS, END_SLICE_PICTURE, EndOfPictureCmd); 543 //psb_deblock_reg_set( MSVDX_VEC, CR_VEC_CONTROL, EnableReg); /* this is not a command */ 544 return bRetCode; 545 } 546 547 int psb_cmdbuf_second_pass(object_context_p obj_context, 548 uint32_t OperatingModeCmd, 549 unsigned char * pvParamBase, 550 uint32_t PicWidthInMbs, 551 uint32_t FrameHeightInMbs, 552 psb_buffer_p target_buffer, 553 uint32_t chroma_offset 554 ) 555 { 556 int bRetVal = 1; 557 uint32_t Cmd, item_loc; 558 uint32_t *cmd_size; 559 psb_cmdbuf_p cmdbuf = obj_context->cmdbuf; 560 561 if (psb_buffer_map(&cmdbuf->regio_buf, &cmdbuf->regio_base)) { 562 //printf("map cmdbuf->regio_buf error\n"); 563 return bRetVal; 564 } 565 566 item_loc = psb_cmdbuf_buffer_ref(cmdbuf, &cmdbuf->regio_buf); 567 568 cmdbuf->regio_idx = (uint32_t *)cmdbuf->regio_base; 569 cmd_size = cmdbuf->regio_idx++; 570 571 h264_pollForSpaceForNCommands(4); 572 573 psb_deblock_reg_set_RELOC(MSVDX_CMDS, LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES, target_buffer, target_buffer->buffer_ofs, item_loc); 574 psb_deblock_reg_set_RELOC(MSVDX_CMDS, CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES, target_buffer, target_buffer->buffer_ofs + chroma_offset, item_loc); 575 576 Cmd = 0; 577 REGIO_WRITE_FIELD_LITE(Cmd, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, (FrameHeightInMbs * 16) - 1); 578 REGIO_WRITE_FIELD_LITE(Cmd, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, (PicWidthInMbs * 16) - 1); 579 psb_deblock_reg_set(MSVDX_CMDS, DISPLAY_PICTURE_SIZE, Cmd); 580 581 582 Cmd = 0; 583 REGIO_WRITE_FIELD_LITE(Cmd, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_HEIGHT, (FrameHeightInMbs * 16) - 1); 584 REGIO_WRITE_FIELD_LITE(Cmd, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_WIDTH, (PicWidthInMbs * 16) - 1); 585 psb_deblock_reg_set(MSVDX_CMDS, CODED_PICTURE_SIZE, Cmd); 586 587 /* BRN25312 */ 588 psb_deblock_reg_set(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS, 0); 589 psb_deblock_reg_set(MSVDX_CMDS, VC1_CHROMA_RANGE_MAPPING_BASE_ADDRESS, 0); 590 psb_deblock_reg_set(MSVDX_CMDS, VC1_RANGE_MAPPING_FLAGS, 0); 591 592 /* process second pass */ 593 bRetVal = h264_secondPass(cmdbuf, 594 (uint8_t*)pvParamBase, 595 OperatingModeCmd, 596 PicWidthInMbs, 597 FrameHeightInMbs); 598 599 *cmd_size = (cmdbuf->regio_idx - (uint32_t *)cmdbuf->regio_base - 1); 600 601 drv_debug_msg(VIDEO_DEBUG_GENERAL, "DEBLOCK: REGIO size is %d\n", (uint32_t)(cmdbuf->regio_idx - (uint32_t *)cmdbuf->regio_base) - 1); 602 //printf("DEBLOCK: REGIO size is %d\n", (uint32_t)(cmdbuf->regio_idx - (uint32_t *)cmdbuf->regio_base) - 1); 603 psb_buffer_unmap(&cmdbuf->regio_buf); 604 return bRetVal; 605 } 606