예제 #1
0
static int AddChannelList( CHANNEL_LIST *pChannelList, CHANNEL_DATA *pChannelData, TUNE_LIST *pTuneList )
{
	int i, updated = 0;

	if ( pChannelData->stream_format == ATSC_STREAM )
	{
		for ( i = 0; i<pChannelData->num_channel; i++ )
		{
			if ( IsInATSCChannelList( pChannelList, pChannelData->u.atsc[i].major_num
												  , pChannelData->u.atsc[i].minor_num
												  , pChannelData->u.atsc[i].program_id ) )
			   continue;

			if ( pChannelData->sub_format == CABLE && pChannelData->u.atsc[0].u.qam.modulation == 0xfe ) //analog modualtion
				continue;

			//expend channel list
			if ( pChannelList->total_list_num < pChannelData->num_channel )
				ExpendChannelList( pChannelList, 5 );

			if ( pChannelData->u.atsc[i].major_num == 1008 && pChannelData->u.atsc[i].minor_num == 0 )
			{
				SageLog(( _LOG_TRACE, 2, "Drop invalid channel %d name:%s major:%d minor:%d prog:%d  service:%d!", i, 
			 			pChannelData->u.atsc[i].name, pChannelData->u.atsc[i].major_num,
						pChannelData->u.atsc[i].minor_num, pChannelData->u.atsc[i].program_id,
						pChannelData->u.atsc[i].service_type  ));
				continue;
			}

			pChannelList->channel[pChannelList->channel_num].u.atsc  = pChannelData->u.atsc[i];
			pChannelList->channel[pChannelList->channel_num].u.atsc.physical_ch = pChannelData->u.atsc[0].physical_ch;
			pChannelList->channel[pChannelList->channel_num].state = 3;
			pChannelList->channel_num++;
			SageLog(( _LOG_TRACE, 2, "found ATSC channel %d name:%s major:%d minor:%d prog:%d  service:%d", i, 
			 			pChannelData->u.atsc[i].name, pChannelData->u.atsc[i].major_num,
						pChannelData->u.atsc[i].minor_num, pChannelData->u.atsc[i].program_id,
						pChannelData->u.atsc[i].service_type  ));
			updated = 1;
		}


	} else
	if ( pChannelData->stream_format == DVB_STREAM )
	{
		SageLog(( _LOG_TRACE, 2, "ERROR: Unimplmented yet" ));
	}

	return updated;
}
예제 #2
0
//
// Destructor
//
CTSParserFilter::~CTSParserFilter()
{

	SageLog(( _LOG_TRACE, 3, TEXT("*********** CTSParserFilter was releasing...") )); 
	if ( m_hDebugFileSource != NULL )
		fclose( m_hDebugFileSource );

	try
	{
	    if ( m_pInputPin )
			delete m_pInputPin;
	}
	catch ( ... )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("*********** ERROR: catch an error on deconstruct InputPin")  )); 
	}

	try 
	{
		if ( m_pOutputPin )
			delete m_pOutputPin;
	}
	catch ( ... )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("*********** ERROR: catch an error on deconstruct OuputPin")  )); 
	}

    if ( m_pAudioPin )
		delete m_pAudioPin;

    if ( m_pVideoPin )
		delete m_pVideoPin;

    if ( m_pPassThrusPin )
		delete m_pPassThrusPin;

	try {
		if ( m_pDumpPin )
			delete m_pDumpPin;
	}
	catch ( ... )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("*********** ERROR: catch an error on deconstruct DumpPin")  )); 
	}

	SageLog(( _LOG_TRACE, 3, TEXT("*********** CTSParserFilter was released") )); 

} 
예제 #3
0
int PushTSChannelPacketParser( TS_CHANNEL_PARSER *pTSChannelParser, uint8_t* pData, int nSize )
{
	int used_bytes = 0, size = nSize;
	uint8_t* data = pData;

	while ( size >= TS_PACKET_LENGTH )
	{
		int ret;

		if ( *data != TS_SYNC ) //sync header
		{
			for (  ; size>TS_PACKET_LENGTH && *(data) != TS_SYNC ; size--, data++ )
				used_bytes++;

			if ( size < TS_PACKET_LENGTH )
			{
				SageLog(( _LOG_ERROR, 3, TEXT("ERROR: TS SYNC header is lost!") ));
				return used_bytes;
			}
		}

		ret = TSProcessInfo( pTSChannelParser->ts_filter, data  ); //must to be 188 bytes of data

		data += TS_PACKET_LENGTH;
		size -= TS_PACKET_LENGTH;
		used_bytes += TS_PACKET_LENGTH;
	}

	return used_bytes;
}
예제 #4
0
static int AddProgrmToList( PROGRAM_LIST *pProgramList, uint16_t nTsid, uint16_t nProgramId, uint16_t nChannel, int service )
{
	int i;
	if ( nProgramId == 0xffff ) 
		return -3;

	if ( pProgramList->program_num >= pProgramList->total_list_num )
	{
		SageLog(( _LOG_TRACE, 2, "WARING: program list is overflow, drop program %d", nProgramId ) );
		return -2;
	}

	for ( i = 0; i<pProgramList->program_num; i++ )
	{
		if ( pProgramList->program[i].program_id == nProgramId && pProgramList->program[i].tsid == nTsid )
			return -1;
	}

	pProgramList->program[i].channel = (uint8_t)nChannel;
	pProgramList->program[i].program_id = nProgramId;
	pProgramList->program[i].tsid = nTsid;
	pProgramList->program[i].service = service;
	pProgramList->program_num++;
	return i;
}
예제 #5
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
void SetupEPGDumpLanguage( void* Handle, unsigned long lLanguageCode )
{
	REMUXER *pRemuxer = (REMUXER *)Handle;
	if ( pRemuxer->demuxer->ts_parser )
		SetupTSEPGDumpLanguage( pRemuxer->demuxer->ts_parser, lLanguageCode );
	SageLog(( _LOG_ERROR, 3, TEXT("Set default EPG language \"%s\"."), Language(lLanguageCode, NULL )  ));
}
예제 #6
0
static char* _print_es_descriptor_( unsigned short pid, unsigned char* p, int bytes )
{
	static char buf[1024]={0}; 
	unsigned char tag; 
	int len;
	int i=0, pos;
	if ( bytes == 0 ) return "";
	pos = snprintf( buf, sizeof(buf), "\t\tPid:0x%02x descriptor(%02d) ", pid, bytes );
	while ( i+2 <= bytes ) 
	{
		tag = p[i];
		len = p[i+1];
		if ( tag == REGISTRATION_DESC )
		{
			char tmp[16]={0};
			memcpy( tmp, p+2, _MIN( sizeof(tmp)-1, len) );
			pos += snprintf( buf+pos, sizeof(buf)-pos, "%s(%s) ", _look_up_tag_name_(tag),  tmp );
		} else
			pos += snprintf( buf+pos, sizeof(buf)-pos, "%s(%d) ", _look_up_tag_name_(tag), len );
		i += 2+len;
		if ( pos > sizeof(buf)-1 ) break;

	}
	SageLog(( _LOG_TRACE, 3, TEXT("%s"), buf ));
	return buf;
}
예제 #7
0
void DisableParseData( TS_INFO_PARSER *pTSInfoParser )
{
	pTSInfoParser->ts_filter->disable_ts_table_parse = 1;
	pTSInfoParser->ts_filter->disable_stream_filter = 1;
	SageLog(( _LOG_TRACE, 3, TEXT("TS Filter table and stream data parser disabled") ));
	return;
}
예제 #8
0
void ResetTSInfoParser( TS_INFO_PARSER *pTSInfoParser )
{
	int i;
	ResetTSFilter( pTSInfoParser->ts_filter );
	pTSInfoParser->ts_filter->disable_ts_table_parse = 0;
	pTSInfoParser->ts_filter->disable_stream_filter = 0;
	SageLog(( _LOG_TRACE, 3, TEXT("TS Info Parser is reset  .") ));
	pTSInfoParser->state = 0;
	for ( i = 0; i<pTSInfoParser->max_stream_num; i++ )
	{
		pTSInfoParser->es_buffer[i].bytes = 0;
		pTSInfoParser->es_buffer[i].main_track = -1;
		pTSInfoParser->es_buffer[i].input_bytes = 0;
		pTSInfoParser->es_buffer[i].stream_id = 0;
	}
	pTSInfoParser->ts_streams.num_stream = 0;
	pTSInfoParser->es_streams.num_stream = 0;
	pTSInfoParser->av_streams.num_stream = 0;
	memset( pTSInfoParser->ts_streams.ts_element, 0, pTSInfoParser->max_stream_num*sizeof(TS_ELEMENT) );
	memset( pTSInfoParser->es_streams.es_element, 0, pTSInfoParser->max_stream_num*sizeof(ES_ELEMENT) );
	memset( pTSInfoParser->av_streams.av_element, 0, pTSInfoParser->max_stream_num*sizeof(AV_ELEMENT) );
	pTSInfoParser->avinf[0] = 0x0;
	pTSInfoParser->avinf_size = 0;
	pTSInfoParser->total_bytes = 0;
	pTSInfoParser->total_video_num = 0;
	pTSInfoParser->total_audio_num = 0;
	pTSInfoParser->found_video_num = 0;
	pTSInfoParser->found_audio_num = 0;
	pTSInfoParser->utc_sec_start = 0;
	pTSInfoParser->pcr_sec_start = 0;
	memset( &pTSInfoParser->tune, 0x0, sizeof(pTSInfoParser->tune) );
}
예제 #9
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
int CreateFileOutputW( REMUXER *pRemuxer, wchar_t* pFileName, int nOutputFormat, int nMaxTrackNum)
{
	//pRemuxer->output_file = fopen( pFileName, "wb" );
#ifdef WIN32	
	//pRemuxer->output_file  = FOPEN( pFileName, _O_WRONLY|_O_BINARY|_O_CREAT, _SH_DENYNO , _S_IREAD|_S_IWRITE );
	pRemuxer->output_file = _wsopen( (wchar_t*)pFileName, _O_RDONLY|_O_BINARY, _SH_DENYNO , _S_IREAD|_S_IWRITE );
#else
	pRemuxer->output_file  = open( (char*)pFileName, O_WRONLY|O_CREAT, 0666 );
#endif	

	if ( pRemuxer->output_file )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("Output file %s"), pFileName ));
	} else
		return 0;

	pRemuxer->output_track[0] = CreateTracks(nMaxTrackNum);
	pRemuxer->output_track[0]->track_type = nOutputFormat;
	if ( IS_PS_TYPE( nOutputFormat ) )
	{
		int build_header_in_buffer; //if es block has space to build a PACK+PES
		build_header_in_buffer = SourceIsTSType( pRemuxer->demuxer );
		pRemuxer->ps_builder = CreatePSBuilder( pRemuxer->output_track[0], ES_PACKET_SIZE, build_header_in_buffer );
		pRemuxer->ps_builder->dumper.stream_dumper = (DUMP)PSOutputDataFileDumper;
		pRemuxer->ps_builder->dumper.stream_dumper_context = pRemuxer;
	} else
	if ( IS_TS_TYPE(nOutputFormat) )
	{
		pRemuxer->ts_builder = CreateTSBuilder( pRemuxer->output_track[0], nOutputFormat );
		pRemuxer->ts_builder->dumper.stream_dumper = (DUMP)TSOutputDataFileDumper;
		pRemuxer->ts_builder->dumper.stream_dumper_context = pRemuxer;
	}
	return 1;
}
예제 #10
0
void ResetTSChannelParser( TS_CHANNEL_PARSER *pTSChannelParser )
{
	int i;
	ResetTSFilter( pTSChannelParser->ts_filter );
	pTSChannelParser->ts_filter->disable_ts_table_parse = 0;
	pTSChannelParser->ts_filter->disable_stream_filter = 0;
	SageLog(( _LOG_TRACE, 3, TEXT("TS Channel Parser is reset  .") ));
	pTSChannelParser->state = 0;
	for ( i = 0; i<pTSChannelParser->max_stream_num; i++ )
	{
		pTSChannelParser->es_buffer[i].bytes = 0;
		pTSChannelParser->es_buffer[i].main_track = -1;
		pTSChannelParser->es_buffer[i].input_bytes = 0;
		pTSChannelParser->es_buffer[i].stream_id = 0;
	}
	pTSChannelParser->ts_streams.num_stream = 0;
	pTSChannelParser->es_streams.num_stream = 0;
	pTSChannelParser->av_streams.num_stream = 0;
	memset( pTSChannelParser->ts_streams.ts_element, 0, pTSChannelParser->max_stream_num*sizeof(TS_ELEMENT) );
	memset( pTSChannelParser->es_streams.es_element, 0, pTSChannelParser->max_stream_num*sizeof(ES_ELEMENT) );
	memset( pTSChannelParser->av_streams.av_element, 0, pTSChannelParser->max_stream_num*sizeof(AV_ELEMENT) );
	pTSChannelParser->avinf[0] = 0x0;
	pTSChannelParser->avinf_size = 0;
	pTSChannelParser->total_bytes = 0;
	pTSChannelParser->total_video_num = 0;
	pTSChannelParser->total_audio_num = 0;
	pTSChannelParser->found_video_num = 0;
	pTSChannelParser->found_audio_num = 0;

	pTSChannelParser->channel_list.channel_num = 0;
	pTSChannelParser->program_list.program_num = 0;
	pTSChannelParser->program_list.flag = 0;
	pTSChannelParser->program_list.drop_program_num = 0;
}
예제 #11
0
static int PMTDumper( void* pContext, uint8_t* pData, int nSize )
{
	TS_CHANNEL_PARSER *pTSChannelParser = (TS_CHANNEL_PARSER*)pContext;
	PMT_DATA  *pPmtData  = (PMT_DATA*)pData;
	TS_PMT    *pPmt      = (TS_PMT*)pPmtData->pmt_table;
	//TS_SECTION *pPmtSection = pPmtData->pmt_section;
	int channel = pPmtData->channel;
	//int channel_num = pPmtData->total_channel_num;
	int stream_num  = pPmt->total_stream_number;
	int i, encrypted = 0, valid_stream = 0;

	ASSERT( pContext != NULL );
	ASSERT( (nSize == sizeof(PMT_DATA)) );

	if ( stream_num == 0 )		return 1;

	if ( (pPmtData->update_flag & PMT_UPDATED) ) //skip unchanged PMT
	{
		SageLog(( _LOG_TRACE, 3, TEXT("\tChannel:%d (tsid:%d) PMT pid:0x%04x Program:%04d PCR pid:0x%04x %s."),  channel, 
			pPmtData->tsid, pPmtData->pid, pPmt->program_number, pPmt->pcr_pid, pPmt->ca_pid ? CAInfo( pPmt->ca_pid, pPmt->ca_id) :"" ));
		for ( i = 0; i< stream_num; i++ )
		{	
			int has_ca_desc = HasCADesc( pPmt->stream_desc[i].desc_ptr, pPmt->stream_desc[i].desc_bytes )? 1 : 0;
			if ( has_ca_desc ) 
				encrypted++;
			if ( IsVideoType( pPmt->stream_type[i] ) || IsAudioType( pPmt->stream_type[i] ) ) 
				valid_stream++;
			SageLog(( _LOG_TRACE, 3,  TEXT("\t\tType:0x%02x Pid:0x%03x  %s"), pPmt->stream_type[i], pPmt->stream_pid[i], has_ca_desc?"encrypted":" " ));
		}

		//PMT updated and repersent, we need reselect channel to change filter
		if ( ( pPmtData->update_flag & PMT_REPEAT ))
		{
			SageLog(( _LOG_TRACE, 3,  TEXT("PMT Updated, reselect channel" ) ));
		}
	}
	
	if ( pPmt->ca_pid == 0 && encrypted == 0 && valid_stream > 0 )
	{
		if ( AddProgrmToList( &pTSChannelParser->program_list, pPmtData->tsid, pPmt->program_number, pPmtData->channel, 1 ) >= 0 )
		{
			SageLog(( _LOG_TRACE, 3, TEXT("Uncrypted channel is found (channel:%d program:%d tsid:%d)."), pPmtData->channel, pPmt->program_number, pPmtData->tsid ));
		} 
	}

	return 1;
}
예제 #12
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
static void _display_av_inf( TRACKS *pTracks )
{
	//int slot_index = 0;
	char avinf[1024];

	TracksInfo( pTracks, avinf, sizeof(avinf) );
	SageLog(( _LOG_TRACE, 3, TEXT("INPUT-AVINF|%s"), avinf ));
}
예제 #13
0
static int PATDumper( void* pContext, uint8_t* pData, int nSize )
{
	TS_CHANNEL_PARSER *pTSChannelParser = (TS_CHANNEL_PARSER*)pContext;
	PAT_DATA  *pPatData  = (PAT_DATA*)pData;
	TS_PAT    *pPat      = (TS_PAT*)pPatData->pat_table;
	int16_t pat_index = pPatData->pat_index;
	uint16_t tsid  = pPat->tsid;
	int program_num = pPat->total_program_number;
	int i, tsid_locked=0;

	ASSERT( pContext != NULL );
	ASSERT( nSize == sizeof(PAT_DATA) );

	if ( (pTSChannelParser->state & PROGRAM_FOUND) ) 
	{
		return 0;
	}

	SageLog(( _LOG_TRACE, 3, TEXT("PAT-%d:Program (total channel:%d, tsid:%d )"), pat_index, program_num, tsid ));
	for ( i = 0; i<program_num; i++ )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("\tPMT pid:0x%04x program:%04d"), pPat->program_pid[i], pPat->program_number[i] ));
		if ( pPat->program_number[i] >= 0 )
		{
			SageLog(( _LOG_TRACE, 3, TEXT("program %d is added into pid table (%d)"), pPat->program_number[i], i));
			{
				PID_ITEM pid_inf;
				pid_inf.pid = pPat->program_pid[i];
				pid_inf.type = PID_TYPE_PROGRAM;
				pid_inf.service = 0;
				pTSChannelParser->dumper.pid_dumper( pTSChannelParser->dumper.pid_dumper_context, &pid_inf, sizeof(pid_inf) );
				pTSChannelParser->state |= PROGRAM_FOUND;
			}
		}
	}
	
	tsid_locked = CheckTsId( pTSChannelParser, tsid )>0;
	if ( tsid_locked )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("tsid %d is locked (%d)"), tsid, i));
		pTSChannelParser->state |= TSID_LOCKED;
		return 1;
	}
	return 0;
}
예제 #14
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
void CloseRemuxStream( void* Handle )
{
	REMUXER *pRemuxer = (REMUXER *)Handle;

	FlushRemuxer( pRemuxer, 0 );
	ReleaseStreamOutput( pRemuxer );
	CloseStreamSource( pRemuxer->demuxer );
	ReleaseRemuxer( pRemuxer );
	SageLog(( _LOG_ERROR, 3, TEXT("Remuxer was released." ) ));
}
예제 #15
0
파일: Scan.cpp 프로젝트: BOTCrusher/sagetv
CScan::~CScan(void)
{
	if ( m_pScan != NULL )
	{
		if ( m_hScanCacheDataFile > 0 )
			FCLOSE( m_hScanCacheDataFile );
		SageLog(( _LOG_TRACE, 3, TEXT("*********** ChanneScan tuner close: data:%d File data:%d"), 
					m_dwScanTunerData, m_dwScanFileData  ));
		ReleaseChannelScan( m_pScan );
	}
}
예제 #16
0
파일: Scan.cpp 프로젝트: BOTCrusher/sagetv
void CScan::CloseChannelScan( )
{
	if ( m_hScanCacheDataFile > 0 )
	{
		FCLOSE( m_hScanCacheDataFile );
		m_hScanCacheDataFile = 0;
	}
	SageLog(( _LOG_TRACE, 3, TEXT("*********** ChanneScan tuner close: data:%d File data:%d"), 
				m_dwScanTunerData, m_dwScanFileData  ));
	ReleaseChannelScan( m_pScan );
	m_pScan = NULL;
}
예제 #17
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
static void _output_statistic( REMUXER *pRemuxer )
{
	int i;
	if ( pRemuxer->ps_builder != NULL )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("Total output blocks:%d; processed total data:%d "), 
				pRemuxer->ps_builder->output_blocks, pRemuxer->ps_builder->output_bytes ));
		for ( i = 0; i<MAX_TRACK_NUM; i++ )
		{
			if ( pRemuxer->output_track[0]->track[i].es_elmnt &&  pRemuxer->output_track[0]->track[i].es_elmnt->es_id )
			{
				SageLog(( _LOG_TRACE, 3, TEXT("\tes:%d es blocks:%d"), i,
						pRemuxer->output_track[0]->track[i].es_blocks_counter ));
			}
		}
		if ( pRemuxer->ps_builder->out_of_order_blocks )
		{
			SageLog(( _LOG_TRACE, 3, TEXT("out_of_order_blocks in FIFO buffer:%d "), pRemuxer->ps_builder->out_of_order_blocks  ));
		}

	} else
	if ( pRemuxer->ts_builder != NULL )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("Total output blocks:%d; packet:%d; processed total data:%d "), 
				pRemuxer->ts_builder->output_blocks, pRemuxer->ts_builder->output_packets,
				pRemuxer->ts_builder->output_bytes ));
		for ( i = 0; i<MAX_TRACK_NUM; i++ )
		{
			if ( pRemuxer->output_track[0]->track[i].es_elmnt &&  pRemuxer->output_track[0]->track[i].es_elmnt->es_id )
			{
				SageLog(( _LOG_TRACE, 3, TEXT("\tes:%d: ts packects :%d; es blocks:%d"), i,
						pRemuxer->output_track[0]->track[i].ts_packets_counter,
						pRemuxer->output_track[0]->track[i].es_blocks_counter ));
			}
		}
	}

}
예제 #18
0
static int InitScanData(  TS_CHANNEL_PARSER *pTSChannelParser, int nStreamType, int nSubType )
{
	pTSChannelParser->stream_format = nStreamType;
	pTSChannelParser->sub_format = nSubType;
	pTSChannelParser->tune_list.stream_format = nStreamType;
	pTSChannelParser->tune_list.sub_format = nSubType;
	pTSChannelParser->channel_list.stream_format = nStreamType;
	pTSChannelParser->channel_list.sub_format = nSubType;
	pTSChannelParser->program_list.stream_format = nStreamType;
	pTSChannelParser->program_list.sub_format = nSubType;
	//pTSChannelParser->maxium_psi_checking_bytes = MaxPSICheckBytes( nStreamType, nSubType );
	//pTSChannelParser->psi_timeout = MaxPSICheckTimeOut( nStreamType, nSubType );
	pTSChannelParser->channel_list.channel_num = 0;
	pTSChannelParser->program_list.program_num = 0;
	pTSChannelParser->program_list.drop_program_num = 0;
	pTSChannelParser->program_list.flag = 0;

	if ( nStreamType == DVB_STREAM )
	{
		SageLog((  _LOG_ERROR, 3, "DVB Stream isn't support yet" ));
	} else
	if ( nStreamType == ATSC_STREAM )
	{
		if ( nSubType == TERRESTRIAL ) //ATSC
		{
			if ( pTSChannelParser->channel_list.channel == NULL )
			{
				pTSChannelParser->channel_list.total_list_num = MAX_ATSC_CHANNEL_NUM;
				pTSChannelParser->channel_list.channel = SAGETV_MALLOC( sizeof(CHANNEL_DAT)*pTSChannelParser->channel_list.total_list_num );
				pTSChannelParser->program_list.total_list_num = MAX_ATSC_CHANNEL_NUM+10;
				pTSChannelParser->program_list.program = SAGETV_MALLOC( sizeof(PROGRAM_DAT)*pTSChannelParser->program_list.total_list_num );
				return 1;
			}

		} else
		if ( nSubType == CABLE ) //QAM
		{
			if ( pTSChannelParser->channel_list.channel == NULL )
			{
				pTSChannelParser->channel_list.total_list_num = MAX_QAM_CHANNEL_NUM ;
				pTSChannelParser->channel_list.channel = SAGETV_MALLOC( sizeof(CHANNEL_DAT)*pTSChannelParser->channel_list.total_list_num );
				pTSChannelParser->program_list.total_list_num = MAX_QAM_CHANNEL_NUM +10;
				pTSChannelParser->program_list.program = SAGETV_MALLOC( sizeof(PROGRAM_DAT)*pTSChannelParser->program_list.total_list_num );
				return 1;
			}
		} 
	}

	return 0;
}
예제 #19
0
void ReleaseTSInfoParser( TS_INFO_PARSER *pTSInfoParser )
{
	int i;
	SAGETV_FREE( pTSInfoParser->ts_streams.ts_element );
	SAGETV_FREE( pTSInfoParser->es_streams.es_element );
	SAGETV_FREE( pTSInfoParser->av_streams.av_element );
	for ( i = 0; i<pTSInfoParser->max_stream_num; i++ )
		SAGETV_FREE( pTSInfoParser->es_buffer[i].buffer );
	SAGETV_FREE( pTSInfoParser->es_buffer );
	ReleaseTSFilter( pTSInfoParser->ts_filter );
	SAGETV_FREE( pTSInfoParser );

	SageLog(( _LOG_TRACE, 3, TEXT("TS Info Parser is released  .") ));
}
예제 #20
0
TS_INFO_PARSER* CreateTSInfoParser( int nMaxStreamNum, int nStreamFormat, int nSubFormat )
{
	int i;
	TS_INFO_PARSER *pTSInfoParser = SAGETV_MALLOC( sizeof(TS_INFO_PARSER) );
	pTSInfoParser->ts_filter = CreateTSFilter( DEFAULT_PAT_NUM, DEFAULT_PMT_NUM, nStreamFormat, nSubFormat ); //ATSC_STREAM, TERRESTRIAL;
	pTSInfoParser->max_stream_num = nMaxStreamNum;
	pTSInfoParser->ts_streams.ts_element = SAGETV_MALLOC( nMaxStreamNum*sizeof(TS_ELEMENT) );
	pTSInfoParser->ts_streams.total_streams = nMaxStreamNum;
	pTSInfoParser->es_streams.es_element = SAGETV_MALLOC( nMaxStreamNum*sizeof(ES_ELEMENT) );
	pTSInfoParser->es_streams.total_streams = nMaxStreamNum;
	pTSInfoParser->av_streams.av_element = SAGETV_MALLOC( nMaxStreamNum*sizeof(AV_ELEMENT) );
	pTSInfoParser->av_streams.total_streams = nMaxStreamNum;
	pTSInfoParser->es_buffer = SAGETV_MALLOC( nMaxStreamNum*sizeof(ES_BUFFER) );
	for ( i = 0; i<nMaxStreamNum; i++ )
	{
		pTSInfoParser->es_buffer[i].buffer = SAGETV_MALLOC( TMP_ES_BUFFER_SIZE );
		pTSInfoParser->es_buffer[i].buffer_size = TMP_ES_BUFFER_SIZE;
	}


	pTSInfoParser->ts_filter->dumper.pat_dumper = (DUMP)PATDumper;
	pTSInfoParser->ts_filter->dumper.pat_dumper_context = pTSInfoParser;
	pTSInfoParser->ts_filter->dumper.pmt_dumper = (DUMP)PMTDumper;
	pTSInfoParser->ts_filter->dumper.pmt_dumper_context = pTSInfoParser;
	pTSInfoParser->ts_filter->dumper.pcr_dumper = (DUMP)PCRDumper;
	pTSInfoParser->ts_filter->dumper.pcr_dumper_context = pTSInfoParser;
	pTSInfoParser->ts_filter->dumper.stream_dumper = (DUMP)StreamDumper;
	pTSInfoParser->ts_filter->dumper.stream_dumper_context = pTSInfoParser;

	pTSInfoParser->ts_filter->psi_parser->dumper.channel_info_dumper  =	(DUMP)ChannelInfoDumper;
	pTSInfoParser->ts_filter->psi_parser->dumper.channel_info_context =	pTSInfoParser;
	pTSInfoParser->ts_filter->psi_parser->dumper.pid_dumper  =	(DUMP)PSIPidDumper;
	pTSInfoParser->ts_filter->psi_parser->dumper.pid_context =	pTSInfoParser;
	pTSInfoParser->ts_filter->psi_parser->dumper.system_time_dumper   =	(DUMP)SystemTimeDumper;
	pTSInfoParser->ts_filter->psi_parser->dumper.system_time_context  =	pTSInfoParser;
	//pTSInfoParser->ts_filter->psi_parser->dumper.tune_info_dumper     = (DUMP)TuneInfoDumper;
	//pTSInfoParser->ts_filter->psi_parser->dumper.tune_info_context    = pTSInfoParser;
	//pTSInfoParser->ts_filter->psi_parser->dumper.message_dumper       = (DUMP)MessageDumper;
	//pTSInfoParser->ts_filter->psi_parser->dumper.message_context      = pTSInfoParser;
	pTSInfoParser->utc_sec_start = 0;
	pTSInfoParser->pcr_sec_start = 0;
	pTSInfoParser->max_check_limit = 1024*1024*32; //max check 64M data for avinfo
	SageLog(( _LOG_TRACE, 3, TEXT("TS Info Parser filter is created  version 1.0.2  .") ));
	return pTSInfoParser;
}
예제 #21
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
void* OpenRemuxStream( unsigned short nTask, TUNE* pTune, 
					   int nInputFormat, int nOutputFormat, 
					   MEM_ALLOC_HOOK pfnMemAlloc, void* pMemAllocContext,
					   DUMP pfnOutputDump, void* pOutputDumpContext )
{
	REMUXER *pRemuxer;
	int ret, max_track_num;

	//if not specify a input format, detect it
	if ( nInputFormat == 0 )
		return 0;

	if ( nInputFormat == MPEG_M2TS ) 
		 max_track_num = MAX_TRACK_NUM *2;
	else
		 max_track_num = MAX_TRACK_NUM;

	SageLog(( _LOG_ERROR, 3, TEXT("Create Remuxer" ) ));
	pRemuxer = CreateRemuxer( nInputFormat, max_track_num, ES_BUFFER_SIZE );

	//pRemuxer->remuxer_ctrl = MAIN_TRACK_ONLY;
	pRemuxer->task = nTask;

	if ( pfnMemAlloc != NULL )
		SetupMemAlloc( pRemuxer, pfnMemAlloc, pMemAllocContext );

	SetupMessageDumper( pRemuxer->demuxer, (DUMP)RemuxMessageDumper, pRemuxer );

	ret = OpenStreamSource( pRemuxer->demuxer, nInputFormat,  pTune );
	if ( !ret )
	{

		ReleaseRemuxer( pRemuxer );
		return 0;
	}

	CreateStreamOutput( pRemuxer, nOutputFormat, pfnOutputDump, pOutputDumpContext );

	pRemuxer->state = 1;
	pRemuxer->dumper.output_dumper = pfnOutputDump;
	pRemuxer->dumper.output_dumper_context = pOutputDumpContext;

	return pRemuxer;
}
예제 #22
0
파일: AVTrack.c 프로젝트: qianzhang5/sagetv
static int MpegVideoInf( MPEG_VIDEO *pMpegVideo, char* pBuffer, int nSize )
{
	char* p = pBuffer;
	int pos = 0;
	if ( nSize <= 0 ) return 0;
	if ( pMpegVideo->extension_present )
	{
		char* chrome_format="";
		if ( pMpegVideo->chrome == 1  ) chrome_format = "cs=yuv420p;"; else
		if ( pMpegVideo->chrome == 2  ) chrome_format = "cs=yuv422p;"; else
		if ( pMpegVideo->chrome == 3  ) chrome_format = "cs=yuv444p;"; 


SageLog(( _LOG_ERROR, 3, TEXT("TRACE--- %d %d %d %d \n"),
         pMpegVideo->width, pMpegVideo->height, pMpegVideo->ar_info, pMpegVideo->ar_info));

		pos += snprintf( p+pos, nSize-pos, "fps=%f;fpsn=%d;fpsd=%d;ar=%f;arn=%d;ard=%d;w=%d;h=%d;lace=%d;%s",
			              (float)pMpegVideo->frame_rate_nomi/pMpegVideo->frame_rate_deno,
						  pMpegVideo->frame_rate_nomi, 
						  pMpegVideo->frame_rate_deno,
						  Mepg2AspectRatioF( (uint8_t)(pMpegVideo->ar_info & 0x0f), pMpegVideo->width, pMpegVideo->height ),
						  Mepg2AspectRatioNomiValue( (uint8_t)(pMpegVideo->ar_info & 0x0f), pMpegVideo->width, pMpegVideo->height ),
						  Mepg2AspectRatioDenoValue( (uint8_t)(pMpegVideo->ar_info & 0x0f), pMpegVideo->width, pMpegVideo->height ),
						  pMpegVideo->width, 
						  pMpegVideo->height,
						  !pMpegVideo->progressive,
						  chrome_format );

	} else
	{
		pos += snprintf( p+pos, nSize-pos, "fps=%f;fpsn=%d;fpsd=%d;ar=%f;w=%d;h=%d;",
			              (float)pMpegVideo->frame_rate_nomi/pMpegVideo->frame_rate_deno,
						  pMpegVideo->frame_rate_nomi, 
						  pMpegVideo->frame_rate_deno,
						  Mepg1AspectRatioF( (uint8_t)(pMpegVideo->ar_info & 0x0f), pMpegVideo->width, pMpegVideo->height ),
						  pMpegVideo->width, pMpegVideo->height );
	}
	return pos;
}
예제 #23
0
TS_CHANNEL_PARSER* CreateTSChannelParser( int nMaxStreamNum, int nStreamFormat, int nSubFormat )
{
	int i;
	TS_CHANNEL_PARSER *pTSChannelParser = SAGETV_MALLOC( sizeof(TS_CHANNEL_PARSER) );
	pTSChannelParser->ts_filter = CreateTSFilter( DEFAULT_PAT_NUM, DEFAULT_PMT_NUM, nStreamFormat, nSubFormat ); //ATSC_STREAM, TERRESTRIAL;
	pTSChannelParser->max_stream_num = nMaxStreamNum;
	pTSChannelParser->ts_streams.ts_element = SAGETV_MALLOC( nMaxStreamNum*sizeof(TS_ELEMENT) );
	pTSChannelParser->ts_streams.total_streams = nMaxStreamNum;
	pTSChannelParser->es_streams.es_element = SAGETV_MALLOC( nMaxStreamNum*sizeof(ES_ELEMENT) );
	pTSChannelParser->es_streams.total_streams = nMaxStreamNum;
	pTSChannelParser->av_streams.av_element = SAGETV_MALLOC( nMaxStreamNum*sizeof(AV_ELEMENT) );
	pTSChannelParser->av_streams.total_streams = nMaxStreamNum;
	pTSChannelParser->es_buffer = SAGETV_MALLOC( nMaxStreamNum*sizeof(ES_BUFFER_) );
	for ( i = 0; i<nMaxStreamNum; i++ )
	{
		pTSChannelParser->es_buffer[i].buffer = SAGETV_MALLOC( TMP_ES_BUFFER_SIZE );
		pTSChannelParser->es_buffer[i].buffer_size = TMP_ES_BUFFER_SIZE;
	}


	pTSChannelParser->ts_filter->dumper.pat_dumper = (DUMP)PATDumper;
	pTSChannelParser->ts_filter->dumper.pat_dumper_context = pTSChannelParser;
	pTSChannelParser->ts_filter->dumper.pmt_dumper = (DUMP)PMTDumper;
	pTSChannelParser->ts_filter->dumper.pmt_dumper_context = pTSChannelParser;
	pTSChannelParser->ts_filter->dumper.stream_dumper = (DUMP)StreamDumper;
	pTSChannelParser->ts_filter->dumper.stream_dumper_context = pTSChannelParser;

	pTSChannelParser->ts_filter->psi_parser->dumper.channel_info_dumper  =	(DUMP)ChannelInfoDumper;
	pTSChannelParser->ts_filter->psi_parser->dumper.channel_info_context =	pTSChannelParser;
	pTSChannelParser->ts_filter->psi_parser->dumper.pid_dumper  =	(DUMP)PSIPidDumper;
	pTSChannelParser->ts_filter->psi_parser->dumper.pid_context =	pTSChannelParser;

	InitScanData( pTSChannelParser,  nStreamFormat, nSubFormat );

	pTSChannelParser->max_check_limit = 1024*1024*12; //max check 12M data for avinfo
	SageLog(( _LOG_TRACE, 3, TEXT("TS Channel Parser is created  version 1.0.0  .") ));
	return pTSChannelParser;
}
예제 #24
0
void ReleaseTSChannelParser( TS_CHANNEL_PARSER *pTSChannelParser )
{
	int i;

	if ( pTSChannelParser->program_list.program )
		SAGETV_FREE( pTSChannelParser->program_list.program );
	if ( pTSChannelParser->channel_list.channel  )
		SAGETV_FREE( pTSChannelParser->channel_list.channel );
	if ( pTSChannelParser->tune_list.tune  )
		SAGETV_FREE( pTSChannelParser->tune_list.tune );

	SAGETV_FREE( pTSChannelParser->ts_streams.ts_element );
	SAGETV_FREE( pTSChannelParser->es_streams.es_element );
	SAGETV_FREE( pTSChannelParser->av_streams.av_element );
	for ( i = 0; i<pTSChannelParser->max_stream_num; i++ )
		SAGETV_FREE( pTSChannelParser->es_buffer[i].buffer );
		
	SAGETV_FREE( pTSChannelParser->es_buffer );
	ReleaseTSFilter( pTSChannelParser->ts_filter );
	SAGETV_FREE( pTSChannelParser );

	SageLog(( _LOG_TRACE, 3, TEXT("TS Channel Parser is released  .") ));
}
예제 #25
0
int CheckTrackAVInfRead( TS_INFO_PARSER *pTSInfoParser )
{
	unsigned long sec;
	if ( pTSInfoParser->total_video_num && pTSInfoParser->found_video_num >= pTSInfoParser->total_video_num )
		if ( pTSInfoParser->total_audio_num && pTSInfoParser->found_audio_num >= pTSInfoParser->total_audio_num )
			return 1;
			
	if ( (sec = ElapseSeconds( pTSInfoParser )) > 8 || ( sec == 0 && ElapseSecondsByPCR(pTSInfoParser) > 8 ) )
	{
		SageLog(( _LOG_ERROR, 3, TEXT("AVINF checking timeout (%d)!"), ElapseSeconds( pTSInfoParser ) ));
		return 1;
	}
	
	if ( pTSInfoParser->total_bytes > pTSInfoParser->max_check_limit )
		return 1;

	if ( pTSInfoParser->total_bytes > pTSInfoParser->max_check_limit/2 )
	{
		int i, empty_video_track_num = 0, empty_audio_track_num = 0;
		for ( i = 0; i<pTSInfoParser->ts_streams.num_stream; i++ )
		{
			if ( pTSInfoParser->es_buffer[i].input_bytes == 0 )
			{
				if ( pTSInfoParser->ts_streams.ts_element[i].content_type == VIDEO_DATA )
					empty_video_track_num++;
				else
				if ( pTSInfoParser->ts_streams.ts_element[i].content_type == AUDIO_DATA )
					empty_audio_track_num++;
			}
		}

		if ( pTSInfoParser->found_video_num + empty_video_track_num>= pTSInfoParser->total_video_num )
			if ( pTSInfoParser->found_audio_num + empty_audio_track_num >= pTSInfoParser->total_audio_num )
			return 1;
	}
	return 0;
}
예제 #26
0
파일: Scan.cpp 프로젝트: BOTCrusher/sagetv
void CScan::ProcessScan( unsigned char* pData, long lDataLen )
{
	int  nScanState;
	if ( m_nScanState == DONE_SCAN ) 
		return;
		
	if ( m_bScanFileCache )
		CacheChannelScanData( pData, lDataLen );

	if ( !m_bScanFileCache || m_bScanFileCache && !IsCacheDataFull( ) )
		PushChannelScanTunerData( pData, lDataLen );
	else
		PushChannelScanFileData( );

	nScanState = IsChannelInfoReady( m_pScan );
	if ( nScanState == 2 ) //psi channels is ready
	{
		unsigned short iStreamFormat, iSubFormat;
		if ( GetStreamFormat( m_pScan, &iStreamFormat, &iSubFormat ) )
		{
			m_nStreamFormat = (unsigned char)iStreamFormat;
			m_nStreamSubFormat = (unsigned char)iSubFormat;
		}
		if ( IsQAMStream( &m_pScan->tune ) )
		{
			m_Tune.stream_format = (unsigned char)m_nStreamFormat;
			m_Tune.sub_format    = (unsigned char)m_nStreamSubFormat;
			ResetChannelScan( m_pScan );
			DoChannelScan( m_pScan, NAKED_SCAN );
			ChannelScanTune( m_pScan, &m_Tune ); 
			m_nScanState = NAKED_SCAN;
		} else
			m_nScanState = DONE_SCAN;
	} else
	if ( nScanState == 3 ) //naked channels is ready
	{
		MergeChannelListProgramList( m_pScan );
		m_nScanState = DONE_SCAN;
		SageLog(( _LOG_TRACE, 3, TEXT("*********** Scan done ************") )); 
	} else
	if ( nScanState > 0 ) //maxium parsing data
	{
		if ( nScanState == 4 )
			SageLog(( _LOG_TRACE, 3, TEXT("\t**** Stop PSI parsing (maxium bytes searching).") ));
		else
		if ( nScanState == 5 )
			SageLog(( _LOG_TRACE, 3, TEXT("\t**** Stop PSI parsing, no nit, no channel PSI (%d ms)"), UpdateTimeClock( m_pScan, 0 ) ));
		else
		if ( nScanState == 10 )
			SageLog(( _LOG_TRACE, 3, TEXT("\t**** Stop PSI parsing, timeout (%d ms)."), UpdateTimeClock( m_pScan, 0 ) ));
		else
		if ( nScanState == 6 )
		    SageLog(( _LOG_TRACE, 3, TEXT("\t**** Stop naked parsing (maxium bytes searching), no pmt.).") ));
		else
		if ( nScanState == 7 )
			SageLog(( _LOG_TRACE, 3, TEXT("\t**** Stop naked parsing (maxium bytes searching), no clear channel.).") ));
		else
			SageLog(( _LOG_TRACE, 3, TEXT("\t**** Stop PSI parsing, unkonw %d (%d ms)."), nScanState, UpdateTimeClock( m_pScan, 0 ) ));

		if ( m_nScanState == PSI_SCAN && 
			( IsQAMStream( &m_pScan->tune ) || 
			  IsDVBSStream( &m_pScan->tune ) && IsNakedStream( m_pScan ) ) ) //naked DVB-S stream in USA
		{
			SageLog(( _LOG_TRACE, 3, TEXT("*********** Start scaning naked channels ************") )); 
			ResetChannelScan( m_pScan );
			DoChannelScan( m_pScan, NAKED_SCAN );
			ChannelScanTune( m_pScan, &m_Tune ); 
			m_nScanState = NAKED_SCAN; 

		} else
		{
			SageLog(( _LOG_TRACE, 3, TEXT("*********** Scan done (state:%d %s naked:%d )************"),
				m_nScanState, StreamFormatString(m_pScan->tune.stream_format, m_pScan->tune.sub_format), 
				IsNakedStream( m_pScan ) )); 
			m_nScanState = DONE_SCAN;
		}
	} 

}
예제 #27
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
void SetDefaultAudioLanguage( void* Handle, unsigned long lLanguageCode )
{
	REMUXER *pRemuxer = (REMUXER *)Handle;
	pRemuxer->language_code = lLanguageCode;
	SageLog(( _LOG_ERROR, 3, TEXT("Set default audio language \"%s\"."), Language(lLanguageCode, NULL )  ));
}
예제 #28
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
void SetupRemuxOutput( TRACKS *pTrackIn, TRACKS *pTrackOut )
{
	int i;
	if ( pTrackOut == NULL )
		return;
	ASSERT( pTrackIn->total_track == pTrackOut->total_track );
	for ( i = 0; i<pTrackIn->total_track; i++ )
	{
		if ( pTrackIn->track[i].av_elmnt->content_type == VIDEO_DATA || 
			 pTrackIn->track[i].av_elmnt->content_type == AUDIO_DATA  )
		{	
			if ( pTrackIn->track[i].ts_elmnt && pTrackOut->track[i].ts_elmnt )
			{
				*pTrackOut->track[i].ts_elmnt = *pTrackIn->track[i].ts_elmnt;
				if ( pTrackOut->track[i].ts_elmnt->type == PRIVATE_STREAM_TYPE )
				{
					if ( pTrackIn->track[i].av_elmnt->format_fourcc == SAGE_FOURCC( "H264" ) )
						pTrackOut->track[i].ts_elmnt->type = H264_STREAM_TYPE;
					else
					if ( pTrackIn->track[i].av_elmnt->format_fourcc == SAGE_FOURCC( "VC1 " ) )
						pTrackOut->track[i].ts_elmnt->type =  VC1_STREAM_TYPE;
					else
					if ( pTrackIn->track[i].av_elmnt->format_fourcc == SAGE_FOURCC( "AC3 " ) )
						pTrackOut->track[i].ts_elmnt->type =  AC3_STREAM_TYPE;
					else
					if ( pTrackIn->track[i].av_elmnt->format_fourcc ==  SAGE_FOURCC( "MPGA" ) )
						pTrackOut->track[i].ts_elmnt->type =  AUDIO_STREAM_TYPE;
					else
					if ( pTrackIn->track[i].av_elmnt->format_fourcc ==  SAGE_FOURCC( "MPGV" ) )
						pTrackOut->track[i].ts_elmnt->type =  VIDEO_STREAM_TYPE;
					else
					if ( pTrackIn->track[i].av_elmnt->format_fourcc ==  SAGE_FOURCC( "MP4A" ) )
						pTrackOut->track[i].ts_elmnt->type =  MPEG4_STREAM_TYPE;
				}
			}
			*pTrackOut->track[i].av_elmnt = *pTrackIn->track[i].av_elmnt;
			*pTrackOut->track[i].es_elmnt = *pTrackIn->track[i].es_elmnt;
			pTrackOut->track[i].es_elmnt->es_id = MakeESId( pTrackIn->track[i].es_elmnt->pes.stream_id, 
													(unsigned char)(pTrackIn->track[i].es_elmnt->es_id & 0x00ff) );
			SetupTracks( &pTrackOut->track[i] );
		} 
	}

	for ( i = 0; i<pTrackIn->total_track; i++ )
	{
		//we don't need parser work out sub title format, we just pass on 
		if ( pTrackIn->track[i].av_elmnt->content_type == SUBTITLE_DATA || 
			 pTrackIn->track[i].av_elmnt->format_fourcc == SAGE_FOURCC( "SUB " ) )
		{  
			if ( pTrackIn->track[i].ts_elmnt )
				*pTrackOut->track[i].ts_elmnt = *pTrackIn->track[i].ts_elmnt;
			*pTrackOut->track[i].av_elmnt = *pTrackIn->track[i].av_elmnt;
			*pTrackOut->track[i].es_elmnt = *pTrackIn->track[i].es_elmnt;

			pTrackOut->track[i].es_elmnt->es_id = MakeESId( 0xBD, 0x20+(pTrackIn->track[i].es_elmnt->es_id & 0x00ff) );
			SetupTracks( &pTrackOut->track[i] );
			if ( pTrackOut->track[i].av_elmnt->format_fourcc == SAGE_FOURCC( "SUB " ) )
				pTrackOut->track[i].es_elmnt->private_data[1] = (unsigned char)pTrackOut->track[i].av_elmnt->d.s.sub.type; //ZQ subtitle new way
			
			SageLog(( _LOG_TRACE, 3, "Subtitle stream is added, es id:0x%04x at %d", 
				                          pTrackOut->track[i].es_elmnt->es_id, i ));
		}
	}
	pTrackOut->number_track = pTrackIn->number_track;
	pTrackOut->track_attr = pTrackIn->track_attr;
	pTrackOut->main_video_index = pTrackIn->main_video_index;
	pTrackOut->main_audio_index = pTrackIn->main_audio_index;

}
예제 #29
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
int EPGDumper( void* pContext, unsigned char* pData, int nSize )
{
	SageLog(( _LOG_ERROR, 3, (char*)pData ));
	return 1;
}
예제 #30
0
파일: Remuxer.c 프로젝트: neurocis/sagetv
static int RemuxMessageDumper( void* pContext, unsigned char* pData, int nSize )
{
	REMUXER *pRemuxer = (REMUXER*)pContext;
	MESSAGE_DATA *message = (MESSAGE_DATA*)pData;
	if ( strstr( message->title, "LANGUAGE" ) )
	{
		unsigned long language_code = LanguageCode( message->message );
		SetupEPGDumpLanguage( pRemuxer, language_code );
		//SetupEPGDumpLanguage( pRemuxer,  LanguageCode( "eng" ) );
	} else
	if ( !strcmp( message->title, "STATUS" ) )
	{
		SageLog(( _LOG_TRACE, 3, TEXT("*********** PARSER STATUS: %s ***********"), message->message ));
		if ( strstr( (char*)message->message, "STREAM START" ) )
		{
			int slot_index = 0;
			const char *p;
			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );

			ResetBlockBuffer( pRemuxer->demuxer, slot_index );

			if ( pRemuxer->state >= 2 )
			{
				if ( pRemuxer->ps_builder != NULL )
					pRemuxer->ps_builder->state = PUMPOUT_DATA;
				if ( pRemuxer->ts_builder != NULL )
					pRemuxer->ts_builder->state = PUMPOUT_DATA;
			}

		} else
		if ( strstr( (char*)message->message, "STREAM READY" ) )
		{
			int slot_index = 0;
			const char *p;
			TRACKS *tracks, *tracks_out;

			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );

			tracks = GetTracks( pRemuxer->demuxer, slot_index );
			tracks_out = pRemuxer->output_track[slot_index];

			if ( SourceIsPSType( pRemuxer->demuxer ) && IsSageTVRecording( pRemuxer->demuxer ) )
			{
				PickupSageTVMainTrack( pRemuxer->demuxer, tracks );
			}

			CheckTracksAttr( tracks , pRemuxer->language_code );
			if ( FindMainVideoAudio( tracks ) )
			{
				SageLog(( _LOG_TRACE, 3, TEXT("Main video at track:%d; Main audio at track:%d"), 
							                tracks->main_video_index,	tracks->main_audio_index ));
				if ( pRemuxer->remuxer_ctrl & MAIN_TRACK_ONLY )
				{
					DisableAuxTrack( tracks );
				}

			} else
			{
				SageLog(( _LOG_ERROR, 3, TEXT("ERROR: main video and audio track not found" ) ));
			}

			TracksIndexing( tracks );
			_display_av_inf( tracks );
			
			SetupRemuxOutput( tracks, tracks_out );

			if ( pRemuxer->ps_builder != NULL )
			{
				CreatSageStreamHeader( pRemuxer->ps_builder );
			} else
			if ( pRemuxer->ts_builder != NULL )
			{
				UpdatePMT( pRemuxer->ts_builder, slot_index );
			} 

			if ( pRemuxer->state == 1 )
			{
				pRemuxer->state = 2; //output data
			}
			
			if ( pRemuxer->task == STRIP_STREAM )
			{
				char avinf[1024];
				int bytes;
				bytes = snprintf( avinf, sizeof(avinf), "AV-INF|f=" );
				bytes += TracksInfo( tracks, avinf+bytes, sizeof(avinf)-bytes );
				if ( pRemuxer->dumper.avinf_dumper != NULL )
					pRemuxer->dumper.avinf_dumper( pRemuxer->dumper.avinf_dumper_context, avinf, bytes );
				SageLog(( _LOG_TRACE, 3, TEXT("OUTPUT:%s"), avinf ));
			} else
			{
				char avinf[1024];
				int bytes;
				bytes = snprintf( avinf, sizeof(avinf), "AV-INF|f=" );
				bytes += TracksInfo( tracks_out, avinf+bytes, sizeof(avinf)-bytes );
				if ( pRemuxer->dumper.avinf_dumper != NULL )
					pRemuxer->dumper.avinf_dumper( pRemuxer->dumper.avinf_dumper_context, avinf, bytes );
				SageLog(( _LOG_TRACE, 3, TEXT("OUTPUT:%s"), avinf ));
			} 

			//start dumping data
			if ( pRemuxer->task == REMUX_STREAM )
			{
				if ( pRemuxer->ps_builder != NULL )
					pRemuxer->ps_builder->state = PUMPOUT_DATA;
				if ( pRemuxer->ts_builder != NULL )
					pRemuxer->ts_builder->state = PUMPOUT_DATA;
			} else
			//if remux a file, rewind to begining of a file to start
			if ( pRemuxer->task == REMUX_FILE && pRemuxer->state < 3  )
			{
				ULONGLONG pos = DemuxUsedBytes( pRemuxer->demuxer );
				QueueZeroDemux( pRemuxer->demuxer );
				
				DemuxSourceSeekPos( pRemuxer->demuxer, 0, SEEK_SET );
				SageLog(( _LOG_ERROR, 3, TEXT("**** File seek to begin of file to process data. (pos:%d) ****" ), 
																							 (unsigned long)pos ));
				PTSLog(( 0, 0, 0, 0, 0 ) ); 

				pRemuxer->state = 3; //rewinded  
			}

			if ( pRemuxer->ps_builder != NULL )
			{
				OUTPUT_DATA output_data={0};
				if ( !(pRemuxer->ps_builder->build_ctrl & BUILD_HEADER_IN_BUFFER ) )
				{
					//dump a system head block (PACK+SYSTEM HEADER)
					output_data.data_ptr = pRemuxer->ps_builder->block_buffer; 
					output_data.bytes    = pRemuxer->ps_builder->system_packet_bytes;
					pRemuxer->ps_builder->dumper.stream_dumper( pRemuxer->ps_builder->dumper.stream_dumper_context, 
						                              &output_data, sizeof(output_data) );
					//PadingBuffer( pRemuxer->ps_builder->block_buffer, pRemuxer->ps_builder->buffer_size ); //clean up pading buffer
					pRemuxer->ps_builder->system_packet_bytes = 0;
				} else
				{
					BLOCK_BUFFER *block_buffer;
					TRACK track={0}; 
					track.channel_index = 0;
					block_buffer = RequestBlockBuffer( pRemuxer->demuxer, &track );
					if ( block_buffer != NULL )
					{
						ASSERT( block_buffer->buffer_size >= pRemuxer->ps_builder->system_packet_bytes );
						memcpy( block_buffer->buffer_start, pRemuxer->ps_builder->block_buffer, 
															pRemuxer->ps_builder->system_packet_bytes );
						//PadingBuffer( block_buffer->data_start+pRemuxer->ps_builder->system_packet_bytes, 
						//	          block_buffer->data_size-pRemuxer->ps_builder->system_packet_bytes ); 
						output_data.data_ptr = block_buffer->data_start; 
						output_data.bytes    = pRemuxer->ps_builder->system_packet_bytes;
						pRemuxer->ps_builder->dumper.stream_dumper( pRemuxer->ps_builder->dumper.stream_dumper_context, 
																					  &output_data, sizeof(output_data) );
						ReturnBlockBuffer( pRemuxer->demuxer, block_buffer );
					}
				}
			}
			if ( pRemuxer->state == 2 )
			{
				ULONGLONG pos = DemuxUsedBytes( pRemuxer->demuxer );
				SageLog(( _LOG_ERROR, 3, TEXT("****** Find AVINF (pos:%d) ******" ), (unsigned long)pos ));
			}

			//debug_dump_content = 1;  //ZQ

		} else
		if ( strstr( (char*)message->message, "STREAM REBUILD" ) )
		{
			int slot_index = 0;
			const char *p;
			SageLog(( _LOG_TRACE, 3, TEXT("****** PARSER STATUS: %s ******"), message->message ));
			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );
			 {
				ULONGLONG pos = DemuxUsedBytes( pRemuxer->demuxer );
				QueueZeroDemux( pRemuxer->demuxer );
				DemuxSourceSeekPos( pRemuxer->demuxer, 0, SEEK_SET );
				SageLog(( _LOG_ERROR, 3, TEXT("**** File seek to begin of file to process data. (pos:%d) ****" ), 
																							(unsigned long)pos ));
			}


		} else
		if ( strstr( (char*)message->message, "STREAM FAILED" ) )
		{
			int slot_index = 0;
			const char *p;
			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );

		} else
		if ( strstr( (char*)message->message, "STREAM END" ) )
		{
			int slot_index = 0;
			const char *p;
			if ( ( p = strstr( (char*)message->message, "slot:" ) )!= NULL )
				slot_index = atoi( p+5 );

			if ( pRemuxer->task != REMUX_FILE )
			{
				//do nothing
			} else
			{
				if ( pRemuxer->state == 1 )  //parsing information, not done yet, force it done
				{
					TRACKS *tracks, *tracks_out;
					tracks = GetTracks( pRemuxer->demuxer, slot_index );
					tracks_out = pRemuxer->output_track[slot_index];

					CheckTracksAttr( tracks , pRemuxer->language_code );
					if ( FindMainVideoAudio( tracks ) )
					{
						SageLog(( _LOG_TRACE, 3, TEXT("Main video at track:%d; Main audio at track:%d"), 
												  tracks->main_video_index,	tracks->main_audio_index ));

						if ( pRemuxer->remuxer_ctrl & MAIN_TRACK_ONLY )
						{
							DisableAuxTrack( tracks );
						}

					} else
					{
						SageLog(( _LOG_ERROR, 3, TEXT("ERROR: main video and audio track not found" ) ));
					}
					TracksIndexing( tracks );
					_display_av_inf( tracks );

					SetupRemuxOutput( tracks, tracks_out );
					if ( pRemuxer->ps_builder != NULL )
					{
						CreatSageStreamHeader( pRemuxer->ps_builder );
					} else
					if ( pRemuxer->ts_builder != NULL )
					{
						UpdatePMT( pRemuxer->ts_builder, slot_index );
					} 

					pRemuxer->state = 2; //output data

					{
						ULONGLONG pos = DemuxUsedBytes( pRemuxer->demuxer );
						QueueZeroDemux( pRemuxer->demuxer );

						DemuxSourceSeekPos( pRemuxer->demuxer, 0, SEEK_SET );
						SageLog(( _LOG_ERROR, 3, TEXT("**** File seek to begin of file to process data. (pos:%d) ****" ), 
																									 (unsigned long)pos ));
						PTSLog(( 0, 0, 0, 0, 0 ) ); 
					}

				} else
				{
					FlushRemuxer( pRemuxer, slot_index );
				}
			}
		}
	}

	return 1;
}