From c032b653563ff2df53bcce8e5c3f2f7d7b9835e9 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 30 Jun 2014 14:03:44 +0200 Subject: [PATCH 1/5] Profile: can loadProfiles with the constructor By default the list of profiles is not loaded. --- src/AvTranscoder/Profile.cpp | 5 +++-- src/AvTranscoder/Profile.hpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/AvTranscoder/Profile.cpp b/src/AvTranscoder/Profile.cpp index e8ddfcc3..c41cdd89 100644 --- a/src/AvTranscoder/Profile.cpp +++ b/src/AvTranscoder/Profile.cpp @@ -21,9 +21,10 @@ const std::string Profile::avProfileTypeVideo( "avProfileTypeVideo" ); const std::string Profile::avProfileTypeAudio( "avProfileTypeAudio" ); -Profile::Profile() +Profile::Profile( bool autoload ) { - + if( autoload ) + loadProfiles(); } void Profile::loadProfiles() diff --git a/src/AvTranscoder/Profile.hpp b/src/AvTranscoder/Profile.hpp index 35db4ee3..eb3a13a0 100644 --- a/src/AvTranscoder/Profile.hpp +++ b/src/AvTranscoder/Profile.hpp @@ -23,7 +23,7 @@ class Profile typedef std::map< std::string, std::string > ProfileDesc; typedef std::vector< ProfileDesc > ProfilesDesc; - Profile(); + Profile( bool autoload = false ); void loadProfiles(); From b034e6e86b059ce6d2f7a1fe29aefda92882da18 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 30 Jun 2014 14:04:32 +0200 Subject: [PATCH 2/5] Profile: implement getAudioProfiles --- src/AvTranscoder/Profile.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/AvTranscoder/Profile.cpp b/src/AvTranscoder/Profile.cpp index c41cdd89..c9150979 100644 --- a/src/AvTranscoder/Profile.cpp +++ b/src/AvTranscoder/Profile.cpp @@ -101,6 +101,12 @@ Profile::ProfilesDesc Profile::getAudioProfiles() { ProfilesDesc profiles; + for( ProfilesDesc::iterator it = _profiles.begin(); it != _profiles.end(); ++it ) + { + if( (*it).find( avProfileType )->second == avProfileTypeAudio ) + profiles.push_back( *it ); + } + return profiles; } From 00d169491c824cdb277d155eb3d05a596724095a Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 30 Jun 2014 14:05:56 +0200 Subject: [PATCH 3/5] Profile: add update function The function updates the corresponding profile, or create a new one if it doesn't exist. --- src/AvTranscoder/Profile.cpp | 16 ++++++++++++++++ src/AvTranscoder/Profile.hpp | 2 ++ 2 files changed, 18 insertions(+) diff --git a/src/AvTranscoder/Profile.cpp b/src/AvTranscoder/Profile.cpp index c9150979..9e9cd4ec 100644 --- a/src/AvTranscoder/Profile.cpp +++ b/src/AvTranscoder/Profile.cpp @@ -79,6 +79,22 @@ void Profile::loadProfiles() } } +void Profile::update( const ProfileDesc& profile ) +{ + std::string profileId( profile.find( avProfileIdentificator )->second ); + size_t profileIndex = 0; + for( ProfilesDesc::iterator it = _profiles.begin(); it != _profiles.end(); ++it ) + { + if( (*it).find( avProfileIdentificator )->second == profileId ) + { + _profiles.at( profileIndex ) = profile; + return; + } + ++profileIndex; + } + _profiles.push_back( profile ); +} + const Profile::ProfilesDesc& Profile::getProfiles() { return _profiles; diff --git a/src/AvTranscoder/Profile.hpp b/src/AvTranscoder/Profile.hpp index eb3a13a0..b7092d45 100644 --- a/src/AvTranscoder/Profile.hpp +++ b/src/AvTranscoder/Profile.hpp @@ -27,6 +27,8 @@ class Profile void loadProfiles(); + void update( const ProfileDesc& profile ); + const ProfilesDesc& getProfiles(); ProfilesDesc getVideoProfiles(); From 8ea50c6e06222971fbff5920bca939ade137c372 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 30 Jun 2014 14:22:37 +0200 Subject: [PATCH 4/5] Transcoder: can add a stream with a custum profile * Transcoder: 3 ways to add a stream, which call the private function add( const InputStreamDesc& streamDefinition ). * This impacts: * StreamTranscoder: init with a ProfileDesc instead of a profileName. * OutputEssence (and the subclasses OutputVideo and OutputAudio): set profile with a ProfileDesc instead of a profileName. * swig avTranscoder.i: include Profile because of includes in output essence source files. * avTranscoder app.: can't update the profile with only the profileName. * optionChecker app.: set the profile with the profileDesc. --- app/avTranscoder/avTranscoder.cpp | 3 +- app/presetChecker/presetChecker.cpp | 4 +- .../EssenceStream/OutputAudio.cpp | 10 ++-- .../EssenceStream/OutputAudio.hpp | 5 +- .../EssenceStream/OutputEssence.hpp | 6 ++- .../EssenceStream/OutputVideo.cpp | 16 ++----- .../EssenceStream/OutputVideo.hpp | 6 ++- .../Transcoder/StreamTranscoder.cpp | 15 +++--- .../Transcoder/StreamTranscoder.hpp | 3 +- src/AvTranscoder/Transcoder/Transcoder.cpp | 47 +++++++++++++------ src/AvTranscoder/Transcoder/Transcoder.hpp | 43 +++++++++++++++-- src/AvTranscoder/avTranscoder.i | 4 ++ 12 files changed, 111 insertions(+), 51 deletions(-) diff --git a/app/avTranscoder/avTranscoder.cpp b/app/avTranscoder/avTranscoder.cpp index 0de8cd4c..ffc01613 100644 --- a/app/avTranscoder/avTranscoder.cpp +++ b/app/avTranscoder/avTranscoder.cpp @@ -16,6 +16,7 @@ void transcodeVideo( const char* inputfilename, const char* outputFilename ) // av_log_set_level( AV_LOG_DEBUG ); + Profile profile( true ); ProgressListener p; InputFile input( inputfilename ); @@ -29,7 +30,7 @@ void transcodeVideo( const char* inputfilename, const char* outputFilename ) // init video encoder OutputVideo outputVideo; - outputVideo.setProfile( "xdcamhd422" ); + outputVideo.setProfile( profile.getProfile( "xdcamhd422" ) ); Image imageToEncode( outputVideo.getVideoDesc().getImageDesc() ); DataStream codedImage; diff --git a/app/presetChecker/presetChecker.cpp b/app/presetChecker/presetChecker.cpp index 30dfbd99..80525ae9 100644 --- a/app/presetChecker/presetChecker.cpp +++ b/app/presetChecker/presetChecker.cpp @@ -25,13 +25,13 @@ int main( int argc, char** argv ) if( profile.find( avtranscoder::Profile::avProfileType )->second == avtranscoder::Profile::avProfileTypeVideo ) { avtranscoder::OutputVideo outputVideo; - outputVideo.setProfile( profile.find( avtranscoder::Profile::avProfileIdentificator )->second ); + outputVideo.setProfile( profile ); } if( profile.find( avtranscoder::Profile::avProfileType )->second == avtranscoder::Profile::avProfileTypeAudio ) { avtranscoder::OutputAudio outputAudio; - outputAudio.setProfile( profile.find( avtranscoder::Profile::avProfileIdentificator )->second ); + outputAudio.setProfile( profile ); } } diff --git a/src/AvTranscoder/EssenceStream/OutputAudio.cpp b/src/AvTranscoder/EssenceStream/OutputAudio.cpp index c7237a5e..24689bda 100644 --- a/src/AvTranscoder/EssenceStream/OutputAudio.cpp +++ b/src/AvTranscoder/EssenceStream/OutputAudio.cpp @@ -166,14 +166,10 @@ bool OutputAudio::encodeFrame( DataStream& codedFrame ) #endif } -void OutputAudio::setProfile( const std::string& profile ) +void OutputAudio::setProfile( Profile::ProfileDesc& desc ) { - Profile p; - p.loadProfiles(); - Profile::ProfileDesc profDesc = p.getProfile( profile ); - - _audioDesc.setAudioCodec( profDesc["codec"] ); - _audioDesc.setAudioParameters( 48000, 2, av_get_sample_fmt( profDesc["sample_fmt"].c_str() ) ); + _audioDesc.setAudioCodec( desc["codec"] ); + _audioDesc.setAudioParameters( 48000, 2, av_get_sample_fmt( desc["sample_fmt"].c_str() ) ); setup(); } diff --git a/src/AvTranscoder/EssenceStream/OutputAudio.hpp b/src/AvTranscoder/EssenceStream/OutputAudio.hpp index 2a359c4a..111eaec0 100644 --- a/src/AvTranscoder/EssenceStream/OutputAudio.hpp +++ b/src/AvTranscoder/EssenceStream/OutputAudio.hpp @@ -2,9 +2,12 @@ #define _AV_TRANSCODER_ESSENCE_STREAM_OUTPUT_AUDIO_HPP_ #include "OutputEssence.hpp" + #include #include +#include + namespace avtranscoder { @@ -25,7 +28,7 @@ class OutputAudio : public OutputEssence */ bool encodeFrame( DataStream& codedFrame ); - void setProfile( const std::string& profile ); + void setProfile( Profile::ProfileDesc& desc ); AudioDesc& getAudioDesc() { return _audioDesc; } diff --git a/src/AvTranscoder/EssenceStream/OutputEssence.hpp b/src/AvTranscoder/EssenceStream/OutputEssence.hpp index 017763ee..bd99d772 100644 --- a/src/AvTranscoder/EssenceStream/OutputEssence.hpp +++ b/src/AvTranscoder/EssenceStream/OutputEssence.hpp @@ -14,6 +14,8 @@ extern "C" { #include #include +#include + namespace avtranscoder { @@ -50,9 +52,9 @@ class AvExport OutputEssence /** * @brief Set the profile for the encoder * @note see Profile to get list of supported profiles - * @param profile selected profile name + * @param desc description of the selected profile */ - virtual void setProfile( const std::string& profile ) = 0; + virtual void setProfile( Profile::ProfileDesc& desc ) = 0; }; diff --git a/src/AvTranscoder/EssenceStream/OutputVideo.cpp b/src/AvTranscoder/EssenceStream/OutputVideo.cpp index a90b5120..07981d94 100644 --- a/src/AvTranscoder/EssenceStream/OutputVideo.cpp +++ b/src/AvTranscoder/EssenceStream/OutputVideo.cpp @@ -176,19 +176,13 @@ bool OutputVideo::encodeFrame( DataStream& codedFrame ) #endif } -void OutputVideo::setProfile( const std::string& profile ) +void OutputVideo::setProfile( Profile::ProfileDesc& desc ) { - Profile p; - - p.loadProfiles(); - - Profile::ProfileDesc prof = p.getProfile( profile ); - - _videoDesc.setVideoCodec( prof[ "codec" ] ); + _videoDesc.setVideoCodec( desc[ "codec" ] ); _videoDesc.setTimeBase( 1, 25 ); // 25 fps - _videoDesc.setImageParameters( 1920, 1080, av_get_pix_fmt( prof[ "pix_fmt" ].c_str() ) ); + _videoDesc.setImageParameters( 1920, 1080, av_get_pix_fmt( desc[ "pix_fmt" ].c_str() ) ); - for( Profile::ProfileDesc::iterator it = prof.begin(); it != prof.end(); ++it ) + for( Profile::ProfileDesc::iterator it = desc.begin(); it != desc.end(); ++it ) { if( (*it).first == Profile::avProfileIdentificator ) continue; @@ -217,7 +211,7 @@ void OutputVideo::setProfile( const std::string& profile ) setup(); - for( Profile::ProfileDesc::iterator it = prof.begin(); it != prof.end(); ++it ) + for( Profile::ProfileDesc::iterator it = desc.begin(); it != desc.end(); ++it ) { if( (*it).first == Profile::avProfileIdentificator ) continue; diff --git a/src/AvTranscoder/EssenceStream/OutputVideo.hpp b/src/AvTranscoder/EssenceStream/OutputVideo.hpp index 0e8990d4..145c0d17 100644 --- a/src/AvTranscoder/EssenceStream/OutputVideo.hpp +++ b/src/AvTranscoder/EssenceStream/OutputVideo.hpp @@ -13,6 +13,8 @@ extern "C" { #include #include +#include + #include #include @@ -41,10 +43,10 @@ class AvExport OutputVideo : public OutputEssence */ bool encodeFrame( DataStream& codedFrame ); + void setProfile( Profile::ProfileDesc& desc ); + VideoDesc& getVideoDesc() { return _videoDesc; } - void setProfile( const std::string& profile ); - private: VideoDesc _videoDesc; }; diff --git a/src/AvTranscoder/Transcoder/StreamTranscoder.cpp b/src/AvTranscoder/Transcoder/StreamTranscoder.cpp index 5d0e7838..66cef761 100644 --- a/src/AvTranscoder/Transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/Transcoder/StreamTranscoder.cpp @@ -27,9 +27,10 @@ StreamTranscoder::~StreamTranscoder() delete _outputEssence; } -void StreamTranscoder::init( const std::string& profile ) +void StreamTranscoder::init( const Profile::ProfileDesc& profileDesc ) { - _transcodeStream = profile.size(); + const std::string profileName = profileDesc.find( Profile::avProfileIdentificator )->second; + _transcodeStream = profileName.size(); switch( _stream->getStreamType() ) { @@ -39,7 +40,7 @@ void StreamTranscoder::init( const std::string& profile ) _inputEssence->setup(); // re-wrap only, get output descriptor from input - if( profile.empty() ) + if( profileName.empty() ) { _outputFile->addVideoStream( _stream->getVideoDesc() ); break; @@ -48,7 +49,8 @@ void StreamTranscoder::init( const std::string& profile ) OutputVideo* outputVideo = new OutputVideo(); _outputEssence = outputVideo; - _outputEssence->setProfile( profile ); + Profile::ProfileDesc prof = profileDesc; + _outputEssence->setProfile( prof ); _outputFile->addVideoStream( outputVideo->getVideoDesc() ); _videoFrameBuffer = new Image( outputVideo->getVideoDesc().getImageDesc() ); _frameBuffer = _videoFrameBuffer; @@ -61,7 +63,7 @@ void StreamTranscoder::init( const std::string& profile ) _inputEssence->setup(); // re-wrap only, get output descriptor from input - if( profile.empty() ) + if( profileName.empty() ) { _outputFile->addAudioStream( _stream->getAudioDesc() ); break; @@ -70,7 +72,8 @@ void StreamTranscoder::init( const std::string& profile ) OutputAudio* outputAudio = new OutputAudio(); _outputEssence = outputAudio; - _outputEssence->setProfile( profile ); + Profile::ProfileDesc prof = profileDesc; + _outputEssence->setProfile( prof ); _outputFile->addAudioStream( outputAudio->getAudioDesc() ); _audioFrameBuffer = new AudioFrame( outputAudio->getAudioDesc().getFrameDesc() ); _frameBuffer = _audioFrameBuffer; diff --git a/src/AvTranscoder/Transcoder/StreamTranscoder.hpp b/src/AvTranscoder/Transcoder/StreamTranscoder.hpp index 9f004f85..a96dda7f 100644 --- a/src/AvTranscoder/Transcoder/StreamTranscoder.hpp +++ b/src/AvTranscoder/Transcoder/StreamTranscoder.hpp @@ -11,6 +11,7 @@ #include +#include namespace avtranscoder { @@ -21,7 +22,7 @@ class StreamTranscoder StreamTranscoder( InputStream& stream, OutputFile& outputFile, const size_t& streamId ); ~StreamTranscoder(); - void init( const std::string& profile ); + void init( const Profile::ProfileDesc& profileDesc ); bool processFrame(); diff --git a/src/AvTranscoder/Transcoder/Transcoder.cpp b/src/AvTranscoder/Transcoder/Transcoder.cpp index 9494d2d4..290ed659 100644 --- a/src/AvTranscoder/Transcoder/Transcoder.cpp +++ b/src/AvTranscoder/Transcoder/Transcoder.cpp @@ -9,6 +9,7 @@ namespace avtranscoder Transcoder::Transcoder( OutputFile& outputFile ) : _outputFile( outputFile ) + , _profile( true ) { _outputFile.setup(); } @@ -31,8 +32,36 @@ Transcoder::~Transcoder() } } -void Transcoder::add( const std::string& filename, const size_t streamIndex, const std::string& profile ) +void Transcoder::add( const std::string& filename, const size_t streamIndex, const std::string& profileName ) { + InputStreamDesc streamDesc( streamIndex, filename, profileName ); + add( streamDesc ); +} + +void Transcoder::add( const std::string& filename, const size_t streamIndex, const Profile::ProfileDesc& profileDesc ) +{ + _profile.update( profileDesc ); + + InputStreamDesc streamDesc( streamIndex, filename, profileDesc ); + add( streamDesc ); +} + +void Transcoder::add( const InputStreamsDesc& streamDefs ) +{ + for( size_t streamDest = 0; streamDest < streamDefs.size(); ++streamDest ) + { + add( streamDefs.at( streamDest ) ); + } + if( _inputStreams.size() != _streamTranscoders.size() ) + throw std::runtime_error( "_inputStreams and _streamTranscoders must have the same number of streams" ); +} + +void Transcoder::add( const InputStreamDesc& streamDefinition ) +{ + const std::string filename( streamDefinition.filename ); + const size_t streamIndex = streamDefinition.streamId; + const Profile::ProfileDesc profileDesc = streamDefinition.transcodeProfile; + if( ! filename.length() ) { try @@ -82,7 +111,7 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con case AVMEDIA_TYPE_VIDEO: { StreamTranscoder* streamTranscoder = new StreamTranscoder( referenceFile->getStream( streamIndex ), _outputFile, _streamTranscoders.size() ); - streamTranscoder->init( profile ); + streamTranscoder->init( profileDesc ); _streamTranscoders.push_back( streamTranscoder ); _inputStreams.push_back( & referenceFile->getStream( streamIndex ) ); break; @@ -90,7 +119,7 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con case AVMEDIA_TYPE_AUDIO: { StreamTranscoder* streamTranscoder = new StreamTranscoder( referenceFile->getStream( streamIndex ), _outputFile, _streamTranscoders.size() ); - streamTranscoder->init( profile ); + streamTranscoder->init( profileDesc ); _streamTranscoders.push_back( streamTranscoder ); _inputStreams.push_back( & referenceFile->getStream( streamIndex ) ); break; @@ -106,18 +135,6 @@ void Transcoder::add( const std::string& filename, const size_t streamIndex, con return; } -void Transcoder::add( const InputStreamsDesc& streamDefs ) -{ - for( size_t streamDest = 0; streamDest < streamDefs.size(); ++streamDest ) - { - add( streamDefs.at( streamDest ).filename, - streamDefs.at( streamDest ).streamId, - streamDefs.at( streamDest ).transcodeProfile ); - } - if( _inputStreams.size() != _streamTranscoders.size() ) - throw std::runtime_error( "error during settings streams and transcoders" ); -} - bool Transcoder::processFrame() { diff --git a/src/AvTranscoder/Transcoder/Transcoder.hpp b/src/AvTranscoder/Transcoder/Transcoder.hpp index 83fbd5e1..c9c63391 100644 --- a/src/AvTranscoder/Transcoder/Transcoder.hpp +++ b/src/AvTranscoder/Transcoder/Transcoder.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -22,14 +23,34 @@ class Transcoder struct InputStreamDesc { size_t streamId; std::string filename; - std::string transcodeProfile; + Profile::ProfileDesc transcodeProfile; - InputStreamDesc( const size_t& sId, const std::string& filename, const std::string& profile ) + InputStreamDesc( const size_t& sId, const std::string& filename, const Profile::ProfileDesc& profile ) : streamId( sId ) , filename( filename ) , transcodeProfile( profile ) { } + + InputStreamDesc( const size_t& sId, const std::string& filename, const std::string& profileName ) + : streamId( sId ) + , filename( filename ) + { + try + { + Profile p( true ); + transcodeProfile = p.getProfile( profileName ); + } + // if the profile doesn't exist + catch( std::exception& e ) + { + Profile::ProfileDesc emptyDesc; + emptyDesc[ Profile::avProfileIdentificator ] = ""; + emptyDesc[ Profile::avProfileIdentificatorHuman ] = ""; + + transcodeProfile = emptyDesc; + } + } }; typedef std::vector< InputStreamDesc > InputStreamsDesc; @@ -37,7 +58,19 @@ class Transcoder Transcoder( OutputFile& outputFile ); ~Transcoder(); - void add( const std::string& filename, const size_t streamIndex, const std::string& profile ); + /** + * @brief Add a stream and set a profile + * @note If profile is empty, add a dummy stream. + */ + void add( const std::string& filename, const size_t streamIndex, const std::string& profileName = "" ); + /** + * @brief Add a srteam 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, const Profile::ProfileDesc& profileDesc ); + /** + * @brief Add a list of streams. + */ void add( const InputStreamsDesc& streamDefs ); bool processFrame(); @@ -45,6 +78,8 @@ class Transcoder void process( ProgressListener& progress ); private: + void add( const InputStreamDesc& streamDefinition ); + bool getStreamsNextPacket( std::vector< DataStream >& dataStreams ); private: @@ -55,6 +90,8 @@ class Transcoder std::vector< StreamTranscoder* > _streamTranscoders; std::vector< DummyInputStream* > _dummyInputStreams; + + Profile _profile; }; } diff --git a/src/AvTranscoder/avTranscoder.i b/src/AvTranscoder/avTranscoder.i index 9926261f..8397d156 100644 --- a/src/AvTranscoder/avTranscoder.i +++ b/src/AvTranscoder/avTranscoder.i @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -68,6 +70,8 @@ namespace std { %include +%include + %include %include From a9515a79fb1fbf8e9fd2cb9e7581457ee1d7bb12 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 30 Jun 2014 14:44:52 +0200 Subject: [PATCH 5/5] Profile: add comment --- src/AvTranscoder/Profile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AvTranscoder/Profile.cpp b/src/AvTranscoder/Profile.cpp index 9e9cd4ec..5d524344 100644 --- a/src/AvTranscoder/Profile.cpp +++ b/src/AvTranscoder/Profile.cpp @@ -92,6 +92,7 @@ void Profile::update( const ProfileDesc& profile ) } ++profileIndex; } + // profile not found: add the new profile _profiles.push_back( profile ); }