From da40efdc9dd4a7397470fbb8af2cc78a8c5bc13d Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 15:58:16 +0100 Subject: [PATCH 1/8] FormatContext: log info when seek --- src/AvTranscoder/file/FormatContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AvTranscoder/file/FormatContext.cpp b/src/AvTranscoder/file/FormatContext.cpp index 7dd22cbc..9ac0359f 100644 --- a/src/AvTranscoder/file/FormatContext.cpp +++ b/src/AvTranscoder/file/FormatContext.cpp @@ -147,6 +147,7 @@ bool FormatContext::seek( uint64_t position, const int flag ) if( (int)getStartTime() != AV_NOPTS_VALUE ) position += getStartTime(); + LOG_INFO( "Seek in '" << _avFormatContext->filename << "' at " << position << " (in AV_TIME_BASE units)" ) int err = av_seek_frame( _avFormatContext, -1, position, flag ); if( err < 0 ) { From 8e5671e00c870c0cd15535578d58f585dd58a258 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 15:59:47 +0100 Subject: [PATCH 2/8] encoders/decoders: do not log empty profile when setup --- src/AvTranscoder/decoder/AudioDecoder.cpp | 5 ++++- src/AvTranscoder/decoder/VideoDecoder.cpp | 5 ++++- src/AvTranscoder/encoder/AudioEncoder.cpp | 5 ++++- src/AvTranscoder/encoder/VideoEncoder.cpp | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index eb9432fe..346ce765 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -62,7 +62,10 @@ void AudioDecoder::setupDecoder( const ProfileLoader::Profile& profile ) throw std::runtime_error( msg ); } - LOG_INFO( "Setup audio decoder with:\n" << profile ) + if( ! profile.empty() ) + { + LOG_INFO( "Setup audio decoder with:\n" << profile ) + } AudioCodec& codec = _inputStream->getAudioCodec(); diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index 08f87271..ae54d737 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -60,7 +60,10 @@ void VideoDecoder::setupDecoder( const ProfileLoader::Profile& profile ) throw std::runtime_error( msg ); } - LOG_INFO( "Setup video decoder with:\n" << profile ) + if( ! profile.empty() ) + { + LOG_INFO( "Setup video decoder with:\n" << profile ) + } VideoCodec& codec = _inputStream->getVideoCodec(); diff --git a/src/AvTranscoder/encoder/AudioEncoder.cpp b/src/AvTranscoder/encoder/AudioEncoder.cpp index 93e68342..85941c92 100644 --- a/src/AvTranscoder/encoder/AudioEncoder.cpp +++ b/src/AvTranscoder/encoder/AudioEncoder.cpp @@ -37,7 +37,10 @@ AudioEncoder::~AudioEncoder() void AudioEncoder::setupAudioEncoder( const AudioFrameDesc& frameDesc, const ProfileLoader::Profile& profile ) { - LOG_INFO( "Setup audio encoder with:\n" << profile ) + if( ! profile.empty() ) + { + LOG_INFO( "Setup audio encoder with:\n" << profile ) + } // set sampleRate, number of channels, sample format _codec.setAudioParameters( frameDesc ); diff --git a/src/AvTranscoder/encoder/VideoEncoder.cpp b/src/AvTranscoder/encoder/VideoEncoder.cpp index cca0820e..cce274ff 100644 --- a/src/AvTranscoder/encoder/VideoEncoder.cpp +++ b/src/AvTranscoder/encoder/VideoEncoder.cpp @@ -38,7 +38,10 @@ VideoEncoder::~VideoEncoder() void VideoEncoder::setupVideoEncoder( const VideoFrameDesc& frameDesc, const ProfileLoader::Profile& profile ) { - LOG_INFO( "Setup video encoder with:\n" << profile ) + if( ! profile.empty() ) + { + LOG_INFO( "Setup video encoder with:\n" << profile ) + } // set width, height, pixel format, fps _codec.setImageParameters( frameDesc ); From 3e8472bbde1097f4a75aeaae8b10e98cd2c2c92e Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 16:00:04 +0100 Subject: [PATCH 3/8] wrap/unwrap: do not log empty profile when setup --- src/AvTranscoder/file/InputFile.cpp | 6 ++++-- src/AvTranscoder/file/OutputFile.cpp | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/AvTranscoder/file/InputFile.cpp b/src/AvTranscoder/file/InputFile.cpp index f780a090..6c945616 100644 --- a/src/AvTranscoder/file/InputFile.cpp +++ b/src/AvTranscoder/file/InputFile.cpp @@ -173,8 +173,10 @@ void InputFile::setupUnwrapping( const ProfileLoader::Profile& profile ) throw std::runtime_error( msg ); } - // set profile - LOG_INFO( "Setup unwrapping with:\n" << profile ) + if( ! profile.empty() ) + { + LOG_INFO( "Setup unwrapping with:\n" << profile ) + } for( ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it ) { diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index 156507b3..057a33f2 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -223,7 +223,10 @@ void OutputFile::setupWrapping( const ProfileLoader::Profile& profile ) throw std::runtime_error( msg ); } - LOG_INFO( "Setup wrapping with:\n" << profile ) + if( ! profile.empty() ) + { + LOG_INFO( "Setup wrapping with:\n" << profile ) + } // check if output format indicated is valid with the filename extension if( ! matchFormat( profile.find( constants::avProfileFormat )->second, getFilename() ) ) From bd4195166bed8fca3bd646d9d54ec85587622719 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 16:07:52 +0100 Subject: [PATCH 4/8] IReader: added assert to check not NULL --- src/AvTranscoder/reader/IReader.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index 8f938805..a83608b2 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -2,6 +2,8 @@ #include +#include + namespace avtranscoder { @@ -49,6 +51,11 @@ Frame* IReader::readPrevFrame() Frame* IReader::readFrameAt( const size_t frame ) { + assert( _decoder != NULL ); + assert( _transform != NULL ); + assert( _srcFrame != NULL ); + assert( _dstFrame != NULL ); + if( (int)frame != _currentFrame + 1 ) { // seek @@ -65,6 +72,7 @@ Frame* IReader::readFrameAt( const size_t frame ) void IReader::printInfo() { + assert( _streamProperties != NULL ); std::cout << *_streamProperties << std::endl; } From 9b78c0e292e666da82af41ae9f0eb76676193c30 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 16:10:15 +0100 Subject: [PATCH 5/8] FormatContext: do not add stream start time before each seek --- src/AvTranscoder/file/FormatContext.cpp | 5 +---- src/AvTranscoder/file/FormatContext.hpp | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/AvTranscoder/file/FormatContext.cpp b/src/AvTranscoder/file/FormatContext.cpp index 9ac0359f..1306347e 100644 --- a/src/AvTranscoder/file/FormatContext.cpp +++ b/src/AvTranscoder/file/FormatContext.cpp @@ -142,11 +142,8 @@ AVStream& FormatContext::addAVStream( const AVCodec& avCodec ) return *stream; } -bool FormatContext::seek( uint64_t position, const int flag ) +bool FormatContext::seek( const uint64_t position, const int flag ) { - if( (int)getStartTime() != AV_NOPTS_VALUE ) - position += getStartTime(); - LOG_INFO( "Seek in '" << _avFormatContext->filename << "' at " << position << " (in AV_TIME_BASE units)" ) int err = av_seek_frame( _avFormatContext, -1, position, flag ); if( err < 0 ) diff --git a/src/AvTranscoder/file/FormatContext.hpp b/src/AvTranscoder/file/FormatContext.hpp index b446d8a9..7c080531 100644 --- a/src/AvTranscoder/file/FormatContext.hpp +++ b/src/AvTranscoder/file/FormatContext.hpp @@ -77,10 +77,10 @@ class AvExport FormatContext * @brief Seek at a specific position * @param position: can be in AV_TIME_BASE units, in frames... depending on the flag value * @param flag: seeking mode (AVSEEK_FLAG_xxx) - * @note before seek, add offset of start time * @return seek status + * @see flushDecoder */ - bool seek( uint64_t position, const int flag ); + bool seek( const uint64_t position, const int flag ); size_t getNbStreams() const { return _avFormatContext->nb_streams; } /// Get duration of the program, in seconds From 384841b3541c784d87c7b2cd610e412af851b10b Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 18:43:02 +0100 Subject: [PATCH 6/8] pyTest offset: check output nbSamples/nbFrames when rewrap --- test/pyTest/testOffset.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/pyTest/testOffset.py b/test/pyTest/testOffset.py index 3b611a60..7218c915 100644 --- a/test/pyTest/testOffset.py +++ b/test/pyTest/testOffset.py @@ -102,6 +102,7 @@ def testRewrapAudioPositiveOffset(): # check output duration assert_equals( src_audioStream.getDuration() + offset, dst_audioStream.getDuration() ) + assert_equals( src_audioStream.getNbSamples() + ( offset * dst_audioStream.getSampleRate() * dst_audioStream.getChannels() ), dst_audioStream.getNbSamples() ) def testRewrapAudioNegativeOffset(): @@ -132,6 +133,7 @@ def testRewrapAudioNegativeOffset(): # check output duration assert_almost_equals( src_audioStream.getDuration() + offset, dst_audioStream.getDuration(), delta=0.01 ) + assert_equals( src_audioStream.getNbSamples() + ( offset * dst_audioStream.getSampleRate() * dst_audioStream.getChannels() ), dst_audioStream.getNbSamples() ) def testTranscodeVideoPositiveOffset(): @@ -222,6 +224,7 @@ def testRewrapVideoPositiveOffset(): # check output duration assert_equals( src_videoStream.getDuration() + offset, dst_videoStream.getDuration() ) + assert_equals( src_videoStream.getNbFrames() + ( offset * dst_videoStream.getFps() ), dst_videoStream.getNbFrames() ) def testRewrapVideoNegativeOffset(): @@ -252,6 +255,7 @@ def testRewrapVideoNegativeOffset(): # check output duration assert_equals( src_videoStream.getDuration() + offset, dst_videoStream.getDuration() ) + assert_equals( src_videoStream.getNbFrames() + ( offset * dst_videoStream.getFps() ), dst_videoStream.getNbFrames() ) def testMultipleOffsetFromSameInputFile(): From e4aa404c3ac18463006320b5e79fdc9f2aba39c9 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 18:43:53 +0100 Subject: [PATCH 7/8] pyTest offset: check duration of all stream when testMultipleOffsetFromSameInputFile --- test/pyTest/testOffset.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/pyTest/testOffset.py b/test/pyTest/testOffset.py index 7218c915..4fd7fffc 100644 --- a/test/pyTest/testOffset.py +++ b/test/pyTest/testOffset.py @@ -280,12 +280,15 @@ def testMultipleOffsetFromSameInputFile(): src_inputFile = av.InputFile( inputFileName ) src_properties = src_inputFile.getProperties() src_videoStream = src_properties.getVideoProperties()[0] + src_audioStream = src_properties.getAudioProperties()[0] # get dst file dst_inputFile = av.InputFile( outputFileName ) dst_properties = dst_inputFile.getProperties() dst_videoStream = dst_properties.getVideoProperties()[0] + dst_audioStream = dst_properties.getAudioProperties()[0] # check output duration assert_equals( src_videoStream.getDuration() + offset_1, dst_videoStream.getDuration() ) + assert_equals( src_audioStream.getDuration() + offset_1, dst_audioStream.getDuration() ) From 6331f3c7f50e8ed2c97afa059d9382b7e7aa6b8c Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 18:55:45 +0100 Subject: [PATCH 8/8] pyTest offset: add testMultipleOffsetFromSameStream --- test/pyTest/testOffset.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/pyTest/testOffset.py b/test/pyTest/testOffset.py index 4fd7fffc..fec33dc7 100644 --- a/test/pyTest/testOffset.py +++ b/test/pyTest/testOffset.py @@ -292,3 +292,39 @@ def testMultipleOffsetFromSameInputFile(): assert_equals( src_videoStream.getDuration() + offset_1, dst_videoStream.getDuration() ) assert_equals( src_audioStream.getDuration() + offset_1, dst_audioStream.getDuration() ) + +def testMultipleOffsetFromSameStream(): + """ + Process same stream several times with different offset at the beginning of the process. + """ + inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_MOV_FILE'] + outputFileName = "testMultipleOffsetFromSameStream.mov" + offset_1 = 2 + offset_2 = -2 + + ouputFile = av.OutputFile( outputFileName ) + transcoder = av.Transcoder( ouputFile ) + + transcoder.add( inputFileName, 0, "", offset_1 ) + transcoder.add( inputFileName, 0, "", offset_2 ) + + progress = av.ConsoleProgress() + transcoder.process( progress ) + + # get src file + src_inputFile = av.InputFile( inputFileName ) + src_properties = src_inputFile.getProperties() + src_videoStream = src_properties.getVideoProperties()[0] + + # get dst file + dst_inputFile = av.InputFile( outputFileName ) + dst_properties = dst_inputFile.getProperties() + dst_videoStream_1 = dst_properties.getVideoProperties()[0] + dst_videoStream_2 = dst_properties.getVideoProperties()[1] + + # check output duration + assert_equals( src_videoStream.getDuration() + offset_1, dst_videoStream_1.getDuration() ) + assert_equals( src_videoStream.getDuration() + offset_1, dst_videoStream_2.getDuration() ) + assert_almost_equals( src_videoStream.getNbFrames() + ( offset_1 * dst_videoStream_1.getFps() ), dst_videoStream_1.getNbFrames(), delta=0.01 ) + assert_almost_equals( src_videoStream.getNbFrames() + ( offset_1 * dst_videoStream_2.getFps() ), dst_videoStream_2.getNbFrames(), delta=0.01 ) +