www.pudn.com > MPEG2systemsrc.rar > decode.C


/* Copyright (C) 1995, Tektronix Inc. All Rights Reserved.
 *
 *   Usage Restrictions
 *
 * License is granted to copy, to use, and to make and to use derivative
 * works for research and evaluation purposes only.
 *
 *   Disclaimer of Warranty
 *
 * These software programs are available to the user without any license
 * fee or royalty on an "as is" basis.  Tektronix Inc. 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 Tektronix Inc. does not represent or warrant that the programs
 * furnished hereunder are free of infringement of any third-party
 * patents.
*/

/* A sample decoder */

/*
   The following application parses a transport stream. The command
   syntax is

   decode file_name 

   where file_name is the file containing a transport stream.  If
   printflag is present then system diagnostic messages will be
   suppressed.

   This file contains a number of callbacks which can be triggered or
   not by commenting or uncommenting the event registration commands
   below.
*/

#include "Directory.H"
#include "Decoder.H"
#include "IPortFromFile.H"
#include "Events.H" 
#include "Section.H"
#include "Utilities.H"

extern "C"
{
void exit (int);
#include 
}

// Callbacks
void print_ts (EventType, void*, void*);
void print_pes (EventType, void*, void*);
void print_pat (EventType, void*, void*);
void print_map (EventType, void*, void*);
void print_ca (EventType, void*, void*);
void print_pid (EventType, void*, void*);
void print_badcrc (EventType, void*, void*);
void unexpected_pid (EventType, void*, void*);
void pcr_event (EventType, void*, void*);
void ptsdts_event (EventType, void*, void*);
void cleanup (EventType, void*, void*);

main (int argc, char* argv[])
{
  if ((argc < 2) || (argc > 3))
    {
      printf("syntax is decode  \n");
      exit (0);
    }

  if (argc == 3) PRINTFLAG = FALSE;
  
  // create an EventManager
  EventManager* manager = new EventManager();
  EM = manager;
  
  // create a Decoder
  Decoder* decoder = new Decoder(manager);

  // register callbacks
/*
  manager->Register(CAParsed, print_ca, NULL);
  manager->Register(TSParsed, print_ts, decoder);
  manager->Register(BadCRC, print_badcrc, NULL);
  manager->Register(PCREvent, pcr_event, decoder);
  manager->Register(PTSDTSEvent, ptsdts_event, decoder);
  manager->Register(TSParsed, print_pid, decoder);
*/
  manager->Register(PESHeaderParsed, print_pes, NULL);
  manager->Register(PATParsed, print_pat, decoder);
  manager->Register(MapParsed, print_map, decoder);
  manager->Register(Termination, cleanup, decoder);
  manager->Register(UnexpectedPid, unexpected_pid, NULL);
  
  // create Directory and setup decoder
  Directory* dir = new Directory();
  decoder->install_dir(dir);
  decoder->install_netpid(5);

  // build import and connect
  IPortFromFile* iport = new IPortFromFile(argv[1], NOCYCLE);
  decoder->connect(iport);

  // read some packets
  for (;;) 
  {
     decoder->read_packet();
  }
  
  printf("\ndone\n");
}

void cleanup (EventType t, void* client_data, void* call_data)
{
  Decoder* decoder = (Decoder*) client_data;
  decoder->flush();
}

void print_ts (EventType t, void* client_data, void* call_data)
{
  Decoder* decoder = (Decoder*) client_data;
  TS* ts = (TS*) call_data;
  printf("          - Transport Packet %d Begins -\n", decoder->packet_number);
  ts->print();
  printf("\n");
}

void print_badcrc (EventType t, void* client_data, void* call_data)
{
  printf("*** bad crc ***\n");
}

void print_pes (EventType t, void* client_data, void* call_data)
{
  PES* pes = (PES*) call_data;
  printf("    **** PES Packet Start ****\n");
  pes->print();
  printf("    **** PES Packet Header End ****\n\n");
}

void print_pat (EventType t, void* client_data, void* call_data)
{
  PATSection* patsec = (PATSection*) call_data;
  printf("    **** PAT Section Start ****\n");

  patsec->print();

  Decoder* decoder = (Decoder*) client_data;
  printf(" Decoder active PIDS: ");
  decoder->print_pids();
  printf("\n");
  printf(" Directory Contents: \n");
  decoder->get_dir()->print();

  printf("    **** PAT Section End ****\n\n");
}

void print_map (EventType t, void* client_data, void* call_data)
{
  MapSection* mapsec = (MapSection*) call_data;
  printf("    **** Map Section Start ****\n");

  mapsec->print();

  Decoder* decoder = (Decoder*) client_data;
  printf(" Decoder active PIDS: ");
  decoder->print_pids();
  printf("\n");
  printf(" Directory Contents: \n");
  decoder->get_dir()->print();
  
  printf("    **** Map Section End ****\n\n");
}

void print_ca (EventType t, void* client_data, void* call_data)
{
  CASection* casec = (CASection*) call_data;
  printf("    **** CA Section Start ****\n");
  casec->print();
  printf("    **** CA Section End ****\n\n");
}

void print_pid (EventType t, void* client_data, void* call_data)
{
  TS* ts = (TS*) call_data;
  printf("pid: %d\n", ts->pid);
}

void unexpected_pid (EventType t, void* client_data, void* call_data)
{
  Wrapper* wrap = (Wrapper*) call_data;
  printf("unexpected pid: %d\n", wrap->i);
}

void pcr_event (EventType t, void* client_data, void* call_data)
{
  static TimeStamp27 *last_pcr = NULL;
  static int last_packet_number = -1;
  
  Decoder* decoder = (Decoder*) client_data;
  TS* ts = (TS*) call_data;
  
  printf("PCR: ");
  ts->adaptation->PCR->print();

  if ((last_pcr) && (last_packet_number > 0))
    {
      long delta_bits = 1504 * (decoder->packet_number - last_packet_number);
      TimeStamp27 delta_Hz = *ts->adaptation->PCR - *last_pcr;
      long delta_usec = delta_Hz.useconds();
      printf("\tdelta_usec = %d", delta_usec);
      printf("\tBitrate: %.2fMbps", double(delta_bits) / double(delta_usec));
    }
  
  printf("\n");

  last_packet_number = decoder->packet_number;
  last_pcr = ts->adaptation->PCR;
}

void ptsdts_event (EventType t, void* client_data, void* call_data)
{
  Decoder* decoder = (Decoder*) client_data;
  PES* pes = (PES*) call_data;

  if (pes->PTS)
    {
      printf("    PTS: ");
      pes->PTS->print();
    }
  if (pes->DTS)
    {
      printf("    DTS: ");
      pes->DTS->print();
    }
  printf("\n");
}