home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / gfx / misc / mpeg_stat_2_2a.lha / mpeg_stat / src / parseblock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-21  |  12.2 KB  |  504 lines

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