StreamTranscoder::StreamTranscoder( const ICodec& inputCodec, IOutputFile& outputFile, const ProfileLoader::Profile& profile ) : _inputStream( NULL ) , _outputStream( NULL ) , _sourceBuffer( NULL ) , _frameBuffer( NULL ) , _inputDecoder( NULL ) , _generator( NULL ) , _currentDecoder( NULL ) , _outputEncoder( NULL ) , _transform( NULL ) , _subStreamIndex( -1 ) , _offset( 0 ) , _canSwitchToGenerator( false ) { if( profile.find( constants::avProfileType )->second == constants::avProfileTypeVideo ) { // generator decoder VideoGenerator* generatorVideo = new VideoGenerator(); const VideoCodec& inputVideoCodec = static_cast<const VideoCodec&>( inputCodec ); generatorVideo->setVideoFrameDesc( inputVideoCodec.getVideoFrameDesc() ); _currentDecoder = generatorVideo; // buffers to process VideoFrameDesc inputFrameDesc = inputVideoCodec.getVideoFrameDesc(); VideoFrameDesc outputFrameDesc = inputFrameDesc; outputFrameDesc.setParameters( profile ); _sourceBuffer = new VideoFrame( inputFrameDesc ); _frameBuffer = new VideoFrame( outputFrameDesc ); // transform _transform = new VideoTransform(); // output encoder VideoEncoder* outputVideo = new VideoEncoder( profile.at( constants::avProfileCodec ) ); outputVideo->setProfile( profile, outputFrameDesc ); _outputEncoder = outputVideo; // output stream _outputStream = &outputFile.addVideoStream( outputVideo->getVideoCodec() ); } else if( profile.find( constants::avProfileType )->second == constants::avProfileTypeAudio ) { // generator decoder AudioGenerator* generatorAudio = new AudioGenerator(); const AudioCodec& inputAudioCodec = static_cast<const AudioCodec&>( inputCodec ); generatorAudio->setAudioFrameDesc( inputAudioCodec.getAudioFrameDesc() ); _currentDecoder = generatorAudio; // buffers to process AudioFrameDesc inputFrameDesc = inputAudioCodec.getAudioFrameDesc(); AudioFrameDesc outputFrameDesc = inputFrameDesc; outputFrameDesc.setParameters( profile ); _sourceBuffer = new AudioFrame( inputFrameDesc ); _frameBuffer = new AudioFrame( outputFrameDesc ); // transform _transform = new AudioTransform(); // output encoder AudioEncoder* outputAudio = new AudioEncoder( profile.at( constants::avProfileCodec ) ); outputAudio->setProfile( profile, outputFrameDesc ); _outputEncoder = outputAudio; // output stream _outputStream = &outputFile.addAudioStream( outputAudio->getAudioCodec() ); } else { throw std::runtime_error( "unupported stream type" ); } }
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(); }