From a78c4ae3158142f79048a12b5493b14001845a2e Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Tue, 17 May 2022 10:20:20 +0200 Subject: [PATCH 01/19] Revert "CMake: remove patch version in the avtranscoder library name on Windows" This reverts commit c6744c1aa64af3faf8217e73f3369138a7ebf4e2. # Conflicts: # src/CMakeLists.txt --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0d7fbb9b..b9776da3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,7 @@ target_link_libraries(avtranscoder-static ${FFMPEG_LIBRARIES}) add_library(avtranscoder-shared SHARED ${AVTRANSCODER_SRC_FILES}) set_target_properties(avtranscoder-shared PROPERTIES LINKER_LANGUAGE CXX) if(WIN32) - set_target_properties(avtranscoder-shared PROPERTIES OUTPUT_NAME "avtranscoder-${AVTRANSCODER_VERSION_MAJOR}.${AVTRANSCODER_VERSION_MINOR}") + set_target_properties(avtranscoder-shared PROPERTIES OUTPUT_NAME "avtranscoder-${AVTRANSCODER_VERSION}") else() set_target_properties(avtranscoder-shared PROPERTIES OUTPUT_NAME avtranscoder) endif() @@ -154,7 +154,7 @@ if(SWIG_FOUND) # Create 'avtranscoder-java' shared lib swig_add_module(avtranscoder-java java ${AVTRANSCODER_BINDING_FILE}) if(WIN32) - set_target_properties(avtranscoder-java PROPERTIES OUTPUT_NAME "avtranscoder-java-${AVTRANSCODER_VERSION_MAJOR}.${AVTRANSCODER_VERSION_MINOR}") + set_target_properties(avtranscoder-java PROPERTIES OUTPUT_NAME "avtranscoder-java-${AVTRANSCODER_VERSION}") endif() if(NOT APPLE AND NOT WIN32) set_target_properties(${SWIG_MODULE_avtranscoder-java_REAL_NAME} PROPERTIES SOVERSION ${AVTRANSCODER_VERSION_MAJOR}) From 31947486b3791ea398c44bc781f019852ce3ea68 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Tue, 24 May 2022 16:57:01 +0200 Subject: [PATCH 02/19] Update to fit to FFmpeg 5.0 API --- src/AvTranscoder/Library.cpp | 1 + src/AvTranscoder/codec/ICodec.hpp | 3 +- src/AvTranscoder/data/coded/CodedData.cpp | 2 +- src/AvTranscoder/decoder/AudioDecoder.cpp | 19 ++++-- src/AvTranscoder/decoder/VideoDecoder.cpp | 15 +++- src/AvTranscoder/encoder/AudioEncoder.cpp | 22 +++++- src/AvTranscoder/encoder/VideoEncoder.cpp | 27 +++++++- src/AvTranscoder/file/FormatContext.cpp | 11 ++- src/AvTranscoder/file/FormatContext.hpp | 4 +- src/AvTranscoder/file/OutputFile.cpp | 68 +++++++++---------- src/AvTranscoder/filter/FilterGraph.cpp | 2 +- src/AvTranscoder/log.cpp | 2 +- .../properties/AudioProperties.cpp | 6 +- .../properties/DataProperties.cpp | 3 +- .../properties/FileProperties.cpp | 6 +- .../properties/PixelProperties.cpp | 17 +++-- .../properties/PixelProperties.hpp | 4 ++ .../properties/StreamProperties.cpp | 21 +++--- .../properties/StreamProperties.hpp | 2 +- .../properties/VideoProperties.cpp | 8 +-- src/AvTranscoder/stream/InputStream.cpp | 3 +- src/AvTranscoder/stream/OutputStream.cpp | 37 ++++++++-- src/AvTranscoder/stream/OutputStream.hpp | 1 + src/AvTranscoder/transcoder/Transcoder.cpp | 30 +++++++- 24 files changed, 215 insertions(+), 99 deletions(-) diff --git a/src/AvTranscoder/Library.cpp b/src/AvTranscoder/Library.cpp index 9c5ba23c..aed1f827 100644 --- a/src/AvTranscoder/Library.cpp +++ b/src/AvTranscoder/Library.cpp @@ -11,6 +11,7 @@ extern "C" { #else #include #endif +#include #include #include } diff --git a/src/AvTranscoder/codec/ICodec.hpp b/src/AvTranscoder/codec/ICodec.hpp index de3203dd..8ad135ee 100644 --- a/src/AvTranscoder/codec/ICodec.hpp +++ b/src/AvTranscoder/codec/ICodec.hpp @@ -54,7 +54,6 @@ class AvExport ICodec #ifndef SWIG AVCodecContext& getAVCodecContext() { return *_avCodecContext; } const AVCodecContext& getAVCodecContext() const { return *_avCodecContext; } - AVCodec& getAVCodec() { return *_avCodec; } const AVCodec& getAVCodec() const { return *_avCodec; } #endif @@ -66,7 +65,7 @@ class AvExport ICodec protected: AVCodecContext* _avCodecContext; ///< Full codec instance description (has ownership) - AVCodec* _avCodec; ///< Codec abstract description + const AVCodec* _avCodec; ///< Codec abstract description const bool _isCodecContextAllocated; ///< Is the AVCodecContext allocated by the class ECodecType _type; diff --git a/src/AvTranscoder/data/coded/CodedData.cpp b/src/AvTranscoder/data/coded/CodedData.cpp index 6247a0d6..074a0f83 100644 --- a/src/AvTranscoder/data/coded/CodedData.cpp +++ b/src/AvTranscoder/data/coded/CodedData.cpp @@ -87,7 +87,7 @@ void CodedData::assign(const size_t size, const int value) void CodedData::initAVPacket() { - av_init_packet(&_packet); + _packet = *av_packet_alloc(); _packet.data = NULL; _packet.size = 0; } diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index f1086fcc..1a7a7d99 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -87,7 +87,7 @@ bool AudioDecoder::decodeNextFrame(IFrame& frameBuffer) if(!_isSetup) setupDecoder(); - int got_frame = 0; + bool got_frame = false; while(!got_frame) { CodedData data; @@ -98,18 +98,27 @@ bool AudioDecoder::decodeNextFrame(IFrame& frameBuffer) // decoding // @note could be called several times to return the remaining frames (last call with an empty packet) // @see CODEC_CAP_DELAY - int ret = avcodec_decode_audio4(&_inputStream->getAudioCodec().getAVCodecContext(), &frameBuffer.getAVFrame(), - &got_frame, &data.getAVPacket()); + int ret = avcodec_send_packet(&_inputStream->getAudioCodec().getAVCodecContext(), &data.getAVPacket()); + if(ret < 0) { - throw std::runtime_error("An error occurred during audio decoding: " + getDescriptionFromErrorCode(ret)); + throw std::runtime_error("An error occurred sending audio packet to decoder: " + getDescriptionFromErrorCode(ret)); } + ret = avcodec_receive_frame(&_inputStream->getAudioCodec().getAVCodecContext(), &frameBuffer.getAVFrame()); + + if (ret == 0) + got_frame = true; + else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + got_frame = false; + else + throw std::runtime_error("An error occurred receiving audio packet from decoder: " + getDescriptionFromErrorCode(ret)); + // fixed channel layout value after decoding frameBuffer.getAVFrame().channel_layout = channelLayout; // if no frame could be decompressed - if(!nextPacketRead && ret == 0 && got_frame == 0) + if(!nextPacketRead && got_frame == 0) decodeNextFrame = false; else decodeNextFrame = true; diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index 3c1e1beb..03766ab9 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -94,13 +94,22 @@ bool VideoDecoder::decodeNextFrame(IFrame& frameBuffer) // decoding // @note could be called several times to return the remaining frames (last call with an empty packet) // @see CODEC_CAP_DELAY - const int ret = avcodec_decode_video2(&_inputStream->getVideoCodec().getAVCodecContext(), &frameBuffer.getAVFrame(), - &got_frame, &data.getAVPacket()); + int ret = avcodec_send_packet(&_inputStream->getVideoCodec().getAVCodecContext(), &data.getAVPacket()); + if(ret < 0) { - throw std::runtime_error("An error occurred during video decoding: " + getDescriptionFromErrorCode(ret)); + throw std::runtime_error("An error occurred sending video packet to decoder: " + getDescriptionFromErrorCode(ret)); } + ret = avcodec_receive_frame(&_inputStream->getAudioCodec().getAVCodecContext(), &frameBuffer.getAVFrame()); + + if (ret == 0) + got_frame = true; + else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + got_frame = false; + else + throw std::runtime_error("An error occurred receiving video packet from decoder: " + getDescriptionFromErrorCode(ret)); + // if no frame could be decompressed if(!nextPacketRead && ret == 0 && got_frame == 0) decodeNextFrame = false; diff --git a/src/AvTranscoder/encoder/AudioEncoder.cpp b/src/AvTranscoder/encoder/AudioEncoder.cpp index 0e83c0ed..710bc862 100644 --- a/src/AvTranscoder/encoder/AudioEncoder.cpp +++ b/src/AvTranscoder/encoder/AudioEncoder.cpp @@ -7,6 +7,7 @@ extern "C" { } #include +#include namespace avtranscoder { @@ -93,8 +94,6 @@ void AudioEncoder::setupEncoder(const ProfileLoader::Profile& profile) bool AudioEncoder::encodeFrame(const IFrame& sourceFrame, CodedData& codedFrame) { - AVCodecContext& avCodecContext = _codec.getAVCodecContext(); - AVPacket& packet = codedFrame.getAVPacket(); const AVFrame& srcAvFrame = sourceFrame.getAVFrame(); if(srcAvFrame.pts != (int)AV_NOPTS_VALUE) @@ -121,7 +120,24 @@ bool AudioEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData) encodedData.data = NULL; AVCodecContext& avCodecContext = _codec.getAVCodecContext(); -#if LIBAVCODEC_VERSION_MAJOR > 53 +#if LIBAVCODEC_VERSION_MAJOR > 58 + int ret = avcodec_send_frame(&avCodecContext, decodedData); + if(ret != 0) + { + throw std::runtime_error("Error sending audio frame to encoder: " + getDescriptionFromErrorCode(ret)); + } + + ret = avcodec_receive_packet(&avCodecContext, &encodedData); + + if (ret == 0) + return true; + + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return false; + + throw std::runtime_error("Error receiving audio frame from encoder: " + getDescriptionFromErrorCode(ret)); + +#elif LIBAVCODEC_VERSION_MAJOR > 53 int gotPacket = 0; const int ret = avcodec_encode_audio2(&avCodecContext, &encodedData, decodedData, &gotPacket); if(ret != 0) diff --git a/src/AvTranscoder/encoder/VideoEncoder.cpp b/src/AvTranscoder/encoder/VideoEncoder.cpp index 7d878d6a..e21aea63 100644 --- a/src/AvTranscoder/encoder/VideoEncoder.cpp +++ b/src/AvTranscoder/encoder/VideoEncoder.cpp @@ -110,8 +110,6 @@ void VideoEncoder::setupEncoder(const ProfileLoader::Profile& profile) bool VideoEncoder::encodeFrame(const IFrame& sourceFrame, CodedData& codedFrame) { - AVCodecContext& avCodecContext = _codec.getAVCodecContext(); - AVPacket& packet = codedFrame.getAVPacket(); const AVFrame& srcAvFrame = sourceFrame.getAVFrame(); if(srcAvFrame.pts != (int)AV_NOPTS_VALUE) @@ -138,7 +136,29 @@ bool VideoEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData) encodedData.data = NULL; AVCodecContext& avCodecContext = _codec.getAVCodecContext(); -#if LIBAVCODEC_VERSION_MAJOR > 53 +#if LIBAVCODEC_VERSION_MAJOR > 58 + int ret = avcodec_send_frame(&avCodecContext, decodedData); + if(ret != 0) + { + throw std::runtime_error("Error sending video frame to encoder: " + getDescriptionFromErrorCode(ret)); + } + + ret = avcodec_receive_packet(&avCodecContext, &encodedData); + + if (ret == 0) + { + return true; + } + else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + { + return false; + } + else + { + throw std::runtime_error("Error receiving video frame from encoder: " + getDescriptionFromErrorCode(ret)); + } + +#elif LIBAVCODEC_VERSION_MAJOR > 53 int gotPacket = 0; const int ret = avcodec_encode_video2(&avCodecContext, &encodedData, decodedData, &gotPacket); if(ret != 0) @@ -146,6 +166,7 @@ bool VideoEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData) throw std::runtime_error("Encode video frame error: avcodec encode video frame - " + getDescriptionFromErrorCode(ret)); } + return gotPacket == 1; #else const int ret = avcodec_encode_video(&avCodecContext, encodedData.data, encodedData.size, decodedData); diff --git a/src/AvTranscoder/file/FormatContext.cpp b/src/AvTranscoder/file/FormatContext.cpp index 51d78f4e..cd423e85 100644 --- a/src/AvTranscoder/file/FormatContext.cpp +++ b/src/AvTranscoder/file/FormatContext.cpp @@ -46,10 +46,6 @@ FormatContext::~FormatContext() if(!_avFormatContext) return; - // free the streams added - for(std::vector::iterator it = _avStreamAllocated.begin(); it != _avStreamAllocated.end(); ++it) - avcodec_close((*it)->codec); - // free the format context if(_isOpen) avformat_close_input(&_avFormatContext); @@ -151,7 +147,7 @@ AVStream& FormatContext::addAVStream(const AVCodec& avCodec) bool FormatContext::seek(const uint64_t position, const int flag) { - LOG_INFO("Seek in '" << _avFormatContext->filename << "' at " << position << " with flag '" << flag << "'") + LOG_INFO("Seek in '" << _avFormatContext->url << "' at " << position << " with flag '" << flag << "'") const int err = av_seek_frame(_avFormatContext, -1, position, flag); if(err < 0) { @@ -186,12 +182,13 @@ AVStream& FormatContext::getAVStream(size_t index) const void FormatContext::setFilename(const std::string& filename) { - strcpy(&_avFormatContext->filename[0], filename.c_str()); + _avFormatContext->url = (char*)av_malloc(filename.size()); + strcpy(_avFormatContext->url, filename.c_str()); } void FormatContext::setOutputFormat(const std::string& filename, const std::string& shortName, const std::string& mimeType) { - AVOutputFormat* oformat = av_guess_format(shortName.c_str(), filename.c_str(), mimeType.c_str()); + const AVOutputFormat* oformat = av_guess_format(shortName.c_str(), filename.c_str(), mimeType.c_str()); if(!oformat) { std::string msg("Unable to find format for "); diff --git a/src/AvTranscoder/file/FormatContext.hpp b/src/AvTranscoder/file/FormatContext.hpp index 0a33bbe1..b4283e19 100644 --- a/src/AvTranscoder/file/FormatContext.hpp +++ b/src/AvTranscoder/file/FormatContext.hpp @@ -113,8 +113,8 @@ class AvExport FormatContext #ifndef SWIG AVFormatContext& getAVFormatContext() const { return *_avFormatContext; } - AVOutputFormat& getAVOutputFormat() const { return *_avFormatContext->oformat; } - AVInputFormat& getAVInputFormat() const { return *_avFormatContext->iformat; } + const AVOutputFormat& getAVOutputFormat() const { return *_avFormatContext->oformat; } + const AVInputFormat& getAVInputFormat() const { return *_avFormatContext->iformat; } AVIOContext& getAVIOContext() const { return *_avFormatContext->pb; } AVDictionary& getAVMetaData() const { return *_avFormatContext->metadata; } AVStream& getAVStream(size_t index) const; diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index d446b431..142069e7 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -3,6 +3,7 @@ #include #include +#include #ifndef FF_INPUT_BUFFER_PADDING_SIZE #define FF_INPUT_BUFFER_PADDING_SIZE 16 @@ -35,31 +36,29 @@ IOutputStream& OutputFile::addVideoStream(const VideoCodec& videoDesc) { AVStream& stream = _formatContext.addAVStream(videoDesc.getAVCodec()); - stream.codec->width = videoDesc.getAVCodecContext().width; - stream.codec->height = videoDesc.getAVCodecContext().height; - stream.codec->bit_rate = videoDesc.getAVCodecContext().bit_rate; - stream.codec->pix_fmt = videoDesc.getAVCodecContext().pix_fmt; - stream.codec->profile = videoDesc.getAVCodecContext().profile; - stream.codec->level = videoDesc.getAVCodecContext().level; - stream.codec->field_order = videoDesc.getAVCodecContext().field_order; + stream.codecpar->width = videoDesc.getAVCodecContext().width; + stream.codecpar->height = videoDesc.getAVCodecContext().height; + stream.codecpar->bit_rate = videoDesc.getAVCodecContext().bit_rate; + stream.codecpar->format = videoDesc.getAVCodecContext().pix_fmt; + stream.codecpar->profile = videoDesc.getAVCodecContext().profile; + stream.codecpar->level = videoDesc.getAVCodecContext().level; + stream.codecpar->field_order = videoDesc.getAVCodecContext().field_order; - stream.codec->colorspace = videoDesc.getAVCodecContext().colorspace; - stream.codec->color_primaries = videoDesc.getAVCodecContext().color_primaries; - stream.codec->color_range = videoDesc.getAVCodecContext().color_range; - stream.codec->color_trc = videoDesc.getAVCodecContext().color_trc; - stream.codec->chroma_sample_location = videoDesc.getAVCodecContext().chroma_sample_location; + stream.codecpar->color_space = videoDesc.getAVCodecContext().colorspace; + stream.codecpar->color_primaries = videoDesc.getAVCodecContext().color_primaries; + stream.codecpar->color_range = videoDesc.getAVCodecContext().color_range; + stream.codecpar->color_trc = videoDesc.getAVCodecContext().color_trc; + stream.codecpar->chroma_location = videoDesc.getAVCodecContext().chroma_sample_location; setOutputStream(stream, videoDesc); // need to set the time_base on the AVCodecContext and the AVStream // compensating the frame rate with the ticks_per_frame and keeping // a coherent reading speed. - av_reduce(&stream.codec->time_base.num, &stream.codec->time_base.den, + av_reduce(&stream.time_base.num, &stream.time_base.den, videoDesc.getAVCodecContext().time_base.num * videoDesc.getAVCodecContext().ticks_per_frame, videoDesc.getAVCodecContext().time_base.den, INT_MAX); - stream.time_base = stream.codec->time_base; - OutputStream* outputStream = new OutputStream(*this, _formatContext.getNbStreams() - 1); _outputStreams.push_back(outputStream); @@ -70,16 +69,16 @@ IOutputStream& OutputFile::addAudioStream(const AudioCodec& audioDesc) { AVStream& stream = _formatContext.addAVStream(audioDesc.getAVCodec()); - 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; + stream.codecpar->sample_rate = audioDesc.getAVCodecContext().sample_rate; + stream.codecpar->channels = audioDesc.getAVCodecContext().channels; + stream.codecpar->channel_layout = audioDesc.getAVCodecContext().channel_layout; + stream.codecpar->format = audioDesc.getAVCodecContext().sample_fmt; + stream.codecpar->frame_size = audioDesc.getAVCodecContext().frame_size; setOutputStream(stream, audioDesc); // need to set the time_base on the AVCodecContext of the AVStream - av_reduce(&stream.codec->time_base.num, &stream.codec->time_base.den, audioDesc.getAVCodecContext().time_base.num, + av_reduce(&stream.time_base.num, &stream.time_base.den, audioDesc.getAVCodecContext().time_base.num, audioDesc.getAVCodecContext().time_base.den, INT_MAX); OutputStream* outputStream = new OutputStream(*this, _formatContext.getNbStreams() - 1); @@ -92,14 +91,14 @@ IOutputStream& OutputFile::addCustomStream(const ICodec& iCodecDesc) { AVStream& stream = _formatContext.addAVStream(iCodecDesc.getAVCodec()); - stream.codec->sample_rate = 48000; - stream.codec->channels = 1; - stream.codec->channel_layout = AV_CH_LAYOUT_MONO; - stream.codec->sample_fmt = AV_SAMPLE_FMT_S32; - stream.codec->frame_size = 1920; + stream.codecpar->sample_rate = 48000; + stream.codecpar->channels = 1; + stream.codecpar->channel_layout = AV_CH_LAYOUT_MONO; + stream.codecpar->format = AV_SAMPLE_FMT_S32; + stream.codecpar->frame_size = 1920; // need to set the time_base on the AVCodecContext of the AVStream - av_reduce(&stream.codec->time_base.num, &stream.codec->time_base.den, 1, 1, INT_MAX); + av_reduce(&stream.time_base.num, &stream.time_base.den, 1, 1, INT_MAX); OutputStream* outputStream = new OutputStream(*this, _formatContext.getNbStreams() - 1); _outputStreams.push_back(outputStream); @@ -136,7 +135,7 @@ IOutputStream& OutputFile::getStream(const size_t streamIndex) std::string OutputFile::getFilename() const { - return std::string(_formatContext.getAVFormatContext().filename); + return std::string(_formatContext.getAVFormatContext().url); } std::string OutputFile::getFormatName() const @@ -194,8 +193,7 @@ IOutputStream::EWrappingStatus OutputFile::wrap(const CodedData& data, const siz << _frameCount.at(streamIndex) << ")") // Packet to wrap - AVPacket packet; - av_init_packet(&packet); + AVPacket packet = *av_packet_alloc(); packet.stream_index = streamIndex; packet.data = (uint8_t*)data.getData(); packet.size = data.getSize(); @@ -348,6 +346,7 @@ void OutputFile::setupRemainingWrappingOptions() void OutputFile::setOutputStream(AVStream& avStream, const ICodec& codec) { +#if LIBAVCODEC_VERSION_MAJOR < 59 // depending on the format, place global headers in extradata instead of every keyframe if(_formatContext.getAVOutputFormat().flags & AVFMT_GLOBALHEADER) { @@ -368,13 +367,14 @@ void OutputFile::setOutputStream(AVStream& avStream, const ICodec& codec) LOG_WARN("This codec is considered experimental by libav/ffmpeg:" << codec.getCodecName()); avStream.codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; } +#endif // some codecs need/can use extradata to decode uint8_t* srcExtradata = codec.getAVCodecContext().extradata; const int srcExtradataSize = codec.getAVCodecContext().extradata_size; - avStream.codec->extradata = (uint8_t*)av_malloc(srcExtradataSize + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(avStream.codec->extradata, srcExtradata, srcExtradataSize); - memset(((uint8_t*)avStream.codec->extradata) + srcExtradataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE); - avStream.codec->extradata_size = codec.getAVCodecContext().extradata_size; + avStream.codecpar->extradata = (uint8_t*)av_malloc(srcExtradataSize + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(avStream.codecpar->extradata, srcExtradata, srcExtradataSize); + memset(((uint8_t*)avStream.codecpar->extradata) + srcExtradataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE); + avStream.codecpar->extradata_size = codec.getAVCodecContext().extradata_size; } } diff --git a/src/AvTranscoder/filter/FilterGraph.cpp b/src/AvTranscoder/filter/FilterGraph.cpp index 8b960ef9..57b6ce2f 100644 --- a/src/AvTranscoder/filter/FilterGraph.cpp +++ b/src/AvTranscoder/filter/FilterGraph.cpp @@ -211,7 +211,7 @@ bool FilterGraph::areInputFrameSizesEqual(const std::vector& inputs) if(!inputs.size() || inputs.size() == 1) return true; - const int frameSize = inputs.at(0)->getDataSize(); + size_t frameSize = inputs.at(0)->getDataSize(); for(size_t index = 1; index < inputs.size(); ++index) { if(frameSize != inputs.at(index)->getDataSize()) diff --git a/src/AvTranscoder/log.cpp b/src/AvTranscoder/log.cpp index 5eab4325..98ffd649 100644 --- a/src/AvTranscoder/log.cpp +++ b/src/AvTranscoder/log.cpp @@ -56,7 +56,7 @@ void Logger::log(const int level, const std::string& msg) logMessage += "\n"; // send message - av_log(NULL, level, logMessage.c_str()); + av_log(NULL, level, "%s", logMessage.c_str()); } void Logger::logInFile() diff --git a/src/AvTranscoder/properties/AudioProperties.cpp b/src/AvTranscoder/properties/AudioProperties.cpp index cf5793ef..327edc24 100644 --- a/src/AvTranscoder/properties/AudioProperties.cpp +++ b/src/AvTranscoder/properties/AudioProperties.cpp @@ -47,6 +47,8 @@ std::string AudioProperties::getSampleFormatLongName() const return "signed 16 bits"; case AV_SAMPLE_FMT_S32: return "signed 32 bits"; + case AV_SAMPLE_FMT_S64: + return "signed 64 bits"; case AV_SAMPLE_FMT_FLT: return "float"; case AV_SAMPLE_FMT_DBL: @@ -57,6 +59,8 @@ std::string AudioProperties::getSampleFormatLongName() const return "signed 16 bits, planar"; case AV_SAMPLE_FMT_S32P: return "signed 32 bits, planar"; + case AV_SAMPLE_FMT_S64P: + return "signed 64 bits, planar"; case AV_SAMPLE_FMT_FLTP: return "float, planar"; case AV_SAMPLE_FMT_DBLP: @@ -113,7 +117,7 @@ size_t AudioProperties::getBitRate() const if(_codecContext->bit_rate) return _codecContext->bit_rate; - LOG_WARN("The bitrate of the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.") + LOG_WARN("The bitrate of the stream '" << _streamIndex << "' of file '" << _formatContext->url << "' is unknown.") LOG_INFO("Compute the audio bitrate (suppose PCM audio data).") const int bitsPerSample = av_get_bits_per_sample(_codecContext->codec_id); // 0 if unknown for the given codec diff --git a/src/AvTranscoder/properties/DataProperties.cpp b/src/AvTranscoder/properties/DataProperties.cpp index af92b09a..f81a19c3 100644 --- a/src/AvTranscoder/properties/DataProperties.cpp +++ b/src/AvTranscoder/properties/DataProperties.cpp @@ -13,8 +13,7 @@ namespace avtranscoder void DataProperties::detectAncillaryData() { - AVPacket pkt; - av_init_packet(&pkt); + AVPacket pkt = *av_packet_alloc(); bool detection = false; diff --git a/src/AvTranscoder/properties/FileProperties.cpp b/src/AvTranscoder/properties/FileProperties.cpp index 6c135a7b..207850ac 100644 --- a/src/AvTranscoder/properties/FileProperties.cpp +++ b/src/AvTranscoder/properties/FileProperties.cpp @@ -47,7 +47,7 @@ void FileProperties::extractStreamProperties(IProgress& progress, const EAnalyse // reload properties for(size_t streamIndex = 0; streamIndex < _formatContext->getNbStreams(); ++streamIndex) { - switch(_formatContext->getAVStream(streamIndex).codec->codec_type) + switch(_formatContext->getAVStream(streamIndex).codecpar->codec_type) { case AVMEDIA_TYPE_VIDEO: { @@ -139,9 +139,9 @@ void FileProperties::extractStreamProperties(IProgress& progress, const EAnalyse std::string FileProperties::getFilename() const { - if(!_avFormatContext || !_avFormatContext->filename) + if(!_avFormatContext || !_avFormatContext->url) throw std::runtime_error("unknown file name"); - return _avFormatContext->filename; + return _avFormatContext->url; } std::string FileProperties::getFormatName() const diff --git a/src/AvTranscoder/properties/PixelProperties.cpp b/src/AvTranscoder/properties/PixelProperties.cpp index 9e58b298..48961d0a 100644 --- a/src/AvTranscoder/properties/PixelProperties.cpp +++ b/src/AvTranscoder/properties/PixelProperties.cpp @@ -204,12 +204,17 @@ bool PixelProperties::isRgbPixelData() const return (_pixelDesc->flags & AV_PIX_FMT_FLAG_RGB) == AV_PIX_FMT_FLAG_RGB; } -bool PixelProperties::isPseudoPaletted() const -{ - if(!_pixelDesc) +#if LIBAVCODEC_VERSION_MAJOR > 58 +bool PixelProperties::isPaletted() const { + if (!_pixelDesc) + throw std::runtime_error("unable to find pixel description."); + + return (_pixelDesc->flags & AV_PIX_FMT_FLAG_PAL) == AV_PIX_FMT_FLAG_PAL; +#elif LIBAVCODEC_VERSION_MAJOR > 53 +bool PixelProperties::isPseudoPaletted() const { + if (!_pixelDesc) throw std::runtime_error("unable to find pixel description."); -#if LIBAVCODEC_VERSION_MAJOR > 53 return (_pixelDesc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) == AV_PIX_FMT_FLAG_PSEUDOPAL; #else return false; @@ -315,7 +320,11 @@ PropertyVector& PixelProperties::fillVector(PropertyVector& data) const addProperty(data, "bitWiseAcked", &PixelProperties::isBitWisePacked); addProperty(data, "isHardwareAccelerated", &PixelProperties::isHardwareAccelerated); addProperty(data, "rgbPixel", &PixelProperties::isRgbPixelData); +#if LIBAVCODEC_VERSION_MAJOR > 58 + addProperty(data, "isPaletted", &PixelProperties::isPaletted); +#else addProperty(data, "isPseudoPaletted", &PixelProperties::isPseudoPaletted); +#endif try { diff --git a/src/AvTranscoder/properties/PixelProperties.hpp b/src/AvTranscoder/properties/PixelProperties.hpp index 5e087ef2..b5ba672c 100644 --- a/src/AvTranscoder/properties/PixelProperties.hpp +++ b/src/AvTranscoder/properties/PixelProperties.hpp @@ -71,7 +71,11 @@ class AvExport PixelProperties bool isBitWisePacked() const; bool isHardwareAccelerated() const; bool isRgbPixelData() const; +#if LIBAVCODEC_VERSION_MAJOR > 58 + bool isPaletted() const; +#else bool isPseudoPaletted() const; +#endif std::vector getChannels() const; diff --git a/src/AvTranscoder/properties/StreamProperties.cpp b/src/AvTranscoder/properties/StreamProperties.cpp index 2a860aeb..ced1b01a 100644 --- a/src/AvTranscoder/properties/StreamProperties.cpp +++ b/src/AvTranscoder/properties/StreamProperties.cpp @@ -27,19 +27,18 @@ StreamProperties::StreamProperties(const FileProperties& fileProperties, const s ss << "Stream at index " << _streamIndex << " does not exist."; throw std::runtime_error(ss.str()); } - _codecContext = _formatContext->streams[_streamIndex]->codec; + + _codec = avcodec_find_decoder(_formatContext->streams[_streamIndex]->codecpar->codec_id); + _codecContext = avcodec_alloc_context3(_codec); + + avcodec_parameters_to_context(_codecContext, _formatContext->streams[_streamIndex]->codecpar); } // find the decoder - if(_formatContext && _codecContext) + if(_formatContext && _codecContext && _codec) { - _codec = avcodec_find_decoder(_codecContext->codec_id); - - if(_codec) - { - // load specific options of the codec - loadOptions(_options, _codecContext); - } + // load specific options of the codec + loadOptions(_options, _codecContext); } } @@ -67,7 +66,7 @@ float StreamProperties::getDuration() const const size_t duration = _formatContext->streams[_streamIndex]->duration; if(duration == (size_t)AV_NOPTS_VALUE) { - LOG_WARN("The duration of the stream '" << _streamIndex << "' of file '" << _formatContext->filename + LOG_WARN("The duration of the stream '" << _streamIndex << "' of file '" << _formatContext->url << "' is unknown.") return 0; } @@ -78,7 +77,7 @@ AVMediaType StreamProperties::getStreamType() const { if(!_formatContext) throw std::runtime_error("unknown format context"); - return _formatContext->streams[_streamIndex]->codec->codec_type; + return _formatContext->streams[_streamIndex]->codecpar->codec_type; } size_t StreamProperties::getCodecId() const diff --git a/src/AvTranscoder/properties/StreamProperties.hpp b/src/AvTranscoder/properties/StreamProperties.hpp index 2820119b..fca5ffab 100644 --- a/src/AvTranscoder/properties/StreamProperties.hpp +++ b/src/AvTranscoder/properties/StreamProperties.hpp @@ -71,7 +71,7 @@ class AvExport StreamProperties const FileProperties* _fileProperties; ///< Has link (no ownership) const AVFormatContext* _formatContext; ///< Has link (no ownership) AVCodecContext* _codecContext; ///< Has link (no ownership) - AVCodec* _codec; ///< Has link (no ownership) + const AVCodec* _codec; ///< Has link (no ownership) size_t _streamIndex; PropertyVector _metadatas; diff --git a/src/AvTranscoder/properties/VideoProperties.cpp b/src/AvTranscoder/properties/VideoProperties.cpp index da9f5f39..e2ab5bbd 100644 --- a/src/AvTranscoder/properties/VideoProperties.cpp +++ b/src/AvTranscoder/properties/VideoProperties.cpp @@ -35,7 +35,7 @@ VideoProperties::VideoProperties(const FileProperties& fileProperties, const siz if(_codecContext) { _pixelProperties = PixelProperties(_codecContext->pix_fmt); - _firstGopTimeCode = _codecContext->timecode_frame_start; + _firstGopTimeCode = _formatContext->start_time; } switch(_levelAnalysis) @@ -350,7 +350,7 @@ size_t VideoProperties::getBitRate() const // return bit rate of stream if present or VBR mode if(_codecContext->bit_rate || _codecContext->rc_max_rate) return _codecContext->bit_rate; - LOG_WARN("The bitrate of the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.") + LOG_WARN("The bitrate of the stream '" << _streamIndex << "' of file '" << _formatContext->url << "' is unknown.") if(_levelAnalysis == eAnalyseLevelHeader) { @@ -389,7 +389,7 @@ size_t VideoProperties::getNbFrames() const const size_t nbFrames = _formatContext->streams[_streamIndex]->nb_frames; if(nbFrames) return nbFrames; - LOG_WARN("The number of frames of the stream '" << _streamIndex << "' of file '" << _formatContext->filename + LOG_WARN("The number of frames of the stream '" << _streamIndex << "' of file '" << _formatContext->url << "' is unknown.") if(_levelAnalysis == eAnalyseLevelHeader) @@ -472,7 +472,7 @@ float VideoProperties::getDuration() const const float duration = StreamProperties::getDuration(); if(duration != 0) return duration; - LOG_WARN("The duration of the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.") + LOG_WARN("The duration of the stream '" << _streamIndex << "' of file '" << _formatContext->url << "' is unknown.") if(_levelAnalysis == eAnalyseLevelHeader) { diff --git a/src/AvTranscoder/stream/InputStream.cpp b/src/AvTranscoder/stream/InputStream.cpp index ece61cc3..b2417e8d 100644 --- a/src/AvTranscoder/stream/InputStream.cpp +++ b/src/AvTranscoder/stream/InputStream.cpp @@ -21,7 +21,8 @@ InputStream::InputStream(InputFile& inputFile, const size_t streamIndex) , _streamIndex(streamIndex) , _isActivated(false) { - AVCodecContext* context = _inputFile->getFormatContext().getAVStream(_streamIndex).codec; + const AVCodec* codec = avcodec_find_encoder(_inputFile->getFormatContext().getAVStream(_streamIndex).codecpar->codec_id); + AVCodecContext* context = avcodec_alloc_context3(codec); switch(context->codec_type) { diff --git a/src/AvTranscoder/stream/OutputStream.cpp b/src/AvTranscoder/stream/OutputStream.cpp index 0c47d004..ea6ece68 100644 --- a/src/AvTranscoder/stream/OutputStream.cpp +++ b/src/AvTranscoder/stream/OutputStream.cpp @@ -11,11 +11,35 @@ OutputStream::OutputStream(OutputFile& outputFile, const size_t streamIndex) : IOutputStream() , _outputFile(outputFile) , _outputAVStream(outputFile.getFormatContext().getAVStream(streamIndex)) + , _codecContext() , _streamIndex(streamIndex) , _wrappedPacketsDuration(0) , _lastWrappedPacketDuration(0) , _isPTSGenerated(false) { + const AVCodec* codec = avcodec_find_decoder(_outputAVStream.codecpar->codec_id); + _codecContext = avcodec_alloc_context3(codec); + + avcodec_parameters_to_context(_codecContext, _outputAVStream.codecpar); + +#if LIBAVCODEC_VERSION_MAJOR > 58 + // depending on the format, place global headers in extradata instead of every keyframe +#ifdef AV_CODEC_FLAG_GLOBAL_HEADER + if(_outputFile.getFormatContext().getAVOutputFormat().flags & AVFMT_GLOBALHEADER) + { + _codecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + } +#endif + + // if the codec is experimental, allow it +#ifdef AV_CODEC_CAP_EXPERIMENTAL + if(codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) + { + LOG_WARN("This codec is considered experimental by libav/ffmpeg:" << codec->name); + _codecContext->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; + } +#endif +#endif } float OutputStream::getStreamDuration() const @@ -73,7 +97,7 @@ IOutputStream::EWrappingStatus OutputStream::wrap(const CodedData& data) _wrappedPacketsDuration += data.getAVPacket().duration; else { - switch(_outputAVStream.codec->codec_type) + switch(_outputAVStream.codecpar->codec_type) { case AVMEDIA_TYPE_VIDEO: { @@ -85,14 +109,13 @@ IOutputStream::EWrappingStatus OutputStream::wrap(const CodedData& data) Rational audioPacketDuration; audioPacketDuration.num = 0; audioPacketDuration.den = 0; - const int frame_size = av_get_audio_frame_duration(_outputAVStream.codec, data.getSize()); - if(frame_size <= 0 || _outputAVStream.codec->sample_rate <= 0) + const int frame_size = av_get_audio_frame_duration(_codecContext, data.getSize()); + if (frame_size <= 0 || _outputAVStream.codecpar->sample_rate <= 0) break; audioPacketDuration.num = frame_size; - audioPacketDuration.den = _outputAVStream.codec->sample_rate; - _wrappedPacketsDuration += av_rescale(1, audioPacketDuration.num * (int64_t)_outputAVStream.time_base.den * - _outputAVStream.codec->ticks_per_frame, - audioPacketDuration.den * (int64_t)_outputAVStream.time_base.num); + audioPacketDuration.den = _outputAVStream.codecpar->sample_rate; + _wrappedPacketsDuration += av_rescale(1, audioPacketDuration.num * (int64_t) _outputAVStream.time_base.den * _codecContext->ticks_per_frame, + audioPacketDuration.den * (int64_t) _outputAVStream.time_base.num); break; } default: diff --git a/src/AvTranscoder/stream/OutputStream.hpp b/src/AvTranscoder/stream/OutputStream.hpp index 4b2b3a48..b896edb7 100644 --- a/src/AvTranscoder/stream/OutputStream.hpp +++ b/src/AvTranscoder/stream/OutputStream.hpp @@ -26,6 +26,7 @@ class AvExport OutputStream : public IOutputStream private: OutputFile& _outputFile; ///< Has link (no ownership) const AVStream& _outputAVStream; ///< Has link (no ownership) + AVCodecContext* _codecContext; size_t _streamIndex; ///< Index of the stream in the output file diff --git a/src/AvTranscoder/transcoder/Transcoder.cpp b/src/AvTranscoder/transcoder/Transcoder.cpp index eb9895ed..0d578fff 100644 --- a/src/AvTranscoder/transcoder/Transcoder.cpp +++ b/src/AvTranscoder/transcoder/Transcoder.cpp @@ -217,6 +217,8 @@ bool Transcoder::processFrame(IProgress& progress, const size_t& streamIndex) LOG_INFO("End of process because the main stream at index " << _mainStreamIndex << " failed to process a new frame.") return false; + default: + throw std::runtime_error("Unsupported wrapping status"); } } @@ -658,13 +660,35 @@ void Transcoder::fillProcessStat(ProcessStat& processStat) const AVCodecContext& encoderContext = encoder->getCodec().getAVCodecContext(); #ifdef AV_CODEC_FLAG_PSNR - if(encoderContext.coded_frame && (encoderContext.flags & AV_CODEC_FLAG_PSNR)) + if(encoderContext.coded_side_data && encoderContext.coded_side_data->type == AV_PKT_DATA_QUALITY_FACTOR && (encoderContext.flags & AV_CODEC_FLAG_PSNR)) #else if(encoderContext.coded_frame && (encoderContext.flags & CODEC_FLAG_PSNR)) #endif { - videoStat.setQuality(encoderContext.coded_frame->quality); - videoStat.setPSNR(encoderContext.coded_frame->error[0] / + uint8_t* coded_frame = encoderContext.coded_side_data->data; + uint32_t quality = (uint32_t) coded_frame[3] << 24 | + (uint32_t) coded_frame[2] << 16 | + (uint32_t) coded_frame[1] << 8 | + (uint32_t) coded_frame[0]; + // uint8_t picture_type = coded_frame[4]; + uint8_t error_count = coded_frame[5]; + + uint64_t errors[error_count]; + for (int i = 0; i < error_count; ++i) + { + int index = 6 + i; + errors[i] = (uint64_t) coded_frame[index + 7] << 56 | + (uint64_t) coded_frame[index + 6] << 48 | + (uint64_t) coded_frame[index + 5] << 40 | + (uint64_t) coded_frame[index + 4] << 32 | + (uint64_t) coded_frame[index + 3] << 24 | + (uint64_t) coded_frame[2] << 16 | + (uint64_t) coded_frame[1] << 8 | + (uint64_t) coded_frame[0]; + } + + videoStat.setQuality(quality); + videoStat.setPSNR((double) errors[0] / (encoderContext.width * encoderContext.height * 255.0 * 255.0)); } } From 0f4a0662f7ba509c43306b6011e12ab8aca21769 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Tue, 24 May 2022 18:09:12 +0200 Subject: [PATCH 03/19] Fix encoding/decoding and codec context --- src/AvTranscoder/decoder/VideoDecoder.cpp | 8 +++----- src/AvTranscoder/encoder/AudioEncoder.cpp | 3 +-- src/AvTranscoder/encoder/VideoEncoder.cpp | 18 ++++++------------ src/AvTranscoder/file/OutputFile.cpp | 12 ++++++++++++ src/AvTranscoder/stream/InputStream.cpp | 7 ++++++- src/AvTranscoder/stream/OutputStream.cpp | 6 ++++-- 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index 03766ab9..447913be 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -96,12 +96,10 @@ bool VideoDecoder::decodeNextFrame(IFrame& frameBuffer) // @see CODEC_CAP_DELAY int ret = avcodec_send_packet(&_inputStream->getVideoCodec().getAVCodecContext(), &data.getAVPacket()); - if(ret < 0) - { + if (ret < 0 && (nextPacketRead || ret != AVERROR_EOF)) throw std::runtime_error("An error occurred sending video packet to decoder: " + getDescriptionFromErrorCode(ret)); - } - ret = avcodec_receive_frame(&_inputStream->getAudioCodec().getAVCodecContext(), &frameBuffer.getAVFrame()); + ret = avcodec_receive_frame(&_inputStream->getVideoCodec().getAVCodecContext(), &frameBuffer.getAVFrame()); if (ret == 0) got_frame = true; @@ -111,7 +109,7 @@ bool VideoDecoder::decodeNextFrame(IFrame& frameBuffer) throw std::runtime_error("An error occurred receiving video packet from decoder: " + getDescriptionFromErrorCode(ret)); // if no frame could be decompressed - if(!nextPacketRead && ret == 0 && got_frame == 0) + if ((!nextPacketRead && ret == 0) || !got_frame) decodeNextFrame = false; else decodeNextFrame = true; diff --git a/src/AvTranscoder/encoder/AudioEncoder.cpp b/src/AvTranscoder/encoder/AudioEncoder.cpp index 710bc862..0b0621d6 100644 --- a/src/AvTranscoder/encoder/AudioEncoder.cpp +++ b/src/AvTranscoder/encoder/AudioEncoder.cpp @@ -122,10 +122,9 @@ bool AudioEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData) AVCodecContext& avCodecContext = _codec.getAVCodecContext(); #if LIBAVCODEC_VERSION_MAJOR > 58 int ret = avcodec_send_frame(&avCodecContext, decodedData); + if(ret != 0) - { throw std::runtime_error("Error sending audio frame to encoder: " + getDescriptionFromErrorCode(ret)); - } ret = avcodec_receive_packet(&avCodecContext, &encodedData); diff --git a/src/AvTranscoder/encoder/VideoEncoder.cpp b/src/AvTranscoder/encoder/VideoEncoder.cpp index e21aea63..d8662ff8 100644 --- a/src/AvTranscoder/encoder/VideoEncoder.cpp +++ b/src/AvTranscoder/encoder/VideoEncoder.cpp @@ -138,25 +138,19 @@ bool VideoEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData) AVCodecContext& avCodecContext = _codec.getAVCodecContext(); #if LIBAVCODEC_VERSION_MAJOR > 58 int ret = avcodec_send_frame(&avCodecContext, decodedData); - if(ret != 0) - { + + if (ret != 0 && ret != AVERROR_EOF) throw std::runtime_error("Error sending video frame to encoder: " + getDescriptionFromErrorCode(ret)); - } ret = avcodec_receive_packet(&avCodecContext, &encodedData); if (ret == 0) - { return true; - } - else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) - { + + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) return false; - } - else - { - throw std::runtime_error("Error receiving video frame from encoder: " + getDescriptionFromErrorCode(ret)); - } + + throw std::runtime_error("Error receiving video frame from encoder: " + getDescriptionFromErrorCode(ret)); #elif LIBAVCODEC_VERSION_MAJOR > 53 int gotPacket = 0; diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index 142069e7..49711abc 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -36,6 +36,10 @@ IOutputStream& OutputFile::addVideoStream(const VideoCodec& videoDesc) { AVStream& stream = _formatContext.addAVStream(videoDesc.getAVCodec()); + stream.codecpar->codec_type = videoDesc.getAVCodecContext().codec_type; + stream.codecpar->codec_id = videoDesc.getAVCodecContext().codec_id; + stream.codecpar->codec_tag = videoDesc.getAVCodecContext().codec_tag; + stream.codecpar->width = videoDesc.getAVCodecContext().width; stream.codecpar->height = videoDesc.getAVCodecContext().height; stream.codecpar->bit_rate = videoDesc.getAVCodecContext().bit_rate; @@ -69,6 +73,10 @@ IOutputStream& OutputFile::addAudioStream(const AudioCodec& audioDesc) { AVStream& stream = _formatContext.addAVStream(audioDesc.getAVCodec()); + stream.codecpar->codec_type = audioDesc.getAVCodecContext().codec_type; + stream.codecpar->codec_id = audioDesc.getAVCodecContext().codec_id; + stream.codecpar->codec_tag = audioDesc.getAVCodecContext().codec_tag; + stream.codecpar->sample_rate = audioDesc.getAVCodecContext().sample_rate; stream.codecpar->channels = audioDesc.getAVCodecContext().channels; stream.codecpar->channel_layout = audioDesc.getAVCodecContext().channel_layout; @@ -91,6 +99,10 @@ IOutputStream& OutputFile::addCustomStream(const ICodec& iCodecDesc) { AVStream& stream = _formatContext.addAVStream(iCodecDesc.getAVCodec()); + stream.codecpar->codec_type = iCodecDesc.getAVCodecContext().codec_type; + stream.codecpar->codec_id = iCodecDesc.getAVCodecContext().codec_id; + stream.codecpar->codec_tag = iCodecDesc.getAVCodecContext().codec_tag; + stream.codecpar->sample_rate = 48000; stream.codecpar->channels = 1; stream.codecpar->channel_layout = AV_CH_LAYOUT_MONO; diff --git a/src/AvTranscoder/stream/InputStream.cpp b/src/AvTranscoder/stream/InputStream.cpp index b2417e8d..6a13578a 100644 --- a/src/AvTranscoder/stream/InputStream.cpp +++ b/src/AvTranscoder/stream/InputStream.cpp @@ -21,8 +21,13 @@ InputStream::InputStream(InputFile& inputFile, const size_t streamIndex) , _streamIndex(streamIndex) , _isActivated(false) { - const AVCodec* codec = avcodec_find_encoder(_inputFile->getFormatContext().getAVStream(_streamIndex).codecpar->codec_id); + AVCodecParameters* codecParameters = _inputFile->getFormatContext().getAVStream(_streamIndex).codecpar; + const AVCodec* codec = avcodec_find_decoder(codecParameters->codec_id); AVCodecContext* context = avcodec_alloc_context3(codec); + int ret = avcodec_parameters_to_context(context, codecParameters); + + if (ret < 0) + throw std::runtime_error("Failed to copy decoder parameters to input stream context"); switch(context->codec_type) { diff --git a/src/AvTranscoder/stream/OutputStream.cpp b/src/AvTranscoder/stream/OutputStream.cpp index ea6ece68..92034dc6 100644 --- a/src/AvTranscoder/stream/OutputStream.cpp +++ b/src/AvTranscoder/stream/OutputStream.cpp @@ -17,10 +17,12 @@ OutputStream::OutputStream(OutputFile& outputFile, const size_t streamIndex) , _lastWrappedPacketDuration(0) , _isPTSGenerated(false) { - const AVCodec* codec = avcodec_find_decoder(_outputAVStream.codecpar->codec_id); + const AVCodec* codec = avcodec_find_encoder(_outputAVStream.codecpar->codec_id); _codecContext = avcodec_alloc_context3(codec); - avcodec_parameters_to_context(_codecContext, _outputAVStream.codecpar); + int ret = avcodec_parameters_to_context(_codecContext, _outputAVStream.codecpar); + if (ret < 0) + throw std::runtime_error("Failed to copy encoder parameters to output stream context"); #if LIBAVCODEC_VERSION_MAJOR > 58 // depending on the format, place global headers in extradata instead of every keyframe From b030fd32ee09a285c43ecbdede77574fcb1e6393 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 25 May 2022 11:57:30 +0200 Subject: [PATCH 04/19] Set decoder context time base --- src/AvTranscoder/stream/InputStream.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/AvTranscoder/stream/InputStream.cpp b/src/AvTranscoder/stream/InputStream.cpp index 6a13578a..31072a1c 100644 --- a/src/AvTranscoder/stream/InputStream.cpp +++ b/src/AvTranscoder/stream/InputStream.cpp @@ -21,10 +21,14 @@ InputStream::InputStream(InputFile& inputFile, const size_t streamIndex) , _streamIndex(streamIndex) , _isActivated(false) { - AVCodecParameters* codecParameters = _inputFile->getFormatContext().getAVStream(_streamIndex).codecpar; + AVStream& avStream = _inputFile->getFormatContext().getAVStream(_streamIndex); + AVCodecParameters* codecParameters = avStream.codecpar; + const AVCodec* codec = avcodec_find_decoder(codecParameters->codec_id); AVCodecContext* context = avcodec_alloc_context3(codec); + int ret = avcodec_parameters_to_context(context, codecParameters); + context->time_base = avStream.time_base; if (ret < 0) throw std::runtime_error("Failed to copy decoder parameters to input stream context"); From c7b1c99fc62b6864da2d167eb118f3b5ff6622eb Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 25 May 2022 12:27:02 +0200 Subject: [PATCH 05/19] Fix minor memory leak --- src/AvTranscoder/properties/StreamProperties.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AvTranscoder/properties/StreamProperties.cpp b/src/AvTranscoder/properties/StreamProperties.cpp index ced1b01a..38a6be72 100644 --- a/src/AvTranscoder/properties/StreamProperties.cpp +++ b/src/AvTranscoder/properties/StreamProperties.cpp @@ -44,6 +44,7 @@ StreamProperties::StreamProperties(const FileProperties& fileProperties, const s StreamProperties::~StreamProperties() { + avcodec_free_context(&_codecContext); } size_t StreamProperties::getStreamId() const From 59f17bff6ef027eb422a7bc5fb619806a100e0c9 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 25 May 2022 12:27:42 +0200 Subject: [PATCH 06/19] Bump version to 0.16.0 --- src/AvTranscoder/common.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/common.hpp b/src/AvTranscoder/common.hpp index bfd80899..8829bec0 100644 --- a/src/AvTranscoder/common.hpp +++ b/src/AvTranscoder/common.hpp @@ -2,8 +2,8 @@ #define _AV_TRANSCODER_COMMON_HPP_ #define AVTRANSCODER_VERSION_MAJOR 0 -#define AVTRANSCODER_VERSION_MINOR 15 -#define AVTRANSCODER_VERSION_MICRO 5 +#define AVTRANSCODER_VERSION_MINOR 16 +#define AVTRANSCODER_VERSION_MICRO 0 #include From e35eb45e7f45739da39ba0f9d0b23c2940f4e5db Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Thu, 2 Jun 2022 18:00:57 +0200 Subject: [PATCH 07/19] Fix compilation with MSVC error C2131: expression did not evaluate to a constant --- src/AvTranscoder/transcoder/Transcoder.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/AvTranscoder/transcoder/Transcoder.cpp b/src/AvTranscoder/transcoder/Transcoder.cpp index 0d578fff..9db3174b 100644 --- a/src/AvTranscoder/transcoder/Transcoder.cpp +++ b/src/AvTranscoder/transcoder/Transcoder.cpp @@ -673,22 +673,24 @@ void Transcoder::fillProcessStat(ProcessStat& processStat) // uint8_t picture_type = coded_frame[4]; uint8_t error_count = coded_frame[5]; - uint64_t errors[error_count]; + std::vector errors; for (int i = 0; i < error_count; ++i) { int index = 6 + i; - errors[i] = (uint64_t) coded_frame[index + 7] << 56 | - (uint64_t) coded_frame[index + 6] << 48 | - (uint64_t) coded_frame[index + 5] << 40 | - (uint64_t) coded_frame[index + 4] << 32 | - (uint64_t) coded_frame[index + 3] << 24 | - (uint64_t) coded_frame[2] << 16 | - (uint64_t) coded_frame[1] << 8 | - (uint64_t) coded_frame[0]; + errors.push_back( + (uint64_t) coded_frame[index + 7] << 56 | + (uint64_t) coded_frame[index + 6] << 48 | + (uint64_t) coded_frame[index + 5] << 40 | + (uint64_t) coded_frame[index + 4] << 32 | + (uint64_t) coded_frame[index + 3] << 24 | + (uint64_t) coded_frame[2] << 16 | + (uint64_t) coded_frame[1] << 8 | + (uint64_t) coded_frame[0] + ); } videoStat.setQuality(quality); - videoStat.setPSNR((double) errors[0] / + videoStat.setPSNR((double) errors.at(0) / (encoderContext.width * encoderContext.height * 255.0 * 255.0)); } } From cac5c3740ab1d0dcd776e9fa2a3a98fd3b981569 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Thu, 2 Jun 2022 18:09:47 +0200 Subject: [PATCH 08/19] Remove PixelProperties::isPseudoPaletted() function --- src/AvTranscoder/properties/PixelProperties.cpp | 10 ---------- src/AvTranscoder/properties/PixelProperties.hpp | 4 ---- 2 files changed, 14 deletions(-) diff --git a/src/AvTranscoder/properties/PixelProperties.cpp b/src/AvTranscoder/properties/PixelProperties.cpp index 48961d0a..1ca56fe3 100644 --- a/src/AvTranscoder/properties/PixelProperties.cpp +++ b/src/AvTranscoder/properties/PixelProperties.cpp @@ -204,21 +204,11 @@ bool PixelProperties::isRgbPixelData() const return (_pixelDesc->flags & AV_PIX_FMT_FLAG_RGB) == AV_PIX_FMT_FLAG_RGB; } -#if LIBAVCODEC_VERSION_MAJOR > 58 bool PixelProperties::isPaletted() const { if (!_pixelDesc) throw std::runtime_error("unable to find pixel description."); return (_pixelDesc->flags & AV_PIX_FMT_FLAG_PAL) == AV_PIX_FMT_FLAG_PAL; -#elif LIBAVCODEC_VERSION_MAJOR > 53 -bool PixelProperties::isPseudoPaletted() const { - if (!_pixelDesc) - throw std::runtime_error("unable to find pixel description."); - - return (_pixelDesc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) == AV_PIX_FMT_FLAG_PSEUDOPAL; -#else - return false; -#endif } std::vector PixelProperties::getChannels() const diff --git a/src/AvTranscoder/properties/PixelProperties.hpp b/src/AvTranscoder/properties/PixelProperties.hpp index b5ba672c..56607ce8 100644 --- a/src/AvTranscoder/properties/PixelProperties.hpp +++ b/src/AvTranscoder/properties/PixelProperties.hpp @@ -71,11 +71,7 @@ class AvExport PixelProperties bool isBitWisePacked() const; bool isHardwareAccelerated() const; bool isRgbPixelData() const; -#if LIBAVCODEC_VERSION_MAJOR > 58 bool isPaletted() const; -#else - bool isPseudoPaletted() const; -#endif std::vector getChannels() const; From 69e9bda14f3d3ee415f3fcbe4b800539cd1b7b6c Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Fri, 3 Jun 2022 14:32:08 +0200 Subject: [PATCH 09/19] Properties: fix double free corruption --- src/AvTranscoder/properties/StreamProperties.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AvTranscoder/properties/StreamProperties.cpp b/src/AvTranscoder/properties/StreamProperties.cpp index 38a6be72..ced1b01a 100644 --- a/src/AvTranscoder/properties/StreamProperties.cpp +++ b/src/AvTranscoder/properties/StreamProperties.cpp @@ -44,7 +44,6 @@ StreamProperties::StreamProperties(const FileProperties& fileProperties, const s StreamProperties::~StreamProperties() { - avcodec_free_context(&_codecContext); } size_t StreamProperties::getStreamId() const From e6b0d05fe68ca39344e793fdb1fa21ac10ffeffd Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Tue, 14 Jun 2022 15:17:37 +0200 Subject: [PATCH 10/19] VideoProperties: extract min and max bitrate from CPB side data if necessary --- src/AvTranscoder/properties/StreamProperties.cpp | 7 +++++-- src/AvTranscoder/properties/VideoProperties.cpp | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/properties/StreamProperties.cpp b/src/AvTranscoder/properties/StreamProperties.cpp index ced1b01a..a0e6cac1 100644 --- a/src/AvTranscoder/properties/StreamProperties.cpp +++ b/src/AvTranscoder/properties/StreamProperties.cpp @@ -28,10 +28,13 @@ StreamProperties::StreamProperties(const FileProperties& fileProperties, const s throw std::runtime_error(ss.str()); } - _codec = avcodec_find_decoder(_formatContext->streams[_streamIndex]->codecpar->codec_id); + AVStream* stream = _formatContext->streams[_streamIndex]; + _codec = avcodec_find_decoder(stream->codecpar->codec_id); _codecContext = avcodec_alloc_context3(_codec); - avcodec_parameters_to_context(_codecContext, _formatContext->streams[_streamIndex]->codecpar); + avcodec_parameters_to_context(_codecContext, stream->codecpar); + _codecContext->time_base = stream->time_base; + _codecContext->coded_side_data = stream->side_data; } // find the decoder diff --git a/src/AvTranscoder/properties/VideoProperties.cpp b/src/AvTranscoder/properties/VideoProperties.cpp index e2ab5bbd..d61dcede 100644 --- a/src/AvTranscoder/properties/VideoProperties.cpp +++ b/src/AvTranscoder/properties/VideoProperties.cpp @@ -371,6 +371,14 @@ size_t VideoProperties::getMaxBitRate() const { if(!_codecContext) throw std::runtime_error("unknown codec context"); + + if (_codecContext->rc_max_rate == 0 + && _codecContext->coded_side_data + && _codecContext->coded_side_data->type == AV_PKT_DATA_CPB_PROPERTIES) { + const AVCPBProperties* prop = (AVCPBProperties*) _codecContext->coded_side_data->data; + return prop->max_bitrate; + } + return _codecContext->rc_max_rate; } @@ -378,6 +386,14 @@ size_t VideoProperties::getMinBitRate() const { if(!_codecContext) throw std::runtime_error("unknown codec context"); + + if (_codecContext->rc_max_rate == 0 + && _codecContext->coded_side_data + && _codecContext->coded_side_data->type == AV_PKT_DATA_CPB_PROPERTIES) { + const AVCPBProperties* prop = (AVCPBProperties*) _codecContext->coded_side_data->data; + return prop->min_bitrate; + } + return _codecContext->rc_min_rate; } From 068073911de395e2becbe9facf849bc055eca502 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Tue, 14 Jun 2022 16:59:50 +0200 Subject: [PATCH 11/19] Applications: generate versionned executable on Windows --- app/avAudioPhaseMeter/CMakeLists.txt | 2 +- app/avInfo/CMakeLists.txt | 2 +- app/avMeta/CMakeLists.txt | 2 +- app/avPlayer/CMakeLists.txt | 2 +- app/avProcessor/CMakeLists.txt | 2 +- app/customEncoder/CMakeLists.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/avAudioPhaseMeter/CMakeLists.txt b/app/avAudioPhaseMeter/CMakeLists.txt index 4ed40d42..812b8d9e 100644 --- a/app/avAudioPhaseMeter/CMakeLists.txt +++ b/app/avAudioPhaseMeter/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(avaudiophasemeter avtranscoder-shared) # Install app if(WIN32) - set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter.exe") + set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter.exe" "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter" "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter-${AVTRANSCODER_VERSION}") endif() diff --git a/app/avInfo/CMakeLists.txt b/app/avInfo/CMakeLists.txt index 4cba2e5e..cd165a75 100644 --- a/app/avInfo/CMakeLists.txt +++ b/app/avInfo/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(avinfo avtranscoder-shared) # Install app if(WIN32) - set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avinfo.exe") + set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avinfo.exe" "${CMAKE_CURRENT_BINARY_DIR}/avinfo-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avinfo" "${CMAKE_CURRENT_BINARY_DIR}/avinfo-${AVTRANSCODER_VERSION}") endif() diff --git a/app/avMeta/CMakeLists.txt b/app/avMeta/CMakeLists.txt index b12c99c9..bdc67260 100644 --- a/app/avMeta/CMakeLists.txt +++ b/app/avMeta/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(avmeta avtranscoder-shared) # Install app if(WIN32) - set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avmeta.exe") + set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avmeta.exe" "${CMAKE_CURRENT_BINARY_DIR}/avmeta-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avmeta" "${CMAKE_CURRENT_BINARY_DIR}/avmeta-${AVTRANSCODER_VERSION}") endif() diff --git a/app/avPlayer/CMakeLists.txt b/app/avPlayer/CMakeLists.txt index bf735c2e..dec775f2 100644 --- a/app/avPlayer/CMakeLists.txt +++ b/app/avPlayer/CMakeLists.txt @@ -33,7 +33,7 @@ target_link_libraries(avplayer avtranscoder-shared ${OPENGL_LIBRARIES} ${GLUT_LI # Install app if(WIN32) - set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avplayer.exe") + set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avplayer.exe" "${CMAKE_CURRENT_BINARY_DIR}/avplayer-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avplayer" "${CMAKE_CURRENT_BINARY_DIR}/avplayer-${AVTRANSCODER_VERSION}") endif() diff --git a/app/avProcessor/CMakeLists.txt b/app/avProcessor/CMakeLists.txt index 4cb1a118..eb91477f 100644 --- a/app/avProcessor/CMakeLists.txt +++ b/app/avProcessor/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(avprocessor avtranscoder-shared) # Install app if(WIN32) - set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avprocessor.exe") + set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avprocessor.exe" "${CMAKE_CURRENT_BINARY_DIR}/avprocessor-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avprocessor" "${CMAKE_CURRENT_BINARY_DIR}/avprocessor-${AVTRANSCODER_VERSION}") endif() diff --git a/app/customEncoder/CMakeLists.txt b/app/customEncoder/CMakeLists.txt index 2c7e55d2..0eb6286b 100644 --- a/app/customEncoder/CMakeLists.txt +++ b/app/customEncoder/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(custom-encoder avtranscoder-shared) # Install app if(WIN32) - set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder.exe") + set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder.exe" "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder" "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder-${AVTRANSCODER_VERSION}") endif() From 2069c5d1e895e803086d251750e22147687fcd9d Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Tue, 14 Jun 2022 16:37:27 +0200 Subject: [PATCH 12/19] Applications: set version to executable on Windows --- app/avAudioPhaseMeter/CMakeLists.txt | 1 + app/avInfo/CMakeLists.txt | 1 + app/avMeta/CMakeLists.txt | 1 + app/avPlayer/CMakeLists.txt | 1 + app/avProcessor/CMakeLists.txt | 1 + app/customEncoder/CMakeLists.txt | 1 + 6 files changed, 6 insertions(+) diff --git a/app/avAudioPhaseMeter/CMakeLists.txt b/app/avAudioPhaseMeter/CMakeLists.txt index 812b8d9e..68946eb9 100644 --- a/app/avAudioPhaseMeter/CMakeLists.txt +++ b/app/avAudioPhaseMeter/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(avaudiophasemeter avtranscoder-shared) # Install app if(WIN32) + set_target_properties(avaudiophasemeter PROPERTIES OUTPUT_NAME "avaudiophasemeter-${AVTRANSCODER_VERSION}") set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter.exe" "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter" "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter-${AVTRANSCODER_VERSION}") diff --git a/app/avInfo/CMakeLists.txt b/app/avInfo/CMakeLists.txt index cd165a75..8eddbb4c 100644 --- a/app/avInfo/CMakeLists.txt +++ b/app/avInfo/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(avinfo avtranscoder-shared) # Install app if(WIN32) + set_target_properties(avinfo PROPERTIES OUTPUT_NAME "avinfo-${AVTRANSCODER_VERSION}") set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avinfo.exe" "${CMAKE_CURRENT_BINARY_DIR}/avinfo-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avinfo" "${CMAKE_CURRENT_BINARY_DIR}/avinfo-${AVTRANSCODER_VERSION}") diff --git a/app/avMeta/CMakeLists.txt b/app/avMeta/CMakeLists.txt index bdc67260..57277377 100644 --- a/app/avMeta/CMakeLists.txt +++ b/app/avMeta/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(avmeta avtranscoder-shared) # Install app if(WIN32) + set_target_properties(avinfo PROPERTIES OUTPUT_NAME "avinfo-${AVTRANSCODER_VERSION}") set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avmeta.exe" "${CMAKE_CURRENT_BINARY_DIR}/avmeta-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avmeta" "${CMAKE_CURRENT_BINARY_DIR}/avmeta-${AVTRANSCODER_VERSION}") diff --git a/app/avPlayer/CMakeLists.txt b/app/avPlayer/CMakeLists.txt index dec775f2..61c7e05c 100644 --- a/app/avPlayer/CMakeLists.txt +++ b/app/avPlayer/CMakeLists.txt @@ -33,6 +33,7 @@ target_link_libraries(avplayer avtranscoder-shared ${OPENGL_LIBRARIES} ${GLUT_LI # Install app if(WIN32) + set_target_properties(avplayer PROPERTIES OUTPUT_NAME "avplayer-${AVTRANSCODER_VERSION}") set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avplayer.exe" "${CMAKE_CURRENT_BINARY_DIR}/avplayer-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avplayer" "${CMAKE_CURRENT_BINARY_DIR}/avplayer-${AVTRANSCODER_VERSION}") diff --git a/app/avProcessor/CMakeLists.txt b/app/avProcessor/CMakeLists.txt index eb91477f..8c20bf4f 100644 --- a/app/avProcessor/CMakeLists.txt +++ b/app/avProcessor/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(avprocessor avtranscoder-shared) # Install app if(WIN32) + set_target_properties(avprocessor PROPERTIES OUTPUT_NAME "avprocessor-${AVTRANSCODER_VERSION}") set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avprocessor.exe" "${CMAKE_CURRENT_BINARY_DIR}/avprocessor-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avprocessor" "${CMAKE_CURRENT_BINARY_DIR}/avprocessor-${AVTRANSCODER_VERSION}") diff --git a/app/customEncoder/CMakeLists.txt b/app/customEncoder/CMakeLists.txt index 0eb6286b..df273a35 100644 --- a/app/customEncoder/CMakeLists.txt +++ b/app/customEncoder/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(custom-encoder avtranscoder-shared) # Install app if(WIN32) + set_target_properties(custom-encoder PROPERTIES OUTPUT_NAME "custom-encoder-${AVTRANSCODER_VERSION}") set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder.exe" "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder" "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder-${AVTRANSCODER_VERSION}") From 19c582fc4376b142f47813c2839e8039432d764c Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 15 Jun 2022 17:48:12 +0200 Subject: [PATCH 13/19] Applications: fix avmeta executable version on Windows --- app/avMeta/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/avMeta/CMakeLists.txt b/app/avMeta/CMakeLists.txt index 57277377..2228c579 100644 --- a/app/avMeta/CMakeLists.txt +++ b/app/avMeta/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(avmeta avtranscoder-shared) # Install app if(WIN32) - set_target_properties(avinfo PROPERTIES OUTPUT_NAME "avinfo-${AVTRANSCODER_VERSION}") + set_target_properties(avmeta PROPERTIES OUTPUT_NAME "avmeta-${AVTRANSCODER_VERSION}") set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avmeta.exe" "${CMAKE_CURRENT_BINARY_DIR}/avmeta-${AVTRANSCODER_VERSION}.exe") else() set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avmeta" "${CMAKE_CURRENT_BINARY_DIR}/avmeta-${AVTRANSCODER_VERSION}") From c194f6306d6cdc791fcdb0333e499598e543d1fe Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Tue, 12 Jul 2022 18:11:54 +0200 Subject: [PATCH 14/19] FilterGraph: keep reference of the filters input frame --- src/AvTranscoder/filter/FilterGraph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/filter/FilterGraph.cpp b/src/AvTranscoder/filter/FilterGraph.cpp index 57b6ce2f..58fb7d9f 100644 --- a/src/AvTranscoder/filter/FilterGraph.cpp +++ b/src/AvTranscoder/filter/FilterGraph.cpp @@ -275,7 +275,7 @@ void FilterGraph::process(const std::vector& inputs, IFrame& output) { // Retrieve frame from buffer or directly from input IFrame* inputFrame = (bypassBuffers)? inputs.at(index) : _inputAudioFrameBuffers.at(index).getFrameSampleNb(minInputFrameSamplesNb); - const int ret = av_buffersrc_add_frame_flags(_filters.at(index)->getAVFilterContext(), &inputFrame->getAVFrame(), AV_BUFFERSRC_FLAG_PUSH); + const int ret = av_buffersrc_add_frame_flags(_filters.at(index)->getAVFilterContext(), &inputFrame->getAVFrame(), AV_BUFFERSRC_FLAG_PUSH & AV_BUFFERSRC_FLAG_KEEP_REF); if(ret < 0) { From 53298d0fb4d10f42270ca9db159dc7e59434d301 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Fri, 15 Jul 2022 14:58:02 +0200 Subject: [PATCH 15/19] FilterGraph: keep reference of the filters input frame Real fix after c194f6306d6cdc791fcdb0333e499598e543d1fe --- src/AvTranscoder/filter/FilterGraph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/filter/FilterGraph.cpp b/src/AvTranscoder/filter/FilterGraph.cpp index 58fb7d9f..58f62fdb 100644 --- a/src/AvTranscoder/filter/FilterGraph.cpp +++ b/src/AvTranscoder/filter/FilterGraph.cpp @@ -275,7 +275,7 @@ void FilterGraph::process(const std::vector& inputs, IFrame& output) { // Retrieve frame from buffer or directly from input IFrame* inputFrame = (bypassBuffers)? inputs.at(index) : _inputAudioFrameBuffers.at(index).getFrameSampleNb(minInputFrameSamplesNb); - const int ret = av_buffersrc_add_frame_flags(_filters.at(index)->getAVFilterContext(), &inputFrame->getAVFrame(), AV_BUFFERSRC_FLAG_PUSH & AV_BUFFERSRC_FLAG_KEEP_REF); + const int ret = av_buffersrc_add_frame_flags(_filters.at(index)->getAVFilterContext(), &inputFrame->getAVFrame(), AV_BUFFERSRC_FLAG_KEEP_REF); if(ret < 0) { From 468dad2309b67f6bb5b113f812b13ec489c24262 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Tue, 2 May 2023 14:43:01 +0200 Subject: [PATCH 16/19] Transcoder: add getters for number of decoded and generated frames --- .../transcoder/StreamTranscoder.hpp | 17 +++++++++++++++++ src/AvTranscoder/transcoder/Transcoder.hpp | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.hpp b/src/AvTranscoder/transcoder/StreamTranscoder.hpp index 23006d18..9df3f114 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.hpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.hpp @@ -100,6 +100,23 @@ class AvExport StreamTranscoder /// Returns a reference to the stream which wraps data IOutputStream& getOutputStream() const { return *_outputStream; } + /// Returns the total number of generated frames for this processed stream + size_t getNumberOfGeneratedFrames() const { + size_t generatedFrames = 0; + for (IDecoder* generator : _generators) { + generatedFrames += generator->getNbDecodedFrames(); + } + return generatedFrames; + } + /// Returns the total number of decoded frames for this processed stream + size_t getNumberOfDecodedFrames() const { + size_t decodedFrames = 0; + for (IDecoder* inputDecoder : _inputDecoders) { + decodedFrames += inputDecoder->getNbDecodedFrames(); + } + return decodedFrames; + } + /** * @brief Returns if the stream has the ability to switch to a generator. */ diff --git a/src/AvTranscoder/transcoder/Transcoder.hpp b/src/AvTranscoder/transcoder/Transcoder.hpp index cc35c496..9ba27f6e 100644 --- a/src/AvTranscoder/transcoder/Transcoder.hpp +++ b/src/AvTranscoder/transcoder/Transcoder.hpp @@ -139,6 +139,24 @@ class AvExport Transcoder void setProcessMethod(const EProcessMethod eProcessMethod, const size_t indexBasedStream = 0, const double outputDuration = 0); + /** + * @brief Returns the total number of generated frames for a specific stream + * @param streamIndex: the index of the stream + * @return The total number of generated frames + */ + size_t getNumberOfGeneratedFrames(const size_t streamIndex) const { + return _streamTranscoders.at(streamIndex)->getNumberOfGeneratedFrames(); + } + + /** + * @brief Returns the total number of decoded frames for a specific stream + * @param streamIndex: the index of the stream + * @return The total number of decoded frames + */ + size_t getNumberOfDecodedFrames(const size_t streamIndex) const { + return _streamTranscoders.at(streamIndex)->getNumberOfDecodedFrames(); + } + private: void addRewrapStream(const InputStreamDesc& inputStreamDesc, const float offset); void addTranscodeStream(const std::vector& inputStreamDescArray, const ProfileLoader::Profile& profile, From 5b74a24a749d6e31039f78c13968365f7b18c2a4 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Fri, 5 May 2023 09:29:31 +0200 Subject: [PATCH 17/19] Bump version to 0.16.1 --- 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 8829bec0..2d078685 100644 --- a/src/AvTranscoder/common.hpp +++ b/src/AvTranscoder/common.hpp @@ -3,7 +3,7 @@ #define AVTRANSCODER_VERSION_MAJOR 0 #define AVTRANSCODER_VERSION_MINOR 16 -#define AVTRANSCODER_VERSION_MICRO 0 +#define AVTRANSCODER_VERSION_MICRO 1 #include From 92714dfde56395e7310983850a2d7d75da69fdcc Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Fri, 22 Sep 2023 15:38:41 +0200 Subject: [PATCH 18/19] Call string:::empty method instead of comparing to an empty string --- src/AvTranscoder/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/util.cpp b/src/AvTranscoder/util.cpp index f9b690c2..ab4db74b 100644 --- a/src/AvTranscoder/util.cpp +++ b/src/AvTranscoder/util.cpp @@ -15,7 +15,7 @@ std::vector getSupportedPixelFormats(const std::string& videoCodecN std::vector pixelFormats; // all video codec concerned - if(videoCodecName == "") + if(videoCodecName.empty()) { const AVPixFmtDescriptor* pixFmtDesc = NULL; From 91a447e5782572462f9df5b6eb7de79811e0b738 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Fri, 22 Sep 2023 15:38:57 +0200 Subject: [PATCH 19/19] Bump version to 0.16.2 --- 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 2d078685..c249e3a3 100644 --- a/src/AvTranscoder/common.hpp +++ b/src/AvTranscoder/common.hpp @@ -3,7 +3,7 @@ #define AVTRANSCODER_VERSION_MAJOR 0 #define AVTRANSCODER_VERSION_MINOR 16 -#define AVTRANSCODER_VERSION_MICRO 1 +#define AVTRANSCODER_VERSION_MICRO 2 #include