text: /* systems.c, systems-specific routines                                 */
  
  /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  
  /*
   * Disclaimer of Warranty
   *
   * These software programs are available to the user without any license fee or
   * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
   * any and all warranties, whether express, implied, or statuary, including any
   * implied warranties or merchantability or of fitness for a particular
   * purpose.  In no event shall the copyright-holder be liable for any
   * incidental, punitive, or consequential damages of any kind whatsoever
   * arising from the use of these programs.
   *
   * This disclaimer of warranty extends to the user of these programs and user's
   * customers, employees, agents, transferees, successors, and assigns.
   *
   * The MPEG Software Simulation Group does not represent or warrant that the
   * programs furnished hereunder are free of infringement of any third-party
   * patents.
   *
   * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
   * are subject to royalty fees to patent holders.  Many of these patents are
   * general enough such that they are unavoidable regardless of implementation
   * design.
   *
   */
  
  #include <stdio.h>
  #include <stdlib.h>
  
  #include "config.h"
  #include "global.h"
  
  /* initialize buffer, call once before first getbits or showbits */
  
  /* parse system layer, ignore everything we don't need */
  void Next_Packet()
  {
    unsigned int code;
    int l;
  
    for(;;)
    {
      code = Get_Long();
  
      /* remove system layer byte stuffing */
      while ((code & 0xffffff00) != 0x100)
        code = (code<<8) | Get_Byte();
  
      switch(code)
      {
      case PACK_START_CODE: /* pack header */
        /* skip pack header (system_clock_reference and mux_rate) */
        ld->Rdptr += 8;
        break;
      case VIDEO_ELEMENTARY_STREAM:   
        code = Get_Word();             /* packet_length */
        ld->Rdmax = ld->Rdptr + code;
  
        code = Get_Byte();
  
        if((code>>6)==0x02)
        {
          ld->Rdptr++;
          code=Get_Byte();  /* parse PES_header_data_length */
          ld->Rdptr+=code;    /* advance pointer by PES_header_data_length */
          printf("MPEG-2 PES packet\n");
          return;
        }
        else if(code==0xff)
        {
          /* parse MPEG-1 packet header */
          while((code=Get_Byte())== 0xFF);
        }
         
        /* stuffing bytes */
        if(code>=0x40)
        {
          if(code>=0x80)
          {
            fprintf(stderr,"Error in packet header\n");
            exit(1);
          }
          /* skip STD_buffer_scale */
          ld->Rdptr++;
          code = Get_Byte();
        }
  
        if(code>=0x30)
        {
          if(code>=0x40)
          {
            fprintf(stderr,"Error in packet header\n");
            exit(1);
          }
          /* skip presentation and decoding time stamps */
          ld->Rdptr += 9;
        }
        else if(code>=0x20)
        {
          /* skip presentation time stamps */
          ld->Rdptr += 4;
        }
        else if(code!=0x0f)
        {
          fprintf(stderr,"Error in packet header\n");
          exit(1);
        }
        return;
      case ISO_END_CODE: /* end */
        /* simulate a buffer full of sequence end codes */
        l = 0;
        while (l<2048)
        {
          ld->Rdbfr[l++] = SEQUENCE_END_CODE>>24;
          ld->Rdbfr[l++] = SEQUENCE_END_CODE>>16;
          ld->Rdbfr[l++] = SEQUENCE_END_CODE>>8;
          ld->Rdbfr[l++] = SEQUENCE_END_CODE&0xff;
        }
        ld->Rdptr = ld->Rdbfr;
        ld->Rdmax = ld->Rdbfr + 2048;
        return;
      default:
        if(code>=SYSTEM_START_CODE)
        {
          /* skip system headers and non-video packets*/
          code = Get_Word();
          ld->Rdptr += code;
        }
        else
        {
          fprintf(stderr,"Unexpected startcode %08x in system layer\n",code);
          exit(1);
        }
        break;
      }
    }
  }
  
  
  
  void Flush_Buffer32()
  {
    int Incnt;
  
    ld->Bfr = 0;
  
    Incnt = ld->Incnt;
    Incnt -= 32;
  
    if (System_Stream_Flag && (ld->Rdptr >= ld->Rdmax-4))
    {
      while (Incnt <= 24)
      {
        if (ld->Rdptr >= ld->Rdmax)
          Next_Packet();
        ld->Bfr |= Get_Byte() << (24 - Incnt);
        Incnt += 8;
      }
    }
    else
    {
      while (Incnt <= 24)
      {
        if (ld->Rdptr >= ld->Rdbfr+2048)
          Fill_Buffer();
        ld->Bfr |= *ld->Rdptr++ << (24 - Incnt);
        Incnt += 8;
      }
    }
    ld->Incnt = Incnt;
  
  #ifdef VERIFY 
    ld->Bitcnt += 32;
  #endif /* VERIFY */
  }
  
  
  unsigned int Get_Bits32()
  {
    unsigned int l;
  
    l = Show_Bits(32);
    Flush_Buffer32();
  
    return l;
  }
  
  
  int Get_Long()
  {
    int i;
  
    i = Get_Word();
    return (i<<16) | Get_Word();
  }
  
  
  