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

/* PES class, TrickMode class and PESExtension class implementations */

#include "PES.H"

extern "C"
{
#include 
#include 
#include 
}

PES::PES ()
{
  DTS = (TimeStamp90*) NULL;
  PTS = (TimeStamp90*) NULL;
  ESCR = (TimeStamp27*) NULL;
  ES_rate = (int) NULL;
  trick_mode = (TrickMode*) NULL;
  additional_copy_info = (char) NULL;
  previous_CRC = (int) NULL;
  extension = (PESExtension*) NULL;
  number_stuffing_bytes = 0;
}

PES::PES (PES* p)
{
  stream_id = p->stream_id;
  PES_packet_length = p->PES_packet_length;
  scrambling_code = p->scrambling_code;
  priority_code = p->priority_code;
  alignment_indicator_code = p->alignment_indicator_code;
  copyright_code = p->copyright_code;
  original_code = p->original_code;
  DTS = p->DTS;
  PTS = p->PTS;
  ESCR = p->ESCR;
  ES_rate = p->ES_rate;
  trick_mode = p->trick_mode;
  additional_copy_info = p->additional_copy_info;
  previous_CRC = p->previous_CRC;
  extension = p->extension;
  number_stuffing_bytes = p->number_stuffing_bytes;
  file_name = p->file_name;
}

int PES::get_length ()
{
  if (PES_packet_length == 0) return NOLENGTH;
  return PES_packet_length + 6;
}

int PES::get_header_data_length ()
{
  // start with known minimal length and increment
  int header_length = 6;

  // if private or padding then it is what it is
  if ((stream_id == id_private_stream_2) || 
		(stream_id == id_padding_stream))
    return header_length;

  header_length += 3;
  if (PTS && !DTS) header_length += 5;
  if (PTS && DTS) header_length += 10;
  if (ESCR) header_length += 6;
  if (ES_rate) header_length += 3;
  if (trick_mode) header_length += 1;
  if (additional_copy_info) header_length += 1;
  if (previous_CRC) header_length += 2;
  if (extension) header_length += extension->get_length();

  return header_length;
}

int PES::get_header_length ()
{
  return get_header_data_length() + number_stuffing_bytes;
}

void PES::config_basic (int id, int len, char s, char p, char a,
			char c, char o, TimeStamp90* pts, TimeStamp90* dts,
			TimeStamp27* escr, int rate,
			char ac, int pcrc, int ns)
{
  stream_id = id;
  PES_packet_length = len;
  scrambling_code = s;
  priority_code = p;
  alignment_indicator_code = a;
  copyright_code = c;
  original_code = o;
  if (dts) DTS = dts; else DTS = NULL;
  if (pts) PTS = pts; else PTS = NULL;
  if (escr) ESCR = escr; else ESCR = NULL;
  if (rate) ES_rate = rate; else ES_rate = 0;
  additional_copy_info = ac;
  previous_CRC = pcrc;
  number_stuffing_bytes = ns;
}

void PES::config_trick (char c, char f1, char i, char f2, int r)
{
  if (!trick_mode) trick_mode = new TrickMode();
  trick_mode->trick_mode_control_code = c;
  trick_mode->field_id_code = f1;
  trick_mode->intra_slice_refresh_code = i;
  trick_mode->frequency_truncation_code = f2;
  trick_mode->field_rep_control = r;
}

void PES::config_extension ()
{
  if (!extension) extension = new PESExtension();
  // FIX - add real extension fields
}

void PES::print ()
{
  printf("stream_id: %d\n", stream_id);
  printf("PES_packet_length: %d\n", PES_packet_length);    
  printf("scramble_control: %c\n", scrambling_code);
  printf("PES_priority: %c\n", priority_code);
  printf("data_alignment_indicator: %c\n", alignment_indicator_code);      
  printf("copyright: %c\n", copyright_code);
  printf("copy_or_original: %c\n", original_code);
  printf("PES_header_length: %d\n", get_header_length());
  
  if (PTS)
    printf("PTS: bit32 = %d; bits0..31 = %d\n",
	   PTS->bit32, PTS->bits0_31);
  if (DTS)
    printf("DTS: bit32 = %d; bits0..31 = %d\n",
	   DTS->bit32, DTS->bits0_31);
  
  if (ESCR)
    printf("ESCR: b32 = %d; bits0..31 = %d; ext = %d\n",
	   ESCR->bit32,
	   ESCR->bits0_31,
	   ESCR->ext);
  if (ES_rate)
    printf("ES_rate: %d\n", ES_rate);	  
  
  if (trick_mode)
    trick_mode->print();

  if (additional_copy_info)
    {
      printf("additional copy info: ");
      for (int i = 0; i < 7; i++)
	if (additional_copy_info & (1 << i)) printf("1"); else printf("0");
      printf("\n");
    }

  if (previous_CRC)
    printf("previous_CRC: %d\n", previous_CRC);

  if (extension)
    extension->print();

  if (number_stuffing_bytes)
    printf("stuffing bytes: %d\n", number_stuffing_bytes);

  int length = get_length();
  if (length == NOLENGTH)
    printf("pes payload of unknown length\n");
  else
    printf("pes payload of length %d\n",
 	   length - get_header_length());
}

void TrickMode::print ()
{
  switch (trick_mode_control_code)
    {
    case 'F':
      printf("trick_mode: Fast Forward (%c, %c, %c)\n",
	     field_id_code,
	     intra_slice_refresh_code,
	     frequency_truncation_code);
      break;
    case 'S':
      printf("trick_mode: Slow Motion (%d)\n", field_rep_control);
      break;
    case 'Z':
      printf("trick_mode: Freeze Frame (%c)\n", field_id_code);
      break;
    case 'R':
      printf("trick_mode: Fast Reverse (%c, %c, %c)\n",
	     field_id_code,
	     intra_slice_refresh_code,
	     frequency_truncation_code);
      break;
    }
}

PESExtension::PESExtension ()
{
  PES_private_data = NULL;
  pack_field_length = 0;
  pack_header = NULL;
  pp_seq_counter_code = '0';
  P_STD_buffer_code = '0';
  PES_extension_field_length = 0;
}

int PESExtension::get_length ()
{
  int length = 1;
  if (PES_private_data) length += 16;
  length += pack_field_length;
  if (pp_seq_counter_code == 'P') length += 2;
  if (P_STD_buffer_code == 'B') length += 2;
  length += PES_extension_field_length;
  return length;
}
     
void PESExtension::print ()
{
  if (PES_private_data)
    for (int i = 0; i < 16; i++)
      printf("%c", PES_private_data[i]);

  if (pack_field_length)
      printf("pack_header of length: %d\n", pack_field_length);

  if (pp_seq_counter_code == 'P')
    {
      printf("pp_seq_counter: %d\n", pp_seq_counter);
      printf("original_stuff_length: %d\n", original_stuff_length);
    }

  if (P_STD_buffer_code == 'B')
    {
      printf("P_STD_buffer_scale: %c\n", P_STD_buffer_scale);
      printf("P_STD_buffer_size: %d\n", P_STD_buffer_size);
    }
  if (PES_extension_field_length)
    {
      printf("PES_extension_field of length: %d\n",
	     PES_extension_field_length);
    }
}