From 72fe098c8436c96763f677b4c65d32988b931b5b Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Thu, 11 Apr 2024 17:11:32 +0200 Subject: [PATCH 01/10] [ffmpeg] Update to 7.1 --- cmake/modules/FindFFMPEG.cmake | 16 +-- tools/buildsteps/windows/ffmpeg_options.txt | 1 - tools/depends/target/ffmpeg/CMakeLists.txt | 6 +- tools/depends/target/ffmpeg/FFMPEG-VERSION | 4 +- xbmc/cdrip/EncoderFFmpeg.cpp | 2 +- xbmc/cdrip/EncoderFFmpeg.h | 2 +- .../ActiveAE/ActiveAEResampleFFMPEG.cpp | 116 +++++++++--------- .../DVDDemuxers/DVDDemuxFFmpeg.cpp | 71 +---------- 8 files changed, 72 insertions(+), 146 deletions(-) diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake index 26dd6e8301da1..49f18ca9c2ad3 100644 --- a/cmake/modules/FindFFMPEG.cmake +++ b/cmake/modules/FindFFMPEG.cmake @@ -168,14 +168,14 @@ if(WITH_FFMPEG) set(REQUIRED_FFMPEG_VERSION undef) else() # required ffmpeg library versions - set(REQUIRED_FFMPEG_VERSION 6.0.0) - set(_avcodec_ver ">=60.2.100") - set(_avfilter_ver ">=9.3.100") - set(_avformat_ver ">=60.3.100") - set(_avutil_ver ">=58.2.100") - set(_postproc_ver ">=57.1.100") - set(_swresample_ver ">=4.10.100") - set(_swscale_ver ">=7.1.100") + set(REQUIRED_FFMPEG_VERSION 7.0.0) + set(_avcodec_ver ">=61.3.100") + set(_avfilter_ver ">=10.1.100") + set(_avformat_ver ">=61.1.100") + set(_avutil_ver ">=59.8.100") + set(_postproc_ver ">=58.1.100") + set(_swresample_ver ">=5.1.100") + set(_swscale_ver ">=8.1.100") endif() # Allows building with external ffmpeg not found in system paths, diff --git a/tools/buildsteps/windows/ffmpeg_options.txt b/tools/buildsteps/windows/ffmpeg_options.txt index 5034ff26c4073..776c0b4b35ac0 100644 --- a/tools/buildsteps/windows/ffmpeg_options.txt +++ b/tools/buildsteps/windows/ffmpeg_options.txt @@ -1,5 +1,4 @@ --disable-avdevice ---disable-crystalhd --disable-cuda --disable-cuvid --disable-devices diff --git a/tools/depends/target/ffmpeg/CMakeLists.txt b/tools/depends/target/ffmpeg/CMakeLists.txt index 5cadafe29485b..8924dc8c7305b 100644 --- a/tools/depends/target/ffmpeg/CMakeLists.txt +++ b/tools/depends/target/ffmpeg/CMakeLists.txt @@ -92,14 +92,12 @@ elseif(CORE_SYSTEM_NAME STREQUAL android) list(APPEND ffmpeg_conf --extra-cflags=-mno-stackrealign) endif() elseif(CORE_SYSTEM_NAME STREQUAL darwin_embedded) - list(APPEND ffmpeg_conf --disable-crystalhd - --enable-videotoolbox + list(APPEND ffmpeg_conf --enable-videotoolbox --disable-filter=yadif_videotoolbox --target-os=darwin ) elseif(CORE_SYSTEM_NAME STREQUAL osx) - list(APPEND ffmpeg_conf --disable-crystalhd - --enable-videotoolbox + list(APPEND ffmpeg_conf --enable-videotoolbox --target-os=darwin --disable-securetransport ) diff --git a/tools/depends/target/ffmpeg/FFMPEG-VERSION b/tools/depends/target/ffmpeg/FFMPEG-VERSION index f2ba09402e25a..3cb7bc8e0cd9e 100644 --- a/tools/depends/target/ffmpeg/FFMPEG-VERSION +++ b/tools/depends/target/ffmpeg/FFMPEG-VERSION @@ -1,5 +1,5 @@ LIBNAME=ffmpeg -VERSION=6.0.1 +VERSION=7.1 ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz -SHA512=945e34840092dc0fd3824eb1af2be79868af2afb4fe13159b19a9bcfc464cc4d53243c13ff065199290e9393ddbf4b1c5c8abccf83a31a31d6c7490e499fd1fc +SHA512=b0a82ca1a34fb9fa16ee4b7fa682d7c3fdcc68cd703c72487a2de434c714f2dede68d390e61dbb3669e435e271e4580d6bae00875d71a17ad39f43644c5fdd07 diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp index 85f5fa412e961..907d2591ddba7 100644 --- a/xbmc/cdrip/EncoderFFmpeg.cpp +++ b/xbmc/cdrip/EncoderFFmpeg.cpp @@ -235,7 +235,7 @@ void CEncoderFFmpeg::SetTag(const std::string& tag, const std::string& value) av_dict_set(&m_formatCtx->metadata, tag.c_str(), value.c_str(), 0); } -int CEncoderFFmpeg::avio_write_callback(void* opaque, uint8_t* buf, int buf_size) +int CEncoderFFmpeg::avio_write_callback(void* opaque, const uint8_t* buf, int buf_size) { CEncoderFFmpeg* enc = static_cast(opaque); if (enc->Write(buf, buf_size) != buf_size) diff --git a/xbmc/cdrip/EncoderFFmpeg.h b/xbmc/cdrip/EncoderFFmpeg.h index 48471a4b10f70..4e9f0f5bbbad4 100644 --- a/xbmc/cdrip/EncoderFFmpeg.h +++ b/xbmc/cdrip/EncoderFFmpeg.h @@ -33,7 +33,7 @@ class CEncoderFFmpeg : public CEncoder bool Close() override; private: - static int avio_write_callback(void* opaque, uint8_t* buf, int buf_size); + static int avio_write_callback(void* opaque, const uint8_t* buf, int buf_size); static int64_t avio_seek_callback(void* opaque, int64_t offset, int whence); void SetTag(const std::string& tag, const std::string& value); diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp index 70e946a1160ef..a4fc91554f471 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp @@ -73,54 +73,7 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, 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) - { - CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - create context failed"); - return false; - } - - if (sublevel > 0.0f) - av_opt_set_double(m_pContext, "lfe_mix_level", static_cast(sublevel), 0); - - if(quality == AE_QUALITY_HIGH) - { - av_opt_set_double(m_pContext, "cutoff", 1.0, 0); - av_opt_set_int(m_pContext,"filter_size", 256, 0); - } - else if(quality == AE_QUALITY_MID) - { - // 0.97 is default cutoff so use (1.0 - 0.97) / 2.0 + 0.97 - av_opt_set_double(m_pContext, "cutoff", 0.985, 0); - av_opt_set_int(m_pContext,"filter_size", 64, 0); - } - else if(quality == AE_QUALITY_LOW) - { - av_opt_set_double(m_pContext, "cutoff", 0.97, 0); - av_opt_set_int(m_pContext,"filter_size", 32, 0); - } - - if (m_dst_fmt == AV_SAMPLE_FMT_S32 || m_dst_fmt == AV_SAMPLE_FMT_S32P) - { - av_opt_set_int(m_pContext, "output_sample_bits", m_dst_bits, 0); - } - - // tell resampler to clamp float values - // not required for sink stage (remapLayout == true) - if ((m_dst_fmt == AV_SAMPLE_FMT_FLT || m_dst_fmt == AV_SAMPLE_FMT_FLTP) && - (m_src_fmt == AV_SAMPLE_FMT_FLT || m_src_fmt == AV_SAMPLE_FMT_FLTP) && - !remapLayout && normalize) - { - av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); - } - - av_opt_set_double(m_pContext, "center_mix_level", centerMix, 0); - + bool hasMatrix = false; if (remapLayout) { // one-to-one mapping of channels @@ -130,28 +83,19 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, m_dst_chan_layout = 0; for (unsigned int out=0; outCount(); out++) { - m_dst_chan_layout += ((uint64_t)1) << out; + m_dst_chan_layout += static_cast(1) << out; int idx = CAEUtil::GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout); if (idx >= 0) { m_rematrix[out][idx] = 1.0; } } - - av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0); - av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0); - - if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) - { - CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - setting channel matrix failed"); - return false; - } + hasMatrix = true; } // stereo upmix else if (upmix && m_src_channels == 2 && m_dst_channels > 2) { memset(m_rematrix, 0, sizeof(m_rematrix)); - av_channel_layout_uninit(&dstChLayout); av_channel_layout_from_mask(&dstChLayout, m_dst_chan_layout); for (int out=0; out 0.0f) + av_opt_set_double(m_pContext, "lfe_mix_level", static_cast(sublevel), 0); + + if (hasMatrix) + { + if (swr_set_matrix(m_pContext, reinterpret_cast(m_rematrix), AE_CH_MAX) < 0) { CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - setting channel matrix failed"); return false; } } + if (quality == AE_QUALITY_HIGH) + { + av_opt_set_double(m_pContext, "cutoff", 1.0, 0); + av_opt_set_int(m_pContext, "filter_size", 256, 0); + } + else if (quality == AE_QUALITY_MID) + { + // 0.97 is default cutoff so use (1.0 - 0.97) / 2.0 + 0.97 + av_opt_set_double(m_pContext, "cutoff", 0.985, 0); + av_opt_set_int(m_pContext, "filter_size", 64, 0); + } + else if (quality == AE_QUALITY_LOW) + { + av_opt_set_double(m_pContext, "cutoff", 0.97, 0); + av_opt_set_int(m_pContext, "filter_size", 32, 0); + } + + if (m_dst_fmt == AV_SAMPLE_FMT_S32 || m_dst_fmt == AV_SAMPLE_FMT_S32P) + { + av_opt_set_int(m_pContext, "output_sample_bits", m_dst_bits, 0); + } + + // tell resampler to clamp float values + // not required for sink stage (remapLayout == true) + if ((m_dst_fmt == AV_SAMPLE_FMT_FLT || m_dst_fmt == AV_SAMPLE_FMT_FLTP) && + (m_src_fmt == AV_SAMPLE_FMT_FLT || m_src_fmt == AV_SAMPLE_FMT_FLTP) && !remapLayout && + normalize) + { + av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); + } + + av_opt_set_double(m_pContext, "center_mix_level", centerMix, 0); + if(swr_init(m_pContext) < 0) { CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - init resampler failed"); diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index 7a1bb7bd600f6..b64e1be9056cd 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -376,74 +376,7 @@ bool CDVDDemuxFFmpeg::Open(const std::shared_ptr& pInput, bool if (iformat == nullptr) { // let ffmpeg decide which demuxer we have to open - bool trySPDIFonly = (m_pInput->GetContent() == "audio/x-spdif-compressed"); - - if (!trySPDIFonly) - av_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0); - - // Use the more low-level code in case we have been built against an old - // FFmpeg without the above av_probe_input_buffer(), or in case we only - // want to probe for spdif (DTS or IEC 61937) compressed audio - // specifically, or in case the file is a wav which may contain DTS or - // IEC 61937 (e.g. ac3-in-wav) and we want to check for those formats. - if (trySPDIFonly || (iformat && strcmp(iformat->name, "wav") == 0)) - { - AVProbeData pd; - int probeBufferSize = 32768; - std::unique_ptr probe_buffer (new uint8_t[probeBufferSize + AVPROBE_PADDING_SIZE]); - - // init probe data - pd.buf = probe_buffer.get(); - pd.filename = strFile.c_str(); - - // read data using avformat's buffers - pd.buf_size = avio_read(m_ioContext, pd.buf, probeBufferSize); - if (pd.buf_size <= 0) - { - CLog::Log(LOGERROR, "{} - error reading from input stream, {}", __FUNCTION__, - CURL::GetRedacted(strFile)); - return false; - } - memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); - - // restore position again - avio_seek(m_ioContext , 0, SEEK_SET); - - // the advancedsetting is for allowing the user to force outputting the - // 44.1 kHz DTS wav file as PCM, so that an A/V receiver can decode - // it (this is temporary until we handle 44.1 kHz passthrough properly) - if (trySPDIFonly || (iformat && strcmp(iformat->name, "wav") == 0 && !CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_VideoPlayerIgnoreDTSinWAV)) - { - // check for spdif and dts - // This is used with wav files and audio CDs that may contain - // a DTS or AC3 track padded for S/PDIF playback. If neither of those - // is present, we assume it is PCM audio. - // AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS - // may be just padded. - const AVInputFormat* iformat2 = av_find_input_format("spdif"); - if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) - { - iformat = iformat2; - } - else - { - // not spdif or no spdif demuxer, try dts - iformat2 = av_find_input_format("dts"); - - if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) - { - iformat = iformat2; - } - else if (trySPDIFonly) - { - // not dts either, return false in case we were explicitly - // requested to only check for S/PDIF padded compressed audio - CLog::Log(LOGDEBUG, "{} - not spdif or dts file, falling back", __FUNCTION__); - return false; - } - } - } - } + av_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0); if (!iformat) { @@ -1353,7 +1286,7 @@ bool CDVDDemuxFFmpeg::SeekTime(double time, bool backwards, double* startpts) if (ret >= 0) { - if (m_pFormatContext->iformat->read_seek) + if (!(m_pFormatContext->iformat->flags & AVFMT_NOTIMESTAMPS)) m_seekToKeyFrame = true; m_currentPts = DVD_NOPTS_VALUE; } From 8e8e32b7bb609d90837d7e9f45ef07d7e2e64889 Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Thu, 11 Apr 2024 17:13:36 +0200 Subject: [PATCH 02/10] [ffmpeg] Remove deprecated use of FF_API_INTERLACED_FRAME --- .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 5 +++-- .../VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 9 +++++---- xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp | 6 ++++-- xbmc/cores/VideoPlayer/DVDCodecs/Video/VTB.cpp | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp index eb2943bb8ccb9..4da0722d5c118 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp @@ -582,8 +582,9 @@ void CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) pVideoPicture->iRepeatPicture = 0; pVideoPicture->iFlags = 0; - pVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0; - pVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST : 0; + pVideoPicture->iFlags |= m_pFrame->flags & AV_FRAME_FLAG_INTERLACED ? DVP_FLAG_INTERLACED : 0; + pVideoPicture->iFlags |= + m_pFrame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST ? DVP_FLAG_TOP_FIELD_FIRST : 0; pVideoPicture->iFlags |= m_pFrame->data[0] ? 0 : DVP_FLAG_DROPPED; if (m_codecControlFlags & DVD_CODEC_CTRL_DROP) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp index d66378fa07886..9586d211e9156 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -792,12 +792,12 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecFFmpeg::GetPicture(VideoPicture* pVideoPi } m_dropCtrl.Process(framePTS, m_pCodecContext->skip_frame > AVDISCARD_DEFAULT); - if (m_pDecodedFrame->key_frame) + if (m_pDecodedFrame->flags & AV_FRAME_FLAG_KEY) { m_started = true; m_iLastKeyframe = m_pCodecContext->has_b_frames + 2; } - if (m_pDecodedFrame->interlaced_frame) + if (m_pDecodedFrame->flags & AV_FRAME_FLAG_INTERLACED) m_interlaced = true; else m_interlaced = false; @@ -1013,8 +1013,9 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(VideoPicture* pVideoPicture) pVideoPicture->iRepeatPicture = 0.5 * m_pFrame->repeat_pict; pVideoPicture->iFlags = 0; - pVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0; - pVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST: 0; + pVideoPicture->iFlags |= m_pFrame->flags & AV_FRAME_FLAG_INTERLACED ? DVP_FLAG_INTERLACED : 0; + pVideoPicture->iFlags |= + m_pFrame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST ? DVP_FLAG_TOP_FIELD_FIRST : 0; if (m_codecControlFlags & DVD_CODEC_CTRL_DROP) { diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp index 6ace85dc9244d..cc3629d33d620 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp @@ -3070,8 +3070,10 @@ bool CFFmpegPostproc::AddPicture(CVaapiDecodedPicture &inPic) m_pFilterFrameIn->height = m_config.vidHeight; m_pFilterFrameIn->linesize[0] = image.pitches[0]; m_pFilterFrameIn->linesize[1] = image.pitches[1]; - m_pFilterFrameIn->interlaced_frame = (inPic.DVDPic.iFlags & DVP_FLAG_INTERLACED) ? 1 : 0; - m_pFilterFrameIn->top_field_first = (inPic.DVDPic.iFlags & DVP_FLAG_TOP_FIELD_FIRST) ? 1 : 0; + if (inPic.DVDPic.iFlags & DVP_FLAG_INTERLACED) + m_pFilterFrameIn->flags |= AV_FRAME_FLAG_INTERLACED; + if (inPic.DVDPic.iFlags & DVP_FLAG_TOP_FIELD_FIRST) + m_pFilterFrameIn->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; if (inPic.DVDPic.pts == DVD_NOPTS_VALUE) m_pFilterFrameIn->pts = AV_NOPTS_VALUE; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VTB.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VTB.cpp index 1f71f643d229a..567d63559d456 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/VTB.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/VTB.cpp @@ -196,7 +196,7 @@ CDVDVideoCodec::VCReturn CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame) if(frame) { - if (frame->interlaced_frame) + if (frame->flags & AV_FRAME_FLAG_INTERLACED) return CDVDVideoCodec::VC_FATAL; if (m_renderBuffer) From 56315b71a0818fe26256d9e23fa0977109513e4c Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Thu, 11 Apr 2024 17:14:48 +0200 Subject: [PATCH 03/10] [ffmpeg] Remove deprecated use of avcodec_close --- xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp index 0cdf8c3864ac3..477a2e82ece51 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp @@ -188,7 +188,6 @@ bool CDVDDemuxClient::ParsePacket(DemuxPacket* pkt) if (!avcodec_open2(stream->m_context, stream->m_context->codec, nullptr)) { avcodec_send_packet(stream->m_context, avpkt); - avcodec_close(stream->m_context); } } av_packet_free(&avpkt); From 767cbeaa4e61eeb28669a75227df0d3bb19a101d Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Thu, 11 Apr 2024 17:15:16 +0200 Subject: [PATCH 04/10] [ffmpeg] Remove deprecated use av_stream_get_side_data --- .../DVDDemuxers/DVDDemuxFFmpeg.cpp | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp index b64e1be9056cd..6a007a41f8609 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp @@ -1647,42 +1647,49 @@ 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 - size_t size = 0; - uint8_t* side_data = nullptr; + // https://github.com/FFmpeg/FFmpeg/blob/release/7.0/doc/APIchanges + const AVPacketSideData* sideData = nullptr; if (st->hdr_type == StreamHdrType::HDR_TYPE_DOLBYVISION) { - side_data = av_stream_get_side_data(pStream, AV_PKT_DATA_DOVI_CONF, &size); - if (side_data && size) + + sideData = + av_packet_side_data_get(pStream->codecpar->coded_side_data, + pStream->codecpar->nb_coded_side_data, AV_PKT_DATA_DOVI_CONF); + if (sideData && sideData->size) { - st->dovi = *reinterpret_cast(side_data); + st->dovi = *reinterpret_cast(sideData->data); } } - side_data = av_stream_get_side_data(pStream, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, &size); - if (side_data && size) + sideData = av_packet_side_data_get(pStream->codecpar->coded_side_data, + pStream->codecpar->nb_coded_side_data, + AV_PKT_DATA_MASTERING_DISPLAY_METADATA); + if (sideData && sideData->size) { st->masteringMetaData = std::make_shared( - *reinterpret_cast(side_data)); + *reinterpret_cast(sideData->data)); } - side_data = av_stream_get_side_data(pStream, AV_PKT_DATA_CONTENT_LIGHT_LEVEL, &size); - if (side_data && size) + sideData = av_packet_side_data_get(pStream->codecpar->coded_side_data, + pStream->codecpar->nb_coded_side_data, + AV_PKT_DATA_CONTENT_LIGHT_LEVEL); + if (sideData && sideData->size) { st->contentLightMetaData = std::make_shared( - *reinterpret_cast(side_data)); + *reinterpret_cast(sideData->data)); } - uint8_t* displayMatrixSideData = - av_stream_get_side_data(pStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr); - if (displayMatrixSideData) + sideData = av_packet_side_data_get(pStream->codecpar->coded_side_data, + pStream->codecpar->nb_coded_side_data, + AV_PKT_DATA_DISPLAYMATRIX); + if (sideData) { - const double tetha = - av_display_rotation_get(reinterpret_cast(displayMatrixSideData)); - if (!std::isnan(tetha)) + const double theta = + av_display_rotation_get(reinterpret_cast(sideData->data)); + if (!std::isnan(theta)) { - st->iOrientation = ((static_cast(-tetha) % 360) + 360) % 360; + st->iOrientation = ((static_cast(-theta) % 360) + 360) % 360; } } @@ -2505,7 +2512,9 @@ StreamHdrType CDVDDemuxFFmpeg::DetermineHdrType(AVStream* pStream) { StreamHdrType hdrType = StreamHdrType::HDR_TYPE_NONE; - if (av_stream_get_side_data(pStream, AV_PKT_DATA_DOVI_CONF, nullptr)) // DoVi + if (av_packet_side_data_get(pStream->codecpar->coded_side_data, + pStream->codecpar->nb_coded_side_data, + AV_PKT_DATA_DOVI_CONF)) // DoVi hdrType = StreamHdrType::HDR_TYPE_DOLBYVISION; else if (pStream->codecpar->color_trc == AVCOL_TRC_SMPTE2084) // HDR10 hdrType = StreamHdrType::HDR_TYPE_HDR10; @@ -2513,7 +2522,9 @@ StreamHdrType CDVDDemuxFFmpeg::DetermineHdrType(AVStream* pStream) hdrType = StreamHdrType::HDR_TYPE_HLG; // file could be SMPTE2086 which FFmpeg currently returns as unknown // so use the presence of static metadata to detect it - else if (av_stream_get_side_data(pStream, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, nullptr)) + else if (av_packet_side_data_get(pStream->codecpar->coded_side_data, + pStream->codecpar->nb_coded_side_data, + AV_PKT_DATA_MASTERING_DISPLAY_METADATA)) hdrType = StreamHdrType::HDR_TYPE_HDR10; return hdrType; From 4a9f358490ed7fdd7c63e03a16e261ad3863defc Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Tue, 3 Dec 2024 23:40:37 +0100 Subject: [PATCH 05/10] [ffmpeg] Remove deprecated use of avcodec->sample_fmts --- xbmc/cdrip/EncoderFFmpeg.cpp | 13 ++++++++++- .../AudioEngine/Encoders/AEEncoderFFmpeg.cpp | 22 ++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/xbmc/cdrip/EncoderFFmpeg.cpp b/xbmc/cdrip/EncoderFFmpeg.cpp index 907d2591ddba7..a2e571ced52f3 100644 --- a/xbmc/cdrip/EncoderFFmpeg.cpp +++ b/xbmc/cdrip/EncoderFFmpeg.cpp @@ -97,10 +97,21 @@ bool CEncoderFFmpeg::Init() /* Set the basic encoder parameters. * The input file's sample rate is used to avoid a sample rate conversion. */ + const AVSampleFormat* sampleFmts = nullptr; + int numFmts = 0; +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 12, 100) + if (avcodec_get_supported_config(m_codecCtx, codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, + reinterpret_cast(&sampleFmts), &numFmts) < 0) + { + throw FFMpegException("Failed to get supported sample formats"); + } +#else + sampleFmts = codec->sample_fmts; +#endif av_channel_layout_uninit(&m_codecCtx->ch_layout); av_channel_layout_default(&m_codecCtx->ch_layout, m_iInChannels); m_codecCtx->sample_rate = m_iInSampleRate; - m_codecCtx->sample_fmt = codec->sample_fmts[0]; + m_codecCtx->sample_fmt = sampleFmts[0]; m_codecCtx->bit_rate = bitrate; /* Allow experimental encoders (like FFmpeg builtin AAC encoder) */ diff --git a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp index d129e84415595..da4ee594891b1 100644 --- a/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp +++ b/xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp @@ -117,8 +117,19 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input av_channel_layout_uninit(&m_CodecCtx->ch_layout); av_channel_layout_from_mask(&m_CodecCtx->ch_layout, AV_CH_LAYOUT_5POINT1_BACK); + const AVSampleFormat* sampleFmts = nullptr; + int numFmts = 0; +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 12, 100) + avcodec_get_supported_config(m_CodecCtx, codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, + reinterpret_cast(&sampleFmts), &numFmts); +#else + sampleFmts = codec->sample_fmts; + for (numFmts = 0; sampleFmts[numFmts] != AV_SAMPLE_FMT_NONE; ++numFmts) + ; +#endif + /* select a suitable data format */ - if (codec->sample_fmts) + if (sampleFmts) { bool hasFloat = false; bool hasDouble = false; @@ -128,9 +139,9 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input bool hasFloatP = false; bool hasUnknownFormat = false; - for(int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; ++i) + for (int i = 0; i < numFmts; ++i) { - switch (codec->sample_fmts[i]) + switch (sampleFmts[i]) { case AV_SAMPLE_FMT_FLT: hasFloat = true; break; case AV_SAMPLE_FMT_DBL: hasDouble = true; break; @@ -143,7 +154,8 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input else hasUnknownFormat = true; break; - case AV_SAMPLE_FMT_NONE: return false; + case AV_SAMPLE_FMT_NONE: + continue; default: hasUnknownFormat = true; break; } } @@ -180,7 +192,7 @@ bool CAEEncoderFFmpeg::Initialize(AEAudioFormat &format, bool allow_planar_input } else if (hasUnknownFormat) { - m_CodecCtx->sample_fmt = codec->sample_fmts[0]; + m_CodecCtx->sample_fmt = sampleFmts[0]; format.m_dataFormat = AE_FMT_FLOAT; m_NeedConversion = true; CLog::Log(LOGINFO, From 20cb6313b845d1c8203b25c8e6c5bda1bd55662e Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Thu, 11 Apr 2024 17:15:43 +0200 Subject: [PATCH 06/10] [ffmpeg] Remove CrystalHD hw acceleration strings --- addons/resource.language.en_gb/resources/strings.po | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index dceb16a234b2e..4e0f326699871 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -7459,10 +7459,7 @@ msgctxt "#13427" msgid "Allow hardware acceleration - DXVA2" msgstr "" -#: system/settings/settings.xml -msgctxt "#13428" -msgid "Allow hardware acceleration - CrystalHD" -msgstr "" +#empty string with id 13428 #: system/settings/settings.xml msgctxt "#13429" @@ -19819,11 +19816,7 @@ msgctxt "#36158" msgid "Enable DXVA2 hardware decoding of video files." msgstr "" -#. Description of setting with label #13428 "Allow hardware acceleration (CrystalHD)" -#: system/settings/settings.xml -msgctxt "#36159" -msgid "Enable CrystalHD decoding of video files." -msgstr "" +#empty string with id 36159 #. Description of setting with label #13429 "Allow hardware acceleration (VDADecoder)" #: system/settings/settings.xml From eb9d7ae91ad2e6d18792426c8627285d57b96ae6 Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Sat, 13 Apr 2024 10:31:36 +0200 Subject: [PATCH 07/10] [settings] Remove VideoPlayerignoredtsinwav advanced setting --- xbmc/settings/AdvancedSettings.cpp | 2 -- xbmc/settings/AdvancedSettings.h | 1 - 2 files changed, 3 deletions(-) diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp index 527c1158b7514..a0fb486ac0294 100644 --- a/xbmc/settings/AdvancedSettings.cpp +++ b/xbmc/settings/AdvancedSettings.cpp @@ -129,7 +129,6 @@ void CAdvancedSettings::Initialize() return; m_audioApplyDrc = -1.0f; - m_VideoPlayerIgnoreDTSinWAV = false; //default hold time of 25 ms, this allows a 20 hertz sine to pass undistorted m_limiterHold = 0.025f; @@ -580,7 +579,6 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file) GetCustomRegexps(pAudioExcludes, m_audioExcludeFromScanRegExps); XMLUtils::GetFloat(pElement, "applydrc", m_audioApplyDrc); - XMLUtils::GetBoolean(pElement, "VideoPlayerignoredtsinwav", m_VideoPlayerIgnoreDTSinWAV); XMLUtils::GetFloat(pElement, "limiterhold", m_limiterHold, 0.0f, 100.0f); XMLUtils::GetFloat(pElement, "limiterrelease", m_limiterRelease, 0.001f, 100.0f); diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h index a31e88bd4900c..28bb1295c6678 100644 --- a/xbmc/settings/AdvancedSettings.h +++ b/xbmc/settings/AdvancedSettings.h @@ -122,7 +122,6 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler std::string m_audioDefaultPlayer; float m_audioPlayCountMinimumPercent; - bool m_VideoPlayerIgnoreDTSinWAV; float m_limiterHold; float m_limiterRelease; From 83d5bac2f10cba9fd22de66e20d17fb7f20fd857 Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Sat, 13 Apr 2024 13:07:58 +0200 Subject: [PATCH 08/10] [ffmpeg] Use new audio DTS and ATMOS profiles --- .../VideoPlayer/DVDDemuxers/DVDDemux.cpp | 20 +++++++++++++------ .../DVDInputStreams/InputStreamAddon.cpp | 9 +++------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp index 71b3a47aa3b72..74a3667ee982f 100644 --- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp +++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemux.cpp @@ -15,15 +15,15 @@ std::string CDemuxStreamAudio::GetStreamType() std::string strInfo; switch (codec) { - //! @todo: With ffmpeg >= 6.1 add new AC4 codec case AV_CODEC_ID_AC3: strInfo = "AC3"; break; + case AV_CODEC_ID_AC4: + strInfo = "AC4"; + break; case AV_CODEC_ID_EAC3: { - //! @todo: With ffmpeg >= 6.1 add new atmos profile case - // "JOC" its EAC3 Atmos underlying profile, there is no standard codec name string - if (StringUtils::Contains(codecName, "JOC")) + if (profile == FF_PROFILE_EAC3_DDP_ATMOS) strInfo = "DD+ ATMOS"; else strInfo = "DD+"; @@ -31,7 +31,6 @@ std::string CDemuxStreamAudio::GetStreamType() } case AV_CODEC_ID_DTS: { - //! @todo: With ffmpeg >= 6.1 add new DTSX profile cases switch (profile) { case FF_PROFILE_DTS_96_24: @@ -49,6 +48,12 @@ std::string CDemuxStreamAudio::GetStreamType() case FF_PROFILE_DTS_HD_HRA: strInfo = "DTS-HD HRA"; break; + case FF_PROFILE_DTS_HD_MA_X: + strInfo = "DTS-HD MA X"; + break; + case FF_PROFILE_DTS_HD_MA_X_IMAX: + strInfo = "DTS-HD MA X (IMAX)"; + break; default: strInfo = "DTS"; break; @@ -62,7 +67,10 @@ std::string CDemuxStreamAudio::GetStreamType() strInfo = "MP3"; break; case AV_CODEC_ID_TRUEHD: - strInfo = "TrueHD"; + if (profile == FF_PROFILE_TRUEHD_ATMOS) + strInfo = "TrueHD ATMOS"; + else + strInfo = "TrueHD"; break; case AV_CODEC_ID_AAC: { diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp index daf66ce0cd98b..902f38ade2708 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.cpp @@ -762,14 +762,11 @@ int CInputStreamAddon::ConvertAudioCodecProfile(STREAMCODEC_PROFILE profile) case DTSCodecProfileHDExpress: return FF_PROFILE_DTS_EXPRESS; case DTSCodecProfileHDMAX: - //! @todo: with ffmpeg >= 6.1 set the appropriate profile - return FF_PROFILE_UNKNOWN; // FF_PROFILE_DTS_HD_MA_X + return FF_PROFILE_DTS_HD_MA_X; case DTSCodecProfileHDMAIMAX: - //! @todo: with ffmpeg >= 6.1 set the appropriate profile - return FF_PROFILE_UNKNOWN; // FF_PROFILE_DTS_HD_MA_X_IMAX + return FF_PROFILE_DTS_HD_MA_X_IMAX; case DDPlusCodecProfileAtmos: - //! @todo: with ffmpeg >= 6.1 set the appropriate profile - return FF_PROFILE_UNKNOWN; // FF_PROFILE_EAC3_DDP_ATMOS + return FF_PROFILE_EAC3_DDP_ATMOS; default: return FF_PROFILE_UNKNOWN; } From bd030121a86be88553d043e6d11b49190a632434 Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Sat, 7 Dec 2024 16:03:09 +0100 Subject: [PATCH 09/10] [ffmpeg] TEMP: cat on configure failure --- tools/depends/target/ffmpeg/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile index 0a00827ba24c6..06a4a9d3d1c38 100644 --- a/tools/depends/target/ffmpeg/Makefile +++ b/tools/depends/target/ffmpeg/Makefile @@ -46,7 +46,7 @@ $(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE) cd $(PLATFORM)/build; $(CMAKE) $(CMAKE_ARGS) .. .build-$(PLATFORM): $(PLATFORM) - $(MAKE) -C $(PLATFORM)/build + $(MAKE) -C $(PLATFORM)/build || (find . -wholename "*ffbuild/config.log" -exec cat {} \; && false) touch $@ .installed-$(PLATFORM): .build-$(PLATFORM) From e16bd009c536b521a0913b6e59eecd551fbf2fba Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Sat, 7 Dec 2024 18:50:58 +0100 Subject: [PATCH 10/10] fixup! [ffmpeg] Update to 7.1 --- tools/depends/configure.ac | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/depends/configure.ac b/tools/depends/configure.ac index 22920abdefbf3..fd25886cbf474 100644 --- a/tools/depends/configure.ac +++ b/tools/depends/configure.ac @@ -404,9 +404,11 @@ case $host in case $host in *i686*-linux-gnu*|i*86*-*-linux-uclibc*) meson_cpu="x86" + ffmpeg_cpu="i686" ;; x86_64*-linux-gnu*|x86_64-*-linux-uclibc*) meson_cpu="x86_64" + ffmpeg_cpu="x86-64" ;; esac use_cpu=$host_cpu @@ -416,7 +418,7 @@ case $host in platform_cxxflags="$platform_cflags" platform_os="linux" meson_system="linux" - ffmpeg_options_default="--enable-vaapi --enable-vdpau --cpu=$use_cpu" + ffmpeg_options_default="--enable-vaapi --enable-vdpau --cpu=$ffmpeg_cpu" target_platform="x11 wayland gbm" ;; *darwin*)