From b428c88596d26e4721aee0de778c810f4480b529 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 9 Oct 2015 18:41:32 +0200 Subject: [PATCH 01/31] OutputFile: fix AVCodecContext of stream when addAudioStream When create a new audio stream, indicate in the codec the number of samples per channel in an audio frame. --- src/AvTranscoder/file/OutputFile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index 910b7d95..346efe2c 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -74,6 +74,7 @@ IOutputStream& OutputFile::addAudioStream( const AudioCodec& audioDesc ) stream.codec->sample_rate = audioDesc.getAVCodecContext().sample_rate; stream.codec->channels = audioDesc.getAVCodecContext().channels; stream.codec->sample_fmt = audioDesc.getAVCodecContext().sample_fmt; + stream.codec->frame_size = audioDesc.getAVCodecContext().frame_size; // need to set the time_base on the AVCodecContext of the AVStream av_reduce( From 97207e0e0a37a4c576540988c174473dcd36065b Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 12 Oct 2015 12:03:37 +0200 Subject: [PATCH 02/31] CMake: get AvTranscoder versions from headers Because it could be great to get the versions in bindings. --- CMakeLists.txt | 11 ----------- cmake/AvTranscoderMacros.cmake | 21 +++++++++++++++++++++ src/AvTranscoder/common.hpp | 4 ++++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e336bfd..929e4dde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,17 +2,6 @@ cmake_minimum_required(VERSION 2.8.11) project(AvTranscoder) -# Set AvTranscoder versions -set(AVTRANSCODER_VERSION_MAJOR "0") -set(AVTRANSCODER_VERSION_MINOR "5") -set(AVTRANSCODER_VERSION_MICRO "10") -set(AVTRANSCODER_VERSION ${AVTRANSCODER_VERSION_MAJOR}.${AVTRANSCODER_VERSION_MINOR}.${AVTRANSCODER_VERSION_MICRO}) - -# Define AvTranscoder versions -add_definitions(-DAVTRANSCODER_VERSION_MAJOR=${AVTRANSCODER_VERSION_MAJOR}) -add_definitions(-DAVTRANSCODER_VERSION_MINOR=${AVTRANSCODER_VERSION_MINOR}) -add_definitions(-DAVTRANSCODER_VERSION_MICRO=${AVTRANSCODER_VERSION_MICRO}) - # Define AvTranscoder default path to profiles add_definitions(-DAVTRANSCODER_DEFAULT_AVPROFILES="${CMAKE_INSTALL_PREFIX}/share/avprofiles") diff --git a/cmake/AvTranscoderMacros.cmake b/cmake/AvTranscoderMacros.cmake index 4794bd21..2dc45379 100644 --- a/cmake/AvTranscoderMacros.cmake +++ b/cmake/AvTranscoderMacros.cmake @@ -2,3 +2,24 @@ set(AVTRANSCODER_APP_PATH "${PROJECT_SOURCE_DIR}/app") set(AVTRANSCODER_SRC_PATH "${PROJECT_SOURCE_DIR}/src") file(GLOB_RECURSE AVTRANSCODER_SRC_FILES "AvTranscoder/*.cpp" "AvTranscoder/*.hpp") + +# Get AvTranscoder versions +# AVTRANSCODER_VERSION_MAJOR +# AVTRANSCODER_VERSION_MINOR +# AVTRANSCODER_VERSION_MICRO +# AVTRANSCODER_VERSION +file(STRINGS "${AVTRANSCODER_SRC_PATH}/AvTranscoder/common.hpp" _avtranscoder_VERSION_HPP_CONTENTS REGEX "#define AVTRANSCODER_VERSION_") +foreach(v MAJOR MINOR MICRO) + if("${_avtranscoder_VERSION_HPP_CONTENTS}" MATCHES "#define AVTRANSCODER_VERSION_${v} ([0-9]+)") + set(AVTRANSCODER_VERSION_${v} "${CMAKE_MATCH_1}") + else() + set(AVTRANSCODER_RETRIEVE_VERSION_FAILED 1) + endif() +endforeach() +unset(_avtranscoder_VERSION_HPP_CONTENTS) + +set(AVTRANSCODER_VERSION "${AVTRANSCODER_VERSION_MAJOR}.${AVTRANSCODER_VERSION_MINOR}.${AVTRANSCODER_VERSION_MICRO}") + +if(AVTRANSCODER_RETRIEVE_VERSION_FAILED) + message(SEND_ERROR "Failed to retrieve AvTranscoder version: ${AVTRANSCODER_VERSION}") +endif() diff --git a/src/AvTranscoder/common.hpp b/src/AvTranscoder/common.hpp index 33bebcd9..2c379804 100644 --- a/src/AvTranscoder/common.hpp +++ b/src/AvTranscoder/common.hpp @@ -1,6 +1,10 @@ #ifndef _AV_TRANSCODER_COMMON_HPP_ #define _AV_TRANSCODER_COMMON_HPP_ +#define AVTRANSCODER_VERSION_MAJOR 0 +#define AVTRANSCODER_VERSION_MINOR 5 +#define AVTRANSCODER_VERSION_MICRO 10 + #include extern "C" { From b4129f89123213595b900c36446c118693b9efd4 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 12 Oct 2015 12:04:29 +0200 Subject: [PATCH 03/31] CMake: clean --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 929e4dde..933aac0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,8 +26,10 @@ if(AVTRANSCODER_COVERAGE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") endif() +# Build library add_subdirectory(src) +# Build apps if(AVTRANSCODER_DISABLE_APPS) message("Apps disabled, will not build applications.") else() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a895f98..40fc747f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,16 +2,14 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) include(AvTranscoderMacros) -# find package ffmpeg/libav +# Find package ffmpeg/libav find_package(FFmpeg COMPONENTS avcodec avformat avutil swscale swresample avresample) - -# Check if FFmpeg or libav dependency if(swresample_FOUND) add_definitions(-DAVTRANSCODER_FFMPEG_DEPENDENCY) - message("Build avTranscoder with dependency to ffmpeg.") + message(STATUS "Build avTranscoder with dependency to ffmpeg.") elseif(avresample_FOUND) add_definitions(-DAVTRANSCODER_LIBAV_DEPENDENCY) - message("Build avTranscoder with dependency to libav.") + message(STATUS "Build avTranscoder with dependency to libav.") else() message(SEND_ERROR "Can't define if you depend on ffmpeg or libav.") endif() From 89dd123f97152d2de6ad6bf643bf8b3e54dfdc79 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 12 Oct 2015 12:05:01 +0200 Subject: [PATCH 04/31] CMake: print info to check AvTranscoder version --- src/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40fc747f..ad8a4630 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,9 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) include(AvTranscoderMacros) +# AvTranscoder versions +message(STATUS "AvTranscoder version is ${AVTRANSCODER_VERSION}") + # Find package ffmpeg/libav find_package(FFmpeg COMPONENTS avcodec avformat avutil swscale swresample avresample) if(swresample_FOUND) From 11af7c15f1144496ac3ef51d5084b4f2aa886959 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 12 Oct 2015 14:13:03 +0200 Subject: [PATCH 05/31] Up to v0.5.11 --- src/AvTranscoder/common.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/common.hpp b/src/AvTranscoder/common.hpp index 2c379804..6eeeb620 100644 --- a/src/AvTranscoder/common.hpp +++ b/src/AvTranscoder/common.hpp @@ -3,7 +3,7 @@ #define AVTRANSCODER_VERSION_MAJOR 0 #define AVTRANSCODER_VERSION_MINOR 5 -#define AVTRANSCODER_VERSION_MICRO 10 +#define AVTRANSCODER_VERSION_MICRO 11 #include From d4f2d8f9e5d69f28caeb44bacab1de042a34b3a8 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 19 Oct 2015 14:05:03 +0200 Subject: [PATCH 06/31] OutputFile: copy channel_layout for each audio stream added --- src/AvTranscoder/file/OutputFile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index 346efe2c..075889ab 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -73,6 +73,7 @@ IOutputStream& OutputFile::addAudioStream( const AudioCodec& audioDesc ) stream.codec->sample_rate = audioDesc.getAVCodecContext().sample_rate; stream.codec->channels = audioDesc.getAVCodecContext().channels; + stream.codec->channel_layout = audioDesc.getAVCodecContext().channel_layout; stream.codec->sample_fmt = audioDesc.getAVCodecContext().sample_fmt; stream.codec->frame_size = audioDesc.getAVCodecContext().frame_size; From 2d06c07fff2daf77e312eb9cf56d5ae06f48466a Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 19 Oct 2015 14:08:46 +0200 Subject: [PATCH 07/31] pyTest: check channel_layout when rewrap an audio stream --- test/pyTest/testTranscoderRewrap.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/pyTest/testTranscoderRewrap.py b/test/pyTest/testTranscoderRewrap.py index 61c02c5b..0d4b9dcd 100644 --- a/test/pyTest/testTranscoderRewrap.py +++ b/test/pyTest/testTranscoderRewrap.py @@ -52,9 +52,6 @@ def testRewrapAudioStream(): src_propertiesMap = src_audioStream.getPropertiesAsMap() dst_propertiesMap = dst_audioStream.getPropertiesAsMap() for key in src_propertiesMap: - # @todo: don't skip channel layout - if key == "channelLayout": - continue assert_equals( src_propertiesMap[key], dst_propertiesMap[key] ) def testRewrapVideoStream(): From e947d9e850bdcf6cf832d093076b72fc807e49ab Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 19 Oct 2015 14:21:56 +0200 Subject: [PATCH 08/31] pyTest: check video bitrate when transcode to dnxhd --- test/pyTest/testTranscoderTranscodeVideo.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/pyTest/testTranscoderTranscodeVideo.py b/test/pyTest/testTranscoderTranscodeVideo.py index 3538fe9a..5e38d7c8 100644 --- a/test/pyTest/testTranscoderTranscodeVideo.py +++ b/test/pyTest/testTranscoderTranscodeVideo.py @@ -36,7 +36,9 @@ def testTranscodeDnxhd120(): assert_equals( "dnxhd", dst_videoStream.getCodecName() ) assert_equals( "VC3/DNxHD", dst_videoStream.getCodecLongName() ) - # assert_equals( 120000000, dst_videoStream.getBitRate() ) # 120000000 != 0L + expectedBitRate = 120000000 + deltaBitRate = expectedBitRate * 0.05 + assert_almost_equals( expectedBitRate, dst_videoStream.getBitRate(), delta=deltaBitRate ) assert_equals( "yuv422p", dst_videoStream.getPixelProperties().getPixelName() ) # assert_equals( 1, dst_videoStream.getGopSize() ) # 1 != 12L @@ -63,7 +65,9 @@ def testTranscodeDnxhd185(): assert_equals( "dnxhd", dst_videoStream.getCodecName() ) assert_equals( "VC3/DNxHD", dst_videoStream.getCodecLongName() ) - # assert_equals( 185000000, dst_videoStream.getBitRate() ) # 185000000 != 0L + expectedBitRate = 185000000 + deltaBitRate = expectedBitRate * 0.05 + assert_almost_equals( expectedBitRate, dst_videoStream.getBitRate(), delta=deltaBitRate ) assert_equals( "yuv422p", dst_videoStream.getPixelProperties().getPixelName() ) # assert_equals( 1, dst_videoStream.getGopSize() ) # 1 != 12L @@ -90,7 +94,9 @@ def testTranscodeDnxhd185x(): assert_equals( "dnxhd", dst_videoStream.getCodecName() ) assert_equals( "VC3/DNxHD", dst_videoStream.getCodecLongName() ) - # assert_equals( 185000000, dst_videoStream.getBitRate() ) # 185000000 != 0L + expectedBitRate = 185000000 + deltaBitRate = expectedBitRate * 0.05 + assert_almost_equals( expectedBitRate, dst_videoStream.getBitRate(), delta=deltaBitRate ) assert_equals( "yuv422p10le", dst_videoStream.getPixelProperties().getPixelName() ) # assert_equals( 1, dst_videoStream.getGopSize() ) # 1 != 12L @@ -125,4 +131,3 @@ def testTranscodeYUV420(): assert_equals( "mpeg2video", dst_videoStream.getCodecName() ) assert_equals( "yuv420p", dst_videoStream.getPixelProperties().getPixelName() ) - From 15c22fd374f58c316dc4ae0338f1829e50ce7c77 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 19 Oct 2015 14:26:57 +0200 Subject: [PATCH 09/31] pyTest: check bitrate with a relative delta when rewrap --- test/pyTest/testTranscoderRewrap.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/pyTest/testTranscoderRewrap.py b/test/pyTest/testTranscoderRewrap.py index 0d4b9dcd..b36539f0 100644 --- a/test/pyTest/testTranscoderRewrap.py +++ b/test/pyTest/testTranscoderRewrap.py @@ -30,7 +30,7 @@ def testRewrapAudioStream(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "" ) + transcoder.add( inputFileName, 0 ) transcoder.process( progress ) # get dst file of wrap @@ -44,7 +44,7 @@ def testRewrapAudioStream(): assert_equals( src_properties.getFormatLongName(), dst_properties.getFormatLongName() ) assert_equals( src_properties.getStartTime(), dst_properties.getStartTime() ) assert_equals( src_properties.getDuration(), dst_properties.getDuration() ) - deltaBitRateAudio = 10 + deltaBitRateAudio = dst_properties.getBitRate() * 0.01 assert_almost_equals( src_properties.getBitRate(), dst_properties.getBitRate(), delta=deltaBitRateAudio ) assert_equals( src_properties.getPacketSize(), dst_properties.getPacketSize() ) @@ -71,7 +71,7 @@ def testRewrapVideoStream(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "" ) + transcoder.add( inputFileName, 0 ) transcoder.process( progress ) # get dst file of wrap @@ -85,7 +85,7 @@ def testRewrapVideoStream(): assert_equals( src_properties.getFormatLongName(), dst_properties.getFormatLongName() ) assert_equals( src_properties.getStartTime(), dst_properties.getStartTime() ) assert_equals( src_properties.getDuration(), dst_properties.getDuration() ) - deltaBitRateVideo = 500000 + deltaBitRateVideo = dst_properties.getBitRate() * 0.15 assert_almost_equals( src_properties.getBitRate(), dst_properties.getBitRate(), delta=deltaBitRateVideo ) assert_equals( src_properties.getPacketSize(), dst_properties.getPacketSize() ) From e71368c401a176f7d5a3ac5e67ebe37bd6832392 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 19 Oct 2015 14:28:04 +0200 Subject: [PATCH 10/31] pyTest: do not check channel_layout when transcode audio Because the channel layout is not specified in the audio profile. --- test/pyTest/testTranscoderTranscodeAudioWave.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/pyTest/testTranscoderTranscodeAudioWave.py b/test/pyTest/testTranscoderTranscodeAudioWave.py index b10ad1fe..82ab2eea 100644 --- a/test/pyTest/testTranscoderTranscodeAudioWave.py +++ b/test/pyTest/testTranscoderTranscodeAudioWave.py @@ -39,7 +39,6 @@ def testTranscodeWave24b48k5_1(): assert_equals( "s32", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 32 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - # assert_equals( "1 channels", dst_audioStream.getChannelLayout() ) # '1 channels' != '0 channels' assert_equals( 6, dst_audioStream.getChannels() ) def testTranscodeWave24b48kstereo(): @@ -68,7 +67,6 @@ def testTranscodeWave24b48kstereo(): assert_equals( "s32", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 32 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - # assert_equals( "1 channels", dst_audioStream.getChannelLayout() ) # '1 channels' != '0 channels' assert_equals( 2, dst_audioStream.getChannels() ) def testTranscodeWave24b48kmono(): @@ -97,7 +95,6 @@ def testTranscodeWave24b48kmono(): assert_equals( "s32", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 32 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - # assert_equals( "1 channels", dst_audioStream.getChannelLayout() ) # '1 channels' != '0 channels' assert_equals( 1, dst_audioStream.getChannels() ) def testTranscodeWave16b48kmono(): @@ -126,5 +123,4 @@ def testTranscodeWave16b48kmono(): assert_equals( "s16", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 16 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - # assert_equals( "1 channels", dst_audioStream.getChannelLayout() ) # '1 channels' != '0 channels' assert_equals( 1, dst_audioStream.getChannels() ) From 7ad91b9def68129f0c003a7ebc786db234e8a27f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 19 Oct 2015 16:33:43 +0200 Subject: [PATCH 11/31] Up to v0.5.12 --- src/AvTranscoder/common.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/common.hpp b/src/AvTranscoder/common.hpp index 6eeeb620..010fa163 100644 --- a/src/AvTranscoder/common.hpp +++ b/src/AvTranscoder/common.hpp @@ -3,7 +3,7 @@ #define AVTRANSCODER_VERSION_MAJOR 0 #define AVTRANSCODER_VERSION_MINOR 5 -#define AVTRANSCODER_VERSION_MICRO 11 +#define AVTRANSCODER_VERSION_MICRO 12 #include From b59b05011655e8c24b97551c7e790a85d0a4b8e1 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 20 Oct 2015 15:40:42 +0200 Subject: [PATCH 12/31] log: add private attribute to set header of logs only once Fix #255 --- src/AvTranscoder/log.cpp | 22 ++++++++++++---------- src/AvTranscoder/log.hpp | 3 +++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/AvTranscoder/log.cpp b/src/AvTranscoder/log.cpp index 8327f24b..58c32702 100644 --- a/src/AvTranscoder/log.cpp +++ b/src/AvTranscoder/log.cpp @@ -3,6 +3,8 @@ namespace avtranscoder { +std::string Logger::logHeaderMessage = ""; + void callbackToWriteInFile( void *ptr, int level, const char *fmt, va_list vl ) { std::ofstream outputFile; @@ -23,13 +25,10 @@ void callbackToWriteInFile( void *ptr, int level, const char *fmt, va_list vl ) void Logger::setLogLevel( const int level ) { + // set ffmpeg log level av_log_set_level( level ); -} - -void Logger::log( const int level, const std::string& msg ) -{ - std::string avTranscoderMsg( "[avTranscoder - " ); + // set avtranscoder header message std::string levelStr; switch( level ) { @@ -48,12 +47,15 @@ void Logger::log( const int level, const std::string& msg ) default: break; } + Logger::logHeaderMessage = "[avTranscoder - " + levelStr + "] "; +} - avTranscoderMsg += levelStr; - avTranscoderMsg += "] "; - avTranscoderMsg += msg; - avTranscoderMsg += "\n"; - av_log( NULL, level, avTranscoderMsg.c_str() ); +void Logger::log( const int level, const std::string& msg ) +{ + std::string logMessage = Logger::logHeaderMessage; + logMessage += msg; + logMessage += "\n"; + av_log( NULL, level, logMessage.c_str() ); } void Logger::logInFile() diff --git a/src/AvTranscoder/log.hpp b/src/AvTranscoder/log.hpp index d25067c9..e1102479 100644 --- a/src/AvTranscoder/log.hpp +++ b/src/AvTranscoder/log.hpp @@ -44,6 +44,9 @@ class AvExport Logger * @note log filename is avtranscoder.log */ static void logInFile(); + +private: + static std::string logHeaderMessage; ///< First caracters present for each logging message }; } From 2298b6225612f1ba19997319da27b78605e1c9e4 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 11:46:00 +0100 Subject: [PATCH 13/31] InputStream: move doc to based class --- src/AvTranscoder/stream/IInputStream.hpp | 2 +- src/AvTranscoder/stream/InputStream.hpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/AvTranscoder/stream/IInputStream.hpp b/src/AvTranscoder/stream/IInputStream.hpp index 4e8ea4b8..de286ef6 100644 --- a/src/AvTranscoder/stream/IInputStream.hpp +++ b/src/AvTranscoder/stream/IInputStream.hpp @@ -22,7 +22,7 @@ class AvExport IInputStream virtual bool readNextPacket( CodedData& data ) = 0; virtual size_t getStreamIndex() const = 0; - virtual float getDuration() const = 0; + virtual float getDuration() const = 0; ///< Get duration of the stream, in seconds virtual AVMediaType getStreamType() const = 0; //@{ diff --git a/src/AvTranscoder/stream/InputStream.hpp b/src/AvTranscoder/stream/InputStream.hpp index 2bb218f7..7b0608da 100644 --- a/src/AvTranscoder/stream/InputStream.hpp +++ b/src/AvTranscoder/stream/InputStream.hpp @@ -25,7 +25,6 @@ class AvExport InputStream : public IInputStream bool readNextPacket( CodedData& data ); size_t getStreamIndex() const { return _streamIndex; } - /// Get duration of the stream, in seconds float getDuration() const; AVMediaType getStreamType() const; From 87c29ab359f39e39461372d4d2634e86adafc800 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 11:47:20 +0100 Subject: [PATCH 14/31] IOuputFile: clean doc setup function does not exist any more. --- src/AvTranscoder/file/IOutputFile.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/AvTranscoder/file/IOutputFile.hpp b/src/AvTranscoder/file/IOutputFile.hpp index bce7b919..7bb6c9de 100644 --- a/src/AvTranscoder/file/IOutputFile.hpp +++ b/src/AvTranscoder/file/IOutputFile.hpp @@ -26,7 +26,6 @@ class AvExport IOutputFile /** * @brief Add a video output stream - * @note call setup() before adding any stream * @param videoCodec description of output stream **/ virtual IOutputStream& addVideoStream( const VideoCodec& videoCodec ) @@ -36,7 +35,6 @@ class AvExport IOutputFile /** * @brief Add an audio output stream - * @note call setup() before adding any stream * @param audioCodec description of output stream **/ virtual IOutputStream& addAudioStream( const AudioCodec& audioCodec ) @@ -46,7 +44,6 @@ class AvExport IOutputFile /** * @brief Add a data output stream - * @note call setup() before adding any stream * @param dataCodec description of output stream **/ virtual IOutputStream& addDataStream( const DataCodec& dataCodec ) From 88af4f68382e58354ec994ab33659d5448dcff84 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 11:53:02 +0100 Subject: [PATCH 15/31] InputStream: add getProperties method --- src/AvTranscoder/stream/IInputStream.hpp | 9 +++++++++ src/AvTranscoder/stream/InputStream.cpp | 5 +++++ src/AvTranscoder/stream/InputStream.hpp | 1 + 3 files changed, 15 insertions(+) diff --git a/src/AvTranscoder/stream/IInputStream.hpp b/src/AvTranscoder/stream/IInputStream.hpp index de286ef6..0bc368b5 100644 --- a/src/AvTranscoder/stream/IInputStream.hpp +++ b/src/AvTranscoder/stream/IInputStream.hpp @@ -1,9 +1,12 @@ #ifndef _AV_TRANSCODER_CODED_STREAM_I_INPUT_STREAM_HPP_ #define _AV_TRANSCODER_CODED_STREAM_I_INPUT_STREAM_HPP_ +#include + #include #include #include + #include namespace avtranscoder @@ -21,6 +24,12 @@ class AvExport IInputStream **/ virtual bool readNextPacket( CodedData& data ) = 0; + /** + * @note The returned object could be cast depending on the type of the stream (video, audio...) + * @see VideoProperties, AudioProperties... + * @return the properties of the stream + */ + virtual const StreamProperties& getProperties() const = 0; virtual size_t getStreamIndex() const = 0; virtual float getDuration() const = 0; ///< Get duration of the stream, in seconds virtual AVMediaType getStreamType() const = 0; diff --git a/src/AvTranscoder/stream/InputStream.cpp b/src/AvTranscoder/stream/InputStream.cpp index 851bd0f5..752040d4 100644 --- a/src/AvTranscoder/stream/InputStream.cpp +++ b/src/AvTranscoder/stream/InputStream.cpp @@ -108,6 +108,11 @@ DataCodec& InputStream::getDataCodec() return *static_cast( _codec ); } +const StreamProperties& InputStream::getProperties() const +{ + return _inputFile->getProperties().getStreamPropertiesWithIndex( _streamIndex ); +} + AVMediaType InputStream::getStreamType() const { return _inputFile->getFormatContext().getAVStream( _streamIndex ).codec->codec_type; diff --git a/src/AvTranscoder/stream/InputStream.hpp b/src/AvTranscoder/stream/InputStream.hpp index 7b0608da..c5f1b1ef 100644 --- a/src/AvTranscoder/stream/InputStream.hpp +++ b/src/AvTranscoder/stream/InputStream.hpp @@ -24,6 +24,7 @@ class AvExport InputStream : public IInputStream bool readNextPacket( CodedData& data ); + const StreamProperties& getProperties() const; size_t getStreamIndex() const { return _streamIndex; } float getDuration() const; AVMediaType getStreamType() const; From 7341a7a2f62f725e0f75ded565d44b40b8ac751a Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 11:56:40 +0100 Subject: [PATCH 16/31] StreamProperties: add getStreamType method --- src/AvTranscoder/mediaProperty/StreamProperties.cpp | 7 +++++++ src/AvTranscoder/mediaProperty/StreamProperties.hpp | 1 + 2 files changed, 8 insertions(+) diff --git a/src/AvTranscoder/mediaProperty/StreamProperties.cpp b/src/AvTranscoder/mediaProperty/StreamProperties.cpp index b16ee25d..196e425d 100644 --- a/src/AvTranscoder/mediaProperty/StreamProperties.cpp +++ b/src/AvTranscoder/mediaProperty/StreamProperties.cpp @@ -43,6 +43,13 @@ float StreamProperties::getDuration() const return ( timeBase.num / (float) timeBase.den ) * _formatContext->streams[_streamIndex]->duration; } +AVMediaType StreamProperties::getStreamType() const +{ + if( ! _formatContext ) + throw std::runtime_error( "unknown format context" ); + return _formatContext->streams[_streamIndex]->codec->codec_type; +} + PropertyVector StreamProperties::getPropertiesAsVector() const { PropertyVector data; diff --git a/src/AvTranscoder/mediaProperty/StreamProperties.hpp b/src/AvTranscoder/mediaProperty/StreamProperties.hpp index 86c798ac..ee9edf75 100644 --- a/src/AvTranscoder/mediaProperty/StreamProperties.hpp +++ b/src/AvTranscoder/mediaProperty/StreamProperties.hpp @@ -19,6 +19,7 @@ class AvExport StreamProperties size_t getStreamId() const; Rational getTimeBase() const; float getDuration() const; ///< in seconds + AVMediaType getStreamType() const; const PropertyVector& getMetadatas() const { return _metadatas; } #ifndef SWIG From 10b5a09ca4c63156dbe4e4a7276d14539fe2934c Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 12:01:39 +0100 Subject: [PATCH 17/31] IInputStream: remove getStreamType --- src/AvTranscoder/stream/IInputStream.hpp | 1 - src/AvTranscoder/stream/InputStream.cpp | 11 +++-------- src/AvTranscoder/stream/InputStream.hpp | 1 - src/AvTranscoder/transcoder/StreamTranscoder.cpp | 4 ++-- src/AvTranscoder/transcoder/Transcoder.cpp | 6 +++--- 5 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/AvTranscoder/stream/IInputStream.hpp b/src/AvTranscoder/stream/IInputStream.hpp index 0bc368b5..825eec84 100644 --- a/src/AvTranscoder/stream/IInputStream.hpp +++ b/src/AvTranscoder/stream/IInputStream.hpp @@ -32,7 +32,6 @@ class AvExport IInputStream virtual const StreamProperties& getProperties() const = 0; virtual size_t getStreamIndex() const = 0; virtual float getDuration() const = 0; ///< Get duration of the stream, in seconds - virtual AVMediaType getStreamType() const = 0; //@{ /** diff --git a/src/AvTranscoder/stream/InputStream.cpp b/src/AvTranscoder/stream/InputStream.cpp index 752040d4..7830c14e 100644 --- a/src/AvTranscoder/stream/InputStream.cpp +++ b/src/AvTranscoder/stream/InputStream.cpp @@ -76,7 +76,7 @@ VideoCodec& InputStream::getVideoCodec() { assert( _streamIndex <= _inputFile->getFormatContext().getNbStreams() ); - if( getStreamType() != AVMEDIA_TYPE_VIDEO ) + if( getProperties().getStreamType() != AVMEDIA_TYPE_VIDEO ) { throw std::runtime_error( "unable to get video descriptor on non-video stream" ); } @@ -88,7 +88,7 @@ AudioCodec& InputStream::getAudioCodec() { assert( _streamIndex <= _inputFile->getFormatContext().getNbStreams() ); - if( getStreamType() != AVMEDIA_TYPE_AUDIO ) + if( getProperties().getStreamType() != AVMEDIA_TYPE_AUDIO ) { throw std::runtime_error( "unable to get audio descriptor on non-audio stream" ); } @@ -100,7 +100,7 @@ DataCodec& InputStream::getDataCodec() { assert( _streamIndex <= _inputFile->getFormatContext().getNbStreams() ); - if( getStreamType() != AVMEDIA_TYPE_DATA ) + if( getProperties().getStreamType() != AVMEDIA_TYPE_DATA ) { throw std::runtime_error( "unable to get data descriptor on non-data stream" ); } @@ -113,11 +113,6 @@ const StreamProperties& InputStream::getProperties() const return _inputFile->getProperties().getStreamPropertiesWithIndex( _streamIndex ); } -AVMediaType InputStream::getStreamType() const -{ - return _inputFile->getFormatContext().getAVStream( _streamIndex ).codec->codec_type; -} - float InputStream::getDuration() const { return _inputFile->getProperties().getStreamPropertiesWithIndex( _streamIndex ).getDuration(); diff --git a/src/AvTranscoder/stream/InputStream.hpp b/src/AvTranscoder/stream/InputStream.hpp index c5f1b1ef..90982a63 100644 --- a/src/AvTranscoder/stream/InputStream.hpp +++ b/src/AvTranscoder/stream/InputStream.hpp @@ -27,7 +27,6 @@ class AvExport InputStream : public IInputStream const StreamProperties& getProperties() const; size_t getStreamIndex() const { return _streamIndex; } float getDuration() const; - AVMediaType getStreamType() const; VideoCodec& getVideoCodec(); AudioCodec& getAudioCodec(); diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index fae22792..90d15476 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -39,7 +39,7 @@ StreamTranscoder::StreamTranscoder( , _needToSwitchToGenerator( false ) { // create a re-wrapping case - switch( _inputStream->getStreamType() ) + switch( _inputStream->getProperties().getStreamType() ) { case AVMEDIA_TYPE_VIDEO : { @@ -141,7 +141,7 @@ StreamTranscoder::StreamTranscoder( , _needToSwitchToGenerator( false ) { // create a transcode case - switch( _inputStream->getStreamType() ) + switch( _inputStream->getProperties().getStreamType() ) { case AVMEDIA_TYPE_VIDEO : { diff --git a/src/AvTranscoder/transcoder/Transcoder.cpp b/src/AvTranscoder/transcoder/Transcoder.cpp index 6458fa93..723faebc 100644 --- a/src/AvTranscoder/transcoder/Transcoder.cpp +++ b/src/AvTranscoder/transcoder/Transcoder.cpp @@ -317,7 +317,7 @@ void Transcoder::addTranscodeStream( const std::string& filename, const size_t s // Add input file InputFile* referenceFile = addInputFile( filename, streamIndex, offset ); - switch( referenceFile->getStream( streamIndex ).getStreamType() ) + switch( referenceFile->getStream( streamIndex ).getProperties().getStreamType() ) { case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_AUDIO: @@ -385,7 +385,7 @@ ProfileLoader::Profile Transcoder::getProfileFromFile( InputFile& inputFile, con const StreamProperties* streamProperties = &inputFile.getProperties().getStreamPropertiesWithIndex( streamIndex ); const VideoProperties* videoProperties = NULL; const AudioProperties* audioProperties = NULL; - switch( inputFile.getStream( streamIndex ).getStreamType() ) + switch( inputFile.getStream( streamIndex ).getProperties().getStreamType() ) { case AVMEDIA_TYPE_VIDEO: { @@ -522,7 +522,7 @@ void Transcoder::fillProcessStat( ProcessStat& processStat ) for( size_t streamIndex = 0; streamIndex < _streamTranscoders.size(); ++streamIndex ) { IOutputStream& stream = _streamTranscoders.at( streamIndex )->getOutputStream(); - const AVMediaType mediaType = _streamTranscoders.at( streamIndex )->getInputStream().getStreamType(); + const AVMediaType mediaType = _streamTranscoders.at( streamIndex )->getInputStream().getProperties().getStreamType(); switch( mediaType ) { case AVMEDIA_TYPE_VIDEO: From 447392a9e68e8bb84796b9b26decf049152707b0 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 12:12:19 +0100 Subject: [PATCH 18/31] IInputStream: remove getDuration --- src/AvTranscoder/stream/IInputStream.hpp | 1 - src/AvTranscoder/stream/InputStream.cpp | 5 ----- src/AvTranscoder/stream/InputStream.hpp | 1 - src/AvTranscoder/transcoder/StreamTranscoder.cpp | 7 ++++--- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/AvTranscoder/stream/IInputStream.hpp b/src/AvTranscoder/stream/IInputStream.hpp index 825eec84..403d89e5 100644 --- a/src/AvTranscoder/stream/IInputStream.hpp +++ b/src/AvTranscoder/stream/IInputStream.hpp @@ -31,7 +31,6 @@ class AvExport IInputStream */ virtual const StreamProperties& getProperties() const = 0; virtual size_t getStreamIndex() const = 0; - virtual float getDuration() const = 0; ///< Get duration of the stream, in seconds //@{ /** diff --git a/src/AvTranscoder/stream/InputStream.cpp b/src/AvTranscoder/stream/InputStream.cpp index 7830c14e..ef9bc6d0 100644 --- a/src/AvTranscoder/stream/InputStream.cpp +++ b/src/AvTranscoder/stream/InputStream.cpp @@ -113,11 +113,6 @@ const StreamProperties& InputStream::getProperties() const return _inputFile->getProperties().getStreamPropertiesWithIndex( _streamIndex ); } -float InputStream::getDuration() const -{ - return _inputFile->getProperties().getStreamPropertiesWithIndex( _streamIndex ).getDuration(); -} - void InputStream::addPacket( const AVPacket& packet ) { // Do not cache data if the stream is declared as unused in process diff --git a/src/AvTranscoder/stream/InputStream.hpp b/src/AvTranscoder/stream/InputStream.hpp index 90982a63..a7ad47d0 100644 --- a/src/AvTranscoder/stream/InputStream.hpp +++ b/src/AvTranscoder/stream/InputStream.hpp @@ -26,7 +26,6 @@ class AvExport InputStream : public IInputStream const StreamProperties& getProperties() const; size_t getStreamIndex() const { return _streamIndex; } - float getDuration() const; VideoCodec& getVideoCodec(); AudioCodec& getAudioCodec(); diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index 90d15476..ef7a0157 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -383,7 +383,7 @@ bool StreamTranscoder::processFrame() } else if( _offset < 0 ) { - const bool endOfStream = _outputStream->getStreamDuration() >= ( _inputStream->getDuration() + _offset ); + const bool endOfStream = _outputStream->getStreamDuration() >= ( _inputStream->getProperties().getDuration() + _offset ); if( endOfStream ) { LOG_INFO( "End of negative offset" ) @@ -516,10 +516,11 @@ float StreamTranscoder::getDuration() const { if( _inputStream ) { - const float totalDuration = _inputStream->getDuration() + _offset; + const StreamProperties& streamProperties = _inputStream->getProperties(); + const float totalDuration = streamProperties.getDuration() + _offset; if( totalDuration < 0 ) { - LOG_WARN( "Offset of " << _offset << "s applied to a stream with a duration of " << _inputStream->getDuration() << "s. Set its duration to 0s." ) + LOG_WARN( "Offset of " << _offset << "s applied to a stream with a duration of " << streamProperties.getDuration() << "s. Set its duration to 0s." ) return 0.; } return totalDuration; From e41021aaa928b63968c6e43fc7eb51fe3c866efd Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 12:15:26 +0100 Subject: [PATCH 19/31] IInputStream: add doc --- src/AvTranscoder/stream/IInputStream.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/AvTranscoder/stream/IInputStream.hpp b/src/AvTranscoder/stream/IInputStream.hpp index 403d89e5..0b733c60 100644 --- a/src/AvTranscoder/stream/IInputStream.hpp +++ b/src/AvTranscoder/stream/IInputStream.hpp @@ -30,6 +30,10 @@ class AvExport IInputStream * @return the properties of the stream */ virtual const StreamProperties& getProperties() const = 0; + + /** + * @return the index of the stream + */ virtual size_t getStreamIndex() const = 0; //@{ From cf8619f1dcd02fe5920dd3374a866b2f484c3c77 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 14:20:55 +0100 Subject: [PATCH 20/31] OuputFile: rename streamId argument to streamIndex --- src/AvTranscoder/file/IOutputFile.hpp | 6 ++++-- src/AvTranscoder/file/OutputFile.cpp | 16 ++++++++-------- src/AvTranscoder/file/OutputFile.hpp | 6 +++--- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/AvTranscoder/file/IOutputFile.hpp b/src/AvTranscoder/file/IOutputFile.hpp index 7bb6c9de..a8a4f9ad 100644 --- a/src/AvTranscoder/file/IOutputFile.hpp +++ b/src/AvTranscoder/file/IOutputFile.hpp @@ -59,7 +59,9 @@ class AvExport IOutputFile /** * @brief Wrap a packet of data in the output ressource * @param data coded packet information for the current stream - * @param streamId refers to the stream in output ressource + * @param streamIndex refers to the stream in output ressource + * @return the wrapping status after wrapping + * @see EWrappingStatus **/ virtual IOutputStream::EWrappingStatus wrap( const CodedData& data, const size_t streamIndex ) = 0; @@ -70,7 +72,7 @@ class AvExport IOutputFile /** * @brief Get the output stream - * @param streamId select the output stream + * @param streamIndex select the output stream * @return the output stream reference **/ virtual IOutputStream& getStream( const size_t streamIndex ) = 0; diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index 075889ab..156507b3 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -101,11 +101,11 @@ IOutputStream& OutputFile::addDataStream( const DataCodec& dataDesc ) return *outputStream; } -IOutputStream& OutputFile::getStream( const size_t streamId ) +IOutputStream& OutputFile::getStream( const size_t streamIndex ) { - if( streamId >= _outputStreams.size() ) + if( streamIndex >= _outputStreams.size() ) throw std::runtime_error( "unable to get output stream (out of range)" ); - return *_outputStreams.at( streamId ); + return *_outputStreams.at( streamIndex ); } std::string OutputFile::getFilename() const @@ -159,16 +159,16 @@ bool OutputFile::beginWrap( ) return true; } -IOutputStream::EWrappingStatus OutputFile::wrap( const CodedData& data, const size_t streamId ) +IOutputStream::EWrappingStatus OutputFile::wrap( const CodedData& data, const size_t streamIndex ) { if( ! data.getSize() ) return IOutputStream::eWrappingSuccess; - LOG_DEBUG( "Wrap on stream " << streamId << " (" << data.getSize() << " bytes for frame " << _frameCount.at( streamId ) << ")" ) + LOG_DEBUG( "Wrap on stream " << streamIndex << " (" << data.getSize() << " bytes for frame " << _frameCount.at( streamIndex ) << ")" ) AVPacket packet; av_init_packet( &packet ); - packet.stream_index = streamId; + packet.stream_index = streamIndex; packet.data = (uint8_t*)data.getData(); packet.size = data.getSize(); @@ -177,7 +177,7 @@ IOutputStream::EWrappingStatus OutputFile::wrap( const CodedData& data, const si // free packet.side_data, set packet.data to NULL and packet.size to 0 av_free_packet( &packet ); - const double currentStreamDuration = _outputStreams.at( streamId )->getStreamDuration(); + const double currentStreamDuration = _outputStreams.at( streamIndex )->getStreamDuration(); if( currentStreamDuration < _previousProcessedStreamDuration ) { // if the current stream is strictly shorter than the previous, wait for more data @@ -185,7 +185,7 @@ IOutputStream::EWrappingStatus OutputFile::wrap( const CodedData& data, const si } _previousProcessedStreamDuration = currentStreamDuration; - _frameCount.at( streamId )++; + _frameCount.at( streamIndex )++; return IOutputStream::eWrappingSuccess; } diff --git a/src/AvTranscoder/file/OutputFile.hpp b/src/AvTranscoder/file/OutputFile.hpp index 53819a9f..bf71f30d 100644 --- a/src/AvTranscoder/file/OutputFile.hpp +++ b/src/AvTranscoder/file/OutputFile.hpp @@ -37,10 +37,10 @@ class AvExport OutputFile : public IOutputFile * @brief Open ressource, write header, and setup specific wrapping options given when call setupWrapping. * @note Need to add the streams to mux before calling this method. * @note After this call, a new list of AVOption, relative to the format choosen, will be available for the OutputFile. - */ + */ bool beginWrap(); - IOutputStream::EWrappingStatus wrap( const CodedData& data, const size_t streamId ); + IOutputStream::EWrappingStatus wrap( const CodedData& data, const size_t streamIndex ); /** * @brief Close ressource and write trailer. @@ -54,7 +54,7 @@ class AvExport OutputFile : public IOutputFile void addMetadata( const PropertyVector& data ); void addMetadata( const std::string& key, const std::string& value ); - IOutputStream& getStream( const size_t streamId ); + IOutputStream& getStream( const size_t streamIndex ); std::string getFilename() const; From 38b5d8bca350a0b0e7b91d41ed85c0f40d493709 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 15:02:25 +0100 Subject: [PATCH 21/31] IOutputStream: add doc to wrap method --- src/AvTranscoder/stream/IOutputStream.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/AvTranscoder/stream/IOutputStream.hpp b/src/AvTranscoder/stream/IOutputStream.hpp index a45d16d7..83a00415 100644 --- a/src/AvTranscoder/stream/IOutputStream.hpp +++ b/src/AvTranscoder/stream/IOutputStream.hpp @@ -36,6 +36,11 @@ class AvExport IOutputStream */ virtual size_t getNbFrames() const = 0; + /** + * @brief Wrap a packet of data + * @return the wrapping status after wrapping + * @see EWrappingStatus + **/ virtual EWrappingStatus wrap( const CodedData& data ) = 0; }; From 5adc732aedc41a66f67c38abf67b4c49df5a6827 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 15:42:41 +0100 Subject: [PATCH 22/31] IInputStream: move doc of buffering methods to based class --- src/AvTranscoder/stream/IInputStream.hpp | 10 +++++++--- src/AvTranscoder/stream/InputStream.hpp | 6 ------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/AvTranscoder/stream/IInputStream.hpp b/src/AvTranscoder/stream/IInputStream.hpp index 0b733c60..b0d258ba 100644 --- a/src/AvTranscoder/stream/IInputStream.hpp +++ b/src/AvTranscoder/stream/IInputStream.hpp @@ -46,12 +46,16 @@ class AvExport IInputStream virtual DataCodec& getDataCodec() = 0; //@} - /** - * @brief Activate the stream will buffered its data when read packets. - **/ + //@{ + /** + * @brief Functions about buffering + * Activate the stream will buffered its data when read packets. + * @see IInputStream methods + */ virtual void activate( const bool activate = true ) = 0; virtual bool isActivated() const = 0; virtual void clearBuffering() = 0; + //@} }; } diff --git a/src/AvTranscoder/stream/InputStream.hpp b/src/AvTranscoder/stream/InputStream.hpp index a7ad47d0..b0ea4a15 100644 --- a/src/AvTranscoder/stream/InputStream.hpp +++ b/src/AvTranscoder/stream/InputStream.hpp @@ -31,16 +31,10 @@ class AvExport InputStream : public IInputStream AudioCodec& getAudioCodec(); DataCodec& getDataCodec(); - //@{ - /** - * @brief Functions about buffering - * @see IInputStream methods - */ void activate( const bool activate = true ){ _isActivated = activate; }; bool isActivated() const { return _isActivated; }; void addPacket( const AVPacket& packet ); void clearBuffering(); - //@} private: InputFile* _inputFile; ///< Has link (no ownership) From 5c7573e2f5737731aebd5cb4d8ba39965395e845 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 29 Oct 2015 16:15:06 +0100 Subject: [PATCH 23/31] StreamProperties: getAVFormatContext is a const method --- src/AvTranscoder/mediaProperty/StreamProperties.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/mediaProperty/StreamProperties.hpp b/src/AvTranscoder/mediaProperty/StreamProperties.hpp index ee9edf75..a70a9dbe 100644 --- a/src/AvTranscoder/mediaProperty/StreamProperties.hpp +++ b/src/AvTranscoder/mediaProperty/StreamProperties.hpp @@ -23,7 +23,7 @@ class AvExport StreamProperties const PropertyVector& getMetadatas() const { return _metadatas; } #ifndef SWIG - const AVFormatContext& getAVFormatContext() { return *_formatContext; } + const AVFormatContext& getAVFormatContext() const { return *_formatContext; } #endif PropertyMap getPropertiesAsMap() const; ///< Return all properties as a map (name of property, value) From da40efdc9dd4a7397470fbb8af2cc78a8c5bc13d Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 4 Nov 2015 15:58:16 +0100 Subject: [PATCH 24/31] 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 25/31] 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 26/31] 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 27/31] 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 28/31] 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 29/31] 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 30/31] 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 31/31] 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 ) +