home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Meia / source / decode_dv.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  26.3 KB  |  961 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Video decoding library
  3. //    Copyright (C) 1998-2004 Avery Lee
  4. //
  5. //    This program is free software; you can redistribute it and/or modify
  6. //    it under the terms of the GNU General Public License as published by
  7. //    the Free Software Foundation; either version 2 of the License, or
  8. //    (at your option) any later version.
  9. //
  10. //    This program is distributed in the hope that it will be useful,
  11. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. //    GNU General Public License for more details.
  14. //
  15. //    You should have received a copy of the GNU General Public License
  16. //    along with this program; if not, write to the Free Software
  17. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <vd2/system/cpuaccel.h>
  20. #include <vd2/system/debug.h>
  21. #include <vd2/system/memory.h>
  22. #include <vd2/Meia/decode_dv.h>
  23. #include <vd2/Meia/MPEGIDCT.h>
  24. #include <vd2/Kasumi/pixmap.h>
  25.  
  26. #ifdef _M_AMD64
  27.     extern "C" void _mm_sfence();
  28.     #pragma intrinsic(_mm_sfence)
  29. #endif
  30.  
  31. class VDVideoDecoderDV : public IVDVideoDecoderDV {
  32. public:
  33.     void        DecompressFrame(const void *src, bool isPAL);
  34.     VDPixmap    GetFrameBuffer();
  35.  
  36. protected:
  37.     void InterpolatePALChroma();
  38.  
  39.     bool    mbLastWasPAL;
  40.  
  41.     __declspec(align(16)) uint8    mYPlane[576][736];
  42.  
  43.     __declspec(align(16)) union {
  44.         struct {
  45.             uint8    mCrPlane[480][184];
  46.             uint8    mCbPlane[480][184];
  47.         } m411;
  48.         struct {
  49.             uint8    mCrPlane[576][368];
  50.             uint8    mCbPlane[576][368];
  51.         } m420;
  52.     };
  53. };
  54.  
  55. IVDVideoDecoderDV *VDCreateVideoDecoderDV() {
  56.     return new VDVideoDecoderDV;
  57. }
  58.  
  59. // 10 DIF sequences (NTSC) or 12 DIF sequences (PAL)
  60. // Each DIF sequence contains:
  61. //        1 DIF block        header
  62. //        2 DIF blocks    subcode
  63. //        3 DIF blocks    VAUX
  64. //        9 DIF blocks    audio
  65. //        135 DIF blocks    video
  66. //
  67. // Each DIF block has a 3 byte header and 77 bytes of payload.
  68.  
  69. namespace {
  70.  
  71. #define    TIMES_2x(v1,v2,v3) v1,v2,v3,v1,v2,v3
  72. #define    TIMES_4x(v1,v2,v3) v1,v2,v3,v1,v2,v3,v1,v2,v3,v1,v2,v3
  73. #define    TIMES_8x(v1,v2,v3) v1,v2,v3,v1,v2,v3,v1,v2,v3,v1,v2,v3,v1,v2,v3,v1,v2,v3,v1,v2,v3,v1,v2,v3
  74.  
  75. #define VLC_3(run,amp) TIMES_8x({run+1,3,(amp<<7)}),TIMES_8x({run+1,3,-(amp<<7)})
  76. #define VLC_4(run,amp) TIMES_4x({run+1,4,(amp<<7)}),TIMES_4x({run+1,4,-(amp<<7)})
  77. #define REP_4(run,amp) TIMES_4x({run+1,4,(amp<<7)})
  78. #define VLC_5(run,amp) TIMES_2x({run+1,5,(amp<<7)}),TIMES_2x({run+1,5,-(amp<<7)})
  79. #define VLC_6(run,amp) {run+1,6,(amp<<7)},{run+1,6,-(amp<<7)}
  80.  
  81. #define VLC_7(run,amp) TIMES_2x({run+1,7,(amp<<7)}),TIMES_2x({run+1,7,-(amp<<7)})
  82. #define VLC_8(run,amp) {run+1,8,(amp<<7)},{run+1,8,-(amp<<7)}
  83.  
  84. #define VLC_9(run,amp) {run+1,9,(amp<<7)},{run+1,9,-(amp<<7)}
  85.  
  86. #define VLC_10(run,amp) {run+1,10,(amp<<7)},{run+1,10,-(amp<<7)}
  87.  
  88. #define VLC_11(run,amp) TIMES_4x({run+1,11,(amp<<7)}),TIMES_4x({run+1,11,-(amp<<7)})
  89. #define REP_11(run,amp) TIMES_4x({run+1,11,(amp<<7)})
  90. #define VLC_12(run,amp) TIMES_2x({run+1,12,(amp<<7)}),TIMES_2x({run+1,12,-(amp<<7)})
  91. #define REP_12(run,amp) TIMES_2x({run+1,12,(amp<<7)})
  92. #define VLC_13(run,amp) {run+1,13,(amp<<7)},{run+1,13,-(amp<<7)}
  93.  
  94. #define REP_13(run,amp) {run+1,13,(amp<<7)}
  95.  
  96. #define REP_16(run,amp) {run+1,16,(amp<<7)}
  97.  
  98.     struct VLCEntry {
  99.         uint8    run;
  100.         uint8    len;
  101.         sint16    coeff;
  102.     };
  103.  
  104.     static const VLCEntry kDVACDecode1[48]={
  105.                         // xxxxxx
  106.         VLC_3(0,1),        // 00s
  107.         VLC_4(0,2),        // 010s
  108.         REP_4(64,0),    // 0110
  109.         VLC_5(1,1),        // 0111s
  110.         VLC_5(0,3),        // 1000s
  111.         VLC_5(0,4),        // 1001s
  112.         VLC_6(2,1),        // 10100s
  113.         VLC_6(1,2),        // 10101s
  114.         VLC_6(0,5),        // 10110s
  115.         VLC_6(0,6),        // 10111s
  116.     };
  117.  
  118.     static const VLCEntry kDVACDecode2[32]={
  119.                         // 11xxxxxx
  120.         VLC_7(3,1),        // 110000s
  121.         VLC_7(4,1),        // 110001s
  122.         VLC_7(0,7),        // 110010s
  123.         VLC_7(0,8),        // 110011s
  124.         VLC_8(5,1),        // 1101000s
  125.         VLC_8(6,1),        // 1101001s
  126.         VLC_8(2,2),        // 1101010s
  127.         VLC_8(1,3),        // 1101011s
  128.         VLC_8(1,4),        // 1101100s
  129.         VLC_8(0,9),        // 1101101s
  130.         VLC_8(0,10),    // 1101110s
  131.         VLC_8(0,11),    // 1101111s
  132.     };
  133.  
  134.     static const VLCEntry kDVACDecode3[32]={
  135.                         // 111xxxxxx
  136.         VLC_9(7,1),        // 11100000s
  137.         VLC_9(8,1),        // 11100001s
  138.         VLC_9(9,1),        // 11100010s
  139.         VLC_9(10,1),    // 11100011s
  140.         VLC_9(3,2),        // 11100100s
  141.         VLC_9(4,2),        // 11100101s
  142.         VLC_9(2,3),        // 11100110s
  143.         VLC_9(1,5),        // 11100111s
  144.         VLC_9(1,6),        // 11101000s
  145.         VLC_9(1,7),        // 11101001s
  146.         VLC_9(0,12),    // 11101010s
  147.         VLC_9(0,13),    // 11101011s
  148.         VLC_9(0,14),    // 11101100s
  149.         VLC_9(0,15),    // 11101101s
  150.         VLC_9(0,16),    // 11101110s
  151.         VLC_9(0,17),    // 11101111s
  152.     };
  153.  
  154.     static const VLCEntry kDVACDecode4[32]={
  155.                         // 1111xxxxxx
  156.         VLC_10(11,1),    // 111100000s
  157.         VLC_10(12,1),    // 111100001s
  158.         VLC_10(13,1),    // 111100010s
  159.         VLC_10(14,1),    // 111100011s
  160.         VLC_10(5,2),    // 111100100s
  161.         VLC_10(6,2),    // 111100101s
  162.         VLC_10(3,3),    // 111100110s
  163.         VLC_10(4,3),    // 111100111s
  164.         VLC_10(2,4),    // 111101000s
  165.         VLC_10(2,5),    // 111101001s
  166.         VLC_10(1,8),    // 111101010s
  167.         VLC_10(0,18),    // 111101011s
  168.         VLC_10(0,19),    // 111101100s
  169.         VLC_10(0,20),    // 111101101s
  170.         VLC_10(0,21),    // 111101110s
  171.         VLC_10(0,22),    // 111101111s
  172.     };
  173.  
  174.     static const VLCEntry kDVACDecode5[192]={
  175.                         // 111110xxxxxxx
  176.         VLC_11(5,3),    // 1111100000s
  177.         VLC_11(3,4),    // 1111100001s
  178.         VLC_11(3,5),    // 1111100010s
  179.         VLC_11(2,6),    // 1111100011s
  180.         VLC_11(1,9),    // 1111100100s
  181.         VLC_11(1,10),    // 1111100101s
  182.         VLC_11(1,11),    // 1111100110s
  183.         REP_11(0,0),    // 11111001110
  184.         REP_11(1,0),    // 11111001111
  185.         VLC_12(6,3),    // 11111010000s
  186.         VLC_12(4,4),    // 11111010001s
  187.         VLC_12(3,6),    // 11111010010s
  188.         VLC_12(1,12),    // 11111010011s
  189.         VLC_12(1,13),    // 11111010100s
  190.         VLC_12(1,14),    // 11111010101s
  191.         REP_12(2,0),    // 111110101100
  192.         REP_12(3,0),    // 111110101101
  193.         REP_12(4,0),    // 111110101110
  194.         REP_12(5,0),    // 111110101111
  195.         VLC_13(7,2),    // 111110110000s
  196.         VLC_13(8,2),    // 111110110001s
  197.         VLC_13(9,2),    // 111110110010s
  198.         VLC_13(10,2),    // 111110110011s
  199.         VLC_13(7,3),    // 111110110100s
  200.         VLC_13(8,3),    // 111110110101s
  201.         VLC_13(4,5),    // 111110110110s
  202.         VLC_13(3,7),    // 111110110111s
  203.         VLC_13(2,7),    // 111110111000s
  204.         VLC_13(2,8),    // 111110111001s
  205.         VLC_13(2,9),    // 111110111010s
  206.         VLC_13(2,10),    // 111110111011s
  207.         VLC_13(2,11),    // 111110111100s
  208.         VLC_13(1,15),    // 111110111101s
  209.         VLC_13(1,16),    // 111110111110s
  210.         VLC_13(1,17),    // 111110111111s
  211.         REP_13(0,0),    // 1111110000000
  212.         REP_13(1,0),    // 1111110000001
  213.         REP_13(2,0),    // 1111110000010
  214.         REP_13(3,0),    // 1111110000011
  215.         REP_13(4,0),    // 1111110000100
  216.         REP_13(5,0),    // 1111110000101
  217.         REP_13(6,0),    // 1111110000110
  218.         REP_13(7,0),    // 1111110000111
  219.         REP_13(8,0),    // 1111110001000
  220.         REP_13(9,0),    // 1111110001001
  221.         REP_13(10,0),    // 1111110001010
  222.         REP_13(11,0),    // 1111110001011
  223.         REP_13(12,0),    // 1111110001100
  224.         REP_13(13,0),    // 1111110001101
  225.         REP_13(14,0),    // 1111110001110
  226.         REP_13(15,0),    // 1111110001111
  227.         REP_13(16,0),    // 1111110010000
  228.         REP_13(17,0),    // 1111110010001
  229.         REP_13(18,0),    // 1111110010010
  230.         REP_13(19,0),    // 1111110010011
  231.         REP_13(20,0),    // 1111110010100
  232.         REP_13(21,0),    // 1111110010101
  233.         REP_13(22,0),    // 1111110010110
  234.         REP_13(23,0),    // 1111110010111
  235.         REP_13(24,0),    // 1111110011000
  236.         REP_13(25,0),    // 1111110011001
  237.         REP_13(26,0),    // 1111110011010
  238.         REP_13(27,0),    // 1111110011011
  239.         REP_13(28,0),    // 1111110011100
  240.         REP_13(29,0),    // 1111110011101
  241.         REP_13(30,0),    // 1111110011110
  242.         REP_13(31,0),    // 1111110011111
  243.         REP_13(32,0),    // 1111110100000
  244.         REP_13(33,0),    // 1111110100001
  245.         REP_13(34,0),    // 1111110100010
  246.         REP_13(35,0),    // 1111110100011
  247.         REP_13(36,0),    // 1111110100100
  248.         REP_13(37,0),    // 1111110100101
  249.         REP_13(38,0),    // 1111110100110
  250.         REP_13(39,0),    // 1111110100111
  251.         REP_13(40,0),    // 1111110101000
  252.         REP_13(41,0),    // 1111110101001
  253.         REP_13(42,0),    // 1111110101010
  254.         REP_13(43,0),    // 1111110101011
  255.         REP_13(44,0),    // 1111110101100
  256.         REP_13(45,0),    // 1111110101101
  257.         REP_13(46,0),    // 1111110101110
  258.         REP_13(47,0),    // 1111110101111
  259.         REP_13(48,0),    // 1111110110000
  260.         REP_13(49,0),    // 1111110110001
  261.         REP_13(50,0),    // 1111110110010
  262.         REP_13(51,0),    // 1111110110011
  263.         REP_13(52,0),    // 1111110110100
  264.         REP_13(53,0),    // 1111110110101
  265.         REP_13(54,0),    // 1111110110110
  266.         REP_13(55,0),    // 1111110110111
  267.         REP_13(56,0),    // 1111110111000
  268.         REP_13(57,0),    // 1111110111001
  269.         REP_13(58,0),    // 1111110111010
  270.         REP_13(59,0),    // 1111110111011
  271.         REP_13(60,0),    // 1111110111100
  272.         REP_13(61,0),    // 1111110111101
  273.         REP_13(62,0),    // 1111110111110
  274.         REP_13(63,0),    // 1111110111111
  275.     };
  276.  
  277.     static const VLCEntry kDVACDecode8[512]={
  278. #define R2(y) {1,16,((y)<<7)},{1,16,-((y)<<7)}
  279. #define R(x) R2(x+0),R2(x+1),R2(x+2),R2(x+3),R2(x+4),R2(x+5),R2(x+6),R2(x+7),R2(x+8),R2(x+9),R2(x+10),R2(x+11),R2(x+12),R2(x+13),R2(x+14),R2(x+15)
  280.         R(0x00),
  281.         R(0x10),
  282.         R(0x20),
  283.         R(0x30),
  284.         R(0x40),
  285.         R(0x50),
  286.         R(0x60),
  287.         R(0x70),
  288.         R(0x80),
  289.         R(0x90),
  290.         R(0xA0),
  291.         R(0xB0),
  292.         R(0xC0),
  293.         R(0xD0),
  294.         R(0xE0),
  295.         R(0xF0),
  296. #undef R
  297. #undef R2
  298.     };
  299.  
  300.     const VLCEntry *DVDecodeAC(uint32 bitheap) {
  301.         if (bitheap < 0xC0000000)
  302.             return &kDVACDecode1[bitheap >> 26];
  303.  
  304.         if (bitheap < 0xE0000000)
  305.             return &kDVACDecode2[(bitheap >> 24) - (0xC0000000 >> 24)];
  306.  
  307.         if (bitheap < 0xF0000000)
  308.             return &kDVACDecode3[(bitheap >> 23) - (0xE0000000 >> 23)];
  309.  
  310.         if (bitheap < 0xF8000000)
  311.             return &kDVACDecode4[(bitheap >> 22) - (0xF0000000 >> 22)];
  312.  
  313.         if (bitheap < 0xFE000000)
  314.             return &kDVACDecode5[(bitheap >> 19) - (0xF8000000 >> 19)];
  315.  
  316.         return &kDVACDecode8[(bitheap >> 16) - (0xFE000000 >> 16)];
  317.     }
  318.  
  319.     static const int zigzag_std[64]={
  320.          0,  1,  8, 16,  9,  2,  3, 10,
  321.         17, 24, 32, 25, 18, 11,  4,  5,
  322.         12, 19, 26, 33, 40, 48, 41, 34,
  323.         27, 20, 13,  6,  7, 14, 21, 28,
  324.         35, 42, 49, 56, 57, 50, 43, 36,
  325.         29, 22, 15, 23, 30, 37, 44, 51,
  326.         58, 59, 52, 45, 38, 31, 39, 46,
  327.         53, 60, 61, 54, 47, 55, 62, 63,
  328.     };
  329.  
  330.     static const int zigzag_alt[64]={
  331.          0,  8,  1,  9, 16, 24,  2, 10,
  332.         17, 25, 32, 40, 48, 56, 33, 41,
  333.         18, 26,  3, 11,  4, 12, 19, 27,
  334.         34, 42, 49, 57, 50, 58, 35, 43,
  335.         20, 28,  5, 13,  6, 14, 21, 29,
  336.         36, 44, 51, 59, 52, 60, 37, 45,
  337.         22, 30,  7, 15, 23, 31, 38, 46,
  338.         53, 61, 54, 62, 39, 47, 55, 63,
  339.     };
  340.  
  341.     static const int range[64]={
  342.         0,
  343.         0,0,0,0,0,
  344.         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  345.         2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  346.         3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
  347.     };
  348.  
  349.     static const char shifttable[][4]={
  350.         {0,0,0,0},
  351.         {0,0,0,1},
  352.         {0,0,1,1},
  353.         {0,1,1,2},
  354.         {1,1,2,2},
  355.         {1,2,2,3},
  356.         {2,2,3,3},
  357.         {2,3,3,4},
  358.         {3,3,4,4},
  359.         {3,4,4,5},
  360.         {4,4,5,5},
  361.         {1,1,1,1},
  362.         {1,1,1,2},
  363.     };
  364.  
  365.     static const int quanttable[4][16]={
  366.         {            5,5,4,4,3,3,2,2,1,0,0,0,0,0,0,0},
  367.         {      7,6,6,5,5,4,4,3,3,2,2,1,0,0,0,0},
  368.         {8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,0},
  369.         { 10,9,9,8,8,7,7,6,6,5,5,4,4,12,11,11},
  370.     };
  371.  
  372. #if 0
  373.     static const double CS1 = 0.98078528040323044912618223613424;
  374.     static const double CS2 = 0.92387953251128675612818318939679;
  375.     static const double CS3 = 0.83146961230254523707878837761791;
  376.     static const double CS4 = 0.70710678118654752440084436210485;
  377.     static const double CS5 = 0.55557023301960222474283081394853;
  378.     static const double CS6 = 0.3826834323650897717284599840304;
  379.     static const double CS7 = 0.19509032201612826784828486847702;
  380.  
  381.     static const double w[8] = {
  382.         1.0,
  383.         (4.0*CS7*CS2)/CS4,
  384.         (2.0*CS6)/CS4,
  385.         2.0*CS5,
  386.         8.0/7.0,
  387.         CS3/CS4,
  388.         CS2/CS4,
  389.         CS1/CS4
  390.     };
  391. #else
  392.     // Weights 2/(w(i)*w(j)) according to SMPTE 314M 5.2.2, in 12-bit fixed point.
  393.     static const int weights[64]={
  394.          8192,  8352,  8867,  9102,  9362,  9633, 10703, 11363,
  395.          8352,  8516,  9041,  9281,  9546,  9821, 10913, 11585,
  396.          8867,  9041,  9598,  9852, 10134, 10426, 11585, 12299,
  397.          9102,  9281,  9852, 10114, 10403, 10703, 11893, 12625,
  398.          9362,  9546, 10134, 10403, 10700, 11009, 12232, 12986,
  399.          9633,  9821, 10426, 10703, 11009, 11327, 12586, 13361,
  400.         10703, 10913, 11585, 11893, 12232, 12586, 13985, 14846,
  401.         11363, 11585, 12299, 12625, 12986, 13361, 14846, 15760,
  402.     };
  403. #endif
  404.  
  405.     struct DVBitSource {
  406.         const uint8 *src;
  407.         const uint8 *srclimit;
  408.         int bitpos;
  409.  
  410.         void Init(const uint8 *_src, const uint8 *_srclimit, int _bitpos) {
  411.             src = _src;
  412.             srclimit = _srclimit;
  413.             bitpos = _bitpos;
  414.         }
  415.     };
  416.  
  417.     class DVDecoderContext {
  418.     public:
  419.         DVDecoderContext();
  420.  
  421.         const VDMPEGIDCTSet    *mpIDCT;
  422.     };
  423.  
  424.     DVDecoderContext::DVDecoderContext() {
  425.         long flags = CPUGetEnabledExtensions();
  426.  
  427. #ifdef _M_AMD64
  428.         mpIDCT = &g_VDMPEGIDCT_sse2;
  429. #else
  430.         if (flags & CPUF_SUPPORTS_SSE2)
  431.             mpIDCT = &g_VDMPEGIDCT_sse2;
  432.         else if (flags & CPUF_SUPPORTS_INTEGER_SSE)
  433.             mpIDCT = &g_VDMPEGIDCT_isse;
  434.         else if (flags & CPUF_SUPPORTS_MMX)
  435.             mpIDCT = &g_VDMPEGIDCT_mmx;
  436.         else
  437.             mpIDCT = &g_VDMPEGIDCT_scalar;
  438. #endif
  439.     }
  440.  
  441.     class DVDCTBlockDecoder {
  442.     public:
  443.         void Init(uint8 *dst, ptrdiff_t pitch, DVBitSource& bitsource, int qno, bool split, const int zigzag[2][64], short weights_prescaled[2][13][64]);
  444.         bool Decode(DVBitSource& bitsource, const DVDecoderContext& context, bool final);
  445.  
  446.     protected:
  447.         uint32        mBitHeap;
  448.         int            mBitCount;
  449.         int            mIdx;
  450.         const char    *mpShiftTab;
  451.         const int    *mpZigzag;
  452.         const short    *mpWeights;
  453.  
  454.         __declspec(align(16)) sint16        mCoeff[64];
  455.  
  456.         uint8        *mpDst;
  457.         ptrdiff_t    mPitch;
  458.         bool        mb842;
  459.         bool        mbSplit;
  460.     };
  461.  
  462.     void DVDCTBlockDecoder::Init(uint8 *dst, ptrdiff_t pitch, DVBitSource& src, int qno, bool split, const int zigzag[2][64], short weights_prescaled[2][13][64]) {
  463.         mpDst = dst;
  464.         mPitch = pitch;
  465.         mBitHeap = mBitCount = 0;
  466.         mIdx = 0;
  467.  
  468.         memset(&mCoeff, 0, sizeof mCoeff);
  469.  
  470.         const uint8 *src0 = src.src;
  471.         ++src.src;
  472.         src.bitpos = 4;
  473.  
  474.         const int dctclass = (src0[1] >> 4) & 3;
  475.  
  476.         mpShiftTab = shifttable[quanttable[dctclass][qno]];
  477.         mCoeff[0] = (sint16)(((sint8)src0[0]*2 + (src0[1]>>7) + 0x100) << 2);
  478.  
  479.         mb842 = false;
  480.         mpZigzag = zigzag[0];
  481.         mpWeights = weights_prescaled[0][quanttable[dctclass][qno]];
  482.         if (src0[1] & 0x40) {
  483.             mb842 = true;
  484.             mpZigzag = zigzag[1];
  485.             mpWeights = weights_prescaled[1][quanttable[dctclass][qno]];
  486.         }
  487.  
  488.         mbSplit = split;
  489.     }
  490.  
  491. #ifdef _MSC_VER
  492.     #pragma auto_inline(off)
  493. #endif
  494.     void WrapPrescaledIDCT(const VDMPEGIDCTSet& idct, uint8 *dst, ptrdiff_t pitch, void *coeff0, int last_pos) {
  495.         const sint16 *coeff = (const sint16 *)coeff0;
  496.         int coeff2[64];
  497.  
  498.         for(int i=0; i<64; ++i)
  499.             coeff2[i] = (coeff[i] * idct.pPrescaler[i] + 128) >> 8;
  500.  
  501.         idct.pIntra(dst, pitch, coeff2, last_pos);
  502.     }
  503. #ifdef _MSC_VER
  504.     #pragma auto_inline(on)
  505. #endif
  506.  
  507.     bool DVDCTBlockDecoder::Decode(DVBitSource& bitsource, const DVDecoderContext& context, bool final) {
  508.         if (!mpWeights)
  509.             return true;
  510.  
  511.         if (bitsource.src >= bitsource.srclimit) {
  512.             if (final)
  513.                 goto output;
  514.             return false;
  515.         }
  516.  
  517.         VDASSERT(mBitCount < 24);
  518.  
  519.         mBitHeap += (((*bitsource.src++) << bitsource.bitpos) & 0xff) << (24-mBitCount);
  520.         mBitCount += 8 - bitsource.bitpos;
  521.  
  522.         for(;;) {
  523.             if (mBitCount < 16) {
  524.                 if(bitsource.src < bitsource.srclimit) {
  525.                     mBitHeap += *bitsource.src++ << (24 - mBitCount);
  526.                     mBitCount += 8;
  527.                 }
  528.                 if(bitsource.src < bitsource.srclimit) {
  529.                     mBitHeap += *bitsource.src++ << (24 - mBitCount);
  530.                     mBitCount += 8;
  531.                 }
  532.             }
  533.  
  534.             const VLCEntry *acdec = DVDecodeAC(mBitHeap);
  535.  
  536.             int tmpcnt = mBitCount - acdec->len;
  537.  
  538.             if (tmpcnt < 0) {
  539.                 if (final)
  540.                     break;
  541.                 return false;
  542.             }
  543.  
  544.             mBitCount = tmpcnt;
  545.             mBitHeap <<= acdec->len;
  546.  
  547.             if (acdec->run >= 64)
  548.                 break;
  549.  
  550.             int tmpidx = mIdx + acdec->run;
  551.  
  552.             if (tmpidx >= 64) {
  553.                 mIdx = 63;
  554.                 break;
  555.             }
  556.  
  557.             mIdx = tmpidx;
  558.  
  559.             const int q = mpWeights[mIdx];
  560.  
  561.             mCoeff[mpZigzag[mIdx]] = (short)((((sint32)acdec->coeff /*<< mpShiftTab[range[mIdx]]*/) * q + 2048) >> 12);
  562.         }
  563.  
  564.         // release bits
  565.         bitsource.src -= mBitCount >> 3;
  566.         bitsource.bitpos = 0;
  567.         if (mBitCount & 7) {
  568.             --bitsource.src;
  569.             bitsource.bitpos = 8 - (mBitCount & 7);
  570.         }
  571.  
  572. output:
  573.         mpWeights = NULL;
  574.  
  575. #pragma vdpragma_TODO("optimize interlaced 8x4x2 IDCT")
  576.         if (mb842)
  577.             g_VDMPEGIDCT_reference.pIntra4x2(mpDst, mPitch, mCoeff, 63);
  578.         else {
  579.             if (context.mpIDCT->pPrescaler) {
  580. #pragma vdpragma_TODO("consider whether we should suck less here on scalar")
  581.                 WrapPrescaledIDCT(*context.mpIDCT, mpDst, mPitch, mCoeff, mIdx);
  582.             } else {
  583.                 context.mpIDCT->pIntra(mpDst, mPitch, mCoeff, mIdx);
  584.             }
  585.         }
  586.  
  587.         if (mbSplit) {
  588.             for(int i=0; i<8; ++i) {
  589.                 *(uint32 *)(mpDst + mPitch*(8+i)) = *(uint32 *)(mpDst + 4 + mPitch*i);
  590.             }
  591.         }
  592.  
  593.         return true;
  594.     }
  595. }
  596.  
  597. void VDVideoDecoderDV::DecompressFrame(const void *src, bool isPAL) {
  598.     VDASSERT(VDIsValidReadRegion(src, isPAL ? 144000 : 120000));
  599.  
  600.     static const int sNTSCMacroblockOffsets[5][27][2]={
  601. #define P(x,y) {x*32+y*8*sizeof(mYPlane[0]), x*8+y*8*sizeof(m411.mCrPlane[0])}
  602.         {
  603.             P( 9,0),P( 9,1),P( 9,2),P( 9,3),P( 9,4),P( 9,5),
  604.             P(10,5),P(10,4),P(10,3),P(10,2),P(10,1),P(10,0),
  605.             P(11,0),P(11,1),P(11,2),P(11,3),P(11,4),P(11,5),
  606.             P(12,5),P(12,4),P(12,3),P(12,2),P(12,1),P(12,0),
  607.             P(13,0),P(13,1),P(13,2)
  608.         },
  609.         {
  610.                                 P(4,3),P(4,4),P(4,5),
  611.             P(5,5),P(5,4),P(5,3),P(5,2),P(5,1),P(5,0),
  612.             P(6,0),P(6,1),P(6,2),P(6,3),P(6,4),P(6,5),
  613.             P(7,5),P(7,4),P(7,3),P(7,2),P(7,1),P(7,0),
  614.             P(8,0),P(8,1),P(8,2),P(8,3),P(8,4),P(8,5),
  615.         },
  616.         {
  617.                                     P(13,3),P(13,4),P(13,5),
  618.             P(14,5),P(14,4),P(14,3),P(14,2),P(14,1),P(14,0),
  619.             P(15,0),P(15,1),P(15,2),P(15,3),P(15,4),P(15,5),
  620.             P(16,5),P(16,4),P(16,3),P(16,2),P(16,1),P(16,0),
  621.             P(17,0),P(17,1),P(17,2),P(17,3),P(17,4),P(17,5),
  622.         },
  623.         {
  624.             P(0,0),P(0,1),P(0,2),P(0,3),P(0,4),P(0,5),
  625.             P(1,5),P(1,4),P(1,3),P(1,2),P(1,1),P(1,0),
  626.             P(2,0),P(2,1),P(2,2),P(2,3),P(2,4),P(2,5),
  627.             P(3,5),P(3,4),P(3,3),P(3,2),P(3,1),P(3,0),
  628.             P(4,0),P(4,1),P(4,2)
  629.         },
  630.         {
  631.             P(18,0),P(18,1),P(18,2),P(18,3),P(18,4),P(18,5),
  632.             P(19,5),P(19,4),P(19,3),P(19,2),P(19,1),P(19,0),
  633.             P(20,0),P(20,1),P(20,2),P(20,3),P(20,4),P(20,5),
  634.             P(21,5),P(21,4),P(21,3),P(21,2),P(21,1),P(21,0),
  635.             P(22,0),P(22,2),P(22,4)
  636.         },
  637. #undef P
  638.     };
  639.  
  640.     static const int sPALMacroblockOffsets[5][27][2]={
  641. #define P(x,y) {x*16+y*16*sizeof(mYPlane[0]), x*8+y*16*sizeof(m420.mCrPlane[0])}
  642.         {
  643.             P(18,0),P(18,1),P(18,2),P(19,2),P(19,1),P(19,0),
  644.             P(20,0),P(20,1),P(20,2),P(21,2),P(21,1),P(21,0),
  645.             P(22,0),P(22,1),P(22,2),P(23,2),P(23,1),P(23,0),
  646.             P(24,0),P(24,1),P(24,2),P(25,2),P(25,1),P(25,0),
  647.             P(26,0),P(26,1),P(26,2),
  648.         },
  649.         {
  650.             P( 9,0),P( 9,1),P( 9,2),P(10,2),P(10,1),P(10,0),
  651.             P(11,0),P(11,1),P(11,2),P(12,2),P(12,1),P(12,0),
  652.             P(13,0),P(13,1),P(13,2),P(14,2),P(14,1),P(14,0),
  653.             P(15,0),P(15,1),P(15,2),P(16,2),P(16,1),P(16,0),
  654.             P(17,0),P(17,1),P(17,2),
  655.         },
  656.         {
  657.             P(27,0),P(27,1),P(27,2),P(28,2),P(28,1),P(28,0),
  658.             P(29,0),P(29,1),P(29,2),P(30,2),P(30,1),P(30,0),
  659.             P(31,0),P(31,1),P(31,2),P(32,2),P(32,1),P(32,0),
  660.             P(33,0),P(33,1),P(33,2),P(34,2),P(34,1),P(34,0),
  661.             P(35,0),P(35,1),P(35,2),
  662.         },
  663.         {
  664.             P(0,0),P(0,1),P(0,2),P(1,2),P(1,1),P(1,0),
  665.             P(2,0),P(2,1),P(2,2),P(3,2),P(3,1),P(3,0),
  666.             P(4,0),P(4,1),P(4,2),P(5,2),P(5,1),P(5,0),
  667.             P(6,0),P(6,1),P(6,2),P(7,2),P(7,1),P(7,0),
  668.             P(8,0),P(8,1),P(8,2)
  669.         },
  670.         {
  671.             P(36,0),P(36,1),P(36,2),P(37,2),P(37,1),P(37,0),
  672.             P(38,0),P(38,1),P(38,2),P(39,2),P(39,1),P(39,0),
  673.             P(40,0),P(40,1),P(40,2),P(41,2),P(41,1),P(41,0),
  674.             P(42,0),P(42,1),P(42,2),P(43,2),P(43,1),P(43,0),
  675.             P(44,0),P(44,1),P(44,2),
  676.         },
  677. #undef P
  678.     };
  679.  
  680.     static const int sDCTYBlockOffsets411[2][4]={
  681.         0, 8, 16, 24,
  682.         0, 8, 8 * sizeof mYPlane[0], 8 + 8 * sizeof mYPlane[0],
  683.     };
  684.  
  685.     static const int sDCTYBlockOffsets420[2][4]={
  686.         0, 8, 8 * sizeof mYPlane[0], 8 + 8 * sizeof mYPlane[0],
  687.         0, 8, 8 * sizeof mYPlane[0], 8 + 8 * sizeof mYPlane[0],
  688.     };
  689.  
  690.     const int (*const pMacroblockOffsets)[27][2] = (isPAL ? sPALMacroblockOffsets : sNTSCMacroblockOffsets);
  691.     const int (*const pDCTYBlockOffsets)[4] = (isPAL ? sDCTYBlockOffsets420 : sDCTYBlockOffsets411);
  692.     const uint8 *pVideoBlock = (const uint8 *)src + 7*80;
  693.  
  694.     int chromaStep;
  695.  
  696.     uint8 *pCr, *pCb;
  697.     ptrdiff_t chroma_pitch;
  698.     int nDIFSequences;
  699.  
  700.     if (isPAL) {
  701.         chromaStep = sizeof(m420.mCrPlane[0]) * 48;
  702.  
  703.         memset(m420.mCrPlane, 0x80, sizeof m420.mCrPlane);
  704.         memset(m420.mCbPlane, 0x80, sizeof m420.mCbPlane);
  705.  
  706.         pCr = m420.mCrPlane[0];
  707.         pCb = m420.mCbPlane[1];
  708.         chroma_pitch = sizeof m420.mCrPlane[0] * 2;
  709.         nDIFSequences = 12;
  710.     } else {
  711.         chromaStep = sizeof(m411.mCrPlane[0]) * 48;
  712.  
  713.         memset(m411.mCrPlane, 0x80, sizeof m411.mCrPlane);
  714.         memset(m411.mCbPlane, 0x80, sizeof m411.mCbPlane);
  715.  
  716.         pCr = m411.mCrPlane[0];
  717.         pCb = m411.mCbPlane[0];
  718.         chroma_pitch = sizeof m411.mCrPlane[0];
  719.         nDIFSequences = 10;
  720.     }
  721.  
  722.     int zigzag[2][64];
  723.     short weights_prescaled[2][13][64];
  724.  
  725.     DVDecoderContext context;
  726.  
  727.     if (context.mpIDCT->pAltScan)
  728.         memcpy(zigzag[0], context.mpIDCT->pAltScan, sizeof(int)*64);
  729.     else
  730.         memcpy(zigzag[0], zigzag_std, sizeof(int)*64);
  731.  
  732.     memcpy(zigzag[1], zigzag_alt, sizeof(int)*64);
  733.  
  734.     int i;
  735.     for(i=0; i<13; ++i) {
  736.         for(int j=0; j<64; ++j) {
  737.             weights_prescaled[0][i][j] = (short)(((weights[zigzag_std[j]] >> (6 - shifttable[i][range[j]]))+1)>>1);
  738.  
  739.             int zig = zigzag_alt[j];        // for great justice
  740.  
  741.             // fold sum/diff together and then double y
  742.             zig = (zig & 0x1f) + (zig & 0x18);
  743.  
  744.             weights_prescaled[1][i][j] = (short)(((weights[zig] >> (6 - shifttable[i][range[j]]))+1)>>1);
  745.         }
  746.     }
  747.  
  748.     for(i=0; i<nDIFSequences; ++i) {            // 10/12 DIF sequences
  749.         int audiocounter = 0;
  750.  
  751.         const int columns[5]={
  752.             (i+2) % nDIFSequences,
  753.             (i+6) % nDIFSequences,
  754.             (i+8) % nDIFSequences,
  755.             (i  ) % nDIFSequences,
  756.             (i+4) % nDIFSequences,
  757.         };
  758.  
  759.         for(int k=0; k<27; ++k) {
  760.             DVBitSource mSources[30];
  761.             __declspec(align(16)) DVDCTBlockDecoder mDecoders[30];
  762.  
  763.             int blk = 0;
  764.  
  765.             for(int j=0; j<5; ++j) {
  766.                 const int y_offset = pMacroblockOffsets[j][k][0];
  767.                 const int c_offset = pMacroblockOffsets[j][k][1];
  768.                 const int super_y = columns[j];
  769.  
  770.                 uint8 *yptr = mYPlane[super_y*48] + y_offset;
  771.                 uint8 *crptr = pCr + chromaStep * super_y;
  772.                 uint8 *cbptr = pCb + chromaStep * super_y;
  773.  
  774.                 int qno = pVideoBlock[3] & 15;
  775.  
  776.                 bool bHalfBlock = nDIFSequences == 10 && j==4 && k>=24;
  777.                 
  778.                 mSources[blk+0].Init(pVideoBlock +  4, pVideoBlock + 18, 0);
  779.                 mSources[blk+1].Init(pVideoBlock + 18, pVideoBlock + 32, 0);
  780.                 mSources[blk+2].Init(pVideoBlock + 32, pVideoBlock + 46, 0);
  781.                 mSources[blk+3].Init(pVideoBlock + 46, pVideoBlock + 60, 0);
  782.                 mSources[blk+4].Init(pVideoBlock + 60, pVideoBlock + 70, 0);
  783.                 mSources[blk+5].Init(pVideoBlock + 70, pVideoBlock + 80, 0);
  784.                 mDecoders[blk+0].Init(yptr + pDCTYBlockOffsets[bHalfBlock][0], sizeof mYPlane[0], mSources[blk+0], qno, false, zigzag, weights_prescaled);
  785.                 mDecoders[blk+1].Init(yptr + pDCTYBlockOffsets[bHalfBlock][1], sizeof mYPlane[0], mSources[blk+1], qno, false, zigzag, weights_prescaled);
  786.                 mDecoders[blk+2].Init(yptr + pDCTYBlockOffsets[bHalfBlock][2], sizeof mYPlane[0], mSources[blk+2], qno, false, zigzag, weights_prescaled);
  787.                 mDecoders[blk+3].Init(yptr + pDCTYBlockOffsets[bHalfBlock][3], sizeof mYPlane[0], mSources[blk+3], qno, false, zigzag, weights_prescaled);
  788.                 mDecoders[blk+4].Init(crptr + c_offset, chroma_pitch, mSources[blk+4], qno, bHalfBlock, zigzag, weights_prescaled);
  789.                 mDecoders[blk+5].Init(cbptr + c_offset, chroma_pitch, mSources[blk+5], qno, bHalfBlock, zigzag, weights_prescaled);
  790.  
  791.                 int i;
  792.  
  793.                 for(i=0; i<6; ++i)
  794.                     mDecoders[blk+i].Decode(mSources[blk+i], context, false);
  795.  
  796.                 int source = 0;
  797.  
  798.                 i = 0;
  799.                 while(i < 6 && source < 6) {
  800.                     if (!mDecoders[blk+i].Decode(mSources[blk+source], context, false))
  801.                         ++source;
  802.                     else
  803.                         ++i;
  804.                 }
  805.  
  806.                 blk += 6;
  807.  
  808.                 pVideoBlock += 80;
  809.                 if (++audiocounter >= 15) {
  810.                     audiocounter = 0;
  811.                     pVideoBlock += 80;
  812.                 }
  813.             }
  814.  
  815.             int source = 0;
  816.             blk = 0;
  817.  
  818.             while(blk < 30 && source < 30) {
  819.                 if (!mDecoders[blk].Decode(mSources[source], context, false))
  820.                     ++source;
  821.                 else
  822.                     ++blk;
  823.             }
  824.  
  825.             while(blk < 30) {
  826.                 mDecoders[blk++].Decode(mSources[29], context, true);
  827.             }
  828.         }
  829.  
  830.         pVideoBlock += 80 * 6;
  831.     }
  832.  
  833.     if (isPAL)
  834.         InterpolatePALChroma();
  835.  
  836. #ifndef _M_AMD64
  837.     if (MMX_enabled)
  838.         __asm emms
  839.     if (ISSE_enabled)
  840.         __asm sfence
  841. #else
  842.     _mm_sfence();
  843. #endif
  844.  
  845.     mbLastWasPAL = isPAL;
  846. }
  847.  
  848. VDPixmap VDVideoDecoderDV::GetFrameBuffer() {
  849.     VDPixmap pxsrc = {0};
  850.     pxsrc.data        = mYPlane;
  851.     pxsrc.pitch        = sizeof mYPlane[0];
  852.     pxsrc.w            = 720;
  853.     if (mbLastWasPAL) {
  854.         pxsrc.data2        = m420.mCbPlane;
  855.         pxsrc.data3        = m420.mCrPlane;
  856.         pxsrc.pitch2    = sizeof m420.mCbPlane[0];
  857.         pxsrc.pitch3    = sizeof m420.mCrPlane[0];
  858.         pxsrc.h            = 576;
  859.         pxsrc.format    = nsVDPixmap::kPixFormat_YUV422_Planar;
  860.     } else {
  861.         pxsrc.data2        = m411.mCbPlane;
  862.         pxsrc.data3        = m411.mCrPlane;
  863.         pxsrc.pitch2    = sizeof m411.mCbPlane[0];
  864.         pxsrc.pitch3    = sizeof m411.mCrPlane[0];
  865.         pxsrc.h            = 480;
  866.         pxsrc.format    = nsVDPixmap::kPixFormat_YUV411_Planar;
  867.     }
  868.  
  869.     return pxsrc;
  870. }
  871.  
  872. namespace {
  873.     void AverageRows(uint8 *dst0, const uint8 *src10, const uint8 *src20) {
  874.         uint32 *dst = (uint32 *)dst0;
  875.         const uint32 *src1 = (const uint32 *)src10;
  876.         const uint32 *src2 = (const uint32 *)src20;
  877.  
  878.         int x = 45;
  879.         do {
  880.             uint32 a, b;
  881.  
  882.             a = src1[0];
  883.             b = src2[0];
  884.             dst[0] = (a|b) - (((a^b)&0xfefefefe)>>1);
  885.  
  886.             a = src1[1];
  887.             b = src2[1];
  888.             dst[1] = (a|b) - (((a^b)&0xfefefefe)>>1);
  889.  
  890.             src1 += 2;
  891.             src2 += 2;
  892.             dst += 2;
  893.         } while(--x);
  894.     }
  895. }
  896.  
  897. void VDVideoDecoderDV::InterpolatePALChroma() {
  898.     //    Cr:
  899.     //    0    e            e            ok
  900.     //    1                    o        copy
  901.     //    2        o        .            lerp
  902.     //    3                    .        lerp
  903.     //    4    e            e
  904.     //    5                    o
  905.     //    6        o        .
  906.     //    7                    .
  907.  
  908.     uint8 *p0 = m420.mCrPlane[0];
  909.     const ptrdiff_t pitch = sizeof m420.mCrPlane[0];
  910.     const size_t bpr = 360;
  911.  
  912.     int y;
  913.     for(y=0; y<572; y+=4) {
  914.         uint8 *p1 = p0 + pitch;
  915.         uint8 *p2 = p0 + pitch*2;
  916.         uint8 *p3 = p1 + pitch*2;
  917.         uint8 *p4 = p0 + pitch*4;
  918.         uint8 *p6 = p4 + pitch*2;
  919.  
  920.         memcpy(p1, p2, bpr);
  921.         AverageRows(p3, p2, p6);
  922.         AverageRows(p2, p0, p4);
  923.  
  924.         p0 = p4;
  925.     }
  926.  
  927.     memcpy(p0+pitch*1, p0+pitch*2, bpr);
  928.     memcpy(p0+pitch*2, p0        , bpr);
  929.     memcpy(p0+pitch*3, p0+pitch*1, bpr);
  930.  
  931.     //    Cb:
  932.     //    0                .            lerp
  933.     //    1    e                .        copy, lerp
  934.     //    2                e            -
  935.     //    3        o            o        ok
  936.     //    4                .
  937.     //    5    e                .
  938.     //    6                e
  939.     //    7        o            o
  940.  
  941.     p0 = m420.mCbPlane[0];
  942.  
  943.     memcpy(p0        , p0+pitch*1, bpr);
  944.     memcpy(p0+pitch*2, p0+pitch*1, bpr);
  945.     memcpy(p0+pitch*1, p0+pitch*3, bpr);
  946.  
  947.     for(y=4; y<576; y+=4) {
  948.         p0 += pitch*4;
  949.  
  950.         uint8 *py = p0 - pitch*2;
  951.         uint8 *pz = p0 - pitch;
  952.         uint8 *p1 = p0 + pitch;
  953.         uint8 *p2 = p0 + pitch*2;
  954.         uint8 *p3 = p1 + pitch*2;
  955.  
  956.         AverageRows(p0, py, p1);
  957.         memcpy(p2, p1, bpr);
  958.         AverageRows(p1, p3, pz);
  959.     }
  960. }
  961.