From a3116295e1b7e12b9ebd9ac612eb07ca79a8b291 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Mon, 6 Jun 2016 19:27:30 +0300 Subject: [PATCH 1/4] Added CMake modules generation This patch adds AvTranscoderConfig.cmake and FindAvTranscoder.cmake which can be used by the external software to link against avTranscoder libraries. --- cmake/AvTranscoderConfig.cmake.in | 14 ++++++++++++++ cmake/FindAvTranscoder.cmake | 17 +++++++++++++++++ src/CMakeLists.txt | 11 +++++++++++ 3 files changed, 42 insertions(+) create mode 100644 cmake/AvTranscoderConfig.cmake.in create mode 100644 cmake/FindAvTranscoder.cmake diff --git a/cmake/AvTranscoderConfig.cmake.in b/cmake/AvTranscoderConfig.cmake.in new file mode 100644 index 00000000..9f860f6e --- /dev/null +++ b/cmake/AvTranscoderConfig.cmake.in @@ -0,0 +1,14 @@ +set(AvTranscoder_VERSION_MAJOR @AVTRANSCODER_VERSION_MAJOR@) +set(AvTranscoder_VERSION_MINOR @AVTRANSCODER_VERSION_MINOR@) +set(AvTranscoder_VERSION_PATCH @AVTRANSCODER_VERSION_MICRO@) +set(AvTranscoder_VERSION @AVTRANSCODER_VERSION_MAJOR@.@AVTRANSCODER_VERSION_MINOR@.@AVTRANSCODER_VERSION_MICRO@) +set(AvTranscoder_VERSION_STRING "@AVTRANSCODER_VERSION_MAJOR@.@AVTRANSCODER_VERSION_MINOR@.@AVTRANSCODER_VERSION_MICRO@") + +set(AvTranscoder_INSTALL_DIR "@CMAKE_INSTALL_PREFIX@") + +set(AvTranscoder_LIB_DIR "@CMAKE_INSTALL_PREFIX@/lib") +set(AvTranscoder_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include") +set(AvTranscoder_CMAKE_MODULES_DIR "@CMAKE_INSTALL_PREFIX@/lib/cmake/AvTranscoder") +list(APPEND CMAKE_MODULE_PATH "${AvTranscoder_CMAKE_MODULES_DIR}") + +find_library(AvTranscoder_LIBRARIES avtranscoder PATHS "${AvTranscoder_LIB_DIR}" NO_DEFAULT_PATH) diff --git a/cmake/FindAvTranscoder.cmake b/cmake/FindAvTranscoder.cmake new file mode 100644 index 00000000..22cdd96b --- /dev/null +++ b/cmake/FindAvTranscoder.cmake @@ -0,0 +1,17 @@ +# AvTranscoder_FOUND +# AvTranscoder_INCLUDE_DIR +# AvTranscoder_LIBRARIES +# AvTranscoder_DEFINITIONS +# AvTranscoder_VERSION_MAJOR +# AvTranscoder_VERSION_MINOR +# AvTranscoder_VERSION_PATCH +# AvTranscoder_VERSION +# AvTranscoder_VERSION_STRING +# AvTranscoder_INSTALL_DIR +# AvTranscoder_LIB_DIR +# AvTranscoder_CMAKE_MODULES_DIR + +find_package(AvTranscoder ${AvTranscoder_FIND_VERSION} QUIET NO_MODULE PATHS $ENV{HOME} /opt/AvTranscoder) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(AvTranscoder CONFIG_MODE REQUIRED_VARS AvTranscoder_LIBRARIES) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 201608ba..b9d8c185 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,10 @@ include(AvTranscoderMacros) # AvTranscoder versions message(STATUS "AvTranscoder version is ${AVTRANSCODER_VERSION}") +# Create a CMake package definition +configure_file(${PROJECT_SOURCE_DIR}/cmake/AvTranscoderConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/cmake/AvTranscoderConfig.cmake @ONLY) + # Find package ffmpeg/libav find_package(FFmpeg COMPONENTS avcodec avformat avutil swscale avfilter swresample avresample) if(swresample_FOUND) @@ -60,6 +64,13 @@ install( PATTERN "*.prf" ) +### Install AvTranscoder CMake modules +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/cmake/AvTranscoderConfig.cmake + ${PROJECT_SOURCE_DIR}/cmake/FindAvTranscoder.cmake + DESTINATION "lib/cmake/AvTranscoder" +) + ### Bindings with SWIG if(AVTRANSCODER_DISABLE_BINDINGS) message("Bindings disabled, will not build bindings.") From 054678c7f4ee436222ded828245523fae8de11c7 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Mon, 6 Jun 2016 19:29:27 +0300 Subject: [PATCH 2/4] Set the global header flag if the container format requires it Some containers, e.g. Matroska, requires the headers be written in the global headers section, not in each packet. The encoder should be notified, if that is the case. --- src/AvTranscoder/file/OutputFile.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index ff4944a0..fcb38d07 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -42,6 +42,16 @@ IOutputStream& OutputFile::addVideoStream(const VideoCodec& videoDesc) stream.codec->level = videoDesc.getAVCodecContext().level; stream.codec->field_order = videoDesc.getAVCodecContext().field_order; + if (_formatContext.getAVOutputFormat().flags & AVFMT_GLOBALHEADER) { + stream.codec->flags = CODEC_FLAG_GLOBAL_HEADER; + } + + // if the codec is experimental, allow it + if(videoDesc.getAVCodec().capabilities & CODEC_CAP_EXPERIMENTAL) { + LOG_WARN("This codec is considered experimental by libav/ffmpeg:" << videoDesc.getCodecName()); + stream.codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; + } + // some codecs need/can use extradata to decode uint8_t* srcExtradata = videoDesc.getAVCodecContext().extradata; const int srcExtradataSize = videoDesc.getAVCodecContext().extradata_size; From feed9359c7fd56711409bd1824d38d83938a247a Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Wed, 8 Jun 2016 22:52:21 +0300 Subject: [PATCH 3/4] Implement a bitrate option for the video encoder class You can just pass this option in a codec profile and it will be set up in the codec context correctly. --- src/AvTranscoder/encoder/VideoEncoder.cpp | 25 ++++++++++++++++++++-- src/AvTranscoder/profile/ProfileLoader.hpp | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/encoder/VideoEncoder.cpp b/src/AvTranscoder/encoder/VideoEncoder.cpp index a4dd7424..122970cf 100644 --- a/src/AvTranscoder/encoder/VideoEncoder.cpp +++ b/src/AvTranscoder/encoder/VideoEncoder.cpp @@ -9,6 +9,16 @@ extern "C" { #include #include + +template +bool from_string(T &t, + const std::string &s, + std::ios_base & (*f)(std::ios_base&)) +{ + std::istringstream iss(s); + return !(iss>>f>>t).fail(); +} + namespace avtranscoder { @@ -59,7 +69,7 @@ void VideoEncoder::setupEncoder(const ProfileLoader::Profile& profile) (*it).first == constants::avProfileType || (*it).first == constants::avProfileCodec || (*it).first == constants::avProfileWidth || (*it).first == constants::avProfileHeight || (*it).first == constants::avProfilePixelFormat || (*it).first == constants::avProfileFrameRate || - (*it).first == constants::avProfileThreads) + (*it).first == constants::avProfileThreads || (*it).first == constants::avProfileBitRate) continue; try @@ -80,6 +90,17 @@ void VideoEncoder::setupEncoder(const ProfileLoader::Profile& profile) encoderFlags |= CODEC_FLAG_PSNR; } _codec.getAVCodecContext().flags |= encoderFlags; + + if(profile.count(constants::avProfileBitRate)) { + + int64_t bitRate = 0; + bool bconvert = from_string(bitRate, profile.at(constants::avProfileBitRate), std::dec); + + if (bconvert) { + _codec.getAVCodecContext().bit_rate = bitRate; + } + } + _codec.openCodec(); // after open encoder, set specific encoder options @@ -89,7 +110,7 @@ void VideoEncoder::setupEncoder(const ProfileLoader::Profile& profile) (*it).first == constants::avProfileType || (*it).first == constants::avProfileCodec || (*it).first == constants::avProfileWidth || (*it).first == constants::avProfileHeight || (*it).first == constants::avProfilePixelFormat || (*it).first == constants::avProfileFrameRate || - (*it).first == constants::avProfileThreads) + (*it).first == constants::avProfileThreads || (*it).first == constants::avProfileBitRate) continue; try diff --git a/src/AvTranscoder/profile/ProfileLoader.hpp b/src/AvTranscoder/profile/ProfileLoader.hpp index 6670e69e..13c0debf 100644 --- a/src/AvTranscoder/profile/ProfileLoader.hpp +++ b/src/AvTranscoder/profile/ProfileLoader.hpp @@ -24,6 +24,7 @@ const std::string avProfileCodec = "codec"; const std::string avProfilePixelFormat = "pix_fmt"; const std::string avProfileSampleFormat = "sample_fmt"; const std::string avProfileFrameRate = "r"; +const std::string avProfileBitRate = "bit_rate"; const std::string avProfileWidth = "width"; const std::string avProfileHeight = "height"; const std::string avProfileSampleRate = "ar"; From 5d7ff30b6da64840d4c34a52a926a3994d5c8c3f Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Wed, 8 Jun 2016 22:54:07 +0300 Subject: [PATCH 4/4] Use safe method of setting the flags --- src/AvTranscoder/file/OutputFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index fcb38d07..9e404b4e 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -43,7 +43,7 @@ IOutputStream& OutputFile::addVideoStream(const VideoCodec& videoDesc) stream.codec->field_order = videoDesc.getAVCodecContext().field_order; if (_formatContext.getAVOutputFormat().flags & AVFMT_GLOBALHEADER) { - stream.codec->flags = CODEC_FLAG_GLOBAL_HEADER; + stream.codec->flags |= CODEC_FLAG_GLOBAL_HEADER; } // if the codec is experimental, allow it