home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / gfx / misc / mpeg_stat_2_2a.lha / mpeg_stat / src / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-21  |  11.8 KB  |  499 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.  
  46. #include <stdlib.h>
  47. #include "video.h"
  48. #include "proto.h"
  49. #include "util.h"
  50. #include "opts.h"
  51.  
  52. /* Declarations of global variables used. */
  53.  
  54. unsigned int curBits;
  55. int bitOffset;
  56. int bufLength;
  57. unsigned int *bitBuffer;
  58. extern BlockVals blks;
  59. extern int buggy;
  60. long ones = 0;
  61. long zeros = 0;
  62.  
  63. /* Bit masks used by bit i/o operations. */
  64.  
  65. unsigned int nBitMask[] = { 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 
  66.                 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 
  67.                 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 
  68.                 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 
  69.                 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 
  70.                 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 
  71.                 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 
  72.                 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe};
  73.  
  74. unsigned int bitMask[] = {  0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff, 
  75.                 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
  76.                 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
  77.                 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
  78.                 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
  79.                 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
  80.                 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
  81.                 0x0000000f, 0x00000007, 0x00000003, 0x00000001};
  82.  
  83. unsigned int rBitMask[] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 
  84.                 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 
  85.                 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, 
  86.                 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 
  87.                 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, 
  88.                 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 
  89.                 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, 
  90.                 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000};
  91.  
  92. unsigned int bitTest[] = {  0x80000000, 0x40000000, 0x20000000, 0x10000000, 
  93.                 0x08000000, 0x04000000, 0x02000000, 0x01000000,
  94.                 0x00800000, 0x00400000, 0x00200000, 0x00100000,
  95.                 0x00080000, 0x00040000, 0x00020000, 0x00010000,
  96.                 0x00008000, 0x00004000, 0x00002000, 0x00001000,
  97.                 0x00000800, 0x00000400, 0x00000200, 0x00000100,
  98.                 0x00000080, 0x00000040, 0x00000020, 0x00000010,
  99.                 0x00000008, 0x00000004, 0x00000002, 0x00000001};
  100.  
  101.  
  102. /*
  103.  *--------------------------------------------------------------
  104.  *
  105.  * correct_underflow --
  106.  *
  107.  *    Called when buffer does not have sufficient data to 
  108.  *      satisfy request for bits.
  109.  *      Calls get_more_data, an application specific routine
  110.  *      required to fill the buffer with more data.
  111.  *
  112.  * Results:
  113.  *      None really.
  114.  *  
  115.  * Side effects:
  116.  *    buf_length and buffer fields in curVidStream structure
  117.  *      may be changed.
  118.  *
  119.  *--------------------------------------------------------------
  120.  */
  121. void 
  122. correct_underflow() {
  123.  
  124.   int status;
  125.   {
  126.       int init_length = bufLength;
  127.       unsigned int *bp;
  128.       
  129.   status = get_more_data(&curVidStream->buf_start,
  130.              &curVidStream->max_buf_length,
  131.              &bufLength, &bitBuffer);
  132.       if (opts&BITS_INFO) {
  133.     for (bp = bitBuffer + init_length;
  134.          bp < (bitBuffer + bufLength);
  135.          bp++) {
  136.       register unsigned int tmp, tmp2, countones;
  137. #define BITCOUNT(x)     (((x+(x>>4)) & 0x0F0F0F0F) % 255)
  138. #define  BX_PRE(x)         ((x) - (((x)>>1)&0x77777777)  \
  139.                 - (((x)>>2)&0x33333333)      \
  140.                 - (((x)>>3)&0x11111111))
  141.           tmp = *bp;
  142.       tmp2 = BX_PRE(tmp);
  143.       countones = BITCOUNT(tmp2);
  144.       ones += countones;
  145.       zeros += (32-countones);
  146.     }
  147.       }
  148.     }
  149.   if (status  < 0) {
  150.     fprintf (stderr, "\n");
  151.     perror("Unexpected read error.");
  152.     exit(1);
  153.   }
  154.   else if ((status == 0) && (bufLength < 1)) {
  155.     fprintf(stderr, "\nImproper or missing sequence end code.\n");
  156.     buggy = 1;
  157.     if (bitCount>0) {
  158.       if (blks.frame>0) {
  159.     PrintAllStats();
  160.     PrintTimeInfo();
  161.       }
  162.     } else {
  163.       fprintf(stderr,"File appears to be empty.\n");
  164.       fflush(stderr);
  165.     }
  166.     DestroyVidStream(curVidStream);
  167.     exit(0);
  168.   }
  169. #ifdef UTIL2
  170.   curBits = *bitBuffer << bitOffset;
  171. #else
  172.   curBits = *bitBuffer;
  173. #endif
  174.  
  175. }
  176.  
  177.  
  178. /*
  179.  *--------------------------------------------------------------
  180.  *
  181.  * next_bits --
  182.  *
  183.  *    Compares next num bits to low order position in mask.
  184.  *      Buffer pointer is NOT advanced.
  185.  *
  186.  * Results:
  187.  *    TRUE, FALSE, or error code.
  188.  *
  189.  * Side effects:
  190.  *    None.
  191.  *
  192.  *--------------------------------------------------------------
  193.  */
  194.  
  195. int next_bits(num, mask)
  196. int num;
  197. unsigned int mask;
  198. {
  199.   unsigned int stream;
  200.   int ret_value;
  201.  
  202.   /* If no current stream, return error. */
  203.  
  204.   if (curVidStream == NULL)
  205.     return NO_VID_STREAM;
  206.  
  207.   /* Get next num bits, no buffer pointer advance. */
  208.  
  209.   show_bitsn(num, stream);
  210.  
  211.   /* Compare bit stream and mask. Set return value toTRUE if equal, FALSE if
  212.      differs. 
  213.   */
  214.  
  215.   if (mask == stream) {
  216.     ret_value = TRUE;
  217.   } else ret_value = FALSE;
  218.  
  219.   /* Return return value. */
  220.  
  221.   return ret_value;
  222. }
  223.  
  224.  
  225. /*
  226.  *--------------------------------------------------------------
  227.  *
  228.  * get_ext_data --
  229.  *
  230.  *    Assumes that bit stream is at begining of extension
  231.  *      data. Parses off extension data into dynamically 
  232.  *      allocated space until start code is hit. 
  233.  *
  234.  * Results:
  235.  *    Pointer to dynamically allocated memory containing
  236.  *      extension data.
  237.  *
  238.  * Side effects:
  239.  *    Bit stream irreversibly parsed.
  240.  *
  241.  *--------------------------------------------------------------
  242.  */
  243.  
  244. char *get_ext_data (size)
  245. int *size;
  246. {
  247.   int sz, marker;
  248.   char *dataPtr;
  249.   unsigned int data;
  250.  
  251.   /* Set initial ext data buffer size. */
  252.  
  253.   sz = EXT_BUF_SIZE;
  254.  
  255.   /* Allocate ext data buffer. */
  256.  
  257.   dataPtr = (char *) malloc(sz);
  258.  
  259.   /* Initialize marker to keep place in ext data buffer. */
  260.  
  261.   marker = 0;
  262.  
  263.   /* While next data is not start code... */
  264.   while (!next_bits(24, 0x000001)) {
  265.  
  266.     /* Get next byte of ext data. */
  267.  
  268.     get_bits8(data);
  269.  
  270.     /* Put ext data into ext data buffer. Advance marker. */
  271.  
  272.     dataPtr[marker] = (char) data;
  273.     marker++;
  274.  
  275.     /* If end of ext data buffer reached, resize data buffer. */
  276.  
  277.     if (marker == sz) {
  278.       sz += EXT_BUF_SIZE;
  279.       dataPtr = (char *) realloc(dataPtr, sz);
  280.     }
  281.   }
  282.  
  283.   /* Realloc data buffer to free any extra space. */
  284.  
  285.   dataPtr = (char *) realloc(dataPtr, marker);
  286.  
  287.   *size = marker;
  288.  
  289.   /* Return pointer to ext data buffer. */
  290.  
  291.   return dataPtr;
  292. }
  293.  
  294.  
  295. /*
  296.  *--------------------------------------------------------------
  297.  *
  298.  * next_start_code --
  299.  *
  300.  *    Parses off bitstream until start code reached. When done
  301.  *      next 4 bytes of bitstream will be start code. Bit offset
  302.  *      reset to 0.
  303.  *
  304.  * Results:
  305.  *    Status code.
  306.  *
  307.  * Side effects:
  308.  *    Bit stream irreversibly parsed.
  309.  *
  310.  *--------------------------------------------------------------
  311.  */
  312. int next_start_code()
  313. {
  314.   int state;
  315.   int byteoff;
  316.   unsigned int data;
  317.  
  318.   /* If no current stream, return error. */
  319.  
  320.   if (curVidStream == NULL)
  321.     return NO_VID_STREAM;
  322.  
  323.   /* If insufficient buffer length, correct underflow. */
  324.  
  325.   if (bufLength < 4) {
  326.     correct_underflow();
  327.   }
  328.  
  329.   /* If bit offset not zero, reset and advance buffer pointer. */
  330.  
  331.   byteoff = bitOffset % 8;
  332.  
  333.   if (byteoff != 0) {
  334.     flush_bits((8-byteoff));
  335.   }
  336.  
  337.   /* Set state = 0. */
  338.  
  339.   state = 0;
  340.  
  341.   /* While buffer has data ... */
  342.  
  343.   while(bufLength > 0) {
  344.     
  345.     /* If insufficient data exists, correct underflow. */
  346.     
  347.     if (bufLength < 4) {
  348.       correct_underflow();
  349.     }
  350.     
  351.     /* If next byte is zero... */
  352.     get_bits8(data);
  353.     
  354.     if (data == 0) {
  355.       if (state < 2) state++;
  356.     }
  357.     
  358.     /* If next byte is one... */
  359.     else if (data == 1) {
  360.       
  361.       /* If state == 2, advance state (i.e. start code found). */
  362.       if (state == 2) state++;
  363.       
  364.       /* Otherwise, reset state to zero. */
  365.       else state = 0;
  366.     }
  367.     
  368.     /* Otherwise byte is neither 1 or 0, reset state to 0. */
  369.     else {
  370.       state = 0;
  371.     }
  372.     
  373.     /* If state == 3 (i.e. start code found)... */
  374.     if (state == 3) {
  375.       
  376.       /* Set buffer pointer back and reset length & bit offsets so
  377.      next bytes will be beginning of start code. 
  378.      */
  379.       
  380.       bitOffset = bitOffset - 24;
  381.       
  382.       bitCount -= 24;
  383.       
  384.       if (bitOffset < 0) {
  385.     while  (bitOffset < 0) {
  386.       bitOffset += 32;
  387.       bufLength++;
  388.       bitBuffer--;
  389. #ifdef UTIL2
  390.     curBits = *bitBuffer << bitOffset;
  391. #else
  392.     curBits = *bitBuffer;
  393. #endif
  394.     }
  395.       }
  396.       else {
  397. #ifdef UTIL2
  398.     curBits = *bitBuffer << bitOffset;
  399. #else
  400.     curBits = *bitBuffer;
  401. #endif
  402.       }
  403.  
  404.       /* Return success. */
  405. /* if ((bitOffset-8*byteoff)>100) printf("nsc skipped %d\n",(bitOffset-8*byteoff)); */
  406.       return OK;
  407.     }
  408.   }
  409.  
  410.   /* Return underflow error. */
  411.  
  412.   return STREAM_UNDERFLOW;
  413. }
  414.  
  415.  
  416. /*
  417.  *--------------------------------------------------------------
  418.  *
  419.  * get_extra_bit_info --
  420.  *
  421.  *    Parses off extra bit info stream into dynamically 
  422.  *      allocated memory. Extra bit info is indicated by
  423.  *      a flag bit set to 1, followed by 8 bits of data.
  424.  *      This continues until the flag bit is zero. Assumes
  425.  *      that bit stream set to first flag bit in extra
  426.  *      bit info stream.
  427.  *
  428.  * Results:
  429.  *    Pointer to dynamically allocated memory with extra
  430.  *      bit info in it. Flag bits are NOT included.
  431.  *
  432.  * Side effects:
  433.  *    Bit stream irreversibly parsed.
  434.  *
  435.  *--------------------------------------------------------------
  436.  */
  437.  
  438. char *get_extra_bit_info ()
  439. {
  440.   int size, marker;
  441.   char *dataPtr;
  442.   unsigned int data;
  443.  
  444.   /* Get first flag bit. */
  445.   get_bits1(data);
  446.  
  447.   /* If flag is false, return NULL pointer (i.e. no extra bit info). */
  448.  
  449.   if (!data) return NULL;
  450.  
  451.   /* Initialize size of extra bit info buffer and allocate. */
  452.  
  453.   size = EXT_BUF_SIZE;
  454.   dataPtr = (char *) malloc(size);
  455.  
  456.   /* Reset marker to hold place in buffer. */
  457.  
  458.   marker = 0;
  459.  
  460.   /* While flag bit is true. */
  461.  
  462.   while (data) {
  463.  
  464.     /* Get next 8 bits of data. */
  465.     get_bits8(data);
  466.  
  467.     /* Place in extra bit info buffer. */
  468.  
  469.     dataPtr[marker] = (char) data;
  470.     marker++;
  471.  
  472.     /* If buffer is full, reallocate. */
  473.  
  474.     if (marker == size) {
  475.       size += EXT_BUF_SIZE;
  476.       dataPtr = (char *) realloc(dataPtr, size);
  477.     }
  478.  
  479.     /* Get next flag bit. */
  480.     get_bits1(data);
  481.   }
  482.  
  483.   /* Reallocate buffer to free extra space. */
  484.  
  485.   dataPtr = (char *) realloc(dataPtr, marker);
  486.  
  487.   /* Return pointer to extra bit info buffer. */
  488.  
  489.   return dataPtr;
  490. }
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.