From 2218c1c37c16df4ce3da34c8566f5e1335a66c01 Mon Sep 17 00:00:00 2001 From: Alwin Esch <alwin.esch@web.de> Date: Sun, 10 Jul 2022 18:59:52 +0200 Subject: [PATCH 1/7] FFmpeg5 port --- xbmc/cdrip/EncoderFFmpeg.cpp | 95 ++++++--------- xbmc/cdrip/EncoderFFmpeg.h | 1 - .../AudioEngine/Encoders/AEEncoderFFmpeg.cpp | 111 +++++++++++------- .../AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 14 +-- xbmc/cores/FFmpeg.cpp | 14 ++- xbmc/cores/FFmpeg.h | 26 ++++ .../DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp | 12 +- .../Overlay/DVDOverlayCodecFFmpeg.cpp | 3 +- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 36 +++++- .../DVDCodecs/Video/DVDVideoPPFFmpeg.cpp | 5 + .../VideoPlayer/DVDCodecs/Video/VAAPI.cpp | 10 +- .../DVDDemuxers/DVDDemuxClient.cpp | 3 +- .../DVDDemuxers/DVDDemuxFFmpeg.cpp | 71 +++++++++-- .../DVDInputStreams/InputStreamAddon.cpp | 3 +- xbmc/filesystem/AudioBookFileDirectory.cpp | 3 +- xbmc/guilib/FFmpegImage.cpp | 6 +- xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp | 2 +- xbmc/video/tags/VideoTagLoaderFFmpeg.cpp | 2 +- 18 files changed, 281 insertions(+), 136 deletions(-) diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp index 2867b7cb677d6..4c0628b5cc108 100644 --- a/xbmc/cdrip/EncoderFFmpeg.cpp +++ b/xbmc/cdrip/EncoderFFmpeg.cpp @@ -11,6 +11,7 @@ #include "ServiceBroker.h" #include "addons/Addon.h" #include "addons/AddonManager.h" +#include "cores/FFmpeg.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" #include "utils/StringUtils.h" @@ -19,23 +20,8 @@ #include "utils/log.h" using namespace KODI::CDRIP; - -namespace -{ - -struct EncoderException : public std::exception -{ - std::string s; - template<typename... Args> - EncoderException(const std::string& fmt, Args&&... args) - : s(StringUtils::Format(fmt, std::forward<Args>(args)...)) - { - } - ~EncoderException() throw() {} // Updated - const char* what() const throw() { return s.c_str(); } -}; - -} /* namespace */ +using FFMPEG_HELP_TOOLS::FFMpegErrorToString; +using FFMPEG_HELP_TOOLS::FFMpegException; bool CEncoderFFmpeg::Init() { @@ -54,7 +40,7 @@ bool CEncoderFFmpeg::Init() } else { - throw EncoderException("Could not get add-on: {}", addonId); + throw FFMpegException("Could not get add-on: {}", addonId); } // Hack fix about PTS on generated files. @@ -66,45 +52,45 @@ bool CEncoderFFmpeg::Init() else if (addonId == "audioencoder.kodi.builtin.wma") m_samplesCountMultiply = 1000; else - throw EncoderException("Internal add-on id \"{}\" not known as usable", addonId); + throw FFMpegException("Internal add-on id \"{}\" not known as usable", addonId); const std::string filename = URIUtils::GetFileName(m_strFile); m_formatCtx = avformat_alloc_context(); if (!m_formatCtx) - throw EncoderException("Could not allocate output format context"); + throw FFMpegException("Could not allocate output format context"); m_bcBuffer = static_cast<uint8_t*>(av_malloc(BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE)); if (!m_bcBuffer) - throw EncoderException("Could not allocate buffer"); + throw FFMpegException("Could not allocate buffer"); m_formatCtx->pb = avio_alloc_context(m_bcBuffer, BUFFER_SIZE, AVIO_FLAG_WRITE, this, nullptr, avio_write_callback, avio_seek_callback); if (!m_formatCtx->pb) - throw EncoderException("Failed to allocate ByteIOContext"); + throw FFMpegException("Failed to allocate ByteIOContext"); /* Guess the desired container format based on the file extension. */ m_formatCtx->oformat = av_guess_format(nullptr, filename.c_str(), nullptr); if (!m_formatCtx->oformat) - throw EncoderException("Could not find output file format"); + throw FFMpegException("Could not find output file format"); m_formatCtx->url = av_strdup(filename.c_str()); if (!m_formatCtx->url) - throw EncoderException("Could not allocate url"); + throw FFMpegException("Could not allocate url"); /* Find the encoder to be used by its name. */ - AVCodec* codec = avcodec_find_encoder(m_formatCtx->oformat->audio_codec); + FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_encoder(m_formatCtx->oformat->audio_codec); if (!codec) - throw EncoderException("Unable to find a suitable FFmpeg encoder"); + throw FFMpegException("Unable to find a suitable FFmpeg encoder"); /* Create a new audio stream in the output file container. */ m_stream = avformat_new_stream(m_formatCtx, nullptr); if (!m_stream) - throw EncoderException("Failed to allocate AVStream context"); + throw FFMpegException("Failed to allocate AVStream context"); m_codecCtx = avcodec_alloc_context3(codec); if (!m_codecCtx) - throw EncoderException("Failed to allocate the encoder context"); + throw FFMpegException("Failed to allocate the encoder context"); /* Set the basic encoder parameters. * The input file's sample rate is used to avoid a sample rate conversion. */ @@ -128,14 +114,14 @@ bool CEncoderFFmpeg::Init() int err = avcodec_open2(m_codecCtx, codec, nullptr); if (err < 0) - throw EncoderException("Failed to open the codec {} (error '{}')", - codec->long_name ? codec->long_name : codec->name, - FFmpegErrorToString(err)); + throw FFMpegException("Failed to open the codec {} (error '{}')", + codec->long_name ? codec->long_name : codec->name, + FFMpegErrorToString(err)); err = avcodec_parameters_from_context(m_stream->codecpar, m_codecCtx); if (err < 0) - throw EncoderException("Failed to copy encoder parameters to output stream (error '{}')", - FFmpegErrorToString(err)); + throw FFMpegException("Failed to copy encoder parameters to output stream (error '{}')", + FFMpegErrorToString(err)); m_inFormat = GetInputFormat(m_iInBitsPerSample); m_outFormat = m_codecCtx->sample_fmt; @@ -150,7 +136,7 @@ bool CEncoderFFmpeg::Init() m_bufferFrame = av_frame_alloc(); if (!m_bufferFrame || !m_buffer) - throw EncoderException("Failed to allocate necessary buffers"); + throw FFMpegException("Failed to allocate necessary buffers"); m_bufferFrame->nb_samples = m_codecCtx->frame_size; m_bufferFrame->format = m_inFormat; @@ -159,8 +145,8 @@ bool CEncoderFFmpeg::Init() err = av_frame_get_buffer(m_bufferFrame, 0); if (err < 0) - throw EncoderException("Could not allocate output frame samples (error '{}')", - FFmpegErrorToString(err)); + throw FFMpegException("Could not allocate output frame samples (error '{}')", + FFMpegErrorToString(err)); avcodec_fill_audio_frame(m_bufferFrame, m_iInChannels, m_inFormat, m_buffer, m_neededBytes, 0); @@ -170,14 +156,14 @@ bool CEncoderFFmpeg::Init() m_codecCtx->sample_rate, m_codecCtx->channel_layout, m_inFormat, m_codecCtx->sample_rate, 0, nullptr); if (!m_swrCtx || swr_init(m_swrCtx) < 0) - throw EncoderException("Failed to initialize the resampler"); + throw FFMpegException("Failed to initialize the resampler"); m_resampledBufferSize = av_samples_get_buffer_size(nullptr, m_iInChannels, m_neededFrames, m_outFormat, 0); m_resampledBuffer = static_cast<uint8_t*>(av_malloc(m_resampledBufferSize)); m_resampledFrame = av_frame_alloc(); if (!m_resampledBuffer || !m_resampledFrame) - throw EncoderException("Failed to allocate a frame for resampling"); + throw FFMpegException("Failed to allocate a frame for resampling"); m_resampledFrame->nb_samples = m_neededFrames; m_resampledFrame->format = m_outFormat; @@ -186,8 +172,8 @@ bool CEncoderFFmpeg::Init() err = av_frame_get_buffer(m_resampledFrame, 0); if (err < 0) - throw EncoderException("Could not allocate output resample frame samples (error '{}')", - FFmpegErrorToString(err)); + throw FFMpegException("Could not allocate output resample frame samples (error '{}')", + FFMpegErrorToString(err)); avcodec_fill_audio_frame(m_resampledFrame, m_iInChannels, m_outFormat, m_resampledBuffer, m_resampledBufferSize, 0); @@ -204,7 +190,7 @@ bool CEncoderFFmpeg::Init() /* write the header */ err = avformat_write_header(m_formatCtx, nullptr); if (err != 0) - throw EncoderException("Failed to write the header (error '{}')", FFmpegErrorToString(err)); + throw FFMpegException("Failed to write the header (error '{}')", FFMpegErrorToString(err)); CLog::Log(LOGDEBUG, "CEncoderFFmpeg::{} - Successfully initialized with muxer {} and codec {}", __func__, @@ -212,7 +198,7 @@ bool CEncoderFFmpeg::Init() : m_formatCtx->oformat->name, codec->long_name ? codec->long_name : codec->name); } - catch (EncoderException& caught) + catch (const FFMpegException& caught) { CLog::Log(LOGERROR, "CEncoderFFmpeg::{} - {}", __func__, caught.what()); @@ -299,7 +285,7 @@ bool CEncoderFFmpeg::WriteFrame() if (swr_convert(m_swrCtx, m_resampledFrame->data, m_neededFrames, const_cast<const uint8_t**>(m_bufferFrame->extended_data), m_neededFrames) < 0) - throw EncoderException("Error resampling audio"); + throw FFMpegException("Error resampling audio"); frame = m_resampledFrame; } @@ -316,8 +302,8 @@ bool CEncoderFFmpeg::WriteFrame() m_bufferSize = 0; err = avcodec_send_frame(m_codecCtx, frame); if (err < 0) - throw EncoderException("Error sending a frame for encoding (error '{}')", __func__, - FFmpegErrorToString(err)); + throw FFMpegException("Error sending a frame for encoding (error '{}')", + FFMpegErrorToString(err)); while (err >= 0) { @@ -329,19 +315,18 @@ bool CEncoderFFmpeg::WriteFrame() } else if (err < 0) { - throw EncoderException("Error during encoding (error '{}')", __func__, - FFmpegErrorToString(err)); + throw FFMpegException("Error during encoding (error '{}')", FFMpegErrorToString(err)); } err = av_write_frame(m_formatCtx, pkt); if (err < 0) - throw EncoderException("Failed to write the frame data (error '{}')", __func__, - FFmpegErrorToString(err)); + throw FFMpegException("Failed to write the frame data (error '{}')", + FFMpegErrorToString(err)); av_packet_unref(pkt); } } - catch (EncoderException& caught) + catch (const FFMpegException& caught) { CLog::Log(LOGERROR, "CEncoderFFmpeg::{} - {}", __func__, caught.what()); } @@ -400,14 +385,6 @@ AVSampleFormat CEncoderFFmpeg::GetInputFormat(int inBitsPerSample) case 32: return AV_SAMPLE_FMT_S32; default: - throw EncoderException("Invalid input bits per sample"); + throw FFMpegException("Invalid input bits per sample"); } } - -std::string CEncoderFFmpeg::FFmpegErrorToString(int err) -{ - std::string text; - text.reserve(AV_ERROR_MAX_STRING_SIZE); - av_strerror(err, text.data(), AV_ERROR_MAX_STRING_SIZE); - return text; -} diff --git a/xbmc/cdrip/EncoderFFmpeg.h b/xbmc/cdrip/EncoderFFmpeg.h index 39112ba3ba09e..0c2391c7abf5e 100644 --- a/xbmc/cdrip/EncoderFFmpeg.h +++ b/xbmc/cdrip/EncoderFFmpeg.h @@ -39,7 +39,6 @@ class CEncoderFFmpeg : public CEncoder void SetTag(const std::string& tag, const std::string& value); bool WriteFrame(); AVSampleFormat GetInputFormat(int inBitsPerSample); - std::string FFmpegErrorToString(int err); AVFormatContext* m_formatCtx{nullptr}; AVCodecContext* m_codecCtx{nullptr}; diff --git a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp index 09bb26a3270dd..86f65f57f330a 100644 --- a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp +++ b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp @@ -10,13 +10,24 @@ #define DTS_ENCODE_BITRATE 1411200 #include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h" -#include "cores/AudioEngine/Utils/AEUtil.h" + #include "ServiceBroker.h" -#include "utils/log.h" +#include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/FFmpeg.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" -#include <string.h> +#include "utils/log.h" + +extern "C" +{ +#include <libavutil/channel_layout.h> +} + #include <cassert> +#include <string.h> + +using FFMPEG_HELP_TOOLS::FFMpegErrorToString; +using FFMPEG_HELP_TOOLS::FFMpegException; CAEEncoderFFmpeg::CAEEncoderFFmpeg() : m_CodecCtx(NULL), m_SwrCtx(NULL) { @@ -81,7 +92,7 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input bool ac3 = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_AUDIOOUTPUT_AC3PASSTHROUGH); - AVCodec *codec = NULL; + FFMPEG_FMT_CONST AVCodec* codec = nullptr; /* fallback to ac3 if we support it, we might not have DTS support */ if (ac3) @@ -242,63 +253,77 @@ unsigned int CAEEncoderFFmpeg::GetFrames() int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_size) { - int got_output; - AVFrame *frame; + int size = 0; + int err = AVERROR_UNKNOWN; + AVFrame* frame = nullptr; + AVPacket* pkt = nullptr; if (!m_CodecCtx) - return 0; - - /* allocate the input frame - * sadly, we have to alloc/dealloc it everytime since we have no guarantee the - * data argument will be constant over iterated calls and the frame needs to - * setup pointers inside data */ - frame = av_frame_alloc(); - if (!frame) - return 0; + return size; - frame->nb_samples = m_CodecCtx->frame_size; - frame->format = m_CodecCtx->sample_fmt; - frame->channel_layout = m_CodecCtx->channel_layout; - frame->channels = m_CodecCtx->channels; + try + { + /* allocate the input frame and output packet + * sadly, we have to alloc/dealloc it everytime since we have no guarantee the + * data argument will be constant over iterated calls and the frame needs to + * setup pointers inside data */ + frame = av_frame_alloc(); + pkt = av_packet_alloc(); + if (!frame || !pkt) + throw FFMpegException( + "Failed to allocate \"AVFrame\" or \"AVPacket\" for encoding (error '{}')", + strerror(errno)); + + frame->nb_samples = m_CodecCtx->frame_size; + frame->format = m_CodecCtx->sample_fmt; + frame->channel_layout = m_CodecCtx->channel_layout; + frame->channels = m_CodecCtx->channels; + + avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, in, in_size, 0); + + pkt->size = out_size; + pkt->data = out; + + /* encode it */ + err = avcodec_send_frame(m_CodecCtx, frame); + if (err < 0) + throw FFMpegException("Error sending a frame for encoding (error '{}')", + FFMpegErrorToString(err)); + + while (err >= 0) + { + err = avcodec_receive_packet(m_CodecCtx, pkt); + if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) + { + av_frame_free(&frame); + av_packet_free(&pkt); + return (err == AVERROR(EAGAIN)) ? -1 : 0; + } + else if (err < 0) + { + throw FFMpegException("Error during encoding (error '{}')", FFMpegErrorToString(err)); + } - avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, - in, in_size, 0); + av_packet_unref(pkt); + } - /* initialize the output packet */ - AVPacket* pkt = av_packet_alloc(); - if (!pkt) + size = pkt->size; + } + catch (const FFMpegException& caught) { - CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - av_packet_alloc failed: {}", __FUNCTION__, - strerror(errno)); - av_frame_free(&frame); - return 0; + CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - {}", __func__, caught.what()); } - pkt->size = out_size; - pkt->data = out; - - /* encode it */ - int ret = avcodec_encode_audio2(m_CodecCtx, pkt, frame, &got_output); - - int size = pkt->size; - /* free temporary data */ av_frame_free(&frame); /* free the packet */ av_packet_free(&pkt); - if (ret < 0 || !got_output) - { - CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Encoding failed"); - return 0; - } - /* return the number of frames used */ return size; } - int CAEEncoderFFmpeg::GetData(uint8_t **data) { int size; diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp index 3947dd55232af..6000fe9c6357a 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -16,17 +16,17 @@ using namespace ActiveAE; #include "ActiveAESound.h" #include "ActiveAEStream.h" #include "ServiceBroker.h" +#include "cores/AudioEngine/AEResampleFactory.h" +#include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h" #include "cores/AudioEngine/Interfaces/IAudioCallback.h" -#include "cores/AudioEngine/Utils/AEUtil.h" #include "cores/AudioEngine/Utils/AEStreamData.h" #include "cores/AudioEngine/Utils/AEStreamInfo.h" -#include "cores/AudioEngine/AEResampleFactory.h" -#include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h" - +#include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/FFmpeg.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" -#include "windowing/WinSystem.h" #include "utils/log.h" +#include "windowing/WinSystem.h" using namespace std::chrono_literals; @@ -3016,8 +3016,8 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) AVFormatContext *fmt_ctx = nullptr; AVCodecContext *dec_ctx = nullptr; AVIOContext *io_ctx; - AVInputFormat *io_fmt = nullptr; - AVCodec *dec = nullptr; + FFMPEG_FMT_CONST AVInputFormat* io_fmt = nullptr; + FFMPEG_FMT_CONST AVCodec* dec = nullptr; SampleConfig config; // No custom deleter until sound is registered diff --git a/xbmc/cores/FFmpeg.cpp b/xbmc/cores/FFmpeg.cpp index 03a29f7db4854..de1765ed52558 100644 --- a/xbmc/cores/FFmpeg.cpp +++ b/xbmc/cores/FFmpeg.cpp @@ -21,6 +21,19 @@ static thread_local CFFmpegLog* CFFmpegLogTls; +namespace FFMPEG_HELP_TOOLS +{ + +std::string FFMpegErrorToString(int err) +{ + std::string text; + text.resize(AV_ERROR_MAX_STRING_SIZE); + av_strerror(err, text.data(), AV_ERROR_MAX_STRING_SIZE); + return text; +} + +} // namespace FFMPEG_HELP_TOOLS + void CFFmpegLog::SetLogLevel(int level) { CFFmpegLog::ClearLogLevel(); @@ -116,4 +129,3 @@ void ff_avutil_log(void* ptr, int level, const char* format, va_list va) } buffer.erase(0, start); } - diff --git a/xbmc/cores/FFmpeg.h b/xbmc/cores/FFmpeg.h index e1194d19e9e19..8230701ba7a8f 100644 --- a/xbmc/cores/FFmpeg.h +++ b/xbmc/cores/FFmpeg.h @@ -10,6 +10,7 @@ #include "ServiceBroker.h" #include "utils/CPUInfo.h" +#include "utils/StringUtils.h" extern "C" { #include <libavcodec/avcodec.h> @@ -21,6 +22,31 @@ extern "C" { #include <libpostproc/postprocess.h> } +// https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4/doc/APIchanges#L18-L26 +#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 0, 100) +#define FFMPEG_FMT_CONST const +#else +#define FFMPEG_FMT_CONST +#endif + +namespace FFMPEG_HELP_TOOLS +{ + +struct FFMpegException : public std::exception +{ + std::string s; + template<typename... Args> + FFMpegException(const std::string& fmt, Args&&... args) + : s(StringUtils::Format(fmt, std::forward<Args>(args)...)) + { + } + const char* what() const noexcept override { return s.c_str(); } +}; + +std::string FFMpegErrorToString(int err); + +} // namespace FFMPEG_HELP_TOOLS + inline int PPCPUFlags() { unsigned int cpuFeatures = CServiceBroker::GetCPUInfo()->GetCPUFeatures(); diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp index 25f3f08e1fcc6..87e7ae2c5785b 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp @@ -7,14 +7,16 @@ */ #include "DVDAudioCodecFFmpeg.h" -#include "ServiceBroker.h" + #include "../../DVDStreamInfo.h" -#include "utils/log.h" +#include "DVDCodecs/DVDCodecs.h" +#include "ServiceBroker.h" +#include "cores/AudioEngine/Utils/AEUtil.h" +#include "cores/FFmpeg.h" #include "settings/AdvancedSettings.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" -#include "DVDCodecs/DVDCodecs.h" -#include "cores/AudioEngine/Utils/AEUtil.h" +#include "utils/log.h" extern "C" { #include <libavutil/opt.h> @@ -44,7 +46,7 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options return false; } - AVCodec* pCodec = NULL; + FFMPEG_FMT_CONST AVCodec* pCodec = nullptr; bool allowdtshddecode = true; // set any special options diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp index 8c26cad3060a9..3657fc093ca0d 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp @@ -10,6 +10,7 @@ #include "DVDOverlayImage.h" #include "DVDStreamInfo.h" +#include "cores/FFmpeg.h" #include "cores/VideoPlayer/Interface/DemuxPacket.h" #include "cores/VideoPlayer/Interface/TimingConstants.h" #include "utils/EndianSwap.h" @@ -39,7 +40,7 @@ bool CDVDOverlayCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &optio if (hints.codec == AV_CODEC_ID_EIA_608) return false; - AVCodec* pCodec = avcodec_find_decoder(hints.codec); + FFMPEG_FMT_CONST AVCodec* pCodec = avcodec_find_decoder(hints.codec); if (!pCodec) { CLog::Log(LOGDEBUG, "{} - Unable to find codec {}", __FUNCTION__, hints.codec); diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp index 881c02ec123e0..21b5e834b2c5c 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -12,6 +12,7 @@ #include "DVDCodecs/DVDFactoryCodec.h" #include "DVDStreamInfo.h" #include "ServiceBroker.h" +#include "cores/FFmpeg.h" #include "cores/VideoPlayer/Interface/TimingConstants.h" #include "cores/VideoPlayer/VideoRenderers/RenderManager.h" #include "cores/VideoSettings.h" @@ -27,12 +28,13 @@ #include <mutex> extern "C" { -#include <libavutil/opt.h> -#include <libavutil/mastering_display_metadata.h> #include <libavfilter/avfilter.h> #include <libavfilter/buffersink.h> #include <libavfilter/buffersrc.h> +#include <libavutil/mastering_display_metadata.h> +#include <libavutil/opt.h> #include <libavutil/pixdesc.h> +#include <libavutil/video_enc_params.h> } #ifndef TARGET_POSIX @@ -327,7 +329,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options m_hints = hints; m_options = options; - AVCodec* pCodec = nullptr; + FFMPEG_FMT_CONST AVCodec* pCodec = nullptr; m_iOrientation = hints.orientation; @@ -1048,6 +1050,33 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(VideoPicture* pVideoPicture) pVideoPicture->qscale_type = 0; AVFrameSideData* sd; + + // https://github.com/FFmpeg/FFmpeg/blob/991d417692/doc/APIchanges#L18-L20 + // basilgello: AV_VIDEO_ENC_PARAMS_MPEG2 is introduced in 4.4! +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(58, 134, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(56, 45, 100) + sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_VIDEO_ENC_PARAMS); + if (sd) + { + unsigned int mb_h = (m_pFrame->height + 15) / 16; + unsigned int mb_w = (m_pFrame->width + 15) / 16; + unsigned int nb_mb = mb_h * mb_w; + unsigned int block_idx; + + auto par = reinterpret_cast<AVVideoEncParams*>(sd->data); + if (par->type == AV_VIDEO_ENC_PARAMS_MPEG2 && (par->nb_blocks == 0 || par->nb_blocks == nb_mb)) + { + pVideoPicture->qstride = mb_w; + pVideoPicture->qscale_type = par->type; + pVideoPicture->qp_table = static_cast<int8_t*>(av_malloc(nb_mb)); + for (block_idx = 0; block_idx < nb_mb; block_idx++) + { + AVVideoBlockParams* b = av_video_enc_params_block(par, block_idx); + pVideoPicture->qp_table[block_idx] = par->qp + b->delta_qp; + } + } + } +#else sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_QP_TABLE_PROPERTIES); if (sd) { @@ -1068,6 +1097,7 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(VideoPicture* pVideoPicture) pVideoPicture->qscale_type = qp->type; } } +#endif pVideoPicture->pict_type = m_pFrame->pict_type; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp index a98fbb1710108..3b2739cd22baa 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp @@ -118,6 +118,11 @@ void CDVDVideoPPFFmpeg::Process(VideoPicture* pPicture) m_pMode, m_pContext, pSource->pict_type | pSource->qscale_type ? PP_PICT_TYPE_QP2 : 0); + // https://github.com/FFmpeg/FFmpeg/blob/991d417692/doc/APIchanges#L18-L20 +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(58, 84, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(56, 45, 100) + av_free(pSource->qp_table); +#endif pPicture->SetParams(*pSource); if (pPicture->videoBuffer) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp index 7ad891083c7eb..eaf7b78d3237f 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp @@ -1259,8 +1259,16 @@ void CDecoder::ReturnRenderPicture(CVaapiRenderPicture *renderPic) IHardwareDecoder* CDecoder::Create(CDVDStreamInfo &hint, CProcessInfo &processInfo, AVPixelFormat fmt) { - if (fmt == AV_PIX_FMT_VAAPI_VLD && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(SETTING_VIDEOPLAYER_USEVAAPI)) + // https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4fdda160f4039fc2ae33edfd27765c9/doc/APIchanges#L18-L26 +#if LIBAVUTIL_BUILD >= AV_VERSION_INT(55, 8, 0) +#define PIX_FMT_VAAPI AV_PIX_FMT_VAAPI +#else +#define PIX_FMT_VAAPI AV_PIX_FMT_VAAPI_VLD +#endif + if (fmt == PIX_FMT_VAAPI && + CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(SETTING_VIDEOPLAYER_USEVAAPI)) return new VAAPI::CDecoder(processInfo); +#undef PIX_FMT_VAAPI return nullptr; } diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index 2bdc3ea5a9fc8..5be134e381a06 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -10,6 +10,7 @@ #include "DVDDemuxUtils.h" #include "DVDInputStreams/DVDInputStream.h" +#include "cores/FFmpeg.h" #include "cores/VideoPlayer/Interface/TimingConstants.h" #include "utils/log.h" @@ -130,7 +131,7 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt) if (stream->m_context == nullptr) { - AVCodec *codec = avcodec_find_decoder(st->codec); + FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(st->codec); if (codec == nullptr) { CLog::Log(LOGERROR, "{} - can't find decoder", __FUNCTION__); diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 739bf51922153..bf6f32227440a 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -38,6 +38,7 @@ extern "C" { +#include "libavutil/channel_layout.h" #include "libavutil/pixdesc.h" } @@ -235,7 +236,7 @@ bool CDVDDemuxFFmpeg::Aborted() bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool fileinfo) { - AVInputFormat* iformat = NULL; + FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr; std::string strFile; m_streaminfo = !pInput->IsRealtime() && !m_reopen; m_reopen = false; @@ -422,9 +423,7 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool // is present, we assume it is PCM audio. // AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS // may be just padded. - AVInputFormat* iformat2; - iformat2 = av_find_input_format("spdif"); - + FFMPEG_FMT_CONST AVInputFormat* iformat2 = av_find_input_format("spdif"); if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) { iformat = iformat2; @@ -544,11 +543,14 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool m_streaminfo = true; } + // https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4/doc/APIchanges#L18-L26 +#if LIBAVFORMAT_BUILD < AV_VERSION_INT(59, 0, 100) if (iformat && (strcmp(iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0)) { if (URIUtils::IsRemote(strFile)) m_pFormatContext->iformat->flags |= AVFMT_NOGENSEARCH; } +#endif // we need to know if this is matroska, avi or sup later m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" @@ -604,8 +606,11 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool // if format can be nonblocking, let's use that m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK; - // deprecated, will be always set in future versions + // https://github.com/FFmpeg/FFmpeg/blob/d682ae70b4/doc/APIchanges#L18-L21 +#if LIBAVFORMAT_BUILD < AV_VERSION_INT(57, 66, 105) && \ + LIBAVCODEC_BUILD < AV_VERSION_INT(57, 83, 101) m_pFormatContext->flags |= AVFMT_FLAG_KEEP_SIDE_DATA; +#endif UpdateCurrentPTS(); @@ -647,12 +652,24 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool { int idx = m_pFormatContext->programs[i]->stream_index[j]; AVStream* st = m_pFormatContext->streams[idx]; +#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 3, 100) + // Related to https://patchwork.ffmpeg.org/project/ffmpeg/patch/20210429143825.53040-1-jamrial@gmail.com/ + // has been replaced with AVSTREAM_EVENT_FLAG_NEW_PACKETS. + if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && + (st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)) || + (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate > 0)) + { + nProgram = i; + break; + } +#else if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->codec_info_nb_frames > 0) || (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate > 0)) { nProgram = i; break; } +#endif } } } @@ -1401,11 +1418,19 @@ void CDVDDemuxFFmpeg::UpdateCurrentPTS() if (idx >= 0) { AVStream* stream = m_pFormatContext->streams[idx]; +#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) + if (stream && m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE) + { + double ts = ConvertTimestamp(m_pkt.pkt.dts, stream->time_base.den, stream->time_base.num); + m_currentPts = ts; + } +#else if (stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE) { double ts = ConvertTimestamp(stream->cur_dts, stream->time_base.den, stream->time_base.num); m_currentPts = ts; } +#endif } } @@ -1621,7 +1646,12 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->iBitsPerSample = pStream->codecpar->bits_per_raw_sample; st->iChannelLayout = pStream->codecpar->channel_layout; char buf[32] = {}; + // https://github.com/FFmpeg/FFmpeg/blob/6ccc3989d15/doc/APIchanges#L50-L53 +#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 24, 100) + av_channel_layout_describe(st->iChannelLayout, buf, sizeof(buf)); +#else av_get_channel_layout_string(buf, 31, st->iChannels, st->iChannelLayout); +#endif st->m_channelLayoutName = buf; if (st->iBitsPerSample == 0) st->iBitsPerSample = pStream->codecpar->bits_per_coded_sample; @@ -1663,6 +1693,7 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->iFpsScale = 0; } +#if LIBAVFORMAT_BUILD < AV_VERSION_INT(59, 3, 100) if (pStream->codec_info_nb_frames > 0 && pStream->codec_info_nb_frames <= 2 && m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) @@ -1672,6 +1703,7 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->iFpsRate = 0; st->iFpsScale = 0; } +#endif st->iWidth = pStream->codecpar->width; st->iHeight = pStream->codecpar->height; @@ -1693,7 +1725,12 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->colorRange = pStream->codecpar->color_range; st->hdr_type = DetermineHdrType(pStream); + // https://github.com/FFmpeg/FFmpeg/blob/release/5.0/doc/APIchanges +#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 10, 100) + size_t size = 0; +#else int size = 0; +#endif uint8_t* side_data = nullptr; side_data = av_stream_get_side_data(pStream, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, &size); @@ -2103,7 +2140,7 @@ std::string CDVDDemuxFFmpeg::GetStreamCodecName(int iStreamId) return strName; } - AVCodec* codec = avcodec_find_decoder(stream->codec); + FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(stream->codec); if (codec) strName = avcodec_get_name(codec->id); } @@ -2279,7 +2316,7 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket* pkt) parser->second->m_parserCtx = av_parser_init(st->codecpar->codec_id); - AVCodec* codec = avcodec_find_decoder(st->codecpar->codec_id); + FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(st->codecpar->codec_id); if (codec == nullptr) { CLog::Log(LOGERROR, "{} - can't find decoder", __FUNCTION__); @@ -2357,7 +2394,12 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamAudioState() { if (!m_startTime) { +#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) + m_startTime = + av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; +#else m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; +#endif m_seekStream = idx; } return TRANSPORT_STREAM_STATE::READY; @@ -2377,7 +2419,12 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamAudioState() { if (!m_startTime) { +#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) + m_startTime = + av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; +#else m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; +#endif m_seekStream = i; } return TRANSPORT_STREAM_STATE::READY; @@ -2410,7 +2457,12 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamVideoState() { if (!m_startTime) { +#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) + m_startTime = + av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; +#else m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; +#endif m_seekStream = idx; } return TRANSPORT_STREAM_STATE::READY; @@ -2430,7 +2482,12 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamVideoState() { if (!m_startTime) { +#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) + m_startTime = + av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; +#else m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; +#endif m_seekStream = i; } return TRANSPORT_STREAM_STATE::READY; diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp index b8494e504e385..392853cc6809a 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp @@ -12,6 +12,7 @@ #include "addons/addoninfo/AddonType.h" #include "addons/binary-addons/AddonDll.h" #include "addons/kodi-dev-kit/include/kodi/addon-instance/VideoCodec.h" +#include "cores/FFmpeg.h" #include "cores/VideoPlayer/DVDDemuxers/DVDDemux.h" #include "cores/VideoPlayer/DVDDemuxers/DVDDemuxUtils.h" #include "cores/VideoPlayer/Interface/DemuxCrypto.h" @@ -392,7 +393,7 @@ KODI_HANDLE CInputStreamAddon::cb_get_stream_transfer(KODI_HANDLE handle, return nullptr; std::string codecName(stream->m_codecName); - AVCodec* codec = nullptr; + FFMPEG_FMT_CONST AVCodec* codec = nullptr; if (stream->m_streamType != INPUTSTREAM_TYPE_TELETEXT && stream->m_streamType != INPUTSTREAM_TYPE_RDS && stream->m_streamType != INPUTSTREAM_TYPE_ID3) diff --git a/xbmc/filesystem/AudioBookFileDirectory.cpp b/xbmc/filesystem/AudioBookFileDirectory.cpp index 04d1c14343386..d82b2a9bbda9c 100644 --- a/xbmc/filesystem/AudioBookFileDirectory.cpp +++ b/xbmc/filesystem/AudioBookFileDirectory.cpp @@ -11,6 +11,7 @@ #include "TextureDatabase.h" #include "URL.h" #include "Util.h" +#include "cores/FFmpeg.h" #include "filesystem/File.h" #include "guilib/LocalizeStrings.h" #include "music/tags/MusicInfoTag.h" @@ -149,7 +150,7 @@ bool CAudioBookFileDirectory::ContainsFiles(const CURL& url) m_ioctx->max_packet_size = 32768; - AVInputFormat* iformat=nullptr; + FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr; av_probe_input_buffer(m_ioctx, &iformat, url.Get().c_str(), nullptr, 0, 0); bool contains = false; diff --git a/xbmc/guilib/FFmpegImage.cpp b/xbmc/guilib/FFmpegImage.cpp index fa255278b74ca..9d01a21f38b1e 100644 --- a/xbmc/guilib/FFmpegImage.cpp +++ b/xbmc/guilib/FFmpegImage.cpp @@ -52,7 +52,7 @@ struct ThumbDataManagement AVFrame* frame_temporary = nullptr; SwsContext* sws = nullptr; AVCodecContext* avOutctx = nullptr; - AVCodec* codec = nullptr; + FFMPEG_FMT_CONST AVCodec* codec = nullptr; ~ThumbDataManagement() { av_free(intermediateBuffer); @@ -198,7 +198,7 @@ bool CFFmpegImage::Initialize(unsigned char* buffer, size_t bufSize) bool is_png = (bufSize > 3 && buffer[1] == 'P' && buffer[2] == 'N' && buffer[3] == 'G'); bool is_tiff = (bufSize > 2 && buffer[0] == 'I' && buffer[1] == 'I' && buffer[2] == '*'); - AVInputFormat* inp = nullptr; + FFMPEG_FMT_CONST AVInputFormat* inp = nullptr; if (is_jpeg) inp = av_find_input_format("image2"); else if (m_strMimeType == "image/apng") @@ -236,7 +236,7 @@ bool CFFmpegImage::Initialize(unsigned char* buffer, size_t bufSize) return false; } AVCodecParameters* codec_params = m_fctx->streams[0]->codecpar; - AVCodec* codec = avcodec_find_decoder(codec_params->codec_id); + FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(codec_params->codec_id); m_codec_ctx = avcodec_alloc_context3(codec); if (!m_codec_ctx) { diff --git a/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp b/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp index 9bb2cdc09ba5c..dbd8893c97b6e 100644 --- a/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp +++ b/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp @@ -58,7 +58,7 @@ bool CMusicInfoTagLoaderFFmpeg::Load(const std::string& strFileName, CMusicInfoT if (file.IoControl(IOCTRL_SEEK_POSSIBLE, NULL) != 1) ioctx->seekable = 0; - AVInputFormat* iformat=NULL; + FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr; av_probe_input_buffer(ioctx, &iformat, strFileName.c_str(), NULL, 0, 0); if (avformat_open_input(&fctx, strFileName.c_str(), iformat, NULL) < 0) diff --git a/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp b/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp index c1b0495179c1d..5564696be65fc 100644 --- a/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp +++ b/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp @@ -65,7 +65,7 @@ CVideoTagLoaderFFmpeg::CVideoTagLoaderFFmpeg(const CFileItem& item, if (m_file->IoControl(IOCTRL_SEEK_POSSIBLE, nullptr) != 1) m_ioctx->seekable = 0; - AVInputFormat* iformat = nullptr; + FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr; av_probe_input_buffer(m_ioctx, &iformat, m_item.GetPath().c_str(), nullptr, 0, 0); if (avformat_open_input(&m_fctx, m_item.GetPath().c_str(), iformat, nullptr) < 0) { From 3de036ef45b0df3368997500d210090a7f6ff5e7 Mon Sep 17 00:00:00 2001 From: Vasyl Gello <vasek.gello@gmail.com> Date: Thu, 13 Oct 2022 04:56:26 +0000 Subject: [PATCH 2/7] Use Channel Layout API if built against FFmpeg 5.1 Signed-off-by: Vasyl Gello <vasek.gello@gmail.com> --- xbmc/cdrip/EncoderFFmpeg.cpp | 51 +++++++++++++ .../AudioEngine/Encoders/AEEncoderFFmpeg.cpp | 60 ++++++++++++++- .../AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 22 ++++++ .../Engines/ActiveAE/ActiveAEFilter.cpp | 38 +++++++++- .../ActiveAE/ActiveAEResampleFFMPEG.cpp | 55 +++++++++++++- .../Engines/ActiveAE/ActiveAEStream.cpp | 2 +- xbmc/cores/AudioEngine/Utils/AEUtil.cpp | 73 +++++++++++++++++-- xbmc/cores/AudioEngine/Utils/AEUtil.h | 9 ++- .../DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp | 58 ++++++++++++--- .../DVDDemuxers/DVDDemuxClient.cpp | 15 +++- .../DVDDemuxers/DVDDemuxFFmpeg.cpp | 42 +++++++++-- 11 files changed, 388 insertions(+), 37 deletions(-) diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp index 4c0628b5cc108..c05cdeab9eece 100644 --- a/xbmc/cdrip/EncoderFFmpeg.cpp +++ b/xbmc/cdrip/EncoderFFmpeg.cpp @@ -94,8 +94,14 @@ bool CEncoderFFmpeg::Init() /* Set the basic encoder parameters. * The input file's sample rate is used to avoid a sample rate conversion. */ +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_codecCtx->ch_layout); + av_channel_layout_default(&m_codecCtx->ch_layout, m_iInChannels); +#else m_codecCtx->channels = m_iInChannels; m_codecCtx->channel_layout = av_get_default_channel_layout(m_iInChannels); +#endif m_codecCtx->sample_rate = m_iInSampleRate; m_codecCtx->sample_fmt = codec->sample_fmts[0]; m_codecCtx->bit_rate = bitrate; @@ -140,7 +146,14 @@ bool CEncoderFFmpeg::Init() m_bufferFrame->nb_samples = m_codecCtx->frame_size; m_bufferFrame->format = m_inFormat; + +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_bufferFrame->ch_layout); + av_channel_layout_copy(&m_bufferFrame->ch_layout, &m_codecCtx->ch_layout); +#else m_bufferFrame->channel_layout = m_codecCtx->channel_layout; +#endif m_bufferFrame->sample_rate = m_codecCtx->sample_rate; err = av_frame_get_buffer(m_bufferFrame, 0); @@ -152,10 +165,18 @@ bool CEncoderFFmpeg::Init() if (m_needConversion) { +#if LIBSWRESAMPLE_BUILD >= AV_VERSION_INT(4, 7, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int ret = swr_alloc_set_opts2(&m_swrCtx, &m_codecCtx->ch_layout, m_outFormat, + m_codecCtx->sample_rate, &m_codecCtx->ch_layout, m_inFormat, + m_codecCtx->sample_rate, 0, nullptr); + if (ret || swr_init(m_swrCtx) < 0) +#else m_swrCtx = swr_alloc_set_opts(nullptr, m_codecCtx->channel_layout, m_outFormat, m_codecCtx->sample_rate, m_codecCtx->channel_layout, m_inFormat, m_codecCtx->sample_rate, 0, nullptr); if (!m_swrCtx || swr_init(m_swrCtx) < 0) +#endif throw FFMpegException("Failed to initialize the resampler"); m_resampledBufferSize = @@ -167,7 +188,13 @@ bool CEncoderFFmpeg::Init() m_resampledFrame->nb_samples = m_neededFrames; m_resampledFrame->format = m_outFormat; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_resampledFrame->ch_layout); + av_channel_layout_copy(&m_resampledFrame->ch_layout, &m_codecCtx->ch_layout); +#else m_resampledFrame->channel_layout = m_codecCtx->channel_layout; +#endif m_resampledFrame->sample_rate = m_codecCtx->sample_rate; err = av_frame_get_buffer(m_resampledFrame, 0); @@ -203,11 +230,23 @@ bool CEncoderFFmpeg::Init() CLog::Log(LOGERROR, "CEncoderFFmpeg::{} - {}", __func__, caught.what()); av_freep(&m_buffer); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_bufferFrame->ch_layout); +#endif av_frame_free(&m_bufferFrame); swr_free(&m_swrCtx); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_resampledFrame->ch_layout); +#endif av_frame_free(&m_resampledFrame); av_freep(&m_resampledBuffer); av_free(m_bcBuffer); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_codecCtx->ch_layout); +#endif avcodec_free_context(&m_codecCtx); if (m_formatCtx) { @@ -351,8 +390,16 @@ bool CEncoderFFmpeg::Close() /* Flush if needed */ av_freep(&m_buffer); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_bufferFrame->ch_layout); +#endif av_frame_free(&m_bufferFrame); swr_free(&m_swrCtx); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_resampledFrame->ch_layout); +#endif av_frame_free(&m_resampledFrame); av_freep(&m_resampledBuffer); m_needConversion = false; @@ -364,6 +411,10 @@ bool CEncoderFFmpeg::Close() /* cleanup */ av_free(m_bcBuffer); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_codecCtx->ch_layout); +#endif avcodec_free_context(&m_codecCtx); av_freep(&m_formatCtx->pb); avformat_free_context(m_formatCtx); diff --git a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp index 86f65f57f330a..5d8ca71de1969 100644 --- a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp +++ b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp @@ -37,6 +37,10 @@ CAEEncoderFFmpeg::~CAEEncoderFFmpeg() { Reset(); swr_free(&m_SwrCtx); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_CodecCtx->ch_layout); +#endif avcodec_free_context(&m_CodecCtx); } @@ -113,7 +117,13 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input m_CodecCtx->bit_rate = m_BitRate; m_CodecCtx->sample_rate = format.m_sampleRate; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_CodecCtx->ch_layout); + av_channel_layout_from_mask(&m_CodecCtx->ch_layout, AV_CH_LAYOUT_5POINT1_BACK); +#else m_CodecCtx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK; +#endif /* select a suitable data format */ if (codec->sample_fmts) @@ -190,22 +200,44 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input LOGERROR, "CAEEncoderFFmpeg::Initialize - Unable to find a suitable data format for the codec ({})", m_CodecName); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_CodecCtx->ch_layout); +#endif avcodec_free_context(&m_CodecCtx); return false; } } +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + uint64_t mask = m_CodecCtx->ch_layout.u.mask; + av_channel_layout_uninit(&m_CodecCtx->ch_layout); + av_channel_layout_from_mask(&m_CodecCtx->ch_layout, mask); + m_CodecCtx->ch_layout.nb_channels = BuildChannelLayout(mask, m_Layout); +#else m_CodecCtx->channels = BuildChannelLayout(m_CodecCtx->channel_layout, m_Layout); +#endif /* open the codec */ if (avcodec_open2(m_CodecCtx, codec, NULL)) { +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_CodecCtx->ch_layout); +#endif avcodec_free_context(&m_CodecCtx); return false; } format.m_frames = m_CodecCtx->frame_size; - format.m_frameSize = m_CodecCtx->channels * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int channels = m_CodecCtx->ch_layout.nb_channels; +#else + int channels = m_CodecCtx->channels; +#endif + format.m_frameSize = channels * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3); format.m_channelLayout = m_Layout; m_CurrentFormat = format; @@ -215,14 +247,26 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input if (m_NeedConversion) { +#if LIBSWRESAMPLE_BUILD >= AV_VERSION_INT(4, 7, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int ret = swr_alloc_set_opts2(&m_SwrCtx, &m_CodecCtx->ch_layout, m_CodecCtx->sample_fmt, + m_CodecCtx->sample_rate, &m_CodecCtx->ch_layout, + AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate, 0, NULL); + if (ret || swr_init(m_SwrCtx) < 0) +#else m_SwrCtx = swr_alloc_set_opts(NULL, m_CodecCtx->channel_layout, m_CodecCtx->sample_fmt, m_CodecCtx->sample_rate, m_CodecCtx->channel_layout, AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate, 0, NULL); if (!m_SwrCtx || swr_init(m_SwrCtx) < 0) +#endif { CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Initialize - Failed to initialise resampler."); swr_free(&m_SwrCtx); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_CodecCtx->ch_layout); +#endif avcodec_free_context(&m_CodecCtx); return false; } @@ -276,10 +320,18 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz frame->nb_samples = m_CodecCtx->frame_size; frame->format = m_CodecCtx->sample_fmt; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&frame->ch_layout); + av_channel_layout_copy(&frame->ch_layout, &m_CodecCtx->ch_layout); + int channelNum = m_CodecCtx->ch_layout.nb_channels; +#else frame->channel_layout = m_CodecCtx->channel_layout; frame->channels = m_CodecCtx->channels; + int channelNum = m_CodecCtx->channels; +#endif - avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt, in, in_size, 0); + avcodec_fill_audio_frame(frame, channelNum, m_CodecCtx->sample_fmt, in, in_size, 0); pkt->size = out_size; pkt->data = out; @@ -295,6 +347,10 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz err = avcodec_receive_packet(m_CodecCtx, pkt); if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) { +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&frame->ch_layout); +#endif av_frame_free(&frame); av_packet_free(&pkt); return (err == AVERROR(EAGAIN)) ? -1 : 0; diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp index 6000fe9c6357a..9cd3bddda884e 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -3069,8 +3069,14 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) AVCodecID codecId = fmt_ctx->streams[0]->codecpar->codec_id; dec = avcodec_find_decoder(codecId); config.sample_rate = fmt_ctx->streams[0]->codecpar->sample_rate; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + config.channels = fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels; + config.channel_layout = fmt_ctx->streams[0]->codecpar->ch_layout.u.mask; +#else config.channels = fmt_ctx->streams[0]->codecpar->channels; config.channel_layout = fmt_ctx->streams[0]->codecpar->channel_layout; +#endif } } if (dec == nullptr) @@ -3086,10 +3092,22 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) dec_ctx = avcodec_alloc_context3(dec); dec_ctx->sample_rate = config.sample_rate; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + AVChannelLayout layout = {}; + if (!config.channel_layout) + av_channel_layout_default(&layout, config.channels); + else + av_channel_layout_from_mask(&layout, config.channel_layout); + config.channel_layout = layout.u.mask; + av_channel_layout_copy(&dec_ctx->ch_layout, &layout); + av_channel_layout_uninit(&layout); +#else dec_ctx->channels = config.channels; if (!config.channel_layout) config.channel_layout = av_get_default_channel_layout(config.channels); dec_ctx->channel_layout = config.channel_layout; +#endif AVPacket* avpkt = av_packet_alloc(); if (!avpkt) @@ -3156,6 +3174,10 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) av_packet_free(&avpkt); av_frame_free(&decoded_frame); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&dec_ctx->ch_layout); +#endif avcodec_free_context(&dec_ctx); avformat_close_input(&fmt_ctx); if (io_ctx) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp index 26b669a2cf68c..1d79dc6db40be 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp @@ -12,10 +12,11 @@ #include <algorithm> extern "C" { -#include <libavfilter/avfilter.h> #include <libavcodec/avcodec.h> +#include <libavfilter/avfilter.h> #include <libavfilter/buffersink.h> #include <libavfilter/buffersrc.h> +#include <libavutil/version.h> #include <libswresample/swresample.h> } @@ -171,7 +172,13 @@ void CActiveAEFilter::CloseFilter() } if (m_pOutFrame) + { +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_pOutFrame->ch_layout); +#endif av_frame_free(&m_pOutFrame); + } if (m_pConvertFrame) av_frame_free(&m_pConvertFrame); @@ -205,10 +212,17 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ if (!frame) return -1; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&frame->ch_layout); + av_channel_layout_from_mask(&frame->ch_layout, m_channelLayout); + int channels = frame->ch_layout.nb_channels; +#else int channels = av_get_channel_layout_nb_channels(m_channelLayout); frame->channel_layout = m_channelLayout; frame->channels = channels; +#endif frame->sample_rate = m_sampleRate; frame->nb_samples = src_samples; frame->format = m_sampleFormat; @@ -224,6 +238,10 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ src_buffer[0], src_bufsize, 16); if (result < 0) { +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&frame->ch_layout); +#endif av_frame_free(&frame); CLog::Log(LOGERROR, "CActiveAEFilter::ProcessFilter - avcodec_fill_audio_frame failed"); m_filterEof = true; @@ -231,6 +249,10 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ } result = av_buffersrc_write_frame(m_pFilterCtxIn, frame); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&frame->ch_layout); +#endif av_frame_free(&frame); if (result < 0) { @@ -284,7 +306,13 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ { av_frame_unref(m_pOutFrame); m_pOutFrame->format = m_sampleFormat; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_pOutFrame->ch_layout); + av_channel_layout_from_mask(&m_pOutFrame->ch_layout, m_channelLayout); +#else m_pOutFrame->channel_layout = m_channelLayout; +#endif m_pOutFrame->sample_rate = m_sampleRate; result = swr_convert_frame(m_pConvertCtx, m_pOutFrame, m_pConvertFrame); av_frame_unref(m_pConvertFrame); @@ -302,7 +330,15 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ if (m_hasData) { +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + AVChannelLayout layout = {}; + av_channel_layout_from_mask(&layout, m_channelLayout); + int channels = layout.nb_channels; + av_channel_layout_uninit(&layout); +#else int channels = av_get_channel_layout_nb_channels(m_channelLayout); +#endif int planes = av_sample_fmt_is_planar(m_sampleFormat) ? channels : 1; int samples = std::min(dst_samples, m_pOutFrame->nb_samples - m_sampleOffset); int bytes = samples * av_get_bytes_per_sample(m_sampleFormat) * channels / planes; diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp index bfef8371144df..379dfe644635f 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp @@ -11,8 +11,10 @@ #include "utils/log.h" extern "C" { +#include <libavcodec/version.h> #include <libavutil/channel_layout.h> #include <libavutil/opt.h> +#include <libavutil/version.h> #include <libswresample/swresample.h> } @@ -49,15 +51,49 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi m_doesResample = true; if (m_dst_chan_layout == 0) +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + { + AVChannelLayout layout = {}; + av_channel_layout_default(&layout, m_dst_channels); + m_dst_chan_layout = layout.u.mask; + av_channel_layout_uninit(&layout); + } +#else m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels); +#endif if (m_src_chan_layout == 0) +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + { + AVChannelLayout layout = {}; + av_channel_layout_default(&layout, m_src_channels); + m_src_chan_layout = layout.u.mask; + av_channel_layout_uninit(&layout); + } +#else m_src_chan_layout = av_get_default_channel_layout(m_src_channels); +#endif + +#if LIBSWRESAMPLE_BUILD >= AV_VERSION_INT(4, 7, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + AVChannelLayout dstChLayout = {}; + AVChannelLayout srcChLayout = {}; + av_channel_layout_from_mask(&dstChLayout, m_dst_chan_layout); + av_channel_layout_from_mask(&srcChLayout, m_src_chan_layout); + + int ret = swr_alloc_set_opts2(&m_pContext, &dstChLayout, m_dst_fmt, m_dst_rate, &srcChLayout, + m_src_fmt, m_src_rate, 0, NULL); + + if (ret) +#else m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, m_dst_fmt, m_dst_rate, m_src_chan_layout, m_src_fmt, m_src_rate, 0, NULL); if (!m_pContext) +#endif { CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - create context failed"); return false; @@ -126,10 +162,20 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi else if (upmix && m_src_channels == 2 && m_dst_channels > 2) { memset(m_rematrix, 0, sizeof(m_rematrix)); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&dstChLayout); + av_channel_layout_from_mask(&dstChLayout, m_dst_chan_layout); +#endif for (int out=0; out<m_dst_channels; out++) { - uint64_t out_chan = av_channel_layout_extract_channel(m_dst_chan_layout, out); - switch(out_chan) +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + AVChannel outChan = av_channel_layout_channel_from_index(&dstChLayout, out); +#else + uint64_t outChan = av_channel_layout_extract_channel(m_dst_chan_layout, out); +#endif + switch (outChan) { case AV_CH_FRONT_LEFT: case AV_CH_BACK_LEFT: @@ -154,6 +200,11 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi } } +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&dstChLayout); +#endif + if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) { CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - setting channel matrix failed"); diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp index 858b0f2f22056..a52ac2829f7b0 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp @@ -88,7 +88,7 @@ void CActiveAEStream::InitRemapper() for(unsigned int i=0; i<m_format.m_channelLayout.Count(); i++) { avLast = avCur; - avCur = CAEUtil::GetAVChannel(m_format.m_channelLayout[i]); + avCur = CAEUtil::GetAVChannelMask(m_format.m_channelLayout[i]); if(avCur < avLast) { needRemap = true; diff --git a/xbmc/cores/AudioEngine/Utils/AEUtil.cpp b/xbmc/cores/AudioEngine/Utils/AEUtil.cpp index bfa2cf9e4cfa8..98f82816efc32 100644 --- a/xbmc/cores/AudioEngine/Utils/AEUtil.cpp +++ b/xbmc/cores/AudioEngine/Utils/AEUtil.cpp @@ -19,10 +19,6 @@ #include <xmmintrin.h> #endif -extern "C" { -#include <libavutil/channel_layout.h> -} - void AEDelayStatus::SetDelay(double d) { delay = d; @@ -550,8 +546,15 @@ AVSampleFormat CAEUtil::GetAVSampleFormat(AEDataFormat format) } } -uint64_t CAEUtil::GetAVChannel(enum AEChannel aechannel) +uint64_t CAEUtil::GetAVChannelMask(enum AEChannel aechannel) { +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + enum AVChannel ch = GetAVChannel(aechannel); + if (ch == AV_CHAN_NONE) + return 0; + return (1ULL << ch); +#else switch (aechannel) { case AE_CH_FL: return AV_CH_FRONT_LEFT; @@ -575,9 +578,67 @@ uint64_t CAEUtil::GetAVChannel(enum AEChannel aechannel) default: return 0; } +#endif } +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) +enum AVChannel CAEUtil::GetAVChannel(enum AEChannel aechannel) +{ + switch (aechannel) + { + case AE_CH_FL: + return AV_CHAN_FRONT_LEFT; + case AE_CH_FR: + return AV_CHAN_FRONT_RIGHT; + case AE_CH_FC: + return AV_CHAN_FRONT_CENTER; + case AE_CH_LFE: + return AV_CHAN_LOW_FREQUENCY; + case AE_CH_BL: + return AV_CHAN_BACK_LEFT; + case AE_CH_BR: + return AV_CHAN_BACK_RIGHT; + case AE_CH_FLOC: + return AV_CHAN_FRONT_LEFT_OF_CENTER; + case AE_CH_FROC: + return AV_CHAN_FRONT_RIGHT_OF_CENTER; + case AE_CH_BC: + return AV_CHAN_BACK_CENTER; + case AE_CH_SL: + return AV_CHAN_SIDE_LEFT; + case AE_CH_SR: + return AV_CHAN_SIDE_RIGHT; + case AE_CH_TC: + return AV_CHAN_TOP_CENTER; + case AE_CH_TFL: + return AV_CHAN_TOP_FRONT_LEFT; + case AE_CH_TFC: + return AV_CHAN_TOP_FRONT_CENTER; + case AE_CH_TFR: + return AV_CHAN_TOP_FRONT_RIGHT; + case AE_CH_TBL: + return AV_CHAN_TOP_BACK_LEFT; + case AE_CH_TBC: + return AV_CHAN_TOP_BACK_CENTER; + case AE_CH_TBR: + return AV_CHAN_TOP_BACK_RIGHT; + default: + return AV_CHAN_NONE; + } +} +#endif + int CAEUtil::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout) { - return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel)); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + AVChannelLayout ch_layout = {}; + av_channel_layout_from_mask(&ch_layout, layout); + int idx = av_channel_layout_index_from_channel(&ch_layout, GetAVChannel(aechannel)); + av_channel_layout_uninit(&ch_layout); + return idx; +#else + return av_get_channel_layout_channel_index(layout, GetAVChannelMask(aechannel)); +#endif } diff --git a/xbmc/cores/AudioEngine/Utils/AEUtil.h b/xbmc/cores/AudioEngine/Utils/AEUtil.h index 034e115ee8a6d..8acbeec44212f 100644 --- a/xbmc/cores/AudioEngine/Utils/AEUtil.h +++ b/xbmc/cores/AudioEngine/Utils/AEUtil.h @@ -13,7 +13,10 @@ #include <math.h> extern "C" { +#include <libavcodec/version.h> +#include <libavutil/channel_layout.h> #include <libavutil/samplefmt.h> +#include <libavutil/version.h> } // AV sync options @@ -171,6 +174,10 @@ class CAEUtil static uint64_t GetAVChannelLayout(const CAEChannelInfo &info); static CAEChannelInfo GetAEChannelLayout(uint64_t layout); static AVSampleFormat GetAVSampleFormat(AEDataFormat format); - static uint64_t GetAVChannel(enum AEChannel aechannel); + static uint64_t GetAVChannelMask(enum AEChannel aechannel); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + static enum AVChannel GetAVChannel(enum AEChannel aechannel); +#endif static int GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout); }; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp index 87e7ae2c5785b..44dcb32620f9b 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp @@ -78,7 +78,14 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options m_matrixEncoding = AV_MATRIX_ENCODING_NONE; m_channels = 0; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + av_channel_layout_uninit(&m_pCodecContext->ch_layout); + m_pCodecContext->ch_layout.order = AV_CHANNEL_ORDER_NATIVE; + m_pCodecContext->ch_layout.nb_channels = hints.channels; +#else m_pCodecContext->channels = hints.channels; +#endif m_hint_layout = hints.channellayout; m_pCodecContext->sample_rate = hints.samplerate; m_pCodecContext->block_align = hints.blockalign; @@ -261,12 +268,18 @@ int CDVDAudioCodecFFmpeg::GetData(uint8_t** dst) m_format.m_frameSize = m_format.m_channelLayout.Count() * CAEUtil::DataFormatToBits(m_format.m_dataFormat) >> 3; - int planes = av_sample_fmt_is_planar(m_pCodecContext->sample_fmt) ? m_pFrame->channels : 1; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int channels = m_pFrame->ch_layout.nb_channels; +#else + int channels = m_pFrame->channels; +#endif + int planes = av_sample_fmt_is_planar(m_pCodecContext->sample_fmt) ? channels : 1; + for (int i=0; i<planes; i++) dst[i] = m_pFrame->extended_data[i]; - return m_pFrame->nb_samples * m_pFrame->channels * - av_get_bytes_per_sample(m_pCodecContext->sample_fmt); + return m_pFrame->nb_samples * channels * av_get_bytes_per_sample(m_pCodecContext->sample_fmt); } return 0; @@ -280,7 +293,12 @@ void CDVDAudioCodecFFmpeg::Reset() int CDVDAudioCodecFFmpeg::GetChannels() { +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + return m_pCodecContext->ch_layout.nb_channels; +#else return m_pCodecContext->channels; +#endif } int CDVDAudioCodecFFmpeg::GetSampleRate() @@ -347,28 +365,44 @@ static unsigned count_bits(int64_t value) void CDVDAudioCodecFFmpeg::BuildChannelMap() { - if (m_channels == m_pCodecContext->channels && m_layout == m_pCodecContext->channel_layout) +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int codecChannels = m_pCodecContext->ch_layout.nb_channels; + uint64_t codecChannelLayout = m_pCodecContext->ch_layout.u.mask; +#else + int codecChannels = m_pCodecContext->channels; + uint64_t codecChannelLayout = m_pCodecContext->channel_layout; +#endif + if (m_channels == codecChannels && m_layout == codecChannelLayout) return; //nothing to do here - m_channels = m_pCodecContext->channels; - m_layout = m_pCodecContext->channel_layout; + m_channels = codecChannels; + m_layout = codecChannelLayout; int64_t layout; - int bits = count_bits(m_pCodecContext->channel_layout); - if (bits == m_pCodecContext->channels) - layout = m_pCodecContext->channel_layout; + int bits = count_bits(codecChannelLayout); + if (bits == codecChannels) + layout = codecChannelLayout; else { CLog::Log(LOGINFO, "CDVDAudioCodecFFmpeg::GetChannelMap - FFmpeg reported {} channels, but the layout " "contains {} - trying hints", - m_pCodecContext->channels, bits); - if (static_cast<int>(count_bits(m_hint_layout)) == m_pCodecContext->channels) + codecChannels, bits); + if (static_cast<int>(count_bits(m_hint_layout)) == codecChannels) layout = m_hint_layout; else { +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + AVChannelLayout def_layout = {}; + av_channel_layout_default(&def_layout, codecChannels); + layout = def_layout.u.mask; + av_channel_layout_uninit(&def_layout); +#else layout = av_get_default_channel_layout(m_pCodecContext->channels); +#endif CLog::Log(LOGINFO, "Using default layout..."); } } @@ -394,7 +428,7 @@ void CDVDAudioCodecFFmpeg::BuildChannelMap() if (layout & AV_CH_TOP_BACK_CENTER ) m_channelLayout += AE_CH_BC ; if (layout & AV_CH_TOP_BACK_RIGHT ) m_channelLayout += AE_CH_BR ; - m_channels = m_pCodecContext->channels; + m_channels = codecChannels; } CAEChannelInfo CDVDAudioCodecFFmpeg::GetChannelMap() diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index 5be134e381a06..70f0562462bf2 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -220,10 +220,17 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt) case STREAM_AUDIO: { CDemuxStreamClientInternalTpl<CDemuxStreamAudio>* sta = static_cast<CDemuxStreamClientInternalTpl<CDemuxStreamAudio>*>(st); - if (stream->m_context->channels != sta->iChannels && stream->m_context->channels != 0) +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int streamChannels = stream->m_context->ch_layout.nb_channels; +#else + int streamChannels = stream->m_context->channels; +#endif + if (streamChannels != sta->iChannels && streamChannels != 0) { - CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - ({}) channels changed from {} to {}", st->uniqueId, sta->iChannels, stream->m_context->channels); - sta->iChannels = stream->m_context->channels; + CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - ({}) channels changed from {} to {}", + st->uniqueId, sta->iChannels, streamChannels); + sta->iChannels = streamChannels; sta->changes++; sta->disabled = false; } @@ -235,7 +242,7 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt) sta->changes++; sta->disabled = false; } - if (stream->m_context->channels) + if (streamChannels) st->changes = -1; // stop parsing break; } diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index bf6f32227440a..4ad52cd32a115 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1235,8 +1235,16 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() else if (stream->type == STREAM_AUDIO) { CDemuxStreamAudioFFmpeg* audiostream = dynamic_cast<CDemuxStreamAudioFFmpeg*>(stream); - if (audiostream && (audiostream->iChannels != m_pFormatContext->streams[pPacket->iStreamId]->codecpar->channels || - audiostream->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codecpar->sample_rate)) +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int codecparChannels = + m_pFormatContext->streams[pPacket->iStreamId]->codecpar->ch_layout.nb_channels; +#else + int codecparChannels = m_pFormatContext->streams[pPacket->iStreamId]->codecpar->channels; +#endif + if (audiostream && (audiostream->iChannels != codecparChannels || + audiostream->iSampleRate != + m_pFormatContext->streams[pPacket->iStreamId]->codecpar->sample_rate)) { // content has changed stream = AddStream(pPacket->iStreamId); @@ -1418,6 +1426,7 @@ void CDVDDemuxFFmpeg::UpdateCurrentPTS() if (idx >= 0) { AVStream* stream = m_pFormatContext->streams[idx]; + #if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) if (stream && m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE) { @@ -1639,16 +1648,28 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) { CDemuxStreamAudioFFmpeg* st = new CDemuxStreamAudioFFmpeg(pStream); stream = st; - st->iChannels = pStream->codecpar->channels; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int codecparChannels = pStream->codecpar->ch_layout.nb_channels; + int codecparChannelLayout = pStream->codecpar->ch_layout.u.mask; +#else + int codecparChannels = pStream->codecpar->channels; + int codecparChannelLayout = pStream->codecpar->channel_layout; +#endif + st->iChannels = codecparChannels; + st->iChannelLayout = codecparChannelLayout; st->iSampleRate = pStream->codecpar->sample_rate; st->iBlockAlign = pStream->codecpar->block_align; st->iBitRate = static_cast<int>(pStream->codecpar->bit_rate); st->iBitsPerSample = pStream->codecpar->bits_per_raw_sample; - st->iChannelLayout = pStream->codecpar->channel_layout; char buf[32] = {}; // https://github.com/FFmpeg/FFmpeg/blob/6ccc3989d15/doc/APIchanges#L50-L53 -#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 24, 100) - av_channel_layout_describe(st->iChannelLayout, buf, sizeof(buf)); +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + AVChannelLayout layout = {}; + av_channel_layout_from_mask(&layout, st->iChannelLayout); + av_channel_layout_describe(&layout, buf, sizeof(buf)); + av_channel_layout_uninit(&layout); #else av_get_channel_layout_string(buf, 31, st->iChannels, st->iChannelLayout); #endif @@ -2195,8 +2216,13 @@ bool CDVDDemuxFFmpeg::IsProgramChange() if (m_pFormatContext->streams[idx]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { CDemuxStreamAudioFFmpeg* audiostream = dynamic_cast<CDemuxStreamAudioFFmpeg*>(stream); - if (audiostream && - m_pFormatContext->streams[idx]->codecpar->channels != audiostream->iChannels) +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ + LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) + int codecparChannels = m_pFormatContext->streams[idx]->codecpar->ch_layout.nb_channels; +#else + int codecparChannels = m_pFormatContext->streams[idx]->codecpar->channels; +#endif + if (audiostream && codecparChannels != audiostream->iChannels) { return true; } From 0a10e05700dfd12b7f5d720588b993089ea33be4 Mon Sep 17 00:00:00 2001 From: Vasyl Gello <vasek.gello@gmail.com> Date: Sat, 15 Oct 2022 11:46:52 +0000 Subject: [PATCH 3/7] ffmpeg5: Get extradata with extract_extradata BSF Fixes the transport stream playback failures described in https://bugs.debian.org/1016925 Rogo95 made an excellent technical analysis of the root cause and reported that to the bug thread. Later on, James Almer (jamrial) suggested the solution to use extract_extradata bitstream filter to replace the removed split() function. Finally, I adapted the following code snippet: https://gist.github.com/moonpfe/f6795d51294d91ee0f82f62ff6985db0 to Kodi and tested it by playing the affected files in TS format. HiassofT form LibreELEC found another edge case decoding HTSP streams from pvr.hts. The comparison of log files revealed that the split function is also used in DVDDemuxClient. Signed-off-by: Vasyl Gello <vasek.gello@gmail.com> --- xbmc/cores/FFmpeg.cpp | 154 ++++++++++++++++++ xbmc/cores/FFmpeg.h | 5 + .../DVDDemuxers/DVDDemuxClient.cpp | 37 ++--- .../DVDDemuxers/DVDDemuxFFmpeg.cpp | 61 +++---- 4 files changed, 203 insertions(+), 54 deletions(-) diff --git a/xbmc/cores/FFmpeg.cpp b/xbmc/cores/FFmpeg.cpp index de1765ed52558..eb9c653fa3d06 100644 --- a/xbmc/cores/FFmpeg.cpp +++ b/xbmc/cores/FFmpeg.cpp @@ -16,6 +16,11 @@ #include "utils/StringUtils.h" #include "utils/log.h" +extern "C" +{ +#include <libavcodec/bsf.h> +} + #include <map> #include <mutex> @@ -129,3 +134,152 @@ void ff_avutil_log(void* ptr, int level, const char* format, va_list va) } buffer.erase(0, start); } + +std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, + const AVCodecParserContext* parserCtx, + AVCodecContext* codecCtx) +{ + constexpr int FF_MAX_EXTRADATA_SIZE = ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE); + + if (!pkt) + return std::make_tuple(nullptr, 0); + + uint8_t* extraData = nullptr; + int extraDataSize = 0; + +#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 0, 100) + /* extract_extradata bitstream filter is implemented only + * for certain codecs, as noted in discussion of PR#21248 + */ + + AVCodecID codecId = codecCtx->codec_id; + + // clang-format off + if ( + codecId != AV_CODEC_ID_MPEG1VIDEO && + codecId != AV_CODEC_ID_MPEG2VIDEO && + codecId != AV_CODEC_ID_H264 && + codecId != AV_CODEC_ID_HEVC && + codecId != AV_CODEC_ID_MPEG4 && + codecId != AV_CODEC_ID_VC1 && + codecId != AV_CODEC_ID_AV1 && + codecId != AV_CODEC_ID_AVS2 && + codecId != AV_CODEC_ID_AVS3 && + codecId != AV_CODEC_ID_CAVS + ) + // clang-format on + return std::make_tuple(nullptr, 0); + + const AVBitStreamFilter* f = av_bsf_get_by_name("extract_extradata"); + if (!f) + return std::make_tuple(nullptr, 0); + + AVBSFContext* bsf = nullptr; + int ret = av_bsf_alloc(f, &bsf); + if (ret < 0) + return std::make_tuple(nullptr, 0); + + bsf->par_in->codec_id = codecId; + + ret = av_bsf_init(bsf); + if (ret < 0) + { + av_bsf_free(&bsf); + return std::make_tuple(nullptr, 0); + } + + AVPacket* dstPkt = av_packet_alloc(); + if (!dstPkt) + { + CLog::LogF(LOGERROR, "failed to allocate packet"); + + av_bsf_free(&bsf); + return std::make_tuple(nullptr, 0); + } + AVPacket* pktRef = dstPkt; + + ret = av_packet_ref(pktRef, pkt); + if (ret < 0) + { + av_bsf_free(&bsf); + av_packet_free(&dstPkt); + return std::make_tuple(nullptr, 0); + } + + ret = av_bsf_send_packet(bsf, pktRef); + if (ret < 0) + { + av_packet_unref(pktRef); + av_bsf_free(&bsf); + av_packet_free(&dstPkt); + return std::make_tuple(nullptr, 0); + } + + ret = 0; + while (ret >= 0) + { + ret = av_bsf_receive_packet(bsf, pktRef); + if (ret < 0) + { + if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + break; + + continue; + } + + size_t retExtraDataSize = 0; + uint8_t* retExtraData = + av_packet_get_side_data(pktRef, AV_PKT_DATA_NEW_EXTRADATA, &retExtraDataSize); + if (retExtraData && retExtraDataSize > 0 && retExtraDataSize < FF_MAX_EXTRADATA_SIZE) + { + extraData = static_cast<uint8_t*>(av_malloc(retExtraDataSize + AV_INPUT_BUFFER_PADDING_SIZE)); + if (!extraData) + { + CLog::LogF(LOGERROR, "failed to allocate {} bytes for extradata", retExtraDataSize); + + av_packet_unref(pktRef); + av_bsf_free(&bsf); + av_packet_free(&dstPkt); + return std::make_tuple(nullptr, 0); + } + + CLog::LogF(LOGDEBUG, "fetching extradata, extradata_size({})", retExtraDataSize); + + memcpy(extraData, retExtraData, retExtraDataSize); + memset(extraData + retExtraDataSize, 0, AV_INPUT_BUFFER_PADDING_SIZE); + extraDataSize = retExtraDataSize; + + av_packet_unref(pktRef); + break; + } + + av_packet_unref(pktRef); + } + + av_bsf_free(&bsf); + av_packet_free(&dstPkt); +#else + if (codecCtx && parserCtx && parserCtx->parser && parserCtx->parser->split) + extraDataSize = parserCtx->parser->split(codecCtx, pkt->data, pkt->size); + + if (extraDataSize <= 0 || extraDataSize >= FF_MAX_EXTRADATA_SIZE) + { + CLog::LogF(LOGDEBUG, "fetched extradata of weird size {}", extraDataSize); + return std::make_tuple(nullptr, 0); + } + + extraData = static_cast<uint8_t*>(av_malloc(extraDataSize + AV_INPUT_BUFFER_PADDING_SIZE)); + if (!extraData) + { + CLog::LogF(LOGERROR, "failed to allocate {} bytes for extradata", extraDataSize); + return std::make_tuple(nullptr, 0); + } + + CLog::LogF(LOGDEBUG, "fetching extradata, extradata_size({})", extraDataSize); + + memcpy(extraData, pkt->data, extraDataSize); + memset(extraData + extraDataSize, 0, AV_INPUT_BUFFER_PADDING_SIZE); +#endif + + return std::make_tuple(extraData, extraDataSize); +} diff --git a/xbmc/cores/FFmpeg.h b/xbmc/cores/FFmpeg.h index 8230701ba7a8f..22a253e191f5a 100644 --- a/xbmc/cores/FFmpeg.h +++ b/xbmc/cores/FFmpeg.h @@ -22,6 +22,8 @@ extern "C" { #include <libpostproc/postprocess.h> } +#include <tuple> + // https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4/doc/APIchanges#L18-L26 #if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 0, 100) #define FFMPEG_FMT_CONST const @@ -77,3 +79,6 @@ class CFFmpegLog int level; }; +std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, + const AVCodecParserContext* parserCtx, + AVCodecContext* codecCtx); diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index 70f0562462bf2..f42710282da88 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -14,10 +14,9 @@ #include "cores/VideoPlayer/Interface/TimingConstants.h" #include "utils/log.h" +#include <tuple> #include <utility> -#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE) - class CDemuxStreamClientInternal { public: @@ -150,17 +149,26 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt) stream->m_context->time_base.den = DVD_TIME_BASE; } - if (stream->m_parser_split && stream->m_parser->parser->split) + if (stream->m_parser_split && stream->m_parser && stream->m_parser->parser) { - int len = stream->m_parser->parser->split(stream->m_context, pkt->pData, pkt->iSize); - if (len > 0 && len < FF_MAX_EXTRADATA_SIZE) + AVPacket* avpkt = av_packet_alloc(); + if (!avpkt) + { + CLog::LogF(LOGERROR, "av_packet_alloc failed: {}", strerror(errno)); + return false; + } + + avpkt->data = pkt->pData; + avpkt->size = pkt->iSize; + avpkt->dts = avpkt->pts = AV_NOPTS_VALUE; + + auto [retExtraData, len] = GetPacketExtradata(avpkt, stream->m_parser, stream->m_context); + if (len > 0) { st->changes++; st->disabled = false; st->ExtraSize = len; - st->ExtraData = std::make_unique<uint8_t[]>(len + AV_INPUT_BUFFER_PADDING_SIZE); - memcpy(st->ExtraData.get(), pkt->pData, len); - memset(st->ExtraData.get() + len, 0, AV_INPUT_BUFFER_PADDING_SIZE); + st->ExtraData = std::unique_ptr<uint8_t[]>(retExtraData); stream->m_parser_split = false; change = true; CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - split extradata"); @@ -168,21 +176,12 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt) // Allow ffmpeg to transport codec information to stream->m_context if (!avcodec_open2(stream->m_context, stream->m_context->codec, nullptr)) { - AVPacket* avpkt = av_packet_alloc(); - if (!avpkt) - { - CLog::Log(LOGERROR, "CDVDDemuxClient::{} - av_packet_alloc failed: {}", __FUNCTION__, - strerror(errno)); - return false; - } - avpkt->data = pkt->pData; - avpkt->size = pkt->iSize; - avpkt->dts = avpkt->pts = AV_NOPTS_VALUE; avcodec_send_packet(stream->m_context, avpkt); avcodec_close(stream->m_context); - av_packet_free(&avpkt); } } + + av_packet_free(&avpkt); } uint8_t *outbuf = nullptr; diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 4ad52cd32a115..3081dd8e9adc2 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -34,6 +34,7 @@ #include <mutex> #include <sstream> +#include <tuple> #include <utility> extern "C" @@ -105,8 +106,6 @@ bool AttachmentIsFont(const AVDictionaryEntry* dict) } } // namespace -#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE) - std::string CDemuxStreamAudioFFmpeg::GetStreamName() { if (!m_stream) @@ -2358,44 +2357,36 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket* pkt) if (parser->second->m_parserCtx && parser->second->m_parserCtx->parser && - parser->second->m_parserCtx->parser->split && !st->codecpar->extradata) { - int i = parser->second->m_parserCtx->parser->split(parser->second->m_codecCtx, pkt->data, pkt->size); - if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) + auto [retExtraData, i] = + GetPacketExtradata(pkt, parser->second->m_parserCtx, parser->second->m_codecCtx); + if (i > 0) { - st->codecpar->extradata = (uint8_t*)av_malloc(i + AV_INPUT_BUFFER_PADDING_SIZE); - if (st->codecpar->extradata) - { - CLog::Log(LOGDEBUG, - "CDVDDemuxFFmpeg::ParsePacket() fetching extradata, extradata_size({})", i); - st->codecpar->extradata_size = i; - memcpy(st->codecpar->extradata, pkt->data, i); - memset(st->codecpar->extradata + i, 0, AV_INPUT_BUFFER_PADDING_SIZE); + st->codecpar->extradata_size = i; + st->codecpar->extradata = retExtraData; - if (parser->second->m_parserCtx->parser->parser_parse) + if (parser->second->m_parserCtx->parser->parser_parse) + { + parser->second->m_codecCtx->extradata = st->codecpar->extradata; + parser->second->m_codecCtx->extradata_size = st->codecpar->extradata_size; + const uint8_t* outbufptr; + int bufSize; + parser->second->m_parserCtx->flags |= PARSER_FLAG_COMPLETE_FRAMES; + parser->second->m_parserCtx->parser->parser_parse(parser->second->m_parserCtx, + parser->second->m_codecCtx, &outbufptr, + &bufSize, pkt->data, pkt->size); + parser->second->m_codecCtx->extradata = nullptr; + parser->second->m_codecCtx->extradata_size = 0; + + if (parser->second->m_parserCtx->width != 0) { - parser->second->m_codecCtx->extradata = st->codecpar->extradata; - parser->second->m_codecCtx->extradata_size = st->codecpar->extradata_size; - const uint8_t* outbufptr; - int bufSize; - parser->second->m_parserCtx->flags |= PARSER_FLAG_COMPLETE_FRAMES; - parser->second->m_parserCtx->parser->parser_parse(parser->second->m_parserCtx, - parser->second->m_codecCtx, - &outbufptr, &bufSize, - pkt->data, pkt->size); - parser->second->m_codecCtx->extradata = nullptr; - parser->second->m_codecCtx->extradata_size = 0; - - if (parser->second->m_parserCtx->width != 0) - { - st->codecpar->width = parser->second->m_parserCtx->width; - st->codecpar->height = parser->second->m_parserCtx->height; - } - else - { - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::ParsePacket() invalid width/height"); - } + st->codecpar->width = parser->second->m_parserCtx->width; + st->codecpar->height = parser->second->m_parserCtx->height; + } + else + { + CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::ParsePacket() invalid width/height"); } } } From 2eb3cf3b0128510254478cf820714774a5cee449 Mon Sep 17 00:00:00 2001 From: Vasyl Gello <vasek.gello@gmail.com> Date: Tue, 18 Oct 2022 05:30:30 +0000 Subject: [PATCH 4/7] Separate commit to remove FFmpeg 4 support Team Kodi does officially support one major FFmpeg version. This commit is intentionally separated to let *nix distro maintainers revert it if building Kodi 20+ is needed with FFmpeg 4. Signed-off-by: Vasyl Gello <vasek.gello@gmail.com> --- cmake/modules/FindFFMPEG.cmake | 16 ++-- xbmc/cdrip/EncoderFFmpeg.cpp | 45 +-------- .../AudioEngine/Encoders/AEEncoderFFmpeg.cpp | 48 +--------- .../AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 22 +---- .../Engines/ActiveAE/ActiveAEFilter.cpp | 28 ------ .../ActiveAE/ActiveAEResampleFFMPEG.cpp | 32 ------- xbmc/cores/AudioEngine/Utils/AEUtil.cpp | 35 ------- xbmc/cores/AudioEngine/Utils/AEUtil.h | 5 - xbmc/cores/FFmpeg.cpp | 23 ----- xbmc/cores/FFmpeg.h | 7 -- .../DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp | 28 +----- .../Overlay/DVDOverlayCodecFFmpeg.cpp | 2 +- .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 27 +----- .../DVDCodecs/Video/DVDVideoPPFFmpeg.cpp | 3 - .../VideoPlayer/DVDCodecs/Video/VAAPI.cpp | 8 +- .../DVDDemuxers/DVDDemuxClient.cpp | 7 +- .../DVDDemuxers/DVDDemuxFFmpeg.cpp | 93 +------------------ .../DVDInputStreams/InputStreamAddon.cpp | 2 +- xbmc/filesystem/AudioBookFileDirectory.cpp | 2 +- xbmc/guilib/FFmpegImage.cpp | 6 +- xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp | 2 +- xbmc/video/tags/VideoTagLoaderFFmpeg.cpp | 2 +- 22 files changed, 29 insertions(+), 414 deletions(-) diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake index fedbf0adde28b..e58b026088c94 100644 --- a/cmake/modules/FindFFMPEG.cmake +++ b/cmake/modules/FindFFMPEG.cmake @@ -151,14 +151,14 @@ if(WITH_FFMPEG) set(REQUIRED_FFMPEG_VERSION undef) else() # required ffmpeg library versions - set(REQUIRED_FFMPEG_VERSION 4.4.1) - set(_avcodec_ver ">=58.134.100") - set(_avfilter_ver ">=7.110.100") - set(_avformat_ver ">=58.76.100") - set(_avutil_ver ">=56.70.100") - set(_postproc_ver ">=55.9.100") - set(_swresample_ver ">=3.9.100") - set(_swscale_ver ">=5.9.100") + set(REQUIRED_FFMPEG_VERSION 5.0.0) + set(_avcodec_ver ">=59.18.100") + set(_avfilter_ver ">=8.24.100") + set(_avformat_ver ">=59.16.100") + set(_avutil_ver ">=57.17.100") + set(_postproc_ver ">=56.3.100") + set(_swresample_ver ">=4.3.100") + set(_swscale_ver ">=6.4.100") endif() # Allows building with external ffmpeg not found in system paths, diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp index c05cdeab9eece..5d290ee26d072 100644 --- a/xbmc/cdrip/EncoderFFmpeg.cpp +++ b/xbmc/cdrip/EncoderFFmpeg.cpp @@ -79,7 +79,7 @@ bool CEncoderFFmpeg::Init() throw FFMpegException("Could not allocate url"); /* Find the encoder to be used by its name. */ - FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_encoder(m_formatCtx->oformat->audio_codec); + const AVCodec* codec = avcodec_find_encoder(m_formatCtx->oformat->audio_codec); if (!codec) throw FFMpegException("Unable to find a suitable FFmpeg encoder"); @@ -94,14 +94,8 @@ bool CEncoderFFmpeg::Init() /* Set the basic encoder parameters. * The input file's sample rate is used to avoid a sample rate conversion. */ -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_codecCtx->ch_layout); av_channel_layout_default(&m_codecCtx->ch_layout, m_iInChannels); -#else - m_codecCtx->channels = m_iInChannels; - m_codecCtx->channel_layout = av_get_default_channel_layout(m_iInChannels); -#endif m_codecCtx->sample_rate = m_iInSampleRate; m_codecCtx->sample_fmt = codec->sample_fmts[0]; m_codecCtx->bit_rate = bitrate; @@ -147,13 +141,9 @@ bool CEncoderFFmpeg::Init() m_bufferFrame->nb_samples = m_codecCtx->frame_size; m_bufferFrame->format = m_inFormat; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_bufferFrame->ch_layout); av_channel_layout_copy(&m_bufferFrame->ch_layout, &m_codecCtx->ch_layout); -#else - m_bufferFrame->channel_layout = m_codecCtx->channel_layout; -#endif + m_bufferFrame->sample_rate = m_codecCtx->sample_rate; err = av_frame_get_buffer(m_bufferFrame, 0); @@ -165,18 +155,10 @@ bool CEncoderFFmpeg::Init() if (m_needConversion) { -#if LIBSWRESAMPLE_BUILD >= AV_VERSION_INT(4, 7, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int ret = swr_alloc_set_opts2(&m_swrCtx, &m_codecCtx->ch_layout, m_outFormat, m_codecCtx->sample_rate, &m_codecCtx->ch_layout, m_inFormat, m_codecCtx->sample_rate, 0, nullptr); if (ret || swr_init(m_swrCtx) < 0) -#else - m_swrCtx = swr_alloc_set_opts(nullptr, m_codecCtx->channel_layout, m_outFormat, - m_codecCtx->sample_rate, m_codecCtx->channel_layout, m_inFormat, - m_codecCtx->sample_rate, 0, nullptr); - if (!m_swrCtx || swr_init(m_swrCtx) < 0) -#endif throw FFMpegException("Failed to initialize the resampler"); m_resampledBufferSize = @@ -188,13 +170,8 @@ bool CEncoderFFmpeg::Init() m_resampledFrame->nb_samples = m_neededFrames; m_resampledFrame->format = m_outFormat; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_resampledFrame->ch_layout); av_channel_layout_copy(&m_resampledFrame->ch_layout, &m_codecCtx->ch_layout); -#else - m_resampledFrame->channel_layout = m_codecCtx->channel_layout; -#endif m_resampledFrame->sample_rate = m_codecCtx->sample_rate; err = av_frame_get_buffer(m_resampledFrame, 0); @@ -230,23 +207,14 @@ bool CEncoderFFmpeg::Init() CLog::Log(LOGERROR, "CEncoderFFmpeg::{} - {}", __func__, caught.what()); av_freep(&m_buffer); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_bufferFrame->ch_layout); -#endif av_frame_free(&m_bufferFrame); swr_free(&m_swrCtx); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_resampledFrame->ch_layout); -#endif av_frame_free(&m_resampledFrame); av_freep(&m_resampledBuffer); av_free(m_bcBuffer); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_codecCtx->ch_layout); -#endif avcodec_free_context(&m_codecCtx); if (m_formatCtx) { @@ -390,16 +358,10 @@ bool CEncoderFFmpeg::Close() /* Flush if needed */ av_freep(&m_buffer); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_bufferFrame->ch_layout); -#endif av_frame_free(&m_bufferFrame); swr_free(&m_swrCtx); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_resampledFrame->ch_layout); -#endif av_frame_free(&m_resampledFrame); av_freep(&m_resampledBuffer); m_needConversion = false; @@ -411,10 +373,7 @@ bool CEncoderFFmpeg::Close() /* cleanup */ av_free(m_bcBuffer); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_codecCtx->ch_layout); -#endif avcodec_free_context(&m_codecCtx); av_freep(&m_formatCtx->pb); avformat_free_context(m_formatCtx); diff --git a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp index 5d8ca71de1969..ba35c9506395e 100644 --- a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp +++ b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp @@ -37,10 +37,7 @@ CAEEncoderFFmpeg::~CAEEncoderFFmpeg() { Reset(); swr_free(&m_SwrCtx); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_CodecCtx->ch_layout); -#endif avcodec_free_context(&m_CodecCtx); } @@ -96,7 +93,7 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input bool ac3 = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_AUDIOOUTPUT_AC3PASSTHROUGH); - FFMPEG_FMT_CONST AVCodec* codec = nullptr; + const AVCodec* codec = nullptr; /* fallback to ac3 if we support it, we might not have DTS support */ if (ac3) @@ -117,13 +114,8 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input m_CodecCtx->bit_rate = m_BitRate; m_CodecCtx->sample_rate = format.m_sampleRate; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_CodecCtx->ch_layout); av_channel_layout_from_mask(&m_CodecCtx->ch_layout, AV_CH_LAYOUT_5POINT1_BACK); -#else - m_CodecCtx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK; -#endif /* select a suitable data format */ if (codec->sample_fmts) @@ -200,43 +192,27 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input LOGERROR, "CAEEncoderFFmpeg::Initialize - Unable to find a suitable data format for the codec ({})", m_CodecName); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_CodecCtx->ch_layout); -#endif avcodec_free_context(&m_CodecCtx); return false; } } -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) uint64_t mask = m_CodecCtx->ch_layout.u.mask; av_channel_layout_uninit(&m_CodecCtx->ch_layout); av_channel_layout_from_mask(&m_CodecCtx->ch_layout, mask); m_CodecCtx->ch_layout.nb_channels = BuildChannelLayout(mask, m_Layout); -#else - m_CodecCtx->channels = BuildChannelLayout(m_CodecCtx->channel_layout, m_Layout); -#endif /* open the codec */ if (avcodec_open2(m_CodecCtx, codec, NULL)) { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_CodecCtx->ch_layout); -#endif avcodec_free_context(&m_CodecCtx); return false; } format.m_frames = m_CodecCtx->frame_size; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int channels = m_CodecCtx->ch_layout.nb_channels; -#else - int channels = m_CodecCtx->channels; -#endif format.m_frameSize = channels * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3); format.m_channelLayout = m_Layout; @@ -247,26 +223,14 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input if (m_NeedConversion) { -#if LIBSWRESAMPLE_BUILD >= AV_VERSION_INT(4, 7, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int ret = swr_alloc_set_opts2(&m_SwrCtx, &m_CodecCtx->ch_layout, m_CodecCtx->sample_fmt, m_CodecCtx->sample_rate, &m_CodecCtx->ch_layout, AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate, 0, NULL); if (ret || swr_init(m_SwrCtx) < 0) -#else - m_SwrCtx = swr_alloc_set_opts(NULL, - m_CodecCtx->channel_layout, m_CodecCtx->sample_fmt, m_CodecCtx->sample_rate, - m_CodecCtx->channel_layout, AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate, - 0, NULL); - if (!m_SwrCtx || swr_init(m_SwrCtx) < 0) -#endif { CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Initialize - Failed to initialise resampler."); swr_free(&m_SwrCtx); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_CodecCtx->ch_layout); -#endif avcodec_free_context(&m_CodecCtx); return false; } @@ -320,16 +284,9 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz frame->nb_samples = m_CodecCtx->frame_size; frame->format = m_CodecCtx->sample_fmt; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&frame->ch_layout); av_channel_layout_copy(&frame->ch_layout, &m_CodecCtx->ch_layout); int channelNum = m_CodecCtx->ch_layout.nb_channels; -#else - frame->channel_layout = m_CodecCtx->channel_layout; - frame->channels = m_CodecCtx->channels; - int channelNum = m_CodecCtx->channels; -#endif avcodec_fill_audio_frame(frame, channelNum, m_CodecCtx->sample_fmt, in, in_size, 0); @@ -347,10 +304,7 @@ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_siz err = avcodec_receive_packet(m_CodecCtx, pkt); if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&frame->ch_layout); -#endif av_frame_free(&frame); av_packet_free(&pkt); return (err == AVERROR(EAGAIN)) ? -1 : 0; diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp index 9cd3bddda884e..74ddace8e4c44 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp @@ -22,7 +22,6 @@ using namespace ActiveAE; #include "cores/AudioEngine/Utils/AEStreamData.h" #include "cores/AudioEngine/Utils/AEStreamInfo.h" #include "cores/AudioEngine/Utils/AEUtil.h" -#include "cores/FFmpeg.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" #include "utils/log.h" @@ -3016,8 +3015,8 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) AVFormatContext *fmt_ctx = nullptr; AVCodecContext *dec_ctx = nullptr; AVIOContext *io_ctx; - FFMPEG_FMT_CONST AVInputFormat* io_fmt = nullptr; - FFMPEG_FMT_CONST AVCodec* dec = nullptr; + const AVInputFormat* io_fmt = nullptr; + const AVCodec* dec = nullptr; SampleConfig config; // No custom deleter until sound is registered @@ -3069,14 +3068,8 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) AVCodecID codecId = fmt_ctx->streams[0]->codecpar->codec_id; dec = avcodec_find_decoder(codecId); config.sample_rate = fmt_ctx->streams[0]->codecpar->sample_rate; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) config.channels = fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels; config.channel_layout = fmt_ctx->streams[0]->codecpar->ch_layout.u.mask; -#else - config.channels = fmt_ctx->streams[0]->codecpar->channels; - config.channel_layout = fmt_ctx->streams[0]->codecpar->channel_layout; -#endif } } if (dec == nullptr) @@ -3092,8 +3085,6 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) dec_ctx = avcodec_alloc_context3(dec); dec_ctx->sample_rate = config.sample_rate; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) AVChannelLayout layout = {}; if (!config.channel_layout) av_channel_layout_default(&layout, config.channels); @@ -3102,12 +3093,6 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) config.channel_layout = layout.u.mask; av_channel_layout_copy(&dec_ctx->ch_layout, &layout); av_channel_layout_uninit(&layout); -#else - dec_ctx->channels = config.channels; - if (!config.channel_layout) - config.channel_layout = av_get_default_channel_layout(config.channels); - dec_ctx->channel_layout = config.channel_layout; -#endif AVPacket* avpkt = av_packet_alloc(); if (!avpkt) @@ -3174,10 +3159,7 @@ IAE::SoundPtr CActiveAE::MakeSound(const std::string& file) av_packet_free(&avpkt); av_frame_free(&decoded_frame); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&dec_ctx->ch_layout); -#endif avcodec_free_context(&dec_ctx); avformat_close_input(&fmt_ctx); if (io_ctx) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp index 1d79dc6db40be..9c79d8740d9b5 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp @@ -16,7 +16,6 @@ extern "C" { #include <libavfilter/avfilter.h> #include <libavfilter/buffersink.h> #include <libavfilter/buffersrc.h> -#include <libavutil/version.h> #include <libswresample/swresample.h> } @@ -173,10 +172,7 @@ void CActiveAEFilter::CloseFilter() if (m_pOutFrame) { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_pOutFrame->ch_layout); -#endif av_frame_free(&m_pOutFrame); } @@ -212,17 +208,9 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ if (!frame) return -1; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&frame->ch_layout); av_channel_layout_from_mask(&frame->ch_layout, m_channelLayout); int channels = frame->ch_layout.nb_channels; -#else - int channels = av_get_channel_layout_nb_channels(m_channelLayout); - - frame->channel_layout = m_channelLayout; - frame->channels = channels; -#endif frame->sample_rate = m_sampleRate; frame->nb_samples = src_samples; frame->format = m_sampleFormat; @@ -238,10 +226,7 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ src_buffer[0], src_bufsize, 16); if (result < 0) { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&frame->ch_layout); -#endif av_frame_free(&frame); CLog::Log(LOGERROR, "CActiveAEFilter::ProcessFilter - avcodec_fill_audio_frame failed"); m_filterEof = true; @@ -249,10 +234,7 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ } result = av_buffersrc_write_frame(m_pFilterCtxIn, frame); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&frame->ch_layout); -#endif av_frame_free(&frame); if (result < 0) { @@ -306,13 +288,8 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ { av_frame_unref(m_pOutFrame); m_pOutFrame->format = m_sampleFormat; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_pOutFrame->ch_layout); av_channel_layout_from_mask(&m_pOutFrame->ch_layout, m_channelLayout); -#else - m_pOutFrame->channel_layout = m_channelLayout; -#endif m_pOutFrame->sample_rate = m_sampleRate; result = swr_convert_frame(m_pConvertCtx, m_pOutFrame, m_pConvertFrame); av_frame_unref(m_pConvertFrame); @@ -330,15 +307,10 @@ int CActiveAEFilter::ProcessFilter(uint8_t **dst_buffer, int dst_samples, uint8_ if (m_hasData) { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) AVChannelLayout layout = {}; av_channel_layout_from_mask(&layout, m_channelLayout); int channels = layout.nb_channels; av_channel_layout_uninit(&layout); -#else - int channels = av_get_channel_layout_nb_channels(m_channelLayout); -#endif int planes = av_sample_fmt_is_planar(m_sampleFormat) ? channels : 1; int samples = std::min(dst_samples, m_pOutFrame->nb_samples - m_sampleOffset); int bytes = samples * av_get_bytes_per_sample(m_sampleFormat) * channels / planes; diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp index 379dfe644635f..02c8eb1b83722 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp @@ -11,10 +11,8 @@ #include "utils/log.h" extern "C" { -#include <libavcodec/version.h> #include <libavutil/channel_layout.h> #include <libavutil/opt.h> -#include <libavutil/version.h> #include <libswresample/swresample.h> } @@ -51,32 +49,20 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi m_doesResample = true; if (m_dst_chan_layout == 0) -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) { AVChannelLayout layout = {}; av_channel_layout_default(&layout, m_dst_channels); m_dst_chan_layout = layout.u.mask; av_channel_layout_uninit(&layout); } -#else - m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels); -#endif if (m_src_chan_layout == 0) -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) { AVChannelLayout layout = {}; av_channel_layout_default(&layout, m_src_channels); m_src_chan_layout = layout.u.mask; av_channel_layout_uninit(&layout); } -#else - m_src_chan_layout = av_get_default_channel_layout(m_src_channels); -#endif -#if LIBSWRESAMPLE_BUILD >= AV_VERSION_INT(4, 7, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) AVChannelLayout dstChLayout = {}; AVChannelLayout srcChLayout = {}; @@ -87,13 +73,6 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi m_src_fmt, m_src_rate, 0, NULL); if (ret) -#else - m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, m_dst_fmt, m_dst_rate, - m_src_chan_layout, m_src_fmt, m_src_rate, - 0, NULL); - - if (!m_pContext) -#endif { CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - create context failed"); return false; @@ -162,19 +141,11 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi else if (upmix && m_src_channels == 2 && m_dst_channels > 2) { memset(m_rematrix, 0, sizeof(m_rematrix)); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&dstChLayout); av_channel_layout_from_mask(&dstChLayout, m_dst_chan_layout); -#endif for (int out=0; out<m_dst_channels; out++) { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) AVChannel outChan = av_channel_layout_channel_from_index(&dstChLayout, out); -#else - uint64_t outChan = av_channel_layout_extract_channel(m_dst_chan_layout, out); -#endif switch (outChan) { case AV_CH_FRONT_LEFT: @@ -200,10 +171,7 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi } } -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&dstChLayout); -#endif if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) { diff --git a/xbmc/cores/AudioEngine/Utils/AEUtil.cpp b/xbmc/cores/AudioEngine/Utils/AEUtil.cpp index 98f82816efc32..81a5f1995a291 100644 --- a/xbmc/cores/AudioEngine/Utils/AEUtil.cpp +++ b/xbmc/cores/AudioEngine/Utils/AEUtil.cpp @@ -548,41 +548,12 @@ AVSampleFormat CAEUtil::GetAVSampleFormat(AEDataFormat format) uint64_t CAEUtil::GetAVChannelMask(enum AEChannel aechannel) { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) enum AVChannel ch = GetAVChannel(aechannel); if (ch == AV_CHAN_NONE) return 0; return (1ULL << ch); -#else - switch (aechannel) - { - case AE_CH_FL: return AV_CH_FRONT_LEFT; - case AE_CH_FR: return AV_CH_FRONT_RIGHT; - case AE_CH_FC: return AV_CH_FRONT_CENTER; - case AE_CH_LFE: return AV_CH_LOW_FREQUENCY; - case AE_CH_BL: return AV_CH_BACK_LEFT; - case AE_CH_BR: return AV_CH_BACK_RIGHT; - case AE_CH_FLOC: return AV_CH_FRONT_LEFT_OF_CENTER; - case AE_CH_FROC: return AV_CH_FRONT_RIGHT_OF_CENTER; - case AE_CH_BC: return AV_CH_BACK_CENTER; - case AE_CH_SL: return AV_CH_SIDE_LEFT; - case AE_CH_SR: return AV_CH_SIDE_RIGHT; - case AE_CH_TC: return AV_CH_TOP_CENTER; - case AE_CH_TFL: return AV_CH_TOP_FRONT_LEFT; - case AE_CH_TFC: return AV_CH_TOP_FRONT_CENTER; - case AE_CH_TFR: return AV_CH_TOP_FRONT_RIGHT; - case AE_CH_TBL: return AV_CH_TOP_BACK_LEFT; - case AE_CH_TBC: return AV_CH_TOP_BACK_CENTER; - case AE_CH_TBR: return AV_CH_TOP_BACK_RIGHT; - default: - return 0; - } -#endif } -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) enum AVChannel CAEUtil::GetAVChannel(enum AEChannel aechannel) { switch (aechannel) @@ -627,18 +598,12 @@ enum AVChannel CAEUtil::GetAVChannel(enum AEChannel aechannel) return AV_CHAN_NONE; } } -#endif int CAEUtil::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout) { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) AVChannelLayout ch_layout = {}; av_channel_layout_from_mask(&ch_layout, layout); int idx = av_channel_layout_index_from_channel(&ch_layout, GetAVChannel(aechannel)); av_channel_layout_uninit(&ch_layout); return idx; -#else - return av_get_channel_layout_channel_index(layout, GetAVChannelMask(aechannel)); -#endif } diff --git a/xbmc/cores/AudioEngine/Utils/AEUtil.h b/xbmc/cores/AudioEngine/Utils/AEUtil.h index 8acbeec44212f..6b5fc123c652f 100644 --- a/xbmc/cores/AudioEngine/Utils/AEUtil.h +++ b/xbmc/cores/AudioEngine/Utils/AEUtil.h @@ -13,10 +13,8 @@ #include <math.h> extern "C" { -#include <libavcodec/version.h> #include <libavutil/channel_layout.h> #include <libavutil/samplefmt.h> -#include <libavutil/version.h> } // AV sync options @@ -175,9 +173,6 @@ class CAEUtil static CAEChannelInfo GetAEChannelLayout(uint64_t layout); static AVSampleFormat GetAVSampleFormat(AEDataFormat format); static uint64_t GetAVChannelMask(enum AEChannel aechannel); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) static enum AVChannel GetAVChannel(enum AEChannel aechannel); -#endif static int GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout); }; diff --git a/xbmc/cores/FFmpeg.cpp b/xbmc/cores/FFmpeg.cpp index eb9c653fa3d06..d071f6d8e33a3 100644 --- a/xbmc/cores/FFmpeg.cpp +++ b/xbmc/cores/FFmpeg.cpp @@ -147,7 +147,6 @@ std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, uint8_t* extraData = nullptr; int extraDataSize = 0; -#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 0, 100) /* extract_extradata bitstream filter is implemented only * for certain codecs, as noted in discussion of PR#21248 */ @@ -258,28 +257,6 @@ std::tuple<uint8_t*, int> GetPacketExtradata(const AVPacket* pkt, av_bsf_free(&bsf); av_packet_free(&dstPkt); -#else - if (codecCtx && parserCtx && parserCtx->parser && parserCtx->parser->split) - extraDataSize = parserCtx->parser->split(codecCtx, pkt->data, pkt->size); - - if (extraDataSize <= 0 || extraDataSize >= FF_MAX_EXTRADATA_SIZE) - { - CLog::LogF(LOGDEBUG, "fetched extradata of weird size {}", extraDataSize); - return std::make_tuple(nullptr, 0); - } - - extraData = static_cast<uint8_t*>(av_malloc(extraDataSize + AV_INPUT_BUFFER_PADDING_SIZE)); - if (!extraData) - { - CLog::LogF(LOGERROR, "failed to allocate {} bytes for extradata", extraDataSize); - return std::make_tuple(nullptr, 0); - } - - CLog::LogF(LOGDEBUG, "fetching extradata, extradata_size({})", extraDataSize); - - memcpy(extraData, pkt->data, extraDataSize); - memset(extraData + extraDataSize, 0, AV_INPUT_BUFFER_PADDING_SIZE); -#endif return std::make_tuple(extraData, extraDataSize); } diff --git a/xbmc/cores/FFmpeg.h b/xbmc/cores/FFmpeg.h index 22a253e191f5a..05547a0ba2b5f 100644 --- a/xbmc/cores/FFmpeg.h +++ b/xbmc/cores/FFmpeg.h @@ -24,13 +24,6 @@ extern "C" { #include <tuple> -// https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4/doc/APIchanges#L18-L26 -#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 0, 100) -#define FFMPEG_FMT_CONST const -#else -#define FFMPEG_FMT_CONST -#endif - namespace FFMPEG_HELP_TOOLS { diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp index 44dcb32620f9b..b2849c797dbc4 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecFFmpeg.cpp @@ -46,7 +46,7 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options return false; } - FFMPEG_FMT_CONST AVCodec* pCodec = nullptr; + const AVCodec* pCodec = nullptr; bool allowdtshddecode = true; // set any special options @@ -78,14 +78,9 @@ bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options m_matrixEncoding = AV_MATRIX_ENCODING_NONE; m_channels = 0; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) av_channel_layout_uninit(&m_pCodecContext->ch_layout); m_pCodecContext->ch_layout.order = AV_CHANNEL_ORDER_NATIVE; m_pCodecContext->ch_layout.nb_channels = hints.channels; -#else - m_pCodecContext->channels = hints.channels; -#endif m_hint_layout = hints.channellayout; m_pCodecContext->sample_rate = hints.samplerate; m_pCodecContext->block_align = hints.blockalign; @@ -268,12 +263,7 @@ int CDVDAudioCodecFFmpeg::GetData(uint8_t** dst) m_format.m_frameSize = m_format.m_channelLayout.Count() * CAEUtil::DataFormatToBits(m_format.m_dataFormat) >> 3; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int channels = m_pFrame->ch_layout.nb_channels; -#else - int channels = m_pFrame->channels; -#endif int planes = av_sample_fmt_is_planar(m_pCodecContext->sample_fmt) ? channels : 1; for (int i=0; i<planes; i++) @@ -293,12 +283,7 @@ void CDVDAudioCodecFFmpeg::Reset() int CDVDAudioCodecFFmpeg::GetChannels() { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) return m_pCodecContext->ch_layout.nb_channels; -#else - return m_pCodecContext->channels; -#endif } int CDVDAudioCodecFFmpeg::GetSampleRate() @@ -365,14 +350,8 @@ static unsigned count_bits(int64_t value) void CDVDAudioCodecFFmpeg::BuildChannelMap() { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int codecChannels = m_pCodecContext->ch_layout.nb_channels; uint64_t codecChannelLayout = m_pCodecContext->ch_layout.u.mask; -#else - int codecChannels = m_pCodecContext->channels; - uint64_t codecChannelLayout = m_pCodecContext->channel_layout; -#endif if (m_channels == codecChannels && m_layout == codecChannelLayout) return; //nothing to do here @@ -394,15 +373,10 @@ void CDVDAudioCodecFFmpeg::BuildChannelMap() layout = m_hint_layout; else { -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) AVChannelLayout def_layout = {}; av_channel_layout_default(&def_layout, codecChannels); layout = def_layout.u.mask; av_channel_layout_uninit(&def_layout); -#else - layout = av_get_default_channel_layout(m_pCodecContext->channels); -#endif CLog::Log(LOGINFO, "Using default layout..."); } } diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp index 3657fc093ca0d..164360ff538e3 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp @@ -40,7 +40,7 @@ bool CDVDOverlayCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &optio if (hints.codec == AV_CODEC_ID_EIA_608) return false; - FFMPEG_FMT_CONST AVCodec* pCodec = avcodec_find_decoder(hints.codec); + const AVCodec* pCodec = avcodec_find_decoder(hints.codec); if (!pCodec) { CLog::Log(LOGDEBUG, "{} - Unable to find codec {}", __FUNCTION__, hints.codec); diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp index 21b5e834b2c5c..bb9c20bf9d06e 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -329,7 +329,7 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options m_hints = hints; m_options = options; - FFMPEG_FMT_CONST AVCodec* pCodec = nullptr; + const AVCodec* pCodec = nullptr; m_iOrientation = hints.orientation; @@ -1052,9 +1052,6 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(VideoPicture* pVideoPicture) AVFrameSideData* sd; // https://github.com/FFmpeg/FFmpeg/blob/991d417692/doc/APIchanges#L18-L20 - // basilgello: AV_VIDEO_ENC_PARAMS_MPEG2 is introduced in 4.4! -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(58, 134, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(56, 45, 100) sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_VIDEO_ENC_PARAMS); if (sd) { @@ -1076,28 +1073,6 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(VideoPicture* pVideoPicture) } } } -#else - sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_QP_TABLE_PROPERTIES); - if (sd) - { - struct qp_properties - { - int stride; - int type; - }; - - auto qp = reinterpret_cast<qp_properties*>(sd->data); - - sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_QP_TABLE_DATA); - if (sd && sd->buf && qp) - { - // this seems wrong but it's what ffmpeg does internally - pVideoPicture->qp_table = reinterpret_cast<int8_t*>(sd->buf->data); - pVideoPicture->qstride = qp->stride; - pVideoPicture->qscale_type = qp->type; - } - } -#endif pVideoPicture->pict_type = m_pFrame->pict_type; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp index 3b2739cd22baa..481d44672dbac 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoPPFFmpeg.cpp @@ -119,10 +119,7 @@ void CDVDVideoPPFFmpeg::Process(VideoPicture* pPicture) pSource->pict_type | pSource->qscale_type ? PP_PICT_TYPE_QP2 : 0); // https://github.com/FFmpeg/FFmpeg/blob/991d417692/doc/APIchanges#L18-L20 -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(58, 84, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(56, 45, 100) av_free(pSource->qp_table); -#endif pPicture->SetParams(*pSource); if (pPicture->videoBuffer) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp index eaf7b78d3237f..272ae3af51214 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp @@ -1260,15 +1260,9 @@ void CDecoder::ReturnRenderPicture(CVaapiRenderPicture *renderPic) IHardwareDecoder* CDecoder::Create(CDVDStreamInfo &hint, CProcessInfo &processInfo, AVPixelFormat fmt) { // https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4fdda160f4039fc2ae33edfd27765c9/doc/APIchanges#L18-L26 -#if LIBAVUTIL_BUILD >= AV_VERSION_INT(55, 8, 0) -#define PIX_FMT_VAAPI AV_PIX_FMT_VAAPI -#else -#define PIX_FMT_VAAPI AV_PIX_FMT_VAAPI_VLD -#endif - if (fmt == PIX_FMT_VAAPI && + if (fmt == AV_PIX_FMT_VAAPI && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(SETTING_VIDEOPLAYER_USEVAAPI)) return new VAAPI::CDecoder(processInfo); -#undef PIX_FMT_VAAPI return nullptr; } diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index f42710282da88..052332331702a 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -130,7 +130,7 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt) if (stream->m_context == nullptr) { - FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(st->codec); + const AVCodec* codec = avcodec_find_decoder(st->codec); if (codec == nullptr) { CLog::Log(LOGERROR, "{} - can't find decoder", __FUNCTION__); @@ -219,12 +219,7 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt) case STREAM_AUDIO: { CDemuxStreamClientInternalTpl<CDemuxStreamAudio>* sta = static_cast<CDemuxStreamClientInternalTpl<CDemuxStreamAudio>*>(st); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int streamChannels = stream->m_context->ch_layout.nb_channels; -#else - int streamChannels = stream->m_context->channels; -#endif if (streamChannels != sta->iChannels && streamChannels != 0) { CLog::Log(LOGDEBUG, "CDVDDemuxClient::ParsePacket - ({}) channels changed from {} to {}", diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 3081dd8e9adc2..7e6a2e10616d7 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -235,7 +235,7 @@ bool CDVDDemuxFFmpeg::Aborted() bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool fileinfo) { - FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr; + const AVInputFormat* iformat = nullptr; std::string strFile; m_streaminfo = !pInput->IsRealtime() && !m_reopen; m_reopen = false; @@ -422,7 +422,7 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool // is present, we assume it is PCM audio. // AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS // may be just padded. - FFMPEG_FMT_CONST AVInputFormat* iformat2 = av_find_input_format("spdif"); + const AVInputFormat* iformat2 = av_find_input_format("spdif"); if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) { iformat = iformat2; @@ -542,15 +542,6 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool m_streaminfo = true; } - // https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4/doc/APIchanges#L18-L26 -#if LIBAVFORMAT_BUILD < AV_VERSION_INT(59, 0, 100) - if (iformat && (strcmp(iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0)) - { - if (URIUtils::IsRemote(strFile)) - m_pFormatContext->iformat->flags |= AVFMT_NOGENSEARCH; - } -#endif - // we need to know if this is matroska, avi or sup later m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0; @@ -605,12 +596,6 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool // if format can be nonblocking, let's use that m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK; - // https://github.com/FFmpeg/FFmpeg/blob/d682ae70b4/doc/APIchanges#L18-L21 -#if LIBAVFORMAT_BUILD < AV_VERSION_INT(57, 66, 105) && \ - LIBAVCODEC_BUILD < AV_VERSION_INT(57, 83, 101) - m_pFormatContext->flags |= AVFMT_FLAG_KEEP_SIDE_DATA; -#endif - UpdateCurrentPTS(); // select the correct program if requested @@ -651,7 +636,6 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool { int idx = m_pFormatContext->programs[i]->stream_index[j]; AVStream* st = m_pFormatContext->streams[idx]; -#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 3, 100) // Related to https://patchwork.ffmpeg.org/project/ffmpeg/patch/20210429143825.53040-1-jamrial@gmail.com/ // has been replaced with AVSTREAM_EVENT_FLAG_NEW_PACKETS. if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && @@ -661,14 +645,6 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr<CDVDInputStream>& pInput, bool nProgram = i; break; } -#else - if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->codec_info_nb_frames > 0) || - (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate > 0)) - { - nProgram = i; - break; - } -#endif } } } @@ -1234,13 +1210,8 @@ DemuxPacket* CDVDDemuxFFmpeg::Read() else if (stream->type == STREAM_AUDIO) { CDemuxStreamAudioFFmpeg* audiostream = dynamic_cast<CDemuxStreamAudioFFmpeg*>(stream); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int codecparChannels = m_pFormatContext->streams[pPacket->iStreamId]->codecpar->ch_layout.nb_channels; -#else - int codecparChannels = m_pFormatContext->streams[pPacket->iStreamId]->codecpar->channels; -#endif if (audiostream && (audiostream->iChannels != codecparChannels || audiostream->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codecpar->sample_rate)) @@ -1426,19 +1397,11 @@ void CDVDDemuxFFmpeg::UpdateCurrentPTS() { AVStream* stream = m_pFormatContext->streams[idx]; -#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) if (stream && m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE) { double ts = ConvertTimestamp(m_pkt.pkt.dts, stream->time_base.den, stream->time_base.num); m_currentPts = ts; } -#else - if (stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE) - { - double ts = ConvertTimestamp(stream->cur_dts, stream->time_base.den, stream->time_base.num); - m_currentPts = ts; - } -#endif } } @@ -1647,14 +1610,8 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) { CDemuxStreamAudioFFmpeg* st = new CDemuxStreamAudioFFmpeg(pStream); stream = st; -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int codecparChannels = pStream->codecpar->ch_layout.nb_channels; int codecparChannelLayout = pStream->codecpar->ch_layout.u.mask; -#else - int codecparChannels = pStream->codecpar->channels; - int codecparChannelLayout = pStream->codecpar->channel_layout; -#endif st->iChannels = codecparChannels; st->iChannelLayout = codecparChannelLayout; st->iSampleRate = pStream->codecpar->sample_rate; @@ -1663,15 +1620,10 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->iBitsPerSample = pStream->codecpar->bits_per_raw_sample; char buf[32] = {}; // https://github.com/FFmpeg/FFmpeg/blob/6ccc3989d15/doc/APIchanges#L50-L53 -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) AVChannelLayout layout = {}; av_channel_layout_from_mask(&layout, st->iChannelLayout); av_channel_layout_describe(&layout, buf, sizeof(buf)); av_channel_layout_uninit(&layout); -#else - av_get_channel_layout_string(buf, 31, st->iChannels, st->iChannelLayout); -#endif st->m_channelLayoutName = buf; if (st->iBitsPerSample == 0) st->iBitsPerSample = pStream->codecpar->bits_per_coded_sample; @@ -1713,18 +1665,6 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->iFpsScale = 0; } -#if LIBAVFORMAT_BUILD < AV_VERSION_INT(59, 3, 100) - if (pStream->codec_info_nb_frames > 0 && - pStream->codec_info_nb_frames <= 2 && - m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) - { - CLog::Log(LOGDEBUG, "{} - fps may be unreliable since ffmpeg decoded only {} frame(s)", - __FUNCTION__, pStream->codec_info_nb_frames); - st->iFpsRate = 0; - st->iFpsScale = 0; - } -#endif - st->iWidth = pStream->codecpar->width; st->iHeight = pStream->codecpar->height; st->fAspect = SelectAspect(pStream, st->bForcedAspect); @@ -1746,11 +1686,7 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx) st->hdr_type = DetermineHdrType(pStream); // https://github.com/FFmpeg/FFmpeg/blob/release/5.0/doc/APIchanges -#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 10, 100) size_t size = 0; -#else - int size = 0; -#endif uint8_t* side_data = nullptr; side_data = av_stream_get_side_data(pStream, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, &size); @@ -2160,7 +2096,7 @@ std::string CDVDDemuxFFmpeg::GetStreamCodecName(int iStreamId) return strName; } - FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(stream->codec); + const AVCodec* codec = avcodec_find_decoder(stream->codec); if (codec) strName = avcodec_get_name(codec->id); } @@ -2215,12 +2151,7 @@ bool CDVDDemuxFFmpeg::IsProgramChange() if (m_pFormatContext->streams[idx]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { CDemuxStreamAudioFFmpeg* audiostream = dynamic_cast<CDemuxStreamAudioFFmpeg*>(stream); -#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \ - LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100) int codecparChannels = m_pFormatContext->streams[idx]->codecpar->ch_layout.nb_channels; -#else - int codecparChannels = m_pFormatContext->streams[idx]->codecpar->channels; -#endif if (audiostream && codecparChannels != audiostream->iChannels) { return true; @@ -2341,7 +2272,7 @@ void CDVDDemuxFFmpeg::ParsePacket(AVPacket* pkt) parser->second->m_parserCtx = av_parser_init(st->codecpar->codec_id); - FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(st->codecpar->codec_id); + const AVCodec* codec = avcodec_find_decoder(st->codecpar->codec_id); if (codec == nullptr) { CLog::Log(LOGERROR, "{} - can't find decoder", __FUNCTION__); @@ -2411,12 +2342,8 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamAudioState() { if (!m_startTime) { -#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) m_startTime = av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; -#else - m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; -#endif m_seekStream = idx; } return TRANSPORT_STREAM_STATE::READY; @@ -2436,12 +2363,8 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamAudioState() { if (!m_startTime) { -#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) m_startTime = av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; -#else - m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; -#endif m_seekStream = i; } return TRANSPORT_STREAM_STATE::READY; @@ -2474,12 +2397,8 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamVideoState() { if (!m_startTime) { -#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) m_startTime = av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; -#else - m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; -#endif m_seekStream = idx; } return TRANSPORT_STREAM_STATE::READY; @@ -2499,12 +2418,8 @@ TRANSPORT_STREAM_STATE CDVDDemuxFFmpeg::TransportStreamVideoState() { if (!m_startTime) { -#if LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 17, 100) m_startTime = av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001; -#else - m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001; -#endif m_seekStream = i; } return TRANSPORT_STREAM_STATE::READY; diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp index 392853cc6809a..f78e5dc78906c 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp @@ -393,7 +393,7 @@ KODI_HANDLE CInputStreamAddon::cb_get_stream_transfer(KODI_HANDLE handle, return nullptr; std::string codecName(stream->m_codecName); - FFMPEG_FMT_CONST AVCodec* codec = nullptr; + const AVCodec* codec = nullptr; if (stream->m_streamType != INPUTSTREAM_TYPE_TELETEXT && stream->m_streamType != INPUTSTREAM_TYPE_RDS && stream->m_streamType != INPUTSTREAM_TYPE_ID3) diff --git a/xbmc/filesystem/AudioBookFileDirectory.cpp b/xbmc/filesystem/AudioBookFileDirectory.cpp index d82b2a9bbda9c..94fb232db68c6 100644 --- a/xbmc/filesystem/AudioBookFileDirectory.cpp +++ b/xbmc/filesystem/AudioBookFileDirectory.cpp @@ -150,7 +150,7 @@ bool CAudioBookFileDirectory::ContainsFiles(const CURL& url) m_ioctx->max_packet_size = 32768; - FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr; + const AVInputFormat* iformat = nullptr; av_probe_input_buffer(m_ioctx, &iformat, url.Get().c_str(), nullptr, 0, 0); bool contains = false; diff --git a/xbmc/guilib/FFmpegImage.cpp b/xbmc/guilib/FFmpegImage.cpp index 9d01a21f38b1e..e71980998b2e5 100644 --- a/xbmc/guilib/FFmpegImage.cpp +++ b/xbmc/guilib/FFmpegImage.cpp @@ -52,7 +52,7 @@ struct ThumbDataManagement AVFrame* frame_temporary = nullptr; SwsContext* sws = nullptr; AVCodecContext* avOutctx = nullptr; - FFMPEG_FMT_CONST AVCodec* codec = nullptr; + const AVCodec* codec = nullptr; ~ThumbDataManagement() { av_free(intermediateBuffer); @@ -198,7 +198,7 @@ bool CFFmpegImage::Initialize(unsigned char* buffer, size_t bufSize) bool is_png = (bufSize > 3 && buffer[1] == 'P' && buffer[2] == 'N' && buffer[3] == 'G'); bool is_tiff = (bufSize > 2 && buffer[0] == 'I' && buffer[1] == 'I' && buffer[2] == '*'); - FFMPEG_FMT_CONST AVInputFormat* inp = nullptr; + const AVInputFormat* inp = nullptr; if (is_jpeg) inp = av_find_input_format("image2"); else if (m_strMimeType == "image/apng") @@ -236,7 +236,7 @@ bool CFFmpegImage::Initialize(unsigned char* buffer, size_t bufSize) return false; } AVCodecParameters* codec_params = m_fctx->streams[0]->codecpar; - FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(codec_params->codec_id); + const AVCodec* codec = avcodec_find_decoder(codec_params->codec_id); m_codec_ctx = avcodec_alloc_context3(codec); if (!m_codec_ctx) { diff --git a/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp b/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp index dbd8893c97b6e..6ede1a31df387 100644 --- a/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp +++ b/xbmc/music/tags/MusicInfoTagLoaderFFmpeg.cpp @@ -58,7 +58,7 @@ bool CMusicInfoTagLoaderFFmpeg::Load(const std::string& strFileName, CMusicInfoT if (file.IoControl(IOCTRL_SEEK_POSSIBLE, NULL) != 1) ioctx->seekable = 0; - FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr; + const AVInputFormat* iformat = nullptr; av_probe_input_buffer(ioctx, &iformat, strFileName.c_str(), NULL, 0, 0); if (avformat_open_input(&fctx, strFileName.c_str(), iformat, NULL) < 0) diff --git a/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp b/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp index 5564696be65fc..9fa3687b5e30a 100644 --- a/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp +++ b/xbmc/video/tags/VideoTagLoaderFFmpeg.cpp @@ -65,7 +65,7 @@ CVideoTagLoaderFFmpeg::CVideoTagLoaderFFmpeg(const CFileItem& item, if (m_file->IoControl(IOCTRL_SEEK_POSSIBLE, nullptr) != 1) m_ioctx->seekable = 0; - FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr; + const AVInputFormat* iformat = nullptr; av_probe_input_buffer(m_ioctx, &iformat, m_item.GetPath().c_str(), nullptr, 0, 0); if (avformat_open_input(&m_fctx, m_item.GetPath().c_str(), iformat, nullptr) < 0) { From e88b01304ecea2d626f2ec24e92852ee389d6d02 Mon Sep 17 00:00:00 2001 From: Vasyl Gello <vasek.gello@gmail.com> Date: Tue, 18 Oct 2022 05:47:22 +0000 Subject: [PATCH 5/7] Bump depends-build ffmpeg version to 5.1.2 Signed-off-by: Vasyl Gello <vasek.gello@gmail.com> --- tools/depends/target/ffmpeg/FFMPEG-VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/depends/target/ffmpeg/FFMPEG-VERSION b/tools/depends/target/ffmpeg/FFMPEG-VERSION index 2c9eda8750d75..d80ab0a81dd4c 100644 --- a/tools/depends/target/ffmpeg/FFMPEG-VERSION +++ b/tools/depends/target/ffmpeg/FFMPEG-VERSION @@ -1,5 +1,5 @@ LIBNAME=ffmpeg BASE_URL=https://github.com/xbmc/FFmpeg -VERSION=4.4.1-Nexus-Alpha1 +VERSION=5.1.2-Nexus-Alpha3 ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz -SHA512=8beb04d577b5251e74b0d52f4d130997a8ba94bbd488c7c8309e6b45095c27807e150212888ce3a384b23dff52f8df1a7bde5407bae924ddc363f8125c0616c5 +SHA512=ce60852b8456d6f4bfc60de0ceadb33034d9b3eea8c0bc84d8b7199984ecbf334a2c4d9b42eade439d0ef30ce22e3b2ca0a49d4df837a18cd3136b4343ed3113 From 85e1c52ec2edad81f44f19da00c97cd69f6bbabc Mon Sep 17 00:00:00 2001 From: Vasyl Gello <vasek.gello@gmail.com> Date: Sun, 30 Oct 2022 07:11:06 +0000 Subject: [PATCH 6/7] Disable broken filter for darwin_embedded Signed-off-by: Vasyl Gello <vasek.gello@gmail.com> --- tools/depends/target/ffmpeg/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/depends/target/ffmpeg/CMakeLists.txt b/tools/depends/target/ffmpeg/CMakeLists.txt index f09258058b94f..1739bc2cfd329 100644 --- a/tools/depends/target/ffmpeg/CMakeLists.txt +++ b/tools/depends/target/ffmpeg/CMakeLists.txt @@ -92,6 +92,7 @@ elseif(CORE_SYSTEM_NAME STREQUAL android) elseif(CORE_SYSTEM_NAME STREQUAL darwin_embedded) list(APPEND ffmpeg_conf --disable-crystalhd --enable-videotoolbox + --disable-filter=yadif_videotoolbox --target-os=darwin ) elseif(CORE_SYSTEM_NAME STREQUAL osx) From ddd8da9aae81a803aa3ada80d5e131ad034f369a Mon Sep 17 00:00:00 2001 From: thexai <58434170+thexai@users.noreply.github.com> Date: Sun, 30 Oct 2022 19:32:14 +0100 Subject: [PATCH 7/7] Updates FFmpeg Windows patches --- .../0001-ffmpeg-windows-configure-detect-openssl.patch | 2 +- .../0002-ffmpeg-windows-configure-fix-zlib-conflict.patch | 6 +++--- ...003-ffmpeg-windows-configure-allow-building-static.patch | 4 ++-- .../0004-ffmpeg-windows-configure-detect-libdav1d.patch | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch b/tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch index b8e5b2f7e14b5..29f5a83e165c6 100644 --- a/tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch +++ b/tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch @@ -11,7 +11,7 @@ diff --git a/configure b/configure index d7a3f507e8..4b85e881b1 100755 --- a/configure +++ b/configure -@@ -6530,6 +6530,8 @@ enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OP +@@ -6728,6 +6728,8 @@ enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OP check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto || check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || diff --git a/tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch b/tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch index 064be1ddd30f9..2a7c8f6897213 100644 --- a/tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch +++ b/tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch @@ -11,16 +11,16 @@ diff --git a/configure b/configure index 4b85e881b1..da457705d1 100755 --- a/configure +++ b/configure -@@ -7627,6 +7627,9 @@ print_config CONFIG_ "$config_files" $CONFIG_LIST \ +@@ -7825,6 +7825,9 @@ print_config CONFIG_ "$config_files" $CONFIG_LIST \ + print_config CONFIG_ "$config_files" $CONFIG_LIST \ $CONFIG_EXTRA \ - $ALL_COMPONENTS \ +echo "#if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H == 0" >> $TMPH +echo "#undef HAVE_UNISTD_H" >> $TMPH +echo "#endif" >> $TMPH echo "#endif /* FFMPEG_CONFIG_H */" >> $TMPH - echo "endif # FFMPEG_CONFIG_MAK" >> ffbuild/config.mak + # Do not overwrite an unchanged config.h to avoid superfluous rebuilds. -- 2.29.2 diff --git a/tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch b/tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch index bbb3e0a9f671f..0dee8c9d042bb 100644 --- a/tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch +++ b/tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch @@ -11,7 +11,7 @@ diff --git a/configure b/configure index da457705d1..e3a8f45ff4 100755 --- a/configure +++ b/configure -@@ -5440,6 +5440,8 @@ case $target_os in +@@ -5566,6 +5566,8 @@ case $target_os in enabled shared && ! enabled small && test_cmd $windres --version && enable gnu_windres enabled x86_32 && check_ldflags -Wl,--large-address-aware shlibdir_default="$bindir_default" @@ -20,7 +20,7 @@ index da457705d1..e3a8f45ff4 100755 SLIBPREF="" SLIBSUF=".dll" SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' -@@ -5489,6 +5491,8 @@ case $target_os in +@@ -5615,6 +5617,8 @@ case $target_os in fi enabled x86_32 && check_ldflags -LARGEADDRESSAWARE shlibdir_default="$bindir_default" diff --git a/tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch b/tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch index 617c87a8b00f6..e5a90d090a230 100644 --- a/tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch +++ b/tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch @@ -11,7 +11,7 @@ diff --git a/configure b/configure index e3a8f45ff4..983d7e1078 100755 --- a/configure +++ b/configure -@@ -6358,7 +6358,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && +@@ -6541,7 +6541,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2