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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy