pnw_MPEG2.c revision 3f3d1e8746d2b793c982ac19a73061e006b1b178
1/* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * Copyright (c) Imagination Technologies Limited, UK 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Waldo Bastian <waldo.bastian@intel.com> 27 * Zeng Li <zeng.li@intel.com> 28 * 29 */ 30 31#include "pnw_MPEG2.h" 32#include "psb_def.h" 33#include "psb_surface.h" 34#include "psb_cmdbuf.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_vec_reg_io2.h" 40#include "hwdefs/msvdx_vec_mpeg2_reg_io2.h" 41#include "hwdefs/dxva_fw_ctrl.h" 42 43#include <stdlib.h> 44#include <stdint.h> 45#include <string.h> 46 47#define GET_SURFACE_INFO_is_defined(psb_surface) ((int) (psb_surface->extra_info[0])) 48#define SET_SURFACE_INFO_is_defined(psb_surface, val) psb_surface->extra_info[0] = (uint32_t) val; 49#define GET_SURFACE_INFO_picture_structure(psb_surface) (psb_surface->extra_info[1]) 50#define SET_SURFACE_INFO_picture_structure(psb_surface, val) psb_surface->extra_info[1] = val; 51#define GET_SURFACE_INFO_picture_coding_type(psb_surface) ((int) (psb_surface->extra_info[2])) 52#define SET_SURFACE_INFO_picture_coding_type(psb_surface, val) psb_surface->extra_info[2] = (uint32_t) val; 53#define SET_SURFACE_INFO_rotate(psb_surface, rotate) psb_surface->extra_info[5] = (uint32_t) rotate; 54#define GET_SURFACE_INFO_rotate(psb_surface) ((int) psb_surface->extra_info[5]) 55 56 57#define SLICEDATA_BUFFER_TYPE(type) ((type==VASliceDataBufferType)?"VASliceDataBufferType":"VAProtectedSliceDataBufferType") 58 59/* 60 * Frame types - format dependant! 61 */ 62#define PICTURE_CODING_I 0x01 63#define PICTURE_CODING_P 0x02 64#define PICTURE_CODING_B 0x03 65/* A special syntax is defined for D-pictures (picture_coding_type = 4). D-pictures are like I-pictures with only Intra-DC coefficients, 66 no End of Block, and a special end_of_macroblock code '1'. PICTURE_CODING_D is not allowed in MPEG2 */ 67#define PICTURE_CODING_D 0x04 68 69/************************************************************************************/ 70/* Variable length codes in 'packed' format */ 71/************************************************************************************/ 72 73/* Format is: opcode, width, symbol. All VLC tables are concatenated. Index */ 74/* infomation is stored in gui16mpeg2VlcIndexData[] */ 75#define VLC_PACK(a,b,c) ( ( (a) << 12 ) | ( (b) << 9 ) | (c) ) 76static const IMG_UINT16 gaui16mpeg2VlcTableDataPacked[] = { 77 VLC_PACK(6 , 0 , 0) , 78 VLC_PACK(0 , 0 , 6) , 79 VLC_PACK(4 , 2 , 4) , 80 VLC_PACK(4 , 3 , 5) , 81 VLC_PACK(4 , 4 , 6) , 82 VLC_PACK(4 , 5 , 7) , 83 VLC_PACK(1 , 1 , 3) , 84 VLC_PACK(4 , 0 , 0) , 85 VLC_PACK(4 , 0 , 3) , 86 VLC_PACK(4 , 0 , 8) , 87 VLC_PACK(4 , 1 , 9) , 88 VLC_PACK(5 , 0 , 5) , 89 VLC_PACK(5 , 0 , 0) , 90 VLC_PACK(4 , 1 , 2) , 91 VLC_PACK(4 , 2 , 3) , 92 VLC_PACK(4 , 3 , 4) , 93 VLC_PACK(4 , 4 , 5) , 94 VLC_PACK(4 , 5 , 6) , 95 VLC_PACK(1 , 2 , 1) , 96 VLC_PACK(4 , 0 , 7) , 97 VLC_PACK(4 , 1 , 8) , 98 VLC_PACK(4 , 2 , 9) , 99 VLC_PACK(5 , 0 , 5) , 100 VLC_PACK(0 , 2 , 16) , 101 VLC_PACK(0 , 1 , 87) , 102 VLC_PACK(2 , 3 , 90) , 103 VLC_PACK(0 , 0 , 98) , 104 VLC_PACK(5 , 0 , 253) , 105 VLC_PACK(5 , 0 , 366) , 106 VLC_PACK(4 , 3 , 380) , 107 VLC_PACK(4 , 3 , 381) , 108 VLC_PACK(4 , 1 , 508) , 109 VLC_PACK(4 , 1 , 508) , 110 VLC_PACK(4 , 1 , 508) , 111 VLC_PACK(4 , 1 , 508) , 112 VLC_PACK(4 , 1 , 509) , 113 VLC_PACK(4 , 1 , 509) , 114 VLC_PACK(4 , 1 , 509) , 115 VLC_PACK(4 , 1 , 509) , 116 VLC_PACK(0 , 4 , 8) , 117 VLC_PACK(0 , 2 , 63) , 118 VLC_PACK(4 , 1 , 255) , 119 VLC_PACK(4 , 1 , 255) , 120 VLC_PACK(5 , 0 , 365) , 121 VLC_PACK(5 , 0 , 470) , 122 VLC_PACK(5 , 0 , 251) , 123 VLC_PACK(5 , 0 , 471) , 124 VLC_PACK(3 , 4 , 0) , 125 VLC_PACK(0 , 1 , 31) , 126 VLC_PACK(0 , 0 , 40) , 127 VLC_PACK(2 , 2 , 41) , 128 VLC_PACK(5 , 2 , 224) , 129 VLC_PACK(5 , 2 , 228) , 130 VLC_PACK(5 , 2 , 232) , 131 VLC_PACK(5 , 2 , 236) , 132 VLC_PACK(5 , 1 , 437) , 133 VLC_PACK(0 , 0 , 39) , 134 VLC_PACK(0 , 0 , 40) , 135 VLC_PACK(0 , 0 , 41) , 136 VLC_PACK(5 , 1 , 241) , 137 VLC_PACK(0 , 0 , 41) , 138 VLC_PACK(5 , 1 , 454) , 139 VLC_PACK(5 , 1 , 456) , 140 VLC_PACK(5 , 0 , 244) , 141 VLC_PACK(5 , 0 , 439) , 142 VLC_PACK(5 , 0 , 348) , 143 VLC_PACK(5 , 0 , 245) , 144 VLC_PACK(5 , 0 , 363) , 145 VLC_PACK(5 , 0 , 325) , 146 VLC_PACK(5 , 0 , 458) , 147 VLC_PACK(5 , 0 , 459) , 148 VLC_PACK(5 , 0 , 246) , 149 VLC_PACK(5 , 0 , 460) , 150 VLC_PACK(5 , 0 , 461) , 151 VLC_PACK(5 , 0 , 186) , 152 VLC_PACK(5 , 0 , 356) , 153 VLC_PACK(5 , 0 , 247) , 154 VLC_PACK(5 , 0 , 333) , 155 VLC_PACK(5 , 0 , 462) , 156 VLC_PACK(5 , 2 , 173) , 157 VLC_PACK(2 , 1 , 3) , 158 VLC_PACK(1 , 1 , 5) , 159 VLC_PACK(5 , 2 , 449) , 160 VLC_PACK(5 , 1 , 432) , 161 VLC_PACK(5 , 0 , 431) , 162 VLC_PACK(5 , 0 , 332) , 163 VLC_PACK(5 , 1 , 434) , 164 VLC_PACK(5 , 0 , 436) , 165 VLC_PACK(5 , 0 , 448) , 166 VLC_PACK(5 , 2 , 215) , 167 VLC_PACK(5 , 2 , 219) , 168 VLC_PACK(5 , 2 , 180) , 169 VLC_PACK(5 , 1 , 178) , 170 VLC_PACK(5 , 0 , 177) , 171 VLC_PACK(5 , 0 , 223) , 172 VLC_PACK(5 , 0 , 340) , 173 VLC_PACK(5 , 0 , 355) , 174 VLC_PACK(5 , 0 , 362) , 175 VLC_PACK(5 , 0 , 184) , 176 VLC_PACK(5 , 0 , 185) , 177 VLC_PACK(5 , 0 , 240) , 178 VLC_PACK(5 , 0 , 243) , 179 VLC_PACK(5 , 0 , 453) , 180 VLC_PACK(5 , 0 , 463) , 181 VLC_PACK(5 , 0 , 341) , 182 VLC_PACK(5 , 0 , 248) , 183 VLC_PACK(5 , 0 , 364) , 184 VLC_PACK(5 , 0 , 187) , 185 VLC_PACK(5 , 0 , 464) , 186 VLC_PACK(5 , 0 , 465) , 187 VLC_PACK(5 , 0 , 349) , 188 VLC_PACK(5 , 0 , 326) , 189 VLC_PACK(5 , 0 , 334) , 190 VLC_PACK(5 , 0 , 189) , 191 VLC_PACK(5 , 0 , 342) , 192 VLC_PACK(5 , 0 , 252) , 193 VLC_PACK(0 , 1 , 4) , 194 VLC_PACK(5 , 1 , 467) , 195 VLC_PACK(5 , 0 , 249) , 196 VLC_PACK(5 , 0 , 466) , 197 VLC_PACK(5 , 0 , 357) , 198 VLC_PACK(5 , 0 , 188) , 199 VLC_PACK(5 , 0 , 250) , 200 VLC_PACK(5 , 0 , 469) , 201 VLC_PACK(5 , 0 , 350) , 202 VLC_PACK(5 , 0 , 358) , 203 VLC_PACK(0 , 2 , 16) , 204 VLC_PACK(0 , 1 , 87) , 205 VLC_PACK(2 , 3 , 90) , 206 VLC_PACK(0 , 0 , 98) , 207 VLC_PACK(5 , 0 , 253) , 208 VLC_PACK(5 , 0 , 366) , 209 VLC_PACK(4 , 3 , 380) , 210 VLC_PACK(4 , 3 , 381) , 211 VLC_PACK(4 , 1 , 254) , 212 VLC_PACK(4 , 1 , 254) , 213 VLC_PACK(4 , 1 , 254) , 214 VLC_PACK(4 , 1 , 254) , 215 VLC_PACK(4 , 2 , 508) , 216 VLC_PACK(4 , 2 , 508) , 217 VLC_PACK(4 , 2 , 509) , 218 VLC_PACK(4 , 2 , 509) , 219 VLC_PACK(0 , 4 , 8) , 220 VLC_PACK(0 , 2 , 63) , 221 VLC_PACK(4 , 1 , 255) , 222 VLC_PACK(4 , 1 , 255) , 223 VLC_PACK(5 , 0 , 365) , 224 VLC_PACK(5 , 0 , 470) , 225 VLC_PACK(5 , 0 , 251) , 226 VLC_PACK(5 , 0 , 471) , 227 VLC_PACK(3 , 4 , 0) , 228 VLC_PACK(0 , 1 , 31) , 229 VLC_PACK(0 , 0 , 40) , 230 VLC_PACK(2 , 2 , 41) , 231 VLC_PACK(5 , 2 , 224) , 232 VLC_PACK(5 , 2 , 228) , 233 VLC_PACK(5 , 2 , 232) , 234 VLC_PACK(5 , 2 , 236) , 235 VLC_PACK(5 , 1 , 437) , 236 VLC_PACK(0 , 0 , 39) , 237 VLC_PACK(0 , 0 , 40) , 238 VLC_PACK(0 , 0 , 41) , 239 VLC_PACK(5 , 1 , 241) , 240 VLC_PACK(0 , 0 , 41) , 241 VLC_PACK(5 , 1 , 454) , 242 VLC_PACK(5 , 1 , 456) , 243 VLC_PACK(5 , 0 , 244) , 244 VLC_PACK(5 , 0 , 439) , 245 VLC_PACK(5 , 0 , 348) , 246 VLC_PACK(5 , 0 , 245) , 247 VLC_PACK(5 , 0 , 363) , 248 VLC_PACK(5 , 0 , 325) , 249 VLC_PACK(5 , 0 , 458) , 250 VLC_PACK(5 , 0 , 459) , 251 VLC_PACK(5 , 0 , 246) , 252 VLC_PACK(5 , 0 , 460) , 253 VLC_PACK(5 , 0 , 461) , 254 VLC_PACK(5 , 0 , 186) , 255 VLC_PACK(5 , 0 , 356) , 256 VLC_PACK(5 , 0 , 247) , 257 VLC_PACK(5 , 0 , 333) , 258 VLC_PACK(5 , 0 , 462) , 259 VLC_PACK(5 , 2 , 173) , 260 VLC_PACK(2 , 1 , 3) , 261 VLC_PACK(1 , 1 , 5) , 262 VLC_PACK(5 , 2 , 449) , 263 VLC_PACK(5 , 1 , 432) , 264 VLC_PACK(5 , 0 , 431) , 265 VLC_PACK(5 , 0 , 332) , 266 VLC_PACK(5 , 1 , 434) , 267 VLC_PACK(5 , 0 , 436) , 268 VLC_PACK(5 , 0 , 448) , 269 VLC_PACK(5 , 2 , 215) , 270 VLC_PACK(5 , 2 , 219) , 271 VLC_PACK(5 , 2 , 180) , 272 VLC_PACK(5 , 1 , 178) , 273 VLC_PACK(5 , 0 , 177) , 274 VLC_PACK(5 , 0 , 223) , 275 VLC_PACK(5 , 0 , 340) , 276 VLC_PACK(5 , 0 , 355) , 277 VLC_PACK(5 , 0 , 362) , 278 VLC_PACK(5 , 0 , 184) , 279 VLC_PACK(5 , 0 , 185) , 280 VLC_PACK(5 , 0 , 240) , 281 VLC_PACK(5 , 0 , 243) , 282 VLC_PACK(5 , 0 , 453) , 283 VLC_PACK(5 , 0 , 463) , 284 VLC_PACK(5 , 0 , 341) , 285 VLC_PACK(5 , 0 , 248) , 286 VLC_PACK(5 , 0 , 364) , 287 VLC_PACK(5 , 0 , 187) , 288 VLC_PACK(5 , 0 , 464) , 289 VLC_PACK(5 , 0 , 465) , 290 VLC_PACK(5 , 0 , 349) , 291 VLC_PACK(5 , 0 , 326) , 292 VLC_PACK(5 , 0 , 334) , 293 VLC_PACK(5 , 0 , 189) , 294 VLC_PACK(5 , 0 , 342) , 295 VLC_PACK(5 , 0 , 252) , 296 VLC_PACK(0 , 1 , 4) , 297 VLC_PACK(5 , 1 , 467) , 298 VLC_PACK(5 , 0 , 249) , 299 VLC_PACK(5 , 0 , 466) , 300 VLC_PACK(5 , 0 , 357) , 301 VLC_PACK(5 , 0 , 188) , 302 VLC_PACK(5 , 0 , 250) , 303 VLC_PACK(5 , 0 , 469) , 304 VLC_PACK(5 , 0 , 350) , 305 VLC_PACK(5 , 0 , 358) , 306 VLC_PACK(2 , 2 , 32) , 307 VLC_PACK(0 , 1 , 87) , 308 VLC_PACK(5 , 1 , 248) , 309 VLC_PACK(0 , 0 , 89) , 310 VLC_PACK(1 , 2 , 90) , 311 VLC_PACK(5 , 0 , 366) , 312 VLC_PACK(5 , 0 , 189) , 313 VLC_PACK(5 , 0 , 358) , 314 VLC_PACK(4 , 3 , 380) , 315 VLC_PACK(4 , 3 , 380) , 316 VLC_PACK(4 , 3 , 381) , 317 VLC_PACK(4 , 3 , 381) , 318 VLC_PACK(4 , 3 , 254) , 319 VLC_PACK(4 , 3 , 254) , 320 VLC_PACK(4 , 4 , 504) , 321 VLC_PACK(4 , 4 , 505) , 322 VLC_PACK(4 , 2 , 508) , 323 VLC_PACK(4 , 2 , 508) , 324 VLC_PACK(4 , 2 , 508) , 325 VLC_PACK(4 , 2 , 508) , 326 VLC_PACK(4 , 2 , 509) , 327 VLC_PACK(4 , 2 , 509) , 328 VLC_PACK(4 , 2 , 509) , 329 VLC_PACK(4 , 2 , 509) , 330 VLC_PACK(4 , 3 , 506) , 331 VLC_PACK(4 , 3 , 506) , 332 VLC_PACK(4 , 3 , 507) , 333 VLC_PACK(4 , 3 , 507) , 334 VLC_PACK(5 , 0 , 251) , 335 VLC_PACK(5 , 0 , 250) , 336 VLC_PACK(0 , 1 , 71) , 337 VLC_PACK(0 , 2 , 74) , 338 VLC_PACK(4 , 0 , 255) , 339 VLC_PACK(0 , 1 , 3) , 340 VLC_PACK(0 , 2 , 8) , 341 VLC_PACK(0 , 3 , 17) , 342 VLC_PACK(5 , 0 , 341) , 343 VLC_PACK(5 , 0 , 465) , 344 VLC_PACK(0 , 0 , 2) , 345 VLC_PACK(5 , 0 , 464) , 346 VLC_PACK(5 , 0 , 363) , 347 VLC_PACK(5 , 0 , 463) , 348 VLC_PACK(5 , 1 , 438) , 349 VLC_PACK(5 , 1 , 348) , 350 VLC_PACK(5 , 1 , 324) , 351 VLC_PACK(5 , 1 , 458) , 352 VLC_PACK(5 , 1 , 459) , 353 VLC_PACK(5 , 1 , 461) , 354 VLC_PACK(5 , 1 , 356) , 355 VLC_PACK(0 , 0 , 1) , 356 VLC_PACK(5 , 0 , 333) , 357 VLC_PACK(5 , 0 , 462) , 358 VLC_PACK(3 , 3 , 0) , 359 VLC_PACK(0 , 1 , 15) , 360 VLC_PACK(0 , 0 , 24) , 361 VLC_PACK(2 , 2 , 25) , 362 VLC_PACK(5 , 2 , 224) , 363 VLC_PACK(5 , 2 , 228) , 364 VLC_PACK(5 , 2 , 232) , 365 VLC_PACK(5 , 2 , 236) , 366 VLC_PACK(5 , 1 , 437) , 367 VLC_PACK(0 , 0 , 23) , 368 VLC_PACK(0 , 0 , 24) , 369 VLC_PACK(5 , 1 , 185) , 370 VLC_PACK(3 , 3 , 0) , 371 VLC_PACK(5 , 1 , 452) , 372 VLC_PACK(5 , 1 , 454) , 373 VLC_PACK(5 , 1 , 456) , 374 VLC_PACK(5 , 2 , 173) , 375 VLC_PACK(2 , 1 , 3) , 376 VLC_PACK(1 , 1 , 5) , 377 VLC_PACK(5 , 2 , 449) , 378 VLC_PACK(5 , 1 , 432) , 379 VLC_PACK(5 , 0 , 431) , 380 VLC_PACK(5 , 0 , 332) , 381 VLC_PACK(5 , 1 , 434) , 382 VLC_PACK(5 , 0 , 436) , 383 VLC_PACK(5 , 0 , 448) , 384 VLC_PACK(5 , 2 , 215) , 385 VLC_PACK(5 , 2 , 219) , 386 VLC_PACK(5 , 2 , 180) , 387 VLC_PACK(5 , 1 , 178) , 388 VLC_PACK(5 , 0 , 177) , 389 VLC_PACK(5 , 0 , 223) , 390 VLC_PACK(5 , 0 , 340) , 391 VLC_PACK(5 , 0 , 355) , 392 VLC_PACK(5 , 0 , 362) , 393 VLC_PACK(5 , 0 , 184) , 394 VLC_PACK(5 , 0 , 326) , 395 VLC_PACK(5 , 0 , 471) , 396 VLC_PACK(5 , 0 , 334) , 397 VLC_PACK(5 , 0 , 365) , 398 VLC_PACK(5 , 0 , 350) , 399 VLC_PACK(5 , 0 , 342) , 400 VLC_PACK(2 , 1 , 4) , 401 VLC_PACK(5 , 1 , 466) , 402 VLC_PACK(5 , 0 , 357) , 403 VLC_PACK(5 , 0 , 187) , 404 VLC_PACK(5 , 1 , 244) , 405 VLC_PACK(5 , 0 , 468) , 406 VLC_PACK(5 , 0 , 186) , 407 VLC_PACK(5 , 0 , 470) , 408 VLC_PACK(5 , 0 , 188) , 409 VLC_PACK(5 , 0 , 469) , 410 VLC_PACK(5 , 0 , 247) , 411 VLC_PACK(4 , 2 , 492) , 412 VLC_PACK(4 , 2 , 493) , 413 VLC_PACK(5 , 0 , 243) , 414 VLC_PACK(5 , 0 , 242) , 415 VLC_PACK(5 , 0 , 364) , 416 VLC_PACK(5 , 0 , 349) , 417 VLC_PACK(5 , 0 , 241) , 418 VLC_PACK(5 , 0 , 240) , 419 VLC_PACK(4 , 0 , 30) , 420 VLC_PACK(5 , 0 , 14) , 421 VLC_PACK(5 , 0 , 13) , 422 VLC_PACK(5 , 0 , 12) , 423 VLC_PACK(0 , 0 , 3) , 424 VLC_PACK(2 , 2 , 4) , 425 VLC_PACK(0 , 1 , 7) , 426 VLC_PACK(5 , 1 , 9) , 427 VLC_PACK(5 , 0 , 11) , 428 VLC_PACK(5 , 0 , 8) , 429 VLC_PACK(5 , 1 , 6) , 430 VLC_PACK(5 , 0 , 5) , 431 VLC_PACK(5 , 1 , 3) , 432 VLC_PACK(3 , 1 , 0) , 433 VLC_PACK(2 , 2 , 3) , 434 VLC_PACK(3 , 1 , 0) , 435 VLC_PACK(2 , 1 , 5) , 436 VLC_PACK(3 , 2 , 0) , 437 VLC_PACK(3 , 2 , 0) , 438 VLC_PACK(3 , 2 , 0) , 439 VLC_PACK(4 , 2 , 226) , 440 VLC_PACK(5 , 1 , 1) , 441 VLC_PACK(5 , 0 , 0) , 442 VLC_PACK(5 , 0 , 31) , 443 VLC_PACK(4 , 0 , 62) , 444 VLC_PACK(5 , 0 , 30) , 445 VLC_PACK(5 , 0 , 29) , 446 VLC_PACK(5 , 0 , 28) , 447 VLC_PACK(0 , 0 , 3) , 448 VLC_PACK(2 , 2 , 4) , 449 VLC_PACK(1 , 1 , 7) , 450 VLC_PACK(5 , 1 , 25) , 451 VLC_PACK(5 , 0 , 27) , 452 VLC_PACK(5 , 0 , 24) , 453 VLC_PACK(5 , 1 , 22) , 454 VLC_PACK(5 , 0 , 21) , 455 VLC_PACK(5 , 1 , 19) , 456 VLC_PACK(3 , 1 , 0) , 457 VLC_PACK(3 , 1 , 0) , 458 VLC_PACK(5 , 2 , 15) 459}; 460 461#define MAX_QUANT_TABLES (2) /* only 2 tables for 4:2:0 decode */ 462 463static int scan0[64] = { // spec, fig 7-2 464 /*u 0 ..... 7*/ 465 0, 1, 5, 6, 14, 15, 27, 28, /* v = 0 */ 466 2, 4, 7, 13, 16, 26, 29, 42, 467 3, 8, 12, 17, 25, 30, 41, 43, 468 9, 11, 18, 24, 31, 40, 44, 53, 469 10, 19, 23, 32, 39, 45, 52, 54, 470 20, 22, 33, 38, 46, 51, 55, 60, 471 21, 34, 37, 47, 50, 56, 59, 61, 472 35, 36, 48, 49, 57, 58, 62, 63 /* v = 7 */ 473}; 474 475typedef enum { 476 NONINTRA_LUMA_Q = 0, 477 INTRA_LUMA_Q = 1 478} QUANT_IDX; 479 480struct context_MPEG2_s { 481 object_context_p obj_context; /* back reference */ 482 483 /* Picture parameters */ 484 VAPictureParameterBufferMPEG2 *pic_params; 485 object_surface_p forward_ref_surface; 486 object_surface_p backward_ref_surface; 487 488 uint32_t coded_picture_width; /* in pixels */ 489 uint32_t coded_picture_height; /* in pixels */ 490 491 uint32_t picture_width_mb; /* in macroblocks */ 492 uint32_t picture_height_mb; /* in macroblocks */ 493 uint32_t size_mb; /* in macroblocks */ 494 495 uint32_t coded_picture_size; /* MSVDX format */ 496 uint32_t display_picture_size; /* MSVDX format */ 497 498 uint32_t BE_PPS0; 499 uint32_t BE_PPS1; 500 uint32_t BE_PPS2; 501 uint32_t BE_SPS0; 502 uint32_t BE_SPS1; 503 uint32_t FE_PPS0; 504 uint32_t FE_PPS1; 505 506 /* IQ Matrix */ 507 uint32_t qmatrix_data[MAX_QUANT_TABLES][16]; 508 int got_iq_matrix; 509 510 /* Split buffers */ 511 int split_buffer_pending; 512 513 /* List of VASliceParameterBuffers */ 514 object_buffer_p *slice_param_list; 515 int slice_param_list_size; 516 int slice_param_list_idx; 517 518 /* VLC packed data */ 519 struct psb_buffer_s vlc_packed_table; 520 521 /* Misc */ 522 unsigned int previous_slice_vertical_position; 523 524 uint32_t *p_range_mapping_base0; 525 uint32_t *p_range_mapping_base1; 526 uint32_t *p_slice_params; /* pointer to ui32SliceParams in CMD_HEADER */ 527 uint32_t *slice_first_pic_last; 528}; 529 530typedef struct context_MPEG2_s *context_MPEG2_p; 531 532#define INIT_CONTEXT_MPEG2 context_MPEG2_p ctx = (context_MPEG2_p) obj_context->format_data; 533 534#define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id )) 535 536 537static void pnw_MPEG2_QueryConfigAttributes( 538 VAProfile profile, 539 VAEntrypoint entrypoint, 540 VAConfigAttrib *attrib_list, 541 int num_attribs) 542{ 543 /* No MPEG2 specific attributes */ 544} 545 546static VAStatus pnw_MPEG2_ValidateConfig( 547 object_config_p obj_config) 548{ 549 int i; 550 /* Check all attributes */ 551 for (i = 0; i < obj_config->attrib_count; i++) { 552 switch (obj_config->attrib_list[i].type) { 553 case VAConfigAttribRTFormat: 554 /* Ignore */ 555 break; 556 557 default: 558 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 559 } 560 } 561 562 return VA_STATUS_SUCCESS; 563} 564 565static VAStatus psb__MPEG2_check_legal_picture(object_context_p obj_context, object_config_p obj_config) 566{ 567 VAStatus vaStatus = VA_STATUS_SUCCESS; 568 569 if (NULL == obj_context) { 570 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 571 DEBUG_FAILURE; 572 return vaStatus; 573 } 574 575 if (NULL == obj_config) { 576 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 577 DEBUG_FAILURE; 578 return vaStatus; 579 } 580 581 /* MSVDX decode capability for MPEG2: 582 * MP@HL 583 * 584 * Refer to Table 8-11 (Upper bounds for luminance sample rate) of ISO/IEC 13818-2: 1995(E), 585 * and the "MSVDX MPEG2 decode capability" table of "Poulsbo Media Software Overview" 586 */ 587 588 switch (obj_config->profile) { 589 case VAProfileMPEG2Simple: 590 if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 352) 591 || (obj_context->picture_height <= 0) || (obj_context->picture_height > 288)) { 592 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 593 } 594 break; 595 596 case VAProfileMPEG2Main: 597 if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 1920) 598 || (obj_context->picture_height <= 0) || (obj_context->picture_height > 1088)) { 599 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 600 } 601 break; 602 603 default: 604 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 605 break; 606 } 607 608 return vaStatus; 609} 610 611static void pnw_MPEG2_DestroyContext(object_context_p obj_context); 612 613static VAStatus pnw_MPEG2_CreateContext( 614 object_context_p obj_context, 615 object_config_p obj_config) 616{ 617 VAStatus vaStatus = VA_STATUS_SUCCESS; 618 context_MPEG2_p ctx; 619 /* Validate flag */ 620 /* Validate picture dimensions */ 621 vaStatus = psb__MPEG2_check_legal_picture(obj_context, obj_config); 622 if (VA_STATUS_SUCCESS != vaStatus) { 623 DEBUG_FAILURE; 624 return vaStatus; 625 } 626 627 if (obj_context->num_render_targets < 1) { 628 vaStatus = VA_STATUS_ERROR_UNKNOWN; 629 DEBUG_FAILURE; 630 return vaStatus; 631 } 632 ctx = (context_MPEG2_p) calloc(1, sizeof(struct context_MPEG2_s)); 633 if (NULL == ctx) { 634 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 635 DEBUG_FAILURE; 636 return vaStatus; 637 } 638 639 obj_context->format_data = (void*) ctx; 640 ctx->obj_context = obj_context; 641 ctx->pic_params = NULL; 642 ctx->got_iq_matrix = FALSE; 643 ctx->previous_slice_vertical_position = ~1; 644 645 ctx->split_buffer_pending = FALSE; 646 647 ctx->slice_param_list_size = 8; 648 ctx->slice_param_list = (object_buffer_p*) calloc(1, sizeof(object_buffer_p) * ctx->slice_param_list_size); 649 ctx->slice_param_list_idx = 0; 650 651 if (NULL == ctx->slice_param_list) { 652 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 653 DEBUG_FAILURE; 654 } 655 656 if (vaStatus == VA_STATUS_SUCCESS) { 657 vaStatus = psb_buffer_create(obj_context->driver_data, 658 sizeof(gaui16mpeg2VlcTableDataPacked), 659 psb_bt_cpu_vpu, 660 &ctx->vlc_packed_table); 661 DEBUG_FAILURE; 662 } 663 if (vaStatus == VA_STATUS_SUCCESS) { 664 unsigned char *vlc_packed_data_address; 665 if (0 == psb_buffer_map(&ctx->vlc_packed_table, &vlc_packed_data_address)) { 666 memcpy(vlc_packed_data_address, gaui16mpeg2VlcTableDataPacked, sizeof(gaui16mpeg2VlcTableDataPacked)); 667 psb_buffer_unmap(&ctx->vlc_packed_table); 668 } else { 669 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 670 DEBUG_FAILURE; 671 } 672 } 673 674 if (vaStatus != VA_STATUS_SUCCESS) { 675 pnw_MPEG2_DestroyContext(obj_context); 676 } 677 678 return vaStatus; 679} 680 681static void pnw_MPEG2_DestroyContext( 682 object_context_p obj_context) 683{ 684 INIT_CONTEXT_MPEG2 685 686 psb_buffer_destroy(&ctx->vlc_packed_table); 687 688 if (ctx->pic_params) { 689 free(ctx->pic_params); 690 ctx->pic_params = NULL; 691 } 692 693 if (ctx->slice_param_list) { 694 free(ctx->slice_param_list); 695 ctx->slice_param_list = NULL; 696 } 697 698 free(obj_context->format_data); 699 obj_context->format_data = NULL; 700} 701 702static VAStatus psb__MPEG2_process_picture_param(context_MPEG2_p ctx, object_buffer_p obj_buffer) 703{ 704 ASSERT(obj_buffer->type == VAPictureParameterBufferType); 705 ASSERT(obj_buffer->num_elements == 1); 706 ASSERT(obj_buffer->size == sizeof(VAPictureParameterBufferMPEG2)); 707 708 if ((obj_buffer->num_elements != 1) || 709 (obj_buffer->size != sizeof(VAPictureParameterBufferMPEG2))) { 710 return VA_STATUS_ERROR_UNKNOWN; 711 } 712 713 /* Transfer ownership of VAPictureParameterBufferMPEG2 data */ 714 if (ctx->pic_params) { 715 free(ctx->pic_params); 716 } 717 ctx->pic_params = (VAPictureParameterBufferMPEG2 *) obj_buffer->buffer_data; 718 obj_buffer->buffer_data = NULL; 719 obj_buffer->size = 0; 720 721 /* Lookup surfaces for backward/forward references */ 722 switch (ctx->pic_params->picture_coding_type) { 723 case PICTURE_CODING_I: 724 ctx->forward_ref_surface = NULL; 725 ctx->backward_ref_surface = NULL; 726 break; 727 728 case PICTURE_CODING_P: 729 ctx->forward_ref_surface = SURFACE(ctx->pic_params->forward_reference_picture); 730 ctx->backward_ref_surface = NULL; 731 if (NULL == ctx->forward_ref_surface) { 732 return VA_STATUS_ERROR_INVALID_SURFACE; 733 } 734 break; 735 736 case PICTURE_CODING_B: 737 ctx->forward_ref_surface = SURFACE(ctx->pic_params->forward_reference_picture); 738 ctx->backward_ref_surface = SURFACE(ctx->pic_params->backward_reference_picture); 739 if ((NULL == ctx->forward_ref_surface) || 740 (NULL == ctx->backward_ref_surface)) { 741 return VA_STATUS_ERROR_INVALID_SURFACE; 742 } 743 break; 744 745 default: 746 return VA_STATUS_ERROR_UNKNOWN; 747 } 748 749 ctx->picture_width_mb = (ctx->pic_params->horizontal_size + 15) / 16; 750 if (ctx->obj_context->va_flags & VA_PROGRESSIVE) { 751 ctx->picture_height_mb = (ctx->pic_params->vertical_size + 15) / 16; 752 } else { 753 ctx->picture_height_mb = (ctx->pic_params->vertical_size + 31) / 32; 754 ctx->picture_height_mb *= 2; 755 } 756 ctx->coded_picture_width = ctx->picture_width_mb * 16; 757 ctx->coded_picture_height = ctx->picture_height_mb * 16; 758 759 ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb; 760 761 /* Display picture size */ 762 ctx->display_picture_size = 0; 763 /* 764 * coded_picture_width/height is aligned to the size of a macroblock.. 765 * Both coded_picture_height or vertical_size can be used for DISPLAY_SIZE and both give correct results, 766 * however Vista driver / test app uses the aligned value that's in coded_picture_height so we do too. 767 * See e.g. low4.m2v for an example clip where vertical_size will differ from coded_picture_height 768 */ 769#if 0 770 REGIO_WRITE_FIELD_LITE(ctx->display_picture_size, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, ctx->pic_params->vertical_size - 1); 771 REGIO_WRITE_FIELD_LITE(ctx->display_picture_size, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, ctx->pic_params->horizontal_size - 1); 772#else 773 REGIO_WRITE_FIELD_LITE(ctx->display_picture_size, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, ctx->coded_picture_height - 1); 774 REGIO_WRITE_FIELD_LITE(ctx->display_picture_size, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, ctx->coded_picture_width - 1); 775#endif 776 777 /* Coded picture size */ 778 ctx->coded_picture_size = 0; 779 REGIO_WRITE_FIELD_LITE(ctx->coded_picture_size, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_HEIGHT, ctx->coded_picture_height - 1); 780 REGIO_WRITE_FIELD_LITE(ctx->coded_picture_size, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_WIDTH, ctx->coded_picture_width - 1); 781 782 ctx->BE_SPS0 = 0; 783 REGIO_WRITE_FIELD_LITE(ctx->BE_SPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_SPS0, BE_HORIZONTAL_SIZE_MINUS1, ctx->picture_width_mb - 1); 784 785 ctx->BE_SPS1 = 0; 786 REGIO_WRITE_FIELD_LITE(ctx->BE_SPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_SPS1, BE_VERTICAL_SIZE_MINUS1, ctx->picture_height_mb); 787 788 ctx->FE_PPS0 = 0; 789 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_ALTERNATE_SCAN, !!(ctx->pic_params->picture_coding_extension.bits.alternate_scan)); 790 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_Q_SCALE_TYPE, !!(ctx->pic_params->picture_coding_extension.bits.q_scale_type)); 791 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_INTRA_DC_PRECISION, ctx->pic_params->picture_coding_extension.bits.intra_dc_precision); 792 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_TOP_FIELD_FIRST, !!(ctx->pic_params->picture_coding_extension.bits.top_field_first)); 793 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_CONCEALMENT_MOTION_VECTORS, !!(ctx->pic_params->picture_coding_extension.bits.concealment_motion_vectors)); 794 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_FRAME_PRED_FRAME_DCT, !!(ctx->pic_params->picture_coding_extension.bits.frame_pred_frame_dct)); 795 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_PICTURE_STRUCTURE, ctx->pic_params->picture_coding_extension.bits.picture_structure); 796 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_INTRA_VLC_FORMAT, !!(ctx->pic_params->picture_coding_extension.bits.intra_vlc_format)); 797 798 ctx->FE_PPS1 = 0; 799 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_PICTURE_CODING_TYPE, ctx->pic_params->picture_coding_type); 800 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_F_CODE00, (ctx->pic_params->f_code >> 12) & 0x0F); 801 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_F_CODE01, (ctx->pic_params->f_code >> 8) & 0x0F); 802 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_F_CODE10, (ctx->pic_params->f_code >> 4) & 0x0F); 803 REGIO_WRITE_FIELD_LITE(ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_F_CODE11, (ctx->pic_params->f_code >> 0) & 0x0F); 804 805 /* VEC Control register: Back-End MPEG2 PPS0 */ 806 ctx->BE_PPS0 = 0; 807 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS0, BE_FRAME_PRED_FRAME_DCT, !!(ctx->pic_params->picture_coding_extension.bits.frame_pred_frame_dct)); 808 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS0, BE_INTRA_DC_PRECISION, ctx->pic_params->picture_coding_extension.bits.intra_dc_precision); 809 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS0, BE_Q_SCALE_TYPE, !!(ctx->pic_params->picture_coding_extension.bits.q_scale_type)); 810 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS0, BE_ALTERNATE_SCAN, !!(ctx->pic_params->picture_coding_extension.bits.alternate_scan)); 811 812 ctx->BE_PPS1 = 0; 813 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS1, BE_F_CODE00, (ctx->pic_params->f_code >> 12) & 0x0F); 814 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS1, BE_F_CODE01, (ctx->pic_params->f_code >> 8) & 0x0F); 815 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS1, BE_F_CODE10, (ctx->pic_params->f_code >> 4) & 0x0F); 816 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS1, BE_F_CODE11, (ctx->pic_params->f_code >> 0) & 0x0F); 817 818 /* VEC Control register: Back-End MPEG2 PPS2 */ 819 ctx->BE_PPS2 = 0; 820 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS2, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS2, BE_PICTURE_CODING_TYPE, ctx->pic_params->picture_coding_type); 821 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS2, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS2, BE_TOP_FIELD_FIRST, !!(ctx->pic_params->picture_coding_extension.bits.top_field_first)); 822 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS2, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS2, BE_CONCEALMENT_MOTION_VECTORS, !!(ctx->pic_params->picture_coding_extension.bits.concealment_motion_vectors)); 823 REGIO_WRITE_FIELD_LITE(ctx->BE_PPS2, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS2, BE_PICTURE_STRUCTURE, ctx->pic_params->picture_coding_extension.bits.picture_structure); 824 825 ctx->obj_context->operating_mode = 0; 826 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CHROMA_INTERLEAVED, 0); 827 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, ctx->obj_context->current_render_target->psb_surface->stride_mode); 828 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, 1); /* MPEG2 profile */ 829 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 3); /* MPEG2 mode */ 830 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1); /* VDMC only */ 831 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1); 832 833 return VA_STATUS_SUCCESS; 834} 835 836static void psb__MPEG2_convert_iq_matrix(uint32_t *dest32, unsigned char *src) 837{ 838 int i; 839 int *idx = scan0; 840 uint8_t *dest8 = (uint8_t*) dest32; 841 842 for (i = 0; i < 64; i++) { 843 *dest8++ = src[*idx++]; 844 } 845} 846 847static VAStatus psb__MPEG2_process_iq_matrix(context_MPEG2_p ctx, object_buffer_p obj_buffer) 848{ 849 VAIQMatrixBufferMPEG2 *iq_matrix = (VAIQMatrixBufferMPEG2 *) obj_buffer->buffer_data; 850 ASSERT(obj_buffer->type == VAIQMatrixBufferType); 851 ASSERT(obj_buffer->num_elements == 1); 852 ASSERT(obj_buffer->size == sizeof(VAIQMatrixBufferMPEG2)); 853 854 if ((obj_buffer->num_elements != 1) || 855 (obj_buffer->size != sizeof(VAIQMatrixBufferMPEG2))) { 856 return VA_STATUS_ERROR_UNKNOWN; 857 } 858 859 /* Only update the qmatrix data if the load flag is set */ 860 if (iq_matrix->load_non_intra_quantiser_matrix) { 861 psb__MPEG2_convert_iq_matrix(ctx->qmatrix_data[NONINTRA_LUMA_Q], iq_matrix->non_intra_quantiser_matrix); 862 } 863 if (iq_matrix->load_intra_quantiser_matrix) { 864 psb__MPEG2_convert_iq_matrix(ctx->qmatrix_data[INTRA_LUMA_Q], iq_matrix->intra_quantiser_matrix); 865 } 866 /* We ignore the Chroma tables because those are not supported with VA_RT_FORMAT_YUV420 */ 867 ctx->got_iq_matrix = TRUE; 868 869 return VA_STATUS_SUCCESS; 870} 871 872/* 873 * Adds a VASliceParameterBuffer to the list of slice params 874 */ 875static VAStatus psb__MPEG2_add_slice_param(context_MPEG2_p ctx, object_buffer_p obj_buffer) 876{ 877 ASSERT(obj_buffer->type == VASliceParameterBufferType); 878 if (ctx->slice_param_list_idx >= ctx->slice_param_list_size) { 879 unsigned char *new_list; 880 ctx->slice_param_list_size += 8; 881 new_list = realloc(ctx->slice_param_list, 882 sizeof(object_buffer_p) * ctx->slice_param_list_size); 883 if (NULL == new_list) { 884 return VA_STATUS_ERROR_ALLOCATION_FAILED; 885 } 886 ctx->slice_param_list = (object_buffer_p*) new_list; 887 } 888 ctx->slice_param_list[ctx->slice_param_list_idx] = obj_buffer; 889 ctx->slice_param_list_idx++; 890 return VA_STATUS_SUCCESS; 891} 892 893/* Precalculated values */ 894#define ADDR0 (0x00006000) 895#define ADDR1 (0x0003f017) 896#define ADDR2 (0x000ab0e5) 897#define ADDR3 (0x0000016e) 898#define WIDTH0 (0x0016c6ed) 899#define OPCODE0 (0x00002805) 900 901static void psb__MPEG2_write_VLC_tables(context_MPEG2_p ctx) 902{ 903 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 904 905 psb_cmdbuf_skip_start_block(cmdbuf, SKIP_ON_CONTEXT_SWITCH); 906 /* VLC Table */ 907 /* Write a LLDMA Cmd to transfer VLD Table data */ 908 psb_cmdbuf_lldma_write_cmdbuf(cmdbuf, &ctx->vlc_packed_table, 0, 909 sizeof(gaui16mpeg2VlcTableDataPacked), 910 0, LLDMA_TYPE_VLC_TABLE); 911 912 /* Write the vec registers with the index data for each of the tables and then write */ 913 /* the actual table data. */ 914 psb_cmdbuf_reg_start_block(cmdbuf); 915 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0), ADDR0); 916 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR1), ADDR1); 917 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2), ADDR2); 918 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR3), ADDR3); 919 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0), WIDTH0); 920 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0), OPCODE0); 921 psb_cmdbuf_reg_end_block(cmdbuf); 922 923 psb_cmdbuf_skip_end_block(cmdbuf); 924} 925 926/* Programme the Alt output if there is a rotation*/ 927static void psb__MPEG2_setup_alternative_frame(context_MPEG2_p ctx, IMG_BOOL write_reg) 928{ 929 uint32_t cmd; 930 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 931 psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; 932 object_context_p obj_context = ctx->obj_context; 933 934 if (rotate_surface == NULL) { 935 psb__information_message("rotate surface is NULL, abort msvdx rotation\n"); 936 return; 937 } 938 939 if (GET_SURFACE_INFO_rotate(rotate_surface) != obj_context->msvdx_rotate) 940 psb__error_message("Display rotate mode does not match surface rotate mode!\n"); 941 942 943 /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ 944 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS)); 945 946 psb_cmdbuf_rendec_write_address(cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs); 947 psb_cmdbuf_rendec_write_address(cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); 948 949 RELOC(*ctx->p_range_mapping_base0, rotate_surface->buf.buffer_ofs, &rotate_surface->buf); 950 RELOC(*ctx->p_range_mapping_base1, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset, &rotate_surface->buf); 951 952 psb_cmdbuf_rendec_end(cmdbuf); 953 954 if (write_reg) { 955 /* Set the rotation registers */ 956 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION)); 957 cmd = 0; 958 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1); 959 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, rotate_surface->stride_mode); 960 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); /* FIXME Always has Rec */ 961 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(rotate_surface)); 962 963 psb_cmdbuf_rendec_write(cmdbuf, cmd); 964 965 psb_cmdbuf_rendec_end(cmdbuf); 966 } 967} 968 969static void psb__MPEG2_set_operating_mode(context_MPEG2_p ctx) 970{ 971 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 972 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 973 974 if (CONTEXT_ROTATE(ctx->obj_context)) 975 psb__MPEG2_setup_alternative_frame(ctx, ctx->pic_params->picture_coding_extension.bits.progressive_frame); 976 977 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE)); 978 psb_cmdbuf_rendec_write(cmdbuf, ctx->display_picture_size); 979 psb_cmdbuf_rendec_write(cmdbuf, ctx->coded_picture_size); 980 psb_cmdbuf_rendec_write(cmdbuf, ctx->obj_context->operating_mode); 981 982 /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 983 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); 984 985 /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 986 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); 987 988 psb_cmdbuf_rendec_end(cmdbuf); 989} 990 991static void psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx) 992{ 993 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 994 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 995 996 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES)); 997 998 /* In MPEG2, the registers at N=0 are always used to store the base address of the luma and chroma buffers 999 of the most recently decoded reference picture. The registers at N=1 are used to store the base address 1000 of the luma and chroma buffers of the older reference picture, if more than one reference picture is used. 1001 This means that when decoding a P picture the forward reference picture�s address is at index 0. 1002 When decoding a B-picture the backward reference picture�s address is at index 0 and the address of the 1003 forward reference picture � which was decoded earlier than the backward reference � is at index 1. 1004 */ 1005 1006 switch (ctx->pic_params->picture_coding_type) { 1007 case PICTURE_CODING_I: 1008 psb__information_message(" I-Frame\n"); 1009 /* No reference pictures */ 1010 psb_cmdbuf_rendec_write(cmdbuf, 0); 1011 psb_cmdbuf_rendec_write(cmdbuf, 0); 1012 psb_cmdbuf_rendec_write(cmdbuf, 0); 1013 psb_cmdbuf_rendec_write(cmdbuf, 0); 1014 break; 1015 1016 case PICTURE_CODING_P: 1017 psb__information_message(" P-Frame\n"); 1018 if (ctx->pic_params->picture_coding_extension.bits.is_first_field) { 1019 /* forward reference picture */ 1020 /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1021 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs); 1022 1023 /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1024 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface\ 1025 ->buf.buffer_ofs + ctx->forward_ref_surface->psb_surface->chroma_offset); 1026 1027 /* No backward reference picture */ 1028 psb_cmdbuf_rendec_write(cmdbuf, 0); 1029 psb_cmdbuf_rendec_write(cmdbuf, 0); 1030 } else { 1031 /* backward reference picture */ 1032 /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1033 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); 1034 1035 /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1036 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); 1037 1038 /* forward reference picture */ 1039 /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1040 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs); 1041 1042 /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1043 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs + ctx->forward_ref_surface->psb_surface->chroma_offset); 1044 } 1045 break; 1046 1047 case PICTURE_CODING_B: 1048 psb__information_message(" B-Frame\n"); 1049 /* backward reference picture */ 1050 /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1051 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface->buf.buffer_ofs); 1052 1053 /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1054 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface->buf.buffer_ofs + ctx->backward_ref_surface->psb_surface->chroma_offset); 1055 1056 /* forward reference picture */ 1057 /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1058 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs); 1059 1060 /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1061 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs + ctx->forward_ref_surface->psb_surface->chroma_offset); 1062 break; 1063 } 1064 1065 psb_cmdbuf_rendec_end(cmdbuf); 1066} 1067 1068static void psb__MPEG2_set_picture_header(context_MPEG2_p ctx, VASliceParameterBufferMPEG2 *slice_param) 1069{ 1070 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1071 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 1072 uint32_t FE_slice; 1073 uint32_t BE_slice; 1074 1075 psb_cmdbuf_reg_start_block(cmdbuf); 1076 1077 /* VEC Control register: Front-End MPEG2 PPS0 */ 1078 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0) , ctx->FE_PPS0); 1079 1080 /* VEC Control register: Front-End MPEG2 PPS1 */ 1081 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1) , ctx->FE_PPS1); 1082 1083 /* Slice level */ 1084 FE_slice = 0; 1085 REGIO_WRITE_FIELD(FE_slice, 1086 MSVDX_VEC_MPEG2, 1087 CR_VEC_MPEG2_FE_SLICE, 1088 FE_FIRST_IN_ROW, 1089 (ctx->previous_slice_vertical_position != slice_param->slice_vertical_position)); 1090 1091 REGIO_WRITE_FIELD(FE_slice, 1092 MSVDX_VEC_MPEG2, 1093 CR_VEC_MPEG2_FE_SLICE, 1094 FE_SLICE_VERTICAL_POSITION_MINUS1, 1095 slice_param->slice_vertical_position); 1096 1097 REGIO_WRITE_FIELD(FE_slice, 1098 MSVDX_VEC_MPEG2, 1099 CR_VEC_MPEG2_FE_SLICE, 1100 FE_QUANTISER_SCALE_CODE, 1101 slice_param->quantiser_scale_code); 1102 1103 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_SLICE) , FE_slice); 1104 1105 psb_cmdbuf_reg_end_block(cmdbuf); 1106 1107 1108 /* BE Section */ 1109 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG2_CR_VEC_MPEG2_BE_SPS0)); 1110 1111 psb_cmdbuf_rendec_write(cmdbuf, ctx->BE_SPS0); 1112 psb_cmdbuf_rendec_write(cmdbuf, ctx->BE_SPS1); 1113 psb_cmdbuf_rendec_write(cmdbuf, ctx->BE_PPS0); /* VEC Control register: Back-End MPEG2 PPS0 */ 1114 psb_cmdbuf_rendec_write(cmdbuf, ctx->BE_PPS1); /* VEC Control register: Back-End MPEG2 PPS1 */ 1115 psb_cmdbuf_rendec_write(cmdbuf, ctx->BE_PPS2); /* VEC Control register: Back-End MPEG2 PPS2 */ 1116 1117 BE_slice = 0; 1118 if (!ctx->pic_params->picture_coding_extension.bits.is_first_field) { 1119 /* 1120 BE_IP_PAIR_FLAG is 1 if the current picture_data is a P-coded field which is the 2nd field of a frame, 1121 and which uses the first field of the frame (which was I-coded) as a reference. 0 otherwise. 1122 BE_IP_PAIR_FLAG will only be 1 if BE_SECOND_FIELD_FLAG is 1, and the condition 1123 of "this is a P-field which uses the accompanying I-field as a reference" is met. 1124 */ 1125 if (ctx->pic_params->picture_coding_type == PICTURE_CODING_P) { 1126 if (GET_SURFACE_INFO_picture_coding_type(target_surface) == PICTURE_CODING_I) { 1127 REGIO_WRITE_FIELD_LITE(BE_slice, 1128 MSVDX_VEC_MPEG2, 1129 CR_VEC_MPEG2_BE_SLICE, 1130 BE_IP_PAIR_FLAG, 1); 1131 } 1132 } 1133 1134 REGIO_WRITE_FIELD_LITE(BE_slice, 1135 MSVDX_VEC_MPEG2, 1136 CR_VEC_MPEG2_BE_SLICE, 1137 BE_SECOND_FIELD_FLAG, 1); 1138 1139 } else { 1140 // BE_IP_PAIR_FLAG = 0; 1141 // BE_SECOND_FIELD_FLAG = 0; 1142 1143 /* Update with current settings first field */ 1144 SET_SURFACE_INFO_is_defined(target_surface, TRUE); 1145 SET_SURFACE_INFO_picture_structure(target_surface, ctx->pic_params->picture_coding_extension.bits.picture_structure); 1146 SET_SURFACE_INFO_picture_coding_type(target_surface, ctx->pic_params->picture_coding_type); 1147 } 1148 1149 REGIO_WRITE_FIELD_LITE(BE_slice, 1150 MSVDX_VEC_MPEG2, 1151 CR_VEC_MPEG2_BE_SLICE, 1152 BE_FIRST_IN_ROW, 1153 (ctx->previous_slice_vertical_position != slice_param->slice_vertical_position)); 1154 1155 REGIO_WRITE_FIELD_LITE(BE_slice, 1156 MSVDX_VEC_MPEG2, 1157 CR_VEC_MPEG2_BE_SLICE, 1158 BE_SLICE_VERTICAL_POSITION_MINUS1, 1159 slice_param->slice_vertical_position); 1160 1161 REGIO_WRITE_FIELD_LITE(BE_slice, 1162 MSVDX_VEC_MPEG2, 1163 CR_VEC_MPEG2_BE_SLICE, 1164 BE_QUANTISER_SCALE_CODE, 1165 slice_param->quantiser_scale_code); 1166 1167 psb__information_message("BE_slice = %08x first_field = %d\n", BE_slice, ctx->pic_params->picture_coding_extension.bits.is_first_field); 1168 1169 psb_cmdbuf_rendec_write(cmdbuf, BE_slice); 1170 1171 psb_cmdbuf_rendec_end(cmdbuf); 1172 1173 ctx->previous_slice_vertical_position = slice_param->slice_vertical_position; 1174} 1175 1176static void psb__MPEG2_set_slice_params(context_MPEG2_p ctx) 1177{ 1178 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1179 1180 uint32_t cmd_data; 1181 1182 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS)); 1183 1184 cmd_data = 0; /* Build slice parameters */ 1185 REGIO_WRITE_FIELD(cmd_data, 1186 MSVDX_CMDS, 1187 SLICE_PARAMS, 1188 SLICE_FIELD_TYPE, 1189 ctx->pic_params->picture_coding_extension.bits.picture_structure - 1); 1190 1191 REGIO_WRITE_FIELD(cmd_data, 1192 MSVDX_CMDS, 1193 SLICE_PARAMS, 1194 SLICE_CODE_TYPE, 1195 PICTURE_CODING_D == ctx->pic_params->picture_coding_type ? 0 : ctx->pic_params->picture_coding_type - 1); 1196 1197 psb_cmdbuf_rendec_write(cmdbuf, cmd_data); 1198 1199 *ctx->p_slice_params = cmd_data; 1200 1201 psb_cmdbuf_rendec_end(cmdbuf); 1202} 1203 1204static void psb__MPEG2_write_qmatrices(context_MPEG2_p ctx) 1205{ 1206 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1207 int i; 1208 1209 /* Since we only decode 4:2:0 We only need to the Intra tables. 1210 Chroma quant tables are only used in Mpeg 4:2:2 and 4:4:4. 1211 The hardware wants non-intra followed by intra */ 1212 psb_cmdbuf_rendec_start(cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET); 1213 1214 /* todo : optimisation here is to only load the need table */ 1215 1216 /* NONINTRA_LUMA_Q --> REG_MSVDX_VEC_IQRAM_OFFSET + 0 */ 1217 for (i = 0; i < 16; i++) { 1218 psb_cmdbuf_rendec_write(cmdbuf, ctx->qmatrix_data[NONINTRA_LUMA_Q][i]); 1219// psb__information_message("NONINTRA_LUMA_Q[i] = %08x\n", ctx->qmatrix_data[NONINTRA_LUMA_Q][i]); 1220 } 1221 /* INTRA_LUMA_Q --> REG_MSVDX_VEC_IQRAM_OFFSET + (16*4) */ 1222 for (i = 0; i < 16; i++) { 1223 psb_cmdbuf_rendec_write(cmdbuf, ctx->qmatrix_data[INTRA_LUMA_Q][i]); 1224// psb__information_message("INTRA_LUMA_Q[i] = %08x\n", ctx->qmatrix_data[INTRA_LUMA_Q][i]); 1225 } 1226 1227 psb_cmdbuf_rendec_end(cmdbuf); 1228} 1229 1230static void psb__MPEG2_set_ent_dec(context_MPEG2_p ctx) 1231{ 1232 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1233 1234 uint32_t cmd_data; 1235 1236 psb_cmdbuf_reg_start_block(cmdbuf); 1237 1238 cmd_data = 0; /* Entdec Front-End controls */ 1239 REGIO_WRITE_FIELD_LITE(cmd_data, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_PROFILE, 1); /* MPEG2 Main Profile */ 1240 REGIO_WRITE_FIELD_LITE(cmd_data, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_MODE, 3); /* Set MPEG2 mode */ 1241 1242 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL), cmd_data); 1243 1244 psb_cmdbuf_reg_end_block(cmdbuf); 1245 1246 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL)); 1247 1248 cmd_data = 0; /* Entdec Back-End controls */ 1249 REGIO_WRITE_FIELD(cmd_data, 1250 MSVDX_VEC, 1251 CR_VEC_ENTDEC_BE_CONTROL, 1252 ENTDEC_BE_PROFILE, 1253 1); /* MPEG2 Main Profile */ 1254 1255 REGIO_WRITE_FIELD(cmd_data, 1256 MSVDX_VEC, 1257 CR_VEC_ENTDEC_BE_CONTROL, 1258 ENTDEC_BE_MODE, 1259 3); /* Set MPEG2 mode */ 1260 1261 psb_cmdbuf_rendec_write(cmdbuf, cmd_data); 1262 1263 psb_cmdbuf_rendec_end(cmdbuf); 1264} 1265 1266static void psb__MPEG2_write_kick(context_MPEG2_p ctx, VASliceParameterBufferMPEG2 *slice_param) 1267{ 1268 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1269 1270 (void) slice_param; /* Unused for now */ 1271 1272 *cmdbuf->cmd_idx++ = CMD_COMPLETION; 1273} 1274 1275static void psb__MPEG2_FE_state(context_MPEG2_p ctx) 1276{ 1277 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1278 1279 /* See RENDER_BUFFER_HEADER */ 1280 *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; 1281 1282 ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++; 1283 ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; 1284 1285 *ctx->p_range_mapping_base0 = 0; 1286 *ctx->p_range_mapping_base1 = 0; 1287 1288 ctx->p_slice_params = cmdbuf->cmd_idx; 1289 *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */ 1290 1291 *cmdbuf->cmd_idx++ = 0; /* skip two lldma addr field */ 1292 1293 *cmdbuf->cmd_idx++ = 0; 1294 ctx->slice_first_pic_last = cmdbuf->cmd_idx++; 1295} 1296 1297static VAStatus psb__MPEG2_process_slice(context_MPEG2_p ctx, 1298 VASliceParameterBufferMPEG2 *slice_param, 1299 object_buffer_p obj_buffer) 1300{ 1301 VAStatus vaStatus = VA_STATUS_SUCCESS; 1302 1303 ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); 1304 1305 psb__information_message("MPEG2 process slice\n"); 1306 psb__information_message(" size = %08x offset = %08x\n", slice_param->slice_data_size, slice_param->slice_data_offset); 1307 psb__information_message(" vertical pos = %d\n", slice_param->slice_vertical_position); 1308 psb__information_message(" slice_data_flag = %d\n", slice_param->slice_data_flag); 1309 psb__information_message(" coded size = %dx%d\n", ctx->picture_width_mb, ctx->picture_height_mb); 1310 1311 if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) || 1312 (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL)) { 1313 if (0 == slice_param->slice_data_size) { 1314 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1315 DEBUG_FAILURE; 1316 return vaStatus; 1317 } 1318 1319 ASSERT(!ctx->split_buffer_pending); 1320 1321 /* Initialise the command buffer */ 1322 psb_context_get_next_cmdbuf(ctx->obj_context); 1323 1324 psb__MPEG2_FE_state(ctx); 1325 psb__MPEG2_write_VLC_tables(ctx); 1326 1327 psb_cmdbuf_lldma_write_bitstream(ctx->obj_context->cmdbuf, 1328 obj_buffer->psb_buffer, 1329 obj_buffer->psb_buffer->buffer_ofs + slice_param->slice_data_offset, 1330 slice_param->slice_data_size, 1331 slice_param->macroblock_offset, 1332 0); 1333 1334 if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) { 1335 ctx->split_buffer_pending = TRUE; 1336 } 1337 } else { 1338 ASSERT(ctx->split_buffer_pending); 1339 ASSERT(0 == slice_param->slice_data_offset); 1340 /* Create LLDMA chain to continue buffer */ 1341 if (slice_param->slice_data_size) { 1342 psb_cmdbuf_lldma_write_bitstream_chained(ctx->obj_context->cmdbuf, 1343 obj_buffer->psb_buffer, 1344 slice_param->slice_data_size); 1345 } 1346 } 1347 1348 if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL) || 1349 (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END)) { 1350 if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END) { 1351 ASSERT(ctx->split_buffer_pending); 1352 } 1353 1354 psb__MPEG2_set_operating_mode(ctx); 1355 1356 psb__MPEG2_set_reference_pictures(ctx); 1357 1358 psb__MPEG2_set_picture_header(ctx, slice_param); 1359 1360 psb__MPEG2_set_slice_params(ctx); 1361 1362 psb__MPEG2_write_qmatrices(ctx); 1363 1364 psb__MPEG2_set_ent_dec(ctx); 1365 1366 psb__MPEG2_write_kick(ctx, slice_param); 1367 1368 ctx->split_buffer_pending = FALSE; 1369 ctx->obj_context->video_op = psb_video_vld; 1370 ctx->obj_context->flags = FW_VA_RENDER_IS_VLD_NOT_MC; 1371 ctx->obj_context->first_mb = 0; 1372 1373 if (ctx->pic_params->picture_coding_extension.bits.progressive_frame) 1374 ctx->obj_context->last_mb = ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1); 1375 else 1376 ctx->obj_context->last_mb = ((ctx->picture_height_mb / 2 - 1) << 8) | (ctx->picture_width_mb - 1); 1377 1378 *ctx->slice_first_pic_last = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb); 1379 1380 if (psb_context_submit_cmdbuf(ctx->obj_context)) { 1381 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1382 } 1383 } 1384 return vaStatus; 1385} 1386 1387static VAStatus psb__MPEG2_process_slice_data(context_MPEG2_p ctx, object_buffer_p obj_buffer) 1388{ 1389 VAStatus vaStatus = VA_STATUS_SUCCESS; 1390 VASliceParameterBufferMPEG2 *slice_param; 1391 int buffer_idx = 0; 1392 unsigned int element_idx = 0; 1393 1394 ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); 1395 1396 ASSERT(ctx->got_iq_matrix); 1397 ASSERT(ctx->pic_params); 1398 ASSERT(ctx->slice_param_list_idx); 1399 1400 if (!ctx->got_iq_matrix || !ctx->pic_params) { 1401 /* IQ matrix or Picture params missing */ 1402 return VA_STATUS_ERROR_UNKNOWN; 1403 } 1404 if ((NULL == obj_buffer->psb_buffer) || 1405 (0 == obj_buffer->size)) { 1406 /* We need to have data in the bitstream buffer */ 1407 return VA_STATUS_ERROR_UNKNOWN; 1408 } 1409 1410 while (buffer_idx < ctx->slice_param_list_idx) { 1411 object_buffer_p slice_buf = ctx->slice_param_list[buffer_idx]; 1412 if (element_idx >= slice_buf->num_elements) { 1413 /* Move to next buffer */ 1414 element_idx = 0; 1415 buffer_idx++; 1416 continue; 1417 } 1418 1419 slice_param = (VASliceParameterBufferMPEG2 *) slice_buf->buffer_data; 1420 slice_param += element_idx; 1421 element_idx++; 1422 vaStatus = psb__MPEG2_process_slice(ctx, slice_param, obj_buffer); 1423 if (vaStatus != VA_STATUS_SUCCESS) { 1424 DEBUG_FAILURE; 1425 break; 1426 } 1427 } 1428 ctx->slice_param_list_idx = 0; 1429 1430 return vaStatus; 1431} 1432 1433static void psb__MEPG2_send_highlevel_cmd(context_MPEG2_p ctx) 1434{ 1435 uint32_t cmd; 1436 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1437 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 1438 psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; 1439 1440 psb_cmdbuf_reg_start_block(cmdbuf); 1441 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE), ctx->display_picture_size); 1442 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, CODED_PICTURE_SIZE), ctx->coded_picture_size); 1443 1444 cmd = 0; 1445 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1); 1446 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1); // 0 = VDMC and VDEB active. 1 = VDEB pass-thru. 1447 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 3); // MPEG2 1448 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, 1); // MAIN 1449 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, target_surface->stride_mode); 1450 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, OPERATING_MODE), cmd); 1451 1452 psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES), 1453 &target_surface->buf, target_surface->buf.buffer_ofs); 1454 1455 psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES), 1456 &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); 1457 1458 psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + (0 * 8), 1459 &target_surface->buf, target_surface->buf.buffer_ofs); 1460 1461 psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + 4 + (0 * 8), 1462 &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); 1463 1464 psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + (1 * 8), 1465 &target_surface->buf, target_surface->buf.buffer_ofs); 1466 1467 psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + 4 + (1 * 8), 1468 &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); 1469 1470 cmd = 0; 1471 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE, 2); /* FRAME PICTURE -- ui8SliceFldType */ 1472 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, 1); /* P PICTURE -- (ui8PicType == WMF_PTYPE_BI) ? WMF_PTYPE_I : (ui8PicType & 0x3) */ 1473 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS), cmd); 1474 *ctx->p_slice_params = cmd; 1475 psb_cmdbuf_reg_end_block(cmdbuf); 1476 1477 1478 psb_cmdbuf_reg_start_block(cmdbuf); 1479 psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS), 1480 &rotate_surface->buf, rotate_surface->buf.buffer_ofs); 1481 1482 psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, VC1_CHROMA_RANGE_MAPPING_BASE_ADDRESS), 1483 &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); 1484 psb_cmdbuf_reg_end_block(cmdbuf); 1485 1486 RELOC(*ctx->p_range_mapping_base0, rotate_surface->buf.buffer_ofs, &rotate_surface->buf); 1487 RELOC(*ctx->p_range_mapping_base1, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset, &rotate_surface->buf); 1488} 1489 1490static void psb__MEPG2_send_blit_cmd(context_MPEG2_p ctx) 1491{ 1492 uint32_t cmd; 1493 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1494 psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; 1495 1496 psb_cmdbuf_reg_start_block(cmdbuf); 1497 cmd = 0; 1498 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1); 1499 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, rotate_surface->stride_mode); 1500 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); 1501 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(rotate_surface)); 1502 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION), cmd); 1503 psb_cmdbuf_reg_end_block(cmdbuf); 1504 1505 *cmdbuf->cmd_idx++ = 0x40000000; /* CMD_BLIT_CMD */ 1506 *cmdbuf->cmd_idx++ = ctx->picture_width_mb; 1507 *cmdbuf->cmd_idx++ = ctx->picture_height_mb; /* FIXME */ 1508 *cmdbuf->cmd_idx++ = CMD_COMPLETION; 1509} 1510 1511static void psb__MPEG2_insert_blit_cmd_to_rotate(context_MPEG2_p ctx) 1512{ 1513 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1514 1515 /* See RENDER_BUFFER_HEADER */ 1516 *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; 1517 1518 ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++; 1519 ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; 1520 1521 *ctx->p_range_mapping_base0 = 0; 1522 *ctx->p_range_mapping_base1 = 0; 1523 1524 ctx->p_slice_params = cmdbuf->cmd_idx; 1525 *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */ 1526 1527 *cmdbuf->cmd_idx++ = 0; /* skip two lldma addr field */ 1528 *cmdbuf->cmd_idx++ = 0; 1529 1530 ctx->slice_first_pic_last = cmdbuf->cmd_idx++; 1531 *ctx->slice_first_pic_last = 0; 1532 1533 psb__MEPG2_send_highlevel_cmd(ctx); 1534 psb__MEPG2_send_blit_cmd(ctx); 1535 1536 ctx->obj_context->video_op = psb_video_mc; 1537 ctx->obj_context->flags = FW_VA_RENDER_IS_LAST_SLICE; 1538 1539 if (psb_context_submit_cmdbuf(ctx->obj_context)) { 1540 ASSERT(0); 1541 } 1542} 1543 1544static VAStatus pnw_MPEG2_BeginPicture( 1545 object_context_p obj_context) 1546{ 1547 INIT_CONTEXT_MPEG2 1548 1549 psb__information_message("pnw_MPEG2_BeginPicture\n"); 1550 if (ctx->pic_params) { 1551 free(ctx->pic_params); 1552 ctx->pic_params = NULL; 1553 } 1554 ctx->previous_slice_vertical_position = ~1; 1555 1556 return VA_STATUS_SUCCESS; 1557} 1558 1559static VAStatus pnw_MPEG2_RenderPicture( 1560 object_context_p obj_context, 1561 object_buffer_p *buffers, 1562 int num_buffers) 1563{ 1564 int i; 1565 INIT_CONTEXT_MPEG2 1566 VAStatus vaStatus = VA_STATUS_SUCCESS; 1567 1568 for (i = 0; i < num_buffers; i++) { 1569 object_buffer_p obj_buffer = buffers[i]; 1570 1571 switch (obj_buffer->type) { 1572 case VAPictureParameterBufferType: 1573 psb__information_message("pnw_MPEG2_RenderPicture got VAPictureParameterBuffer\n"); 1574 vaStatus = psb__MPEG2_process_picture_param(ctx, obj_buffer); 1575 DEBUG_FAILURE; 1576 break; 1577 1578 case VAIQMatrixBufferType: 1579 psb__information_message("pnw_MPEG2_RenderPicture got VAIQMatrixBufferType\n"); 1580 vaStatus = psb__MPEG2_process_iq_matrix(ctx, obj_buffer); 1581 DEBUG_FAILURE; 1582 break; 1583 1584 case VASliceParameterBufferType: 1585 psb__information_message("pnw_MPEG2_RenderPicture got VASliceParameterBufferType\n"); 1586 vaStatus = psb__MPEG2_add_slice_param(ctx, obj_buffer); 1587 DEBUG_FAILURE; 1588 break; 1589 1590 case VASliceDataBufferType: 1591 case VAProtectedSliceDataBufferType: 1592 1593 psb__information_message("pnw_MPEG2_RenderPicture got %s\n", SLICEDATA_BUFFER_TYPE(obj_buffer->type)); 1594 vaStatus = psb__MPEG2_process_slice_data(ctx, obj_buffer); 1595 DEBUG_FAILURE; 1596 break; 1597 1598 default: 1599 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1600 DEBUG_FAILURE; 1601 } 1602 if (vaStatus != VA_STATUS_SUCCESS) { 1603 break; 1604 } 1605 } 1606 1607 return vaStatus; 1608} 1609 1610static VAStatus pnw_MPEG2_EndPicture( 1611 object_context_p obj_context) 1612{ 1613 VAStatus vaStatus = VA_STATUS_SUCCESS; 1614 INIT_CONTEXT_MPEG2 1615 1616 psb__information_message("pnw_MPEG2_EndPicture\n"); 1617 1618 if (CONTEXT_ROTATE(ctx->obj_context)) { 1619 if (!(ctx->pic_params->picture_coding_extension.bits.progressive_frame) && 1620 !(ctx->pic_params->picture_coding_extension.bits.is_first_field)) 1621 psb__MPEG2_insert_blit_cmd_to_rotate(ctx); 1622 } 1623 1624 if (psb_context_flush_cmdbuf(ctx->obj_context)) { 1625 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1626 } 1627 1628 if (ctx->pic_params) { 1629 free(ctx->pic_params); 1630 ctx->pic_params = NULL; 1631 } 1632 1633 return vaStatus; 1634} 1635 1636struct format_vtable_s pnw_MPEG2_vtable = { 1637queryConfigAttributes: 1638 pnw_MPEG2_QueryConfigAttributes, 1639validateConfig: 1640 pnw_MPEG2_ValidateConfig, 1641createContext: 1642 pnw_MPEG2_CreateContext, 1643destroyContext: 1644 pnw_MPEG2_DestroyContext, 1645beginPicture: 1646 pnw_MPEG2_BeginPicture, 1647renderPicture: 1648 pnw_MPEG2_RenderPicture, 1649endPicture: 1650 pnw_MPEG2_EndPicture 1651}; 1652