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; }
STDMETHODIMP CTSParserFilter::SetAudioLanguage(CHAR *pszLanguageCode ) { REMUXER* pRemuxer; HRESULT hr = m_pInputPin->GetParser( &pRemuxer ); if ( hr != NOERROR ) return hr; if ( pszLanguageCode == NULL ) return E_INVALIDARG; if ( !stricmp( pszLanguageCode, "original" ) ) pszLanguageCode = "qaa"; SetupEPGDumpLanguage( pRemuxer, LANGUAGE_CODE( pszLanguageCode ) ); //set default language SetDefaultAudioLanguage( pRemuxer, LANGUAGE_CODE( pszLanguageCode ) ); return S_OK; }
CTSParserInputPin::CTSParserInputPin( CTSParserFilter *pFilter, LPUNKNOWN pUnk, CCritSec *pLock, CCritSec *pReceiveLock, HRESULT *phr) : CRenderedInputPin(NAME("CTSSplitterInputPin"), (CBaseFilter *) pFilter, // Filter pLock, // Locking phr, // Return code L"Input") // Pin name , m_pFilter(pFilter) , m_pReceiveLock(pReceiveLock) , m_bCreated(false) { { CAutoLock lock(&m_gTSSplitterLock); MEMORY_TRACK(); } m_pTSRemuxer = (REMUXER*)OpenRemuxStream( REMUX_STREAM , &m_Tune, MPEG_TS, MPEG_PS, NULL, NULL, //MemAllocHook, m_pFilter, OutputDump, m_pFilter ); m_bCreated = true;; m_lUnusedBytes = 0; m_nExpectedBytes = 0; m_nAlignBytes = 0; m_pCScan = NULL; m_bScanChannel = 0; m_mt.SetType(&MEDIATYPE_Stream); m_mt.SetSubtype(&MEDIASUBTYPE_MPEG2_TRANSPORT); m_bIsSagePushSource = FALSE; SetupEPGDumpLanguage( m_pTSRemuxer, LANGUAGE_CODE( "eng" ) ); //set default language SetDefaultAudioLanguage( m_pTSRemuxer, LANGUAGE_CODE( "eng" ) ); } // (Constructor)
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; }