diff --git a/app/genericProcessor/genericProcessor.cpp b/app/genericProcessor/genericProcessor.cpp index da67d7a8..c9858b76 100644 --- a/app/genericProcessor/genericProcessor.cpp +++ b/app/genericProcessor/genericProcessor.cpp @@ -108,13 +108,16 @@ int main( int argc, char** argv ) avtranscoder::OutputFile outputFile( argv[2] ); avtranscoder::Transcoder transcoder( outputFile ); - transcoder.setVerbose( verbose ); - transcoder.setProcessMethod( avtranscoder::eProcessMethodShortest ); if( verbose ) std::cout << "parse config file" << std::endl; parseConfigFile( inputConfigFile, transcoder, profiles ); + // set verbose of all stream + transcoder.setVerbose( verbose ); + transcoder.setProcessMethod( avtranscoder::eProcessMethodInfinity ); + //transcoder.setOutputFps( 12 ); + if( verbose ) std::cout << "start Transcode" << std::endl; diff --git a/src/AvTranscoder/Transcoder/StreamTranscoder.cpp b/src/AvTranscoder/Transcoder/StreamTranscoder.cpp index 12e8a04b..9f9d415e 100644 --- a/src/AvTranscoder/Transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/Transcoder/StreamTranscoder.cpp @@ -15,6 +15,7 @@ #include #include +#include namespace avtranscoder { @@ -32,9 +33,12 @@ StreamTranscoder::StreamTranscoder( , _outputEssence( NULL ) , _transform( NULL ) , _subStreamIndex( -1 ) - , _transcodeStream( false ) - , _infiniteProcess( false ) + , _frameProcessed( 0 ) + , _offset( 0 ) + , _takeFromDummy( false ) , _verbose( false ) + , _offsetPassed( false ) + , _infinityStream( false ) { // create a re-wrapping case switch( _inputStream->getStreamType() ) @@ -58,7 +62,8 @@ StreamTranscoder::StreamTranscoder( InputStream& inputStream, OutputFile& outputFile, const Profile::ProfileDesc& profile, - const int subStreamIndex + const int subStreamIndex, + const size_t offset ) : _inputStream( &inputStream ) , _outputStream( NULL ) @@ -69,9 +74,12 @@ StreamTranscoder::StreamTranscoder( , _outputEssence( NULL ) , _transform( NULL ) , _subStreamIndex( subStreamIndex ) - , _transcodeStream( true ) - , _infiniteProcess( false ) + , _frameProcessed( 0 ) + , _offset( offset ) + , _takeFromDummy( false ) , _verbose( false ) + , _offsetPassed( false ) + , _infinityStream( false ) { // create a transcode case switch( _inputStream->getStreamType() ) @@ -99,8 +107,6 @@ StreamTranscoder::StreamTranscoder( DummyVideo* dummyVideo = new DummyVideo(); dummyVideo->setVideoDesc( outputVideo->getVideoDesc() ); _dummyEssence = dummyVideo; - - _currentEssence = _inputEssence; break; } @@ -137,8 +143,6 @@ StreamTranscoder::StreamTranscoder( dummyAudio->setAudioDesc( outputAudio->getAudioDesc() ); _dummyEssence = dummyAudio; - _currentEssence = _inputEssence; - break; } default: @@ -147,6 +151,7 @@ StreamTranscoder::StreamTranscoder( break; } } + switchEssence( offset != 0 ); } StreamTranscoder::StreamTranscoder( @@ -163,9 +168,12 @@ StreamTranscoder::StreamTranscoder( , _outputEssence( NULL ) , _transform( NULL ) , _subStreamIndex( -1 ) - , _transcodeStream( true ) - , _infiniteProcess( false ) + , _frameProcessed( 0 ) + , _offset( 0 ) + , _takeFromDummy( false ) , _verbose( false ) + , _offsetPassed( false ) + , _infinityStream( false ) { // create a coding case based on a InputEssence (aka dummy reader) if( ! profile.count( Profile::avProfileType ) ) @@ -237,7 +245,8 @@ StreamTranscoder::~StreamTranscoder() bool StreamTranscoder::processFrame() { - if( _transcodeStream ) + ++_frameProcessed; + if( _transform ) { if( _subStreamIndex < 0 ) { @@ -275,12 +284,10 @@ bool StreamTranscoder::processRewrap( const int subStreamIndex ) assert( _outputStream != NULL ); DataStream dataStream; - // std::vector dataStream; if( ! _inputStream->readNextPacket( dataStream ) ) return false; _outputStream->wrap( dataStream ); - // outputStream.wrap( dataStream.at( subStreamIndex ) ); return true; } @@ -297,6 +304,16 @@ bool StreamTranscoder::processTranscode() DataStream dataStream; if( _verbose ) std::cout << "transcode a frame " << std::endl; + + if( _offset && + _frameProcessed > _offset && + ! _offsetPassed && + _takeFromDummy ) + { + switchToInputEssence(); + _offsetPassed = true; + } + if( _currentEssence->readNextFrame( *_sourceBuffer ) ) { if( _verbose ) @@ -308,16 +325,15 @@ bool StreamTranscoder::processTranscode() } else { - if( _infiniteProcess ) - { - switchToDummyEssence(); - return processTranscode( ); - } - if( _verbose ) std::cout << "encode last frame(s)" << std::endl; if( ! _outputEssence->encodeFrame( dataStream ) ) { + if( _infinityStream ) + { + switchToDummyEssence(); + return processTranscode(); + } return false; } } @@ -340,6 +356,16 @@ bool StreamTranscoder::processTranscode( const int subStreamIndex ) DataStream dataStream; if( _verbose ) std::cout << "transcode a frame " << std::endl; + + if( _offset && + _frameProcessed > _offset && + ! _offsetPassed && + _takeFromDummy ) + { + switchToInputEssence(); + _offsetPassed = true; + } + if( _currentEssence->readNextFrame( *_sourceBuffer, subStreamIndex ) ) { if( _verbose ) @@ -351,14 +377,15 @@ bool StreamTranscoder::processTranscode( const int subStreamIndex ) } else { - if( _infiniteProcess ) - { - switchToDummyEssence(); - return processTranscode( ); - } - + if( _verbose ) + std::cout << "encode last frame(s)" << std::endl; if( ! _outputEssence->encodeFrame( dataStream ) ) { + if( _infinityStream ) + { + switchToDummyEssence(); + return processTranscode(); + } return false; } } @@ -368,22 +395,35 @@ bool StreamTranscoder::processTranscode( const int subStreamIndex ) return true; } -void StreamTranscoder::switchToDummyEssence() +void StreamTranscoder::switchEssence( bool swithToDummy ) { - if( _dummyEssence == NULL ) - return; - _takeFromDummy = true; - _currentEssence = _dummyEssence; + _takeFromDummy = swithToDummy; + _currentEssence = swithToDummy ? _dummyEssence : _inputEssence; assert( _currentEssence != NULL ); } +void StreamTranscoder::switchToDummyEssence() +{ + switchEssence( true ); +} + void StreamTranscoder::switchToInputEssence() { - if( _inputEssence == NULL ) - return; - _takeFromDummy = false; - _currentEssence = _inputEssence; - assert( _currentEssence != NULL ); + switchEssence( false ); +} + +double StreamTranscoder::getDuration() const +{ + if( _inputStream ) + { + double totalDuration = 0; + totalDuration += _inputStream->getDuration(); + // @todo add offset + return totalDuration; + } + // dummy + else + return std::numeric_limits::max(); } } diff --git a/src/AvTranscoder/Transcoder/StreamTranscoder.hpp b/src/AvTranscoder/Transcoder/StreamTranscoder.hpp index 290a68f4..79dde63c 100644 --- a/src/AvTranscoder/Transcoder/StreamTranscoder.hpp +++ b/src/AvTranscoder/Transcoder/StreamTranscoder.hpp @@ -22,16 +22,18 @@ class StreamTranscoder public: /** * @brief rewrap stream + * @note offset feature when rewrap a stream is not supported **/ StreamTranscoder( InputStream& inputStream, OutputFile& outputFile ); /** * @brief transcode stream **/ - StreamTranscoder( InputStream& inputStream, OutputFile& outputFile, const Profile::ProfileDesc& profile, const int subStreamIndex = -1 ); + StreamTranscoder( InputStream& inputStream, OutputFile& outputFile, const Profile::ProfileDesc& profile, const int subStreamIndex = -1, const size_t offset = 0 ); /** * @brief encode from dummy stream + * @note offset feature has no sense here **/ StreamTranscoder( InputEssence& inputEssence, OutputFile& outputFile, const Profile::ProfileDesc& profile ); @@ -43,13 +45,21 @@ class StreamTranscoder */ bool processFrame(); - bool isTranscodeStream() const { return _transcodeStream; } + void switchEssence( bool swithToDummy = true ); + void switchToDummyEssence(); + void switchToInputEssence(); void setVerbose( bool verbose = true ){ _verbose = verbose; } - void switchToDummyEssence(); - void switchToInputEssence(); - void setInfinityProcess( bool infinity = true ){ _infiniteProcess = infinity; } + void setInfinityStream( bool isInfinity ) { _infinityStream = isInfinity; } + + void setOffset( bool offset = true ){ _offset = offset; } + + /** + * @brief Get the duration of the stream. + * @note if it's a dummy stream, return limit of double. + */ + double getDuration() const; private: bool processRewrap(); @@ -72,11 +82,27 @@ class StreamTranscoder EssenceTransform* _transform; int _subStreamIndex; - bool _transcodeStream; + + /** + * @brief How many frame processed for this StreamTranscoder. + */ + size_t _frameProcessed; + /** + * @brief Offset, in frame, at the beginning of the StreamTranscoder. + */ + size_t _offset; + bool _takeFromDummy; - bool _infiniteProcess; bool _verbose; + + bool _offsetPassed; + + /** + * @brief Automatic switch to dummy + * @note not applicable when rewrap + */ + bool _infinityStream; }; } diff --git a/src/AvTranscoder/Transcoder/Transcoder.cpp b/src/AvTranscoder/Transcoder/Transcoder.cpp index 26bbf862..1510c1c4 100644 --- a/src/AvTranscoder/Transcoder/Transcoder.cpp +++ b/src/AvTranscoder/Transcoder/Transcoder.cpp @@ -40,7 +40,7 @@ Transcoder::~Transcoder() } } -void Transcoder::add( const std::string& filename, const size_t streamIndex, const std::string& profileName ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, const std::string& profileName, const size_t offset ) { if( profileName.length() == 0 ) // no profile, only re-wrap stream { @@ -51,10 +51,10 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con } Profile::ProfileDesc& transcodeProfile = _profile.getProfile( profileName ); - add( filename, streamIndex, transcodeProfile ); + add( filename, streamIndex, transcodeProfile, offset ); } -void Transcoder::add( const std::string& filename, const size_t streamIndex, const std::string& profileName, CodedDesc& essenceDesc ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, const std::string& profileName, CodedDesc& essenceDesc, const size_t offset ) { if( profileName.length() == 0 ) // no profile, only re-wrap stream { @@ -72,25 +72,24 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con } Profile::ProfileDesc& transcodeProfile = _profile.getProfile( profileName ); - add( filename, streamIndex, transcodeProfile, essenceDesc ); + add( filename, streamIndex, transcodeProfile, essenceDesc, offset ); } -void Transcoder::add( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profileDesc ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profileDesc, const size_t offset ) { _profile.update( profileDesc ); if( ! filename.length() ) { - // if( _verbose ) std::cerr << "can't add a stream with no filename indicated" << std::endl; return; } if( _verbose ) std::cout << "add transcoding stream" << std::endl; - addTranscodeStream( filename, streamIndex, profileDesc ); + addTranscodeStream( filename, streamIndex, profileDesc, offset ); } -void Transcoder::add( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profileDesc, CodedDesc& essenceDesc ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profileDesc, CodedDesc& essenceDesc, const size_t offset ) { _profile.update( profileDesc ); if( ! filename.length() ) @@ -103,14 +102,14 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, Pro if( _verbose ) std::cout << "add transcoding stream" << std::endl; - addTranscodeStream( filename, streamIndex, profileDesc ); + addTranscodeStream( filename, streamIndex, profileDesc, offset ); } -void Transcoder::add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName, const size_t offset ) { if( subStreamIndex < 0 ) { - add( filename, streamIndex, profileName ); + add( filename, streamIndex, profileName, offset ); return; } @@ -124,10 +123,10 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con } Profile::ProfileDesc& transcodeProfile = _profile.getProfile( profileName ); - add( filename, streamIndex, subStreamIndex, transcodeProfile ); + add( filename, streamIndex, subStreamIndex, transcodeProfile, offset ); } -void Transcoder::add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName, CodedDesc& essenceDesc ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName, CodedDesc& essenceDesc, const size_t offset ) { if( subStreamIndex < 0 ) { @@ -151,16 +150,16 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con } Profile::ProfileDesc& transcodeProfile = _profile.getProfile( profileName ); - add( filename, streamIndex, subStreamIndex, transcodeProfile, essenceDesc ); + add( filename, streamIndex, subStreamIndex, transcodeProfile, essenceDesc, offset ); } -void Transcoder::add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, Profile::ProfileDesc& profileDesc ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, Profile::ProfileDesc& profileDesc, const size_t offset ) { _profile.update( profileDesc ); if( subStreamIndex < 0 ) { - add( filename, streamIndex, profileDesc ); + add( filename, streamIndex, profileDesc, offset ); return; } @@ -173,10 +172,10 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con if( _verbose ) std::cout << "add transcoding stream for substream " << subStreamIndex << std::endl; - addTranscodeStream( filename, streamIndex, subStreamIndex, profileDesc ); + addTranscodeStream( filename, streamIndex, subStreamIndex, profileDesc, offset ); } -void Transcoder::add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, Profile::ProfileDesc& profileDesc, CodedDesc& essenceDesc ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, Profile::ProfileDesc& profileDesc, CodedDesc& essenceDesc, const size_t offset ) { _profile.update( profileDesc ); @@ -196,7 +195,7 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con if( _verbose ) std::cout << "add transcoding stream for substream " << subStreamIndex << std::endl; - addTranscodeStream( filename, streamIndex, subStreamIndex, profileDesc ); + addTranscodeStream( filename, streamIndex, subStreamIndex, profileDesc, offset ); } void Transcoder::add( StreamTranscoder& stream ) @@ -220,27 +219,10 @@ bool Transcoder::processFrame() bool streamProcessStatus = _streamTranscoders.at( streamIndex )->processFrame(); - if( streamProcessStatus ) - continue; - - switch( _eProcessMethod ) + if( ! streamProcessStatus ) { - case eProcessMethodShortest : - _streamTranscoders.clear(); - break; - case eProcessMethodLongest : - ++_finalisedStreams; - _streamTranscoders.at( streamIndex )->switchToDummyEssence(); - if( _verbose ) - std::cout << "-> switch to dummy for stream " << streamIndex << std::endl; - if( _finalisedStreams == _streamTranscoders.size() ) - _streamTranscoders.clear(); - break; - case eProcessMethodInfinity : - if( _verbose ) - std::cout << "-> infinity processing: switch to dummy for stream " << streamIndex << std::endl; - _streamTranscoders.at( streamIndex )->switchToDummyEssence(); - break; + _streamTranscoders.clear(); + return false; } } return true; @@ -273,21 +255,13 @@ void Transcoder::process( ProgressListener& progress ) _outputFile.beginWrap(); double totalDuration = std::numeric_limits::max(); - double minTotalDuration = std::numeric_limits::max(); - double maxTotalDuration = 0; - - for( size_t i = 0; i < _inputStreams.size(); ++i ) - { - minTotalDuration = std::min( _inputStreams.at( i )->getDuration(), minTotalDuration ); - maxTotalDuration = std::max( _inputStreams.at( i )->getDuration(), maxTotalDuration ); - } switch( _eProcessMethod ) { case eProcessMethodShortest : - totalDuration = minTotalDuration; + totalDuration = getMinTotalDuration(); break; case eProcessMethodLongest : - totalDuration = maxTotalDuration; + totalDuration = getMaxTotalDuration(); break; case eProcessMethodInfinity : totalDuration = std::numeric_limits::max(); @@ -321,9 +295,27 @@ void Transcoder::process( ProgressListener& progress ) void Transcoder::setProcessMethod( const EProcessMethod eProcessMethod ) { _eProcessMethod = eProcessMethod; - for( std::vector< StreamTranscoder* >::iterator it = _streamTranscoders.begin(); it != _streamTranscoders.end(); ++it ) + + for( size_t i = 0; i < _streamTranscoders.size(); ++i ) { - (*it)->setInfinityProcess( eProcessMethod == eProcessMethodInfinity ); + switch( _eProcessMethod ) + { + case eProcessMethodShortest : + if( _streamTranscoders.at( i )->getDuration() == getMinTotalDuration() ) + _streamTranscoders.at( i )->setInfinityStream( false ); + else + _streamTranscoders.at( i )->setInfinityStream( true ); + break; + case eProcessMethodLongest : + if( _streamTranscoders.at( i )->getDuration() == getMaxTotalDuration() ) + _streamTranscoders.at( i )->setInfinityStream( false ); + else + _streamTranscoders.at( i )->setInfinityStream( true ); + break; + case eProcessMethodInfinity : + _streamTranscoders.at( i )->setInfinityStream( true ); + break; + } } } @@ -344,7 +336,7 @@ void Transcoder::addRewrapStream( const std::string& filename, const size_t stre _inputStreams.push_back( &referenceFile->getStream( streamIndex ) ); } -void Transcoder::addTranscodeStream( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profile ) +void Transcoder::addTranscodeStream( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profile, const size_t offset ) { InputFile* referenceFile = addInputFile( filename, streamIndex ); @@ -353,7 +345,7 @@ void Transcoder::addTranscodeStream( const std::string& filename, const size_t s case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_AUDIO: { - _streamTranscoders.push_back( new StreamTranscoder( referenceFile->getStream( streamIndex ), _outputFile, profile ) ); + _streamTranscoders.push_back( new StreamTranscoder( referenceFile->getStream( streamIndex ), _outputFile, profile, -1 , offset ) ); _inputStreams.push_back( &referenceFile->getStream( streamIndex ) ); break; } @@ -367,7 +359,7 @@ void Transcoder::addTranscodeStream( const std::string& filename, const size_t s } } -void Transcoder::addTranscodeStream( const std::string& filename, const size_t streamIndex, const size_t subStreamIndex, Profile::ProfileDesc& profile ) +void Transcoder::addTranscodeStream( const std::string& filename, const size_t streamIndex, const size_t subStreamIndex, Profile::ProfileDesc& profile, const size_t offset ) { InputFile* referenceFile = addInputFile( filename, streamIndex ); @@ -376,7 +368,7 @@ void Transcoder::addTranscodeStream( const std::string& filename, const size_t s case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_AUDIO: { - _streamTranscoders.push_back( new StreamTranscoder( referenceFile->getStream( streamIndex ), _outputFile, profile, subStreamIndex ) ); + _streamTranscoders.push_back( new StreamTranscoder( referenceFile->getStream( streamIndex ), _outputFile, profile, subStreamIndex, offset ) ); _inputStreams.push_back( &referenceFile->getStream( streamIndex ) ); break; } @@ -443,4 +435,26 @@ InputFile* Transcoder::addInputFile( const std::string& filename, const size_t s return referenceFile; } +double Transcoder::getMinTotalDuration() const +{ + double minTotalDuration = std::numeric_limits::max(); + + for( size_t i = 0; i < _streamTranscoders.size(); ++i ) + { + minTotalDuration = std::min( _streamTranscoders.at( i )->getDuration(), minTotalDuration ); + } + return minTotalDuration; +} + +double Transcoder::getMaxTotalDuration() const +{ + double maxTotalDuration = 0; + + for( size_t i = 0; i < _streamTranscoders.size(); ++i ) + { + maxTotalDuration = std::max( _streamTranscoders.at( i )->getDuration(), maxTotalDuration ); + } + return maxTotalDuration; +} + } diff --git a/src/AvTranscoder/Transcoder/Transcoder.hpp b/src/AvTranscoder/Transcoder/Transcoder.hpp index d7f8fa39..ccc76f7f 100644 --- a/src/AvTranscoder/Transcoder/Transcoder.hpp +++ b/src/AvTranscoder/Transcoder/Transcoder.hpp @@ -48,72 +48,102 @@ class Transcoder * @brief Add a stream and set a profile * @note If profileName is empty, rewrap. */ - void add( const std::string& filename, const size_t streamIndex, const std::string& profileName = "" ); + void add( const std::string& filename, const size_t streamIndex, const std::string& profileName = "", const size_t offset = 0 ); /* * @note If filename is empty, add a dummy stream. * @note If filename is empty, profileName can't be empty (no sens to rewrap a dummy stream). */ - void add( const std::string& filename, const size_t streamIndex, const std::string& profileName, CodedDesc& essenceDesc ); + void add( const std::string& filename, const size_t streamIndex, const std::string& profileName, CodedDesc& essenceDesc, const size_t offset = 0 ); /** * @brief Add a stream and set a custom profile * @note Profile will be updated, be sure to pass unique profile name. */ - void add( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profileDesc ); + void add( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profileDesc, const size_t offset = 0 ); /* * @note If filename is empty, add a dummy stream. */ - void add( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profileDesc, CodedDesc& essenceDesc ); + void add( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profileDesc, CodedDesc& essenceDesc, const size_t offset = 0 ); /** * @brief Add a stream and set a profile * @note If profileName is empty, rewrap. * @note If subStreamIndex is negative, no substream is selected it's the stream. */ - void add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName = "" ); + void add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName = "", const size_t offset = 0 ); /** * @note If filename is empty, add a dummy stream. * @note If filename is empty, profileName can't be empty (no sens to rewrap a dummy stream). */ - void add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName, CodedDesc& essenceDesc ); + void add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, const std::string& profileName, CodedDesc& essenceDesc, const size_t offset = 0 ); /** * @brief Add a stream and set a custom profile * @note Profile will be updated, be sure to pass unique profile name. * @note If subStreamIndex is negative, no substream is selected it's the stream. */ - void add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, Profile::ProfileDesc& profileDesc ); + void add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, Profile::ProfileDesc& profileDesc, const size_t offset = 0 ); /** * @note If filename is empty, add a dummy stream. */ - void add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, Profile::ProfileDesc& profileDesc, CodedDesc& essenceDesc ); + void add( const std::string& filename, const size_t streamIndex, const int subStreamIndex, Profile::ProfileDesc& profileDesc, CodedDesc& essenceDesc, const size_t offset = 0 ); /** * @brief Add the stream * @note The stream will be deleted in Transcoder's destructor. */ void add( StreamTranscoder& stream ); - + + /** + * @brief Process the next frame of all streams. + * @return if a frame was processed or not. + */ bool processFrame(); + /** + * @brief Process all the streams, and ended the process depending on the transcode politic. + * @param progress + */ void process( ProgressListener& progress ); + /** + * @brief Set the transcodage politic. + * @note If you call it before adding the streams, the process will stop at the end of the shortest stream. + */ void setProcessMethod( const EProcessMethod eProcessMethod ); + /** + * @brief Set verbose mode for the Transcoder and his streams. + * @note If you call it before adding the streams, no verbose mode will be set for the new streams. + */ void setVerbose( bool verbose = true ); + void setOutputFps( double fps ) { _outputFps = fps; } + private: void addRewrapStream( const std::string& filename, const size_t streamIndex ); - void addTranscodeStream( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profile ); + void addTranscodeStream( const std::string& filename, const size_t streamIndex, Profile::ProfileDesc& profile, const size_t offset = 0 ); - void addTranscodeStream( const std::string& filename, const size_t streamIndex, const size_t subStreamIndex, Profile::ProfileDesc& profile ); + void addTranscodeStream( const std::string& filename, const size_t streamIndex, const size_t subStreamIndex, Profile::ProfileDesc& profile, const size_t offset = 0 ); void addDummyStream( const Profile::ProfileDesc& profile, const CodedDesc& essenceDesc ); InputFile* addInputFile( const std::string& filename, const size_t streamIndex ); + /** + * @brief Get the duration of the shortest stream. + * @note if there is only dummy, return limit of double. + */ + double getMinTotalDuration() const; + + /** + * @brief Get the duration of the longest stream. + * @note if there is only dummy, return limit of double. + */ + double getMaxTotalDuration() const; + private: OutputFile& _outputFile; std::vector< InputFile* > _inputFiles;