From 1ec2e0e408f9e3735d64894e2710f81a3b983bd0 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 22 Dec 2015 11:33:39 +0100 Subject: [PATCH 01/11] pyTest: removed calls to analyse headers in testTranscoderRewrap According to the documentation, the InputFile constructor already analyses the header of the given file. --- test/pyTest/testTranscoderRewrap.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/pyTest/testTranscoderRewrap.py b/test/pyTest/testTranscoderRewrap.py index 732c1852..a2da7cba 100644 --- a/test/pyTest/testTranscoderRewrap.py +++ b/test/pyTest/testTranscoderRewrap.py @@ -53,8 +53,6 @@ def testRewrapAudioStream(): # get src file of wrap inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_WAVE_FILE'] src_inputFile = av.InputFile( inputFileName ) - progress = av.NoDisplayProgress() - src_inputFile.analyse( progress ) src_properties = src_inputFile.getProperties() src_audioStream = src_properties.getAudioProperties()[0] @@ -64,11 +62,11 @@ def testRewrapAudioStream(): transcoder = av.Transcoder( ouputFile ) transcoder.add( inputFileName, 0 ) + progress = av.NoDisplayProgress() transcoder.process( progress ) # get dst file of wrap dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelHeader ) dst_properties = dst_inputFile.getProperties() dst_audioStream = dst_properties.getAudioProperties()[0] @@ -86,8 +84,6 @@ def testRewrapAVIVideoStream(): # get src file of wrap inputFileName = os.environ['AVTRANSCODER_TEST_VIDEO_AVI_FILE'] src_inputFile = av.InputFile( inputFileName ) - progress = av.NoDisplayProgress() - src_inputFile.analyse( progress ) src_properties = src_inputFile.getProperties() src_videoStream = src_properties.getVideoProperties()[0] @@ -97,11 +93,11 @@ def testRewrapAVIVideoStream(): transcoder = av.Transcoder( ouputFile ) transcoder.add( inputFileName, 0 ) + progress = av.NoDisplayProgress() transcoder.process( progress ) # get dst file of wrap dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress ) dst_properties = dst_inputFile.getProperties() dst_videoStream = dst_properties.getVideoProperties()[0] @@ -119,8 +115,6 @@ def testRewrapMOVVideoStream(): # get src file of wrap inputFileName = os.environ['AVTRANSCODER_TEST_VIDEO_MOV_FILE'] src_inputFile = av.InputFile( inputFileName ) - progress = av.NoDisplayProgress() - src_inputFile.analyse( progress ) src_properties = src_inputFile.getProperties() src_videoStream = src_properties.getVideoProperties()[0] @@ -130,11 +124,11 @@ def testRewrapMOVVideoStream(): transcoder = av.Transcoder( ouputFile ) transcoder.add( inputFileName, 1 ) + progress = av.NoDisplayProgress() transcoder.process( progress ) # get dst file of wrap dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress ) dst_properties = dst_inputFile.getProperties() dst_videoStream = dst_properties.getVideoProperties()[0] From e79eefa4d7afd75205453aad50538b6dc23ea92d Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 22 Dec 2015 12:03:38 +0100 Subject: [PATCH 02/11] Video/AudioStat: added getters/setters to attributes To keep the same API in bindings (if there is no getter, SWIG automatically generates methods to access the attributes.) --- src/AvTranscoder/stat/AudioStat.hpp | 4 ++++ src/AvTranscoder/stat/VideoStat.cpp | 4 ++-- src/AvTranscoder/stat/VideoStat.hpp | 13 +++++++++++-- src/AvTranscoder/transcoder/Transcoder.cpp | 6 +++--- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/AvTranscoder/stat/AudioStat.hpp b/src/AvTranscoder/stat/AudioStat.hpp index 70d43afa..6968c142 100644 --- a/src/AvTranscoder/stat/AudioStat.hpp +++ b/src/AvTranscoder/stat/AudioStat.hpp @@ -19,6 +19,10 @@ class AvExport AudioStat } public: + float getDuration() const { return _duration; } + size_t getNbPackets() const { return _nbPackets; } + +private: float _duration; size_t _nbPackets; }; diff --git a/src/AvTranscoder/stat/VideoStat.cpp b/src/AvTranscoder/stat/VideoStat.cpp index 7454962e..86f09982 100644 --- a/src/AvTranscoder/stat/VideoStat.cpp +++ b/src/AvTranscoder/stat/VideoStat.cpp @@ -5,8 +5,8 @@ namespace avtranscoder { -double VideoStat::psnr(const double d) +double VideoStat::toPSNR(const double mse) { - return -10.0 * log10(d); + return -10.0 * log10(mse); } } diff --git a/src/AvTranscoder/stat/VideoStat.hpp b/src/AvTranscoder/stat/VideoStat.hpp index cab9fb90..3c9b248d 100644 --- a/src/AvTranscoder/stat/VideoStat.hpp +++ b/src/AvTranscoder/stat/VideoStat.hpp @@ -21,9 +21,18 @@ class AvExport VideoStat } public: - static double psnr(const double d); + float getDuration() const { return _duration; } + size_t getNbFrames() const { return _nbFrames; } + size_t getQuality() const { return _quality; } + double getPSNR() const { return _psnr; } -public: + void setQuality(const size_t quality) { _quality = quality; } + void setPSNR(const double mse) { _psnr = VideoStat::toPSNR(mse); } + +private: + static double toPSNR(const double mse); + +private: float _duration; size_t _nbFrames; size_t _quality; ///< Between 1 (good) and FF_LAMBDA_MAX (bad). 0 if unknown. diff --git a/src/AvTranscoder/transcoder/Transcoder.cpp b/src/AvTranscoder/transcoder/Transcoder.cpp index 24855a1d..db698f7b 100644 --- a/src/AvTranscoder/transcoder/Transcoder.cpp +++ b/src/AvTranscoder/transcoder/Transcoder.cpp @@ -580,9 +580,9 @@ void Transcoder::fillProcessStat(ProcessStat& processStat) const AVCodecContext& encoderContext = encoder->getCodec().getAVCodecContext(); if(encoderContext.coded_frame && (encoderContext.flags & CODEC_FLAG_PSNR)) { - videoStat._quality = encoderContext.coded_frame->quality; - videoStat._psnr = VideoStat::psnr(encoderContext.coded_frame->error[0] / - (encoderContext.width * encoderContext.height * 255.0 * 255.0)); + videoStat.setQuality(encoderContext.coded_frame->quality); + videoStat.setPSNR(encoderContext.coded_frame->error[0] / + (encoderContext.width * encoderContext.height * 255.0 * 255.0)); } } processStat.addVideoStat(streamIndex, videoStat); From 725cb4bec588ea3a88be904121958728e1ede574 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 22 Dec 2015 12:05:25 +0100 Subject: [PATCH 03/11] SWIG: fixed access to stat classes in bindings Need to declare Video/AudioStat before ProcessStat, to enable SWIG to know the type of the objects manipulated by ProcessStat. --- src/AvTranscoder/stat/stat.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/stat/stat.i b/src/AvTranscoder/stat/stat.i index 96927a68..57fa121a 100644 --- a/src/AvTranscoder/stat/stat.i +++ b/src/AvTranscoder/stat/stat.i @@ -1,9 +1,9 @@ %{ -#include #include #include +#include %} -%include %include %include +%include From 6b4b55851686d5a8124f1cc6fe4a3d93ebae8fd1 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 22 Dec 2015 12:14:30 +0100 Subject: [PATCH 04/11] pyTest: updated rewrap tests by checking process stats returned --- test/pyTest/testTranscoderRewrap.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/test/pyTest/testTranscoderRewrap.py b/test/pyTest/testTranscoderRewrap.py index a2da7cba..c16c54ad 100644 --- a/test/pyTest/testTranscoderRewrap.py +++ b/test/pyTest/testTranscoderRewrap.py @@ -45,6 +45,13 @@ def checkStream(src_stream, dst_stream): continue assert_equals( src_propertiesMap[key], dst_propertiesMap[key] ) +def checkVideoStat(src_videoStream, dst_videoStat): + """ + Check the values of the video process stats returned after a process. + """ + assert_equals(src_videoStream.getDuration(), dst_videoStat.getDuration()) + assert_equals(int(src_videoStream.getDuration() * src_videoStream.getFps()), dst_videoStat.getNbFrames()) + def testRewrapAudioStream(): """ @@ -63,7 +70,11 @@ def testRewrapAudioStream(): transcoder = av.Transcoder( ouputFile ) transcoder.add( inputFileName, 0 ) progress = av.NoDisplayProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + audioStat = processStat.getAudioStat(0) + assert_equals(src_audioStream.getDuration(), audioStat.getDuration()) # get dst file of wrap dst_inputFile = av.InputFile( outputFileName ) @@ -94,7 +105,10 @@ def testRewrapAVIVideoStream(): transcoder = av.Transcoder( ouputFile ) transcoder.add( inputFileName, 0 ) progress = av.NoDisplayProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + checkVideoStat(src_videoStream, processStat.getVideoStat(0)) # get dst file of wrap dst_inputFile = av.InputFile( outputFileName ) @@ -125,7 +139,10 @@ def testRewrapMOVVideoStream(): transcoder = av.Transcoder( ouputFile ) transcoder.add( inputFileName, 1 ) progress = av.NoDisplayProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + checkVideoStat(src_videoStream, processStat.getVideoStat(0)) # get dst file of wrap dst_inputFile = av.InputFile( outputFileName ) From 77f311ea5749cd84ca948964408d369134369041 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 22 Dec 2015 14:56:59 +0100 Subject: [PATCH 05/11] InputFile: fixed filled of properties when create a new InputFile * Need to find stream info before get them as properties. * Need to have FileProperties attribute as pointer, because we want to create it only once (after _formatContext.findStreamInfo()). --- src/AvTranscoder/file/InputFile.cpp | 13 +++++++++---- src/AvTranscoder/file/InputFile.hpp | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/AvTranscoder/file/InputFile.cpp b/src/AvTranscoder/file/InputFile.cpp index 0bf12a8c..156fc565 100644 --- a/src/AvTranscoder/file/InputFile.cpp +++ b/src/AvTranscoder/file/InputFile.cpp @@ -22,12 +22,16 @@ namespace avtranscoder InputFile::InputFile(const std::string& filename) : _formatContext(filename, AV_OPT_FLAG_DECODING_PARAM) - , _properties(_formatContext) + , _properties(NULL) , _filename(filename) , _inputStreams() { + // Fill the FormatContext with the stream information _formatContext.findStreamInfo(); + // Get the stream information as properties + _properties = new FileProperties(_formatContext); + // Create streams for(size_t streamIndex = 0; streamIndex < _formatContext.getNbStreams(); ++streamIndex) { @@ -37,6 +41,7 @@ InputFile::InputFile(const std::string& filename) InputFile::~InputFile() { + delete _properties; for(std::vector::iterator it = _inputStreams.begin(); it != _inputStreams.end(); ++it) { delete(*it); @@ -45,7 +50,7 @@ InputFile::~InputFile() void InputFile::analyse(IProgress& progress, const EAnalyseLevel level) { - _properties.extractStreamProperties(progress, level); + _properties->extractStreamProperties(progress, level); } FileProperties InputFile::analyseFile(const std::string& filename, IProgress& progress, const EAnalyseLevel level) @@ -160,8 +165,8 @@ std::string InputFile::getFormatMimeType() const double InputFile::getFps() { double fps = 1; - if(_properties.getNbVideoStreams()) - fps = _properties.getVideoProperties().at(0).getFps(); + if(_properties->getNbVideoStreams()) + fps = _properties->getVideoProperties().at(0).getFps(); return fps; } diff --git a/src/AvTranscoder/file/InputFile.hpp b/src/AvTranscoder/file/InputFile.hpp index 9c9f3f67..97846ef4 100644 --- a/src/AvTranscoder/file/InputFile.hpp +++ b/src/AvTranscoder/file/InputFile.hpp @@ -68,7 +68,7 @@ class AvExport InputFile * @note require to launch analyse() before to fill the property struture * @return structure of media metadatas **/ - const FileProperties& getProperties() const { return _properties; } + const FileProperties& getProperties() const { return *_properties; } /** * @brief Get stream type: video, audio, subtitle, etc. @@ -121,7 +121,7 @@ class AvExport InputFile protected: FormatContext _formatContext; - FileProperties _properties; + FileProperties* _properties; std::string _filename; std::vector _inputStreams; ///< Has ownership }; From 0dd7e4954e301863fbd5b53b1ab8d76036f60800 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 22 Dec 2015 14:57:25 +0100 Subject: [PATCH 06/11] pyTest: updated transcode tests by checking process stats returned --- .../pyTest/testTranscoderTranscodeAudioMov.py | 10 ++-- .../testTranscoderTranscodeAudioWave.py | 48 ++++++++++++----- test/pyTest/testTranscoderTranscodeVideo.py | 52 ++++++++++++++----- 3 files changed, 83 insertions(+), 27 deletions(-) diff --git a/test/pyTest/testTranscoderTranscodeAudioMov.py b/test/pyTest/testTranscoderTranscodeAudioMov.py index d32ff05c..993f725f 100644 --- a/test/pyTest/testTranscoderTranscodeAudioMov.py +++ b/test/pyTest/testTranscoderTranscodeAudioMov.py @@ -30,11 +30,16 @@ def testTranscodeMovVariableNbSamplesPerFrame(): customProfile[av.avProfileCodec] = "pcm_s24le" inputFile = av.InputFile( inputFileName ) - audioStreamIndex = inputFile.getProperties().getAudioProperties()[0].getStreamIndex() + src_audioStream = inputFile.getProperties().getAudioProperties()[0] + audioStreamIndex = src_audioStream.getStreamIndex() transcoder.add( inputFileName, audioStreamIndex, customProfile ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + audioStat = processStat.getAudioStat(0) + assert_equals(src_audioStream.getDuration(), audioStat.getDuration()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) @@ -44,4 +49,3 @@ def testTranscodeMovVariableNbSamplesPerFrame(): assert_equals( "pcm_s24le", dst_audioStream.getCodecName() ) assert_equals( "PCM signed 24-bit little-endian", dst_audioStream.getCodecLongName() ) - diff --git a/test/pyTest/testTranscoderTranscodeAudioWave.py b/test/pyTest/testTranscoderTranscodeAudioWave.py index e268e9f6..2a189af4 100644 --- a/test/pyTest/testTranscoderTranscodeAudioWave.py +++ b/test/pyTest/testTranscoderTranscodeAudioWave.py @@ -20,14 +20,20 @@ def testTranscodeWave24b48k5_1(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "wave24b48k5_1" ) + inputFile = av.InputFile( inputFileName ) + src_audioStream = inputFile.getProperties().getAudioProperties()[0] + audioStreamIndex = src_audioStream.getStreamIndex() + transcoder.add( inputFileName, audioStreamIndex, "wave24b48k5_1" ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + audioStat = processStat.getAudioStat(0) + assert_equals(src_audioStream.getDuration(), audioStat.getDuration()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelHeader ) dst_properties = dst_inputFile.getProperties() dst_audioStream = dst_properties.getAudioProperties()[0] @@ -48,14 +54,20 @@ def testTranscodeWave24b48kstereo(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "wave24b48kstereo" ) + inputFile = av.InputFile( inputFileName ) + src_audioStream = inputFile.getProperties().getAudioProperties()[0] + audioStreamIndex = src_audioStream.getStreamIndex() + transcoder.add( inputFileName, audioStreamIndex, "wave24b48kstereo" ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + audioStat = processStat.getAudioStat(0) + assert_equals(src_audioStream.getDuration(), audioStat.getDuration()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelHeader ) dst_properties = dst_inputFile.getProperties() dst_audioStream = dst_properties.getAudioProperties()[0] @@ -76,14 +88,20 @@ def testTranscodeWave24b48kmono(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "wave24b48kmono" ) + inputFile = av.InputFile( inputFileName ) + src_audioStream = inputFile.getProperties().getAudioProperties()[0] + audioStreamIndex = src_audioStream.getStreamIndex() + transcoder.add( inputFileName, audioStreamIndex, "wave24b48kmono" ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + audioStat = processStat.getAudioStat(0) + assert_equals(src_audioStream.getDuration(), audioStat.getDuration()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelHeader ) dst_properties = dst_inputFile.getProperties() dst_audioStream = dst_properties.getAudioProperties()[0] @@ -104,14 +122,20 @@ def testTranscodeWave16b48kmono(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "wave16b48kmono" ) + inputFile = av.InputFile( inputFileName ) + src_audioStream = inputFile.getProperties().getAudioProperties()[0] + audioStreamIndex = src_audioStream.getStreamIndex() + transcoder.add( inputFileName, audioStreamIndex, "wave16b48kmono" ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + audioStat = processStat.getAudioStat(0) + assert_equals(src_audioStream.getDuration(), audioStat.getDuration()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelHeader ) dst_properties = dst_inputFile.getProperties() dst_audioStream = dst_properties.getAudioProperties()[0] diff --git a/test/pyTest/testTranscoderTranscodeVideo.py b/test/pyTest/testTranscoderTranscodeVideo.py index cae40fc3..9b77dc59 100644 --- a/test/pyTest/testTranscoderTranscodeVideo.py +++ b/test/pyTest/testTranscoderTranscodeVideo.py @@ -20,14 +20,21 @@ def testTranscodeDnxhd120(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "dnxhd120" ) + inputFile = av.InputFile( inputFileName ) + src_videoStream = inputFile.getProperties().getVideoProperties()[0] + videoStreamIndex = src_videoStream.getStreamIndex() + transcoder.add( inputFileName, videoStreamIndex, "dnxhd120" ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + videoStat = processStat.getVideoStat(0) + # do not test duration because the profile "dnxhd120" forces the fps to 25 + assert_equals(int(src_videoStream.getDuration() * src_videoStream.getFps()), videoStat.getNbFrames()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelFirstGop ) dst_properties = dst_inputFile.getProperties() dst_videoStream = dst_properties.getVideoProperties()[0] @@ -49,14 +56,21 @@ def testTranscodeDnxhd185(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "dnxhd185" ) + inputFile = av.InputFile( inputFileName ) + src_videoStream = inputFile.getProperties().getVideoProperties()[0] + videoStreamIndex = src_videoStream.getStreamIndex() + transcoder.add( inputFileName, videoStreamIndex, "dnxhd185" ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + videoStat = processStat.getVideoStat(0) + # do not test duration because the profile "dnxhd185" forces the fps to 25 + assert_equals(int(src_videoStream.getDuration() * src_videoStream.getFps()), videoStat.getNbFrames()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelHeader ) dst_properties = dst_inputFile.getProperties() dst_videoStream = dst_properties.getVideoProperties()[0] @@ -78,14 +92,21 @@ def testTranscodeDnxhd185x(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "dnxhd185x" ) + inputFile = av.InputFile( inputFileName ) + src_videoStream = inputFile.getProperties().getVideoProperties()[0] + videoStreamIndex = src_videoStream.getStreamIndex() + transcoder.add( inputFileName, videoStreamIndex, "dnxhd185x" ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + videoStat = processStat.getVideoStat(0) + # do not test duration because the profile "dnxhd185x" forces the fps to 25 + assert_equals(int(src_videoStream.getDuration() * src_videoStream.getFps()), videoStat.getNbFrames()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelHeader ) dst_properties = dst_inputFile.getProperties() dst_videoStream = dst_properties.getVideoProperties()[0] @@ -115,14 +136,21 @@ def testTranscodeYUV420(): customProfile[av.avProfileCodec] = "mpeg2video" customProfile[av.avProfilePixelFormat] = "yuv420p" - transcoder.add( inputFileName, 0, customProfile ) + inputFile = av.InputFile( inputFileName ) + src_videoStream = inputFile.getProperties().getVideoProperties()[0] + videoStreamIndex = src_videoStream.getStreamIndex() + transcoder.add( inputFileName, videoStreamIndex, customProfile ) progress = av.ConsoleProgress() - transcoder.process( progress ) + processStat = transcoder.process( progress ) + + # check process stat returned + videoStat = processStat.getVideoStat(0) + assert_equals(src_videoStream.getDuration(), videoStat.getDuration()) + assert_equals(int(src_videoStream.getDuration() * src_videoStream.getFps()), videoStat.getNbFrames()) # get dst file of transcode dst_inputFile = av.InputFile( outputFileName ) - dst_inputFile.analyse( progress, av.eAnalyseLevelHeader ) dst_properties = dst_inputFile.getProperties() dst_videoStream = dst_properties.getVideoProperties()[0] From 1b4510ce5b106c0ffcd8d609d1a1f6b019a42774 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 22 Dec 2015 15:45:59 +0100 Subject: [PATCH 07/11] pyTest: added a test to check a process with the statistics activated --- test/pyTest/testProcessStat.py | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/pyTest/testProcessStat.py diff --git a/test/pyTest/testProcessStat.py b/test/pyTest/testProcessStat.py new file mode 100644 index 00000000..29831469 --- /dev/null +++ b/test/pyTest/testProcessStat.py @@ -0,0 +1,46 @@ +import os + +# Check if environment is setup to run the tests +if os.environ.get('AVTRANSCODER_TEST_VIDEO_AVI_FILE') is None: + from nose.plugins.skip import SkipTest + raise SkipTest("Need to define environment variables " + "AVTRANSCODER_TEST_VIDEO_AVI_FILE") + +from nose.tools import * + +from pyAvTranscoder import avtranscoder as av + + +def testProcessWithStatistics(): + """ + Process one video stream with a custom profile of encoding to activate statistics. + """ + inputFileName = os.environ['AVTRANSCODER_TEST_VIDEO_AVI_FILE'] + outputFileName = "testProcessWithStatistics.mov" + + ouputFile = av.OutputFile( outputFileName ) + transcoder = av.Transcoder( ouputFile ) + + # create custom profile + customProfile = av.ProfileMap() + customProfile[av.avProfileIdentificator] = "customProfile" + customProfile[av.avProfileIdentificatorHuman] = "custom profile" + customProfile[av.avProfileType] = av.avProfileTypeVideo + customProfile[av.avProfileCodec] = "mpeg2video" + customProfile[av.avProfileProcessStat] = "processStat" + + src_inputFile = av.InputFile( inputFileName ) + src_properties = src_inputFile.getProperties() + src_videoStream = src_properties.getVideoProperties()[0] + videoStreamIndex = src_videoStream.getStreamIndex() + transcoder.add( inputFileName, videoStreamIndex, customProfile ) + + progress = av.ConsoleProgress() + processStat = transcoder.process( progress ) + + # check process stat returned + videoStat = processStat.getVideoStat(0) + assert_equals(videoStat.getDuration(), src_videoStream.getDuration()) + assert_equals(videoStat.getNbFrames(), int(src_videoStream.getDuration() * src_videoStream.getFps())) + assert_not_equals(videoStat.getQuality(), 0) + assert_not_equals(videoStat.getPSNR(), 0) From 96cd13815b356db938886e614f584052cb01389f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 22 Dec 2015 15:47:51 +0100 Subject: [PATCH 08/11] pyTest: updated check of video stat in case of rewrap --- test/pyTest/testTranscoderRewrap.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/pyTest/testTranscoderRewrap.py b/test/pyTest/testTranscoderRewrap.py index c16c54ad..62833957 100644 --- a/test/pyTest/testTranscoderRewrap.py +++ b/test/pyTest/testTranscoderRewrap.py @@ -48,9 +48,12 @@ def checkStream(src_stream, dst_stream): def checkVideoStat(src_videoStream, dst_videoStat): """ Check the values of the video process stats returned after a process. + @note Because the process does not include a profile with "processStat", output quality and PSNR are not set. """ - assert_equals(src_videoStream.getDuration(), dst_videoStat.getDuration()) - assert_equals(int(src_videoStream.getDuration() * src_videoStream.getFps()), dst_videoStat.getNbFrames()) + assert_equals(dst_videoStat.getDuration(), src_videoStream.getDuration()) + assert_equals(dst_videoStat.getNbFrames(), int(src_videoStream.getDuration() * src_videoStream.getFps())) + assert_equals(dst_videoStat.getQuality(), 0) + assert_equals(dst_videoStat.getPSNR(), 0) def testRewrapAudioStream(): From 6e76869c482a5ee87211d0d9702f5ea2b029608d Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 5 Jan 2016 15:16:54 +0100 Subject: [PATCH 09/11] Appveyor: up ffmpeg version to v2.4.5 --- INSTALL.md | 2 +- tools/appveyor/build.bat | 2 +- tools/appveyor/python.nosetests.bat | 2 +- tools/appveyor/win.install.deps.bat | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index fb1537f8..acb110e8 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -4,7 +4,7 @@ AvTranscoder uses CMake as build system. #### Dependencies AvTranscoder can depend on ffmpeg, libav, or any fork of these projects that follow the same API. -* Recommended ffmpeg versions: 2.2.11, 2.4.2, 2.5.7 +* Recommended ffmpeg versions: 2.4.2, 2.4.5, 2.5.7 * Recommended libav versions: 11.3 #### To build diff --git a/tools/appveyor/build.bat b/tools/appveyor/build.bat index 5d930198..95bdfbbe 100755 --- a/tools/appveyor/build.bat +++ b/tools/appveyor/build.bat @@ -1,6 +1,6 @@ @echo on -set FFMPEG_VERSION=2.2.11 +set FFMPEG_VERSION=2.4.5 MKDIR build cd build diff --git a/tools/appveyor/python.nosetests.bat b/tools/appveyor/python.nosetests.bat index 4eb1bdb5..badaee09 100755 --- a/tools/appveyor/python.nosetests.bat +++ b/tools/appveyor/python.nosetests.bat @@ -1,7 +1,7 @@ @echo on set PWD=C:\projects\avtranscoder -set FFMPEG_VERSION=2.2.11 +set FFMPEG_VERSION=2.4.5 :: Get avtranscoder library set PYTHONPATH=%PWD%\build\lib\python2.7\site-packages;%PYTHONPATH% diff --git a/tools/appveyor/win.install.deps.bat b/tools/appveyor/win.install.deps.bat index 7368d4f1..5cfeeac2 100755 --- a/tools/appveyor/win.install.deps.bat +++ b/tools/appveyor/win.install.deps.bat @@ -1,6 +1,6 @@ @echo on -set FFMPEG_VERSION=2.2.11 +set FFMPEG_VERSION=2.4.5 if %platform% == x86 set PLATFORM_VERSION=32 if %platform% == X64 set PLATFORM_VERSION=64 From e074ab9232b62b7424abff9cd1829a642c545108 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 5 Jan 2016 17:11:50 +0100 Subject: [PATCH 10/11] Appveyor: set FFMPEG_VERSION only once --- appveyor.yml | 3 +++ tools/appveyor/build.bat | 2 -- tools/appveyor/python.nosetests.bat | 1 - tools/appveyor/win.install.deps.bat | 2 -- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index dbb44d5d..14eb8413 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,9 @@ platform: - x86 # - x64 +environment: + FFMPEG_VERSION: 2.4.5 + matrix: fast_finish: true diff --git a/tools/appveyor/build.bat b/tools/appveyor/build.bat index 95bdfbbe..de875805 100755 --- a/tools/appveyor/build.bat +++ b/tools/appveyor/build.bat @@ -1,7 +1,5 @@ @echo on -set FFMPEG_VERSION=2.4.5 - MKDIR build cd build diff --git a/tools/appveyor/python.nosetests.bat b/tools/appveyor/python.nosetests.bat index badaee09..ac5ad016 100755 --- a/tools/appveyor/python.nosetests.bat +++ b/tools/appveyor/python.nosetests.bat @@ -1,7 +1,6 @@ @echo on set PWD=C:\projects\avtranscoder -set FFMPEG_VERSION=2.4.5 :: Get avtranscoder library set PYTHONPATH=%PWD%\build\lib\python2.7\site-packages;%PYTHONPATH% diff --git a/tools/appveyor/win.install.deps.bat b/tools/appveyor/win.install.deps.bat index 5cfeeac2..7f399154 100755 --- a/tools/appveyor/win.install.deps.bat +++ b/tools/appveyor/win.install.deps.bat @@ -1,7 +1,5 @@ @echo on -set FFMPEG_VERSION=2.4.5 - if %platform% == x86 set PLATFORM_VERSION=32 if %platform% == X64 set PLATFORM_VERSION=64 From c488619c677c98858a81d24d0adf91aedd03a998 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 5 Jan 2016 17:15:52 +0100 Subject: [PATCH 11/11] pyTest: added tests to check InputFile methods --- test/pyTest/testInputFile.py | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/pyTest/testInputFile.py diff --git a/test/pyTest/testInputFile.py b/test/pyTest/testInputFile.py new file mode 100644 index 00000000..d9b4f247 --- /dev/null +++ b/test/pyTest/testInputFile.py @@ -0,0 +1,42 @@ +import os + +# Check if environment is setup to run the tests +if os.environ.get('AVTRANSCODER_TEST_VIDEO_MOV_FILE') is None: + from nose.plugins.skip import SkipTest + raise SkipTest("Need to define environment variables " + "AVTRANSCODER_TEST_VIDEO_MOV_FILE") + +from nose.tools import * + +from pyAvTranscoder import avtranscoder as av + + +@raises(IOError) +def testCreateInputFileFromUnexistingFilename(): + """ + Create an InputFile from an unexisting filename. + """ + inputFileName = "testCreateInputFileFromUnexistingFilename" + av.InputFile( inputFileName ) + + +def testInputFileAnalyseFirstGop(): + """ + Analyse the first gop of an InputFile, and check if the correct attributes are filled. + """ + inputFileName = os.environ['AVTRANSCODER_TEST_VIDEO_MOV_FILE'] + inputFile = av.InputFile( inputFileName ) + + # The analyse of the first GOP is not done yet + videoProperties = inputFile.getProperties().getVideoProperties()[0] + assert_equals(videoProperties.isInterlaced(), False) + assert_equals(videoProperties.isTopFieldFirst(), False) + assert_equals(videoProperties.getGopStructure(), ()) + + # Analyse first GOP + progress = av.NoDisplayProgress() + inputFile.analyse( progress, av.eAnalyseLevelFirstGop ) + + # Check properties after GOP analysis + videoProperties = inputFile.getProperties().getVideoProperties()[0] + assert_not_equals(videoProperties.getGopStructure(), ())