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();
}