diff --git a/app/avMeta/avMeta.cpp b/app/avMeta/avMeta.cpp index d74e4ae9..ce466112 100644 --- a/app/avMeta/avMeta.cpp +++ b/app/avMeta/avMeta.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include @@ -16,7 +16,7 @@ int main( int argc, char** argv ) avtranscoder::NoDisplayProgress p; avtranscoder::InputFile input( argv[1] ); - input.analyse( p, avtranscoder::InputFile::eAnalyseLevelFull ); + input.analyse( p, avtranscoder::eAnalyseLevelFirstGop ); // a simply metadata display std::cout << input; diff --git a/app/avTranscoder/avTranscoder.cpp b/app/avTranscoder/avTranscoder.cpp index 218a3ccd..e1001e58 100644 --- a/app/avTranscoder/avTranscoder.cpp +++ b/app/avTranscoder/avTranscoder.cpp @@ -28,7 +28,7 @@ void transcodeVideo( const char* inputfilename, const char* outputFilename ) InputFile input( inputfilename ); input.analyse( p ); - input.readStream( input.getProperties().videoStreams.at( 0 ).streamId ); + input.readStream( input.getProperties().getVideoProperties().at( 0 ).getStreamId() ); // init video decoders AvInputVideo inputVideo( input.getStream( 0 ) ); diff --git a/app/avplay/AvReader.hpp b/app/avplay/AvReader.hpp index 5cda2c80..60fbd0cd 100644 --- a/app/avplay/AvReader.hpp +++ b/app/avplay/AvReader.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include @@ -23,7 +23,7 @@ class AvReader : public Reader avtranscoder::ConsoleProgress p; _inputFile.analyse( p ); - _videoStream = _inputFile.getProperties().videoStreams.at(0).streamId; + _videoStream = _inputFile.getProperties().getVideoProperties().at(0).getStreamId(); _inputFile.readStream( _videoStream ); @@ -58,17 +58,17 @@ class AvReader : public Reader size_t getWidth() { - return _inputFile.getProperties().videoStreams.at(0).width; + return _inputFile.getProperties().getVideoProperties().at(0).getWidth(); }; size_t getHeight() { - return _inputFile.getProperties().videoStreams.at(0).height; + return _inputFile.getProperties().getVideoProperties().at(0).getHeight(); } size_t getComponents() { - return _inputFile.getProperties().videoStreams.at(0).componentsCount; + return _inputFile.getProperties().getVideoProperties().at(0).getComponentsCount(); } size_t getBitDepth() diff --git a/app/genericProcessor/genericProcessor.cpp b/app/genericProcessor/genericProcessor.cpp index 381c10e4..95591013 100644 --- a/app/genericProcessor/genericProcessor.cpp +++ b/app/genericProcessor/genericProcessor.cpp @@ -114,7 +114,6 @@ int main( int argc, char** argv ) // set verbose of all stream transcoder.setVerbose( verbose ); transcoder.setProcessMethod( avtranscoder::eProcessMethodLongest ); - //transcoder.setOutputFps( 12 ); transcoder.init(); if( verbose ) diff --git a/app/presetChecker/presetChecker.cpp b/app/presetChecker/presetChecker.cpp index e3ca2ac7..d987f3b7 100644 --- a/app/presetChecker/presetChecker.cpp +++ b/app/presetChecker/presetChecker.cpp @@ -34,7 +34,7 @@ int main( int argc, char** argv ) if( profile.find( avtranscoder::constants::avProfileType )->second == avtranscoder::constants::avProfileTypeAudio ) { avtranscoder::AvOutputAudio outputAudio; - outputAudio.setProfile( profile, outputAudio.getAudioCodec().getFrameDesc() ); + outputAudio.setProfile( profile, outputAudio.getAudioCodec().getAudioFrameDesc() ); } } catch( ... ) diff --git a/src/AvTranscoder/avTranscoder.i b/src/AvTranscoder/avTranscoder.i index 5768f912..8ae01290 100644 --- a/src/AvTranscoder/avTranscoder.i +++ b/src/AvTranscoder/avTranscoder.i @@ -25,8 +25,6 @@ #include #include -#include - #include #include @@ -40,28 +38,22 @@ #include #include #include - -#include -#include +#include +#include #include #include %} -namespace std { +namespace std { %template(IntPair) pair< size_t, size_t >; -%template(VideoVector) vector< avtranscoder::VideoProperties >; -%template(AudioVector) vector< avtranscoder::AudioProperties >; -%template(MetadataPair) pair< string, string >; -%template(MetadatasVector) vector< pair< string, string > >; -%template(GopPair) pair< char, bool >; -%template(GopVector) vector< pair< char, bool > >; -%template(ChannelVector) vector< avtranscoder::Channel >; %template(ProfileMap) map< string, string >; %template(ProfilesVector) vector< map< string, string > >; +%template(DataBuffer) std::vector< unsigned char >; } %include "AvTranscoder/progress/progress.i" +%include "AvTranscoder/mediaProperty/mediaProperty.i" %include @@ -75,8 +67,6 @@ namespace std { %include %include -%include - %include %include @@ -90,9 +80,10 @@ namespace std { %include %include %include +%include +%include -%include -%include +%include "AvTranscoder/file/file.i" %include %include diff --git a/src/AvTranscoder/codec/AudioCodec.cpp b/src/AvTranscoder/codec/AudioCodec.cpp index b96bbdaf..ba94746e 100644 --- a/src/AvTranscoder/codec/AudioCodec.cpp +++ b/src/AvTranscoder/codec/AudioCodec.cpp @@ -20,7 +20,7 @@ AudioCodec::AudioCodec( const ICodec& codec ) { } -AudioFrameDesc AudioCodec::getFrameDesc() const +AudioFrameDesc AudioCodec::getAudioFrameDesc() const { assert( _codecContext != NULL ); AudioFrameDesc audioFrameDesc; @@ -33,24 +33,6 @@ AudioFrameDesc AudioCodec::getFrameDesc() const return audioFrameDesc; } -const size_t AudioCodec::getSampleRate() const -{ - assert( _codecContext != NULL ); - return _codecContext->sample_rate; -} - -const size_t AudioCodec::getChannels() const -{ - assert( _codecContext != NULL ); - return _codecContext->channels; -} - -const AVSampleFormat AudioCodec::getAVSampleFormat() const -{ - assert( _codecContext != NULL ); - return _codecContext->sample_fmt; -} - void AudioCodec::setAudioParameters( const AudioFrameDesc& audioFrameDesc ) { setAudioParameters( audioFrameDesc.getSampleRate(), audioFrameDesc.getChannels(), audioFrameDesc.getAVSampleFormat() ); diff --git a/src/AvTranscoder/codec/AudioCodec.hpp b/src/AvTranscoder/codec/AudioCodec.hpp index 5d86e1aa..75c0734c 100644 --- a/src/AvTranscoder/codec/AudioCodec.hpp +++ b/src/AvTranscoder/codec/AudioCodec.hpp @@ -14,11 +14,8 @@ class AvExport AudioCodec : public ICodec AudioCodec( const ECodecType type, const AVCodecID codecId ); AudioCodec( const ICodec& codec ); - AudioFrameDesc getFrameDesc() const; - const size_t getSampleRate() const; - const size_t getChannels() const; - const AVSampleFormat getAVSampleFormat() const; - + AudioFrameDesc getAudioFrameDesc() const; + void setAudioParameters( const AudioFrameDesc& audioFrameDesc ); void setAudioParameters( const size_t sampleRate, const size_t channels, const AVSampleFormat sampleFormat ); }; diff --git a/src/AvTranscoder/codec/VideoCodec.cpp b/src/AvTranscoder/codec/VideoCodec.cpp index faae1076..f29b581b 100644 --- a/src/AvTranscoder/codec/VideoCodec.cpp +++ b/src/AvTranscoder/codec/VideoCodec.cpp @@ -23,14 +23,16 @@ VideoCodec::VideoCodec( const ICodec& codec ) VideoFrameDesc VideoCodec::getVideoFrameDesc() const { assert( _codecContext != NULL ); - VideoFrameDesc VideoFrameDesc; + + VideoFrameDesc videoFrameDesc; + videoFrameDesc.setWidth ( _codecContext->width ); + videoFrameDesc.setHeight( _codecContext->height ); + videoFrameDesc.setDar( _codecContext->width, _codecContext->height ); + Pixel pixel( _codecContext->pix_fmt ); + videoFrameDesc.setPixel( pixel ); - VideoFrameDesc.setWidth ( _codecContext->width ); - VideoFrameDesc.setHeight( _codecContext->height ); - VideoFrameDesc.setPixel ( pixel ); - VideoFrameDesc.setDar ( _codecContext->height, _codecContext->width ); - return VideoFrameDesc; + return videoFrameDesc; } std::pair< size_t, size_t > VideoCodec::getTimeBase() const diff --git a/src/AvTranscoder/codedStream/AvInputStream.cpp b/src/AvTranscoder/codedStream/AvInputStream.cpp index 3f143b7f..1e6c15e0 100644 --- a/src/AvTranscoder/codedStream/AvInputStream.cpp +++ b/src/AvTranscoder/codedStream/AvInputStream.cpp @@ -17,7 +17,6 @@ AvInputStream::AvInputStream( InputFile& inputFile, const size_t streamIndex ) : IInputStream( ) , _inputFile( &inputFile ) , _codec( NULL ) - , _packetDuration( 0 ) , _streamIndex( streamIndex ) , _bufferized( false ) { @@ -98,7 +97,6 @@ void AvInputStream::addPacket( AVPacket& packet ) //std::cout << "add packet for stream " << _streamIndex << std::endl; CodedData data; _streamCache.push_back( data ); - _packetDuration = packet.duration; if( ! _bufferized ) return; @@ -166,11 +164,6 @@ double AvInputStream::getDuration() const return 1.0 * _inputFile->getFormatContext().duration / AV_TIME_BASE; } -double AvInputStream::getPacketDuration() const -{ - return _packetDuration * av_q2d( _inputFile->getFormatContext().streams[_streamIndex]->time_base ); -} - void AvInputStream::clearBuffering() { _streamCache.clear(); diff --git a/src/AvTranscoder/codedStream/AvInputStream.hpp b/src/AvTranscoder/codedStream/AvInputStream.hpp index e13ebbdf..a34ce6d8 100644 --- a/src/AvTranscoder/codedStream/AvInputStream.hpp +++ b/src/AvTranscoder/codedStream/AvInputStream.hpp @@ -30,7 +30,6 @@ class AvExport AvInputStream : public IInputStream AVMediaType getStreamType() const; double getDuration() const; - double getPacketDuration() const; void addPacket( AVPacket& packet ); @@ -43,14 +42,13 @@ class AvExport AvInputStream : public IInputStream AVStream* getAVStream() const; private: - InputFile* _inputFile; - std::vector _streamCache; - + InputFile* _inputFile; ///< Has link (no ownership) ICodec* _codec; ///< Has ownership - int _packetDuration; - size_t _streamIndex; - bool _bufferized; + std::vector _streamCache; + + size_t _streamIndex; ///< Index of the stream in the input file + bool _bufferized; ///< If the stream is bufferized }; } diff --git a/src/AvTranscoder/codedStream/AvOutputStream.hpp b/src/AvTranscoder/codedStream/AvOutputStream.hpp index 2b23ea83..bda78453 100644 --- a/src/AvTranscoder/codedStream/AvOutputStream.hpp +++ b/src/AvTranscoder/codedStream/AvOutputStream.hpp @@ -18,9 +18,9 @@ class AvExport AvOutputStream : public IOutputStream IOutputStream::EWrappingStatus wrap( const CodedData& data ); private: - OutputFile* _outputFile; + OutputFile* _outputFile; ///< Has link (no ownership) - size_t _streamIndex; + size_t _streamIndex; ///< Index of the stream in the output file }; } diff --git a/src/AvTranscoder/codedStream/IInputStream.hpp b/src/AvTranscoder/codedStream/IInputStream.hpp index 1557b0e7..4f9ae9a1 100644 --- a/src/AvTranscoder/codedStream/IInputStream.hpp +++ b/src/AvTranscoder/codedStream/IInputStream.hpp @@ -26,7 +26,6 @@ class IInputStream virtual AVMediaType getStreamType() const = 0; virtual double getDuration() const = 0; - virtual double getPacketDuration() const = 0; virtual void setBufferred( const bool bufferized ) = 0; diff --git a/src/AvTranscoder/essenceStream/AvInputAudio.cpp b/src/AvTranscoder/essenceStream/AvInputAudio.cpp index 0187f20e..e369d88d 100644 --- a/src/AvTranscoder/essenceStream/AvInputAudio.cpp +++ b/src/AvTranscoder/essenceStream/AvInputAudio.cpp @@ -20,9 +20,9 @@ namespace avtranscoder AvInputAudio::AvInputAudio( AvInputStream& inputStream ) : IInputEssence() , _inputStream ( &inputStream ) - , _codec( eCodecTypeDecoder, inputStream.getAudioCodec().getCodecId() ) + , _codec( &inputStream.getAudioCodec() ) , _frame ( NULL ) - , _selectedStream( -1 ) + , _selectedStream( inputStream.getStreamIndex() ) { } @@ -46,10 +46,10 @@ AvInputAudio::~AvInputAudio() void AvInputAudio::setup() { - AVCodecContext* avCodecContext = _codec.getAVCodecContext(); - AVCodec* avCodec = _codec.getAVCodec(); + AVCodecContext* avCodecContext = _codec->getAVCodecContext(); + AVCodec* avCodec = _codec->getAVCodec(); - avCodecContext->channels = _inputStream->getAudioCodec().getChannels(); + avCodecContext->channels = _inputStream->getAudioCodec().getAudioFrameDesc().getChannels(); int ret = avcodec_open2( avCodecContext, avCodec, NULL ); @@ -82,10 +82,10 @@ void AvInputAudio::setup() bool AvInputAudio::readNextFrame( Frame& frameBuffer ) { - if( ! getNextFrame() ) + if( ! decodeNextFrame() ) return false; - AVCodecContext* avCodecContext = _codec.getAVCodecContext(); + AVCodecContext* avCodecContext = _codec->getAVCodecContext(); size_t decodedSize = av_samples_get_buffer_size( NULL, avCodecContext->channels, @@ -116,14 +116,14 @@ bool AvInputAudio::readNextFrame( Frame& frameBuffer ) bool AvInputAudio::readNextFrame( Frame& frameBuffer, const size_t subStreamIndex ) { - if( ! getNextFrame() ) + if( ! decodeNextFrame() ) return false; const int output_nbChannels = 1; const int output_align = 1; - size_t decodedSize = av_samples_get_buffer_size(NULL, output_nbChannels, _frame->nb_samples, _codec.getAVCodecContext()->sample_fmt, output_align); + size_t decodedSize = av_samples_get_buffer_size(NULL, output_nbChannels, _frame->nb_samples, _codec->getAVCodecContext()->sample_fmt, output_align); - size_t nbSubStreams = _codec.getAVCodecContext()->channels; + size_t nbSubStreams = _codec->getAVCodecContext()->channels; size_t bytePerSample = av_get_bytes_per_sample( (AVSampleFormat)_frame->format ); if( subStreamIndex > nbSubStreams - 1 ) @@ -156,7 +156,7 @@ bool AvInputAudio::readNextFrame( Frame& frameBuffer, const size_t subStreamInde return true; } -bool AvInputAudio::getNextFrame() +bool AvInputAudio::decodeNextFrame() { int got_frame = 0; while( ! got_frame ) @@ -172,7 +172,7 @@ bool AvInputAudio::getNextFrame() packet.data = data.getPtr(); packet.size = data.getSize(); - int ret = avcodec_decode_audio4( _codec.getAVCodecContext(), _frame, &got_frame, &packet ); + int ret = avcodec_decode_audio4( _codec->getAVCodecContext(), _frame, &got_frame, &packet ); if( ret < 0 ) { diff --git a/src/AvTranscoder/essenceStream/AvInputAudio.hpp b/src/AvTranscoder/essenceStream/AvInputAudio.hpp index 394fbf0d..26b0fc9c 100644 --- a/src/AvTranscoder/essenceStream/AvInputAudio.hpp +++ b/src/AvTranscoder/essenceStream/AvInputAudio.hpp @@ -23,13 +23,13 @@ class AvExport AvInputAudio : public IInputEssence bool readNextFrame( Frame& frameBuffer, const size_t subStreamIndex ); private: - bool getNextFrame(); + bool decodeNextFrame(); - AvInputStream* _inputStream; - AudioCodec _codec; - AVFrame* _frame; + AvInputStream* _inputStream; ///< Stream from which we read next frames + const AudioCodec* _codec; ///< Audio decoder. Has link (no ownership) + AVFrame* _frame; ///< Libav object to store decoded data - int _selectedStream; + int _selectedStream; ///< Index of the selected stream in the input file }; } diff --git a/src/AvTranscoder/essenceStream/AvInputVideo.cpp b/src/AvTranscoder/essenceStream/AvInputVideo.cpp index f11e7e12..224b4dc8 100644 --- a/src/AvTranscoder/essenceStream/AvInputVideo.cpp +++ b/src/AvTranscoder/essenceStream/AvInputVideo.cpp @@ -20,8 +20,9 @@ namespace avtranscoder AvInputVideo::AvInputVideo( AvInputStream& inputStream ) : IInputEssence() , _inputStream ( &inputStream ) - , _codec( eCodecTypeDecoder, inputStream.getVideoCodec().getCodecId() ) + , _codec( &inputStream.getVideoCodec() ) , _frame ( NULL ) + , _selectedStream( inputStream.getStreamIndex() ) { } @@ -44,8 +45,8 @@ AvInputVideo::~AvInputVideo() void AvInputVideo::setup() { - AVCodecContext* avCodecContext = _codec.getAVCodecContext(); - AVCodec* avCodec = _codec.getAVCodec(); + AVCodecContext* avCodecContext = _codec->getAVCodecContext(); + AVCodec* avCodec = _codec->getAVCodec(); // if( avCodec->capabilities & CODEC_CAP_TRUNCATED ) // avCodecContext->flags |= CODEC_FLAG_TRUNCATED; @@ -76,28 +77,46 @@ void AvInputVideo::setup() bool AvInputVideo::readNextFrame( Frame& frameBuffer ) { - int got_frame = 0; + if( ! decodeNextFrame() ) + return false; + + VideoFrame& imageBuffer = static_cast( frameBuffer ); + + size_t decodedSize = avpicture_get_size( (AVPixelFormat)_frame->format, _frame->width, _frame->height ); + if( ! decodedSize ) + return false; + + if( imageBuffer.getBuffer().size() != decodedSize ) + imageBuffer.getBuffer().resize( decodedSize ); + + // Copy pixel data from an AVPicture into one contiguous buffer. + avpicture_layout( (AVPicture*)_frame, (AVPixelFormat)_frame->format, _frame->width, _frame->height, &imageBuffer.getBuffer()[0], frameBuffer.getBuffer().size() ); + return true; +} + +bool AvInputVideo::readNextFrame( Frame& frameBuffer, const size_t subStreamIndex ) +{ + return false; +} + +bool AvInputVideo::decodeNextFrame() +{ + int got_frame = 0; while( ! got_frame ) { CodedData data; + if( ! _inputStream->readNextPacket( data ) ) // error or end of file + return false; AVPacket packet; av_init_packet( &packet ); - bool nextPacketRead = _inputStream->readNextPacket( data ); - - packet.stream_index = _inputStream->getStreamIndex(); - packet.data = nextPacketRead ? data.getPtr(): NULL; + packet.stream_index = _selectedStream; //_inputStream->getStreamIndex(); + packet.data = data.getPtr(); //nextPacketRead ? data.getPtr(): NULL; packet.size = data.getSize(); - int ret = avcodec_decode_video2( _codec.getAVCodecContext(), _frame, &got_frame, &packet ); - - av_free_packet( &packet ); - - if( ! nextPacketRead && ret == 0 && got_frame == 0 ) - return false; - + int ret = avcodec_decode_video2( _codec->getAVCodecContext(), _frame, &got_frame, &packet ); if( ret < 0 ) { char err[250]; @@ -105,33 +124,19 @@ bool AvInputVideo::readNextFrame( Frame& frameBuffer ) throw std::runtime_error( "an error occured during video decoding - " + std::string(err) ); } + av_free_packet( &packet ); } - - VideoFrame& imageBuffer = static_cast( frameBuffer ); - - size_t decodedSize = avpicture_get_size( (AVPixelFormat)_frame->format, _frame->width, _frame->height ); - if( imageBuffer.getBuffer().size() != decodedSize ) - imageBuffer.getBuffer().resize( decodedSize ); - - // Copy pixel data from an AVPicture into one contiguous buffer. - avpicture_layout( (AVPicture*)_frame, (AVPixelFormat)_frame->format, _frame->width, _frame->height, &imageBuffer.getBuffer()[0], frameBuffer.getBuffer().size() ); - return true; } -bool AvInputVideo::readNextFrame( Frame& frameBuffer, const size_t subStreamIndex ) -{ - return false; -} - void AvInputVideo::flushDecoder() { - avcodec_flush_buffers( _codec.getAVCodecContext() ); + avcodec_flush_buffers( _codec->getAVCodecContext() ); } void AvInputVideo::setProfile( const ProfileLoader::Profile& profile ) { - Context codecContext( _codec.getAVCodecContext() ); + Context codecContext( _codec->getAVCodecContext() ); for( ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it ) { diff --git a/src/AvTranscoder/essenceStream/AvInputVideo.hpp b/src/AvTranscoder/essenceStream/AvInputVideo.hpp index 9132662c..0a2292ec 100644 --- a/src/AvTranscoder/essenceStream/AvInputVideo.hpp +++ b/src/AvTranscoder/essenceStream/AvInputVideo.hpp @@ -28,9 +28,14 @@ class AvExport AvInputVideo : public IInputEssence void setProfile( const ProfileLoader::Profile& profile ); private: - AvInputStream* _inputStream; - VideoCodec _codec; - AVFrame* _frame; + bool decodeNextFrame(); + +private: + AvInputStream* _inputStream; ///< Stream from which we read next frames + const VideoCodec* _codec; ///< Video decoder. Has link (no ownership) + AVFrame* _frame; ///< Libav object to store decoded data + + int _selectedStream; ///< Index of the selected stream in the input file }; } diff --git a/src/AvTranscoder/essenceStream/AvOutputVideo.cpp b/src/AvTranscoder/essenceStream/AvOutputVideo.cpp index 128e3e22..fe082379 100644 --- a/src/AvTranscoder/essenceStream/AvOutputVideo.cpp +++ b/src/AvTranscoder/essenceStream/AvOutputVideo.cpp @@ -103,25 +103,7 @@ bool AvOutputVideo::encodeFrame( const Frame& sourceFrame, Frame& codedFrame ) memcpy( codedFrame.getPtr(), packet.data, packet.size ); } #endif -/* - std::string imgType = ""; - switch( codecContext->coded_frame->pict_type ) - { - case AV_PICTURE_TYPE_NONE : imgType = "None"; break; - case AV_PICTURE_TYPE_I : imgType = "I"; break; - case AV_PICTURE_TYPE_P : imgType = "P"; break; - case AV_PICTURE_TYPE_B : imgType = "B"; break; - case AV_PICTURE_TYPE_S : imgType = "S"; break; - case AV_PICTURE_TYPE_SI : imgType = "SI"; break; - case AV_PICTURE_TYPE_SP : imgType = "SP"; break; - case AV_PICTURE_TYPE_BI : imgType = "BI"; break; - } - std::clog << "\tframe " << codecContext->coded_frame->display_picture_number; - std::clog << " coded @ " << codecContext->coded_frame->coded_picture_number; - std::clog << " type : " << imgType; - std::clog << " quality : " << codecContext->coded_frame->quality << std::endl; -*/ av_free_packet( &packet ); #if LIBAVCODEC_VERSION_MAJOR > 54 av_frame_free( &frame ); diff --git a/src/AvTranscoder/essenceStream/GeneratorAudio.cpp b/src/AvTranscoder/essenceStream/GeneratorAudio.cpp index bd13ef4d..e2a6be2b 100644 --- a/src/AvTranscoder/essenceStream/GeneratorAudio.cpp +++ b/src/AvTranscoder/essenceStream/GeneratorAudio.cpp @@ -5,25 +5,15 @@ namespace avtranscoder GeneratorAudio::GeneratorAudio( ) : IInputEssence( ) - , _codec( NULL ) , _inputFrame( NULL ) , _frameDesc() { } -void GeneratorAudio::setAudioCodec( const AudioCodec& codec ) +void GeneratorAudio::setAudioFrameDesc( const AudioFrameDesc& frameDesc ) { - _frameDesc.setFps ( 25.0 ); - _codec = &codec; - - _frameDesc.setSampleRate( _codec->getAVCodecContext()->sample_rate ); - _frameDesc.setChannels( _codec->getAVCodecContext()->channels ); - _frameDesc.setSampleFormat( _codec->getAVCodecContext()->sample_fmt ); -} - -const AudioCodec& GeneratorAudio::getAudioCodec() -{ - return *_codec; + _frameDesc = frameDesc; + _frameDesc.setFps( 25. ); } void GeneratorAudio::setFrame( Frame& inputFrame ) diff --git a/src/AvTranscoder/essenceStream/GeneratorAudio.hpp b/src/AvTranscoder/essenceStream/GeneratorAudio.hpp index 0c8e80d1..2f14c946 100644 --- a/src/AvTranscoder/essenceStream/GeneratorAudio.hpp +++ b/src/AvTranscoder/essenceStream/GeneratorAudio.hpp @@ -12,9 +12,8 @@ class AvExport GeneratorAudio : public IInputEssence public: GeneratorAudio( ); - void setAudioCodec( const AudioCodec& codec ); - - const AudioCodec& getAudioCodec(); + AudioFrameDesc& getAudioFrameDesc() { return _frameDesc; } + void setAudioFrameDesc( const AudioFrameDesc& frameDesc ); void setup() {} @@ -24,8 +23,7 @@ class AvExport GeneratorAudio : public IInputEssence bool readNextFrame( Frame& frameBuffer, const size_t subStreamIndex ); private: - const AudioCodec* _codec; - Frame* _inputFrame; + Frame* _inputFrame; ///< Has link (no ownership) AudioFrameDesc _frameDesc; }; diff --git a/src/AvTranscoder/essenceStream/GeneratorVideo.cpp b/src/AvTranscoder/essenceStream/GeneratorVideo.cpp index e1a37861..30e8ed3e 100644 --- a/src/AvTranscoder/essenceStream/GeneratorVideo.cpp +++ b/src/AvTranscoder/essenceStream/GeneratorVideo.cpp @@ -7,22 +7,14 @@ namespace avtranscoder GeneratorVideo::GeneratorVideo( ) : IInputEssence( ) - , _codec( NULL ) , _inputFrame( NULL ) - , _videoFrameDesc() - , _numberOfView( 1 ) + , _frameDesc() { } -void GeneratorVideo::setVideoCodec( const VideoCodec& codec ) +void GeneratorVideo::setVideoFrameDesc( const VideoFrameDesc& frameDesc ) { - _codec = &codec; - _videoFrameDesc = _codec->getVideoFrameDesc(); -} - -const VideoCodec& GeneratorVideo::getVideoCodec() -{ - return *_codec; + _frameDesc = frameDesc; } void GeneratorVideo::setFrame( Frame& inputFrame ) @@ -32,30 +24,32 @@ void GeneratorVideo::setFrame( Frame& inputFrame ) bool GeneratorVideo::readNextFrame( Frame& frameBuffer ) { + // Generate black image if( ! _inputFrame ) { // @todo support PAL (0 to 255) and NTFS (16 to 235) int fillChar = 0; - if( frameBuffer.getSize() != _videoFrameDesc.getDataSize() ) - frameBuffer.getBuffer().resize( _videoFrameDesc.getDataSize() ); + if( frameBuffer.getSize() != _frameDesc.getDataSize() ) + frameBuffer.getBuffer().resize( _frameDesc.getDataSize() ); - VideoFrameDesc desc( _codec->getVideoFrameDesc() ); + VideoFrameDesc desc( _frameDesc ); Pixel rgbPixel; rgbPixel.setColorComponents( eComponentRgb ); rgbPixel.setPlanar( false ); desc.setPixel( rgbPixel ); VideoFrame intermediateBuffer( desc ); - intermediateBuffer.getBuffer().resize( _videoFrameDesc.getDataSize() ); - memset( intermediateBuffer.getPtr(), fillChar, _videoFrameDesc.getDataSize() ); + intermediateBuffer.getBuffer().resize( _frameDesc.getDataSize() ); + memset( intermediateBuffer.getPtr(), fillChar, _frameDesc.getDataSize() ); VideoTransform videoEssenceTransform; videoEssenceTransform.convert( intermediateBuffer, frameBuffer ); return true; } - + + // Take image from _inputFrame if( frameBuffer.getSize() != _inputFrame->getSize() ) frameBuffer.getBuffer().resize( _inputFrame->getSize() ); std::memcpy( frameBuffer.getPtr(), _inputFrame->getPtr(), _inputFrame->getSize() ); diff --git a/src/AvTranscoder/essenceStream/GeneratorVideo.hpp b/src/AvTranscoder/essenceStream/GeneratorVideo.hpp index 54a206ab..f32513bf 100644 --- a/src/AvTranscoder/essenceStream/GeneratorVideo.hpp +++ b/src/AvTranscoder/essenceStream/GeneratorVideo.hpp @@ -12,10 +12,8 @@ class AvExport GeneratorVideo : public IInputEssence public: GeneratorVideo( ); - // Stream properties - void setVideoCodec( const VideoCodec& codec ); - - const VideoCodec& getVideoCodec(); + VideoFrameDesc& getVideoFrameDesc() { return _frameDesc; } + void setVideoFrameDesc( const VideoFrameDesc& frameDesc ); void setup() {} @@ -25,11 +23,8 @@ class AvExport GeneratorVideo : public IInputEssence bool readNextFrame( Frame& frameBuffer, const size_t subStreamIndex ); private: - const VideoCodec* _codec; - Frame* _inputFrame; - VideoFrameDesc _videoFrameDesc; - - size_t _numberOfView; + Frame* _inputFrame; ///< Has link (no ownership) + VideoFrameDesc _frameDesc; }; } diff --git a/src/AvTranscoder/essenceStream/IInputEssence.hpp b/src/AvTranscoder/essenceStream/IInputEssence.hpp index 33f7968a..8e232dc0 100644 --- a/src/AvTranscoder/essenceStream/IInputEssence.hpp +++ b/src/AvTranscoder/essenceStream/IInputEssence.hpp @@ -31,6 +31,13 @@ class AvExport IInputEssence * @return status of decoding */ virtual bool readNextFrame( Frame& frameBuffer, const size_t subStreamIndex ) = 0; + + /** + * Set the next frame of the input stream + * @note Not yet implemented for AvInputVideo and AvInputAudio + * @param inputFrame: the new next frame + */ + virtual void setFrame( Frame& inputFrame ) {} }; } diff --git a/src/AvTranscoder/file/InputFile.cpp b/src/AvTranscoder/file/InputFile.cpp index 79c50753..e957c473 100644 --- a/src/AvTranscoder/file/InputFile.cpp +++ b/src/AvTranscoder/file/InputFile.cpp @@ -1,13 +1,13 @@ #include "InputFile.hpp" #include -#include -#include -#include -#include -#include -#include - +#include +#include +#include +#include +#include +#include +#include extern "C" { #include @@ -24,7 +24,8 @@ namespace avtranscoder InputFile::InputFile( const std::string& filename ) : _formatContext ( NULL ) - , _filename ( filename ) + , _properties( NULL ) + , _filename( filename ) { av_register_all(); if( avformat_open_input( &_formatContext, _filename.c_str(), NULL, NULL ) < 0 ) @@ -42,6 +43,10 @@ InputFile::InputFile( const std::string& filename ) throw std::runtime_error( "unable to find stream informations" ); } + // Initialize FileProperties + _properties = FileProperties( _formatContext ); + + // Create streams for( size_t streamIndex = 0; streamIndex < _formatContext->nb_streams; ++streamIndex ) { _inputStreams.push_back( new AvInputStream( *this, streamIndex ) ); @@ -68,56 +73,44 @@ InputFile& InputFile::analyse( IProgress& progress, const EAnalyseLevel level ) seekAtFrame( 0 ); - _properties.filename = _formatContext->filename; - _properties.formatName = _formatContext->iformat->name; - _properties.formatLongName = _formatContext->iformat->long_name; - _properties.streamsCount = _formatContext->nb_streams; - _properties.programsCount = _formatContext->nb_programs; - _properties.startTime = 1.0 * (unsigned int)_formatContext->start_time / AV_TIME_BASE; - _properties.duration = 1.0 * _formatContext->duration / AV_TIME_BASE; - _properties.bitRate = _formatContext->bit_rate; - _properties.packetSize = _formatContext->packet_size; - - detail::fillMetadataDictionnary( _formatContext->metadata, _properties.metadatas ); - for( size_t streamId = 0; streamId < _formatContext->nb_streams; streamId++ ) { switch( _formatContext->streams[streamId]->codec->codec_type ) { case AVMEDIA_TYPE_VIDEO: { - _properties.videoStreams.push_back( videoStreamInfo( _formatContext, streamId, progress, level ) ); - detail::fillMetadataDictionnary( _formatContext->streams[streamId]->metadata, _properties.videoStreams.back().metadatas ); + VideoProperties properties( _formatContext, streamId, progress, level ); + _properties.getVideoProperties().push_back( properties ); break; } case AVMEDIA_TYPE_AUDIO: { - _properties.audioStreams.push_back( audioStreamInfo( _formatContext, streamId ) ); - detail::fillMetadataDictionnary( _formatContext->streams[streamId]->metadata, _properties.audioStreams.back().metadatas ); + AudioProperties properties( _formatContext, streamId ); + _properties.getAudioProperties().push_back( properties ); break; } case AVMEDIA_TYPE_DATA: { - _properties.dataStreams.push_back( dataStreamInfo( _formatContext, streamId ) ); - detail::fillMetadataDictionnary( _formatContext->streams[streamId]->metadata, _properties.dataStreams.back().metadatas ); + DataProperties properties( _formatContext, streamId ); + _properties.getDataProperties().push_back( properties ); break; } case AVMEDIA_TYPE_SUBTITLE: { - _properties.subtitleStreams.push_back( subtitleStreamInfo( _formatContext, streamId ) ); - detail::fillMetadataDictionnary( _formatContext->streams[streamId]->metadata, _properties.subtitleStreams.back().metadatas ); + SubtitleProperties properties( _formatContext, streamId ); + _properties.getSubtitleProperties().push_back( properties ); break; } case AVMEDIA_TYPE_ATTACHMENT: { - _properties.attachementStreams.push_back( attachementStreamInfo( _formatContext, streamId ) ); - detail::fillMetadataDictionnary( _formatContext->streams[streamId]->metadata, _properties.attachementStreams.back().metadatas ); + AttachementProperties properties( _formatContext, streamId ); + _properties.getAttachementProperties().push_back( properties ); break; } case AVMEDIA_TYPE_UNKNOWN: { - _properties.unknownStreams.push_back( unknownStreamInfo( _formatContext, streamId ) ); - detail::fillMetadataDictionnary( _formatContext->streams[streamId]->metadata, _properties.unknownStreams.back().metadatas ); + UnknownProperties properties( _formatContext, streamId ); + _properties.getUnknownPropertiesProperties().push_back( properties ); break; } case AVMEDIA_TYPE_NB: @@ -132,13 +125,11 @@ InputFile& InputFile::analyse( IProgress& progress, const EAnalyseLevel level ) return *this; } -Properties InputFile::analyseFile( const std::string& filename, IProgress& progress, const EAnalyseLevel level ) +FileProperties InputFile::analyseFile( const std::string& filename, IProgress& progress, const EAnalyseLevel level ) { InputFile file( filename ); file.analyse( progress, level ); - Properties properties; - file.getProperties( properties ); - return properties; + return file.getProperties(); } AVMediaType InputFile::getStreamType( size_t index ) @@ -229,9 +220,9 @@ void InputFile::setProfile( const ProfileLoader::Profile& profile ) } catch( std::exception& e ) { - std::cout << "[InputFile] warning - can't set option " << (*it).first << " to " << (*it).second << ": " << e.what() << std::endl; + std::cout << "[InputFile] warning: " << e.what() << std::endl; } } } -} +} \ No newline at end of file diff --git a/src/AvTranscoder/file/InputFile.hpp b/src/AvTranscoder/file/InputFile.hpp index a0542a09..6283f977 100644 --- a/src/AvTranscoder/file/InputFile.hpp +++ b/src/AvTranscoder/file/InputFile.hpp @@ -3,12 +3,14 @@ #include +#include + #include #include #include -#include +#include #include @@ -34,12 +36,6 @@ class AvExport InputFile virtual ~InputFile(); - enum EAnalyseLevel - { - eAnalyseLevelFast = 0, - eAnalyseLevelFull = 0, - }; - /** * @return Return the resource to access **/ @@ -50,16 +46,16 @@ class AvExport InputFile * call this function before getProperties(). * @param progress callback to get analysis progression **/ - InputFile& analyse( IProgress& progress, const EAnalyseLevel level = eAnalyseLevelFull ); + InputFile& analyse( IProgress& progress, const EAnalyseLevel level = eAnalyseLevelFirstGop ); /** * @brief Return media properties on the current InputFile. * @note require to launch analyse() before to fill the property struture * @return structure of media metadatas **/ - const Properties& getProperties() const { return _properties; } + const FileProperties& getProperties() const { return _properties; } - void getProperties( Properties& properties ) const { properties = _properties; } + void getProperties( FileProperties& properties ) const { properties = _properties; } /** * @brief Get media file properties using static method. @@ -67,7 +63,7 @@ class AvExport InputFile * @param progress callback to get analysis progression * @return structure of media metadatas **/ - static Properties analyseFile( const std::string& filename, IProgress& progress, const EAnalyseLevel level = eAnalyseLevelFull ); + static FileProperties analyseFile( const std::string& filename, IProgress& progress, const EAnalyseLevel level = eAnalyseLevelFirstGop ); /** * @brief Get stream type: video, audio, subtitle, etc. @@ -125,7 +121,7 @@ class AvExport InputFile protected: AVFormatContext* _formatContext; - Properties _properties; + FileProperties _properties; std::string _filename; std::vector _inputStreams; }; diff --git a/src/AvTranscoder/file/OutputFile.hpp b/src/AvTranscoder/file/OutputFile.hpp index 99cfd6f8..52163e4c 100644 --- a/src/AvTranscoder/file/OutputFile.hpp +++ b/src/AvTranscoder/file/OutputFile.hpp @@ -3,7 +3,7 @@ #include -#include +#include #include #include diff --git a/src/AvTranscoder/file/file.i b/src/AvTranscoder/file/file.i new file mode 100644 index 00000000..a0c3ee0e --- /dev/null +++ b/src/AvTranscoder/file/file.i @@ -0,0 +1,9 @@ +%{ +#include +#include +#include +%} + +%include +%include +%include diff --git a/src/AvTranscoder/file/util.hpp b/src/AvTranscoder/file/util.hpp new file mode 100644 index 00000000..95dcaea4 --- /dev/null +++ b/src/AvTranscoder/file/util.hpp @@ -0,0 +1,20 @@ +#ifndef _AV_TRANSCODER_FILE_UTIL_HPP_ +#define _AV_TRANSCODER_FILE_UTIL_HPP_ + +namespace avtranscoder +{ + +/** + * @brief Level of file analysis. + */ +enum EAnalyseLevel +{ + eAnalyseLevelHeader = 0, + eAnalyseLevelFirstGop = 1, + //eAnalyseLevelFull = 2, +}; + +} + +#endif + diff --git a/src/AvTranscoder/frame/VideoFrame.hpp b/src/AvTranscoder/frame/VideoFrame.hpp index 169dc3ee..4423d41f 100644 --- a/src/AvTranscoder/frame/VideoFrame.hpp +++ b/src/AvTranscoder/frame/VideoFrame.hpp @@ -40,7 +40,7 @@ class AvExport VideoFrameDesc void setWidth ( const size_t width ) { _width = width; } void setHeight( const size_t height ) { _height = height; } - void setPixel ( const Pixel pixel ) { _pixel = pixel; } + void setPixel( const Pixel& pixel ) { _pixel = pixel; } void setDar( const size_t num, const size_t den ) { _displayAspectRatio.num = num; _displayAspectRatio.den = den; } void setDar( const Rational ratio ) { _displayAspectRatio = ratio; } diff --git a/src/AvTranscoder/mediaProperty/AttachementProperties.cpp b/src/AvTranscoder/mediaProperty/AttachementProperties.cpp new file mode 100644 index 00000000..0250d986 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/AttachementProperties.cpp @@ -0,0 +1,28 @@ +#include "AttachementProperties.hpp" + +namespace avtranscoder +{ + +AttachementProperties::AttachementProperties( const AVFormatContext* formatContext, const size_t index ) + : _formatContext( formatContext ) + , _streamId( index ) +{ + if( formatContext ) + detail::fillMetadataDictionnary( _formatContext->streams[index]->metadata, _metadatas ); +} + +MetadatasMap AttachementProperties::getDataMap() const +{ + MetadatasMap dataMap; + + detail::add( dataMap, "streamId", _streamId ); + + for( size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex ) + { + detail::add( dataMap, _metadatas.at( metadataIndex ).first, _metadatas.at( metadataIndex ).second ); + } + + return dataMap; +} + +} diff --git a/src/AvTranscoder/mediaProperty/AttachementProperties.hpp b/src/AvTranscoder/mediaProperty/AttachementProperties.hpp new file mode 100644 index 00000000..9e5755ef --- /dev/null +++ b/src/AvTranscoder/mediaProperty/AttachementProperties.hpp @@ -0,0 +1,35 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_ATTACHEMENT_PROPERTIES_HPP +#define _AV_TRANSCODER_MEDIA_PROPERTY_ATTACHEMENT_PROPERTIES_HPP + +#include +#include + +extern "C" { +#include +} + +namespace avtranscoder +{ + +class AvExport AttachementProperties +{ +public: + AttachementProperties( const AVFormatContext* formatContext, const size_t index ); + + size_t getStreamId() const { return _streamId; } + MetadatasMap& getMetadatas() { return _metadatas; } + + const AVFormatContext& getAVFormatContext() { return *_formatContext; } + + MetadatasMap getDataMap() const; + +private: + const AVFormatContext* _formatContext; ///< Has link (no ownership) + + size_t _streamId; + MetadatasMap _metadatas; +}; + +} + +#endif diff --git a/src/AvTranscoder/mediaProperty/AttachementStreamProperty.hpp b/src/AvTranscoder/mediaProperty/AttachementStreamProperty.hpp deleted file mode 100644 index 93de0ae5..00000000 --- a/src/AvTranscoder/mediaProperty/AttachementStreamProperty.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _AV_TRANSCODER_ATTACHEMENT_STREAM_PROPERTIES_HPP_ -#define _AV_TRANSCODER_ATTACHEMENT_STREAM_PROPERTIES_HPP_ - -class AVFormatContext; - -namespace avtranscoder -{ - -AttachementProperties attachementStreamInfo( const AVFormatContext* formatContext, const size_t index ) -{ - AttachementProperties ap; - ap.streamId = index; - return ap; -} - -} - -#endif \ No newline at end of file diff --git a/src/AvTranscoder/mediaProperty/AudioProperties.cpp b/src/AvTranscoder/mediaProperty/AudioProperties.cpp new file mode 100644 index 00000000..751183d9 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/AudioProperties.cpp @@ -0,0 +1,152 @@ +#include "AudioProperties.hpp" + +extern "C" { +#include +#include +#include +#include +#include +} + +namespace avtranscoder +{ + +AudioProperties::AudioProperties( const AVFormatContext* formatContext, const size_t index ) + : _formatContext( formatContext ) + , _codecContext( NULL ) + , _codec( NULL ) + , _streamId( index ) +{ + if( _formatContext ) + _codecContext = formatContext->streams[index]->codec; + + if( _formatContext && _codecContext ) + _codec = avcodec_find_decoder( _codecContext->codec_id ); + + if( formatContext ) + detail::fillMetadataDictionnary( _formatContext->streams[index]->metadata, _metadatas ); +} + +std::string AudioProperties::getCodecName() const +{ + if( _codec && _codec->name ) + return std::string( _codec->name ); + else + return "unknown codec"; +} + +std::string AudioProperties::getCodecLongName() const +{ + if( _codec && _codec->long_name ) + return std::string( _codec->long_name ); + return "unknown codec"; +} + +std::string AudioProperties::getSampleFormatName() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + const char* fmtName = av_get_sample_fmt_name( _codecContext->sample_fmt ); + if( fmtName ) + return std::string( fmtName ); + return "unknown sample format"; +} + +std::string AudioProperties::getSampleFormatLongName() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + switch( _codecContext->sample_fmt ) + { + case AV_SAMPLE_FMT_NONE: + return "none"; + case AV_SAMPLE_FMT_U8: + return "unsigned 8 bits"; + case AV_SAMPLE_FMT_S16: + return "signed 16 bits"; + case AV_SAMPLE_FMT_S32: + return "signed 32 bits"; + case AV_SAMPLE_FMT_FLT: + return "float"; + case AV_SAMPLE_FMT_DBL: + return "double"; + case AV_SAMPLE_FMT_U8P: + return "unsigned 8 bits, planar"; + case AV_SAMPLE_FMT_S16P: + return "signed 16 bits, planar"; + case AV_SAMPLE_FMT_S32P: + return "signed 32 bits, planar"; + case AV_SAMPLE_FMT_FLTP: + return "float, planar"; + case AV_SAMPLE_FMT_DBLP: + return "double, planar"; + case AV_SAMPLE_FMT_NB: + return "number of sample formats"; + } + return "unknown sample format"; +} + +std::string AudioProperties::getChannelLayout() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + char buf1[1024]; + av_get_channel_layout_string( buf1, sizeof( buf1 ), -1, _codecContext->channel_layout ); + return std::string( buf1 ); +} + +std::string AudioProperties::getChannelName() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + const char* channelName = av_get_channel_name( _codecContext->channel_layout ); + if( channelName ) + return std::string( channelName ); + return "unknown channel name"; +} + +std::string AudioProperties::getChannelDescription() const +{ + if( ! _codecContext ) + return "unknown codec context"; + +#ifdef FF_RESAMPLE_LIBRARY + const char* channelDescription = av_get_channel_description( _codecContext->channel_layout ); + if( channelDescription ) + return std::string( channelDescription ); + return "unknown channel description"; +#else + return "can't access channel description"; +#endif +} + +MetadatasMap AudioProperties::getDataMap() const +{ + MetadatasMap dataMap; + + detail::add( dataMap, "streamId", getStreamId() ); + detail::add( dataMap, "codecId", getCodecId() ); + detail::add( dataMap, "codecName", getCodecName() ); + detail::add( dataMap, "codecLongName", getCodecLongName() ); + detail::add( dataMap, "sampleFormatName", getSampleFormatName() ); + detail::add( dataMap, "sampleFormatLongName", getSampleFormatLongName() ); + detail::add( dataMap, "sampleRate", getSampleRate() ); + detail::add( dataMap, "bitRate", getBitRate() ); + detail::add( dataMap, "channels", getChannels() ); + detail::add( dataMap, "channelLayout", getChannelLayout() ); + detail::add( dataMap, "channelName", getChannelName() ); + detail::add( dataMap, "channelDescription", getChannelDescription() ); + + for( size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex ) + { + detail::add( dataMap, _metadatas.at( metadataIndex ).first, _metadatas.at( metadataIndex ).second ); + } + + return dataMap; +} + +} diff --git a/src/AvTranscoder/mediaProperty/AudioProperties.hpp b/src/AvTranscoder/mediaProperty/AudioProperties.hpp new file mode 100644 index 00000000..bc2165f3 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/AudioProperties.hpp @@ -0,0 +1,54 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_AUDIO_PROPERTIES_HPP +#define _AV_TRANSCODER_MEDIA_PROPERTY_AUDIO_PROPERTIES_HPP + +#include +#include + +extern "C" { +#include +#include +} + +#include + +class AVFormatContext; + +namespace avtranscoder +{ + +class AvExport AudioProperties +{ +public: + AudioProperties( const AVFormatContext* formatContext, const size_t index ); + + std::string getCodecName() const; + std::string getCodecLongName() const; + std::string getSampleFormatName() const; + std::string getSampleFormatLongName() const; + std::string getChannelLayout() const; + std::string getChannelName() const; + std::string getChannelDescription() const; + size_t getStreamId() const { return _streamId; } + size_t getCodecId() const { return _codecContext->codec_id; } + size_t getSampleRate() const { return _codecContext->sample_rate; } + size_t getChannels() const { return _codecContext->channels; } + size_t getBitRate() const { return _codecContext->bit_rate; } + MetadatasMap& getMetadatas() { return _metadatas; } + + const AVFormatContext& getAVFormatContext() { return *_formatContext; } + AVCodecContext& getAVCodecContext() { return *_codecContext; } + + MetadatasMap getDataMap() const; + +private: + const AVFormatContext* _formatContext; ///< Has link (no ownership) + AVCodecContext* _codecContext; ///< Has link (no ownership) + AVCodec* _codec; ///< Has link (no ownership) + + size_t _streamId; + MetadatasMap _metadatas; +}; + +} + +#endif diff --git a/src/AvTranscoder/mediaProperty/AudioStreamProperty.hpp b/src/AvTranscoder/mediaProperty/AudioStreamProperty.hpp deleted file mode 100644 index 7b651cfa..00000000 --- a/src/AvTranscoder/mediaProperty/AudioStreamProperty.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _AV_TRANSCODER_AUDIO_STREAM_PROPERTIES_HPP_ -#define _AV_TRANSCODER_AUDIO_STREAM_PROPERTIES_HPP_ - -extern "C" { -#include -#include -#include -#include -#include -} - -namespace avtranscoder -{ - -avtranscoder::AudioProperties audioStreamInfo( const AVFormatContext* formatContext, const size_t index ) -{ - AudioProperties ap; - AVCodecContext* codec_context = formatContext->streams[index]->codec; - - ap.codecId = codec_context->codec_id; - ap.sampleRate = codec_context->sample_rate; - ap.channels = codec_context->channels; - ap.bit_rate = codec_context->bit_rate; - ap.streamId = index; - - AVCodec* codec = avcodec_find_decoder( codec_context->codec_id ); - if( codec != NULL ) - { - ap.codecName = codec->name; - ap.codecLongName = codec->long_name; - } - - char buf1[1024]; - av_get_channel_layout_string( buf1, sizeof( buf1 ), -1, codec_context->channel_layout ); - - ap.channelLayout = std::string( buf1 ); - - const char* channelName = av_get_channel_name( codec_context->channel_layout ); - if( channelName ) - ap.channelName = std::string( channelName ); -#ifdef FF_RESAMPLE_LIBRARY - const char* channelDescription = av_get_channel_description( codec_context->channel_layout ); - if( channelDescription ) - ap.channelDescription = std::string( channelDescription ); -#endif - const char* fmtName = av_get_sample_fmt_name( codec_context->sample_fmt ); - if( fmtName ) - ap.sampleFormatName = std::string( fmtName ); - - std::string sampleFormat = ""; - switch( codec_context->sample_fmt ) - { - case AV_SAMPLE_FMT_NONE : ap.sampleFormatLongName = "none"; break; - case AV_SAMPLE_FMT_U8 : ap.sampleFormatLongName = "unsigned 8 bits"; break; - case AV_SAMPLE_FMT_S16 : ap.sampleFormatLongName = "signed 16 bits"; break; - case AV_SAMPLE_FMT_S32 : ap.sampleFormatLongName = "signed 32 bits"; break; - case AV_SAMPLE_FMT_FLT : ap.sampleFormatLongName = "float"; break; - case AV_SAMPLE_FMT_DBL : ap.sampleFormatLongName = "double"; break; - case AV_SAMPLE_FMT_U8P : ap.sampleFormatLongName = "unsigned 8 bits, planar"; break; - case AV_SAMPLE_FMT_S16P : ap.sampleFormatLongName = "signed 16 bits, planar"; break; - case AV_SAMPLE_FMT_S32P : ap.sampleFormatLongName = "signed 32 bits, planar"; break; - case AV_SAMPLE_FMT_FLTP : ap.sampleFormatLongName = "float, planar"; break; - case AV_SAMPLE_FMT_DBLP : ap.sampleFormatLongName = "double, planar"; break; - case AV_SAMPLE_FMT_NB : ap.sampleFormatLongName = "Number of sample formats."; break; - } - - return ap; -} - -} - -#endif diff --git a/src/AvTranscoder/mediaProperty/DataStreamProperty.hpp b/src/AvTranscoder/mediaProperty/DataProperties.cpp similarity index 78% rename from src/AvTranscoder/mediaProperty/DataStreamProperty.hpp rename to src/AvTranscoder/mediaProperty/DataProperties.cpp index 6669ad99..6043c44f 100644 --- a/src/AvTranscoder/mediaProperty/DataStreamProperty.hpp +++ b/src/AvTranscoder/mediaProperty/DataProperties.cpp @@ -1,28 +1,51 @@ -#ifndef _AV_TRANSCODER_DATA_STREAM_PROPERTIES_HPP_ -#define _AV_TRANSCODER_DATA_STREAM_PROPERTIES_HPP_ +#include "DataProperties.hpp" extern "C" { #include -#include #include #include } #include +#include namespace avtranscoder { -void detectAncillaryData( AVFormatContext* formatContext, const int index ) +DataProperties::DataProperties( const AVFormatContext* formatContext, const size_t index ) + : _formatContext( formatContext ) + , _streamId( index ) +{ + //detectAncillaryData( _formatContext, _streamId ); + + if( formatContext ) + detail::fillMetadataDictionnary( _formatContext->streams[index]->metadata, _metadatas ); +} + +MetadatasMap DataProperties::getDataMap() const +{ + MetadatasMap dataMap; + + detail::add( dataMap, "streamId", _streamId ); + + for( size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex ) + { + detail::add( dataMap, _metadatas.at( metadataIndex ).first, _metadatas.at( metadataIndex ).second ); + } + + return dataMap; +} + +void DataProperties::detectAncillaryData() { AVPacket pkt; av_init_packet( &pkt ); bool detection = false; - while( ! av_read_frame( formatContext, &pkt ) ) + while( ! av_read_frame( const_cast( _formatContext ), &pkt ) ) { - if( pkt.stream_index == index ) + if( pkt.stream_index == (int)_streamId ) { std::cout << "start detect packet" << std::endl; size_t offset = 0; @@ -62,20 +85,4 @@ void detectAncillaryData( AVFormatContext* formatContext, const int index ) } } -DataProperties dataStreamInfo( AVFormatContext* formatContext, const size_t index ) -{ - DataProperties dp; - dp.streamId = index; - - // AVCodecContext* codec_context = formatContext->streams[index]->codec; - - // dp.codecId = codec_context->codec_id; - - //detectAncillaryData( formatContext, index ); - - return dp; -} - } - -#endif \ No newline at end of file diff --git a/src/AvTranscoder/mediaProperty/DataProperties.hpp b/src/AvTranscoder/mediaProperty/DataProperties.hpp new file mode 100644 index 00000000..658f84a6 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/DataProperties.hpp @@ -0,0 +1,38 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_DATA_PROPERTIES_HPP +#define _AV_TRANSCODER_MEDIA_PROPERTY_DATA_PROPERTIES_HPP + +#include +#include + +extern "C" { +#include +} + +namespace avtranscoder +{ + +class AvExport DataProperties +{ +public: + DataProperties( const AVFormatContext* formatContext, const size_t index ); + + size_t getStreamId() const { return _streamId; } + MetadatasMap& getMetadatas() { return _metadatas; } + + const AVFormatContext& getAVFormatContext() { return *_formatContext; } + + MetadatasMap getDataMap() const; + +private: + void detectAncillaryData(); + +private: + const AVFormatContext* _formatContext; ///< Has link (no ownership) + + size_t _streamId; + MetadatasMap _metadatas; +}; + +} + +#endif diff --git a/src/AvTranscoder/mediaProperty/FileProperties.cpp b/src/AvTranscoder/mediaProperty/FileProperties.cpp new file mode 100644 index 00000000..4636ca91 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/FileProperties.cpp @@ -0,0 +1,48 @@ +#include "FileProperties.hpp" + +namespace avtranscoder +{ + +FileProperties::FileProperties( const AVFormatContext* formatContext ) + : _formatContext( formatContext ) + , _videoStreams() + , _audioStreams() + , _dataStreams() + , _subtitleStreams() + , _attachementStreams() + , _unknownStreams() +{ + if( formatContext ) + detail::fillMetadataDictionnary( _formatContext->metadata, _metadatas ); +} + + +MetadatasMap FileProperties::getDataMap() const +{ + MetadatasMap dataMap; + + detail::add( dataMap, "filename", getFilename() ); + detail::add( dataMap, "formatName", getFormatName() ); + detail::add( dataMap, "formatLongName", getFormatLongName() ); + + detail::add( dataMap, "startTime", getStartTime() ); + detail::add( dataMap, "duration", getDuration() ); + detail::add( dataMap, "bitrate", getBitRate() ); + detail::add( dataMap, "numberOfStreams", getNbStreams() ); + detail::add( dataMap, "numberOfPrograms", getProgramsCount() ); + detail::add( dataMap, "numberOfVideoStreams", getNbVideoStreams() ); + detail::add( dataMap, "numberOfAudioStreams", getNbAudioStreams() ); + detail::add( dataMap, "numberOfDataStreams", getNbDataStreams() ); + detail::add( dataMap, "numberOfSubtitleStreams", getNbSubtitleStreams() ); + detail::add( dataMap, "numberOfAttachementStreams", getNbAttachementStreams() ); + detail::add( dataMap, "numberOfUnknownStreams", getNbUnknownStreams() ); + + for( size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex ) + { + detail::add( dataMap, _metadatas.at( metadataIndex ).first, _metadatas.at( metadataIndex ).second ); + } + + return dataMap; +} + +} diff --git a/src/AvTranscoder/mediaProperty/FileProperties.hpp b/src/AvTranscoder/mediaProperty/FileProperties.hpp new file mode 100644 index 00000000..4e87b51f --- /dev/null +++ b/src/AvTranscoder/mediaProperty/FileProperties.hpp @@ -0,0 +1,80 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_FILE_PROPERTIES_HPP +#define _AV_TRANSCODER_MEDIA_PROPERTY_FILE_PROPERTIES_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +} + +#include +#include + +namespace avtranscoder +{ + +class AvExport FileProperties +{ +public: + FileProperties( const AVFormatContext* formatContext ); + + std::string getFilename() const { return _formatContext->filename; } + std::string getFormatName() const { return _formatContext->iformat->name; } + std::string getFormatLongName() const { return _formatContext->iformat->long_name; } + + size_t getProgramsCount() const { return _formatContext->nb_programs; } + double getStartTime() const { return 1.0 * (unsigned int)_formatContext->start_time / AV_TIME_BASE; } + double getDuration() const { return 1.0 * _formatContext->duration / AV_TIME_BASE; } + size_t getBitRate() const { return _formatContext->bit_rate; } + size_t getPacketSize() const { return _formatContext->packet_size; } + + MetadatasMap& getMetadatas() { return _metadatas; } + + size_t getNbStreams() const { return _formatContext->nb_streams; } + size_t getNbVideoStreams() const { return _videoStreams.size(); } + size_t getNbAudioStreams() const { return _audioStreams.size(); } + size_t getNbDataStreams() const { return _dataStreams.size(); } + size_t getNbSubtitleStreams() const { return _subtitleStreams.size(); } + size_t getNbAttachementStreams() const { return _attachementStreams.size(); } + size_t getNbUnknownStreams() const { return _unknownStreams.size(); } + + std::vector< avtranscoder::VideoProperties >& getVideoProperties() { return _videoStreams; } + const std::vector< avtranscoder::VideoProperties >& getVideoProperties() const { return _videoStreams; } + std::vector< avtranscoder::AudioProperties >& getAudioProperties() { return _audioStreams; } + const std::vector< avtranscoder::AudioProperties >& getAudioProperties() const { return _audioStreams; } + std::vector< avtranscoder::DataProperties >& getDataProperties() { return _dataStreams; } + const std::vector< avtranscoder::DataProperties >& getDataProperties() const { return _dataStreams; } + std::vector< avtranscoder::SubtitleProperties >& getSubtitleProperties() { return _subtitleStreams; } + const std::vector< avtranscoder::SubtitleProperties >& getSubtitleProperties() const { return _subtitleStreams; } + std::vector< avtranscoder::AttachementProperties >& getAttachementProperties() { return _attachementStreams; } + const std::vector< avtranscoder::AttachementProperties >& getAttachementProperties() const { return _attachementStreams; } + std::vector< avtranscoder::UnknownProperties >& getUnknownPropertiesProperties() { return _unknownStreams; } + const std::vector< avtranscoder::UnknownProperties >& getUnknownPropertiesProperties() const { return _unknownStreams; } + + const AVFormatContext& getAVFormatContext() { return *_formatContext; } + + MetadatasMap getDataMap() const; + +private: + const AVFormatContext* _formatContext; ///< Has link (no ownership) + + std::vector< VideoProperties > _videoStreams; ///< Array of properties per video stream + std::vector< AudioProperties > _audioStreams; ///< Array of properties per audio stream + std::vector< DataProperties > _dataStreams; ///< Array of properties per data stream + std::vector< SubtitleProperties > _subtitleStreams; ///< Array of properties per subtitle stream + std::vector< AttachementProperties > _attachementStreams; ///< Array of properties per attachement stream + std::vector< UnknownProperties > _unknownStreams; ///< Array of properties per unknown stream + + MetadatasMap _metadatas; +}; + +} + +#endif diff --git a/src/AvTranscoder/mediaProperty/SubtitleProperties.cpp b/src/AvTranscoder/mediaProperty/SubtitleProperties.cpp new file mode 100644 index 00000000..8dd124ca --- /dev/null +++ b/src/AvTranscoder/mediaProperty/SubtitleProperties.cpp @@ -0,0 +1,28 @@ +#include "SubtitleProperties.hpp" + +namespace avtranscoder +{ + +SubtitleProperties::SubtitleProperties( const AVFormatContext* formatContext, const size_t index ) + : _formatContext( formatContext ) + , _streamId( index ) +{ + if( formatContext ) + detail::fillMetadataDictionnary( _formatContext->streams[index]->metadata, _metadatas ); +} + +MetadatasMap SubtitleProperties::getDataMap() const +{ + MetadatasMap dataMap; + + detail::add( dataMap, "streamId", _streamId ); + + for( size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex ) + { + detail::add( dataMap, _metadatas.at( metadataIndex ).first, _metadatas.at( metadataIndex ).second ); + } + + return dataMap; +} + +} diff --git a/src/AvTranscoder/mediaProperty/SubtitleProperties.hpp b/src/AvTranscoder/mediaProperty/SubtitleProperties.hpp new file mode 100644 index 00000000..b08f69c8 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/SubtitleProperties.hpp @@ -0,0 +1,35 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_SUBTITLE_PROPERTIES_HPP +#define _AV_TRANSCODER_MEDIA_PROPERTY_SUBTITLE_PROPERTIES_HPP + +#include +#include + +extern "C" { +#include +} + +namespace avtranscoder +{ + +class AvExport SubtitleProperties +{ +public: + SubtitleProperties( const AVFormatContext* formatContext, const size_t index ); + + size_t getStreamId() const { return _streamId; } + MetadatasMap& getMetadatas() { return _metadatas; } + + const AVFormatContext& getAVFormatContext() { return *_formatContext; } + + MetadatasMap getDataMap() const; + +private: + const AVFormatContext* _formatContext; ///< Has link (no ownership) + + size_t _streamId; + MetadatasMap _metadatas; +}; + +} + +#endif diff --git a/src/AvTranscoder/mediaProperty/SubtitleStreamProperty.hpp b/src/AvTranscoder/mediaProperty/SubtitleStreamProperty.hpp deleted file mode 100644 index 9253a319..00000000 --- a/src/AvTranscoder/mediaProperty/SubtitleStreamProperty.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _AV_TRANSCODER_SUBTITLE_STREAM_PROPERTIES_HPP_ -#define _AV_TRANSCODER_SUBTITLE_STREAM_PROPERTIES_HPP_ - -class AVFormatContext; - -namespace avtranscoder -{ - -SubtitleProperties subtitleStreamInfo( const AVFormatContext* formatContext, const size_t index ) -{ - SubtitleProperties sp; - sp.streamId = index; - - return sp; -} - -} - -#endif \ No newline at end of file diff --git a/src/AvTranscoder/mediaProperty/UnknownProperties.cpp b/src/AvTranscoder/mediaProperty/UnknownProperties.cpp new file mode 100644 index 00000000..386838a3 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/UnknownProperties.cpp @@ -0,0 +1,28 @@ +#include "UnknownProperties.hpp" + +namespace avtranscoder +{ + +UnknownProperties::UnknownProperties( const AVFormatContext* formatContext, const size_t index ) + : _formatContext( formatContext ) + , _streamId( index ) +{ + if( formatContext ) + detail::fillMetadataDictionnary( _formatContext->streams[index]->metadata, _metadatas ); +} + +MetadatasMap UnknownProperties::getDataMap() const +{ + MetadatasMap dataMap; + + detail::add( dataMap, "streamId", _streamId ); + + for( size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex ) + { + detail::add( dataMap, _metadatas.at( metadataIndex ).first, _metadatas.at( metadataIndex ).second ); + } + + return dataMap; +} + +} diff --git a/src/AvTranscoder/mediaProperty/UnknownProperties.hpp b/src/AvTranscoder/mediaProperty/UnknownProperties.hpp new file mode 100644 index 00000000..3e07a357 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/UnknownProperties.hpp @@ -0,0 +1,35 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_UNKNOWN_PROPERTIES_HPP +#define _AV_TRANSCODER_MEDIA_PROPERTY_UNKNOWN_PROPERTIES_HPP + +#include +#include + +extern "C" { +#include +} + +namespace avtranscoder +{ + +class AvExport UnknownProperties +{ +public: + UnknownProperties( const AVFormatContext* formatContext, const size_t index ); + + size_t getStreamId() const { return _streamId; } + MetadatasMap& getMetadatas() { return _metadatas; } + + const AVFormatContext& getAVFormatContext() { return *_formatContext; } + + MetadatasMap getDataMap() const; + +private: + const AVFormatContext* _formatContext; ///< Has link (no ownership) + + size_t _streamId; + MetadatasMap _metadatas; +}; + +} + +#endif diff --git a/src/AvTranscoder/mediaProperty/UnknownStreamProperty.hpp b/src/AvTranscoder/mediaProperty/UnknownStreamProperty.hpp deleted file mode 100644 index 3d2b21e4..00000000 --- a/src/AvTranscoder/mediaProperty/UnknownStreamProperty.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _AV_TRANSCODER_UNKNOWN_STREAM_PROPERTIES_HPP_ -#define _AV_TRANSCODER_UNKNOWN_STREAM_PROPERTIES_HPP_ - -class AVFormatContext; - -namespace avtranscoder -{ - -UnknownProperties unknownStreamInfo( const AVFormatContext* formatContext, const size_t index ) -{ - UnknownProperties up; - up.streamId = index; - - return up; -} - -} - -#endif \ No newline at end of file diff --git a/src/AvTranscoder/mediaProperty/VideoProperties.cpp b/src/AvTranscoder/mediaProperty/VideoProperties.cpp new file mode 100644 index 00000000..84f04a4e --- /dev/null +++ b/src/AvTranscoder/mediaProperty/VideoProperties.cpp @@ -0,0 +1,739 @@ +#include "VideoProperties.hpp" + +#include + +extern "C" { +#include +} + +#include +#include +#include +#include + +#ifdef _MSC_VER +#include +#define isnan _isnan +#define isinf(x) (!_finite(x)) +#endif + +namespace avtranscoder +{ + +VideoProperties::VideoProperties( const AVFormatContext* formatContext, const size_t index, IProgress& progress, const EAnalyseLevel level ) + : _formatContext( formatContext ) + , _codecContext( NULL ) + , _codec( NULL ) + , _pixFmt( NULL ) + , _streamId( index ) + , _isInterlaced( false ) + , _isTopFieldFirst( false ) + , _gopStructure() +{ + if( _formatContext ) + _codecContext = formatContext->streams[index]->codec; + + if( _formatContext && _codecContext ) + _codec = avcodec_find_decoder( _codecContext->codec_id ); + + if( formatContext ) + detail::fillMetadataDictionnary( _formatContext->streams[index]->metadata, _metadatas ); + + // Skip decoding for selected frames + _codecContext->skip_frame = AVDISCARD_NONE; + + // Get pixel format +#if LIBAVUTIL_VERSION_MAJOR > 51 + _pixFmt = av_pix_fmt_desc_get( _codecContext->pix_fmt ); +#else + if( _codecContext->pix_fmt >= 0 && _codecContext->pix_fmt < PIX_FMT_NB ) + _pixFmt = &av_pix_fmt_descriptors[ _codecContext->pix_fmt ]; +#endif + + if( level == eAnalyseLevelFirstGop ) + analyseGopStructure( progress ); +} + +std::string VideoProperties::getCodecName() const +{ + if( _codecContext && _codec ) + { + if( _codec->capabilities & CODEC_CAP_TRUNCATED ) + _codecContext->flags|= CODEC_FLAG_TRUNCATED; + + if( _codec->name ) + return std::string( _codec->name ); + } + return "unknown codec"; +} + +std::string VideoProperties::getCodecLongName() const +{ + if( _codecContext && _codec ) + { + if( _codec->capabilities & CODEC_CAP_TRUNCATED ) + _codecContext->flags|= CODEC_FLAG_TRUNCATED; + + if( _codec->long_name ) + return std::string( _codec->long_name ); + } + return "unknown codec"; +} + +std::string VideoProperties::getProfileName() const +{ + if( _codecContext && _codec ) + { + if( _codec->capabilities & CODEC_CAP_TRUNCATED ) + _codecContext->flags|= CODEC_FLAG_TRUNCATED; + + if( _codecContext->profile != -99 ) + { + const char* profile; + if( ( profile = av_get_profile_name( _codec, _codecContext->profile ) ) != NULL ) + return std::string( profile ); + } + } + return "unknown profile"; +} + +std::string VideoProperties::getColorTransfert() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + switch( _codecContext->color_trc ) + { + case AVCOL_TRC_BT709: + return "Rec 709 / ITU-R BT1361"; + case AVCOL_TRC_UNSPECIFIED: + return "unspecified"; + case AVCOL_TRC_GAMMA22: + return "Gamma 2.2"; + case AVCOL_TRC_GAMMA28: + return "Gamma 2.8"; +#if LIBAVCODEC_VERSION_MAJOR > 53 + case AVCOL_TRC_SMPTE240M: + return "Smpte 240M"; +#endif +#if LIBAVCODEC_VERSION_MAJOR > 54 +#ifdef AVCOL_TRC_SMPTE170M + case AVCOL_TRC_SMPTE170M: + return "Rec 601 / ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC"; +#endif +#ifdef AVCOL_TRC_LINEAR + case AVCOL_TRC_LINEAR: + return "Linear transfer characteristics"; +#endif +#ifdef AVCOL_TRC_LOG + case AVCOL_TRC_LOG: + return "Logarithmic transfer characteristic (100:1 range)"; +#endif +#ifdef AVCOL_TRC_LOG_SQRT + case AVCOL_TRC_LOG_SQRT: + return "Logarithmic transfer characteristic (100 * Sqrt( 10 ) : 1 range)"; +#endif +#ifdef AVCOL_TRC_IEC61966_2_4 + case AVCOL_TRC_IEC61966_2_4: + return "IEC 61966-2-4"; +#endif +#ifdef AVCOL_TRC_BT1361_ECG + case AVCOL_TRC_BT1361_ECG: + return "ITU-R BT1361 Extended Colour Gamut"; +#endif +#ifdef AVCOL_TRC_IEC61966_2_1 + case AVCOL_TRC_IEC61966_2_1: + return "IEC 61966-2-1 (sRGB or sYCC)"; +#endif +#ifdef AVCOL_TRC_BT2020_10 + case AVCOL_TRC_BT2020_10: + return "ITU-R BT2020 for 10 bit system"; +#endif +#ifdef AVCOL_TRC_BT2020_12 + case AVCOL_TRC_BT2020_12: + return "ITU-R BT2020 for 12 bit system"; +#endif +#endif + case AVCOL_TRC_NB: + return "Not ABI"; + default: + return ""; + } +} + +std::string VideoProperties::getColorspace() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + switch( _codecContext->colorspace ) + { + case AVCOL_SPC_RGB: + return "RGB"; + case AVCOL_SPC_BT709: + return "Rec 709"; + case AVCOL_SPC_UNSPECIFIED: + return "unspecified"; + case AVCOL_SPC_FCC: + return "Four CC"; + case AVCOL_SPC_BT470BG: + return "BT470 (PAL - 625)"; + case AVCOL_SPC_SMPTE170M: + return "Smpte 170M (NTSC)"; + case AVCOL_SPC_SMPTE240M: + return "Smpte 240M"; +#if LIBAVCODEC_VERSION_MAJOR > 53 + case AVCOL_SPC_YCOCG: + return "Y Co Cg"; +//#else +// case AVCOL_SPC_YCGCO: +// return "Y Cg Co"; +#endif +#if LIBAVCODEC_VERSION_MAJOR > 54 +#ifdef AVCOL_TRC_BT2020_12 + case AVCOL_SPC_BT2020_NCL: + return "ITU-R BT2020 non-constant luminance system"; +#endif +#ifdef AVCOL_TRC_BT2020_CL + case AVCOL_SPC_BT2020_CL: + return "ITU-R BT2020 constant luminance system"; +#endif +#endif + case AVCOL_SPC_NB: + return "Not ABI"; + default: + return ""; + } +} + +std::string VideoProperties::getColorRange() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + switch( _codecContext->color_range ) + { + case AVCOL_RANGE_UNSPECIFIED: + return "unspecified"; + case AVCOL_RANGE_MPEG: + return "Head"; + case AVCOL_RANGE_JPEG: + return "Full"; + case AVCOL_RANGE_NB: + return "Not ABI"; + default: + return ""; + } +} + +std::string VideoProperties::getColorPrimaries() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + switch( _codecContext->color_primaries ) + { + case AVCOL_PRI_BT709: + return "Rec 709"; + case AVCOL_PRI_UNSPECIFIED: + return "unspecified"; + case AVCOL_PRI_BT470M: + return "BT 470M"; + case AVCOL_PRI_BT470BG: + return "Rec 601 (PAL & SECAM)"; + case AVCOL_PRI_SMPTE170M: + return "Rec 601 (NTSC)"; + case AVCOL_PRI_SMPTE240M: + return "Smpte 240 (NTSC)"; + case AVCOL_PRI_FILM: + return "Film"; +#if LIBAVCODEC_VERSION_MAJOR > 54 +#ifdef AVCOL_TRC_BT2020_CL + case AVCOL_PRI_BT2020: + return "ITU-R BT2020"; +#endif +#endif + case AVCOL_PRI_NB: + return "Not ABI"; + default: + return ""; + } +} + +std::string VideoProperties::getChromaSampleLocation() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + switch( _codecContext->chroma_sample_location ) + { + case AVCHROMA_LOC_UNSPECIFIED: + return "unspecified"; + case AVCHROMA_LOC_LEFT: + return "left (mpeg2/4, h264 default)"; + case AVCHROMA_LOC_CENTER: + return "center (mpeg1, jpeg, h263)"; + case AVCHROMA_LOC_TOPLEFT: + return "top left"; + case AVCHROMA_LOC_TOP: + return "top"; + case AVCHROMA_LOC_BOTTOMLEFT: + return "bottom left"; + case AVCHROMA_LOC_BOTTOM: + return "bottom"; + case AVCHROMA_LOC_NB: + return "Not ABI"; + default: + return ""; + } +} + +std::string VideoProperties::getFieldOrder() const +{ + if( ! _codecContext ) + return "unknown codec context"; + + switch( _codecContext->field_order ) + { + case AV_FIELD_UNKNOWN: + return "unknown"; + case AV_FIELD_PROGRESSIVE: + return "progressive"; + case AV_FIELD_TT: + return "top top"; + case AV_FIELD_BB: + return "bottom bottom"; + case AV_FIELD_TB: + return "top bottom"; + case AV_FIELD_BT: + return "bottom top"; + default: + return ""; + } +} + +std::string VideoProperties::getPixelName() const +{ + if( _pixFmt && _pixFmt->name ) + return std::string( _pixFmt->name ); + return "unknown pixel name"; +} + +std::string VideoProperties::getEndianess() const +{ + if( _pixFmt ) + return ( _pixFmt->flags & PIX_FMT_BE ) ? "big" : "little"; + return "unknown pixel format"; +} + + +int64_t VideoProperties::getStartTimecode() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->timecode_frame_start; +} + +std::string VideoProperties::getStartTimecodeString() const +{ + int64_t stratTimeCode = getStartTimecode(); + std::ostringstream os; + os << std::setfill( '0' ); + os << std::setw(2) << ( stratTimeCode >> 19 & 0x1f ) << ":"; // 5-bit hours + os << std::setw(2) << ( stratTimeCode >> 13 & 0x3f ) << ":"; // 6-bit minutes + os << std::setw(2) << ( stratTimeCode >> 6 & 0x3f ) ; // 6-bit seconds + os << ( stratTimeCode & 1 << 24 ? ';' : ':' ); // 1-bit drop flag + os << std::setw(2) << ( stratTimeCode & 0x3f ); // 6-bit frames + return os.str(); +} + + +Rational VideoProperties::getTimeBase() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + Rational timeBase = { + _codecContext->time_base.num, + _codecContext->time_base.den, + }; + return timeBase; +} + +Rational VideoProperties::getSar() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + Rational sar = { + _codecContext->sample_aspect_ratio.num, + _codecContext->sample_aspect_ratio.den, + }; + return sar; +} + +Rational VideoProperties::getDar() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + int darNum, darDen; + av_reduce( &darNum, &darDen, + _codecContext->width * getSar().num, + _codecContext->height * getSar().den, + 1024 * 1024); + + Rational dar = { + darNum, + darDen, + }; + return dar; +} + +size_t VideoProperties::getCodecId() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->codec_id; +} + +size_t VideoProperties::getBitRate() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->bit_rate; +} + +size_t VideoProperties::getMaxBitRate() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->rc_max_rate; +} + +size_t VideoProperties::getMinBitRate() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->rc_min_rate; +} + +size_t VideoProperties::getTicksPerFrame() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->ticks_per_frame; +} + +size_t VideoProperties::getWidth() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->width; +} + +size_t VideoProperties::getHeight() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->height; +} + +size_t VideoProperties::getGopSize() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->gop_size; +} + +size_t VideoProperties::getDtgActiveFormat() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->dtg_active_format; +} + +size_t VideoProperties::getReferencesFrames() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->refs; +} + +int VideoProperties::getProfile() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->profile; +} + +int VideoProperties::getLevel() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return _codecContext->level; +} + +size_t VideoProperties::getComponentsCount() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + + return _pixFmt->nb_components; +} + +size_t VideoProperties::getChromaWidth() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + + return _pixFmt->log2_chroma_w; +} + +size_t VideoProperties::getChromaHeight() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + + return _pixFmt->log2_chroma_h; +} + +double VideoProperties::getFps() const +{ + Rational timeBase = getTimeBase(); + double fps = 1.0 * timeBase.den / ( timeBase.num * getTicksPerFrame() ); + if( isinf( fps ) ) + fps = 0.0; + return fps; +} + +bool VideoProperties::hasBFrames() const +{ + if( ! _codecContext ) + throw std::runtime_error( "unknown codec context" ); + + return (bool) _codecContext->has_b_frames; +} + +bool VideoProperties::isIndexedColors() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + + return (bool) _pixFmt->flags & PIX_FMT_PAL; +} + +bool VideoProperties::isBitWisePacked() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + + return (bool) _pixFmt->flags & PIX_FMT_BITSTREAM; +} + +bool VideoProperties::isHardwareAccelerated() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + + return (bool) _pixFmt->flags & PIX_FMT_HWACCEL; +} + +bool VideoProperties::isPlanar() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + + return (bool) _pixFmt->flags & PIX_FMT_PLANAR; +} + +bool VideoProperties::isRgbPixelData() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + + return (bool) _pixFmt->flags & PIX_FMT_RGB; +} + +bool VideoProperties::isPseudoPaletted() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + +#if LIBAVCODEC_VERSION_MAJOR > 53 + return (bool) _pixFmt->flags & PIX_FMT_PSEUDOPAL; +#else + return false; +#endif +} + +bool VideoProperties::hasAlpha() const +{ + if( ! _pixFmt ) + throw std::runtime_error( "unknown pixel format" ); + +#if LIBAVCODEC_VERSION_MAJOR > 53 + return (bool) _pixFmt->flags & PIX_FMT_ALPHA; +#else + return false; +#endif +} + +void VideoProperties::analyseGopStructure( IProgress& progress ) +{ + if( _formatContext && _codecContext && _codec ) + { + if( _codec->capabilities & CODEC_CAP_TRUNCATED ) + _codecContext->flags|= CODEC_FLAG_TRUNCATED; + + if( _codecContext->width && _codecContext->height ) + { + AVPacket pkt; + +#if LIBAVCODEC_VERSION_MAJOR > 54 + AVFrame* frame = av_frame_alloc(); +#else + AVFrame* frame = avcodec_alloc_frame(); +#endif + + av_init_packet( &pkt ); + avcodec_open2( _codecContext, _codec, NULL ); + + int count = 0; + int gotFrame = 0; + bool stopAnalyse = false; + + while( ! av_read_frame( const_cast( _formatContext ), &pkt ) ) + { + if( pkt.stream_index == (int)_streamId ) + { + avcodec_decode_video2( _codecContext, frame, &gotFrame, &pkt ); + if( gotFrame ) + { + _gopStructure.push_back( std::make_pair( av_get_picture_type_char( frame->pict_type ), frame->key_frame ) ); + _isInterlaced = frame->interlaced_frame; + _isTopFieldFirst = frame->top_field_first; + ++count; + if( progress.progress( count, _codecContext->gop_size ) == eJobStatusCancel ) + stopAnalyse = true; + } + } + + av_free_packet( &pkt ); + + if( _codecContext->gop_size == count ) + { + stopAnalyse = true; + } + + if( stopAnalyse ) + break; + } +#if LIBAVCODEC_VERSION_MAJOR > 54 + av_frame_free( &frame ); +#else +#if LIBAVCODEC_VERSION_MAJOR > 53 + avcodec_free_frame( &frame ); +#else + av_free( frame ); +#endif +#endif + } + } +} + +std::vector VideoProperties::getChannels() const +{ + std::vector channels; + if( _pixFmt ) + { + for( size_t channel = 0; channel < (size_t)_pixFmt->nb_components; ++channel ) + { + Channel c; + c.id = channel; + c.chromaHeight = (size_t)_pixFmt->comp[channel].plane; + c.bitStep = (size_t)_pixFmt->comp[channel].step_minus1; + channels.push_back( c ); + } + } + return channels; +} + +MetadatasMap VideoProperties::getDataMap() const +{ + MetadatasMap dataMap; + + detail::add( dataMap, "streamId", getStreamId() ); + detail::add( dataMap, "codecId", getCodecId() ); + detail::add( dataMap, "codecName", getCodecName() ); + detail::add( dataMap, "codecLongName", getCodecLongName() ); + detail::add( dataMap, "profile", getProfile() ); + detail::add( dataMap, "profileName", getProfileName() ); + detail::add( dataMap, "level", getLevel() ); + detail::add( dataMap, "startTimecode", getStartTimecode() ); + detail::add( dataMap, "width", getWidth() ); + detail::add( dataMap, "height", getHeight() ); + detail::add( dataMap, "pixelAspectRatio", getSar().num / getSar().den ); + detail::add( dataMap, "displayAspectRatio", getDar().num / getDar().den ); + detail::add( dataMap, "dtgActiveFormat", getDtgActiveFormat() ); + detail::add( dataMap, "componentsCount", getComponentsCount() ); + detail::add( dataMap, "pixelType", getPixelName() ); + detail::add( dataMap, "bitWiseAcked", isBitWisePacked() ); + detail::add( dataMap, "rgbPixel", isRgbPixelData() ); + detail::add( dataMap, "asAlpha", hasAlpha() ); + detail::add( dataMap, "chromaWidth", getChromaWidth() ); + detail::add( dataMap, "chromaHeight", getChromaHeight() ); + detail::add( dataMap, "endianess", getEndianess() ); + detail::add( dataMap, "colorTransfert", getColorTransfert() ); + detail::add( dataMap, "colorspace", getColorspace() ); + detail::add( dataMap, "colorRange", getColorRange() ); + detail::add( dataMap, "colorPrimaries", getColorPrimaries() ); + detail::add( dataMap, "indexedColors", isIndexedColors() ); + detail::add( dataMap, "pseudoPaletted", isPseudoPaletted() ); + detail::add( dataMap, "chromaSampleLocation", getChromaSampleLocation() ); + detail::add( dataMap, "interlaced ", isInterlaced() ); + detail::add( dataMap, "topFieldFirst", isTopFieldFirst() ); + detail::add( dataMap, "fieldOrder", getFieldOrder() ); + detail::add( dataMap, "timeBase", getTimeBase().num / getTimeBase().den ); + detail::add( dataMap, "fps", getFps() ); + detail::add( dataMap, "ticksPerFrame", getTicksPerFrame() ); + detail::add( dataMap, "bitRate", getBitRate() ); + detail::add( dataMap, "maxBitRate", getMaxBitRate() ); + detail::add( dataMap, "minBitRate", getMinBitRate() ); + detail::add( dataMap, "gopSize", getGopSize() ); + + std::string gop; + NoDisplayProgress progress; + std::vector< std::pair< char, bool > > gopStructure = getGopStructure(); + for( size_t frameIndex = 0; frameIndex < gopStructure.size(); ++frameIndex ) + { + gop += gopStructure.at( frameIndex ).first; + gop += ( gopStructure.at( frameIndex ).second ? "*" : " " ); + } + detail::add( dataMap, "gop", gop ); + + detail::add( dataMap, "hasBFrames", hasBFrames() ); + detail::add( dataMap, "referencesFrames", getReferencesFrames() ); + + for( size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex ) + { + detail::add( dataMap, _metadatas.at( metadataIndex ).first, _metadatas.at( metadataIndex ).second ); + } + + return dataMap; +} + +} diff --git a/src/AvTranscoder/mediaProperty/VideoProperties.hpp b/src/AvTranscoder/mediaProperty/VideoProperties.hpp new file mode 100644 index 00000000..f5143d45 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/VideoProperties.hpp @@ -0,0 +1,127 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_VIDEO_PROPERTIES_HPP +#define _AV_TRANSCODER_MEDIA_PROPERTY_VIDEO_PROPERTIES_HPP + +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +} + +#include +#include +#include + +namespace avtranscoder +{ + +struct AvExport Channel +{ + size_t id; + size_t chromaHeight; + size_t bitStep; +}; + +class AvExport VideoProperties +{ +public: + VideoProperties( const AVFormatContext* formatContext, const size_t index, IProgress& progress, const EAnalyseLevel level = eAnalyseLevelFirstGop ); + + std::string getCodecName() const; + std::string getCodecLongName() const; + std::string getProfileName() const; + std::string getColorTransfert() const; + std::string getColorspace() const; + std::string getColorRange() const; + std::string getColorPrimaries() const; + std::string getChromaSampleLocation() const; + std::string getFieldOrder() const; + + std::string getPixelName() const; + std::string getEndianess() const; + + int64_t getStartTimecode() const; + std::string getStartTimecodeString() const; + + Rational getTimeBase() const; + Rational getSar() const; // sample/pixel aspect ratio + Rational getDar() const; // display aspect ratio + + size_t getStreamId() const { return _streamId; } + size_t getCodecId() const; + size_t getBitRate() const; + size_t getMaxBitRate() const; + size_t getMinBitRate() const; + size_t getTicksPerFrame() const; + size_t getWidth() const; + size_t getHeight() const; + size_t getGopSize() const; + size_t getDtgActiveFormat() const; + size_t getReferencesFrames() const; + int getProfile() const; + int getLevel() const; + size_t getComponentsCount() const; + size_t getChromaWidth() const; + size_t getChromaHeight() const; + + double getFps() const; + + bool hasBFrames() const; + bool isIndexedColors() const; + bool isBitWisePacked() const; + bool isHardwareAccelerated() const; + bool isPlanar() const; + bool isRgbPixelData() const; + bool isPseudoPaletted() const; + bool hasAlpha() const; + + //@{ + // Warning: Can acces these data when analyse first gop + // Construct the VideoProperties with level = eAnalyseLevelFull + // @see EAnalyseLevel + // @see analyseGopStructure + bool isInterlaced() const { return _isInterlaced; } + bool isTopFieldFirst() const { return _isTopFieldFirst; } + std::vector< std::pair< char, bool > > getGopStructure() const { return _gopStructure; } + //@} + + std::vector getChannels() const; + + MetadatasMap& getMetadatas() { return _metadatas; } + + const AVFormatContext& getAVFormatContext() { return *_formatContext; } + AVCodecContext& getAVCodecContext() { return *_codecContext; } + const AVPixFmtDescriptor& getAVPixFmtDescriptor() { return *_pixFmt; } + + MetadatasMap getDataMap() const; ///< Warning: the method calls analyseGopStructure, which can modify state of the object + +private: + /** + * @brief frame type / is key frame + * @param progress: callback to get analysis progression + */ + void analyseGopStructure( IProgress& progress ); + +private: + const AVFormatContext* _formatContext; ///< Has link (no ownership) + AVCodecContext* _codecContext; ///< Has link (no ownership) + AVCodec* _codec; ///< Has link (no ownership) + const AVPixFmtDescriptor* _pixFmt; ///< Has link (no ownership) + + size_t _streamId; + //@{ + // Can acces these data when analyse first gop + bool _isInterlaced; + bool _isTopFieldFirst; + std::vector< std::pair< char, bool > > _gopStructure; + //@} + MetadatasMap _metadatas; +}; + +} + +#endif diff --git a/src/AvTranscoder/mediaProperty/VideoStreamProperty.hpp b/src/AvTranscoder/mediaProperty/VideoStreamProperty.hpp deleted file mode 100644 index da3f0778..00000000 --- a/src/AvTranscoder/mediaProperty/VideoStreamProperty.hpp +++ /dev/null @@ -1,344 +0,0 @@ -#ifndef _AV_TRANSCODER_VIDEO_STREAM_PROPERTIES_HPP_ -#define _AV_TRANSCODER_VIDEO_STREAM_PROPERTIES_HPP_ - -extern "C" { -#include -#include -#include -#include -} - -#include -#include -#include - -#ifdef _MSC_VER -#include -#define isnan _isnan -#define isinf(x) (!_finite(x)) -#endif - -namespace avtranscoder -{ - -namespace details -{ - -void getGopProperties( - VideoProperties& vp, - AVFormatContext* formatContext, - AVCodecContext* codecContext, - AVCodec* codec, - const int videoStreamIndex, - IProgress& progress - ) -{ - AVPacket pkt; - -#if LIBAVCODEC_VERSION_MAJOR > 54 - AVFrame* frame = av_frame_alloc(); -#else - AVFrame* frame = avcodec_alloc_frame(); -#endif - - av_init_packet( &pkt ); - avcodec_open2( codecContext, codec, NULL ); - - int count = 0; - int gotFrame = 0; - bool stopAnalyse = false; - - while( ! av_read_frame( formatContext, &pkt ) ) - { - if( pkt.stream_index == videoStreamIndex ) - { - // std::cout << "decode frame" << std::endl; - avcodec_decode_video2( codecContext, frame, &gotFrame, &pkt ); - if( gotFrame ) - { - // std::cout << "inteleaved " << frame->interlaced_frame << std::endl; - vp.gopStructure.push_back( std::pair( av_get_picture_type_char( frame->pict_type ), frame->key_frame ) ); - vp.isInterlaced = frame->interlaced_frame; - vp.topFieldFirst = frame->top_field_first; - ++count; - if( progress.progress( count, codecContext->gop_size ) == eJobStatusCancel ) - stopAnalyse = true; - } - } - - av_free_packet( &pkt ); - - if( codecContext->gop_size == count ) - { - stopAnalyse = true; - } - - if( stopAnalyse ) - break; - } -#if LIBAVCODEC_VERSION_MAJOR > 54 - av_frame_free( &frame ); -#else - #if LIBAVCODEC_VERSION_MAJOR > 53 - avcodec_free_frame( &frame ); - #else - av_free( frame ); - #endif -#endif -} - -} - -std::string makeTimecodeMpegToString( uint32_t tc25bit ) -{ - std::ostringstream os; - os << std::setfill( '0' ); - os << std::setw(2) << ( tc25bit >> 19 & 0x1f ) << ":"; // 5-bit hours - os << std::setw(2) << ( tc25bit >> 13 & 0x3f ) << ":"; // 6-bit minutes - os << std::setw(2) << ( tc25bit >> 6 & 0x3f ) ; // 6-bit seconds - os << ( tc25bit & 1 << 24 ? ';' : ':' ); // 1-bit drop flag - os << std::setw(2) << ( tc25bit & 0x3f ); // 6-bit frames - return os.str(); -} - - -VideoProperties videoStreamInfo( - AVFormatContext* formatContext, - const size_t videoStreamIndex, - IProgress& progress, - const InputFile::EAnalyseLevel level - ) -{ - VideoProperties vp; - AVCodecContext* codec_context = formatContext->streams[videoStreamIndex]->codec; - - codec_context->skip_frame = AVDISCARD_NONE; - - vp.streamId = videoStreamIndex; - - vp.codecId = codec_context->codec_id; - vp.bitRate = codec_context->bit_rate; - vp.maxBitRate = codec_context->rc_max_rate; - vp.minBitRate = codec_context->rc_min_rate; - vp.isInterlaced = false; - vp.topFieldFirst = false; - - vp.ticksPerFrame = codec_context->ticks_per_frame, - vp.width = codec_context->width, - vp.height = codec_context->height, - vp.gopSize = codec_context->gop_size, - vp.dtgActiveFormat = codec_context->dtg_active_format, - vp.referencesFrames = codec_context->refs, - vp.profile = codec_context->profile, - vp.level = codec_context->level; - - vp.timeBase.num = codec_context->time_base.num; - vp.timeBase.den = codec_context->time_base.den; - vp.sar.num = codec_context->sample_aspect_ratio.num; - vp.sar.den = codec_context->sample_aspect_ratio.den; - - vp.startTimecode = makeTimecodeMpegToString( codec_context->timecode_frame_start ); - - int darNum, darDen; - av_reduce( &darNum, &darDen, - codec_context->width * codec_context->sample_aspect_ratio.num, - codec_context->height * codec_context->sample_aspect_ratio.den, - 1024 * 1024); - vp.dar.num = darNum; - vp.dar.den = darDen; - - vp.fps = 1.0 * codec_context->time_base.den / ( codec_context->time_base.num * codec_context->ticks_per_frame ); - - if( isinf( vp.fps ) ) - vp.fps = 0.0; - - vp.hasBFrames = (bool) codec_context->has_b_frames; - - - vp.colorspace = ""; - vp.colorTransfert = ""; - vp.colorRange = ""; - vp.colorPrimaries = ""; - vp.chromaSampleLocation = ""; - vp.fieldOrder = ""; - - switch( codec_context->color_trc ) - { - case AVCOL_TRC_BT709: vp.colorTransfert = "Rec 709 / ITU-R BT1361"; break; - case AVCOL_TRC_UNSPECIFIED: vp.colorTransfert = "unspecified"; break; - case AVCOL_TRC_GAMMA22: vp.colorTransfert = "Gamma 2.2"; break; - case AVCOL_TRC_GAMMA28: vp.colorTransfert = "Gamma 2.8"; break; -#if LIBAVCODEC_VERSION_MAJOR > 53 - case AVCOL_TRC_SMPTE240M: vp.colorTransfert = "Smpte 240M"; break; -#endif -#if LIBAVCODEC_VERSION_MAJOR > 54 - #ifdef AVCOL_TRC_SMPTE170M - case AVCOL_TRC_SMPTE170M: vp.colorTransfert = "Rec 601 / ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC"; break; - #endif - #ifdef AVCOL_TRC_LINEAR - case AVCOL_TRC_LINEAR: vp.colorTransfert = "Linear transfer characteristics"; break; - #endif - #ifdef AVCOL_TRC_LOG - case AVCOL_TRC_LOG: vp.colorTransfert = "Logarithmic transfer characteristic (100:1 range)"; break; - #endif - #ifdef AVCOL_TRC_LOG_SQRT - case AVCOL_TRC_LOG_SQRT: vp.colorTransfert = "Logarithmic transfer characteristic (100 * Sqrt( 10 ) : 1 range)"; break; - #endif - #ifdef AVCOL_TRC_IEC61966_2_4 - case AVCOL_TRC_IEC61966_2_4: vp.colorTransfert = "IEC 61966-2-4"; break; - #endif - #ifdef AVCOL_TRC_BT1361_ECG - case AVCOL_TRC_BT1361_ECG: vp.colorTransfert = "ITU-R BT1361 Extended Colour Gamut"; break; - #endif - #ifdef AVCOL_TRC_IEC61966_2_1 - case AVCOL_TRC_IEC61966_2_1: vp.colorTransfert = "IEC 61966-2-1 (sRGB or sYCC)"; break; - #endif - #ifdef AVCOL_TRC_BT2020_10 - case AVCOL_TRC_BT2020_10: vp.colorTransfert = "ITU-R BT2020 for 10 bit system"; break; - #endif - #ifdef AVCOL_TRC_BT2020_12 - case AVCOL_TRC_BT2020_12: vp.colorTransfert = "ITU-R BT2020 for 12 bit system"; break; - #endif -#endif - case AVCOL_TRC_NB: vp.colorTransfert = "Not ABI"; break; - default: break; - } - switch( codec_context->colorspace ) - { - case AVCOL_SPC_RGB: vp.colorspace = "RGB"; break; - case AVCOL_SPC_BT709: vp.colorspace = "Rec 709"; break; - case AVCOL_SPC_UNSPECIFIED: vp.colorspace = "unspecified"; break; - case AVCOL_SPC_FCC: vp.colorspace = "Four CC"; break; - case AVCOL_SPC_BT470BG: vp.colorspace = "BT470 (PAL - 625)"; break; - case AVCOL_SPC_SMPTE170M: vp.colorspace = "Smpte 170M (NTSC)"; break; - case AVCOL_SPC_SMPTE240M: vp.colorspace = "Smpte 240M"; break; -#if LIBAVCODEC_VERSION_MAJOR > 53 - case AVCOL_SPC_YCOCG: vp.colorspace = "Y Co Cg"; break; -//#else -// case AVCOL_SPC_YCGCO: vp.colorspace = "Y Cg Co"; break; -#endif -#if LIBAVCODEC_VERSION_MAJOR > 54 - #ifdef AVCOL_TRC_BT2020_12 - case AVCOL_SPC_BT2020_NCL: vp.colorspace = "ITU-R BT2020 non-constant luminance system"; break; - #endif - #ifdef AVCOL_TRC_BT2020_CL - case AVCOL_SPC_BT2020_CL: vp.colorspace = "ITU-R BT2020 constant luminance system"; break; - #endif -#endif - case AVCOL_SPC_NB: vp.colorspace = "Not ABI"; break; - default: break; - } - switch( codec_context->color_range ) - { - case AVCOL_RANGE_UNSPECIFIED: vp.colorRange = "unspecified"; break; - case AVCOL_RANGE_MPEG: vp.colorRange = "Head"; break; - case AVCOL_RANGE_JPEG: vp.colorRange = "Full"; break; - case AVCOL_RANGE_NB: vp.colorRange = "Not ABI"; break; - default: break; - } - switch( codec_context->color_primaries ) - { - case AVCOL_PRI_BT709: vp.colorPrimaries = "Rec 709"; break; - case AVCOL_PRI_UNSPECIFIED: vp.colorPrimaries = "unspecified"; break; - case AVCOL_PRI_BT470M: vp.colorPrimaries = "BT 470M"; break; - case AVCOL_PRI_BT470BG: vp.colorPrimaries = "Rec 601 (PAL & SECAM)"; break; - case AVCOL_PRI_SMPTE170M: vp.colorPrimaries = "Rec 601 (NTSC)"; break; - case AVCOL_PRI_SMPTE240M: vp.colorPrimaries = "Smpte 240 (NTSC)"; break; - case AVCOL_PRI_FILM: vp.colorPrimaries = "Film"; break; -#if LIBAVCODEC_VERSION_MAJOR > 54 - #ifdef AVCOL_TRC_BT2020_CL - case AVCOL_PRI_BT2020: vp.colorPrimaries = "ITU-R BT2020"; break; - #endif -#endif - case AVCOL_PRI_NB: vp.colorPrimaries = "Not ABI"; break; - default: break; - } - switch( codec_context->chroma_sample_location ) - { - case AVCHROMA_LOC_UNSPECIFIED: vp.chromaSampleLocation = "unspecified"; break; - case AVCHROMA_LOC_LEFT: vp.chromaSampleLocation = "left (mpeg2/4, h264 default)"; break; - case AVCHROMA_LOC_CENTER: vp.chromaSampleLocation = "center (mpeg1, jpeg, h263)"; break; - case AVCHROMA_LOC_TOPLEFT: vp.chromaSampleLocation = "top left"; break; - case AVCHROMA_LOC_TOP: vp.chromaSampleLocation = "top"; break; - case AVCHROMA_LOC_BOTTOMLEFT: vp.chromaSampleLocation = "bottom left"; break; - case AVCHROMA_LOC_BOTTOM: vp.chromaSampleLocation = "bottom"; break; - case AVCHROMA_LOC_NB: vp.chromaSampleLocation = "Not ABI"; break; - default: break; - } - switch( codec_context->field_order ) - { - case AV_FIELD_UNKNOWN: vp.fieldOrder = "unknown"; break; - case AV_FIELD_PROGRESSIVE: vp.fieldOrder = "progressive"; break; - case AV_FIELD_TT: vp.fieldOrder = "top top"; break; - case AV_FIELD_BB: vp.fieldOrder = "bottom bottom"; break; - case AV_FIELD_TB: vp.fieldOrder = "top bottom"; break; - case AV_FIELD_BT: vp.fieldOrder = "bottom top"; break; - default: break; - } -#if LIBAVUTIL_VERSION_MAJOR > 51 - const AVPixFmtDescriptor* pixFmt = av_pix_fmt_desc_get( codec_context->pix_fmt ); -#else - const AVPixFmtDescriptor* pixFmt = NULL; - if( codec_context->pix_fmt >= 0 && codec_context->pix_fmt < PIX_FMT_NB ) - pixFmt = &av_pix_fmt_descriptors[ codec_context->pix_fmt ]; -#endif - - if( pixFmt != NULL ) - { - vp.pixelName = pixFmt->name; - vp.componentsCount = pixFmt->nb_components; - vp.chromaWidth = pixFmt->log2_chroma_w; - vp.chromaHeight = pixFmt->log2_chroma_h; - vp.endianess = ( pixFmt->flags & PIX_FMT_BE ) ? "big" : "little"; - vp.indexedColors = (bool) pixFmt->flags & PIX_FMT_PAL; - vp.bitWisePacked = (bool) pixFmt->flags & PIX_FMT_BITSTREAM; - vp.hardwareAcceleration = (bool) pixFmt->flags & PIX_FMT_HWACCEL; - vp.notFirstPlane = (bool) pixFmt->flags & PIX_FMT_PLANAR; - vp.rgbPixelData = (bool) pixFmt->flags & PIX_FMT_RGB; -#if LIBAVCODEC_VERSION_MAJOR > 53 - vp.pseudoPaletted = (bool) pixFmt->flags & PIX_FMT_PSEUDOPAL; - vp.asAlpha = (bool) pixFmt->flags & PIX_FMT_ALPHA; -#else -#endif - - for( size_t channel = 0; channel < (size_t)pixFmt->nb_components; ++channel ) - { - Channel c; - c.id = channel; - c.chromaHeight = (size_t)pixFmt->comp[channel].plane; - c.bitStep = (size_t)pixFmt->comp[channel].step_minus1; - vp.channels.push_back( c ); - } - } - - AVCodec* codec = NULL; - if( ( codec = avcodec_find_decoder( codec_context->codec_id ) ) != NULL ) - { - if( codec->capabilities & CODEC_CAP_TRUNCATED ) - codec_context->flags|= CODEC_FLAG_TRUNCATED; - - vp.codecName = codec->name; - vp.codecLongName = codec->long_name; - - if( codec_context->profile != -99 ) - { - const char* profile; - if( ( profile = av_get_profile_name( codec, codec_context->profile ) ) != NULL ) - vp.profileName = profile; - } - - // std::cout << "pass here " << codec_context->width << "x" << codec_context->height<< std::endl; - - if( codec_context->width && codec_context->height )// && level != InputFile::eAnalyseLevelFast ) - { - // std::cout << "full analysis" << std::endl; - details::getGopProperties( vp, formatContext, codec_context, codec, videoStreamIndex, progress ); - } - } - - return vp; -} - -} - -#endif diff --git a/src/AvTranscoder/mediaProperty/mediaProperty.cpp b/src/AvTranscoder/mediaProperty/mediaProperty.cpp deleted file mode 100644 index 1b950179..00000000 --- a/src/AvTranscoder/mediaProperty/mediaProperty.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include "mediaProperty.hpp" - -extern "C" { -#include -} - -#include -#include - -namespace avtranscoder -{ - -namespace detail -{ - -template -void add( MetadatasMap& dataMap, const std::string& key, const T& value ) -{ - std::stringstream ss; - ss << value; - add( dataMap, key, ss.str() ); -} - -template<> -void add( MetadatasMap& dataMap, const std::string& key, const std::string& value ) -{ - dataMap.push_back( std::pair( key, value ) ); -} - -template<> -void add( MetadatasMap& dataMap, const std::string& key, const bool& value ) -{ - add( dataMap, key, value ? "True" : "False" ); -} - -void fillMetadataDictionnary( AVDictionary* avdictionnary, MetadatasMap& metadata ) -{ - AVDictionaryEntry* tag = NULL; - while( ( tag = av_dict_get( avdictionnary, "", tag, AV_DICT_IGNORE_SUFFIX ) ) ) - { - metadata.push_back( std::pair( tag->key, tag->value ) ); - } -} - -} - -MetadatasMap VideoProperties::getDataMap() const -{ - MetadatasMap dataMap; - - detail::add( dataMap, "stream id", streamId ); - detail::add( dataMap, "codec id", codecId ); - detail::add( dataMap, "codec name", codecName ); - detail::add( dataMap, "codec long name", codecLongName ); - detail::add( dataMap, "profile", profile ); - detail::add( dataMap, "profile name", profileName ); - detail::add( dataMap, "level", level ); - detail::add( dataMap, "start timecode", startTimecode ); - detail::add( dataMap, "width", width ); - detail::add( dataMap, "height", height ); - detail::add( dataMap, "pixel aspect ratio", sar.num / sar.den ); - detail::add( dataMap, "display aspect ratio", dar.num / dar.den ); - detail::add( dataMap, "dtgActiveFormat", dtgActiveFormat ); - detail::add( dataMap, "components count", componentsCount ); - detail::add( dataMap, "pixel type", pixelName ); - detail::add( dataMap, "bit wise acked", bitWisePacked ); - detail::add( dataMap, "rgb pixel", rgbPixelData ); - detail::add( dataMap, "as alpha", asAlpha ); - detail::add( dataMap, "chroma width", chromaWidth ); - detail::add( dataMap, "chroma height", chromaHeight ); - detail::add( dataMap, "endianess", endianess ); - detail::add( dataMap, "color transfert", colorTransfert ); - detail::add( dataMap, "colorspace", colorspace ); - detail::add( dataMap, "color range", colorRange ); - detail::add( dataMap, "color primaries", colorPrimaries ); - detail::add( dataMap, "indexed colors", indexedColors ); - detail::add( dataMap, "pseudo paletted", pseudoPaletted ); - detail::add( dataMap, "chroma sample location", chromaSampleLocation); - detail::add( dataMap, "interlaced ", isInterlaced ); - detail::add( dataMap, "top field first", topFieldFirst ); - detail::add( dataMap, "field order", fieldOrder); - detail::add( dataMap, "timeBase", timeBase.num / timeBase.den ); - detail::add( dataMap, "fps", fps ); - detail::add( dataMap, "ticksPerFrame", ticksPerFrame ); - detail::add( dataMap, "bit rate", bitRate ); - detail::add( dataMap, "max bit rate", maxBitRate ); - detail::add( dataMap, "min bit rate", minBitRate ); - detail::add( dataMap, "gop size", gopSize ); - - std::string gop; - for( size_t frameIndex = 0; frameIndex < gopStructure.size(); ++frameIndex ) - { - gop += gopStructure.at( frameIndex ).first; - gop += ( gopStructure.at( frameIndex ).second ? "*" : " " ); - } - detail::add( dataMap, "gop", gop ); - - detail::add( dataMap, "has B frames", hasBFrames ); - detail::add( dataMap, "references frames", referencesFrames ); - - for( size_t metadataIndex = 0; metadataIndex < metadatas.size(); ++metadataIndex ) - { - detail::add( dataMap, metadatas.at( metadataIndex ).first, metadatas.at( metadataIndex ).second ); - } - - return dataMap; -} - -MetadatasMap AudioProperties::getDataMap() const -{ - MetadatasMap dataMap; - - detail::add( dataMap, "stream id", streamId ); - detail::add( dataMap, "codec id", codecId ); - detail::add( dataMap, "codec name", codecName ); - detail::add( dataMap, "codec long name", codecLongName ); - detail::add( dataMap, "sample format name", sampleFormatName ); - detail::add( dataMap, "sample format long name", sampleFormatLongName ); - detail::add( dataMap, "sample rate", sampleRate ); - detail::add( dataMap, "bit rate", bit_rate ); - detail::add( dataMap, "channels", channels ); - detail::add( dataMap, "channel layout", channelLayout ); - detail::add( dataMap, "channel name", channelName ); - detail::add( dataMap, "channel description", channelDescription ); - - for( size_t metadataIndex = 0; metadataIndex < metadatas.size(); ++metadataIndex ) - { - detail::add( dataMap, metadatas.at( metadataIndex ).first, metadatas.at( metadataIndex ).second ); - } - - return dataMap; -} - -MetadatasMap DataProperties::getDataMap() const -{ - MetadatasMap dataMap; - - detail::add( dataMap, "streamId", streamId ); - - for( size_t metadataIndex = 0; metadataIndex < metadatas.size(); ++metadataIndex ) - { - detail::add( dataMap, metadatas.at( metadataIndex ).first, metadatas.at( metadataIndex ).second ); - } - - return dataMap; -} - -MetadatasMap SubtitleProperties::getDataMap() const -{ - MetadatasMap dataMap; - - detail::add( dataMap, "streamId", streamId ); - - for( size_t metadataIndex = 0; metadataIndex < metadatas.size(); ++metadataIndex ) - { - detail::add( dataMap, metadatas.at( metadataIndex ).first, metadatas.at( metadataIndex ).second ); - } - - return dataMap; -} - -MetadatasMap AttachementProperties::getDataMap() const -{ - MetadatasMap dataMap; - - detail::add( dataMap, "streamId", streamId ); - - for( size_t metadataIndex = 0; metadataIndex < metadatas.size(); ++metadataIndex ) - { - detail::add( dataMap, metadatas.at( metadataIndex ).first, metadatas.at( metadataIndex ).second ); - } - - return dataMap; -} - -MetadatasMap UnknownProperties::getDataMap() const -{ - MetadatasMap dataMap; - - detail::add( dataMap, "streamId", streamId ); - - for( size_t metadataIndex = 0; metadataIndex < metadatas.size(); ++metadataIndex ) - { - detail::add( dataMap, metadatas.at( metadataIndex ).first, metadatas.at( metadataIndex ).second ); - } - - return dataMap; -} - -MetadatasMap Properties::getDataMap() const -{ - MetadatasMap dataMap; - - detail::add( dataMap, "filename", filename ); - detail::add( dataMap, "format name", formatName ); - detail::add( dataMap, "format long name", formatLongName ); - - detail::add( dataMap, "start time", startTime ); - detail::add( dataMap, "duration", duration ); - detail::add( dataMap, "bitrate", bitRate ); - detail::add( dataMap, "number of streams", streamsCount ); - detail::add( dataMap, "number of programs", programsCount ); - detail::add( dataMap, "number of video streams", videoStreams.size() ); - detail::add( dataMap, "number of audio streams", audioStreams.size() ); - detail::add( dataMap, "number of data streams", dataStreams.size() ); - detail::add( dataMap, "number of subtitle streams", subtitleStreams.size() ); - detail::add( dataMap, "number of attachement streams", attachementStreams.size() ); - detail::add( dataMap, "number of unknown streams", unknownStreams.size() ); - - for( size_t metadataIndex = 0; metadataIndex < metadatas.size(); ++metadataIndex ) - { - detail::add( dataMap, metadatas.at( metadataIndex ).first, metadatas.at( metadataIndex ).second ); - } - - return dataMap; -} - -} diff --git a/src/AvTranscoder/mediaProperty/mediaProperty.hpp b/src/AvTranscoder/mediaProperty/mediaProperty.hpp deleted file mode 100644 index 89e89013..00000000 --- a/src/AvTranscoder/mediaProperty/mediaProperty.hpp +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef _AV_TRANSCODER_MEDIA_HPP_ -#define _AV_TRANSCODER_MEDIA_HPP_ - -#include - -#include -#include -#include - -namespace avtranscoder -{ - -/** - * @brief Can get all data of Properties structures by getDataMap(), which return a MetadatasMap. - */ -typedef std::vector< std::pair > MetadatasMap; - -namespace detail -{ - /** - * @brief Fill metadata parameter with the given AVDictionary. - */ - void AvExport fillMetadataDictionnary( AVDictionary* avdictionnary, MetadatasMap& metadata ); -} - -struct AvExport Channel -{ - size_t id; - size_t chromaHeight; - size_t bitStep; -}; - -struct AvExport VideoProperties -{ - VideoProperties() - { - timeBase.num = 0; - timeBase.den = 0; - sar.num = 0; - sar.den = 0; - dar.num = 0; - dar.den = 0; - } - -public: - std::string codecName; - std::string codecLongName; - std::string profileName; - std::string colorTransfert; - std::string colorspace; - std::string colorRange; - std::string colorPrimaries; - std::string chromaSampleLocation; - std::string fieldOrder; - - std::string pixelName; - std::string endianess; - - std::string startTimecode; - - Rational timeBase; - Rational sar; // sample/pixel aspect ratio - Rational dar; // display aspect ratio - - size_t streamId; - size_t codecId; - size_t bitRate; - size_t maxBitRate; - size_t minBitRate; - size_t ticksPerFrame; - size_t width; - size_t height; - size_t gopSize; - size_t dtgActiveFormat; - size_t referencesFrames; - int profile; - int level; - size_t componentsCount; - size_t chromaWidth; - size_t chromaHeight; - - double fps; - - bool hasBFrames; - bool indexedColors; - bool bitWisePacked; - bool hardwareAcceleration; - bool notFirstPlane; - bool rgbPixelData; - bool pseudoPaletted; - bool asAlpha; - bool isInterlaced; - bool topFieldFirst; - - // ( frame type / is key frame ) - std::vector< std::pair< char, bool > > gopStructure; - std::vector channels; - - MetadatasMap metadatas; - -public: - MetadatasMap getDataMap() const; -}; - -struct AvExport AudioProperties -{ - std::string codecName; - std::string codecLongName; - std::string sampleFormatName; - std::string sampleFormatLongName; - std::string channelLayout; - std::string channelName; - std::string channelDescription; - size_t streamId; - size_t codecId; - size_t sampleRate; - size_t channels; - size_t bit_rate; - - MetadatasMap metadatas; - -public: - MetadatasMap getDataMap() const; -}; - -struct AvExport DataProperties -{ - size_t streamId; - MetadatasMap metadatas; - -public: - MetadatasMap getDataMap() const; -}; - -struct AvExport SubtitleProperties -{ - size_t streamId; - MetadatasMap metadatas; - -public: - MetadatasMap getDataMap() const; -}; - -struct AvExport AttachementProperties -{ - size_t streamId; - MetadatasMap metadatas; - -public: - MetadatasMap getDataMap() const; -}; - -struct AvExport UnknownProperties -{ - size_t streamId; - MetadatasMap metadatas; - -public: - MetadatasMap getDataMap() const; -}; - -struct AvExport Properties -{ - std::string filename; - std::string formatName; - std::string formatLongName; - size_t streamsCount; - size_t programsCount; - double startTime; - double duration; - size_t bitRate; - size_t packetSize; - - std::vector< VideoProperties > videoStreams; - std::vector< AudioProperties > audioStreams; - std::vector< DataProperties > dataStreams; - std::vector< SubtitleProperties > subtitleStreams; - std::vector< AttachementProperties > attachementStreams; - std::vector< UnknownProperties > unknownStreams; - - MetadatasMap metadatas; - -public: - MetadatasMap getDataMap() const; -}; - -} - -#endif \ No newline at end of file diff --git a/src/AvTranscoder/mediaProperty/mediaProperty.i b/src/AvTranscoder/mediaProperty/mediaProperty.i new file mode 100644 index 00000000..2d6fa5fd --- /dev/null +++ b/src/AvTranscoder/mediaProperty/mediaProperty.i @@ -0,0 +1,53 @@ +%{ +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace avtranscoder; +%} + +namespace std { +// Allow vector of object with no default constructor +%ignore vector< avtranscoder::VideoProperties >::vector(size_type); +%ignore vector< avtranscoder::VideoProperties >::resize; +%ignore vector< avtranscoder::AudioProperties >::vector(size_type); +%ignore vector< avtranscoder::AudioProperties >::resize; +%ignore vector< avtranscoder::DataProperties >::vector(size_type); +%ignore vector< avtranscoder::DataProperties >::resize; +%ignore vector< avtranscoder::SubtitleProperties >::vector(size_type); +%ignore vector< avtranscoder::SubtitleProperties >::resize; +%ignore vector< avtranscoder::AttachementProperties >::vector(size_type); +%ignore vector< avtranscoder::AttachementProperties >::resize; +%ignore vector< avtranscoder::UnknownProperties >::vector(size_type); +%ignore vector< avtranscoder::UnknownProperties >::resize; + +// Create instantiations of a template classes +%template(VideoVector) vector< avtranscoder::VideoProperties >; +%template(AudioVector) vector< avtranscoder::AudioProperties >; +%template(DataVector) vector< avtranscoder::DataProperties >; +%template(SubtitleVector) vector< avtranscoder::SubtitleProperties >; +%template(AttachementVector) vector< avtranscoder::AttachementProperties >; +%template(UnknownVector) vector< avtranscoder::UnknownProperties >; + +%template(MetadataPair) pair< string, string >; +%template(MetadatasVector) vector< pair< string, string > >; + +%template(GopPair) pair< char, bool >; +%template(GopVector) vector< pair< char, bool > >; + +%template(ChannelVector) vector< avtranscoder::Channel >; +} + +%include +%include +%include +%include +%include +%include +%include +%include diff --git a/src/AvTranscoder/mediaProperty/printMediaProperty.hpp b/src/AvTranscoder/mediaProperty/print.hpp similarity index 80% rename from src/AvTranscoder/mediaProperty/printMediaProperty.hpp rename to src/AvTranscoder/mediaProperty/print.hpp index a2a69c80..92ce2561 100644 --- a/src/AvTranscoder/mediaProperty/printMediaProperty.hpp +++ b/src/AvTranscoder/mediaProperty/print.hpp @@ -14,7 +14,7 @@ namespace avtranscoder static const size_t keyWidth = 32; static const std::string separator = "===================="; -std::ostream& operator<<( std::ostream& flux, const Properties& properties ) +std::ostream& operator<<( std::ostream& flux, const FileProperties& properties ) { flux << std::left; flux << separator << " Wrapper " << separator << std::endl; @@ -114,39 +114,39 @@ std::ostream& operator<<( std::ostream& flux, const InputFile& input ) flux << input.getProperties(); // video streams - for( size_t videoStreamIndex = 0; videoStreamIndex < input.getProperties().videoStreams.size(); ++videoStreamIndex ) + for( size_t videoStreamIndex = 0; videoStreamIndex < input.getProperties().getNbVideoStreams(); ++videoStreamIndex ) { - flux << input.getProperties().videoStreams.at( videoStreamIndex ); + flux << input.getProperties().getVideoProperties().at( videoStreamIndex ); } // audio streams - for( size_t audioStreamIndex = 0; audioStreamIndex < input.getProperties().audioStreams.size(); ++audioStreamIndex ) + for( size_t audioStreamIndex = 0; audioStreamIndex < input.getProperties().getNbAudioStreams(); ++audioStreamIndex ) { - flux << input.getProperties().audioStreams.at( audioStreamIndex ); + flux << input.getProperties().getAudioProperties().at( audioStreamIndex ); } // data streams - for( size_t dataStreamIndex = 0; dataStreamIndex < input.getProperties().dataStreams.size(); ++dataStreamIndex ) + for( size_t dataStreamIndex = 0; dataStreamIndex < input.getProperties().getNbDataStreams(); ++dataStreamIndex ) { - flux << input.getProperties().dataStreams.at( dataStreamIndex ); + flux << input.getProperties().getDataProperties().at( dataStreamIndex ); } // subtitle streams - for( size_t subtitleStreamIndex = 0; subtitleStreamIndex < input.getProperties().subtitleStreams.size(); ++subtitleStreamIndex ) + for( size_t subtitleStreamIndex = 0; subtitleStreamIndex < input.getProperties().getNbSubtitleStreams(); ++subtitleStreamIndex ) { - flux << input.getProperties().subtitleStreams.at( subtitleStreamIndex ); + flux << input.getProperties().getSubtitleProperties().at( subtitleStreamIndex ); } // attachement streams - for( size_t attachementStreamIndex = 0; attachementStreamIndex < input.getProperties().attachementStreams.size(); ++attachementStreamIndex ) + for( size_t attachementStreamIndex = 0; attachementStreamIndex < input.getProperties().getNbAttachementStreams(); ++attachementStreamIndex ) { - flux << input.getProperties().attachementStreams.at( attachementStreamIndex ); + flux << input.getProperties().getAttachementProperties().at( attachementStreamIndex ); } // unknown streams - for( size_t unknownStreamIndex = 0; unknownStreamIndex < input.getProperties().unknownStreams.size(); ++unknownStreamIndex ) + for( size_t unknownStreamIndex = 0; unknownStreamIndex < input.getProperties().getNbUnknownStreams(); ++unknownStreamIndex ) { - flux << input.getProperties().unknownStreams.at( unknownStreamIndex ); + flux << input.getProperties().getUnknownPropertiesProperties().at( unknownStreamIndex ); } return flux; @@ -154,4 +154,4 @@ std::ostream& operator<<( std::ostream& flux, const InputFile& input ) } -#endif \ No newline at end of file +#endif diff --git a/src/AvTranscoder/mediaProperty/util.cpp b/src/AvTranscoder/mediaProperty/util.cpp new file mode 100644 index 00000000..6b4ab4dc --- /dev/null +++ b/src/AvTranscoder/mediaProperty/util.cpp @@ -0,0 +1,36 @@ +#include "util.hpp" + +extern "C" { +#include +} + +namespace avtranscoder +{ + +namespace detail +{ + +template<> +void add( MetadatasMap& dataMap, const std::string& key, const std::string& value ) +{ + dataMap.push_back( std::make_pair( key, value ) ); +} + +template<> +void add( MetadatasMap& dataMap, const std::string& key, const bool& value ) +{ + add( dataMap, key, value ? "True" : "False" ); +} + +void fillMetadataDictionnary( AVDictionary* avdictionnary, MetadatasMap& metadata ) +{ + AVDictionaryEntry* tag = NULL; + while( ( tag = av_dict_get( avdictionnary, "", tag, AV_DICT_IGNORE_SUFFIX ) ) ) + { + metadata.push_back( std::make_pair( tag->key, tag->value ) ); + } +} + +} + +} diff --git a/src/AvTranscoder/mediaProperty/util.hpp b/src/AvTranscoder/mediaProperty/util.hpp new file mode 100644 index 00000000..34e7e034 --- /dev/null +++ b/src/AvTranscoder/mediaProperty/util.hpp @@ -0,0 +1,45 @@ +#ifndef _AV_TRANSCODER_MEDIA_PROPERTY_UTIL_HPP_ +#define _AV_TRANSCODER_MEDIA_PROPERTY_UTIL_HPP_ + +#include + +#include +#include +#include +#include + +namespace avtranscoder +{ + +/** + * @brief Can get all data of Properties structures by getDataMap(), which return a MetadatasMap. + */ +typedef std::vector< std::pair > MetadatasMap; + +namespace detail +{ + +template +void add( MetadatasMap& dataMap, const std::string& key, const T& value ) +{ + std::stringstream ss; + ss << value; + add( dataMap, key, ss.str() ); +} + +template<> +void add( MetadatasMap& dataMap, const std::string& key, const std::string& value ); + +template<> +void add( MetadatasMap& dataMap, const std::string& key, const bool& value ); + +/** + * @brief Fill metadata parameter with the given AVDictionary. + */ +void AvExport fillMetadataDictionnary( AVDictionary* avdictionnary, MetadatasMap& metadata ); + +} + +} + +#endif diff --git a/src/AvTranscoder/option/Context.hpp b/src/AvTranscoder/option/Context.hpp index b804943c..b7e43e8d 100644 --- a/src/AvTranscoder/option/Context.hpp +++ b/src/AvTranscoder/option/Context.hpp @@ -11,6 +11,9 @@ namespace avtranscoder { +typedef std::vector