欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

ts2secpes.c

dvbsnoop is a DVB/MPEG stream analyzer program. The program can be used to sniff, monitor, debug, d
C
字号:
/*$Id: ts2secpes.c,v 1.6 2004/04/18 19:30:32 rasc Exp $ DVBSNOOP a dvb sniffer  and mpeg2 stream analyzer tool http://dvbsnoop.sourceforge.net/ (c) 2001-2004   Rainer.Scherg@gmx.de -- Transport Stream Sub-Decode  PES / SECTION   $Log: ts2secpes.c,v $Revision 1.6  2004/04/18 19:30:32  rascTransport Stream payload sub-decoding (Section, PES data) improvedRevision 1.5  2004/04/15 23:22:58  rascno messageRevision 1.4  2004/04/15 22:29:23  rascPMT: some brainded section checkTS: filter single pids from multi-pid ts-input-fileminor enhancementsRevision 1.3  2004/04/15 10:53:22  rascminor changesRevision 1.2  2004/04/15 04:08:49  rascno messageRevision 1.1  2004/04/15 03:40:39  rascnew: TransportStream sub-decoding (ts2PES, ts2SEC)  [-tssubdecode]checks for continuity errors, etc. and decode in TS enclosed sections/pes packets*/#include "dvbsnoop.h"#include "ts2secpes.h"#include "sections/sectables.h"#include "pes/pespacket.h"#include "misc/packet_mem.h"#include "misc/output.h"#define TS_SUBDEC_BUFFER   (128*1024)enum  { TSD_no_error = 0, TSD_output_done,	TSD_no_pui, TSD_error, TSD_continuity_error,	TSD_scrambled_error, TSD_pid_change, TSD_mem_error};typedef struct _TS_SUBDEC {	int	mem_handle;	int	pid;	int     status;			// content is invalid?	int     continuity_counter;	// 4 bit max !!	int     packet_counter;	int	payload_length;		// total length of PES or SECTION to be read, 0 = unspecified} TS_SUBDEC;static  TS_SUBDEC  tsd;//------------------------------------------------------------ //// -- init TS sub decoding buffer// -- return: < 0: fail//int ts2SecPesInit (void){  tsd.mem_handle = packetMem_acquire (TS_SUBDEC_BUFFER);  tsd.pid = -1;  tsd.status = TSD_no_pui;  tsd.continuity_counter = -1;  tsd.packet_counter = 0;  tsd.payload_length = 0;  return tsd.mem_handle;}//// -- free TS sub decoding buffer//void ts2SecPesFree (void){  packetMem_free (tsd.mem_handle);}//// -- add TS data // -- return: 0 = fail//int ts2SecPes_AddPacketStart (int pid, int cc, u_char *b, u_int len){    int l;    // -- duplicate packet ?    if ((pid == tsd.pid) && (cc == tsd.continuity_counter)) {	    return 1;    }    tsd.status = TSD_no_error;    tsd.pid = pid;    tsd.continuity_counter = cc;    tsd.packet_counter = 1;    // -- Save PES or SECTION length information of incoming packet    // -- set 0 for unspecified length    l = 0;    if (len > 6) {	if (b[0]==0x00 && b[1]==0x00 && b[2]==0x01 && b[3]>=0xBC) {		l = (b[4]<<8) + b[5];		// PES packet size...		if (l) l += 6;			// length with PES-sync, etc.    	} else {		int pointer = b[0]+1;		if (pointer+3 <= len) {	// not out of this packet?			l = ((b[pointer+1] & 0x0F) << 8) + b[pointer+2]; // sect size		}		if (l) l += pointer + 3;	// length with pointer & tableId    	}    }    tsd.payload_length = l;    packetMem_clear (tsd.mem_handle);    if (! packetMem_add_data (tsd.mem_handle,b,len)) {	tsd.status = TSD_mem_error;	return 0;    }        return 1;}int ts2SecPes_AddPacketContinue (int pid, int cc, u_char *b, u_int len){    // -- duplicate packet?  (this would be ok, due to ISO13818-1)    if ((pid == tsd.pid) && (cc == tsd.continuity_counter)) {	    return 1;    }    // -- pid change in stream? (without packet start)    // -- This is currently not supported   $$$ TODO    if ((tsd.status == TSD_no_error) && (pid != tsd.pid)) {	tsd.status = TSD_pid_change;    }    // -- discontinuity error in packet ?    if ((tsd.status == TSD_no_error) && (cc != (++tsd.continuity_counter%16))) {	tsd.status = TSD_continuity_error;    }    if (tsd.status == TSD_no_error) {	if (!packetMem_add_data (tsd.mem_handle,b,len) ) {		tsd.status = TSD_mem_error;	} else {    		tsd.packet_counter++;	  	return 1;	}    }    return 0;}//------------------------------------------------------------ //// -- TS  SECTION/PES  subdecoding// -- check TS buffer and push data to sub decoding buffer// -- on new packet start, output old packet data//void ts2SecPes_subdecode (u_char *b, int len, u_int opt_pid){    u_int  transport_error_indicator;		    u_int  payload_unit_start_indicator;		    u_int  pid;		    u_int  transport_scrambling_control;		    u_int  continuity_counter;		    u_int  adaptation_field_control;  pid				 = getBits (b, 0,11,13); // -- filter pid? if (opt_pid >= 0 && opt_pid <= MAX_PID) {	 if (opt_pid != pid)  return; }  transport_error_indicator	 = getBits (b, 0, 8, 1); payload_unit_start_indicator	 = getBits (b, 0, 9, 1); transport_scrambling_control	 = getBits (b, 0,24, 2); adaptation_field_control	 = getBits (b, 0,26, 2); continuity_counter		 = getBits (b, 0,28, 4); len -= 4; b   += 4; // -- skip adaptation field if (adaptation_field_control & 0x2) {	int n;	n = b[0] + 1;	b += n;	len -= n; } // -- push data to subdecoding collector buffer // -- on packet start, output collected data of buffer if (adaptation_field_control & 0x1) {	// -- payload buffering/decoding	// -- oerks, this we cannot use	if (transport_scrambling_control || transport_error_indicator) {		tsd.status = TSD_scrambled_error;		return;	}	// -- if payload_start, check PES/SECTION	if (payload_unit_start_indicator) {		// -- output data of prev. collected packets		// -- if not already decoded or length was unspecified     		if ((tsd.status != TSD_output_done) && packetMem_length(tsd.mem_handle))  {			ts2SecPes_Output_subdecode ();		}		// -- first buffer data		ts2SecPes_AddPacketStart (pid, continuity_counter, b, (u_long)len);	} else {		// -- add more data		ts2SecPes_AddPacketContinue (pid, continuity_counter, b, (u_long)len);	} }}//// -- check if TS packet should already be sent to sub-decoding and output... // -- if so, do sub-decoding and do output// -- return: 0 = no output, 1 = output done//int  ts2SecPes_checkAndDo_PacketSubdecode_Output (void){	// -- already read all data? decode & output data...	if ( (tsd.payload_length) && (tsd.payload_length <= packetMem_length(tsd.mem_handle)) ) {     		if (tsd.status != TSD_output_done) {			ts2SecPes_Output_subdecode ();			return 1;		}	}	return 0;}//// -- TS  SECTION/PES  subdecoding  output//void ts2SecPes_Output_subdecode (void){     indent (+1);     out_NL (3);     if (tsd.pid > MAX_PID) {     	out_nl (3,"TS sub-decoding (%d packet(s)):", tsd.packet_counter);     } else {     	out_nl (3,"TS sub-decoding (%d packet(s) stored for PID 0x%04x):",			tsd.packet_counter,tsd.pid & 0xFFFF);     }     out_nl (3,"=====================================================");     if (tsd.status != TSD_no_error) {   	char *s = "";	switch (tsd.status) {	   case TSD_error:  		s = "unknown packet error"; break;	   case TSD_no_pui:  		s = "no data collected, no payload start"; break;	   case TSD_continuity_error:  	s = "packet continuity error"; break;	   case TSD_scrambled_error:  	s = "packet scrambled or packet error"; break;	   case TSD_pid_change:  	s = "PID change in TS stream"; break;	   case TSD_mem_error:  	s = "subdecoding buffer (allocation) error"; break;	   case TSD_output_done:  	s = "[data already displayed (this should never happen)]"; break;	}     	out_nl (3,"Packet cannot be sub-decoded: %s",s);     } else {   	u_char *b;	u_int  len;	b   = packetMem_buffer_start (tsd.mem_handle);	len = (u_int) packetMem_length (tsd.mem_handle);	if (b && len) {	    // -- PES or SECTION	    if (b[0]==0x00 && b[1]==0x00 && b[2]==0x01 && b[3]>=0xBC) {		out_nl (3,"TS contains PES stream...");	    	indent (+1);		decodePES_buf (b, len, tsd.pid);	    	indent (-1);	    } else {		int pointer = b[0]+1;		b += pointer;		out_nl (3,"TS contains Section...");	    	indent (+1);		decodeSections_buf (b, len-pointer, tsd.pid);	    	indent (-1);	    }	} else {		out_nl (3,"No prev. packet start found...");	}     }     out_NL (3);     out_NL (3);     indent (-1);     tsd.status = TSD_output_done;}// // $$$ TODO:// sections: pui-start && pointer != 0 push data to last section????...//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -