www.pudn.com > MPEG2systemsrc.rar > TSProducer.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.
*/
/* TSProducer class implementation */
#include "Utilities.H"
#include "TSProducer.H"
#include "OPortToRam.H"
TSProducer::TSProducer (Encoder* e) : Producer(e)
{
}
void TSProducer::send_ts_packet (Producer* payload_prod)
{
// write sync byte
oport->write_pattern("01000111");
// write transport_error_indicator
if (ts->transport_error_code == 'E') oport->write_bit('1');
else oport->write_bit('0');
// write payload_unit_start_indicator
if (payload_prod->get_nready() == 0)
{
ts->payload_unit_start_code = 'A';
oport->write_bit('1');
// a good time to load the payload producer
payload_prod->fill_buffer();
}
else
{
ts->payload_unit_start_code = '0';
oport->write_bit('0');
}
// write transport_priority
if (ts->priority_code == 'H') oport->write_bit('1');
else oport->write_bit('0');
// write pid
oport->write_uimsbf(ts->pid, 13);
// write transport_scrambling_control
if (ts->scrambling_code == 'S') oport->write_pattern("11");
else oport->write_pattern("00");
// check lengths and adjust stuffing bytes
int nready = payload_prod->get_nready();
if (nready < 188 - ts->get_header_length())
{
if (ts->adaptation)
{
ts->adaptation->number_stuffing_bytes +=
188 - ts->get_header_length() - nready;
}
else
{
ts->adaptation = new AdaptationField();
if (nready < 183)
{
ts->adaptation->number_stuffing_bytes = 182 - nready;
ts->adaptation->adaptation_field_length =
ts->adaptation->number_stuffing_bytes + 1;
}
}
}
// write adaptation_field_control
if (ts->adaptation) oport->write_bit('1');
else oport->write_bit('0');
if (ts->payload_code) oport->write_bit('1');
else oport->write_bit('0');
// write continuity_counter
oport->write_uimsbf(ts->continuity_counter, 4);
//send adaptation field
if (ts->adaptation)
send_adaptation(payload_prod);
// send null payload
if (ts->pid == 8191)
{
int nbytes = 188 - ts->get_header_length();
for (int k = 0; k < nbytes; k++)
oport->write_byte(0xff);
return;
}
// send nonnull payload
if (ts->payload_code && payload_prod)
send_payload(payload_prod);
}
void TSProducer::send_adaptation (Producer* payload_prod)
{
// write adaptation_field_length
oport->write_uimsbf(ts->adaptation->get_length() - 1, 8);
// write discontinuity_indicator
if (ts->adaptation->discontinuity_code == 'D') oport->write_bit('1');
else oport->write_bit('0');
// write random_access_indicator
if (ts->adaptation->random_access_code == 'R') oport->write_bit('1');
else oport->write_bit('0');
// write elementary_stream_priority_indicator
if (ts->adaptation->elem_stream_priority_code == 'H') oport->write_bit('1');
else oport->write_bit('0');
// write PCR_flag
if (ts->adaptation->PCR) oport->write_bit('1');
else oport->write_bit('0');
// write OPCR_flag
if (ts->adaptation->OPCR) oport->write_bit('1');
else oport->write_bit('0');
// write splicing_point_flag
if (ts->adaptation->splice_countdown != NOSPLICE) oport->write_bit('1');
else oport->write_bit('0');
// write transport_private_data_flag
if (ts->adaptation->transport_private_data_length != NULL)
oport->write_bit('1');
else
oport->write_bit('0');
// write adaptation_field_extension_flag
if (ts->adaptation->adaptation_extension_length != 0) oport->write_bit('1');
else oport->write_bit('0');
// write PCR
if (ts->adaptation->PCR)
oport->write_timestamp27_ts_format(ts->adaptation->PCR);
// write OPCR
if (ts->adaptation->OPCR)
oport->write_timestamp27_ts_format(ts->adaptation->OPCR);
// write splice_countdown
if (ts->adaptation->splice_countdown != NOSPLICE)
oport->write_tcimsbf(ts->adaptation->splice_countdown, 8);
// write transport_private_data
if (ts->adaptation->transport_private_data_length != 0)
{
oport->write_uimsbf(ts->adaptation->transport_private_data_length, 8);
for (int i = 0; i < ts->adaptation->transport_private_data_length; i++)
oport->write_byte((char) 0);
}
// write adaptation_field_extension
if (ts->adaptation->adaptation_extension_length != 0)
{
oport->write_uimsbf(ts->adaptation->adaptation_extension_length, 8);
for (int j = 0; j < ts->adaptation->adaptation_extension_length; j++)
oport->write_byte((char) 0xff);
}
// write stuffing bytes
if (ts->adaptation->number_stuffing_bytes != 0)
{
for (int k = 0; k < ts->adaptation->number_stuffing_bytes; k++)
oport->write_byte(0xff);
}
}
void TSProducer::send_payload (Producer* payload_prod)
{
int nbytes = 188 - ts->get_header_length();
if (payload_prod == NULL)
{
sys_error("unexpected NULL producer found");
}
payload_prod->connect(oport);
// payload_prod has already been loaded
int done = payload_prod->send_partial(nbytes);
}