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

  1. /*
  2.  * Copyright (c) 1995 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.  
  22. #include "video.h"
  23. #include "proto.h"
  24. #include <sys/types.h>
  25. #include <signal.h>
  26. #include <string.h>
  27. #include <machine/endian.h>
  28.  
  29. #ifndef MIPS
  30. #include <netinet/in.h>
  31. #else
  32. #include <bsd/netinet/in.h>
  33. #endif
  34.  
  35. #ifdef __STDC__
  36. #include <stdlib.h>
  37. #else
  38. #include <malloc.h>
  39. #endif
  40.  
  41. #include "util.h"
  42. #include "opts.h"
  43.  
  44. #ifdef __SAVE_DECODED_FILE__
  45. static FILE *hackOutput;
  46. #endif
  47.  
  48. /* 
  49.   Are we a system layer parser or pure video?
  50.   (-1 is uninit, 0 is video, 1 is sys_layer)
  51. */
  52. int sys_layer = -1;
  53. /* Keep track of bytes parsed in system layer */
  54. int audBytes,vidBytes,sysBytes;
  55.  
  56. /* End of File flag. */
  57. extern int EOF_flag;
  58.  
  59. /* Global file pointer to incoming data. */
  60. extern FILE *input;
  61.  
  62. /* Options to control logging */
  63. extern FILE *syslogOutput;
  64. extern int opts;
  65.   
  66.   
  67. /*
  68.  *--------------------------------------------------------------
  69.  *
  70.  * get_more_data --
  71.  *
  72.  *    Called by get_more_data to read in more data from
  73.  *      video MPG files (non-system-layer)
  74.  *
  75.  * Results:
  76.  *    Input buffer updated, buffer length updated.
  77.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  78.  *
  79.  * Side effects:
  80.  *      None.
  81.  *
  82.  *--------------------------------------------------------------
  83.  */
  84. int 
  85.   get_more_data(bs_ptr, max_length, length_ptr, buf_ptr)
  86. unsigned int **bs_ptr;
  87. int *max_length, *length_ptr;
  88. unsigned int **buf_ptr;
  89. {
  90.   static BOOLEAN swap;
  91.   int ioBytes, data, result;
  92.   unsigned int *mark;
  93.   
  94.   if (sys_layer == 0) {
  95.     return pure_get_more_data(*bs_ptr, *max_length, length_ptr, buf_ptr, swap);
  96.   }
  97.   if (sys_layer == -1) {
  98.     /* Time to init ourselves */
  99.     swap = (htonl(1)!=1);
  100.     mark = *bs_ptr;
  101.     ioBytes = fread(&data,1,4,input);
  102.     if (ioBytes!=4) return 0;
  103.     data=ntohl(data);
  104.     if ((data==PACK_START_CODE) || (data==SYSTEM_HEADER_START_CODE)) {
  105.       /* Yow, a System Layer Stream.  Much harder to parse.  Call in the
  106.      specialist.... */
  107.       fprintf(stderr,"This is an MPEG System Layer Stream.  ");
  108.       fprintf(stderr,"Audio is not analyzed.\n");
  109.       sys_layer=1;
  110.       init_read_sys();
  111.       result= read_sys(bs_ptr, max_length, length_ptr, buf_ptr, data);
  112. #ifdef __SAVE_DECODED_FILE__
  113.       fwrite((unsigned char *)(*buf_ptr),1,*length_ptr*4,hackOutput);
  114. #endif
  115.       return result;
  116.     } else {
  117.       /* No system Layer junk, just pretent we didn't peek,
  118.      and hereafter just call pure_get_more_data */
  119.       sys_layer=0;
  120.       **bs_ptr=data;
  121.       *length_ptr=1;
  122.       result= pure_get_more_data(*bs_ptr, *max_length, 
  123.                  length_ptr, buf_ptr, swap);
  124.       *buf_ptr= *bs_ptr;
  125.       return result;
  126.     }}
  127.   /* A system layer stream (called after the 1st time), call the specialist */
  128. #ifdef __SAVE_DECODED_FILE__
  129.   data= *length_ptr;
  130. #endif
  131.   result=read_sys(bs_ptr, max_length, length_ptr, buf_ptr, 0);
  132. #ifdef __SAVE_DECODED_FILE__
  133.   fwrite((unsigned char *) ((*buf_ptr)+data),1,4*((*length_ptr)-data),hackOutput);
  134. #endif
  135.   return result;
  136. }
  137. /*
  138.  *--------------------------------------------------------------
  139.  *
  140.  * pure_get_more_data --
  141.  *      (get_more_data from ver 2.0 with swap added)
  142.  *
  143.  *    Called by get_more_data to read in more data from
  144.  *      video MPG files (non-system-layer)
  145.  *
  146.  * Results:
  147.  *    Input buffer updated, buffer length updated.
  148.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  149.  *
  150.  * Side effects:
  151.  *      None.
  152.  *
  153.  *--------------------------------------------------------------
  154.  */
  155.  
  156. int 
  157.   pure_get_more_data(buf_start, max_length, length_ptr, buf_ptr, swap)
  158. unsigned int *buf_start;
  159. int max_length;
  160. int *length_ptr;
  161. unsigned int **buf_ptr;
  162. BOOLEAN swap;
  163. {
  164.   
  165.   int length, num_read, i, request;
  166.   unsigned char *buffer, *mark;
  167.   unsigned int *lmark;
  168.   
  169.   if (EOF_flag) return 0;
  170.   
  171.   length = *length_ptr;
  172.   buffer = (unsigned char *) *buf_ptr;
  173.   
  174.   if (length > 0) {
  175.     memcpy((void *) buf_start, (void *) buffer, (size_t) (length*4));
  176.     mark = ((unsigned char *) (buf_start + length));
  177.   }
  178.   else {
  179.     mark = (unsigned char *) buf_start;
  180.     length = 0;
  181.   }
  182.   
  183.   request = (max_length-length)*4;
  184.   
  185.   
  186.   num_read = fread( mark, 1, request, input);
  187.   
  188.   /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
  189.   {
  190.     int num_read_rounded;
  191.     unsigned char *index;
  192.     
  193.     num_read_rounded = 4*(num_read/4);
  194.     
  195.     /* this can happen only if num_read<request; i.e. end of file reached */
  196.     if( num_read_rounded < num_read )
  197.       { 
  198.      num_read_rounded = 4*( num_read/4+1 );
  199.      /* fill in with zeros */
  200.      for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
  201.      /* advance to the next 4-byte boundary */
  202.      num_read = num_read_rounded;
  203.       }
  204.   }
  205.   
  206.   if   (num_read < 0) {
  207.     return -1;
  208.   }
  209.   else if (num_read == 0) {
  210.     *buf_ptr = buf_start;
  211.     
  212.     /* Make 32 bits after end equal to 0 and 32
  213.        bits after that equal to seq end code
  214.        in order to prevent messy data from infinite
  215.        recursion.
  216.        */
  217.     
  218.     *(buf_start + length) = 0x0;
  219.     *(buf_start + length+1) = SEQ_END_CODE;
  220.     
  221.     EOF_flag = 1;
  222.     return 0;
  223.   }
  224.   
  225.   lmark = (unsigned int *) mark;
  226.   
  227.   num_read = num_read/4;
  228.   
  229.   if (swap) {
  230.     for (i=0; i<num_read; i++) {
  231.       *lmark = htonl(*lmark);
  232.       lmark++;
  233.     }
  234.   }
  235.   
  236.   *buf_ptr = buf_start;
  237.   *length_ptr = length + num_read;
  238.   
  239.   return 1;
  240. }
  241.  
  242.  
  243.  
  244.  
  245. /* 
  246.   Here is the specialist.... 
  247.   Code is adapted from our program demux....
  248.   A bunch of this needs to be #ifdef ANALYSIS'ed
  249.   define __SYSREAD_LOGGING_ON__ to get  an output file for debugging
  250.   */
  251.  
  252.  
  253. /* Stream IDs */
  254. static int gAudioStreamID;
  255. static int gVideoStreamID;
  256. static int gReservedStreamID;
  257.  
  258. #ifdef ANALYSIS
  259. /* Statistics */
  260. static int gNumAudioPackets;
  261. static int gNumVideoPackets;
  262. static int gNumPaddingPackets;
  263. static int gNumReservedPackets;
  264. static int gNumPrivate_1_Packets;
  265. static int gNumPrivate_2_Packets;
  266. #endif
  267.  
  268. /*
  269.  *----------------------------------------------------------
  270.  *
  271.  *  init_read_sys
  272.  *
  273.  *      Called before read_sys is used to parse the file.
  274.  *      Currently only sets up the logging file (when defined)
  275.  *
  276.  *  Results:  None
  277.  *
  278.  *  Side Effects: Zeros Byte counts, opens Hack Output if needed
  279.  *
  280.  *----------------------------------------------------------
  281.  */
  282. void init_read_sys() {
  283. #ifdef __SAVE_DECODED_FILE__
  284.   hackOutput = fopen("hack.vid", "w");
  285.   if (hackOutput == NULL) {
  286.     fprintf(stderr, "Can't open output file \"hack.vid\"\n");
  287.     exit(1);
  288.   }
  289. #endif
  290.   audBytes=0; vidBytes=0; sysBytes=0;
  291. }
  292.  
  293.  
  294. /*
  295.  *----------------------------------------------------------
  296.  *
  297.  *  read_sys
  298.  *
  299.  *      Parse out a packet of the system layer MPEG file.
  300.  *
  301.  *  Results:  Returns 0 if error or EOF
  302.  *            Returns 1 if more data read (could be just one int)
  303.  *
  304.  *  Side Effects:  ReadPacket can change *bs_ptr to be a new buffer
  305.  *                 buf_ptr will remain pointing at *length_ptr (at input)
  306.  *                         into the buffer
  307.  *                 *length_ptr will be changed to the new size
  308.  *                 *max_length can be changed if a new buffer is alloc'd
  309.  *
  310.  *----------------------------------------------------------
  311.  */
  312. int read_sys(bs_ptr, max_length, length_ptr, buf_ptr, start)
  313.      unsigned int **bs_ptr;
  314.      int *max_length, *length_ptr;
  315.      unsigned int **buf_ptr, start;  
  316.      /* start is either a start code or 0 to indicate continued parsing */
  317. {
  318.   unsigned int startCode;
  319.   int errorCode, PacketReply;
  320.   unsigned char packetID;
  321.   double systemClockTime;
  322.   unsigned long muxRate;
  323.   /* Statistics */
  324.   static int numPacks = 0;
  325.   static int numPackets = 0;
  326.   static int numSystemHeaders = 0;
  327.   static BOOLEAN Parse_done=FALSE;
  328.   BOOLEAN match;
  329.   
  330.   if (!start) {
  331.     errorCode = ReadStartCode(&startCode);
  332.     if (EOF_flag) return 0;
  333.     if (errorCode != 0) {
  334.       fprintf(stderr, "Unable to read initial pack start code\n");
  335.       return 0;
  336.     }}
  337.   else {
  338.     errorCode = 0;
  339.     startCode = start;
  340.   }
  341.   
  342.   while (1) {
  343.     match=FALSE;
  344.     if (startCode == PACK_START_CODE) {
  345.       ++numPacks; match=TRUE;
  346.       if (opts&SYSLAYER_LOG) {
  347.     fprintf(syslogOutput, "PACK #%d:\n", numPacks);
  348.       }
  349.       errorCode = ReadPackHeader( &systemClockTime, &muxRate);
  350.       if (errorCode != 0) {
  351.     fprintf(stderr, "Error in reading pack header\n");
  352.     return 0;
  353.       }
  354.       errorCode = ReadStartCode( &startCode);
  355.       if (errorCode != 0) {
  356.     fprintf(stderr, "Error in reading start code\n");
  357.     return 0;
  358.       }
  359.     }
  360.     if (startCode == SYSTEM_HEADER_START_CODE) {
  361.       if (opts&SYSLAYER_LOG) {
  362.     fprintf(syslogOutput, "SYSTEM HEADER:\n");
  363.       }
  364.       ++numSystemHeaders; match=TRUE;
  365.       errorCode = ReadSystemHeader();
  366.       if (errorCode != 0) {
  367.     fprintf(stderr, "Error in reading system header\n");
  368.     return 0;
  369.       }
  370.       errorCode = ReadStartCode( &startCode);
  371.       if (errorCode != 0) {
  372.     fprintf(stderr,"Error in reading start code after system header\n");
  373.     return 0;
  374.       }
  375.     }
  376.     packetID = startCode & 0xff;
  377.     while (((startCode & PACKET_START_CODE_MASK) == PACKET_START_CODE_PREFIX) &&
  378.        (packetID>=0xbc)) {
  379.       ++numPackets; match=TRUE;
  380.       packetID = startCode & 0xff;
  381.       if (opts&SYSLAYER_LOG) {
  382.     fprintf(syslogOutput, "PACKET ID %02x:\n", packetID);
  383.       }
  384.       PacketReply = ReadPacket(packetID, bs_ptr, max_length, length_ptr, buf_ptr);
  385.       switch (PacketReply) {
  386.       case 2: 
  387.     return 1;
  388.       case 1: 
  389.     if (opts&SYSLAYER_LOG) {
  390.       fprintf(syslogOutput, "Problems in ReadPacket, returning partial.\n");
  391.     }
  392.     return 0;
  393.       default: /* do nothing */
  394.     break;
  395.       }
  396.       errorCode = ReadStartCode( &startCode);
  397.       if (errorCode != 0) {
  398.     fprintf(stderr,"Error in start code after packet\n");
  399.     return 0;
  400.       }
  401.       if (startCode == PACK_START_CODE || startCode == ISO_11172_END_CODE)
  402.     break;
  403.     }
  404.     if (startCode == ISO_11172_END_CODE) {
  405.       match=TRUE;
  406.       if (Parse_done) return 1;
  407. #ifdef ANALYSIS
  408.       fprintf(stderr, "Successful parse of MPEG system level\n");
  409.       fprintf(stderr, "%d system headers, %d packs, %d packets\n",
  410.           numSystemHeaders, numPacks, numPackets);
  411.       fprintf(stderr, "%d audio packets, %d video packets, %d padding packets\n",
  412.           gNumAudioPackets, gNumVideoPackets, gNumPaddingPackets);
  413.       fprintf(stderr, "%d reserved packets, %d/%d private type 1/2 packets\n",
  414.           gNumReservedPackets, gNumPrivate_1_Packets, gNumPrivate_2_Packets);
  415. #endif
  416.       ReadPacket(NOT_PACKET_ID, bs_ptr, max_length, length_ptr, buf_ptr);
  417.       Parse_done=TRUE;
  418.       return 1;
  419.     }
  420.     if (errorCode != 0)
  421.       return 1;
  422.     if (!match) {
  423.       fprintf(stderr,"\nNo match found for start code %08x in system layer, skipping\n",startCode);
  424.       if (opts&SYSLAYER_LOG)
  425.     fprintf(syslogOutput, "Error with start code %08x, did not match at %d\n",
  426.         startCode, (int) ftell(input));  
  427.       startCode=(int) find_start_code();
  428.       if (opts&SYSLAYER_LOG) {
  429.     if (startCode==EOF) 
  430.       fprintf(syslogOutput, "Found EOF in find_start_code\n");
  431.     else fprintf(syslogOutput, "Found %08x at %d\n",
  432.              startCode, (int) ftell(input));  
  433.       }
  434.       if (startCode==EOF) {
  435.     EOF_flag=1;
  436.     return 0;
  437.       }
  438.     }
  439.   }
  440.   return 0; /* shouldnt get here */
  441. }
  442.  
  443. /*
  444.  *-----------------------------------------------------------
  445.  *
  446.  *  ReadStartCode
  447.  *
  448.  *      Parses a start code out of the stream
  449.  *
  450.  *  Results/Side Effects:  Sets *startCode to the code, returns
  451.  *     1 on error, 0 on success
  452.  *
  453.  *-----------------------------------------------------------
  454.  */
  455. int ReadStartCode(startCode)
  456.      unsigned int *startCode;
  457. {
  458.   int numRead;
  459.   
  460.   numRead = fread((unsigned char *)startCode, 1, 4, input);
  461.   *startCode=htonl(*startCode);
  462.   
  463.   if (numRead < 4) {
  464.     if ((opts&SYSLAYER_LOG)&&(EOF_flag==0)) {
  465.       fprintf(syslogOutput, "Error in reading start code, only got %d bytes\n", 
  466.               numRead);
  467.     }
  468.     EOF_flag=1;
  469.     return 1;
  470.   }
  471.   if (opts&SYSLAYER_LOG) {
  472.     fprintf(syslogOutput, "Read as start code: %08x\n", *startCode);
  473.   }
  474.   if ((*startCode&0xfffffe00) != 0) {
  475.     int start_pos;
  476.     fprintf(stderr,"Problem with system layer parse, skipping to start code\n");
  477.     if (opts&SYSLAYER_LOG) {
  478.       start_pos = (int) ftell(input);
  479.       fprintf(syslogOutput, "Error with start code, not a start code! at %d\n",
  480.           start_pos);  
  481.     }
  482.     *startCode=(int) find_start_code();
  483.     if (*startCode==EOF) {
  484.       if (opts&SYSLAYER_LOG) {
  485.     fprintf(syslogOutput, "Skipped all the way to EOF!\n");
  486.     }
  487.       EOF_flag=TRUE;
  488.       return 0;
  489.     }
  490.     if (opts&SYSLAYER_LOG) {
  491.       int end_pos=(int) ftell(input);
  492.       fprintf(syslogOutput, "Found %08x at %d, skipped over %d bytes.\n",
  493.           *startCode, end_pos, end_pos-start_pos);
  494.     }
  495.   }
  496.   sysBytes+=4;
  497.   return 0;
  498. }
  499.  
  500. /*
  501.  *-----------------------------------------------------------
  502.  *
  503.  *  find_start_code
  504.  *
  505.  *      Parses a start code out of the stream by tossing bytes until it gets one
  506.  *
  507.  *  Results/Side Effects:  Parses bytes of the stream, returns code
  508.  *                         Returns EOF in case of end of file
  509.  *
  510.  *-----------------------------------------------------------
  511.  */
  512. int find_start_code()
  513. {
  514.  NO_ZEROS:
  515.   switch(fgetc(input)) {
  516.   case 0:    goto ONE_ZERO;
  517.   case EOF:  goto EOF_FOUND;
  518.   default:   goto NO_ZEROS;
  519.   }
  520.  
  521.  ONE_ZERO:
  522.   switch(fgetc(input)) {
  523.   case 0:    goto TWO_ZEROS;
  524.   case EOF:  goto EOF_FOUND;
  525.   default:   goto NO_ZEROS;
  526.   }
  527.  
  528.  TWO_ZEROS:
  529.   switch(fgetc(input)) {
  530.   case 0x01:  goto CODE_FOUND;
  531.   case 0x00:  goto TWO_ZEROS;
  532.   case EOF:  goto EOF_FOUND;
  533.   default:    goto NO_ZEROS;
  534.   }
  535.  
  536.  CODE_FOUND:
  537.   return 0x00000100+fgetc(input);
  538.  
  539.  EOF_FOUND:   /* received EOF */
  540.   return EOF;
  541. }
  542.  
  543.  
  544.  
  545. /*
  546.  *-----------------------------------------------------------------
  547.  *
  548.  *  ReadPackHeader
  549.  *
  550.  *      Parses out the PACK header
  551.  *
  552.  *  Returns: 1 on error, 0 on success
  553.  *
  554.  *-------------------------------------------------------------------
  555.  */
  556. int ReadPackHeader(systemClockTime,muxRate)
  557.      double *systemClockTime;
  558.      unsigned long *muxRate;
  559. {
  560.   int numRead;
  561.   unsigned char inputBuffer[PACK_HEADER_SIZE];
  562.   unsigned long systemClockRef;
  563.   unsigned char systemClockRefHiBit;
  564.   int errorCode;
  565.   
  566.   numRead = fread(inputBuffer, 1, PACK_HEADER_SIZE, input);
  567.   if (numRead < PACK_HEADER_SIZE) {
  568.     EOF_flag=1;
  569.     if (opts&SYSLAYER_LOG) {
  570.       fprintf(syslogOutput, 
  571.               "Error in reading Pack header, only got %d bytes\n", numRead);
  572.     }
  573.     return 1;
  574.   }
  575.   sysBytes+=numRead;
  576.   ReadTimeStamp(inputBuffer, &systemClockRefHiBit, &systemClockRef);
  577.   errorCode = MakeFloatClockTime(systemClockRefHiBit, systemClockRef, 
  578.                  systemClockTime);
  579.   ReadRate(&inputBuffer[5], muxRate);
  580.   *muxRate *= MUX_RATE_SCALE_FACTOR;
  581.   if (opts&SYSLAYER_LOG) {
  582.     fprintf(syslogOutput, "\tSystem clock reference: %d, %lu (0x%x%08x)\n",
  583.         (int)systemClockRefHiBit, systemClockRef,
  584.         (int)systemClockRefHiBit, systemClockRef);
  585.     if (errorCode == 0) {
  586.       fprintf(syslogOutput, "\tSystem clock time: %1.4lf\n", *systemClockTime);
  587.     } else {
  588.       fprintf(syslogOutput, "Error reading system clock time\n");
  589.     }
  590.     fprintf(syslogOutput, "\tmuxRate: %lu (0x%08x)\n", *muxRate, *muxRate);
  591.   }
  592.   return 0;
  593. }
  594.  
  595. /*
  596.  *------------------------------------------------------------------
  597.  *
  598.  *   ReadSystemHeader
  599.  *
  600.  *      Parse out the system header, setup out dtream IDs for parsing packets
  601.  *
  602.  *   Results:  Returns 1 on error, 0 on success.
  603.  *             Sets gAudioStreamID and gVideoStreamID
  604.  *
  605.  *------------------------------------------------------------------
  606.  */
  607. int ReadSystemHeader()
  608.   unsigned char *inputBuffer = NULL;
  609.   int numRead;
  610.   int pos,i;
  611.   unsigned short headerSize;
  612.   unsigned char streamID;
  613.   /* Only needed for system log file */
  614.   unsigned long rateBound;
  615.   unsigned long audioBound;
  616.   unsigned char fixedFlag;
  617.   unsigned char cspsFlag;
  618.   unsigned long videoBound;
  619.   unsigned char sysAudioLockFlag;
  620.   unsigned char sysVideoLockFlag;
  621.   unsigned char stdBufferScale;
  622.   unsigned long stdBufferSize;
  623.   
  624.   numRead = fread((char *)&headerSize, 1, 2, input); 
  625.   headerSize=ntohs(headerSize);
  626.   if (numRead != 2) {
  627.     EOF_flag=1;
  628.     if (opts&SYSLAYER_LOG) {
  629.       fprintf(syslogOutput, 
  630.               "error in reading System header size, only got %d bytes\n", 
  631.               numRead);
  632.     }
  633.     return 1;
  634.   }
  635.   inputBuffer = (unsigned char *) malloc(headerSize+1);
  636.   sysBytes+=headerSize;
  637.   if (inputBuffer == NULL) {
  638.     if (opts&SYSLAYER_LOG) {
  639.       fprintf(syslogOutput, 
  640.               "error in allocating %d bytes\n", headerSize);
  641.     }
  642.     return 1;
  643.   }
  644.   inputBuffer[headerSize]=0;
  645.   numRead = fread(inputBuffer, 1, headerSize, input); 
  646.   if (opts&SYSLAYER_LOG) {
  647.     for(i=0;i<headerSize;i++) 
  648.       fprintf(syslogOutput, 
  649.               "%x ",*(inputBuffer+i));
  650.     fprintf(syslogOutput,"\n");
  651.   }
  652.   if (numRead < headerSize) {
  653.     EOF_flag=1;
  654.     if (opts&SYSLAYER_LOG) {
  655.       fprintf(syslogOutput, 
  656.               "error in reading System Header, only got %d bytes\n", 
  657.               numRead);
  658.     }
  659.     return 1;
  660.   }
  661.   if (opts&SYSLAYER_LOG) {
  662.     ReadRate(&inputBuffer[0], &rateBound);
  663.     rateBound *= MUX_RATE_SCALE_FACTOR;
  664.     fprintf(syslogOutput, "\trate_bound: %lu (0x%08x)\n", rateBound, rateBound);
  665.     audioBound = (unsigned long)inputBuffer[3] >> 2;
  666.     fprintf(syslogOutput, "\taudio_bound: %lu (0x%08x)\n", audioBound, audioBound);
  667.     fixedFlag = (inputBuffer[3] >> 1) & 0x01;
  668.     fprintf(syslogOutput, "\tfixed_flag: %d\n", fixedFlag);
  669.     cspsFlag = inputBuffer[3] & 0x01;
  670.     fprintf(syslogOutput, "\tCSPS_flag: %d\n", cspsFlag);
  671.     videoBound = (unsigned long)inputBuffer[4] & 0x1f;
  672.     fprintf(syslogOutput, "\tvideo_bound: %lu (0x%08x)\n", videoBound, videoBound);
  673.     sysAudioLockFlag = (inputBuffer[4] & 0x80) >> 7;
  674.     fprintf(syslogOutput, "\tsystem_audio_lock_flag: %d\n", sysAudioLockFlag);
  675.     sysVideoLockFlag = (inputBuffer[4] & 0x40) >> 6;
  676.     fprintf(syslogOutput, "\tsystem_video_lock_flag: %d\n", sysVideoLockFlag);
  677.   }
  678.   
  679.   pos = 6;
  680.   while ((inputBuffer[pos] & 0x80) == 0x80) {
  681.     streamID = inputBuffer[pos];
  682.     if (opts&SYSLAYER_LOG) {
  683.       ReadSTD(&inputBuffer[pos + 1], &stdBufferScale, &stdBufferSize);
  684.       fprintf(syslogOutput, 
  685.               "\tRead STD_buffer_scale = %d, STD_buffer_size = %lu (0x%0x)\n",
  686.               (int)stdBufferScale, stdBufferSize, stdBufferSize);
  687.       fprintf(syslogOutput, "\tSystem Header: stream with ID 0x%x\n", streamID); 
  688.     }
  689.     switch (streamID) {
  690.     case STD_VIDEO_STREAM_ID: 
  691.       if (opts&SYSLAYER_LOG) {
  692.     fprintf(syslogOutput, "\tSystem Header: Std video stream\n");
  693.       }
  694.       break;
  695.     case STD_AUDIO_STREAM_ID: 
  696.       if (opts&SYSLAYER_LOG) {
  697.     fprintf(syslogOutput, "\tSystem Header: Std audio stream\n");
  698.       }
  699.       break;
  700.     case RESERVED_STREAM_ID: 
  701.       if (opts&SYSLAYER_LOG) {
  702.     fprintf(syslogOutput, "\tSystem Header: Reserved stream\n");
  703.       }
  704.       break;
  705.     case PADDING_STREAM_ID: 
  706.       if (opts&SYSLAYER_LOG) {
  707.     fprintf(syslogOutput, "\tSystem Header: Padding stream\n");
  708.       }
  709.       break;
  710.     case PRIVATE_STREAM_1_ID: 
  711.       if (opts&SYSLAYER_LOG) {
  712.     fprintf(syslogOutput, "\tSystem Header: Private (1) stream\n");
  713.       }
  714.       break;
  715.     case PRIVATE_STREAM_2_ID: 
  716.       if (opts&SYSLAYER_LOG) {
  717.     fprintf(syslogOutput, "\tSystem Header: Private (2) stream\n");
  718.       }
  719.       break;
  720.     case 0xb1:
  721.       if (streamID < MIN_STREAM_ID_ID) {
  722.     if (opts&SYSLAYER_LOG) {
  723.       fprintf(syslogOutput, "\tSystem Header: Illegal stream ID\n");
  724.       fprintf(syslogOutput, "\tWe believe MPOWER is creating invalid codes here.\n");
  725.     }
  726.     return 1;
  727.       }
  728.       
  729.     default:
  730.       if (streamID < MIN_STREAM_ID_ID) {
  731.     if (opts&SYSLAYER_LOG) {
  732.       fprintf(syslogOutput, "\tSystem Header: Illegal stream ID\n");
  733.     }
  734.     return 1;
  735.       }
  736.       switch (streamID >> 4) {
  737.       case 0xc:
  738.       case 0xd:
  739.     if (opts&SYSLAYER_LOG) {
  740.       fprintf(syslogOutput, "\tSystem Header: audio stream #%d\n",
  741.           (streamID & 0x1f));
  742.     }
  743.     gAudioStreamID = streamID;
  744.     break;
  745.       case 0xe:
  746.     if (opts&SYSLAYER_LOG) {
  747.       fprintf(syslogOutput, "\tSystem Header: video stream #%d\n",
  748.           (streamID & 0xf));
  749.     }
  750.     if ((gVideoStreamID != 0) && (gVideoStreamID!=streamID)) {
  751.       if (opts&SYSLAYER_LOG) {
  752.         fprintf(syslogOutput, 
  753.             "\tThis program can only handle a single video stream\n");
  754.       }
  755.       break;
  756.     }
  757.     gVideoStreamID = streamID;
  758.     break;
  759.       case 0xf:
  760.     gReservedStreamID = streamID;
  761.     if (opts&SYSLAYER_LOG) {
  762.       fprintf(syslogOutput, "S\tystem Header: reserved stream #%d\n",
  763.           (streamID & 0xf));
  764.     }
  765.     break;
  766.       }
  767.       break;
  768.     }
  769.     pos += 3;
  770.   }
  771.   if (inputBuffer != NULL)
  772.     free(inputBuffer);
  773.   return 0;
  774. }
  775.  
  776. /*
  777.  *-----------------------------------------------------------------
  778.  *
  779.  *  ReadPacket
  780.  *
  781.  *      Reads a single packet out of the stream, and puts it in the
  782.  *      buffer if it is video.
  783.  *
  784.  *  Results:
  785.  *      Changes the value of *length_ptr to be the new length (plus old)
  786.  *      If the buffer is too small, can change *bs_ptr, *max_length, and *buf_ptr
  787.  *      to be correct for a newly allocated buffer.
  788.  *
  789.  *  State:  The buffer is in ints, but the packets can be an arbitrary number
  790.  *      of bytes, so leftover bytes are kept in static vars and added in on the
  791.  *      next call.
  792.  *
  793.  *-----------------------------------------------------------------
  794.  */   
  795. int ReadPacket(packetID, bs_ptr, max_length, length_ptr, buf_ptr) 
  796. unsigned char packetID;
  797. unsigned int **bs_ptr;
  798. int *max_length;
  799. int *length_ptr;
  800. unsigned int **buf_ptr;
  801. /* Returns:
  802.    0 - no error, but not video packet we want
  803.    1 - error
  804.    2 - got video packet into buffer
  805.    */
  806. {   
  807.   int ioBytes;
  808.   unsigned char nextByte;
  809.   unsigned short packetLength;
  810.   unsigned char *packetBuffer = NULL;
  811.   int pos;
  812.   int numStuffBytes = 0;
  813.   int packetDataLength;
  814.   int byte_length;
  815.   unsigned char scratch[10];
  816.   int errorCode; /* For syslog */
  817.   /* Leftovers from previous video packets */
  818.   static unsigned int num_left=0, leftover_bytes=0;
  819.   
  820.   if (packetID==NOT_PACKET_ID) {
  821.     /* Gross hack to handle unread bytes before end of stream */
  822.     if (num_left!=0) {
  823.       /* Sigh, deal with previous leftovers */
  824.       *(*buf_ptr+*length_ptr)=leftover_bytes;
  825.       *(*buf_ptr+*length_ptr+1)=ISO_11172_END_CODE;
  826.       *length_ptr+=2;
  827.     } else {
  828.       *(*buf_ptr+*length_ptr)=ISO_11172_END_CODE;
  829.       *length_ptr+=1;
  830.     }
  831.     return 1;
  832.   }
  833.   
  834.   ioBytes = fread(&packetLength, 1, 2, input);
  835.   packetLength=htons(packetLength);
  836.   if (ioBytes < 2) {
  837.     if (opts&SYSLAYER_LOG) {
  838.       fprintf(syslogOutput, "ReadPacket: Error in reading packet length\n");
  839.     }
  840.     return 1;
  841.   }
  842.   if (opts&SYSLAYER_LOG) {
  843.     fprintf(syslogOutput, 
  844.         "\tinput packet with ID %02x has length = %d at file offset %d\n", 
  845.         packetID, packetLength, (int) ftell(input));
  846.   }
  847.   if (packetID == gAudioStreamID) {
  848. #ifdef ANALYSIS
  849.     ++gNumAudioPackets;
  850. #endif
  851.   }
  852.   else if (packetID == gVideoStreamID) {
  853. #ifdef ANALYSIS     
  854.     ++gNumVideoPackets;
  855. #endif
  856.   }
  857.   else {
  858.     switch (packetID) {
  859.     case PADDING_STREAM_ID:
  860.       if (opts&SYSLAYER_LOG) {
  861.     fprintf(syslogOutput, "\tPadding packet.\n");
  862.       }
  863. #ifdef ANALYSIS
  864.       ++gNumPaddingPackets;
  865. #endif
  866.       break;
  867.     case RESERVED_STREAM_ID:
  868.       if (opts&SYSLAYER_LOG) {
  869.     fprintf(syslogOutput, "\tReserved packet.\n");
  870.       }
  871. #ifdef ANALYSIS
  872.       ++gNumReservedPackets;
  873. #endif
  874.       break;
  875.     case PRIVATE_STREAM_1_ID:
  876.       if (opts&SYSLAYER_LOG) {
  877.     fprintf(syslogOutput, "\tPrivate packet type 1.\n");
  878.       }
  879. #ifdef ANALYSIS
  880.       ++gNumPrivate_1_Packets;
  881. #endif
  882.       break;
  883.     case PRIVATE_STREAM_2_ID:
  884.       if (opts&SYSLAYER_LOG) {
  885.     fprintf(syslogOutput, "\tPrivate packet type 2.\n");
  886.       }
  887. #ifdef ANALYSIS
  888.       ++gNumPrivate_2_Packets;
  889. #endif
  890.       break;
  891.     default:
  892.       fprintf(stderr, "\nUnknown packet type encountered. P'bly audio? (%x) at %d\n",
  893.           packetID,(int) ftell(input));
  894.       if (opts&SYSLAYER_LOG) {
  895.     fprintf(syslogOutput,"\tUnknown packet type encountered. P'bly audio. (%x), length %d at offset %d.\n",
  896.         packetID,packetLength,(int) ftell(input));
  897.     fflush(syslogOutput);
  898.       }
  899.     } /* switch */
  900.   } /* else */
  901.  
  902.   if (packetID != gVideoStreamID) {        /* changed by jim */
  903.     if (opts&SYSLAYER_LOG) {
  904.       fprintf(syslogOutput, "\tSkipping over this packet.\n");
  905.     }
  906.     fseek(input, packetLength, 1);
  907.     sysBytes+=packetLength;
  908.     return 0;
  909.   }
  910.  
  911.   fread(&nextByte,1,1,input);
  912.   pos = 0;
  913.   while (nextByte & 0x80) {
  914.     ++numStuffBytes;
  915.     if (opts&SYSLAYER_LOG) {
  916.       if (nextByte != 0xff)
  917.     fprintf(syslogOutput, "\tWarning: stuffing byte = 0x%x not 0xff\n", 
  918.         (int)nextByte);
  919.     }
  920.     ++pos;
  921.     fread(&nextByte,1,1,input);
  922.   }
  923.   if (numStuffBytes > 0)
  924.     if (opts&SYSLAYER_LOG) {
  925.       fprintf(syslogOutput, "\tSkipped %d stuffing bytes\n", numStuffBytes);
  926.     }
  927.   if ((nextByte >> 6) == 0x01) {
  928.     pos += 2;
  929.     fread(&nextByte,1,1,input);
  930.     fread(&nextByte,1,1,input);
  931.   } 
  932.   if ((nextByte >> 4) == 0x02) {
  933.     scratch[0] = nextByte;            /* jim */
  934.     fread(&scratch[1],1,4,input);        /* jim */
  935.     fread(&nextByte,1,1,input);
  936.     pos+=5;
  937.   }
  938.   else if ((nextByte >> 4) == 0x03) {
  939.     scratch[0] = nextByte;            /* jim */
  940.     fread(&scratch[1],1,9,input);        /* jim */
  941.     fread(&nextByte,1,1,input);
  942.     pos += 10;
  943.   } 
  944.   else {
  945.     if (opts&SYSLAYER_LOG) {
  946.       fprintf(syslogOutput, "\tRead 0x%02x (s.b. 0x0f)\n", nextByte);
  947.     }
  948.     fread(&nextByte,1,1,input);
  949.     pos += 1;
  950.   }
  951. #define TC_STUFF
  952. #define xTC_DEBUG
  953. #ifdef TC_STUFF
  954.   if (((scratch[0] >> 4) == 0x02) || ((scratch[0] >> 4) == 0x03)) {
  955.     unsigned long pts, dts;
  956.     unsigned char pts_high, dts_high;
  957.     
  958.     if (opts&SYSLAYER_LOG) {
  959.       fprintf(syslogOutput, "\ttimestamp at offset %ld\n", ftell(input));
  960. #ifdef TC_DEBUG
  961.       fprintf(syslogOutput, "\tdata: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
  962.           savebyte, scratch[0], scratch[1], scratch[2], scratch[3], scratch[4],
  963.           scratch[5], scratch[6], scratch[7], scratch[8]);
  964. #endif
  965.     }
  966.  
  967.     if (opts&SYSLAYER_LOG) {
  968.       if((scratch[0] >> 4) == 0x3) {
  969.         ReadTimeStamp(&scratch[5], &dts_high, &dts);
  970.         fprintf(syslogOutput, "\tdts: %01x, %u (0x%08x)\n", dts_high, dts, dts);
  971.       }
  972.       ReadTimeStamp(scratch, &pts_high, &pts);
  973.       fprintf(syslogOutput, "\tpts: %01x, %u (0x%08x)\n", pts_high, pts, pts);
  974.     }
  975.   }
  976. #endif
  977.   /* Read all the headers, now make room for packet */
  978.   if (*bs_ptr+*max_length<*buf_ptr+packetLength/4+*length_ptr) {
  979.     if (opts&SYSLAYER_LOG) {
  980.       fprintf(syslogOutput, "\tProblems with buffer length! %d %d\n",
  981.           *max_length-*length_ptr,packetLength/4);
  982.     }
  983.     if (*max_length-*length_ptr<packetLength/4) {
  984.       /* Buffer too small for a packet (plus whats there),
  985.      time to enlarge it! */
  986.       unsigned int *old= *bs_ptr;
  987.       if (opts&SYSLAYER_LOG) {
  988.     fprintf(syslogOutput,"\tMega Resize! old=%d, new=%d\n",
  989.         *max_length,*length_ptr + packetLength/2);
  990.       }
  991.       *max_length = *length_ptr + packetLength/2;
  992.       *bs_ptr=(unsigned int *)malloc(*max_length*4);
  993.       if (*bs_ptr == NULL) {
  994.     if (opts&SYSLAYER_LOG) {
  995.       fprintf(syslogOutput, "\tReadPacket: Error in allocating %d bytes\n",
  996.           *max_length);
  997.     }
  998.     return 1;
  999.       }
  1000.       memcpy((unsigned char *)*bs_ptr,*buf_ptr,*length_ptr*4);
  1001.       free(old);
  1002.       *buf_ptr= *bs_ptr;
  1003.     } else {
  1004.       memcpy((unsigned char *)*bs_ptr,*buf_ptr,*length_ptr*4);
  1005.       *buf_ptr = *bs_ptr;
  1006.     }}
  1007.   byte_length= *length_ptr*4;
  1008.   if (num_left!=0) {
  1009.     /* Sigh, deal with previous leftovers */
  1010.     byte_length += num_left;
  1011.     *(*buf_ptr+*length_ptr)=leftover_bytes;
  1012.   }
  1013.   packetBuffer=((unsigned char *)*buf_ptr)+byte_length;
  1014.   packetDataLength = packetLength - pos;
  1015.   *packetBuffer++=nextByte;
  1016.   if (packetID == gVideoStreamID) {
  1017.     ioBytes=fread(packetBuffer, 1, packetDataLength-1, input);
  1018.     if (ioBytes!=packetDataLength-1) {
  1019.       EOF_flag=1;
  1020.       if (opts&SYSLAYER_LOG) {
  1021.     fprintf(syslogOutput,"\tEOF in middle of packet!\n");
  1022.       }
  1023.       return 1;
  1024.     }
  1025.     if (opts&SYSLAYER_LOG) {
  1026.       fprintf(syslogOutput, "\tKeeping Video packet of length %d (%%=%d)\n",
  1027.               packetDataLength,packetDataLength%4);
  1028.     }
  1029.     if (1!=ntohl(1)) {
  1030.       unsigned int *mark= *buf_ptr+*length_ptr;
  1031.       int i;
  1032.       
  1033.       for (i=0; i < ((packetDataLength+num_left)&0xfffffffc); i+=4) {
  1034.     *mark = ntohl(*mark);
  1035.     mark++;
  1036.       }}
  1037.     byte_length = byte_length+packetDataLength;
  1038.     num_left = byte_length%4;
  1039.     *length_ptr = byte_length/4;
  1040.     leftover_bytes = *(*buf_ptr+*length_ptr);
  1041.     sysBytes += packetLength-packetDataLength;
  1042.     vidBytes += packetDataLength;
  1043.     return 2;
  1044.   }
  1045.   else if (packetID == gAudioStreamID) { 
  1046.     sysBytes += packetLength-packetDataLength;
  1047.     audBytes += packetDataLength;
  1048.     packetBuffer = (unsigned char *)(*buf_ptr+*length_ptr+1);
  1049.     fread(packetBuffer, 1, packetDataLength-1, input);
  1050.     if (opts&SYSLAYER_LOG) {
  1051.       fprintf(syslogOutput, "\tReceived Audio packet of length %d\n",
  1052.           packetDataLength);
  1053.     }
  1054.   }
  1055.   else /* Donno what it is, just nuke it */ {
  1056.     /* This code should be unreachable */
  1057.     sysBytes+=packetLength;
  1058.     packetBuffer=(unsigned char *)(*buf_ptr+*length_ptr+1);
  1059.     fread(packetBuffer, 1, packetDataLength-1, input);
  1060.     if (opts&SYSLAYER_LOG) {
  1061.       fprintf(syslogOutput, "\tReceived Unknown packet of length %d\n",
  1062.           packetDataLength);
  1063.     }
  1064.   }
  1065.   return 0; 
  1066. }
  1067.  
  1068.  
  1069. /*
  1070.  * The remaining procedures are formatting utility procedures.
  1071.  */
  1072. void ReadTimeStamp(inputBuffer,hiBit,low4Bytes)
  1073.      unsigned char *inputBuffer, *hiBit;
  1074.      unsigned long *low4Bytes;
  1075. {
  1076.   *hiBit = ((unsigned long)inputBuffer[0] >> 3) & 0x01;
  1077.   *low4Bytes = (((unsigned long)inputBuffer[0] >> 1) & 0x03) << 30; 
  1078.   *low4Bytes |= (unsigned long)inputBuffer[1] << 22; 
  1079.   *low4Bytes |= ((unsigned long)inputBuffer[2] >> 1) << 15; 
  1080.   *low4Bytes |= (unsigned long)inputBuffer[3] << 7; 
  1081.   *low4Bytes |= ((unsigned long)inputBuffer[4]) >> 1; 
  1082. }
  1083.  
  1084. void ReadSTD(
  1085.          unsigned char *inputBuffer,
  1086.          unsigned char *stdBufferScale,
  1087.          unsigned long *stdBufferSize) 
  1088. {
  1089.   *stdBufferScale = ((inputBuffer[0] & 0x20) >> 5); 
  1090.   *stdBufferSize = ((unsigned long)inputBuffer[0] & 0x1f) << 8;
  1091.   *stdBufferSize |= (unsigned long)inputBuffer[1];
  1092. }
  1093.  
  1094.  
  1095. void ReadRate(inputBuffer,rate)
  1096.      unsigned char *inputBuffer;
  1097.      unsigned long *rate;
  1098. {
  1099.   *rate = (inputBuffer[0] & 0x7f) << 15;
  1100.   *rate |= inputBuffer[1] << 7;
  1101.   *rate |= (inputBuffer[2] & 0xfe) >> 1;
  1102. }
  1103.  
  1104. #define FLOAT_0x10000 (double)((unsigned long)1 << 16)
  1105.  
  1106. int MakeFloatClockTime(hiBit,low4Bytes,floatClockTime)
  1107.      unsigned char hiBit;
  1108.      unsigned long low4Bytes;
  1109.      double *floatClockTime;
  1110. {
  1111.   if (hiBit != 0 && hiBit != 1) {
  1112.     *floatClockTime = 0.0;
  1113.     return 1;
  1114.   }
  1115.   *floatClockTime 
  1116.     = (double)hiBit*FLOAT_0x10000*FLOAT_0x10000 + (double)low4Bytes;
  1117.   *floatClockTime /= (double)STD_SYSTEM_CLOCK_FREQ;
  1118.   return 0;
  1119. }
  1120.