home *** CD-ROM | disk | FTP | other *** search
/ MPEG Toolkit / MPEG Toolkit.iso / dos / mpegstat / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-01  |  11.3 KB  |  470 lines

  1. /* MPEGSTAT - analyzing tool for MPEG-I video streams
  2.  * 
  3.  * Technical University of Berlin, Germany, Dept. of Computer Science
  4.  * Tom Pfeifer - Multimedia systems project - pfeifer@fokus.gmd.de
  5.  *
  6.  * Jens Brettin, Harald Masche, Alexander Schulze, Dirk Schubert
  7.  *
  8.  * This program uses parts of the source code of the Berkeley MPEG player
  9.  *
  10.  * ---------------------------
  11.  *
  12.  * Copyright (c) 1993 Technical University of Berlin, Germany
  13.  *
  14.  * for the parts of the Berkeley player used:
  15.  *
  16.  * Copyright (c) 1992 The Regents of the University of California.
  17.  * All rights reserved.
  18.  *
  19.  * ---------------------------
  20.  *
  21.  * Permission to use, copy, modify, and distribute this software and its
  22.  * documentation for any purpose, without fee, and without written agreement is
  23.  * hereby granted, provided that the above copyright notices and the following
  24.  * two paragraphs appear in all copies of this software.
  25.  * 
  26.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA 
  27.  * or the Technical University of Berlin BE LIABLE TO ANY PARTY FOR
  28.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  29.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  30.  * CALIFORNIA or the Technical University of Berlin HAS BEEN ADVISED OF THE 
  31.  * POSSIBILITY OF SUCH DAMAGE.
  32.  * 
  33.  * THE UNIVERSITY OF CALIFORNIA and the Technical University of Berlin 
  34.  * SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
  35.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  36.  * PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE 
  37.  * UNIVERSITY OF CALIFORNIA and the Technical University of Berlin HAVE NO 
  38.  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 
  39.  * OR MODIFICATIONS.
  40.  */
  41. #include <stdlib.h>
  42. #include "video.h"
  43. #include "proto.h"
  44. #include "util.h"
  45. #include "dither.h"
  46.  
  47. /* Declarations of global variables used. */
  48.  
  49. unsigned int curBits;
  50. int bitOffset;
  51. int bufLength;
  52. unsigned int *bitBuffer;
  53.  
  54. /* Bit masks used by bit i/o operations. */
  55.  
  56. unsigned int nBitMask[] = { 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 
  57.                 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 
  58.                 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 
  59.                 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 
  60.                 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 
  61.                 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 
  62.                 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 
  63.                 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe};
  64.  
  65. unsigned int bitMask[] = {  0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff, 
  66.                 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
  67.                 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
  68.                 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
  69.                 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
  70.                 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
  71.                 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
  72.                 0x0000000f, 0x00000007, 0x00000003, 0x00000001};
  73.  
  74. unsigned int rBitMask[] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 
  75.                 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 
  76.                 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, 
  77.                 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 
  78.                 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, 
  79.                 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 
  80.                 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, 
  81.                 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000};
  82.  
  83. unsigned int bitTest[] = {  0x80000000, 0x40000000, 0x20000000, 0x10000000, 
  84.                 0x08000000, 0x04000000, 0x02000000, 0x01000000,
  85.                 0x00800000, 0x00400000, 0x00200000, 0x00100000,
  86.                 0x00080000, 0x00040000, 0x00020000, 0x00010000,
  87.                 0x00008000, 0x00004000, 0x00002000, 0x00001000,
  88.                 0x00000800, 0x00000400, 0x00000200, 0x00000100,
  89.                 0x00000080, 0x00000040, 0x00000020, 0x00000010,
  90.                 0x00000008, 0x00000004, 0x00000002, 0x00000001};
  91.  
  92.  
  93. /*
  94.  *--------------------------------------------------------------
  95.  *
  96.  * correct_underflow --
  97.  *
  98.  *    Called when buffer does not have sufficient data to 
  99.  *      satisfy request for bits.
  100.  *      Calls get_more_data, an application specific routine
  101.  *      required to fill the buffer with more data.
  102.  *
  103.  * Results:
  104.  *      None really.
  105.  *  
  106.  * Side effects:
  107.  *    buf_length and buffer fields in curVidStream structure
  108.  *      may be changed.
  109.  *
  110.  *--------------------------------------------------------------
  111.  */
  112.  
  113. void 
  114. correct_underflow() {
  115.  
  116.   int status;
  117.  
  118.   status = get_more_data(curVidStream->buf_start,
  119.              curVidStream->max_buf_length,
  120.              &bufLength, &bitBuffer);
  121.  
  122.   if (status  < 0) {
  123.     fprintf (stderr, "\n");
  124.     perror("Unexpected read error.");
  125.     exit(1);
  126.   }
  127.   else if ((status == 0) && (bufLength < 1)) {
  128.     fprintf(stderr, "\nImproper or missing sequence end code.\n");
  129.     PrintAllStats();
  130.     PrintTimeInfo();
  131.     if (loopFlag) longjmp(env, 1);
  132.     DestroyVidStream(curVidStream);
  133.     exit(0);
  134.   }
  135. #ifdef UTIL2
  136.   curBits = *bitBuffer << bitOffset;
  137. #else
  138.   curBits = *bitBuffer;
  139. #endif
  140.  
  141. }
  142.  
  143.  
  144. /*
  145.  *--------------------------------------------------------------
  146.  *
  147.  * next_bits --
  148.  *
  149.  *    Compares next num bits to low order position in mask.
  150.  *      Buffer pointer is NOT advanced.
  151.  *
  152.  * Results:
  153.  *    TRUE, FALSE, or error code.
  154.  *
  155.  * Side effects:
  156.  *    None.
  157.  *
  158.  *--------------------------------------------------------------
  159.  */
  160.  
  161. int next_bits(num, mask)
  162. int num;
  163. unsigned int mask;
  164. {
  165.   unsigned int stream;
  166.   int ret_value;
  167.  
  168.   /* If no current stream, return error. */
  169.  
  170.   if (curVidStream == NULL)
  171.     return NO_VID_STREAM;
  172.  
  173.   /* Get next num bits, no buffer pointer advance. */
  174.  
  175.   show_bitsn(num, stream);
  176.  
  177.   /* Compare bit stream and mask. Set return value toTRUE if equal, FALSE if
  178.      differs. 
  179.   */
  180.  
  181.   if (mask == stream) {
  182.     ret_value = TRUE;
  183.   } else ret_value = FALSE;
  184.  
  185.   /* Return return value. */
  186.  
  187.   return ret_value;
  188. }
  189.  
  190.  
  191. /*
  192.  *--------------------------------------------------------------
  193.  *
  194.  * get_ext_data --
  195.  *
  196.  *    Assumes that bit stream is at begining of extension
  197.  *      data. Parses off extension data into dynamically 
  198.  *      allocated space until start code is hit. 
  199.  *
  200.  * Results:
  201.  *    Pointer to dynamically allocated memory containing
  202.  *      extension data.
  203.  *
  204.  * Side effects:
  205.  *    Bit stream irreversibly parsed.
  206.  *
  207.  *--------------------------------------------------------------
  208.  */
  209.  
  210. char *get_ext_data ()
  211. {
  212.   int size, marker;
  213.   char *dataPtr;
  214.   unsigned int data;
  215.  
  216.   /* Set initial ext data buffer size. */
  217.  
  218.   size = EXT_BUF_SIZE;
  219.  
  220.   /* Allocate ext data buffer. */
  221.  
  222.   dataPtr = (char *) malloc(size);
  223.  
  224.   /* Initialize marker to keep place in ext data buffer. */
  225.  
  226.   marker = 0;
  227.  
  228.   /* While next data is not start code... */
  229.   while (!next_bits(24, 0x000001)) {
  230.  
  231.     /* Get next byte of ext data. */
  232.  
  233.     get_bits8(data);
  234.  
  235.     /* Put ext data into ext data buffer. Advance marker. */
  236.  
  237.     dataPtr[marker] = (char) data;
  238.     marker++;
  239.  
  240.     /* If end of ext data buffer reached, resize data buffer. */
  241.  
  242.     if (marker == size) {
  243.       size += EXT_BUF_SIZE;
  244.       dataPtr = (char *) realloc(dataPtr, size);
  245.     }
  246.   }
  247.  
  248.   /* Realloc data buffer to free any extra space. */
  249.  
  250.   dataPtr = (char *) realloc(dataPtr, marker);
  251.  
  252.   /* Return pointer to ext data buffer. */
  253.  
  254.   return dataPtr;
  255. }
  256.  
  257.  
  258. /*
  259.  *--------------------------------------------------------------
  260.  *
  261.  * next_start_code --
  262.  *
  263.  *    Parses off bitstream until start code reached. When done
  264.  *      next 4 bytes of bitstream will be start code. Bit offset
  265.  *      reset to 0.
  266.  *
  267.  * Results:
  268.  *    Status code.
  269.  *
  270.  * Side effects:
  271.  *    Bit stream irreversibly parsed.
  272.  *
  273.  *--------------------------------------------------------------
  274.  */
  275.  
  276. int next_start_code()
  277. {
  278.   int state;
  279.   int byteoff;
  280.   unsigned int data;
  281.  
  282.   /* If no current stream, return error. */
  283.  
  284.   if (curVidStream == NULL)
  285.     return NO_VID_STREAM;
  286.  
  287.   /* If insufficient buffer length, correct underflow. */
  288.  
  289.   if (bufLength < 2) {
  290.     correct_underflow();
  291.   }
  292.  
  293.   /* If bit offset not zero, reset and advance buffer pointer. */
  294.  
  295.   byteoff = bitOffset % 8;
  296.  
  297.   if (byteoff != 0) {
  298.     flush_bits((8-byteoff));
  299.   }
  300.  
  301.   /* Set state = 0. */
  302.  
  303.   state = 0;
  304.  
  305.   /* While buffer has data ... */
  306.  
  307.   while(bufLength > 0) {
  308.  
  309.     /* If insufficient data exists, correct underflow. */
  310.  
  311.     if (bufLength < 2) {
  312.       correct_underflow();
  313.     }
  314.  
  315.     /* If next byte is zero... */
  316.  
  317.     get_bits8(data);
  318.  
  319.     if (data == 0) {
  320.  
  321.       /* If state < 2, advance state. */
  322.  
  323.       if (state < 2) state++;
  324.     }
  325.  
  326.     /* If next byte is one... */
  327.  
  328.     else if (data == 1) {
  329.  
  330.       /* If state == 2, advance state (i.e. start code found). */
  331.  
  332.       if (state == 2) state++;
  333.  
  334.       /* Otherwise, reset state to zero. */
  335.  
  336.       else state = 0;
  337.     }
  338.  
  339.     /* Otherwise byte is neither 1 or 0, reset state to 0. */
  340.  
  341.     else {
  342.       state = 0;
  343.     }
  344.  
  345.     /* If state == 3 (i.e. start code found)... */
  346.  
  347.     if (state == 3) {
  348.  
  349.       /* Set buffer pointer back and reset length & bit offsets so
  350.      next bytes will be beginning of start code. 
  351.       */
  352.  
  353.       bitOffset = bitOffset - 24;
  354.  
  355.       bitCount -= 24;
  356.  
  357.       if (bitOffset < 0) {
  358.     bitOffset = 32 + bitOffset;
  359.     bufLength++;
  360.     bitBuffer--;
  361. #ifdef UTIL2
  362.     curBits = *bitBuffer << bitOffset;
  363. #else
  364.     curBits = *bitBuffer;
  365. #endif
  366.       }
  367.       else {
  368. #ifdef UTIL2
  369.     curBits = *bitBuffer << bitOffset;
  370. #else
  371.     curBits = *bitBuffer;
  372. #endif
  373.       }
  374.  
  375.       /* Return success. */
  376.  
  377.       return OK;
  378.     }
  379.   }
  380.  
  381.   /* Return underflow error. */
  382.  
  383.   return UNDERFLOW;
  384. }
  385.  
  386.  
  387. /*
  388.  *--------------------------------------------------------------
  389.  *
  390.  * get_extra_bit_info --
  391.  *
  392.  *    Parses off extra bit info stream into dynamically 
  393.  *      allocated memory. Extra bit info is indicated by
  394.  *      a flag bit set to 1, followed by 8 bits of data.
  395.  *      This continues until the flag bit is zero. Assumes
  396.  *      that bit stream set to first flag bit in extra
  397.  *      bit info stream.
  398.  *
  399.  * Results:
  400.  *    Pointer to dynamically allocated memory with extra
  401.  *      bit info in it. Flag bits are NOT included.
  402.  *
  403.  * Side effects:
  404.  *    Bit stream irreversibly parsed.
  405.  *
  406.  *--------------------------------------------------------------
  407.  */
  408.  
  409. char *get_extra_bit_info ()
  410. {
  411.   int size, marker;
  412.   char *dataPtr;
  413.   unsigned int data;
  414.  
  415.   /* Get first flag bit. */
  416.   get_bits1(data);
  417.  
  418.   /* If flag is false, return NULL pointer (i.e. no extra bit info). */
  419.  
  420.   if (!data) return NULL;
  421.  
  422.   /* Initialize size of extra bit info buffer and allocate. */
  423.  
  424.   size = EXT_BUF_SIZE;
  425.   dataPtr = (char *) malloc(size);
  426.  
  427.   /* Reset marker to hold place in buffer. */
  428.  
  429.   marker = 0;
  430.  
  431.   /* While flag bit is true. */
  432.  
  433.   while (data) {
  434.  
  435.     /* Get next 8 bits of data. */
  436.     get_bits8(data);
  437.  
  438.     /* Place in extra bit info buffer. */
  439.  
  440.     dataPtr[marker] = (char) data;
  441.     marker++;
  442.  
  443.     /* If buffer is full, reallocate. */
  444.  
  445.     if (marker == size) {
  446.       size += EXT_BUF_SIZE;
  447.       dataPtr = (char *) realloc(dataPtr, size);
  448.     }
  449.  
  450.     /* Get next flag bit. */
  451.     get_bits1(data);
  452.   }
  453.  
  454.   /* Reallocate buffer to free extra space. */
  455.  
  456.   dataPtr = (char *) realloc(dataPtr, marker);
  457.  
  458.   /* Return pointer to extra bit info buffer. */
  459.  
  460.   return dataPtr;
  461. }
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.