StreamTranscoder::StreamTranscoder( IInputStream& inputStream, IOutputFile& outputFile, const ProfileLoader::Profile& profile, const int subStreamIndex, const double offset ) : _inputStream( &inputStream ) , _outputStream( NULL ) , _sourceBuffer( NULL ) , _frameBuffer( NULL ) , _inputDecoder( NULL ) , _generator( NULL ) , _currentDecoder( NULL ) , _outputEncoder( NULL ) , _transform( NULL ) , _subStreamIndex( subStreamIndex ) , _offset( offset ) , _canSwitchToGenerator( false ) { // create a transcode case switch( _inputStream->getStreamType() ) { case AVMEDIA_TYPE_VIDEO : { // input decoder VideoDecoder* inputVideo = new VideoDecoder( *static_cast<InputStream*>( _inputStream ) ); // set decoder options with empty profile to set some key options to specific values (example: threads to auto) inputVideo->setProfile( ProfileLoader::Profile() ); inputVideo->setup(); _inputDecoder = inputVideo; _currentDecoder = _inputDecoder; // output encoder VideoEncoder* outputVideo = new VideoEncoder( profile.at( constants::avProfileCodec ) ); _outputEncoder = outputVideo; VideoFrameDesc outputFrameDesc = _inputStream->getVideoCodec().getVideoFrameDesc(); outputFrameDesc.setParameters( profile ); outputVideo->setProfile( profile, outputFrameDesc ); // output stream _outputStream = &outputFile.addVideoStream( outputVideo->getVideoCodec() ); // buffers to process _sourceBuffer = new VideoFrame( _inputStream->getVideoCodec().getVideoFrameDesc() ); _frameBuffer = new VideoFrame( outputVideo->getVideoCodec().getVideoFrameDesc() ); // transform _transform = new VideoTransform(); // generator decoder VideoGenerator* generatorVideo = new VideoGenerator(); generatorVideo->setVideoFrameDesc( outputVideo->getVideoCodec().getVideoFrameDesc() ); _generator = generatorVideo; break; } case AVMEDIA_TYPE_AUDIO : { // input decoder AudioDecoder* inputAudio = new AudioDecoder( *static_cast<InputStream*>( _inputStream ) ); // set decoder options with empty profile to set some key options to specific values (example: threads to auto) inputAudio->setProfile( ProfileLoader::Profile() ); inputAudio->setup(); _inputDecoder = inputAudio; _currentDecoder = _inputDecoder; // output encoder AudioEncoder* outputAudio = new AudioEncoder( profile.at( constants::avProfileCodec ) ); _outputEncoder = outputAudio; AudioFrameDesc outputFrameDesc( _inputStream->getAudioCodec().getAudioFrameDesc() ); outputFrameDesc.setParameters( profile ); if( subStreamIndex > -1 ) { // @todo manage downmix ? outputFrameDesc.setChannels( 1 ); } outputAudio->setProfile( profile, outputFrameDesc ); // output stream _outputStream = &outputFile.addAudioStream( outputAudio->getAudioCodec() ); // buffers to process AudioFrameDesc inputFrameDesc( _inputStream->getAudioCodec().getAudioFrameDesc() ); if( subStreamIndex > -1 ) inputFrameDesc.setChannels( 1 ); _sourceBuffer = new AudioFrame( inputFrameDesc ); _frameBuffer = new AudioFrame( outputAudio->getAudioCodec().getAudioFrameDesc() ); // transform _transform = new AudioTransform(); // generator decoder AudioGenerator* generatorAudio = new AudioGenerator(); generatorAudio->setAudioFrameDesc( outputAudio->getAudioCodec().getAudioFrameDesc() ); _generator = generatorAudio; break; } default: { throw std::runtime_error( "unupported stream type" ); break; } } if( offset ) switchToGeneratorDecoder(); }