www.pudn.com > MPEG2systemsrc.rar > SectionProducers.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.
*/

/* SectionProducer classes implementations */

#include "SectionProducers.H"
#include "OPortToRam.H"

extern "C"
{
#include 
#include 
}

SectionProducer::SectionProducer (Encoder*e, Section* s) : Producer(e)
{
  sec = s;
}

int SectionProducer::fill_buffer ()
{
  if (buf) delete buf;
  length_stored = sec->section_length + 4;
  buf = (char*) malloc (length_stored);
  OutputPort* save_port = oport;
  oport = new OPortToRam(buf, length_stored, NULL);
  send_section();
  delete oport;
  oport = save_port;
  buf_index = 0;
  return length_stored;
}

void SectionProducer::send_header_a ()
{
  // send pointer field and stuffing bytes
  oport->write_uimsbf(sec->pointer, 8);
  for (int i = 0; i < sec->pointer; i++)
    oport->write_byte(0xff);

  // start CRC
  oport->start_crc();

  // send table_id
  oport->write_uimsbf(sec->table_id, 8);

  // send section_syntax_indicator
  if (sec->section_syntax_code == 'S') oport->write_bit('1');
  else oport->write_bit('0');

  // send '0' and reserved bits
  oport->write_bit('0');
  oport->write_reserved_bits(2);

  // send section_length
  oport->write_uimsbf(sec->section_length, 12);
}

void SectionProducer::send_header_b ()
{
  // send reserved bits
  oport->write_reserved_bits(2);
  
  // send version_number
  oport->write_uimsbf(sec->version_number, 5);
  
  // send current_next_indicator
  if (sec->current_next_code == 'C') oport->write_bit('1');
  else oport->write_bit('0');
  
  // send section_number
  oport->write_uimsbf(sec->section_number, 8);
  
  // send last_section_number
  oport->write_uimsbf(sec->last_section_number, 8);
}

void SectionProducer::send_CRC ()
{
  oport->stop_crc();
  oport->write_crc();
}

PATProducer::PATProducer (Encoder* e, PATSection* s)
    : SectionProducer(e, s)
{
  // set fields 
  patsec = s;
  // set fields in patsec
  patsec->section_length = 4 * encoder->get_dir()->get_num_programs() + 9;
}

void PATProducer::send_section ()
{
  // send header_a
  send_header_a();

  // send transport_stream_id
  oport->write_uimsbf(patsec->transport_stream_id, 16);
  
  // send header_b
  send_header_b();

  // send loop
  ProgramRecord* prec = encoder->get_dir()->head_prec;
  while (prec)
    {
      // send program_number
      int program_number = prec->program->program_number;
      // FIX - who manages program_numbers; currently the program->pid
      oport->write_uimsbf(program_number, 16);
      // send reservered bits
      oport->write_reserved_bits(3);
      // send pid
      int pid;
      if (program_number == 0)
	{
	  pid = encoder->new_pid();
	}
      else
	{
	  pid = prec->program->pid;
	}
      oport->write_uimsbf(pid, 13);
      prec = prec->next_prec;
    }
  
  // send CRC
  send_CRC();
}

MapProducer::MapProducer (Encoder* e, MapSection* s)
    : SectionProducer(e, s)
{
  // set fields
  mapsec = s;

  // set fields in mapsec
  mapsec->section_length = 5 * mapsec->program->get_num_streams() + 13;
  // FIX - map sections currently assume no info descriptors
}

void MapProducer::send_section ()
{
  // send header_a
  send_header_a();

  // send program_number
  oport->write_uimsbf(mapsec->program_number, 16);
  
  // send header_b
  send_header_b();

  // send program-specific info
  oport->write_reserved_bits(3);
  oport->write_uimsbf(mapsec->pcr_pid, 13);  
  oport->write_reserved_bits(4);
  oport->write_uimsbf(0, 12);   
  // FIX - currently no info descriptors so info_length = 0
  
  // send loop
  EStreamRecord* erec = mapsec->program->head_erec;
  while (erec)
    {
      oport->write_uimsbf(erec->estream->stream_type, 8);
      oport->write_reserved_bits(3);
      oport->write_uimsbf(erec->estream->pid, 13);
      oport->write_reserved_bits(4);
      oport->write_uimsbf(0, 12);
      // FIX - currently descriptors length = 0
      erec = erec->next_erec;
    }
  
  // send CRC
  send_CRC();
}

CAProducer::CAProducer (Encoder* e, CASection* s) : SectionProducer(e, s)
{
  casec = s;
  // FIX - set section_length or other section fields in CASection
}

void CAProducer::send_section ()
{
  // send header_a
  send_header_a();

  // send reserved_bits
  oport->write_reserved_bits(16);
  
  // send header_b
  send_header_b();

  // send loop
  for (int i = 0; i < casec->section_length - 9; i += 4)
    {
      // FIX - CAProducer has to send CA_descriptor
    }
  
  // send CRC
  send_CRC();
}