1/* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19/** 20 * @file 21 * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1 22 */ 23 24#include "libavutil/avassert.h" 25#include "libavutil/thread.h" 26#include "avcodec.h" 27#include "get_bits.h" 28#include "idctdsp.h" 29#include "msmpeg4data.h" 30#include "intrax8huf.h" 31#include "intrax8.h" 32#include "intrax8dsp.h" 33#include "mpegutils.h" 34 35#define VLC_BUFFER_SIZE 28150 36 37#define MAX_TABLE_DEPTH(table_bits, max_bits) \ 38 ((max_bits + table_bits - 1) / table_bits) 39 40#define DC_VLC_BITS 9 41#define AC_VLC_BITS 9 42#define OR_VLC_BITS 7 43 44#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS) 45#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS) 46#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS) 47 48static VLC j_ac_vlc[2][2][8]; // [quant < 13], [intra / inter], [select] 49static VLC j_dc_vlc[2][8]; // [quant], [select] 50static VLC j_orient_vlc[2][4]; // [quant], [select] 51 52static av_cold void x8_init_vlc(VLC *vlc, int nb_bits, int nb_codes, 53 int *offset, const uint8_t table[][2]) 54{ 55 static VLCElem vlc_buf[VLC_BUFFER_SIZE]; 56 57 vlc->table = &vlc_buf[*offset]; 58 vlc->table_allocated = VLC_BUFFER_SIZE - *offset; 59 ff_init_vlc_from_lengths(vlc, nb_bits, nb_codes, &table[0][1], 2, 60 &table[0][0], 2, 1, 0, INIT_VLC_STATIC_OVERLONG, NULL); 61 *offset += vlc->table_size; 62} 63 64static av_cold void x8_vlc_init(void) 65{ 66 int i; 67 int offset = 0; 68 69// set ac tables 70 for (int i = 0; i < 2; i++) 71 for (int j = 0; j < 2; j++) 72 for (int k = 0; k < 8; k++) 73 x8_init_vlc(&j_ac_vlc[i][j][k], AC_VLC_BITS, 77, 74 &offset, x8_ac_quant_table[i][j][k]); 75 76// set dc tables 77 for (int i = 0; i < 2; i++) 78 for (int j = 0; j < 8; j++) 79 x8_init_vlc(&j_dc_vlc[i][j], DC_VLC_BITS, 34, &offset, 80 x8_dc_quant_table[i][j]); 81 82// set orient tables 83 for (i = 0; i < 2; i++) 84 x8_init_vlc(&j_orient_vlc[0][i], OR_VLC_BITS, 12, 85 &offset, x8_orient_highquant_table[i]); 86 for (i = 0; i < 4; i++) 87 x8_init_vlc(&j_orient_vlc[1][i], OR_VLC_BITS, 12, 88 &offset, x8_orient_lowquant_table[i]); 89 90 av_assert2(offset == VLC_BUFFER_SIZE); 91} 92 93static void x8_reset_vlc_tables(IntraX8Context *w) 94{ 95 memset(w->j_dc_vlc, 0, sizeof(w->j_dc_vlc)); 96 memset(w->j_ac_vlc, 0, sizeof(w->j_ac_vlc)); 97 w->j_orient_vlc = NULL; 98} 99 100static inline void x8_select_ac_table(IntraX8Context *const w, int mode) 101{ 102 int table_index; 103 104 av_assert2(mode < 4); 105 106 if (w->j_ac_vlc[mode]) 107 return; 108 109 table_index = get_bits(w->gb, 3); 110 // 2 modes use same tables 111 w->j_ac_vlc[mode] = &j_ac_vlc[w->quant < 13][mode >> 1][table_index]; 112 av_assert2(w->j_ac_vlc[mode]); 113} 114 115static inline int x8_get_orient_vlc(IntraX8Context *w) 116{ 117 if (!w->j_orient_vlc) { 118 int table_index = get_bits(w->gb, 1 + (w->quant < 13)); 119 w->j_orient_vlc = &j_orient_vlc[w->quant < 13][table_index]; 120 } 121 122 return get_vlc2(w->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD); 123} 124 125#define extra_bits(eb) (eb) // 3 bits 126#define extra_run (0xFF << 8) // 1 bit 127#define extra_level (0x00 << 8) // 1 bit 128#define run_offset(r) ((r) << 16) // 6 bits 129#define level_offset(l) ((l) << 24) // 5 bits 130static const uint32_t ac_decode_table[] = { 131 /* 46 */ extra_bits(3) | extra_run | run_offset(16) | level_offset(0), 132 /* 47 */ extra_bits(3) | extra_run | run_offset(24) | level_offset(0), 133 /* 48 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1), 134 /* 49 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1), 135 136 /* 50 */ extra_bits(5) | extra_run | run_offset(32) | level_offset(0), 137 /* 51 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1), 138 139 /* 52 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4), 140 /* 53 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(8), 141 /* 54 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(12), 142 /* 55 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(16), 143 /* 56 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(24), 144 145 /* 57 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3), 146 /* 58 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7), 147 148 /* 59 */ extra_bits(2) | extra_run | run_offset(16) | level_offset(0), 149 /* 60 */ extra_bits(2) | extra_run | run_offset(20) | level_offset(0), 150 /* 61 */ extra_bits(2) | extra_run | run_offset(24) | level_offset(0), 151 /* 62 */ extra_bits(2) | extra_run | run_offset(28) | level_offset(0), 152 /* 63 */ extra_bits(4) | extra_run | run_offset(32) | level_offset(0), 153 /* 64 */ extra_bits(4) | extra_run | run_offset(48) | level_offset(0), 154 155 /* 65 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1), 156 /* 66 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1), 157 /* 67 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1), 158 159 /* 68 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4), 160 /* 69 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(8), 161 /* 70 */ extra_bits(4) | extra_level | run_offset(0) | level_offset(16), 162 163 /* 71 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3), 164 /* 72 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7), 165}; 166#undef extra_bits 167#undef extra_run 168#undef extra_level 169#undef run_offset 170#undef level_offset 171 172static void x8_get_ac_rlf(IntraX8Context *const w, const int mode, 173 int *const run, int *const level, int *const final) 174{ 175 int i, e; 176 177// x8_select_ac_table(w, mode); 178 i = get_vlc2(w->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD); 179 180 if (i < 46) { // [0-45] 181 int t, l; 182 if (i < 0) { 183 *level = 184 *final = // prevent 'may be used uninitialized' 185 *run = 64; // this would cause error exit in the ac loop 186 return; 187 } 188 189 /* 190 * i == 0-15 r = 0-15 l = 0; r = i & %01111 191 * i == 16-19 r = 0-3 l = 1; r = i & %00011 192 * i == 20-21 r = 0-1 l = 2; r = i & %00001 193 * i == 22 r = 0 l = 3; r = i & %00000 194 */ 195 196 *final = 197 t = i > 22; 198 i -= 23 * t; 199 200 /* l = lut_l[i / 2] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3 }[i >> 1]; 201 * 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 */ 202 l = (0xE50000 >> (i & 0x1E)) & 3; // 0x1E or ~1 or (i >> 1 << 1) 203 204 /* t = lut_mask[l] = { 0x0f, 0x03, 0x01, 0x00 }[l]; 205 * as i < 256 the higher bits do not matter */ 206 t = 0x01030F >> (l << 3); 207 208 *run = i & t; 209 *level = l; 210 } else if (i < 73) { // [46-72] 211 uint32_t sm; 212 uint32_t mask; 213 214 i -= 46; 215 sm = ac_decode_table[i]; 216 217 e = get_bits(w->gb, sm & 0xF); 218 sm >>= 8; // 3 bits 219 mask = sm & 0xff; 220 sm >>= 8; // 1 bit 221 222 *run = (sm & 0xff) + (e & mask); // 6 bits 223 *level = (sm >> 8) + (e & ~mask); // 5 bits 224 *final = i > (58 - 46); 225 } else if (i < 75) { // [73-74] 226 static const uint8_t crazy_mix_runlevel[32] = { 227 0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63, 228 0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83, 229 0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64, 230 0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84, 231 }; 232 233 *final = !(i & 1); 234 e = get_bits(w->gb, 5); // get the extra bits 235 *run = crazy_mix_runlevel[e] >> 4; 236 *level = crazy_mix_runlevel[e] & 0x0F; 237 } else { 238 *level = get_bits(w->gb, 7 - 3 * (i & 1)); 239 *run = get_bits(w->gb, 6); 240 *final = get_bits1(w->gb); 241 } 242 return; 243} 244 245/* static const uint8_t dc_extra_sbits[] = { 246 * 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 247 * }; */ 248static const uint8_t dc_index_offset[] = { 249 0, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 250}; 251 252static int x8_get_dc_rlf(IntraX8Context *const w, const int mode, 253 int *const level, int *const final) 254{ 255 int i, e, c; 256 257 av_assert2(mode < 3); 258 if (!w->j_dc_vlc[mode]) { 259 int table_index = get_bits(w->gb, 3); 260 // 4 modes, same table 261 w->j_dc_vlc[mode] = &j_dc_vlc[w->quant < 13][table_index]; 262 } 263 264 i = get_vlc2(w->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD); 265 266 /* (i >= 17) { i -= 17; final =1; } */ 267 c = i > 16; 268 *final = c; 269 i -= 17 * c; 270 271 if (i <= 0) { 272 *level = 0; 273 return -i; 274 } 275 c = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[] 276 c -= c > 1; 277 278 e = get_bits(w->gb, c); // get the extra bits 279 i = dc_index_offset[i] + (e >> 1); 280 281 e = -(e & 1); // 0, 0xffffff 282 *level = (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1) 283 return 0; 284} 285 286// end of huffman 287 288static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma) 289{ 290 int range; 291 int sum; 292 int quant; 293 294 w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad, 295 w->frame->linesize[chroma > 0], 296 &range, &sum, w->edges); 297 if (chroma) { 298 w->orient = w->chroma_orient; 299 quant = w->quant_dc_chroma; 300 } else { 301 quant = w->quant; 302 } 303 304 w->flat_dc = 0; 305 if (range < quant || range < 3) { 306 w->orient = 0; 307 308 // yep you read right, a +-1 idct error may break decoding! 309 if (range < 3) { 310 w->flat_dc = 1; 311 sum += 9; 312 // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899 313 w->predicted_dc = sum * 6899 >> 17; 314 } 315 } 316 if (chroma) 317 return 0; 318 319 av_assert2(w->orient < 3); 320 if (range < 2 * w->quant) { 321 if ((w->edges & 3) == 0) { 322 if (w->orient == 1) 323 w->orient = 11; 324 if (w->orient == 2) 325 w->orient = 10; 326 } else { 327 w->orient = 0; 328 } 329 w->raw_orient = 0; 330 } else { 331 static const uint8_t prediction_table[3][12] = { 332 { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 }, 333 { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 }, 334 { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 }, 335 }; 336 w->raw_orient = x8_get_orient_vlc(w); 337 if (w->raw_orient < 0) 338 return -1; 339 av_assert2(w->raw_orient < 12); 340 av_assert2(w->orient < 3); 341 w->orient=prediction_table[w->orient][w->raw_orient]; 342 } 343 return 0; 344} 345 346static void x8_update_predictions(IntraX8Context *const w, const int orient, 347 const int est_run) 348{ 349 w->prediction_table[w->mb_x * 2 + (w->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8); 350/* 351 * y = 2n + 0 -> // 0 2 4 352 * y = 2n + 1 -> // 1 3 5 353 */ 354} 355 356static void x8_get_prediction_chroma(IntraX8Context *const w) 357{ 358 w->edges = 1 * !(w->mb_x >> 1); 359 w->edges |= 2 * !(w->mb_y >> 1); 360 w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd 361 362 w->raw_orient = 0; 363 // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC 364 if (w->edges & 3) { 365 w->chroma_orient = 4 << ((0xCC >> w->edges) & 1); 366 return; 367 } 368 // block[x - 1][y | 1 - 1)] 369 w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2; 370} 371 372static void x8_get_prediction(IntraX8Context *const w) 373{ 374 int a, b, c, i; 375 376 w->edges = 1 * !w->mb_x; 377 w->edges |= 2 * !w->mb_y; 378 w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); 379 380 switch (w->edges & 3) { 381 case 0: 382 break; 383 case 1: 384 // take the one from the above block[0][y - 1] 385 w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2; 386 w->orient = 1; 387 return; 388 case 2: 389 // take the one from the previous block[x - 1][0] 390 w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2; 391 w->orient = 2; 392 return; 393 case 3: 394 w->est_run = 16; 395 w->orient = 0; 396 return; 397 } 398 // no edge cases 399 b = w->prediction_table[2 * w->mb_x + !(w->mb_y & 1)]; // block[x ][y - 1] 400 a = w->prediction_table[2 * w->mb_x - 2 + (w->mb_y & 1)]; // block[x - 1][y ] 401 c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1] 402 403 w->est_run = FFMIN(b, a); 404 /* This condition has nothing to do with w->edges, even if it looks 405 * similar it would trigger if e.g. x = 3; y = 2; 406 * I guess somebody wrote something wrong and it became standard. */ 407 if ((w->mb_x & w->mb_y) != 0) 408 w->est_run = FFMIN(c, w->est_run); 409 w->est_run >>= 2; 410 411 a &= 3; 412 b &= 3; 413 c &= 3; 414 415 i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3; 416 if (i != 3) 417 w->orient = i; 418 else 419 w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3; 420/* 421 * lut1[b][a] = { 422 * ->{ 0, 1, 0, pad }, 423 * { 0, 1, X, pad }, 424 * { 2, 2, 2, pad } 425 * } 426 * pad 2 2 2; 427 * pad X 1 0; 428 * pad 0 1 0 <- 429 * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4 430 * 431 * lut2[q>12][c] = { 432 * ->{ 0, 2, 1, pad}, 433 * { 2, 2, 2, pad} 434 * } 435 * pad 2 2 2; 436 * pad 1 2 0 <- 437 * -> 11 10'10 10 '11 01'10 00 => 0xEAD8 438 */ 439} 440 441static void x8_ac_compensation(IntraX8Context *const w, const int direction, 442 const int dc_level) 443{ 444 int t; 445#define B(x,y) w->block[0][w->idct_permutation[(x) + (y) * 8]] 446#define T(x) ((x) * dc_level + 0x8000) >> 16; 447 switch (direction) { 448 case 0: 449 t = T(3811); // h 450 B(1, 0) -= t; 451 B(0, 1) -= t; 452 453 t = T(487); // e 454 B(2, 0) -= t; 455 B(0, 2) -= t; 456 457 t = T(506); // f 458 B(3, 0) -= t; 459 B(0, 3) -= t; 460 461 t = T(135); // c 462 B(4, 0) -= t; 463 B(0, 4) -= t; 464 B(2, 1) += t; 465 B(1, 2) += t; 466 B(3, 1) += t; 467 B(1, 3) += t; 468 469 t = T(173); // d 470 B(5, 0) -= t; 471 B(0, 5) -= t; 472 473 t = T(61); // b 474 B(6, 0) -= t; 475 B(0, 6) -= t; 476 B(5, 1) += t; 477 B(1, 5) += t; 478 479 t = T(42); // a 480 B(7, 0) -= t; 481 B(0, 7) -= t; 482 B(4, 1) += t; 483 B(1, 4) += t; 484 B(4, 4) += t; 485 486 t = T(1084); // g 487 B(1, 1) += t; 488 489 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8); 490 break; 491 case 1: 492 B(0, 1) -= T(6269); 493 B(0, 3) -= T(708); 494 B(0, 5) -= T(172); 495 B(0, 7) -= T(73); 496 497 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8); 498 break; 499 case 2: 500 B(1, 0) -= T(6269); 501 B(3, 0) -= T(708); 502 B(5, 0) -= T(172); 503 B(7, 0) -= T(73); 504 505 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7); 506 break; 507 } 508#undef B 509#undef T 510} 511 512static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst, 513 const ptrdiff_t linesize) 514{ 515 int k; 516 for (k = 0; k < 8; k++) { 517 memset(dst, pix, 8); 518 dst += linesize; 519 } 520} 521 522static const int16_t quant_table[64] = { 523 256, 256, 256, 256, 256, 256, 259, 262, 524 265, 269, 272, 275, 278, 282, 285, 288, 525 292, 295, 299, 303, 306, 310, 314, 317, 526 321, 325, 329, 333, 337, 341, 345, 349, 527 353, 358, 362, 366, 371, 375, 379, 384, 528 389, 393, 398, 403, 408, 413, 417, 422, 529 428, 433, 438, 443, 448, 454, 459, 465, 530 470, 476, 482, 488, 493, 499, 505, 511, 531}; 532 533static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma) 534{ 535 uint8_t *scantable; 536 int final, run, level; 537 int ac_mode, dc_mode, est_run, dc_level; 538 int pos, n; 539 int zeros_only; 540 int use_quant_matrix; 541 int sign; 542 543 av_assert2(w->orient < 12); 544 w->bdsp.clear_block(w->block[0]); 545 546 if (chroma) 547 dc_mode = 2; 548 else 549 dc_mode = !!w->est_run; // 0, 1 550 551 if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) 552 return -1; 553 n = 0; 554 zeros_only = 0; 555 if (!final) { // decode ac 556 use_quant_matrix = w->use_quant_matrix; 557 if (chroma) { 558 ac_mode = 1; 559 est_run = 64; // not used 560 } else { 561 if (w->raw_orient < 3) 562 use_quant_matrix = 0; 563 564 if (w->raw_orient > 4) { 565 ac_mode = 0; 566 est_run = 64; 567 } else { 568 if (w->est_run > 1) { 569 ac_mode = 2; 570 est_run = w->est_run; 571 } else { 572 ac_mode = 3; 573 est_run = 64; 574 } 575 } 576 } 577 x8_select_ac_table(w, ac_mode); 578 /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <- 579 * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */ 580 scantable = w->scantable[(0x928548 >> (2 * w->orient)) & 3].permutated; 581 pos = 0; 582 do { 583 n++; 584 if (n >= est_run) { 585 ac_mode = 3; 586 x8_select_ac_table(w, 3); 587 } 588 589 x8_get_ac_rlf(w, ac_mode, &run, &level, &final); 590 591 pos += run + 1; 592 if (pos > 63) { 593 // this also handles vlc error in x8_get_ac_rlf 594 return -1; 595 } 596 level = (level + 1) * w->dquant; 597 level += w->qsum; 598 599 sign = -get_bits1(w->gb); 600 level = (level ^ sign) - sign; 601 602 if (use_quant_matrix) 603 level = (level * quant_table[pos]) >> 8; 604 605 w->block[0][scantable[pos]] = level; 606 } while (!final); 607 608 w->block_last_index[0] = pos; 609 } else { // DC only 610 w->block_last_index[0] = 0; 611 if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1] 612 int32_t divide_quant = !chroma ? w->divide_quant_dc_luma 613 : w->divide_quant_dc_chroma; 614 int32_t dc_quant = !chroma ? w->quant 615 : w->quant_dc_chroma; 616 617 // original intent dc_level += predicted_dc/quant; 618 // but it got lost somewhere in the rounding 619 dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13; 620 621 dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3), 622 w->dest[chroma], 623 w->frame->linesize[!!chroma]); 624 625 goto block_placed; 626 } 627 zeros_only = dc_level == 0; 628 } 629 if (!chroma) 630 w->block[0][0] = dc_level * w->quant; 631 else 632 w->block[0][0] = dc_level * w->quant_dc_chroma; 633 634 // there is !zero_only check in the original, but dc_level check is enough 635 if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) { 636 int direction; 637 /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <- 638 * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */ 639 direction = (0x6A017C >> (w->orient * 2)) & 3; 640 if (direction != 3) { 641 // modify block_last[] 642 x8_ac_compensation(w, direction, w->block[0][0]); 643 } 644 } 645 646 if (w->flat_dc) { 647 dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma], 648 w->frame->linesize[!!chroma]); 649 } else { 650 w->dsp.spatial_compensation[w->orient](w->scratchpad, 651 w->dest[chroma], 652 w->frame->linesize[!!chroma]); 653 } 654 if (!zeros_only) 655 w->wdsp.idct_add(w->dest[chroma], 656 w->frame->linesize[!!chroma], 657 w->block[0]); 658 659block_placed: 660 if (!chroma) 661 x8_update_predictions(w, w->orient, n); 662 663 if (w->loopfilter) { 664 uint8_t *ptr = w->dest[chroma]; 665 ptrdiff_t linesize = w->frame->linesize[!!chroma]; 666 667 if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4))) 668 w->dsp.h_loop_filter(ptr, linesize, w->quant); 669 670 if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8))) 671 w->dsp.v_loop_filter(ptr, linesize, w->quant); 672 } 673 return 0; 674} 675 676// FIXME maybe merge with ff_* 677static void x8_init_block_index(IntraX8Context *w, AVFrame *frame) 678{ 679 // not parent codec linesize as this would be wrong for field pics 680 // not that IntraX8 has interlacing support ;) 681 const ptrdiff_t linesize = frame->linesize[0]; 682 const ptrdiff_t uvlinesize = frame->linesize[1]; 683 684 w->dest[0] = frame->data[0]; 685 w->dest[1] = frame->data[1]; 686 w->dest[2] = frame->data[2]; 687 688 w->dest[0] += w->mb_y * linesize << 3; 689 // chroma blocks are on add rows 690 w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2; 691 w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2; 692} 693 694av_cold int ff_intrax8_common_init(AVCodecContext *avctx, 695 IntraX8Context *w, IDCTDSPContext *idsp, 696 int16_t (*block)[64], 697 int block_last_index[12], 698 int mb_width, int mb_height) 699{ 700 static AVOnce init_static_once = AV_ONCE_INIT; 701 702 w->avctx = avctx; 703 w->idsp = *idsp; 704 w->mb_width = mb_width; 705 w->mb_height = mb_height; 706 w->block = block; 707 w->block_last_index = block_last_index; 708 709 // two rows, 2 blocks per cannon mb 710 w->prediction_table = av_mallocz(w->mb_width * 2 * 2); 711 if (!w->prediction_table) 712 return AVERROR(ENOMEM); 713 714 ff_wmv2dsp_init(&w->wdsp); 715 716 ff_init_scantable_permutation(w->idct_permutation, 717 w->wdsp.idct_perm); 718 719 ff_init_scantable(w->idct_permutation, &w->scantable[0], 720 ff_wmv1_scantable[0]); 721 ff_init_scantable(w->idct_permutation, &w->scantable[1], 722 ff_wmv1_scantable[2]); 723 ff_init_scantable(w->idct_permutation, &w->scantable[2], 724 ff_wmv1_scantable[3]); 725 726 ff_intrax8dsp_init(&w->dsp); 727 ff_blockdsp_init(&w->bdsp, avctx); 728 729 ff_thread_once(&init_static_once, x8_vlc_init); 730 731 return 0; 732} 733 734av_cold void ff_intrax8_common_end(IntraX8Context *w) 735{ 736 av_freep(&w->prediction_table); 737} 738 739int ff_intrax8_decode_picture(IntraX8Context *w, Picture *pict, 740 GetBitContext *gb, int *mb_x, int *mb_y, 741 int dquant, int quant_offset, 742 int loopfilter, int lowdelay) 743{ 744 int mb_xy; 745 746 w->gb = gb; 747 w->dquant = dquant; 748 w->quant = dquant >> 1; 749 w->qsum = quant_offset; 750 w->frame = pict->f; 751 w->loopfilter = loopfilter; 752 w->use_quant_matrix = get_bits1(w->gb); 753 754 w->mb_x = *mb_x; 755 w->mb_y = *mb_y; 756 757 w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant; 758 if (w->quant < 5) { 759 w->quant_dc_chroma = w->quant; 760 w->divide_quant_dc_chroma = w->divide_quant_dc_luma; 761 } else { 762 w->quant_dc_chroma = w->quant + ((w->quant + 3) >> 3); 763 w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma; 764 } 765 x8_reset_vlc_tables(w); 766 767 for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) { 768 x8_init_block_index(w, w->frame); 769 mb_xy = (w->mb_y >> 1) * (w->mb_width + 1); 770 if (get_bits_left(gb) < 1) 771 goto error; 772 for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) { 773 x8_get_prediction(w); 774 if (x8_setup_spatial_predictor(w, 0)) 775 goto error; 776 if (x8_decode_intra_mb(w, 0)) 777 goto error; 778 779 if (w->mb_x & w->mb_y & 1) { 780 x8_get_prediction_chroma(w); 781 782 /* when setting up chroma, no vlc is read, 783 * so no error condition can be reached */ 784 x8_setup_spatial_predictor(w, 1); 785 if (x8_decode_intra_mb(w, 1)) 786 goto error; 787 788 x8_setup_spatial_predictor(w, 2); 789 if (x8_decode_intra_mb(w, 2)) 790 goto error; 791 792 w->dest[1] += 8; 793 w->dest[2] += 8; 794 795 pict->qscale_table[mb_xy] = w->quant; 796 mb_xy++; 797 } 798 w->dest[0] += 8; 799 } 800 if (w->mb_y & 1) 801 ff_draw_horiz_band(w->avctx, w->frame, w->frame, 802 (w->mb_y - 1) * 8, 16, 803 PICT_FRAME, 0, lowdelay); 804 } 805 806error: 807 *mb_x = w->mb_x; 808 *mb_y = w->mb_y; 809 810 return 0; 811} 812