diff --git a/src/AvTranscoder/file/InputFile.cpp b/src/AvTranscoder/file/InputFile.cpp index 38086a24..72e95f77 100644 --- a/src/AvTranscoder/file/InputFile.cpp +++ b/src/AvTranscoder/file/InputFile.cpp @@ -63,7 +63,7 @@ bool InputFile::readNextPacket( CodedData& data, const size_t streamIndex ) const int ret = av_read_frame( &_formatContext.getAVFormatContext(), &data.getAVPacket() ); if( ret < 0 ) // error or end of file { - LOG_INFO( "No more data to read on file '" << _filename << "'" ) + LOG_INFO( "No more data to read on file '" << _filename << "' for stream " << streamIndex ) return false; } diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index 4e90eead..7acb815b 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -556,9 +556,9 @@ void StreamTranscoder::setOffset( const float offset ) StreamTranscoder::EProcessCase StreamTranscoder::getProcessCase() const { - if( _inputStream && _inputDecoder ) + if( _inputStream && _inputDecoder && _currentDecoder == _inputDecoder ) return eProcessCaseTranscode; - else if( _inputStream && ! _inputDecoder ) + else if( _inputStream && ! _inputDecoder && ! _currentDecoder ) return eProcessCaseRewrap; else return eProcessCaseGenerator; diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.hpp b/src/AvTranscoder/transcoder/StreamTranscoder.hpp index 912af924..181a90e3 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.hpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.hpp @@ -101,10 +101,6 @@ class AvExport StreamTranscoder */ void setOffset( const float offset ); -private: - bool processRewrap(); - bool processTranscode( const int subStreamIndex = -1 ); ///< By default transcode all channels - //@{ // Get the current process case. enum EProcessCase { @@ -115,6 +111,10 @@ class AvExport StreamTranscoder EProcessCase getProcessCase() const; //@} +private: + bool processRewrap(); + bool processTranscode( const int subStreamIndex = -1 ); ///< By default transcode all channels + private: IInputStream* _inputStream; ///< Input stream to read next packet (has link, no ownership) IOutputStream* _outputStream; ///< Output stream to wrap next packet (has link, no ownership) diff --git a/src/AvTranscoder/transcoder/Transcoder.cpp b/src/AvTranscoder/transcoder/Transcoder.cpp index 984bf34d..44699cdd 100644 --- a/src/AvTranscoder/transcoder/Transcoder.cpp +++ b/src/AvTranscoder/transcoder/Transcoder.cpp @@ -209,16 +209,33 @@ bool Transcoder::processFrame() if( _streamTranscoders.size() == 0 ) return false; + // For each stream, process a frame + size_t nbStreamProcessStatusFailed = 0; for( size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex ) { LOG_DEBUG( "Process stream " << streamIndex << "/" << ( _streamTranscoders.size() - 1 ) ) - - bool streamProcessStatus = _streamTranscoders.at( streamIndex )->processFrame(); - if( ! streamProcessStatus ) + const bool currentStreamProcessStatus = _streamTranscoders.at( streamIndex )->processFrame(); + if( ! currentStreamProcessStatus ) { - return false; + LOG_WARN( "Failed to process stream " << streamIndex ) + ++nbStreamProcessStatusFailed; } } + + // Get the number of streams without the generators (they always succeed) + size_t nbStreamsWithoutGenerator = _streamTranscoders.size(); + for( size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex ) + { + if( _streamTranscoders.at( streamIndex )->getProcessCase() == StreamTranscoder::eProcessCaseGenerator ) + --nbStreamsWithoutGenerator; + } + + // If all streams failed to process a new frame + if( nbStreamProcessStatusFailed == nbStreamsWithoutGenerator ) + { + LOG_INFO( "End of process because all streams (except generators) failed to process a new frame." ) + return false; + } return true; } @@ -241,32 +258,37 @@ ProcessStat Transcoder::process( IProgress& progress ) preProcessCodecLatency(); - const float outputDuration = getOutputDuration(); + const float outputDuration = getExpectedOutputDuration(); LOG_INFO( "Output duration of the process will be " << outputDuration << "s." ) size_t frame = 0; bool frameProcessed = true; while( frameProcessed ) { - const float progressDuration = _outputFile.getStream( 0 ).getStreamDuration(); + const float progressDuration = getCurrentOutputDuration(); // check if JobStatusCancel if( progress.progress( ( progressDuration > outputDuration ) ? outputDuration : progressDuration, outputDuration ) == eJobStatusCancel ) + { + LOG_INFO( "End of process because the job was canceled." ) break; + } // check progressDuration - if( progressDuration >= outputDuration ) + if( _eProcessMethod == eProcessMethodBasedOnDuration && progressDuration >= outputDuration ) + { + LOG_INFO( "End of process because the output program duration (" << progressDuration << "s) is equal or upper than " << outputDuration << "s." ) break; + } LOG_DEBUG( "Process frame " << frame ) frameProcessed = processFrame(); - ++frame; } _outputFile.endWrap(); - LOG_INFO( "End of process" ) + LOG_INFO( "End of process: " << frame << " frames processed" ) LOG_INFO( "Get process statistics" ) ProcessStat processStat; @@ -460,7 +482,7 @@ float Transcoder::getMaxTotalDuration() const return maxTotalDuration; } -float Transcoder::getOutputDuration() const +float Transcoder::getExpectedOutputDuration() const { switch( _eProcessMethod ) { @@ -479,6 +501,20 @@ float Transcoder::getOutputDuration() const } } +float Transcoder::getCurrentOutputDuration() const +{ + float currentOutputDuration = -1; + for( size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex ) + { + const float currentStreamDuration = _outputFile.getStream( streamIndex ).getStreamDuration(); + if( currentOutputDuration == -1 ) + currentOutputDuration = currentStreamDuration; + else if( currentStreamDuration < currentOutputDuration ) + currentOutputDuration = currentStreamDuration; + } + return currentOutputDuration; +} + void Transcoder::manageSwitchToGenerator() { for( size_t i = 0; i < _streamTranscoders.size(); ++i ) diff --git a/src/AvTranscoder/transcoder/Transcoder.hpp b/src/AvTranscoder/transcoder/Transcoder.hpp index b0407859..0f89c662 100644 --- a/src/AvTranscoder/transcoder/Transcoder.hpp +++ b/src/AvTranscoder/transcoder/Transcoder.hpp @@ -180,10 +180,17 @@ class AvExport Transcoder float getMaxTotalDuration() const; /** - * @brief Get the duration of the output program + * @brief Get the expected duration of the output program * @note Depends on the streams, the process method, and the main stream index. */ - float getOutputDuration() const; + float getExpectedOutputDuration() const; + + /** + * @brief Get the current duration of the output program + * @note Returns the duration of the smallest stream. + * @return -1 if there is no output stream. + */ + float getCurrentOutputDuration() const; /** * @brief Set for each StreamTranscoder if it can switch to generator at the end.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: