diff options
Diffstat (limited to 'thirdparty/libtheora/tokenize.c')
-rw-r--r-- | thirdparty/libtheora/tokenize.c | 1006 |
1 files changed, 651 insertions, 355 deletions
diff --git a/thirdparty/libtheora/tokenize.c b/thirdparty/libtheora/tokenize.c index 60574c3594..57b7aa8da9 100644 --- a/thirdparty/libtheora/tokenize.c +++ b/thirdparty/libtheora/tokenize.c @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: tokenize.c 16503 2009-08-22 18:14:02Z giles $ + last mod: $Id$ ********************************************************************/ #include <stdlib.h> @@ -20,27 +20,26 @@ +static unsigned char OC_DCT_EOB_TOKEN[31]={ + 0,1,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; + static int oc_make_eob_token(int _run_count){ - if(_run_count<4)return OC_DCT_EOB1_TOKEN+_run_count-1; - else{ - int cat; - cat=OC_ILOGNZ_32(_run_count)-3; - cat=OC_MINI(cat,3); - return OC_DCT_REPEAT_RUN0_TOKEN+cat; - } + return _run_count<32?OC_DCT_EOB_TOKEN[_run_count-1]:OC_DCT_REPEAT_RUN3_TOKEN; } +static unsigned char OC_DCT_EOB_EB[31]={ + 0,0,0,0,1,2,3,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +}; + static int oc_make_eob_token_full(int _run_count,int *_eb){ - if(_run_count<4){ - *_eb=0; - return OC_DCT_EOB1_TOKEN+_run_count-1; + if(_run_count<32){ + *_eb=OC_DCT_EOB_EB[_run_count-1]; + return OC_DCT_EOB_TOKEN[_run_count-1]; } else{ - int cat; - cat=OC_ILOGNZ_32(_run_count)-3; - cat=OC_MINI(cat,3); - *_eb=_run_count-OC_BYTE_TABLE32(4,8,16,0,cat); - return OC_DCT_REPEAT_RUN0_TOKEN+cat; + *_eb=_run_count; + return OC_DCT_REPEAT_RUN3_TOKEN; } } @@ -49,86 +48,330 @@ static int oc_decode_eob_token(int _token,int _eb){ return (0x20820C41U>>_token*5&0x1F)+_eb; } -/*TODO: This is now only used during DCT tokenization, and never for runs; it - should be simplified.*/ -static int oc_make_dct_token_full(int _zzi,int _zzj,int _val,int *_eb){ - int neg; - int zero_run; - int token; - int eb; - neg=_val<0; - _val=abs(_val); - zero_run=_zzj-_zzi; - if(zero_run>0){ - int adj; - /*Implement a minor restriction on stack 1 so that we know during DC fixups - that extending a dctrun token from stack 1 will never overflow.*/ - adj=_zzi!=1; - if(_val<2&&zero_run<17+adj){ - if(zero_run<6){ - token=OC_DCT_RUN_CAT1A+zero_run-1; - eb=neg; - } - else if(zero_run<10){ - token=OC_DCT_RUN_CAT1B; - eb=zero_run-6+(neg<<2); - } - else{ - token=OC_DCT_RUN_CAT1C; - eb=zero_run-10+(neg<<3); - } - } - else if(_val<4&&zero_run<3+adj){ - if(zero_run<2){ - token=OC_DCT_RUN_CAT2A; - eb=_val-2+(neg<<1); - } - else{ - token=OC_DCT_RUN_CAT2B; - eb=zero_run-2+(_val-2<<1)+(neg<<2); - } - } - else{ - if(zero_run<9)token=OC_DCT_SHORT_ZRL_TOKEN; - else token=OC_DCT_ZRL_TOKEN; - eb=zero_run-1; - } - } - else if(_val<3){ - token=OC_ONE_TOKEN+(_val-1<<1)+neg; - eb=0; - } - else if(_val<7){ - token=OC_DCT_VAL_CAT2+_val-3; - eb=neg; - } - else if(_val<9){ - token=OC_DCT_VAL_CAT3; - eb=_val-7+(neg<<1); - } - else if(_val<13){ - token=OC_DCT_VAL_CAT4; - eb=_val-9+(neg<<2); - } - else if(_val<21){ - token=OC_DCT_VAL_CAT5; - eb=_val-13+(neg<<3); - } - else if(_val<37){ - token=OC_DCT_VAL_CAT6; - eb=_val-21+(neg<<4); - } - else if(_val<69){ - token=OC_DCT_VAL_CAT7; - eb=_val-37+(neg<<5); - } - else{ - token=OC_DCT_VAL_CAT8; - eb=_val-69+(neg<<9); - } - *_eb=eb; - return token; -} +/*Some tables for fast construction of value tokens.*/ + +static const unsigned char OC_DCT_VALUE_TOKEN[1161]={ + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,21,21,21,21,21,21,21,21, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, + 21,21,21,21,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 19,19,19,19,19,19,19,19,18,18,18,18,17,17,16,15,14,13,12,10, + 7, + 9,11,13,14,15,16,17,17,18,18,18,18,19,19,19,19,19,19,19,19, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, + 21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22 +}; + +static const ogg_uint16_t OC_DCT_VALUE_EB[1161]={ + 1023,1022,1021,1020,1019,1018,1017,1016,1015,1014, + 1013,1012,1011,1010,1009,1008,1007,1006,1005,1004, + 1003,1002,1001,1000, 999, 998, 997, 996, 995, 994, + 993, 992, 991, 990, 989, 988, 987, 986, 985, 984, + 983, 982, 981, 980, 979, 978, 977, 976, 975, 974, + 973, 972, 971, 970, 969, 968, 967, 966, 965, 964, + 963, 962, 961, 960, 959, 958, 957, 956, 955, 954, + 953, 952, 951, 950, 949, 948, 947, 946, 945, 944, + 943, 942, 941, 940, 939, 938, 937, 936, 935, 934, + 933, 932, 931, 930, 929, 928, 927, 926, 925, 924, + 923, 922, 921, 920, 919, 918, 917, 916, 915, 914, + 913, 912, 911, 910, 909, 908, 907, 906, 905, 904, + 903, 902, 901, 900, 899, 898, 897, 896, 895, 894, + 893, 892, 891, 890, 889, 888, 887, 886, 885, 884, + 883, 882, 881, 880, 879, 878, 877, 876, 875, 874, + 873, 872, 871, 870, 869, 868, 867, 866, 865, 864, + 863, 862, 861, 860, 859, 858, 857, 856, 855, 854, + 853, 852, 851, 850, 849, 848, 847, 846, 845, 844, + 843, 842, 841, 840, 839, 838, 837, 836, 835, 834, + 833, 832, 831, 830, 829, 828, 827, 826, 825, 824, + 823, 822, 821, 820, 819, 818, 817, 816, 815, 814, + 813, 812, 811, 810, 809, 808, 807, 806, 805, 804, + 803, 802, 801, 800, 799, 798, 797, 796, 795, 794, + 793, 792, 791, 790, 789, 788, 787, 786, 785, 784, + 783, 782, 781, 780, 779, 778, 777, 776, 775, 774, + 773, 772, 771, 770, 769, 768, 767, 766, 765, 764, + 763, 762, 761, 760, 759, 758, 757, 756, 755, 754, + 753, 752, 751, 750, 749, 748, 747, 746, 745, 744, + 743, 742, 741, 740, 739, 738, 737, 736, 735, 734, + 733, 732, 731, 730, 729, 728, 727, 726, 725, 724, + 723, 722, 721, 720, 719, 718, 717, 716, 715, 714, + 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, + 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, + 693, 692, 691, 690, 689, 688, 687, 686, 685, 684, + 683, 682, 681, 680, 679, 678, 677, 676, 675, 674, + 673, 672, 671, 670, 669, 668, 667, 666, 665, 664, + 663, 662, 661, 660, 659, 658, 657, 656, 655, 654, + 653, 652, 651, 650, 649, 648, 647, 646, 645, 644, + 643, 642, 641, 640, 639, 638, 637, 636, 635, 634, + 633, 632, 631, 630, 629, 628, 627, 626, 625, 624, + 623, 622, 621, 620, 619, 618, 617, 616, 615, 614, + 613, 612, 611, 610, 609, 608, 607, 606, 605, 604, + 603, 602, 601, 600, 599, 598, 597, 596, 595, 594, + 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, + 583, 582, 581, 580, 579, 578, 577, 576, 575, 574, + 573, 572, 571, 570, 569, 568, 567, 566, 565, 564, + 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, + 553, 552, 551, 550, 549, 548, 547, 546, 545, 544, + 543, 542, 541, 540, 539, 538, 537, 536, 535, 534, + 533, 532, 531, 530, 529, 528, 527, 526, 525, 524, + 523, 522, 521, 520, 519, 518, 517, 516, 515, 514, + 513, 512, 63, 62, 61, 60, 59, 58, 57, 56, + 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, + 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, + 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 2, 1, 1, 1, 1, 0, 0, + 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, + 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, + 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, + 502, 503, 504, 505, 506, 507, 508, 509, 510, 511 +}; + +/*The first DCT coefficient that both has a smaller magnitude and gets coded + with a different token.*/ +static const ogg_int16_t OC_DCT_TRELLIS_ALT_VALUE[1161]={ + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -12, -12, -12, -12, -12, -12, -12, -12, -8, -8, + -8, -8, -6, -6, -5, -4, -3, -2, -1, 0, + 0, + 0, 1, 2, 3, 4, 5, 6, 6, 8, 8, + 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68 +}; + +#define OC_DCT_VALUE_TOKEN_PTR (OC_DCT_VALUE_TOKEN+580) +#define OC_DCT_VALUE_EB_PTR (OC_DCT_VALUE_EB+580) +#define OC_DCT_TRELLIS_ALT_VALUE_PTR (OC_DCT_TRELLIS_ALT_VALUE+580) + +/*Some tables for fast construction of combo tokens.*/ + +static const unsigned char OC_DCT_RUN_CAT1_TOKEN[17]={ + 23,24,25,26,27,28,28,28,28,29,29,29,29,29,29,29,29 +}; + +static const unsigned char OC_DCT_RUN_CAT1_EB[17][2]={ + {0,1},{0,1},{0, 1},{0, 1},{0, 1},{0, 4},{1, 5},{2, 6},{3,7}, + {0,8},{1,9},{2,10},{3,11},{4,12},{5,13},{6,14},{7,15} +}; + +static const unsigned char OC_DCT_RUN_CAT2_EB[3][2][2]={ + { {0,1},{2,3} },{ {0,2},{4,6} },{ {1,3},{5,7} } +}; /*Token logging to allow a few fragments of efficient rollback. Late SKIP analysis is tied up in the tokenization process, so we need to be @@ -211,10 +454,11 @@ struct oc_quant_token{ /*Tokenizes the AC coefficients, possibly adjusting the quantization, and then dequantizes and de-zig-zags the result. - The DC coefficient is not preserved; it should be restored by the caller.*/ + The AC coefficients of _idct must be pre-initialized to zero.*/ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, - ogg_int16_t *_qdct,const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, - int _zzi,oc_token_checkpoint **_stack,int _acmin){ + ogg_int16_t *_idct,const ogg_int16_t *_qdct, + const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, + int _zzi,oc_token_checkpoint **_stack,int _lambda,int _acmin){ oc_token_checkpoint *stack; ogg_int64_t zflags; ogg_int64_t nzflags; @@ -242,31 +486,29 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, d2_accum[0]=0; zzj=64; for(zzi=OC_MINI(_zzi,63);zzi>0;zzi--){ - ogg_int32_t lambda; ogg_uint32_t best_cost; int best_bits=best_bits; int best_next=best_next; int best_token=best_token; int best_eb=best_eb; int best_qc=best_qc; - int flush_bits; ogg_uint32_t d2; int dq; + int qc_m; int e; int c; int s; int tj; - lambda=_enc->lambda; qc=_qdct[zzi]; s=-(qc<0); - qc=qc+s^s; - c=_dct[OC_FZIG_ZAG[zzi]]; - if(qc<=1){ + qc_m=qc+s^s; + c=_dct[zzi]; + /*The hard case: try a zero run.*/ + if(qc_m<=1){ ogg_uint32_t sum_d2; int nzeros; int dc_reserve; - /*The hard case: try a zero run.*/ - if(!qc){ + if(!qc_m){ /*Skip runs that are already quantized to zeros. If we considered each zero coefficient in turn, we might theoretically find a better way to partition long zero runs (e.g., @@ -281,15 +523,14 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, d2=0; } else{ - c=c+s^s; d2=c*(ogg_int32_t)c; + c=c+s^s; } eob=eob_run[zzi]; nzeros=zzj-zzi; zzj&=63; sum_d2=d2+d2_accum[zzj]; d2_accum[zzi]=sum_d2; - flush_bits=eob>0?oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob)):0; /*We reserve 1 spot for combo run tokens that start in the 1st AC stack to ensure they can be extended to include the DC coefficient if necessary; this greatly simplifies stack-rewriting later on.*/ @@ -297,7 +538,6 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, best_cost=0xFFFFFFFF; for(;;){ if(nzflags>>zzj&1){ - int cat; int val; int val_s; int zzk; @@ -306,11 +546,10 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, tk=next&1; zzk=next>>1; /*Try a pure zero run to this point.*/ - cat=nzeros+55>>6; - token=OC_DCT_SHORT_ZRL_TOKEN+cat; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); + token=OC_DCT_SHORT_ZRL_TOKEN+(nzeros+55>>6); + bits=oc_token_bits(_enc,huffi,zzi,token); d2=sum_d2-d2_accum[zzj]; - cost=d2+lambda*bits+tokens[zzj][1].cost; + cost=d2+_lambda*bits+tokens[zzj][1].cost; if(cost<=best_cost){ best_next=(zzj<<1)+1; best_token=token; @@ -319,25 +558,18 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, best_bits=bits+tokens[zzj][1].bits; best_qc=0; } - if(nzeros<16+dc_reserve){ + if(nzeros<17+dc_reserve){ val=_qdct[zzj]; val_s=-(val<0); val=val+val_s^val_s; if(val<=2){ /*Try a +/- 1 combo token.*/ - if(nzeros<6){ - token=OC_DCT_RUN_CAT1A+nzeros-1; - eb=-val_s; - } - else{ - cat=nzeros+54>>6; - token=OC_DCT_RUN_CAT1B+cat; - eb=(-val_s<<cat+2)+nzeros-6-(cat<<2); - } - e=(_dct[OC_FZIG_ZAG[zzj]]+val_s^val_s)-_dequant[zzj]; + token=OC_DCT_RUN_CAT1_TOKEN[nzeros-1]; + eb=OC_DCT_RUN_CAT1_EB[nzeros-1][-val_s]; + e=_dct[zzj]-(_dequant[zzj]+val_s^val_s); d2=e*(ogg_int32_t)e+sum_d2-d2_accum[zzj]; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits+tokens[zzk][tk].cost; + bits=oc_token_bits(_enc,huffi,zzi,token); + cost=d2+_lambda*bits+tokens[zzk][tk].cost; if(cost<=best_cost){ best_next=next; best_token=token; @@ -347,22 +579,23 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, best_qc=1+val_s^val_s; } } - if(nzeros<2+dc_reserve&&2<=val&&val<=4){ + if(nzeros<3+dc_reserve&&2<=val&&val<=4){ + int sval; /*Try a +/- 2/3 combo token.*/ - cat=nzeros>>1; - token=OC_DCT_RUN_CAT2A+cat; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - val=2+((val+val_s^val_s)>2); - e=(_dct[OC_FZIG_ZAG[zzj]]+val_s^val_s)-_dequant[zzj]*val; + token=OC_DCT_RUN_CAT2A+(nzeros>>1); + bits=oc_token_bits(_enc,huffi,zzi,token); + val=2+(val>2); + sval=val+val_s^val_s; + e=_dct[zzj]-_dequant[zzj]*sval; d2=e*(ogg_int32_t)e+sum_d2-d2_accum[zzj]; - cost=d2+lambda*bits+tokens[zzk][tk].cost; + cost=d2+_lambda*bits+tokens[zzk][tk].cost; if(cost<=best_cost){ best_cost=cost; best_bits=bits+tokens[zzk][tk].bits; best_next=next; best_token=token; - best_eb=(-val_s<<1+cat)+(val-2<<cat)+(nzeros-1>>1); - best_qc=val+val_s^val_s; + best_eb=OC_DCT_RUN_CAT2_EB[nzeros-1][-val_s][val-2]; + best_qc=sval; } } } @@ -378,10 +611,10 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, /*We made it all the way to the end of the block; try an EOB token.*/ if(eob<4095){ bits=oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob+1)) - -flush_bits; + -(eob>0?oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob)):0); } else bits=oc_token_bits(_enc,huffi,zzi,OC_DCT_EOB1_TOKEN); - cost=sum_d2+bits*lambda; + cost=sum_d2+bits*_lambda; /*If the best route so far is still a pure zero run to the end of the block, force coding it as an EOB. Even if it's not optimal for this block, it has a good chance of @@ -408,20 +641,20 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, tokens[zzi][0].bits=best_bits; tokens[zzi][0].qc=best_qc; zflags|=(ogg_int64_t)1<<zzi; - if(qc){ + if(qc_m){ dq=_dequant[zzi]; - if(zzi<_acmin)lambda=0; + if(zzi<_acmin)_lambda=0; e=dq-c; d2=e*(ogg_int32_t)e; token=OC_ONE_TOKEN-s; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); + bits=oc_token_bits(_enc,huffi,zzi,token); zzj=zzi+1&63; tj=best_flags>>zzj&1; next=(zzj<<1)+tj; tokens[zzi][1].next=(unsigned char)next; tokens[zzi][1].token=(signed char)token; tokens[zzi][1].eb=0; - tokens[zzi][1].cost=d2+lambda*bits+tokens[zzj][tj].cost; + tokens[zzi][1].cost=d2+_lambda*bits+tokens[zzj][tj].cost; tokens[zzi][1].bits=bits+tokens[zzj][tj].bits; tokens[zzi][1].qc=1+s^s; nzflags|=(ogg_int64_t)1<<zzi; @@ -430,200 +663,38 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, } } else{ + int alt_qc; eob=eob_run[zzi]; - if(zzi<_acmin)lambda=0; - c=c+s^s; + if(zzi<_acmin)_lambda=0; dq=_dequant[zzi]; /*No zero run can extend past this point.*/ d2_accum[zzi]=0; - flush_bits=eob>0?oc_token_bits(_enc,huffi,zzi,oc_make_eob_token(eob)):0; - if(qc<=2){ - e=2*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_TWO_TOKEN-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=OC_ONE_TOKEN-s; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_bits=bits; - best_cost=cost; - qc--; - } - best_eb=0; - } - else if(qc<=3){ - e=3*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT2; - best_eb=-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=OC_TWO_TOKEN-s; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=0; - best_bits=bits; - best_cost=cost; - qc--; - } - } - else if(qc<=6){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT2+qc-3; - best_eb=-s; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e-=dq; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_bits=bits; - best_cost=cost; - qc--; - } - } - else if(qc<=8){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT3; - best_eb=(-s<<1)+qc-7; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=6*dq-c; - d2=e*(ogg_int32_t)e; - token=OC_DCT_VAL_CAT2+3; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=-s; - best_bits=bits; - best_cost=cost; - qc=6; - } - } - else if(qc<=12){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT4; - best_eb=(-s<<2)+qc-9; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=8*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<1)+1; - best_bits=bits; - best_cost=cost; - qc=8; - } - } - else if(qc<=20){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT5; - best_eb=(-s<<3)+qc-13; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=12*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<2)+3; - best_bits=bits; - best_cost=cost; - qc=12; - } - } - else if(qc<=36){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT6; - best_eb=(-s<<4)+qc-21; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=20*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<=best_cost){ - best_token=token; - best_eb=(-s<<3)+7; - best_bits=bits; - best_cost=cost; - qc=20; - } - } - else if(qc<=68){ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT7; - best_eb=(-s<<5)+qc-37; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=36*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<best_cost){ - best_token=token; - best_eb=(-s<<4)+15; - best_bits=bits; - best_cost=cost; - qc=36; - } - } - else{ - e=qc*dq-c; - d2=e*(ogg_int32_t)e; - best_token=OC_DCT_VAL_CAT8; - best_eb=(-s<<9)+qc-69; - best_bits=flush_bits+oc_token_bits(_enc,huffi,zzi,best_token); - best_cost=d2+lambda*best_bits; - e=68*dq-c; - d2=e*(ogg_int32_t)e; - token=best_token-1; - bits=flush_bits+oc_token_bits(_enc,huffi,zzi,token); - cost=d2+lambda*bits; - if(cost<best_cost){ - best_token=token; - best_eb=(-s<<5)+31; - best_bits=bits; - best_cost=cost; - qc=68; - } + e=qc*dq-c; + d2=e*(ogg_int32_t)e; + best_token=*(OC_DCT_VALUE_TOKEN_PTR+qc); + best_bits=oc_token_bits(_enc,huffi,zzi,best_token); + best_cost=d2+_lambda*best_bits; + alt_qc=*(OC_DCT_TRELLIS_ALT_VALUE_PTR+qc); + e=alt_qc*dq-c; + d2=e*(ogg_int32_t)e; + token=*(OC_DCT_VALUE_TOKEN_PTR+alt_qc); + bits=oc_token_bits(_enc,huffi,zzi,token); + cost=d2+_lambda*bits; + if(cost<best_cost){ + best_token=token; + best_bits=bits; + best_cost=cost; + qc=alt_qc; } zzj=zzi+1&63; tj=best_flags>>zzj&1; next=(zzj<<1)+tj; tokens[zzi][1].next=(unsigned char)next; tokens[zzi][1].token=(signed char)best_token; - tokens[zzi][1].eb=best_eb; + tokens[zzi][1].eb=*(OC_DCT_VALUE_EB_PTR+qc); tokens[zzi][1].cost=best_cost+tokens[zzj][tj].cost; tokens[zzi][1].bits=best_bits+tokens[zzj][tj].bits; - tokens[zzi][1].qc=qc+s^s; + tokens[zzi][1].qc=qc; nzflags|=(ogg_int64_t)1<<zzi; best_flags|=(ogg_int64_t)1<<zzi; } @@ -631,9 +702,6 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, } /*Emit the tokens from the best path through the trellis.*/ stack=*_stack; - /*We blow away the first entry here so that things vectorize better. - The DC coefficient is not actually stored in the array yet.*/ - for(zzi=0;zzi<64;zzi++)_qdct[zzi]=0; dct_fzig_zag=_enc->state.opt_data.dct_fzig_zag; zzi=1; ti=best_flags>>1&1; @@ -643,12 +711,15 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, eob=eob_run[zzi]; if(tokens[zzi][ti].token<OC_NDCT_EOB_TOKEN_MAX){ if(++eob>=4095){ - oc_enc_eob_log(_enc,_pli,zzi,eob); + oc_enc_token_log(_enc,_pli,zzi,OC_DCT_REPEAT_RUN3_TOKEN,eob); eob=0; } eob_run[zzi]=eob; /*We don't include the actual EOB cost for this block in the return value. - It will be paid for by the fragment that terminates the EOB run.*/ + It is very likely to eventually be spread over several blocks, and + including it more harshly penalizes the first few blocks in a long EOB + run. + Omitting it here gives a small PSNR and SSIM gain.*/ bits-=tokens[zzi][ti].bits; zzi=_zzi; break; @@ -664,7 +735,7 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, zzj=(next>>1)-1&63; /*TODO: It may be worth saving the dequantized coefficient in the trellis above; we had to compute it to measure the error anyway.*/ - _qdct[dct_fzig_zag[zzj]]=(ogg_int16_t)(qc*(int)_dequant[zzj]); + _idct[dct_fzig_zag[zzj]]=(ogg_int16_t)(qc*(int)_dequant[zzj]); zzi=next>>1; ti=next&1; } @@ -673,6 +744,237 @@ int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, return bits; } +/*Simplistic R/D tokenizer. + The AC coefficients of _idct must be pre-initialized to zero. + This could be made more accurate by using more sophisticated + rate predictions for zeros. + It could be made faster by switching from R/D decisions to static + lambda-derived rounding biases.*/ +int oc_enc_tokenize_ac_fast(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi, + ogg_int16_t *_idct,const ogg_int16_t *_qdct, + const ogg_uint16_t *_dequant,const ogg_int16_t *_dct, + int _zzi,oc_token_checkpoint **_stack,int _lambda,int _acmin){ + const unsigned char *dct_fzig_zag; + ogg_uint16_t *eob_run; + oc_token_checkpoint *stack; + int huffi; + int zzi; + int zzj; + int zzk; + int total_bits; + int zr[4]; + stack=*_stack; + total_bits=0; + /*The apparent bit-cost of coding a zero from observing the trellis + quantizer is pre-combined with lambda. + Four predictive cases are considered: the last optimized value is zero (+2) + or non-zero and the non-optimized value is zero (+1) or non-zero.*/ + zr[0]=3*_lambda>>1; + zr[1]=_lambda; + zr[2]=4*_lambda; + zr[3]=7*_lambda>>1; + eob_run=_enc->eob_run[_pli]; + dct_fzig_zag=_enc->state.opt_data.dct_fzig_zag; + huffi=_enc->huff_idxs[_enc->state.frame_type][1][_pli+1>>1]; + for(zzj=zzi=1;zzj<_zzi&&!_qdct[zzj];zzj++); + while(zzj<_zzi){ + int v; + int d0; + int d1; + int sign; + int k; + int eob; + int dq0; + int dq1; + int dd0; + int dd1; + int next_zero; + int eob_bits; + int dct_fzig_zzj; + dct_fzig_zzj=dct_fzig_zag[zzj]; + v=_dct[zzj]; + d0=_qdct[zzj]; + eob=eob_run[zzi]; + for(zzk=zzj+1;zzk<_zzi&&!_qdct[zzk];zzk++); + next_zero=zzk-zzj+62>>6; + dq0=d0*_dequant[zzj]; + dd0=dq0-v; + dd0*=dd0; + sign=-(d0<0); + k=d0+sign^sign; + d1=(k-(zzj>_acmin))+sign^sign; + dq1=d1*_dequant[zzj]; + dd1=dq1-v; + dd1*=dd1; + /*The cost of ending an eob run is included when the alternative is to + extend this eob run. + A per qi/zzi weight would probably be useful. + Including it in the overall tokenization cost was not helpful. + The same is true at the far end of the zero run plus token case.*/ + if(eob>0&&d1==0&&zzk==_zzi){ + eob_bits=oc_token_bits(_enc,huffi,zzi,OC_DCT_EOB1_TOKEN); + } + else eob_bits=0; + if(zzj==zzi){ + /*No active zero run.*/ + int best_token; + int best_eb; + int token; + int best_bits; + int bits; + int cost; + best_token=*(OC_DCT_VALUE_TOKEN_PTR+d0); + best_bits=oc_token_bits(_enc,huffi,zzi,best_token); + if(d1!=0){ + token=*(OC_DCT_VALUE_TOKEN_PTR+d1); + bits=oc_token_bits(_enc,huffi,zzi,token); + cost=dd1+(bits+eob_bits)*_lambda; + } + else{ + token=bits=0; + cost=dd1+zr[next_zero]; + } + if((dd0+(best_bits+eob_bits)*_lambda)>cost){ + _idct[dct_fzig_zzj]=dq1; + if(d1==0){ + zzj=zzk; + continue; + } + best_bits=bits; + best_token=token; + best_eb=*(OC_DCT_VALUE_EB_PTR+d1); + } + else{ + best_eb=*(OC_DCT_VALUE_EB_PTR+d0); + _idct[dct_fzig_zzj]=dq0; + } + oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzi); + if(eob>0){ + oc_enc_eob_log(_enc,_pli,zzi,eob); + eob_run[zzi]=0; + } + oc_enc_token_log(_enc,_pli,zzi,best_token,best_eb); + total_bits+=best_bits; + } + else{ + int d; + int dc_reserve; + int best_token; + int best_eb; + int best_bits; + int best_cost; + int best_bits1; + int best_token1; + int best_eb1; + int zr_bits; + int eob2; + int eob_bits2; + int bits; + int token; + int nzeros; + nzeros=zzj-zzi; + dc_reserve=zzi+62>>6; + /*A zero run, followed by the value alone.*/ + best_token=best_token1=OC_DCT_SHORT_ZRL_TOKEN+(nzeros+55>>6); + best_eb=best_eb1=nzeros-1; + eob2=eob_run[zzj]; + eob_bits2=eob2>0?oc_token_bits(_enc,huffi,zzj,OC_DCT_EOB1_TOKEN):0; + zr_bits=oc_token_bits(_enc,huffi,zzi,best_token)+eob_bits2; + best_bits=zr_bits + +oc_token_bits(_enc,huffi,zzj,*(OC_DCT_VALUE_TOKEN_PTR+d0)); + d=d0; + best_bits1=0; + if(d1!=0){ + best_bits1=zr_bits + +oc_token_bits(_enc,huffi,zzj,*(OC_DCT_VALUE_TOKEN_PTR+d1)); + } + if(nzeros<17+dc_reserve){ + if(k<=2){ + /*+/- 1 combo token.*/ + token=OC_DCT_RUN_CAT1_TOKEN[nzeros-1]; + bits=oc_token_bits(_enc,huffi,zzi,token); + if(k==2&&bits<=best_bits1){ + best_bits1=bits; + best_token1=token; + best_eb1=OC_DCT_RUN_CAT1_EB[nzeros-1][-sign]; + } + if(k==1&&bits<=best_bits){ + best_bits=bits; + best_token=token; + best_eb=OC_DCT_RUN_CAT1_EB[nzeros-1][-sign]; + } + } + if(nzeros<3+dc_reserve&&2<=k&&k<=4){ + /*+/- 2/3 combo token.*/ + token=OC_DCT_RUN_CAT2A+(nzeros>>1); + bits=oc_token_bits(_enc,huffi,zzi,token); + if(k==4&&bits<=best_bits1){ + best_bits1=bits; + best_token1=token; + best_eb1=OC_DCT_RUN_CAT2_EB[nzeros-1][-sign][1]; + } + if(k!=4&&bits<=best_bits){ + best_bits=bits; + best_token=token; + best_eb=OC_DCT_RUN_CAT2_EB[nzeros-1][-sign][k-2]; + } + } + } + best_cost=dd0+(best_bits+eob_bits)*_lambda; + if(d1==0&&(dd1+zr[2+next_zero])<=best_cost){ + zzj=zzk; + continue; + } + if(d1!=0&&dd1+(best_bits1+eob_bits)*_lambda<best_cost){ + best_bits=best_bits1; + best_token=best_token1; + best_eb=best_eb1; + d=d1; + _idct[dct_fzig_zzj]=dq1; + } + else _idct[dct_fzig_zzj]=dq0; + oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzi); + if(eob){ + oc_enc_eob_log(_enc,_pli,zzi,eob); + eob_run[zzi]=0; + } + oc_enc_token_log(_enc,_pli,zzi,best_token,best_eb); + /*If a zero run won vs. the combo token we still need to code this + value.*/ + if(best_token<=OC_DCT_ZRL_TOKEN){ + oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzj); + if(eob2){ + oc_enc_eob_log(_enc,_pli,zzj,eob2); + /*The cost of any EOB run we disrupted is ignored because doing so + improved PSNR/SSIM by a small amount.*/ + best_bits-=eob_bits2; + eob_run[zzj]=0; + } + oc_enc_token_log(_enc,_pli,zzj, + *(OC_DCT_VALUE_TOKEN_PTR+d),*(OC_DCT_VALUE_EB_PTR+d)); + } + total_bits+=best_bits; + } + zzi=zzj+1; + zzj=zzk; + } + /*Code an EOB run to complete this block. + The cost of the EOB run is not included in the total as explained in + in a comment in the trellis tokenizer above.*/ + if(zzi<64){ + int eob; + eob=eob_run[zzi]+1; + oc_enc_tokenlog_checkpoint(_enc,stack++,_pli,zzi); + if(eob>=4095){ + oc_enc_token_log(_enc,_pli,zzi,OC_DCT_REPEAT_RUN3_TOKEN,eob); + eob=0; + } + eob_run[zzi]=eob; + } + *_stack=stack; + return total_bits; +} + void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, int _pli,int _fragy0,int _frag_yend){ const oc_fragment_plane *fplane; @@ -695,10 +997,10 @@ void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, predictor for the same reference frame.*/ for(fragx=0;fragx<nhfrags;fragx++,fragi++){ if(frags[fragi].coded){ - int ref; - ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode); - frag_dc[fragi]=(ogg_int16_t)(frags[fragi].dc-pred_last[ref]); - pred_last[ref]=frags[fragi].dc; + int refi; + refi=frags[fragi].refi; + frag_dc[fragi]=(ogg_int16_t)(frags[fragi].dc-pred_last[refi]); + pred_last[refi]=frags[fragi].dc; } } } @@ -710,27 +1012,24 @@ void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, u_frags=frags-nhfrags; l_ref=-1; ul_ref=-1; - u_ref=u_frags[fragi].coded?OC_FRAME_FOR_MODE(u_frags[fragi].mb_mode):-1; + u_ref=u_frags[fragi].refi; for(fragx=0;fragx<nhfrags;fragx++,fragi++){ int ur_ref; if(fragx+1>=nhfrags)ur_ref=-1; - else{ - ur_ref=u_frags[fragi+1].coded? - OC_FRAME_FOR_MODE(u_frags[fragi+1].mb_mode):-1; - } + else ur_ref=u_frags[fragi+1].refi; if(frags[fragi].coded){ int pred; - int ref; - ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode); + int refi; + refi=frags[fragi].refi; /*We break out a separate case based on which of our neighbors use the same reference frames. This is somewhat faster than trying to make a generic case which handles all of them, since it reduces lots of poorly predicted jumps to one switch statement, and also lets a number of the multiplications be optimized out by strength reduction.*/ - switch((l_ref==ref)|(ul_ref==ref)<<1| - (u_ref==ref)<<2|(ur_ref==ref)<<3){ - default:pred=pred_last[ref];break; + switch((l_ref==refi)|(ul_ref==refi)<<1| + (u_ref==refi)<<2|(ur_ref==refi)<<3){ + default:pred=pred_last[refi];break; case 1: case 3:pred=frags[fragi-1].dc;break; case 2:pred=u_frags[fragi-1].dc;break; @@ -764,8 +1063,8 @@ void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc, }break; } frag_dc[fragi]=(ogg_int16_t)(frags[fragi].dc-pred); - pred_last[ref]=frags[fragi].dc; - l_ref=ref; + pred_last[refi]=frags[fragi].dc; + l_ref=refi; } else l_ref=-1; ul_ref=u_ref; @@ -850,9 +1149,8 @@ void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli, ti0++; eob_run0=0; } - token=oc_make_dct_token_full(0,0,val,&eb); - dct_tokens0[ti0]=(unsigned char)token; - extra_bits0[ti0]=(ogg_uint16_t)eb; + dct_tokens0[ti0]=*(OC_DCT_VALUE_TOKEN_PTR+val); + extra_bits0[ti0]=*(OC_DCT_VALUE_EB_PTR+val); ti0++; } else{ @@ -863,9 +1161,8 @@ void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli, /*We're in the middle of an active EOB run in stack 1. Move it to stack 0.*/ if(++eob_run0>=4095){ - token=oc_make_eob_token_full(eob_run0,&eb); - dct_tokens0[ti0]=(unsigned char)token; - extra_bits0[ti0]=(ogg_uint16_t)eb; + dct_tokens0[ti0]=OC_DCT_REPEAT_RUN3_TOKEN; + extra_bits0[ti0]=eob_run0; ti0++; eob_run0=0; } @@ -996,9 +1293,8 @@ void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli, neobs1--; /*If we have more than 4095 EOBs outstanding in stack1, flush the run.*/ if(eob_run1-neobs1>=4095){ - token=oc_make_eob_token_full(4095,&eb); - dct_tokens1[ti1w]=(unsigned char)token; - extra_bits1[ti1w]=(ogg_uint16_t)eb; + dct_tokens1[ti1w]=OC_DCT_REPEAT_RUN3_TOKEN; + extra_bits1[ti1w]=4095; ti1w++; eob_run1-=4095; } |