void AudioDecoder::setProfile( const ProfileLoader::Profile& profile ) { LOG_DEBUG( "Set profile of audio decoder with:\n" << profile ) AudioCodec& codec = _inputStream->getAudioCodec(); // set threads before any other options if( profile.count( constants::avProfileThreads ) ) codec.getOption( constants::avProfileThreads ).setString( profile.at( constants::avProfileThreads ) ); else codec.getOption( constants::avProfileThreads ).setString( "auto" ); // set decoder options for( ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it ) { if( (*it).first == constants::avProfileIdentificator || (*it).first == constants::avProfileIdentificatorHuman || (*it).first == constants::avProfileType || (*it).first == constants::avProfileThreads ) continue; try { Option& decodeOption = codec.getOption( (*it).first ); decodeOption.setString( (*it).second ); } catch( std::exception& e ) { LOG_WARN( "AudioDecoder - can't set option " << (*it).first << " to " << (*it).second << ": " << e.what() ) } } }
void AudioDecoder::setupDecoder( const ProfileLoader::Profile& profile ) { // check the given profile const bool isValid = ProfileLoader::checkAudioProfile( profile ); if( ! isValid && ! profile.empty() ) { const std::string msg( "Invalid audio profile to setup decoder." ); LOG_ERROR( msg ) throw std::runtime_error( msg ); } if( ! profile.empty() ) { LOG_INFO( "Setup audio decoder with:\n" << profile ) } AudioCodec& codec = _inputStream->getAudioCodec(); // set threads before any other options if( profile.count( constants::avProfileThreads ) ) codec.getOption( constants::avProfileThreads ).setString( profile.at( constants::avProfileThreads ) ); else codec.getOption( constants::avProfileThreads ).setInt( codec.getAVCodecContext().thread_count ); // set decoder options for( ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it ) { if( (*it).first == constants::avProfileIdentificator || (*it).first == constants::avProfileIdentificatorHuman || (*it).first == constants::avProfileType || (*it).first == constants::avProfileThreads ) continue; try { Option& decodeOption = codec.getOption( (*it).first ); decodeOption.setString( (*it).second ); } catch( std::exception& e ) { LOG_WARN( "AudioDecoder - can't set option " << (*it).first << " to " << (*it).second << ": " << e.what() ) } } // open decoder _inputStream->getAudioCodec().openCodec(); _isSetup = true; }
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(); }