home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / mpegplay.zip / PARSEBLO.C < prev    next >
C/C++ Source or Header  |  1993-02-02  |  10KB  |  448 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. #define NO_SANITY_CHECKS
  22. #include <assert.h>
  23. #include "video.h"
  24. #include "proto.h"
  25. #include "decoders.h"
  26.  
  27. /* External declarations. */
  28.  
  29. extern int zigzag_direct[];
  30.  
  31. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  32.  
  33. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  34.  
  35.  
  36. /*
  37.  *--------------------------------------------------------------
  38.  *
  39.  * ParseReconBlock --
  40.  *
  41.  *    Parse values for block structure from bitstream.
  42.  *      n is an indication of the position of the block within
  43.  *      the macroblock (i.e. 0-5) and indicates the type of 
  44.  *      block (i.e. luminance or chrominance). Reconstructs
  45.  *      coefficients from values parsed and puts in 
  46.  *      block.dct_recon array in vid stream structure.
  47.  *      sparseFlag is set when the block contains only one
  48.  *      coeffictient and is used by the IDCT.
  49.  *
  50.  * Results:
  51.  *    
  52.  *
  53.  * Side effects:
  54.  *      Bit stream irreversibly parsed.
  55.  *
  56.  *--------------------------------------------------------------
  57.  */
  58.  
  59. #define DCT_recon blockPtr->dct_recon
  60. #define DCT_dc_y_past blockPtr->dct_dc_y_past
  61. #define DCT_dc_cr_past blockPtr->dct_dc_cr_past
  62. #define DCT_dc_cb_past blockPtr->dct_dc_cb_past
  63.  
  64. #define DECODE_DCT_COEFF_FIRST DecodeDCTCoeffFirst
  65. #define DECODE_DCT_COEFF_NEXT DecodeDCTCoeffNext
  66.  
  67. void
  68. ParseReconBlock(n)
  69.      int n;
  70. {
  71. #ifdef RISC
  72.   unsigned int temp_curBits;
  73.   int temp_bitOffset;
  74.   int temp_bufLength;
  75.   unsigned int *temp_bitBuffer;
  76. #endif
  77.  
  78.   Block *blockPtr = &curVidStream->block;
  79.   int coeffCount;
  80.   
  81.   if (bufLength < 100)
  82.     correct_underflow();
  83.  
  84. #ifdef RISC
  85.   temp_curBits = curBits;
  86.   temp_bitOffset = bitOffset;
  87.   temp_bufLength = bufLength;
  88.   temp_bitBuffer = bitBuffer;
  89. #endif
  90.  
  91.   {
  92.     /*
  93.      * Copy the globals curBits, bitOffset, bufLength, and bitBuffer
  94.      * into local variables with the same names, so the macros use the
  95.      * local variables instead.  This allows register allocation and
  96.      * can provide 1-2 fps speedup.  On machines with not so many registers,
  97.      * don't do this.
  98.      */
  99. #ifdef RISC
  100.     register unsigned int curBits = temp_curBits;
  101.     register int bitOffset = temp_bitOffset;
  102.     register int bufLength = temp_bufLength;
  103.     register unsigned int *bitBuffer = temp_bitBuffer;
  104. #endif
  105.  
  106.     int diff;
  107.     int size, level, i, run, pos, coeff;
  108.     short int *reconptr;
  109.     unsigned char *iqmatrixptr, *niqmatrixptr;
  110.     int qscale;
  111.  
  112.     reconptr = DCT_recon[0];
  113.  
  114.     /* 
  115.      * Hand coded version of memset that's a little faster...
  116.      * Old call:
  117.      *    memset((char *) DCT_recon, 0, 64*sizeof(short int));
  118.      */
  119.     {
  120.       INT32 *p;
  121.       p = (INT32 *) reconptr;
  122.  
  123.       p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] = 
  124.       p[10] = p[11] = p[12] = p[13] = p[14] = p[15] = p[16] = p[17] = p[18] =
  125.       p[19] = p[20] = p[21] = p[22] = p[23] = p[24] = p[25] = p[26] = p[27] =
  126.       p[28] = p[29] = p[30] = p[31] = 0;
  127.  
  128.     }
  129.  
  130.     if (curVidStream->mblock.mb_intra) {
  131.  
  132.       if (n < 4) {
  133.  
  134.     /*
  135.      * Get the luminance bits.  This code has been hand optimized to
  136.      * get by the normal bit parsing routines.  We get some speedup
  137.      * by grabbing the next 16 bits and parsing things locally.
  138.      * Thus, calls are translated as:
  139.      *
  140.      *    show_bitsX  <-->   next16bits >> (16-X)
  141.      *    get_bitsX   <-->   val = next16bits >> (16-flushed-X);
  142.      *               flushed += X;
  143.      *               next16bits &= bitMask[flushed];
  144.      *    flush_bitsX <-->   flushed += X;
  145.      *               next16bits &= bitMask[flushed];
  146.      *
  147.      * I've streamlined the code a lot, so that we don't have to mask
  148.      * out the low order bits and a few of the extra adds are removed.
  149.      *    bsmith
  150.      */
  151.     unsigned int next16bits, index, flushed;
  152.  
  153.     show_bits16(next16bits);
  154.     index = next16bits >> (16-7);
  155.     size = dct_dc_size_luminance[index].value;
  156.     flushed = dct_dc_size_luminance[index].num_bits;
  157.     next16bits &= bitMask[16+flushed];
  158.  
  159.     if (size != 0) {
  160.       flushed += size;
  161.       diff = next16bits >> (16-flushed);
  162.           if (!(diff & bitTest[32-size])) {
  163.         diff = rBitMask[size] | (diff + 1);
  164.       }
  165.     } else {
  166.       diff = 0;
  167.     }
  168.     flush_bits(flushed);
  169.  
  170.     if (n == 0) {
  171.       coeff = diff << 3;
  172.       if (curVidStream->mblock.mb_address -
  173.           curVidStream->mblock.past_intra_addr > 1) 
  174.         coeff += 1024;
  175.       else coeff += DCT_dc_y_past;
  176.       DCT_dc_y_past = coeff;
  177.     } else {
  178.       coeff = DCT_dc_y_past + (diff << 3);
  179.       DCT_dc_y_past = coeff;
  180.     }
  181.       } else {
  182.     
  183.     /*
  184.      * Get the chrominance bits.  This code has been hand optimized to
  185.      * as described above
  186.      */
  187.     unsigned int next16bits, index, flushed;
  188.  
  189.     show_bits16(next16bits);
  190.     index = next16bits >> (16-8);
  191.     size = dct_dc_size_chrominance[index].value;
  192.     flushed = dct_dc_size_chrominance[index].num_bits;
  193.     next16bits &= bitMask[16+flushed];
  194.     
  195.     if (size != 0) {
  196.       flushed += size;
  197.       diff = next16bits >> (16-flushed);
  198.           if (!(diff & bitTest[32-size])) {
  199.         diff = rBitMask[size] | (diff + 1);
  200.       }
  201.     } else {
  202.       diff = 0;
  203.     }
  204.     flush_bits(flushed);
  205.     
  206.     if (n == 4) {
  207.       coeff = diff << 3;
  208.       if (curVidStream->mblock.mb_address -
  209.           curVidStream->mblock.past_intra_addr > 1) 
  210.         coeff += 1024;
  211.       else coeff += DCT_dc_cr_past;
  212.       DCT_dc_cr_past = coeff;
  213.  
  214.     } else {
  215.       coeff = diff << 3;
  216.       if (curVidStream->mblock.mb_address -
  217.           curVidStream->mblock.past_intra_addr > 1) 
  218.         coeff += 1024;
  219.       else coeff += DCT_dc_cb_past;
  220.       DCT_dc_cb_past = coeff;
  221.     }
  222.       }
  223.       
  224.       *reconptr = coeff;
  225.       i = 0; pos = 0;
  226.       coeffCount = (coeff != 0);
  227.     
  228.       if (curVidStream->picture.code_type != 4) {
  229.     
  230.     qscale = curVidStream->slice.quant_scale;
  231.     iqmatrixptr = curVidStream->intra_quant_matrix[0];
  232.     
  233.     while(1) {
  234.       
  235.       DECODE_DCT_COEFF_NEXT(run, level);
  236.  
  237.       if (run == END_OF_BLOCK) break;
  238.  
  239.       i = i + run + 1;
  240.       pos = zigzag_direct[i];
  241.       coeff = (level * qscale * ((int) iqmatrixptr[pos])) >> 3;
  242.       if (level < 0) {
  243.           coeff += (coeff & 1);
  244.       } else {
  245.           coeff -= (coeff & 1);
  246.       }
  247.  
  248.       reconptr[pos] = coeff;
  249.       if (coeff) {
  250.         coeffCount++;
  251.       }
  252.  
  253.     }
  254.  
  255. #ifdef ANALYSIS 
  256.  
  257.     {
  258.       extern unsigned int *mbCoeffPtr;
  259.       mbCoeffPtr[pos]++;
  260.     }
  261. #endif
  262.  
  263.     flush_bits(2);
  264.  
  265.     goto end;
  266.       }
  267.     }
  268.     
  269.     else {
  270.       
  271.       niqmatrixptr = curVidStream->non_intra_quant_matrix[0];
  272.       qscale = curVidStream->slice.quant_scale;
  273.       
  274.       DECODE_DCT_COEFF_FIRST(run, level);
  275.       i = run;
  276.  
  277.       pos = zigzag_direct[i];
  278.       if (level < 0) {
  279.       coeff = (((level<<1) - 1) * qscale * 
  280.            ((int) (niqmatrixptr[pos]))) >> 4; 
  281.       coeff += (coeff & 1);
  282.       } else {
  283.       coeff = (((level<<1) + 1) * qscale * 
  284.            ((int) (*(niqmatrixptr+pos)))) >> 4; 
  285.       coeff -= (coeff & 1);
  286.       }
  287.       reconptr[pos] = coeff;
  288.       if (coeff) {
  289.     coeffCount = 1;
  290.       }
  291.  
  292.       if (curVidStream->picture.code_type != 4) {
  293.     
  294.     while(1) {
  295.       
  296.       DECODE_DCT_COEFF_NEXT(run, level);
  297.  
  298.       if (run == END_OF_BLOCK) break;
  299.  
  300.       i = i+run+1;
  301.       pos = zigzag_direct[i];
  302.       if (level < 0) {
  303.           coeff = (((level<<1) - 1) * qscale * 
  304.                ((int) (niqmatrixptr[pos]))) >> 4; 
  305.           coeff += (coeff & 1);
  306.       } else {
  307.           coeff = (((level<<1) + 1) * qscale * 
  308.                ((int) (*(niqmatrixptr+pos)))) >> 4; 
  309.           coeff -= (coeff & 1);
  310.       }
  311.       reconptr[pos] = coeff;
  312.       if (coeff) {
  313.         coeffCount++;
  314.       }
  315.     }
  316.  
  317. #ifdef ANALYSIS
  318.     {
  319.       extern unsigned int *mbCoeffPtr;
  320.       mbCoeffPtr[pos]++;
  321.     }
  322. #endif
  323.  
  324.     flush_bits(2);
  325.  
  326.     goto end;
  327.       }
  328.     }
  329.     
  330.   end:
  331.  
  332.     if (coeffCount == 1) j_rev_dct_sparse (reconptr, pos);
  333.     else j_rev_dct(reconptr);
  334.  
  335. #ifdef RISC
  336.     temp_curBits = curBits;
  337.     temp_bitOffset = bitOffset;
  338.     temp_bufLength = bufLength;
  339.     temp_bitBuffer = bitBuffer;
  340. #endif
  341.  
  342.   }
  343.  
  344. #ifdef RISC
  345.   curBits = temp_curBits;
  346.   bitOffset = temp_bitOffset;
  347.   bufLength = temp_bufLength;
  348.   bitBuffer = temp_bitBuffer;
  349. #endif
  350. }
  351.     
  352. #undef DCT_recon 
  353. #undef DCT_dc_y_past 
  354. #undef DCT_dc_cr_past 
  355. #undef DCT_dc_cb_past 
  356.  
  357.  
  358. /*
  359.  *--------------------------------------------------------------
  360.  *
  361.  * ParseAwayBlock --
  362.  *
  363.  *    Parses off block values, throwing them away.
  364.  *      Used with grayscale dithering.
  365.  *
  366.  * Results:
  367.  *    None.
  368.  *
  369.  * Side effects:
  370.  *      None.
  371.  *
  372.  *--------------------------------------------------------------
  373.  */
  374.  
  375. void
  376. ParseAwayBlock(n)
  377.      int n;
  378. {
  379.   unsigned int diff;
  380.   unsigned int size, run;
  381.   int level;
  382.  
  383.   if (bufLength < 100)
  384.     correct_underflow();
  385.  
  386.   if (curVidStream->mblock.mb_intra) {
  387.  
  388.     /* If the block is a luminance block... */
  389.  
  390.     if (n < 4) {
  391.  
  392.       /* Parse and decode size of first coefficient. */
  393.  
  394.       DecodeDCTDCSizeLum(size);
  395.  
  396.       /* Parse first coefficient. */
  397.  
  398.       if (size != 0) {
  399.     get_bitsn(size, diff);
  400.       }
  401.     }
  402.  
  403.     /* Otherwise, block is chrominance block... */
  404.  
  405.     else {
  406.  
  407.       /* Parse and decode size of first coefficient. */
  408.  
  409.       DecodeDCTDCSizeChrom(size);
  410.  
  411.       /* Parse first coefficient. */
  412.  
  413.       if (size != 0) {
  414.     get_bitsn(size, diff);
  415.       }
  416.     }
  417.   }
  418.  
  419.   /* Otherwise, block is not intracoded... */
  420.  
  421.   else {
  422.  
  423.     /* Decode and set first coefficient. */
  424.  
  425.     DECODE_DCT_COEFF_FIRST(run, level);
  426.   }
  427.  
  428.   /* If picture is not D type (i.e. I, P, or B)... */
  429.  
  430.   if (curVidStream->picture.code_type != 4) {
  431.  
  432.     /* While end of macroblock has not been reached... */
  433.  
  434.     while (1) {
  435.  
  436.       /* Get the dct_coeff_next */
  437.  
  438.       DECODE_DCT_COEFF_NEXT(run, level);
  439.  
  440.       if (run == END_OF_BLOCK) break;
  441.     }
  442.  
  443.     /* End_of_block */
  444.  
  445.     flush_bits(2);
  446.   }
  447. }
  448.