int TagInfo( int nOutputFormat, TS_ELEMENT *pTSElmnt, ES_ELEMENT *pESElmnt, char* pBuffer, int nSize ) { int i, pos = 0; char *p = pBuffer; if ( IS_TS_TYPE(nOutputFormat) ) { return snprintf( p+pos, nSize-pos, "tag=%04x;pid=%d;", pTSElmnt->pid, pTSElmnt->pid ); } else { if ( pESElmnt->private_bytes == 0 ) { return snprintf( p+pos, nSize-pos, "tag=%02x;", pESElmnt->pes.stream_id ); } else { pos += snprintf( p+pos, nSize-pos, "tag=%02x-", pESElmnt->pes.stream_id ); for ( i = 0; i<pESElmnt->private_bytes; i++ ) { pos += snprintf( p+pos, nSize-pos, "%02x", pESElmnt->private_data[i] ); } if ( pos <nSize ) p[pos++] = ';'; return pos; } } return pos; }
int RemuxFileW( unsigned short nTask, wchar_t* pInputFile, TUNE* pTune, int nInputFormat, wchar_t* pOutFile, int nOutputFormat, int nOption ) { REMUXER *pRemuxer; int ret, max_track_num; //if not specify a input format, detect it if ( nInputFormat == 0 ) nInputFormat = DetectFileTypeW( pInputFile ); if ( nInputFormat == 0 ) return 0; if ( nInputFormat == MPEG_M2TS ) max_track_num = MAX_TRACK_NUM *2; else max_track_num = MAX_TRACK_NUM; pRemuxer = CreateRemuxer( nInputFormat, max_track_num, ES_BUFFER_SIZE ); pRemuxer->task = nTask; SetupMessageDumper( pRemuxer->demuxer, (DUMP)RemuxMessageDumper, pRemuxer ); ret = OpenFileSourceW( pRemuxer->demuxer, pInputFile, nInputFormat, pTune ); if ( !ret ) { ReleaseRemuxer( pRemuxer ); return 0; } if ( nOption & 0x01 ) DisabeTSPtsFix( pRemuxer ); if ( nOption & 0x02 ) SetupEPGDump( pRemuxer, (DUMP)EPGDumper, pRemuxer ); SetupEPGDumpLanguage( pRemuxer, LanguageCode((unsigned char*)"eng") ); if ( pOutFile != NULL && pOutFile[0] != 0x0 ) CreateFileOutputW( pRemuxer, pOutFile, nOutputFormat, max_track_num ); if ( IS_TS_TYPE(nOutputFormat) ) SetupBlockDataDumper( pRemuxer->demuxer, BlockBufferTSDump, pRemuxer->ts_builder ); else if ( IS_PS_TYPE(nOutputFormat) ) SetupBlockDataDumper( pRemuxer->demuxer, BlockBufferPSDump, pRemuxer->ps_builder ); pRemuxer->state = 1; //looping pump data from file into remuxer PumpFileData( pRemuxer->demuxer, 0, RemuxFileProgressCallback, pRemuxer ); PostStatusMessage( pRemuxer, "STREAM END (slot:0)" ); ReleaseFileOutput( pRemuxer ); CloseFileSource( pRemuxer->demuxer ); ReleaseRemuxer( pRemuxer ); return 1; }
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; }
void CTSParserFilter::OutpinConnected(IPin *pReceivePin, CBasePin* pFilterPin ) { REMUXER* pRemuxer; HRESULT hr = m_pInputPin->GetParser( &pRemuxer ); if ( hr != NOERROR ) return ; if ( pFilterPin == m_pOutputPin ) { ChangeRemuxOutputFormat( pRemuxer, m_wOutputFormat ); if ( IS_TS_TYPE( m_wOutputFormat ) && m_pOutputPin != NULL ) { int nBlockSize = GetBlockSize( m_pOutputPin ); SetupRemuxOutputBlockSize( pRemuxer, nBlockSize ); } } }
int CreateStreamOutput( REMUXER *pRemuxer, int nOutputFormat, DUMP pfnOutputDump, void* pOutputDumpContext ) { pRemuxer->output_track[0] = CreateTracks(MAX_TRACK_NUM); 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 = pfnOutputDump; pRemuxer->ps_builder->dumper.stream_dumper_context = pOutputDumpContext; SetupBlockDataDumper( pRemuxer->demuxer, BlockBufferPSDump, pRemuxer->ps_builder ); } else if ( IS_TS_TYPE(nOutputFormat) ) { pRemuxer->ts_builder = CreateTSBuilder( pRemuxer->output_track[0], nOutputFormat ); pRemuxer->ts_builder->dumper.stream_dumper = pfnOutputDump; pRemuxer->ts_builder->dumper.stream_dumper_context = pOutputDumpContext; SetupBlockDataDumper( pRemuxer->demuxer, BlockBufferTSDump, pRemuxer->ts_builder ); } pRemuxer->output_format = nOutputFormat; return 1; }
void CheckTracksAttr( TRACKS* pTracks, unsigned long LanguageCode ) { int i; if ( IS_TS_TYPE( pTracks->track_type ) ) { int video_track_num = 0, audio_track_num = 0; int video_scrambling_track_num = 0, audio_scrambling_track_num = 0; //count totoal track for ( i = 0; i<pTracks->total_track; i++ ) { if ( pTracks->track[i].ts_elmnt == NULL ) break; } pTracks->number_track = i; if ( pTracks->main_video_index == 0xffff ) { //select main video and check tracks attribute for ( i = 0; i<pTracks->number_track; i++ ) { if ( pTracks->track[i].ts_elmnt->content_type == VIDEO_DATA ) { if ( pTracks->main_video_index == 0xffff ) pTracks->main_video_index = i; else { if ( pTracks->track[i].ts_packets_counter > pTracks->track[ pTracks->main_video_index ].ts_packets_counter ) pTracks->main_video_index = i; } if ( pTracks->track[i].scrambling_flag ) video_scrambling_track_num++; video_track_num++; if ( pTracks->track[i].es_elmnt->format_fourcc != 0 ) pTracks->track_attr |= ATTR_VIDEO_PRESENT; } } } if ( pTracks->main_audio_index == 0xffff ) { int weights[64]={0}; //select main audio and check tracks attribute for ( i = 0; i<pTracks->number_track && i<64; i++ ) { //skip no data stream; if ( pTracks->track[i].av_elmnt->content_type == 0 ) continue; if ( pTracks->track[i].ts_elmnt->content_type == AUDIO_DATA && pTracks->track[i].ts_packets_counter > 0 ) { weights[i] = 0; if ( LanguageCode ) weights[i] = pTracks->track[i].ts_elmnt->language_code == LanguageCode ? 10000 : pTracks->track[i].ts_elmnt->language_code == 0 ? 10000 : 0; weights[i] += pTracks->track[i].ts_elmnt->audio_type == 0 ? 9000 : /* normal */ pTracks->track[i].ts_elmnt->audio_type == 3 ? 8000 : /* silent */ pTracks->track[i].ts_elmnt->audio_type == 2 ? 7000 : /* impaired */ pTracks->track[i].ts_elmnt->audio_type == 1 ? 6000 : 0; /* commentary */ weights[i] += GetAudioSoundChannelNum( pTracks->track[i].av_elmnt ) * 100; weights[i] += GetAudioSoundBitRate( pTracks->track[i].av_elmnt ) / 10000; /* range 1-100 */ //skip LPCM because parser isn't ready if ( pTracks->track[i].ts_elmnt->format_fourcc == SAGE_FOURCC( "LPCM" ) ) weights[i] = -20000; if ( pTracks->main_audio_index == 0xffff ) pTracks->main_audio_index = i; else { if ( weights[i] > weights[ pTracks->main_audio_index ] ) { pTracks->main_audio_index = i; } else if ( weights[i] == weights[ pTracks->main_audio_index ] ) { if ( pTracks->track[i].ts_packets_counter> pTracks->track[ pTracks->main_audio_index ].ts_packets_counter+3 ) pTracks->main_audio_index = i; } } if ( pTracks->track[i].scrambling_flag ) audio_scrambling_track_num++; audio_track_num++; if ( pTracks->track[i].es_elmnt->format_fourcc != 0 ) pTracks->track_attr |= ATTR_AUDIO_PRESENT; } } } if ( video_track_num && !(pTracks->track_attr & ATTR_VIDEO_PRESENT) && video_scrambling_track_num ) pTracks->track_attr |= ATTR_ENCRYPTED_FLAG ; if ( audio_track_num && !(pTracks->track_attr & ATTR_AUDIO_PRESENT) && audio_scrambling_track_num == audio_track_num ) pTracks->track_attr |= ATTR_ENCRYPTED_FLAG ; //return ( pTracks->main_video_index != 0xffff || pTracks->main_audio_index != 0xffff ); } else if ( IS_PS_TYPE ( pTracks->track_type ) ) { if ( pTracks->main_video_index == 0xffff ) { //select main video for ( i = 0; i<pTracks->number_track; i++ ) { if ( pTracks->track[i].av_elmnt->content_type == VIDEO_DATA ) { if ( pTracks->main_video_index == 0xffff ) pTracks->main_video_index = i; else { if ( pTracks->track[i].es_blocks_counter > pTracks->track[ pTracks->main_video_index ].es_blocks_counter ) pTracks->main_video_index = i; } } } } if ( pTracks->main_audio_index == 0xffff ) { //select main audio int weights[64]={0}; for ( i = 0; i<pTracks->number_track && i <64; i++ ) { if ( pTracks->track[i].av_elmnt->content_type == AUDIO_DATA ) { weights[i] = 0; if ( LanguageCode ) weights[i] = pTracks->track[i].es_elmnt->language_code == LanguageCode ? 10000 : pTracks->track[i].es_elmnt->language_code == 0 ? 10000 : 0; weights[i] += pTracks->track[i].es_elmnt->audio_type == 0 ? 9000 : /* normal */ pTracks->track[i].es_elmnt->audio_type == 3 ? 8000 : /* silent */ pTracks->track[i].es_elmnt->audio_type == 2 ? 7000 : /* impaired */ pTracks->track[i].es_elmnt->audio_type == 1 ? 6000 : 0; /* commentary */ weights[i] += GetAudioSoundChannelNum( pTracks->track[i].av_elmnt ) * 100; weights[i] += GetAudioSoundBitRate( pTracks->track[i].av_elmnt ) / 10000; /* range 1-100 */ //skip LPCM because parser isn't ready if ( pTracks->track[i].es_elmnt->format_fourcc == SAGE_FOURCC( "LPCM" ) ) { weights[i] = -20000; } if ( pTracks->main_audio_index == 0xffff ) pTracks->main_audio_index = i; else { if ( weights[i] > weights[ pTracks->main_audio_index ] ) { pTracks->main_audio_index = i; } else if ( weights[i] == weights[ pTracks->main_audio_index ] ) { if ( pTracks->track[i].es_blocks_counter > pTracks->track[ pTracks->main_audio_index ].es_blocks_counter ) pTracks->main_audio_index = i; } } } } } //check video audio present for ( i = 0; i<pTracks->number_track && i <64; i++ ) { if ( pTracks->track[i].es_elmnt->format_fourcc != 0 ) { if ( pTracks->track[i].av_elmnt->content_type == AUDIO_DATA ) pTracks->track_attr |= ATTR_AUDIO_PRESENT; else if ( pTracks->track[i].av_elmnt->content_type == VIDEO_DATA ) pTracks->track_attr |= ATTR_VIDEO_PRESENT; } } //return ( pTracks->main_video_index != 0xffff || pTracks->main_audio_index != 0xffff ); } return ; }
int TracksInfo( TRACKS* pTracks, char* pBuffer, int nSize ) { int i, pos = 0, video_num=0, audio_num=0; int h_264_present=0, video_data_present=0, audio_data_present=0; char *p = pBuffer; ES_ELEMENT *pESElmnt; unsigned long bit_rate = 0; if ( IS_TS_TYPE( pTracks->track_type ) ) { if ( !(pTracks->track_attr & (ATTR_VIDEO_PRESENT|ATTR_AUDIO_PRESENT)) ) { if ( ( pTracks->track_attr & ATTR_ENCRYPTED_FLAG ) ) { pos += snprintf( pBuffer, nSize-pos, "ENCRYPTED-TS;" ); return pos; } pos += snprintf( pBuffer, nSize-pos, "NO-AV-TS;" ); return pos; } if ( pTracks->main_video_index != 0xffff ) pESElmnt = pTracks->track[pTracks->main_video_index].es_elmnt; else if ( pTracks->main_audio_index != 0xffff ) pESElmnt = pTracks->track[pTracks->main_audio_index].es_elmnt; else { pos += snprintf( p+pos, nSize-pos, "Error: no main video and audio specified." ); return 0; //no main track found; } if ( pESElmnt->es_type == ES_MPEG1 ) pos += snprintf( pBuffer, nSize-pos, "MPEG1-TS;" ); else if ( pESElmnt->es_type == ES_MPEG2 ) pos += snprintf( pBuffer, nSize-pos, "MPEG2-TS;" ); else { if ( ( pTracks->track_attr & ATTR_ENCRYPTED_FLAG ) ) pos += snprintf( pBuffer, nSize-pos, "ENCRYPTED-TS;" ); else pos += snprintf( pBuffer, nSize-pos, "UNKNOWN-TS;" ); } } else { if ( pTracks->main_video_index != 0xffff ) pESElmnt = pTracks->track[pTracks->main_video_index].es_elmnt; else if ( pTracks->main_audio_index != 0xffff ) pESElmnt = pTracks->track[pTracks->main_audio_index].es_elmnt; else { pos += snprintf( p+pos, nSize-pos, "Error: no main video and audio specified." ); return 0; //no main track found; } if ( pESElmnt->es_type == ES_MPEG1 ) pos += snprintf( p, nSize-pos, "MPEG1-PS;" ); else if ( pESElmnt->es_type == ES_MPEG2 ) pos += snprintf( p, nSize-pos, "MPEG2-PS;" ); else pos += snprintf( p, nSize-pos, "UNKNOWN-PS;" ); } for ( i = 0; i<pTracks->number_track; i++ ) { if ( pTracks->track[i].ts_elmnt && pTracks->track[i].ts_elmnt->content_type == VIDEO_DATA && pTracks->track[i].ts_packets_counter > 2 ) { video_data_present = 1; if ( pTracks->track[i].ts_elmnt->format_fourcc == SAGE_FOURCC( "H264" ) ) h_264_present=1; } if ( pTracks->track[i].ts_elmnt && pTracks->track[i].ts_elmnt->content_type == AUDIO_DATA && pTracks->track[i].ts_packets_counter > 2 ) { audio_data_present = 1; } if ( pTracks->track[i].av_elmnt->content_type == VIDEO_DATA ) { bit_rate += GetVideoRate( pTracks->track[i].av_elmnt ); video_num++; } if ( pTracks->track[i].av_elmnt->content_type == AUDIO_DATA ) { bit_rate += GetAudioRate( pTracks->track[i].av_elmnt ); audio_num++; } } if ( nSize > pos && bit_rate > 0 ) pos += snprintf( p+pos, nSize-pos, "br=%ld;", bit_rate ); if ( IS_TS_TYPE( pTracks->track_type ) ) { pos += snprintf( p+pos, nSize-pos, "%s", pTracks->track_type==MPEG_M2TS?"ps=192;":pTracks->track_type==MPEG_ASI?"ps=208;":"" ); } if ( video_num == 0 ) { if ( IS_TS_TYPE( pTracks->track_type ) ) { if ( !video_data_present && audio_num > 0) //R5000 recording live tv has enough data to parse out video AV info, pos += snprintf( p+pos, nSize-pos, "audioonly=1;" ); } else { pos += snprintf( p+pos, nSize-pos, "audioonly=1;" ); } } if ( audio_num == 0 ) { if ( IS_TS_TYPE( pTracks->track_type ) ) { if ( !audio_data_present && video_num > 0 ) //R5000 recording live tv has enough data to parse out video AV info, pos += snprintf( p+pos, nSize-pos, "videoonly=1;" ); } else { pos += snprintf( p+pos, nSize-pos, "videoonly=1;" ); } } for ( i = 0; i<pTracks->number_track ; i++ ) { if ( pTracks->track[i].av_elmnt->content_type == VIDEO_DATA ) { if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "[" ); pos += AVElmntInfo( pTracks->track[i].av_elmnt, p+pos, nSize-pos ); if ( i == pTracks->main_video_index ) if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "main=yes;" ); pos += TagInfo( pTracks->track_type, pTracks->track[i].ts_elmnt, pTracks->track[i].es_elmnt, p+pos, nSize-pos ); if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "index=%d;", pTracks->track[i].av_elmnt->stream_index ); if ( nSize > pos+2 ) { p[pos++] = ']'; p[pos++] = ';'; } //terminator } } for ( i = 0; i<pTracks->number_track ; i++ ) { if ( pTracks->track[i].av_elmnt->content_type == AUDIO_DATA ) { char tmp[16]; unsigned long language_code; unsigned char audio_type; if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "[" ); pos += AVElmntInfo( pTracks->track[i].av_elmnt, p+pos, nSize-pos ); if ( i == pTracks->main_audio_index ) if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "main=yes;" ); if ( pTracks->track[i].ts_elmnt != NULL && pTracks->track[i].ts_elmnt->language_code ) { language_code = pTracks->track[i].ts_elmnt->language_code; audio_type = pTracks->track[i].ts_elmnt->audio_type; } else { language_code = pTracks->track[i].es_elmnt->language_code; audio_type = pTracks->track[i].es_elmnt->audio_type; } if ( language_code ) { if ( language_code == LanguageCode( (unsigned char*)"qaa" ) ) strncpy( tmp, "original", sizeof(tmp) ); else Language(language_code, tmp ); if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "lang=%s;", tmp ); } if ( audio_type ) if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "ty=%s;",AudioType(audio_type) ); pos += TagInfo( pTracks->track_type, pTracks->track[i].ts_elmnt, pTracks->track[i].es_elmnt, p+pos, nSize-pos ); if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "index=%d;", pTracks->track[i].av_elmnt->stream_index ); if ( nSize > pos+3 ) { p[pos++] = ']'; p[pos++] = ';'; } //terminator } } for ( i = 0; i<pTracks->number_track ; i++ ) { if ( pTracks->track[i].av_elmnt->content_type == SUBTITLE_DATA ) { char tmp[16]; unsigned long language_code; if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "[" ); pos += AVElmntInfo( pTracks->track[i].av_elmnt, p+pos, nSize-pos ); if ( pTracks->track[i].ts_elmnt != NULL && pTracks->track[i].ts_elmnt->language_code ) language_code = pTracks->track[i].ts_elmnt->language_code; else language_code = pTracks->track[i].es_elmnt->language_code; if ( language_code ) { Language(language_code, tmp ); if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "lang=%s;", tmp ); } pos += TagInfo( pTracks->track_type, pTracks->track[i].ts_elmnt, pTracks->track[i].es_elmnt, p+pos, nSize-pos ); if ( nSize > pos ) pos += snprintf( p+pos, nSize-pos, "index=%d;", pTracks->track[i].av_elmnt->stream_index ); if ( nSize > pos+2 ) { p[pos++] = ']'; p[pos++] = ';'; } //terminator } } if ( pos < nSize ) p[pos]= 0x0; return pos; }