📄 pesconsumer.cpp
字号:
/* 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 implementation */#include "Utilities.H"#include "PESConsumer.H"#include "IPortFromRam.H"#include "Decoder.H"#include "OPortToFile.H"/*extern "C"{#include <stdio.h>#include <fcntl.h> #include <malloc.h>int write (int, char*, int);}*/PESConsumer::PESConsumer (Decoder* d, PES* p) : Consumer(d){ pes = p;// cstate = CSTART;
cstate = IGNORE; pes_out_flag = TRUE; esport = NULL;}static int char2int (char c) { int result = 0; for (int i = 7; i >= 0; i--) { if ((c & (1 << i)) == 0) result = result * 2; else result = result * 2 + 1; } return result;}/* This function is called to read TP payloads. */int PESConsumer::read_partial (int n){ int i = 0;
int j; int plen;
char* pbuf;
while (i < n) { switch (cstate) { case CSTART: buf = (char*) malloc (512); buf_index = 0; cstate = PCHEAD1; break; case PCHEAD1: if (buf_index < 9) { buf[buf_index] = iport->read_byte(); buf_index++; i++; } if (buf_index == 9) { header_length = char2int(buf[8]) + 9; cstate = PCHEAD2; } break; case PCHEAD2: if (buf_index < header_length) { buf[buf_index] = iport->read_byte(); buf_index++; i++; } if (buf_index == header_length) { InputPort* save_port = iport; iport = new IPortFromRam(buf, header_length); read_pes_header(); delete iport; iport = save_port; if (pes_out_flag) write_elementary_stream_chunk(buf, header_length); delete buf; buf_index = 0; // done with buf cstate = PCPAYLOAD; } break; case PCPAYLOAD: // dispense with remaining n-i payload bytes plen = n - i; pbuf = (char*) malloc(plen); for (j = 0; j < plen; j++) { pbuf[j] = iport->read_byte(); i++; } write_elementary_stream_chunk(pbuf, plen); delete pbuf; assert(i == n); // stay in PCPAYLOAD state; // state changes when payload_unit_start_indicator is seen break;
case IGNORE:
// dispense with remaining n-i payload bytes
plen = n - i;
for (j = 0; j < plen; j++)
{
iport->read_byte();
i++;
}
assert(i == n);
break; default: sys_error("unknown PESConsumer state"); } } return n;}void PESConsumer::flush (){ esport->flush();}void PESConsumer::write_elementary_stream_chunk (char* pbuf, int plen){ // prepare esport if (!esport) { // use decoder->get_ts()->pid or pes->stream_id? int cur_pid = decoder->get_ts()->pid; // FIX - provide access function to current pid from decoder? char fileName[32]; sprintf(fileName, "stream%d", cur_pid); esport = new OPortToFile(fileName, 0); } // output loop for (int i = 0; i < plen; i++) { esport->write_byte(pbuf[i]); }}void PESConsumer::read_pes_header (){
int result = iport->read_pattern("000000000000000000000001"); if(result == 1)
result = 1; pes->stream_id = iport->read_uimsbf(8, "reading stream_id"); pes->PES_packet_length = iport->read_uimsbf(16, "reading PES_packet_length"); if ((pes->stream_id != id_private_stream_2) && (pes->stream_id != id_padding_stream)) { // read "01" int result = iport->read_pattern("10"); if(result == 1)
result = 1;
// read PES_scrambling_control; currently uses only "00" or "11" char scramble1 = iport->read_bit(); char scramble2 = iport->read_bit(); if ((scramble1 == ZERO) && (scramble2 == ZERO)) pes->scrambling_code = '0'; else pes->scrambling_code = 'S'; // read PES_priority char priority = iport->read_bit(); if (priority == ONE) pes->priority_code = 'H'; else pes->priority_code = 'L'; // read data_alignment_indicator char align = iport->read_bit(); if (align == ONE) pes->alignment_indicator_code = 'A'; else pes->alignment_indicator_code = '0'; // read copyright char copyright = iport->read_bit(); if (copyright == ONE) pes->copyright_code = 'C'; else pes->copyright_code = '0'; // read copy_or_original char original = iport->read_bit(); if (original == ONE) pes->original_code = 'C'; else pes->original_code = '0'; // read 8 flags char pts_flag = iport->read_bit(); char dts_flag = iport->read_bit(); char escr_flag = iport->read_bit(); char esrate_flag = iport->read_bit(); char dsm_trick_flag = iport->read_bit(); char additional_copy_flag = iport->read_bit(); char crc_flag = iport->read_bit(); char extension_flag = iport->read_bit(); // read PES_header_data_length int PES_header_length = iport->read_uimsbf(8, "reading PES_header_length"); // read optional fields // read pts,dts if ((pts_flag == ONE) && (dts_flag == ZERO)) { iport->read_pattern("0010"); pes->PTS = iport->read_timestamp90(); pes->DTS = NULL; decoder->get_manager()->Trigger(PTSDTSEvent, pes); } else if ((pts_flag == ONE) && (dts_flag == ONE)) { iport->read_pattern("0011"); pes->PTS = iport->read_timestamp90(); iport->read_pattern("0001"); pes->DTS = iport->read_timestamp90(); decoder->get_manager()->Trigger(PTSDTSEvent, pes); } else { pes->PTS = NULL; pes->DTS = NULL; } // read escr if (escr_flag == ONE) { iport->read_reserved_bits(2); pes->ESCR = iport->read_timestamp27_pes_format(); } // read es_rate if (esrate_flag == ONE) { iport->read_markerbit(); pes->ES_rate = iport->read_uimsbf(22, "reading ES_rate"); iport->read_markerbit(); } // read DSM_trick_mode if (dsm_trick_flag == ONE) { read_trick_mode(); } // read additional_copy_info if (additional_copy_flag == ONE) { iport->read_markerbit(); pes->additional_copy_info = NULL; char c; for (int i = 0; i < 7; i++) { c = iport->read_bit(); if (c == '1') { pes->additional_copy_info |= (1 << i); } } } // read previous_PES_packet_CRC if (crc_flag == ONE) { pes->previous_CRC = iport->read_uimsbf(16, "reading previous_CRC"); } // read PES extension fields if (extension_flag == ONE) { read_extension(); } // skip the stuffing bytes. N.B. the "9" added to PES_header_length pes->number_stuffing_bytes = PES_header_length + 9 - pes->get_header_data_length(); for (int i = 0; i < pes->number_stuffing_bytes; i++) iport->read_byte(); } // call PESParsed callback decoder->get_manager()->Trigger(PESHeaderParsed, pes);}void PESConsumer::read_trick_mode (){ char intra; pes->trick_mode = new TrickMode(); int code = iport->read_uimsbf(3, "reading trick_control_code"); switch (code) { case 0: pes->trick_mode->trick_mode_control_code = 'F'; read_field_id(); intra = iport->read_bit(); if (intra == ONE) { pes->trick_mode->intra_slice_refresh_code = 'I'; } else { pes->trick_mode->intra_slice_refresh_code = '0'; } read_frequency_truncation(); break; case 1: pes->trick_mode->trick_mode_control_code = 'S'; pes->trick_mode->field_rep_control = iport->read_uimsbf(5, "reading field rep_control"); break; case 2: pes->trick_mode->trick_mode_control_code = 'Z'; read_field_id(); iport->read_reserved_bits(3); break; case 3: pes->trick_mode->trick_mode_control_code = 'R'; read_field_id(); intra = iport->read_bit(); if (intra == ONE) { pes->trick_mode->intra_slice_refresh_code = 'I'; } else { pes->trick_mode->intra_slice_refresh_code = '0'; } read_frequency_truncation(); break; default: // It must be one of the reserved modes iport->read_reserved_bits(5); break; }}void PESConsumer::read_field_id (){ if (pes->trick_mode == NULL) return; int code = iport->read_uimsbf(2, "reading field_id"); switch (code) { case 0: pes->trick_mode->field_id_code = '1'; break; case 1: pes->trick_mode->field_id_code = '2'; break; case 2: pes->trick_mode->field_id_code = 'B'; break; }}void PESConsumer::read_frequency_truncation (){ if (pes->trick_mode == NULL) return; int code = iport->read_uimsbf(2, "reading frequency_truncation"); switch (code) { case 0: pes->trick_mode->frequency_truncation_code = 'D'; break; case 1: pes->trick_mode->frequency_truncation_code = '3'; break; case 2: pes->trick_mode->frequency_truncation_code = '6'; break; case 3: pes->trick_mode->frequency_truncation_code = 'A'; break; }}void PESConsumer::read_extension (){ pes->extension = new PESExtension(); // read flags char PES_private_data_flag = iport->read_bit(); char pack_header_field_flag = iport->read_bit(); char pp_seq_counter_flag = iport->read_bit(); char P_STD_buffer_flag = iport->read_bit(); iport->read_reserved_bits(3); char PES_extension_field_flag = iport->read_bit(); if (PES_private_data_flag == ONE) { pes->extension->PES_private_data = (char*) malloc(16); for (int i = 0; i < 16; i++) pes->extension->PES_private_data[i] = iport->read_byte(); } if (pack_header_field_flag == ONE) { pes->extension->pack_field_length = iport->read_uimsbf(8, "reading pack_field_length");
pes->extension->pack_header = (char*) malloc(pes->extension->pack_field_length); for (int j = 0; j < pes->extension->pack_field_length; j++) pes->extension->pack_header[j] = iport->read_byte(); } if (pp_seq_counter_flag == ONE) { pes->extension->pp_seq_counter_code = 'P'; iport->read_markerbit(); pes->extension->pp_seq_counter = iport->read_uimsbf(7, "reading pp_seq_counter"); iport->read_markerbit(); pes->extension->original_stuff_length = iport->read_uimsbf(7, "reading orig. stuff len"); } else pes->extension->pp_seq_counter_code = '0'; if (P_STD_buffer_flag == ONE) { pes->extension->P_STD_buffer_code = 'B'; iport->read_pattern("01"); pes->extension->P_STD_buffer_scale = iport->read_bit(); pes->extension->P_STD_buffer_size = iport->read_uimsbf(13, "reading P_STD_buf_size"); } else pes->extension->P_STD_buffer_code = '0'; if (PES_extension_field_flag == ONE) { iport->read_markerbit(); pes->extension->PES_extension_field_length = iport->read_uimsbf(7, "reading PES_ext_field_length"); for (int k = 0; k < pes->extension->PES_extension_field_length; k++) (void) iport->read_reserved_bits(8); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -