Click here to Skip to main content
15,895,142 members
Articles / Programming Languages / C#

Sample speed test for Transport Stream construction

Rate me:
Please Sign up or sign in to vote.
3.47/5 (45 votes)
13 Apr 20044 min read 124.9K   1.9K   48  
A program that emulates the TS construction from ES files for the HDTV standard.
using System;
using System.IO;
using System.Windows.Forms;

namespace mpeg_tst
{
	
	public class solver
	{
		private int F_nr;		// nr. de fisiere
		private int B_len;		// lungimea buffer-ului in pachete pt. un fisier
		private int PES_HL;		// PES_Header_Length
		private int PES_PL;		// PES_Packet_Length
		private bool to_file;	// Tipul de output ( "File" sau "Emulated Network"

		private PES[][] buffer;  // buffer de pachete
		private int[][] table;	 // tabela de prioritati (nefolosita)
		private bool[][] empty;  // tabela de existenta  

		private TS output;			// Pachetul TS pt. scriere
		private FileStream[] file; // Vectorul fisierelor ES

		private int raw_data_len;  // Lungimea blocului ES
		private byte[] raw_data;   // Blocul ES

		private int[] pos_index;	// index de deplasare pt fiecare linie in buffer
		private int   line_index;	// index de linie(fisier) curent

		private bool[] data_left;	// flag pt. fisiere (a mai ramas info sau nu)
		private bool buffer_empty;	// flag pt. buffer underflow

		private bool pes_vs_ts;  // flag de indicare dc un pes > ts
		private int  packet_pos; // indicator de continuitate pt. cazul de mai sus
		private byte[] this_pes; // buffer pt. un pachet
		private int pes_len;     // lungimea unui PES
 
		private DateTime st=new DateTime();
		private DateTime end=new DateTime();
		private int time;

		public long[] mes=new long[1000000];
		public int nr_mes;
		public long ts_nr;
		

		//Constructorul pentru aceasta clasa - initializeaza toate valorile
		public void set_solver(int f,int b,int hl,int pl,bool dest)
		{
			int i,j;
			F_nr=f;B_len=b;PES_HL=hl;PES_PL=pl;to_file=dest;
			output=new TS();
			raw_data_len=PES_PL-3-PES_HL;
			raw_data=new Byte[raw_data_len];
			buffer=new PES[F_nr][];
			table=new int[F_nr][];
			empty=new bool[F_nr][];
			pos_index=new int[F_nr];
			this_pes=new byte[184];
			if (6+pl>188) pes_vs_ts=true;
			else pes_vs_ts=false;
			packet_pos=0;
			pes_len=6+pl;
			for(i=0;i<F_nr;i++) 
			{
				buffer[i]=new PES[B_len];
				table[i]=new int[B_len];
				empty[i]=new bool[B_len];
				pos_index[i]=0;
			}
			for(i=0;i<F_nr;i++)
				for(j=0;j<B_len;j++) buffer[i][j]=new PES(PES_HL,PES_PL);
			line_index=0;
			data_left=new bool[F_nr];
			file=new FileStream[F_nr];
			for(i=0;i<F_nr;i++) 
			{
				file[i]=new FileStream("ES_sample_"+i.ToString()+".es",FileMode.Open);
				data_left[i]=true;
			}
		}

		//Citeste date din fisier si le pune intr-un pachet PES in buffer
		public void put_PES_in_buffer(int lin,int col)
		{
				int cit,i;
			cit=file[lin].Read(raw_data,0,raw_data_len);
			if(cit==0) {data_left[lin]=false;empty[lin][col]=true;}
			else 
			{
				if(cit<raw_data_len)
					  for(i=cit;i<raw_data_len;i++) raw_data[i]=38; // '&'
				buffer[lin][col].set_Packet_Data(raw_data);
				buffer[lin][col].asemby_output();}
		}

		//Setarea initiala a buffer-ului	
		public void load_buffer()
		{
			int i,j;
			for(i=0;i<F_nr;i++) 
				for(j=0;j<B_len;j++) 
				{
					if(data_left[i])
					{
						put_PES_in_buffer(i,j);
						table[i][j]=j;
						empty[i][j]=false;
						buffer_empty=false;
					}
					else empty[i][j]=true;
				}
		}
				
		//Inchide toate fisierele			
		public void close_files()
		{
			for (int i=0;i<F_nr;i++) file[i].Close();
		}

		public void build_output_higher() // un PES > un TS
		{	int i,len;
			bool gol;
			output.reset_TS();
			
			if(packet_pos>0) 
			{ // mai e de transmis din PES-ul curent
				len=(pes_len<packet_pos+184)?pes_len-packet_pos:184;
				for(i=0;i<len;i++) this_pes[i]=buffer[line_index][pos_index[line_index]].PES_output[packet_pos+i];
				for(i=len;i<184;i++) this_pes[i]=33;
				output.add_data(this_pes);
				packet_pos=(packet_pos+len==pes_len)?0:packet_pos+len;
				if(packet_pos==0) 
				{
					put_PES_in_buffer(line_index,pos_index[line_index]);
					pos_index[line_index]=(pos_index[line_index]+1)%B_len;
					line_index=(line_index+1)%F_nr;
				}
			}
			else
			{// incepe un nou PES
				gol=empty[line_index][pos_index[line_index]];
				if (!gol)
				{
					for(i=0;i<184;i++)
						this_pes[i]=buffer[line_index][pos_index[line_index]].PES_output[i];
					packet_pos=184;
					output.add_data(this_pes);
				}
				else buffer_empty=true;
			}
			output.stuffing();
		}




		public void build_output_lower() // un TS > un PES
		{
			bool add_ok,gol;
			output.reset_TS();
			do 
			{
				gol=empty[line_index][pos_index[line_index]];
				if (!gol)
					add_ok=output.add_data(buffer[line_index][pos_index[line_index]].PES_output);
				else add_ok=false;
				if (add_ok)
				{
					put_PES_in_buffer(line_index,pos_index[line_index]);
					pos_index[line_index]=(pos_index[line_index]+1)%B_len;
					line_index=(line_index+1)%F_nr;
				}
			}
			while((add_ok)&&(!gol));
			if (gol) buffer_empty=true;			
			output.stuffing();
		}

		void time_calc()
		{long t1;
			t1=(end.Ticks-st.Ticks)/10;
			time=Convert.ToInt32(t1);
		}

		void act_prog(Sample unde,long nr)
		{
			int k=Convert.ToInt16(nr*100/unde.est_TS_packs);
			unde.ts_prg.Value=(k>100)?100:k;
			if(nr_mes<1000000)
			{
				mes[nr_mes]=(DateTime.Now.Ticks-st.Ticks)/10000;
				nr_mes++;
			}
		}

//Functia principala a clasei ce construieste Transport Stream-ul pachet cu pachet
//Functia se termina in caz de buffer underrun -> nu mai exista date de transmis
		public int simulation(Sample father)
		{	
			FileStream OUT;

			OUT=new FileStream("./result.ts",FileMode.Create);
			load_buffer();
			ts_nr=0;
			nr_mes=0;
			st=DateTime.Now;
			while (!buffer_empty)
			{
				if(pes_vs_ts) build_output_higher();
				else build_output_lower();
				if(!buffer_empty)
				{
					output.asembly_output();
					if(to_file)
						OUT.Write(output.TS_output,0,output.TS_output.Length);
				}
				ts_nr++;
				if (ts_nr%100==0) act_prog(father,ts_nr);
			}
			end=DateTime.Now;
			if(!to_file)
				OUT.Write(output.TS_output,0,output.TS_output.Length);
			OUT.Close();
			close_files();
			time_calc();
			father.TS_packs=ts_nr;
			return time;
		}

		
	
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Malaysia Malaysia
Dumitru Bogdan - alias Angel

Born 1980 , Brasov , Romania

Final year student at Transilvania University of Brasov , Faculty of Electrical Engineering & Computer Science , Department of Electronics & Computers

Programming : Visual C++ , Visual Fox Pro , Assembler & later , C#

Motto : "Nothing Last Forever" , and software is no exception

Comments and Discussions