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 * Guo Nana <nana.n.guo (at) intel.com> 27 * Zeng Li <li.zeng (at) intel.com> 28 * 29 */ 30 31 #include "va/va_dec_jpeg.h" 32 #include "tng_jpegdec.h" 33 #include "tng_vld_dec.h" 34 #include "psb_def.h" 35 #include "psb_drv_debug.h" 36 37 #include "hwdefs/reg_io2.h" 38 #include "hwdefs/msvdx_offsets.h" 39 #include "hwdefs/msvdx_cmds_io2.h" 40 #include "hwdefs/msvdx_vec_reg_io2.h" 41 #include "hwdefs/msvdx_vec_jpeg_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 #define GET_SURFACE_INFO_is_defined(psb_surface) ((int) (psb_surface->extra_info[0])) 50 #define SET_SURFACE_INFO_is_defined(psb_surface, val) psb_surface->extra_info[0] = (uint32_t) val; 51 #define GET_SURFACE_INFO_picture_structure(psb_surface) (psb_surface->extra_info[1]) 52 #define SET_SURFACE_INFO_picture_structure(psb_surface, val) psb_surface->extra_info[1] = val; 53 #define GET_SURFACE_INFO_picture_coding_type(psb_surface) ((int) (psb_surface->extra_info[2])) 54 #define SET_SURFACE_INFO_picture_coding_type(psb_surface, val) psb_surface->extra_info[2] = (uint32_t) val; 55 56 #define JPEG_MAX_SETS_HUFFMAN_TABLES 2 57 #define JPEG_MAX_QUANT_TABLES 4 58 59 #define TABLE_CLASS_DC 0 60 #define TABLE_CLASS_AC 1 61 #define TABLE_CLASS_NUM 2 62 63 #define JPEG_PROFILE_BASELINE 0 64 65 /************************************/ 66 /* VLC table defines and structures */ 67 68 /* max number of bits allowed in a VLC code */ 69 #define JPG_VLC_MAX_CODE_LEN (16) 70 71 /* max num bits to decode in any one decode direct operation */ 72 #define JPG_VLC_MAX_DIRECT_WIDTH (6) 73 74 static const uint8_t inverse_zigzag[64] = 75 { 76 0x00, 0x01, 0x05, 0x06, 0x0e, 0x0f, 0x1b, 0x1c, 77 0x02, 0x04, 0x07, 0x0D, 0x10, 0x1a, 0x1d, 0x2a, 78 0x03, 0x08, 0x0C, 0x11, 0x19, 0x1e, 0x29, 0x2b, 79 0x09, 0x0B, 0x12, 0x18, 0x1f, 0x28, 0x2c, 0x35, 80 0x0A, 0x13, 0x17, 0x20, 0x27, 0x2d, 0x34, 0x36, 81 0x14, 0x16, 0x21, 0x26, 0x2e, 0x33, 0x37, 0x3c, 82 0x15, 0x22, 0x25, 0x2f, 0x32, 0x38, 0x3b, 0x3d, 83 0x23, 0x24, 0x30, 0x31, 0x39, 0x3a, 0x3e, 0x3f 84 }; 85 86 87 /* 88 ****************************************************************************** 89 90 This structure defines the VLC code used for a partiular symbol 91 92 ******************************************************************************/ 93 typedef struct 94 { 95 uint16_t code; // VLC code with valid data in top-most bits 96 uint8_t code_length; // VLC code length 97 uint8_t symbol; 98 99 } vlc_symbol_code_jpeg; // VLCSymbolCodeJPEG 100 101 102 /* 103 ****************************************************************************** 104 105 This structure describes a set of VLC codes for a particular Huffman tree 106 107 ******************************************************************************/ 108 typedef struct 109 { 110 uint32_t num_codes; 111 uint32_t min_len; 112 uint32_t max_len; 113 114 } vlc_symbol_stats_jpeg; // VLCSymbolStatsJPEG 115 116 117 /* 118 ****************************************************************************** 119 120 This structure describes the generated VLC code table 121 122 ******************************************************************************/ 123 typedef struct 124 { 125 uint32_t size; 126 uint32_t initial_width; 127 uint32_t initial_opcode; 128 129 } vlc_table_stats_jpeg; // VLCTableStatsJPEG 130 131 132 /**************************************/ 133 /* JPEG VLC Table defines and OpCodes */ 134 135 #define JPG_MAKE_MASK(X) ((1<<(X))-1) 136 137 #define JPG_INSTR_OP_CODE_WIDTH (3) 138 #define JPG_INSTR_SHIFT_WIDTH (3) 139 #define JPG_INSTR_OFFSET_WIDTH (9) 140 141 #define JPG_INSTR_OP_CODE_MASK JPG_MAKE_MASK(JPG_JPG_INSTR_OP_CODE_WIDTH) 142 #define JPG_INSTR_SHIFT_MASK JPG_MAKE_MASK(JPG_INSTR_SHIFT_WIDTH) 143 #define JPG_INSTR_OFFSET_MASK JPG_MAKE_MASK(JPG_INSTR_OFFSET_WIDTH) 144 145 146 #define JPG_MAKE_OFFSET(code,width,leading) \ 147 (((code<<leading) & JPG_MAKE_MASK(JPG_VLC_MAX_CODE_LEN)) >> (JPG_VLC_MAX_CODE_LEN-width)) 148 149 typedef enum { 150 JPG_OP_DECODE_DIRECT = 0, 151 JPG_OP_DECODE_LEADING_1, 152 JPG_OP_DECODE_LEADING_0, 153 154 JPG_OP_CODE_INVALID, 155 156 JPG_OP_VALID_SYMBOL, 157 JPG_OP_VALID_RANGE_EVEN, 158 JPG_OP_VALID_RANGE_ODD, 159 JPG_OP_VALID_RANGE_EVEN_SET_FLAG, 160 161 } vlc_op_code_jpeg; // VLCOpCodeJPEG 162 163 /**************************************/ 164 165 struct context_JPEG_s { 166 struct context_DEC_s dec_ctx; 167 object_context_p obj_context; /* back reference */ 168 169 uint32_t profile; 170 171 /* Picture parameters */ 172 VAPictureParameterBufferJPEGBaseline *pic_params; 173 174 uint32_t display_picture_width; /* in pixels */ 175 uint32_t display_picture_height; /* in pixels */ 176 177 uint32_t coded_picture_width; /* in pixels */ 178 uint32_t coded_picture_height; /* in pixels */ 179 180 uint32_t MCU_width; 181 uint32_t MCU_height; 182 uint32_t size_mb; /* in macroblocks */ 183 uint32_t picture_width_mb; /* in macroblocks */ 184 uint32_t picture_height_mb; /* in macroblocks */ 185 186 uint8_t max_scalingH; 187 uint8_t max_scalingV; 188 189 /* VLC packed data */ 190 struct psb_buffer_s vlc_packed_table; 191 192 uint32_t vlctable_buffer_size; 193 uint32_t rendec_qmatrix[JPEG_MAX_QUANT_TABLES][16]; 194 195 /* Huffman table information as parsed from the bitstream */ 196 vlc_symbol_code_jpeg* symbol_codes[TABLE_CLASS_NUM][JPEG_MAX_SETS_HUFFMAN_TABLES]; 197 vlc_symbol_stats_jpeg symbol_stats[TABLE_CLASS_NUM][JPEG_MAX_SETS_HUFFMAN_TABLES]; 198 199 /* Huffman table information compiled for the hardware */ 200 uint32_t huffman_table_space; 201 uint16_t* huffman_table_RAM; 202 vlc_table_stats_jpeg table_stats[TABLE_CLASS_NUM][JPEG_MAX_SETS_HUFFMAN_TABLES]; 203 }; 204 205 typedef struct context_JPEG_s *context_JPEG_p; 206 207 #define INIT_CONTEXT_JPEG context_JPEG_p ctx = (context_JPEG_p) obj_context->format_data; 208 209 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id )) 210 211 static void tng_JPEG_QueryConfigAttributes( 212 VAProfile __maybe_unused profile, 213 VAEntrypoint __maybe_unused entrypoint, 214 VAConfigAttrib __maybe_unused * attrib_list, 215 int __maybe_unused num_attribs) { 216 /* No JPEG specific attributes */ 217 } 218 219 static VAStatus tng_JPEG_ValidateConfig(object_config_p obj_config) { 220 int i; 221 /* Check all attributes */ 222 for (i = 0; i < obj_config->attrib_count; i++) { 223 switch (obj_config->attrib_list[i].type) { 224 case VAConfigAttribRTFormat: 225 /* Ignore */ 226 break; 227 228 default: 229 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 230 } 231 } 232 233 return VA_STATUS_SUCCESS; 234 } 235 236 static VAStatus tng__JPEG_check_legal_picture(object_context_p obj_context, object_config_p obj_config) { 237 VAStatus vaStatus = VA_STATUS_SUCCESS; 238 239 if (NULL == obj_context) { 240 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 241 DEBUG_FAILURE; 242 return vaStatus; 243 } 244 245 if (NULL == obj_config) { 246 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 247 DEBUG_FAILURE; 248 return vaStatus; 249 } 250 251 switch (obj_config->profile) { 252 case VAProfileJPEGBaseline: 253 if ((obj_context->picture_width <= 0) || (obj_context->picture_height <= 0)) { 254 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 255 } 256 break; 257 258 default: 259 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 260 break; 261 } 262 263 return vaStatus; 264 } 265 266 static void tng_JPEG_DestroyContext(object_context_p obj_context); 267 268 static void tng__JPEG_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param); 269 static void tng__JPEG_end_slice(context_DEC_p dec_ctx); 270 static void tng__JPEG_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param); 271 static VAStatus tng_JPEG_process_buffer(context_DEC_p dec_ctx, object_buffer_p buffer); 272 273 static VAStatus tng_JPEG_CreateContext( 274 object_context_p obj_context, 275 object_config_p obj_config) { 276 VAStatus vaStatus = VA_STATUS_SUCCESS; 277 context_JPEG_p ctx; 278 279 /* Validate flag */ 280 /* Validate picture dimensions */ 281 vaStatus = tng__JPEG_check_legal_picture(obj_context, obj_config); 282 if (VA_STATUS_SUCCESS != vaStatus) { 283 DEBUG_FAILURE; 284 return vaStatus; 285 } 286 287 ctx = (context_JPEG_p) calloc(1, sizeof(struct context_JPEG_s)); 288 if (NULL == ctx) { 289 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 290 DEBUG_FAILURE; 291 return vaStatus; 292 } 293 obj_context->format_data = (void*) ctx; 294 ctx->obj_context = obj_context; 295 ctx->pic_params = NULL; 296 297 ctx->dec_ctx.begin_slice = tng__JPEG_begin_slice; 298 ctx->dec_ctx.process_slice = tng__JPEG_process_slice_data; 299 ctx->dec_ctx.end_slice = tng__JPEG_end_slice; 300 ctx->dec_ctx.process_buffer = tng_JPEG_process_buffer; 301 ctx->dec_ctx.preload_buffer = NULL; 302 303 switch (obj_config->profile) { 304 case VAProfileJPEGBaseline: 305 drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG_PROFILE_BASELINE\n"); 306 ctx->profile = JPEG_PROFILE_BASELINE; 307 break; 308 309 default: 310 ASSERT(0 == 1); 311 vaStatus = VA_STATUS_ERROR_UNKNOWN; 312 } 313 314 ctx->vlctable_buffer_size = 1984 * 2; 315 if (vaStatus == VA_STATUS_SUCCESS) { 316 vaStatus = psb_buffer_create(obj_context->driver_data, 317 ctx->vlctable_buffer_size, 318 psb_bt_cpu_vpu, 319 &ctx->vlc_packed_table); 320 DEBUG_FAILURE; 321 } 322 323 if (vaStatus == VA_STATUS_SUCCESS) { 324 vaStatus = vld_dec_CreateContext(&ctx->dec_ctx, obj_context); 325 DEBUG_FAILURE; 326 } 327 328 if (vaStatus != VA_STATUS_SUCCESS) { 329 tng_JPEG_DestroyContext(obj_context); 330 } 331 332 return vaStatus; 333 } 334 335 static void tng_JPEG_DestroyContext( 336 object_context_p obj_context) { 337 INIT_CONTEXT_JPEG 338 int i; 339 340 vld_dec_DestroyContext(&ctx->dec_ctx); 341 342 psb_buffer_destroy(&ctx->vlc_packed_table); 343 344 if (ctx->pic_params) { 345 free(ctx->pic_params); 346 ctx->pic_params = NULL; 347 } 348 349 if (ctx->symbol_codes[0][0]) { 350 free(ctx->symbol_codes[0][0]); 351 ctx->symbol_codes[0][0] = NULL; 352 } 353 if (ctx->symbol_codes[0][1]) { 354 free(ctx->symbol_codes[0][1]); 355 ctx->symbol_codes[0][1] = NULL; 356 } 357 if (ctx->symbol_codes[1][0]) { 358 free(ctx->symbol_codes[1][0]); 359 ctx->symbol_codes[1][0] = NULL; 360 } 361 if (ctx->symbol_codes[1][1]) { 362 free(ctx->symbol_codes[1][1]); 363 ctx->symbol_codes[1][1] = NULL; 364 } 365 free(obj_context->format_data); 366 obj_context->format_data = NULL; 367 } 368 369 static uint16_t jpg_vlc_valid_symbol(const vlc_symbol_code_jpeg * symbol_code, const uint32_t leading) { 370 uint16_t entry = 0; 371 IMG_ASSERT( (symbol_code->code_length - leading - 1) >= 0 ); 372 373 /* VLC microcode entry for a valid symbol */ 374 entry |= (JPG_OP_VALID_SYMBOL << (JPG_INSTR_SHIFT_WIDTH+JPG_INSTR_OFFSET_WIDTH)); 375 entry |= ((symbol_code->code_length - leading - 1) << JPG_INSTR_OFFSET_WIDTH); 376 entry |= symbol_code->symbol; 377 return entry; 378 } 379 380 static uint32_t 381 jpg_vlc_write_direct_command(uint16_t * const vlc_ram, uint32_t result_offset) { 382 uint32_t width = 0x7fff & *vlc_ram; 383 uint16_t entry = 0; 384 385 /* check that the max width read from the VLC entry is valid */ 386 IMG_ASSERT( 0x8000 & *vlc_ram ); 387 388 /* limit to the maximum width for this algorithm */ 389 width = (width > JPG_VLC_MAX_DIRECT_WIDTH)? JPG_VLC_MAX_DIRECT_WIDTH: width; 390 391 /* VLC microcode for decode direct command */ 392 entry |= (JPG_OP_DECODE_DIRECT << (JPG_INSTR_SHIFT_WIDTH+JPG_INSTR_OFFSET_WIDTH)); 393 entry |= ((width - 1) << JPG_INSTR_OFFSET_WIDTH); 394 entry |= result_offset; 395 396 /* write command */ 397 *vlc_ram = entry; 398 399 return width; 400 } 401 402 static uint32_t 403 jpg_vlc_get_offset(const vlc_symbol_code_jpeg * symbol_code, uint32_t width, uint32_t leading) { 404 uint32_t offset; 405 406 /* lose bits already decoded */ 407 offset = symbol_code->code << leading; 408 offset &= JPG_MAKE_MASK(JPG_VLC_MAX_CODE_LEN); 409 /* convert truncated code to offset */ 410 offset >>= (JPG_VLC_MAX_CODE_LEN - width); 411 return offset; 412 } 413 414 static uint32_t 415 jpg_vlc_decode_direct_symbols(const vlc_symbol_code_jpeg * symbol_code, uint16_t * const table_ram, const uint32_t width, 416 const uint32_t leading) { 417 uint32_t offset, limit; 418 uint16_t entry; 419 420 /* this function is only for codes short enough to produce valid symbols */ 421 IMG_ASSERT( symbol_code->code_length <= leading + width ); 422 IMG_ASSERT( symbol_code->code_length > leading ); 423 424 /* lose bits already decoded */ 425 offset = symbol_code->code << leading; 426 offset &= JPG_MAKE_MASK(JPG_VLC_MAX_CODE_LEN); 427 428 /* convert truncated code to offset */ 429 offset >>= (JPG_VLC_MAX_CODE_LEN - width); 430 /* expand offset to encorporate undefined code bits */ 431 limit = offset + (1 << (width - (symbol_code->code_length - leading))); 432 433 /* for all code variants - insert symbol into the decode direct result table */ 434 entry = jpg_vlc_valid_symbol( symbol_code, leading ); 435 for (; offset < limit; offset++) { 436 table_ram[offset] = entry; 437 } 438 439 /* return the number of entries written */ 440 return limit - offset - 1; 441 } 442 443 static uint32_t 444 jpg_vlc_decode_direct( 445 const vlc_symbol_code_jpeg * symbol_codes, 446 const uint32_t num_codes, 447 uint16_t * const table_ram, 448 const uint32_t direct_width, 449 const uint32_t leading_width, 450 const uint32_t leading_pattern) { 451 const uint32_t next_leading_width = leading_width + direct_width; 452 const uint32_t next_leading_mask = JPG_MAKE_MASK(next_leading_width) << (JPG_VLC_MAX_CODE_LEN-next_leading_width); 453 const uint32_t leading_mask = JPG_MAKE_MASK(leading_width) << (JPG_VLC_MAX_CODE_LEN-leading_width); 454 455 uint32_t num_vlc_ops = 1 << direct_width; 456 uint32_t next_section, next_width, next_leading_pattern; 457 uint32_t offset; 458 uint32_t i; 459 460 /* sanity - check this decode direct will not exceed the max code len */ 461 IMG_ASSERT(next_leading_width <= JPG_VLC_MAX_CODE_LEN); 462 463 /* set all VLC ops for this decode direct to invalid */ 464 for (i = 0; i < num_vlc_ops; i++) { 465 table_ram[i] = (JPG_OP_CODE_INVALID << (JPG_INSTR_SHIFT_WIDTH+JPG_INSTR_OFFSET_WIDTH)); 466 } 467 468 /* iterate over code table and insert VLC ops until */ 469 /* codes become too long for this iteration or we run out of codes */ 470 for (i = 0; symbol_codes[i].code_length <= next_leading_width && i < num_codes; i++) { 471 /* only use codes that match the specified leading portion */ 472 if ((((uint32_t)symbol_codes[i].code) & leading_mask) == leading_pattern) { 473 jpg_vlc_decode_direct_symbols(&symbol_codes[i], table_ram, direct_width, leading_width ); 474 } 475 } 476 next_section = i; 477 478 /* assign the longest code length for each remaining entry */ 479 for (i = next_section; i < num_codes; i++) { 480 /* only use codes that match the specified leading portion */ 481 if ((((uint32_t)symbol_codes[i].code) & leading_mask) == leading_pattern) { 482 /* enable the unused VLC bit to indicate this is not a command */ 483 offset = jpg_vlc_get_offset(&symbol_codes[i], direct_width, leading_width); 484 table_ram[offset] = 0x8000 | (symbol_codes[i].code_length - next_leading_width); 485 } 486 } 487 488 /* for the remaining (long) codes */ 489 for (i = next_section; i < num_codes; i++) { 490 /* only use codes that match the specified leading portion */ 491 if ((((uint32_t)symbol_codes[i].code) & leading_mask) == leading_pattern) { 492 /* if a command has not been written for this direct offset */ 493 offset = jpg_vlc_get_offset(&symbol_codes[i], direct_width, leading_width); 494 if (table_ram[offset] & 0x8000) { 495 /* write command the decode direct command */ 496 next_width = jpg_vlc_write_direct_command( 497 &table_ram[offset], 498 num_vlc_ops - offset ); 499 500 next_leading_pattern = (uint32_t)symbol_codes[i].code & next_leading_mask; 501 502 /* decode direct recursive call */ 503 num_vlc_ops += jpg_vlc_decode_direct( 504 &symbol_codes[i], 505 num_codes - i, 506 &table_ram[num_vlc_ops], 507 next_width, 508 next_leading_width, 509 next_leading_pattern); 510 } 511 } 512 } 513 return num_vlc_ops; 514 } 515 516 static void JPG_VLC_CompileTable( 517 const vlc_symbol_code_jpeg * symbol_codes, 518 const vlc_symbol_stats_jpeg * psSymbolStats, 519 const uint32_t __maybe_unused ram_size, 520 uint16_t * table_ram, 521 vlc_table_stats_jpeg * ptable_stats) 522 { 523 ptable_stats->initial_width = 5; 524 ptable_stats->initial_opcode = JPG_OP_DECODE_DIRECT; 525 526 ptable_stats->size = jpg_vlc_decode_direct( 527 symbol_codes, 528 psSymbolStats->num_codes, 529 table_ram, 530 JPG_VLC_MAX_DIRECT_WIDTH, 531 0, 532 0); 533 534 IMG_ASSERT( ptable_stats->size <= ram_size ); 535 } 536 537 static void compile_huffman_tables(context_JPEG_p ctx) { 538 VAStatus vaStatus = VA_STATUS_SUCCESS; 539 ctx->huffman_table_space = 1984; 540 541 if (0 == psb_buffer_map(&ctx->vlc_packed_table, (unsigned char **)&ctx->huffman_table_RAM)) { 542 // Compile Tables 543 uint32_t table_class; 544 uint32_t table_id; 545 for (table_class = 0; table_class < TABLE_CLASS_NUM; table_class++) { 546 for (table_id = 0; table_id < JPEG_MAX_SETS_HUFFMAN_TABLES; table_id++) { 547 if (ctx->symbol_stats[table_class][table_id].num_codes) { 548 JPG_VLC_CompileTable(ctx->symbol_codes[table_class][table_id], 549 &ctx->symbol_stats[table_class][table_id], ctx->huffman_table_space, ctx->huffman_table_RAM, 550 &ctx->table_stats[table_class][table_id]); 551 ctx->huffman_table_space -= ctx->table_stats[table_class][table_id].size; 552 ctx->huffman_table_RAM += ctx->table_stats[table_class][table_id].size; 553 } 554 555 } 556 } 557 psb_buffer_unmap(&ctx->vlc_packed_table); 558 } else { 559 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 560 DEBUG_FAILURE; 561 } 562 563 } 564 565 static VAStatus tng__JPEG_process_picture_param(context_JPEG_p ctx, object_buffer_p obj_buffer) { 566 VAStatus vaStatus; 567 ASSERT(obj_buffer->type == VAPictureParameterBufferType); 568 ASSERT(obj_buffer->num_elements == 1); 569 ASSERT(obj_buffer->size == sizeof(VAPictureParameterBufferJPEGBaseline)); 570 571 if ((obj_buffer->num_elements != 1) || 572 (obj_buffer->size != sizeof(VAPictureParameterBufferJPEGBaseline))) { 573 return VA_STATUS_ERROR_UNKNOWN; 574 } 575 576 /* Transfer ownership of VAPictureParameterBufferJPEGBaseline data */ 577 if (ctx->pic_params) { 578 free(ctx->pic_params); 579 } 580 ctx->pic_params = (VAPictureParameterBufferJPEGBaseline *) obj_buffer->buffer_data; 581 ctx->display_picture_width = ctx->pic_params->picture_width; 582 ctx->display_picture_height = ctx->pic_params->picture_height; 583 584 ctx->coded_picture_width = ( ctx->display_picture_width + 7 ) & ( ~7 ); 585 ctx->coded_picture_height = ( ctx->display_picture_height + 7 ) & ( ~7 ); 586 ctx->max_scalingH = 0; 587 ctx->max_scalingV = 0; 588 589 uint8_t component_id; 590 for (component_id = 0; component_id < ctx->pic_params->num_components; component_id++) { 591 if (ctx->max_scalingH < ctx->pic_params->components->h_sampling_factor) 592 ctx->max_scalingH = ctx->pic_params->components->h_sampling_factor; 593 if (ctx->max_scalingV < ctx->pic_params->components->v_sampling_factor) 594 ctx->max_scalingV = ctx->pic_params->components->v_sampling_factor; 595 } 596 597 ctx->MCU_width = (ctx->coded_picture_width + (8 * ctx->max_scalingH) - 1) / (8 * ctx->max_scalingH); 598 ctx->MCU_height = (ctx->coded_picture_height + (8 * ctx->max_scalingV) - 1) / (8 * ctx->max_scalingV); 599 600 ctx->picture_width_mb = (ctx->coded_picture_width + 15) / 16; 601 ctx->picture_height_mb = (ctx->coded_picture_height + 15) / 16; 602 ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb; 603 604 605 obj_buffer->buffer_data = NULL; 606 obj_buffer->size = 0; 607 608 609 return VA_STATUS_SUCCESS; 610 } 611 612 static void tng__JPEG_write_qmatrices(context_JPEG_p ctx) { 613 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 614 int i; 615 616 psb_cmdbuf_rendec_start(cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET); 617 618 for (i = 0; i < 16; i++) { 619 psb_cmdbuf_rendec_write(cmdbuf, ctx->rendec_qmatrix[0][i]); 620 } 621 for (i = 0; i < 16; i++) { 622 psb_cmdbuf_rendec_write(cmdbuf, ctx->rendec_qmatrix[1][i]); 623 } 624 for (i = 0; i < 16; i++) { 625 psb_cmdbuf_rendec_write(cmdbuf, ctx->rendec_qmatrix[2][i]); 626 } 627 for (i = 0; i < 16; i++) { 628 psb_cmdbuf_rendec_write(cmdbuf, ctx->rendec_qmatrix[3][i]); 629 } 630 631 psb_cmdbuf_rendec_end(cmdbuf); 632 } 633 634 static VAStatus tng__JPEG_process_iq_matrix(context_JPEG_p ctx, object_buffer_p obj_buffer) { 635 VAIQMatrixBufferJPEGBaseline *qmatrix_data = (VAIQMatrixBufferJPEGBaseline *) obj_buffer->buffer_data; 636 ASSERT(obj_buffer->type == VAIQMatrixBufferType); 637 ASSERT(obj_buffer->num_elements == 1); 638 ASSERT(obj_buffer->size == sizeof(VAIQMatrixBufferJPEGBaseline)); 639 640 uint32_t dqt_ind; 641 642 for (dqt_ind = 0; dqt_ind < 4; dqt_ind++) { 643 // Reorder Quant table for hardware 644 uint32_t table_ind = 0; 645 uint32_t rendec_table_ind = 0; 646 if (qmatrix_data->load_quantiser_table[dqt_ind]) { 647 while(table_ind < 64) { 648 ctx->rendec_qmatrix[dqt_ind][rendec_table_ind] = 649 (qmatrix_data->quantiser_table[dqt_ind][inverse_zigzag[table_ind+3]] << 24) | 650 (qmatrix_data->quantiser_table[dqt_ind][inverse_zigzag[table_ind+2]] << 16) | 651 (qmatrix_data->quantiser_table[dqt_ind][inverse_zigzag[table_ind+1]] << 8) | 652 (qmatrix_data->quantiser_table[dqt_ind][inverse_zigzag[table_ind]]); 653 654 table_ind += 4; 655 rendec_table_ind++; 656 } 657 } 658 } 659 660 return VA_STATUS_SUCCESS; 661 } 662 663 664 static void tng__JPEG_write_huffman_tables(context_JPEG_p ctx) { 665 uint32_t reg_value; 666 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 667 668 // VLC Table 669 // Write a LLDMA Cmd to transfer VLD Table data 670 psb_cmdbuf_dma_write_cmdbuf(cmdbuf, &ctx->vlc_packed_table, 0, 671 ctx->vlctable_buffer_size, 0, 672 DMA_TYPE_VLC_TABLE); 673 674 // Write Table addresses 675 psb_cmdbuf_reg_start_block(cmdbuf, 0); 676 reg_value = 0; 677 uint32_t table_address = 0; 678 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0, VLC_TABLE_ADDR0, table_address ); 679 table_address += ctx->table_stats[0][0].size; 680 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0, VLC_TABLE_ADDR1, table_address ); 681 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0 ), reg_value); 682 683 reg_value = 0; 684 table_address += ctx->table_stats[0][1].size; 685 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2, VLC_TABLE_ADDR4, table_address ); 686 table_address += ctx->table_stats[1][0].size; 687 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2, VLC_TABLE_ADDR5, table_address ); 688 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2 ), reg_value); 689 psb_cmdbuf_reg_end_block(cmdbuf); 690 691 // Write Initial Widths 692 psb_cmdbuf_reg_start_block(cmdbuf, 0); 693 reg_value = 0; 694 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH0, 695 ctx->table_stats[0][0].initial_width ); 696 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH1, 697 ctx->table_stats[0][1].initial_width ); 698 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH4, 699 ctx->table_stats[1][0].initial_width ); 700 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH5, 701 ctx->table_stats[1][1].initial_width ); 702 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0 ), reg_value); 703 psb_cmdbuf_reg_end_block(cmdbuf); 704 705 // Write Initial Opcodes 706 psb_cmdbuf_reg_start_block(cmdbuf, 0); 707 reg_value = 0; 708 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE0, 709 ctx->table_stats[0][0].initial_opcode ); 710 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE1, 711 ctx->table_stats[0][1].initial_opcode ); 712 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE4, 713 ctx->table_stats[1][0].initial_opcode ); 714 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE5, 715 ctx->table_stats[1][1].initial_opcode ); 716 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0 ), reg_value); 717 psb_cmdbuf_reg_end_block(cmdbuf); 718 719 } 720 721 static VAStatus tng__JPEG_process_huffman_tables(context_JPEG_p ctx, object_buffer_p obj_buffer) { 722 723 VAHuffmanTableBufferJPEGBaseline *huff = (VAHuffmanTableBufferJPEGBaseline *) obj_buffer->buffer_data; 724 ASSERT(obj_buffer->type == VAHuffmanTableBufferType); 725 ASSERT(obj_buffer->num_elements == 1); 726 ASSERT(obj_buffer->size == sizeof(VAHuffmanTableBufferJPEGBaseline)); 727 728 uint32_t table_id; 729 for (table_id = 0; table_id < JPEG_MAX_SETS_HUFFMAN_TABLES; table_id++) { 730 // Find out the number of entries in the table 731 uint32_t table_entries = 0; 732 uint32_t bit_ind; 733 for (bit_ind = 0; bit_ind < 16; bit_ind++) { 734 table_entries += huff->huffman_table[table_id].num_dc_codes[bit_ind]; 735 } 736 737 ctx->symbol_codes[0][table_id] =(vlc_symbol_code_jpeg *)malloc(sizeof(vlc_symbol_code_jpeg) * table_entries); 738 // Parse huffman code sizes 739 uint32_t huff_ind = 0; 740 for (bit_ind = 0; bit_ind < 16; bit_ind++) { 741 uint32_t num_codes = huff->huffman_table[table_id].num_dc_codes[bit_ind]; 742 while (num_codes) { 743 ctx->symbol_codes[0][table_id][huff_ind].code_length = bit_ind + 1; 744 num_codes--; 745 huff_ind++; 746 } 747 } 748 749 // Calculate huffman codes 750 751 uint16_t code = 0; 752 uint8_t code_size = ctx->symbol_codes[0][table_id][0].code_length; 753 huff_ind = 0; 754 755 while (huff_ind < table_entries) { 756 if (ctx->symbol_codes[0][table_id][huff_ind].code_length == code_size) { 757 ctx->symbol_codes[0][table_id][huff_ind].code = code << ( 16 - code_size ); 758 huff_ind++; 759 code++; 760 } else { 761 code <<= 1; 762 code_size++; 763 } 764 } 765 766 // Create table of code values 767 uint32_t table_ind; 768 for (table_ind = 0; table_ind < table_entries; table_ind++) { 769 ctx->symbol_codes[0][table_id][table_ind].symbol = huff->huffman_table[table_id].dc_values[table_ind]; 770 } 771 772 // Store the number of codes in the table 773 ctx->symbol_stats[0][table_id].num_codes = table_entries; 774 775 // for AC table 776 // Find out the number of entries in the table 777 table_entries = 0; 778 for (bit_ind = 0; bit_ind < 16; bit_ind++) { 779 table_entries += huff->huffman_table[table_id].num_ac_codes[bit_ind]; 780 } 781 782 // Allocate memory for huffman table codes 783 ctx->symbol_codes[1][table_id] = (vlc_symbol_code_jpeg *)malloc(sizeof(vlc_symbol_code_jpeg) * table_entries); 784 785 // Parse huffman code sizes 786 huff_ind = 0; 787 for (bit_ind = 0; bit_ind < 16; bit_ind++) { 788 uint32_t num_codes = huff->huffman_table[table_id].num_ac_codes[bit_ind]; 789 while (num_codes) { 790 ctx->symbol_codes[1][table_id][huff_ind].code_length = bit_ind + 1; 791 num_codes--; 792 huff_ind++; 793 } 794 } 795 796 // Calculate huffman codes 797 code = 0; 798 code_size = ctx->symbol_codes[1][table_id][0].code_length; 799 huff_ind = 0; 800 while (huff_ind < table_entries) { 801 if (ctx->symbol_codes[1][table_id][huff_ind].code_length == code_size) { 802 ctx->symbol_codes[1][table_id][huff_ind].code = code << ( 16 - code_size ); 803 huff_ind++; 804 code++; 805 } else { 806 code <<= 1; 807 code_size++; 808 } 809 } 810 811 // Create table of code values 812 for (table_ind = 0; table_ind < table_entries; table_ind++) { 813 ctx->symbol_codes[1][table_id][table_ind].symbol = huff->huffman_table[table_id].ac_values[table_ind];; 814 } 815 // Store the number of codes in the table 816 ctx->symbol_stats[1][table_id].num_codes = table_entries; 817 } 818 819 compile_huffman_tables(ctx); 820 821 return VA_STATUS_SUCCESS; 822 } 823 824 825 static void tng__JPEG_set_operating_mode(context_JPEG_p ctx) { 826 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 827 ctx->obj_context->operating_mode = 0; 828 829 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, USE_EXT_ROW_STRIDE, 1 ); 830 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1 ); 831 REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1); 832 833 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_CMDS, OPERATING_MODE )); 834 835 psb_cmdbuf_rendec_write(cmdbuf, ctx->obj_context->operating_mode); 836 837 psb_cmdbuf_rendec_end(cmdbuf); 838 839 } 840 841 static void tng__JPEG_set_reference_pictures(context_JPEG_p ctx) 842 { 843 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 844 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 845 846 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES)); 847 848 uint32_t planr_size = target_surface->chroma_offset; 849 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); 850 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + planr_size); 851 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + planr_size * 2); 852 // psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + planr_size * 3); 853 psb_cmdbuf_rendec_end(cmdbuf); 854 } 855 856 static void tng__JPEG_set_ent_dec(context_JPEG_p ctx) { 857 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 858 uint32_t reg_value; 859 860 psb_cmdbuf_reg_start_block(cmdbuf, 0); 861 reg_value = 0; 862 REGIO_WRITE_FIELD_LITE( reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_MODE, 0 ); 863 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL ), reg_value); 864 psb_cmdbuf_reg_end_block(cmdbuf); 865 866 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL )); 867 reg_value = 0; 868 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 0); 869 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 870 psb_cmdbuf_rendec_end(cmdbuf); 871 872 } 873 874 static void tng__JPEG_set_register(context_JPEG_p ctx, VASliceParameterBufferJPEGBaseline *slice_param) { 875 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 876 uint32_t reg_value; 877 const uint32_t num_MCUs = ctx->MCU_width * ctx->MCU_height; 878 const uint32_t num_MCUs_dec = slice_param->restart_interval ? min(slice_param->restart_interval, num_MCUs) : num_MCUs; 879 880 psb_cmdbuf_reg_start_block(cmdbuf, 0); 881 // CR_VEC_JPEG_FE_COMPONENTS 882 reg_value = 0; 883 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, MAX_V, ctx->max_scalingV); 884 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, MAX_H, ctx->max_scalingH); 885 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS, FE_COMPONENTS, 886 slice_param->num_components); 887 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_COMPONENTS ), reg_value); 888 889 // CR_VEC_JPEG_FE_HEIGHT 890 reg_value = 0; 891 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_HEIGHT, FE_HEIGHT_MINUS1, 892 ctx->coded_picture_height - 1); 893 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_HEIGHT ), reg_value); 894 895 // CR_VEC_JPEG_FE_RESTART_POS 896 reg_value = 0; 897 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_RESTART_POS), reg_value); 898 899 // CR_VEC_JPEG_FE_WIDTH 900 reg_value = 0; 901 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_WIDTH, FE_WIDTH_MINUS1, 902 ctx->coded_picture_width - 1 ); 903 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_WIDTH), reg_value); 904 905 // CR_VEC_JPEG_FE_ENTROPY_CODING 906 reg_value = 0; 907 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, NUM_MCUS_LESS1, num_MCUs_dec - 1); 908 909 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA3, 910 slice_param->components[3].ac_table_selector); 911 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD3, 912 slice_param->components[3].dc_table_selector); 913 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA2, 914 slice_param->components[2].ac_table_selector); 915 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD2, 916 slice_param->components[2].dc_table_selector); 917 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA1, 918 slice_param->components[1].ac_table_selector); 919 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD1, 920 slice_param->components[1].dc_table_selector ); 921 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TA0, 922 slice_param->components[0].ac_table_selector); 923 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING, TD0, 924 slice_param->components[0].dc_table_selector); 925 926 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_ENTROPY_CODING ), reg_value); 927 928 // CR_VEC_JPEG_FE_SCALING 929 reg_value = 0; 930 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V3, 931 ctx->pic_params->components[3].v_sampling_factor); 932 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H3, 933 ctx->pic_params->components[3].h_sampling_factor ); 934 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V2, 935 ctx->pic_params->components[2].v_sampling_factor); 936 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H2, 937 ctx->pic_params->components[2].h_sampling_factor ); 938 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V1, 939 ctx->pic_params->components[1].v_sampling_factor ); 940 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H1, 941 ctx->pic_params->components[1].h_sampling_factor ); 942 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_V0, 943 ctx->pic_params->components[0].v_sampling_factor ); 944 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING, FE_H0, 945 ctx->pic_params->components[0].h_sampling_factor ); 946 947 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_FE_SCALING ), reg_value); 948 psb_cmdbuf_reg_end_block(cmdbuf); 949 950 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_HEIGHT )); 951 // CR_VEC_JPEG_BE_HEIGHT 952 reg_value = 0; 953 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_HEIGHT, BE_HEIGHT_MINUS1, 954 ctx->coded_picture_height - 1); 955 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 956 957 // CR_VEC_JPEG_BE_WIDTH 958 reg_value = 0; 959 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_WIDTH, BE_WIDTH_MINUS1, ctx->coded_picture_width - 1); 960 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 961 962 // CR_VEC_JPEG_BE_QUANTISATION 963 reg_value = 0; 964 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ3, 965 ctx->pic_params->components[3].quantiser_table_selector); 966 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ2, 967 ctx->pic_params->components[2].quantiser_table_selector); 968 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ1, 969 ctx->pic_params->components[1].quantiser_table_selector); 970 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_QUANTISATION, TQ0, 971 ctx->pic_params->components[0].quantiser_table_selector ); 972 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 973 974 // CR_VEC_JPEG_BE_CONTROL 975 reg_value = 0; 976 REGIO_WRITE_FIELD( reg_value, MSVDX_VEC_JPEG, CR_VEC_JPEG_BE_CONTROL, RGB, 0 ); 977 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 978 979 psb_cmdbuf_rendec_end(cmdbuf); 980 } 981 982 static void tng__JPEG_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase __maybe_unused * vld_slice_param) 983 { 984 context_JPEG_p ctx = (context_JPEG_p)dec_ctx; 985 986 dec_ctx->bits_offset = 0; 987 dec_ctx->SR_flags = CMD_ENABLE_RBDU_EXTRACTION; 988 *dec_ctx->cmd_params |=ctx->MCU_width * ctx->MCU_height; 989 *dec_ctx->slice_first_pic_last &= 0xfefe; 990 tng__JPEG_write_huffman_tables(ctx); 991 tng__JPEG_write_qmatrices(ctx); 992 } 993 994 static void tng__JPEG_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param) 995 { 996 VASliceParameterBufferJPEGBaseline *slice_param = (VASliceParameterBufferJPEGBaseline *) vld_slice_param; 997 context_JPEG_p ctx = (context_JPEG_p)dec_ctx; 998 999 tng__JPEG_set_operating_mode(ctx); 1000 tng__JPEG_set_reference_pictures(ctx); 1001 vld_dec_setup_alternative_frame(ctx->obj_context); 1002 tng__JPEG_set_ent_dec(ctx); 1003 tng__JPEG_set_register(ctx, slice_param); 1004 } 1005 1006 static void tng__JPEG_end_slice(context_DEC_p dec_ctx) 1007 { 1008 context_JPEG_p ctx = (context_JPEG_p)dec_ctx; 1009 1010 ctx->obj_context->flags = FW_VA_RENDER_IS_FIRST_SLICE | FW_VA_RENDER_IS_LAST_SLICE | FW_INTERNAL_CONTEXT_SWITCH; 1011 ctx->obj_context->first_mb = 0; 1012 ctx->obj_context->last_mb = ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1); 1013 *(dec_ctx->slice_first_pic_last) = (ctx->obj_context->first_mb << 16) | ((ctx->obj_context->last_mb) & 0xfefe); 1014 1015 } 1016 1017 static VAStatus tng_JPEG_BeginPicture( 1018 object_context_p obj_context) { 1019 INIT_CONTEXT_JPEG 1020 1021 if (ctx->pic_params) { 1022 free(ctx->pic_params); 1023 ctx->pic_params = NULL; 1024 } 1025 1026 return VA_STATUS_SUCCESS; 1027 } 1028 1029 static VAStatus tng_JPEG_process_buffer( 1030 context_DEC_p dec_ctx, 1031 object_buffer_p buffer) { 1032 context_JPEG_p ctx = (context_JPEG_p)dec_ctx; 1033 VAStatus vaStatus = VA_STATUS_SUCCESS; 1034 object_buffer_p obj_buffer = buffer; 1035 1036 switch (obj_buffer->type) { 1037 case VAPictureParameterBufferType: 1038 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_JPEG_RenderPicture got VAPictureParameterBuffer\n"); 1039 vaStatus = tng__JPEG_process_picture_param(ctx, obj_buffer); 1040 DEBUG_FAILURE; 1041 break; 1042 1043 case VAIQMatrixBufferType: 1044 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_JPEG_RenderPicture got VAIQMatrixBufferType\n"); 1045 vaStatus = tng__JPEG_process_iq_matrix(ctx, obj_buffer); 1046 DEBUG_FAILURE; 1047 break; 1048 1049 case VAHuffmanTableBufferType: 1050 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_JPEG_RenderPicture got VAIQMatrixBufferType\n"); 1051 vaStatus = tng__JPEG_process_huffman_tables(ctx, obj_buffer); 1052 DEBUG_FAILURE; 1053 break; 1054 1055 default: 1056 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1057 DEBUG_FAILURE; 1058 } 1059 1060 return vaStatus; 1061 } 1062 1063 static VAStatus tng_JPEG_EndPicture( 1064 object_context_p obj_context) { 1065 INIT_CONTEXT_JPEG 1066 1067 if (psb_context_flush_cmdbuf(ctx->obj_context)) { 1068 return VA_STATUS_ERROR_UNKNOWN; 1069 } 1070 1071 if (ctx->pic_params) { 1072 free(ctx->pic_params); 1073 ctx->pic_params = NULL; 1074 } 1075 1076 return VA_STATUS_SUCCESS; 1077 } 1078 1079 struct format_vtable_s tng_JPEG_vtable = { 1080 queryConfigAttributes: 1081 tng_JPEG_QueryConfigAttributes, 1082 validateConfig: 1083 tng_JPEG_ValidateConfig, 1084 createContext: 1085 tng_JPEG_CreateContext, 1086 destroyContext: 1087 tng_JPEG_DestroyContext, 1088 beginPicture: 1089 tng_JPEG_BeginPicture, 1090 renderPicture: 1091 vld_dec_RenderPicture, 1092 endPicture: 1093 tng_JPEG_EndPicture 1094 }; 1095