📄 encoder.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.*//* Encoder class implementation */#include "stdafx.h"#include "Encoder.H"#include "SectionProducers.H"#include "PESProducer.H"#include "TSProducer.H"#include "Utilities.H"Encoder::Encoder (EventManager* m){ manager = m; tsprod = new TSProducer(this); head_prec = NULL; packet_number = 0; sys_time = 0; sys_const = 20000000; // set producer list to null head_prec = NULL;}void Encoder::set_bitrate (int r){ bitrate = r; packet_time = (1504 * 27000) / bitrate; }void Encoder::install_dir (Directory* d){ dir = d; // build null packet TS and add producer TS* nullts = new TS(); nullts->config_basic('0', '0', 'L', '0', '0', '0'); nullts->pid = 8191; (void) add_prod(nullts, new Producer(this), NULLPROD, NULL); // build PAT packet TS and add producer TS* patts = new TS(); patts->config_basic('0', 'A', 'H', '0', '0', 'P'); patts->pid = 0; (void) add_prod(patts, new PATProducer(this, new PATSection()), PSI, NULL); // FIX - set up conditional access producer as well // now setup prec's based on new directory build_records();}void Encoder::build_records (){ // loop through programs in directory ProgramRecord* prec = dir->head_prec; while (prec) { // check pid for MapTable if (prec->program->pid == UNASSIGNED) { prec->program->pid = new_pid(); if (prec->program->active == ACTIVE) { TS* mapts = new TS(); mapts->pid = prec->program->pid; mapts->config_basic('0', 'A', 'H', '0', '0', 'P'); (void) add_prod(mapts, new MapProducer(this, new MapSection(prec->program)), PSI, NULL); } } else { // FIX - check to see if program is active before sending Map table } // loop through programs estreams check estreams EStreamRecord* erec = prec->program->head_erec; while (erec) { if (erec->estream->pid == UNASSIGNED) { erec->estream->pid = new_pid(); if (prec->program->active == ACTIVE) { TS* ts = new TS(); ts->pid = erec->estream->pid; ts->config_basic('0', 'A', 'H', '0', 0, 'P'); ProducerRecord* prodrec = add_prod(ts, new PESProducer(this, new PES()), ELEM, erec->estream->bandwidth); if (erec->estream == prec->program->pcr_estream) { prodrec->pcr_flag = 1; prodrec->next_pcr = 0; } } } else { // FIX - further work on Encoder::build_records } erec = erec->next_erec; } prec = prec->next_prec; }}void Encoder::connect (OutputPort* op){ oport = op; // connect tsport tsprod->connect(op); // payload Producers connect just before they are used}void Encoder::send_packet (int pid){ // get prec ProducerRecord* prec = find_prec(pid); send_packet(prec);}void Encoder::send_scheduled_packet (){ ProducerRecord* min_prec = NULL; double min_cur_gap = 100.0; ProducerRecord* prec = head_prec; while (prec) { if (prec->cur_gap < min_cur_gap) { min_cur_gap = prec->cur_gap; min_prec = prec; } prec = prec->next_prec; } send_packet(min_prec);}void Encoder::send_packet (ProducerRecord* prec_togo){ if (prec_togo == NULL) { prec_togo = find_prec(8191); if (prec_togo == NULL) { sys_message("can't find pid 8191 in Encoder table"); return; } } // set up environment packet_number++; if (packet_number > 1) sys_time = sys_time + packet_time; // prepare and bind ts structure prec_togo->ts->inc_cc(); if ((prec_togo->pcr_flag == 1) && (sys_time > prec_togo->next_pcr)) { prec_togo->ts->add_pcr(sys_time); prec_togo->next_pcr = sys_time + TimeStamp27(270000); } else { prec_togo->ts->delete_pcr(); } tsprod->ts = prec_togo->ts; // send packet tsprod->send_ts_packet(prec_togo->prod); // adjust gaps ProducerRecord* prec = head_prec; while (prec) { if (prec == prec_togo) prec->cur_gap = prec->cur_gap + prec->gap; else prec->cur_gap = prec->cur_gap - 1; prec = prec->next_prec; }}Directory* Encoder::get_dir (){ return dir;}TS* Encoder::get_ts (int pid){ ProducerRecord* prec = find_prec(pid); if (prec) { return prec->ts; } return NULL;}PES* Encoder::get_pes (int pid){ ProducerRecord* prec = find_prec(pid); if (prec) { PESProducer* pesprod = (PESProducer*) prec->prod; return pesprod->pes; } return NULL;}ProducerRecord* Encoder::add_prod (TS* ts, Producer* prod, ProdType t, int b){ ProducerRecord* prec = new ProducerRecord(ts, prod, t); prec->next_prec = head_prec; prec->stream_band = b; head_prec = prec; recalc_mux(); return prec;}void Encoder::delete_prod (int pid){ ProducerRecord* cur_prec = head_prec; ProducerRecord* prev_prec; while (cur_prec) { if (cur_prec->ts->pid == pid) { if (cur_prec == head_prec) { head_prec = head_prec->next_prec; } else { prev_prec->next_prec = cur_prec->next_prec; } delete cur_prec; return; } prev_prec = cur_prec; cur_prec = cur_prec->next_prec; } recalc_mux();}ProducerRecord* Encoder::find_prec (int pid){ ProducerRecord* prec = head_prec; while (prec) { if (prec == NULL) { sys_error("unexpected NULL prec"); } if (prec->ts->pid == pid) { return prec; } prec = prec->next_prec; } return NULL;}Producer* Encoder::get_prod (int pid){ ProducerRecord* prec = find_prec(pid); if (prec == NULL) return NULL; return prec->prod;}int Encoder::new_pid (){ static int counter = 16; return counter++;}int max (int a, int b){ return (a < b) ? b : a;}int Encoder::recalc_mux (){ // sum non-psi and non-null bandwidths int elem_total = 0; int npsi = 0; ProducerRecord* prec = head_prec; while (prec) { if (prec->type == ELEM) elem_total = elem_total + prec->stream_band; if (prec->type == PSI) npsi++; prec = prec->next_prec; } // calculate total psi and set psi bandwidths psi_rate = max(80, int(double(bitrate) / 300.0)); prec = head_prec; while (prec) { if (prec->type == PSI) prec->stream_band = psi_rate / npsi; prec->gap = (1.0 / (double(prec->stream_band) / double(bitrate))) - 1.0; prec = prec->next_prec; } // calculate null bandwidth if (elem_total + psi_rate > bitrate) { sys_error("stream bandwidth's is greater than total available"); } prec = find_prec(8191); prec->stream_band = bitrate - (elem_total + psi_rate); prec->gap = (1.0 / (double(prec->stream_band) / double(bitrate))) - 1.0; return 1;}ProducerRecord::ProducerRecord (TS* t1, Producer* p, ProdType t2){ ts = t1; type = t2; prod = p; pcr_flag = 0; next_prec = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -