📄 sectionconsumers.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.*//* SectionConsumer class implementation */#include "stdafx.h"#include "Utilities.H"#include "IPortFromRam.H"#include "SectionConsumers.H"#include "Decoder.H"#include "Events.H"#include "PES.H"#include "PESConsumer.H"extern "C"{#include <malloc.h>}SectionConsumer::SectionConsumer (Decoder* d, Section* s) : Consumer(d){ sec = s; buf_index = -1; length_expected = -1;}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 SectionConsumer::read_partial (int n){ int i = 0; char c;
while (i < n) { switch (cstate) { case CSTART: buf = (char*) malloc (1024); // FIX -- private sections can be 4096 buf_index = 0; cstate = SCHEAD1; break; case SCHEAD1: if (buf_index < 4) { buf[buf_index] = iport->read_byte(); buf_index++; i++; } if (buf_index == 4) { // FIX -- this case assumes ptr == 0 if (buf[0] != 0) { sys_error("non zero pointer offset in SectionConsumer"); } length_expected = (char2int(buf[2]) & 0xF) << 8; length_expected += char2int(buf[3]) + 4; cstate = SCHEAD2; } break; case SCHEAD2: if (buf_index < length_expected) { buf[buf_index] = iport->read_byte(); buf_index++; i++; } if (buf_index == length_expected) { InputPort* save_port = iport; iport = new IPortFromRam(buf, length_expected); read_section(); delete iport; iport = save_port; delete buf; buf_index = 0; // done with buf cstate = SCFLUSH; } break; case SCFLUSH: c = iport->read_byte(); assert(c == (char) 0xff); i++; break; default: sys_error("unknown SectionConsumer state"); } } return n;}void SectionConsumer::read_header_a (){ // read pointer field // FIX -- this assumes that there is always a pointer field sec->pointer = iport->read_uimsbf(8, "reading pointer field"); // skip to start of section for (int k = 0; k < sec->pointer; k++) (void) iport->read_byte(); // start CRC iport->start_crc(); // read table_id (should be 0) sec->table_id = iport->read_uimsbf(8, "reading table_id"); // read section_syntax_code char syntax = iport->read_bit(); if (syntax == ONE) sec->section_syntax_code = 'S'; else sec->section_syntax_code = 'L'; // read '0' and reserved bits iport->read_bit(); iport->read_reserved_bits(2); // read section_length sec->section_length = iport->read_uimsbf(12, "reading section_length");}void SectionConsumer::read_header_b (){ // read reserved bits iport->read_reserved_bits(2); // read version_number sec->version_number = iport->read_uimsbf(5, "reading version_number"); // read current_next_indicator char cur_next = iport->read_bit(); if (cur_next == ONE) sec->current_next_code = 'C'; else sec->current_next_code = 'N'; // read section_number sec->section_number = iport->read_uimsbf(8, "reading section_number"); // read last_section_number sec->last_section_number = iport->read_uimsbf(8, "reading last_section_number");}void SectionConsumer::read_CRC (){ // read CRC iport->stop_crc(); if (!iport->check_crc()) decoder->get_manager()->Trigger(BadCRC, sec);}PATConsumer::PATConsumer (Decoder* d, PATSection* s) : SectionConsumer(d, s){ patsec = s;}void PATConsumer::read_section (){ // read header_a read_header_a(); // read transport_stream_id patsec->transport_stream_id = iport->read_uimsbf(16, "reading trans_strm_id"); // read header_b read_header_b(); // create new directory; get old one Directory* newdir = new Directory(); Directory* olddir = decoder->get_dir(); int network_pid = decoder->get_networkpid(); // read loop for (int i = 0; i < patsec->section_length - 9; i += 4) { int prog_number = iport->read_uimsbf(16, "reading program number"); iport->read_reserved_bits(3); if (prog_number == 0) { network_pid = iport->read_uimsbf(13, "reading network_pid"); } else { int pid = iport->read_uimsbf(13, "reading pid"); // update Directory Program* program = olddir->get_program(prog_number); if (program) { // not a new program newdir->add_program(program); } else { // a new program newdir->add_program(new Program(prog_number, pid)); } } } // setup decoder using new directory decoder->install_netpid(network_pid); decoder->install_dir(newdir); // read CRC read_CRC(); // call PATParsed callback decoder->get_manager()->Trigger(PATParsed, patsec);}MapConsumer::MapConsumer (Decoder* d, MapSection* s) : SectionConsumer(d, s){ mapsec = s;}void MapConsumer::read_section (){ // read header_a read_header_a(); // read program_number mapsec->program_number = iport->read_uimsbf(16, "reading program_number"); // read header_b read_header_b(); // read reserved bits iport->read_reserved_bits(3); // read pcr_pid mapsec->pcr_pid = iport->read_uimsbf(13, "reading pcr_pid"); // read reserved bits iport->read_reserved_bits(4); // create new program with same program number Program* newprog = new Program(mapsec->program_number, decoder->get_ts()->pid); // read program_info_length and info into newprog mapsec->program_info_length = iport->read_uimsbf(12, "reading program_info_length"); // FIX - implement descriptors for program info for (int i = 0; i < mapsec->program_info_length; i++) { (void) iport->read_byte(); } // read loop int bytes_in_loop = mapsec->section_length - mapsec->program_info_length - 13; for (int j = 0; j < bytes_in_loop; ) { // read fields int stream_type = iport->read_uimsbf(8, "reading stream_type"); iport->read_reserved_bits(3); int elem_pid = iport->read_uimsbf(13, "reading elem_pid"); EStream* estream = new EStream((StreamType) stream_type, elem_pid, NULL); newprog->add_estream(estream); // read estream info iport->read_reserved_bits(4); int info_length = iport->read_uimsbf(12, "reading es_info_length"); // FIX - implement descriptors for estream info for (int k = 0; k < info_length; k++) (void) iport->read_byte(); j += 5 + info_length; } // get dir and install new program decoder->install_prog(newprog); // read CRC read_CRC(); // call MapParsed callback decoder->get_manager()->Trigger(MapParsed, mapsec);}CAConsumer::CAConsumer (Decoder* d, CASection* s) : SectionConsumer(d, s){ casec = s;}void CAConsumer::read_section (){ // read header_a read_header_a(); // read 16/18 reservered bits, read_header_b() will read 2 more bits. iport->read_reserved_bits(16); // read header_b read_header_b(); // read loop int bytes_in_loop = casec->section_length - 9; for (int j = 0; j < bytes_in_loop; ) { // read descriptor int descriptor_tag = iport->read_uimsbf(8, "reading des_tag"); if (descriptor_tag != 9) sys_message("bad descriptor in CASection"); int descriptor_length = iport->read_uimsbf(8, "reading des_length"); int CA_system_id = iport->read_uimsbf(16, "reading CA_system_id"); iport->read_reserved_bits(3); int ca_pid = iport->read_uimsbf(13, "reading des_tag"); // FIX -- eventually add a CAConsumer to consume ca_pid; ignore for now for (int k = 0; k < descriptor_length - 4; k++) (void) iport->read_byte(); j += descriptor_length + 2; } // read CRC read_CRC(); // call CAParsed callback decoder->get_manager()->Trigger(CAParsed, casec);}PriConsumer::PriConsumer (Decoder* d, PriSection* s) : SectionConsumer(d, s){ prisec = s;}void PriConsumer::read_section (){ // read header_a read_header_a(); // check syntax indicator if (prisec->section_syntax_code == 'S') { for (int i = 0; i < prisec->section_length; i++) (void) iport->read_byte(); } else { // read table_id_extension prisec->table_id_extension = iport->read_uimsbf(16, "reading table_id_ext"); // read header_b read_header_b(); // read loop int bytes_in_loop = prisec->section_length - 9; for (int j = 0; j < bytes_in_loop; j++) { (void) iport->read_byte(); } // read CRC read_CRC(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -