From c6a360b1b7003462859c0cf684558e6b1a5f36a4 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 16 Jul 2022 12:05:08 +0200 Subject: [PATCH] kodi: move AW and RK deinterlace patches to common directory Signed-off-by: Matthias Reichl --- packages/mediacenter/kodi/package.mk | 4 + ...odecDRMPRIME-add-support-for-filters.patch | 0 ...0002-WIP-DRMPRIME-deinterlace-filter.patch | 0 ...odecDRMPRIME-add-support-for-filters.patch | 141 ----- ...0002-WIP-DRMPRIME-deinterlace-filter.patch | 497 ------------------ 5 files changed, 4 insertions(+), 638 deletions(-) rename {projects/Allwinner/patches/kodi => packages/mediacenter/kodi/patches/drmprime-filter}/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch (100%) rename {projects/Allwinner/patches/kodi => packages/mediacenter/kodi/patches/drmprime-filter}/0002-WIP-DRMPRIME-deinterlace-filter.patch (100%) delete mode 100644 projects/Rockchip/patches/kodi/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch delete mode 100644 projects/Rockchip/patches/kodi/0002-WIP-DRMPRIME-deinterlace-filter.patch diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index c15225b507..4dc9f1475d 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -203,6 +203,10 @@ configure_package() { fi fi + if [ "${PROJECT}" = "Allwinner" -o "${PROJECT}" = "Rockchip" ]; then + PKG_PATCH_DIRS+=" drmprime-filter" + fi + KODI_LIBDVD="${KODI_DVDCSS} \ -DLIBDVDNAV_URL=${SOURCES}/libdvdnav/libdvdnav-$(get_pkg_version libdvdnav).tar.gz \ -DLIBDVDREAD_URL=${SOURCES}/libdvdread/libdvdread-$(get_pkg_version libdvdread).tar.gz" diff --git a/projects/Allwinner/patches/kodi/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch b/packages/mediacenter/kodi/patches/drmprime-filter/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch similarity index 100% rename from projects/Allwinner/patches/kodi/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch rename to packages/mediacenter/kodi/patches/drmprime-filter/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch diff --git a/projects/Allwinner/patches/kodi/0002-WIP-DRMPRIME-deinterlace-filter.patch b/packages/mediacenter/kodi/patches/drmprime-filter/0002-WIP-DRMPRIME-deinterlace-filter.patch similarity index 100% rename from projects/Allwinner/patches/kodi/0002-WIP-DRMPRIME-deinterlace-filter.patch rename to packages/mediacenter/kodi/patches/drmprime-filter/0002-WIP-DRMPRIME-deinterlace-filter.patch diff --git a/projects/Rockchip/patches/kodi/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch b/projects/Rockchip/patches/kodi/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch deleted file mode 100644 index 7a9b608b94..0000000000 --- a/projects/Rockchip/patches/kodi/0001-WIP-DVDVideoCodecDRMPRIME-add-support-for-filters.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 6789405cbea23dd0d53ba5a6833dc2266f166ad9 Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Sun, 20 Oct 2019 17:10:07 +0000 -Subject: [PATCH 1/2] WIP: DVDVideoCodecDRMPRIME: add support for filters - ---- - .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 68 ++++++++++++++++--- - .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.h | 10 +++ - 2 files changed, 69 insertions(+), 9 deletions(-) - ---- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -27,6 +27,8 @@ - extern "C" - { - #include -+#include -+#include - #include - #include - #include -@@ -559,18 +561,30 @@ void CDVDVideoCodecDRMPRIME::SetPictureP - pVideoPicture->dts = DVD_NOPTS_VALUE; - } - --CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::GetPicture(VideoPicture* pVideoPicture) -+CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterIn() - { -- if (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN) -- Drain(); -+ if (!m_pFilterIn) -+ return VC_PICTURE; - -- if (pVideoPicture->videoBuffer) -+ int ret = av_buffersrc_add_frame(m_pFilterIn, m_pFrame); -+ if (ret < 0) - { -- pVideoPicture->videoBuffer->Release(); -- pVideoPicture->videoBuffer = nullptr; -+ char err[AV_ERROR_MAX_STRING_SIZE] = {}; -+ av_strerror(ret, err, AV_ERROR_MAX_STRING_SIZE); -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - buffersrc add frame failed: {} ({})", -+ __FUNCTION__, err, ret); -+ return VC_ERROR; - } - -- int ret = avcodec_receive_frame(m_pCodecContext, m_pFrame); -+ return ProcessFilterOut(); -+} -+ -+CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterOut() -+{ -+ if (!m_pFilterOut) -+ return VC_EOF; -+ -+ int ret = av_buffersink_get_frame(m_pFilterOut, m_pFrame); - if (ret == AVERROR(EAGAIN)) - return VC_BUFFER; - else if (ret == AVERROR_EOF) -@@ -587,11 +601,47 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecD - { - char err[AV_ERROR_MAX_STRING_SIZE] = {}; - av_strerror(ret, err, AV_ERROR_MAX_STRING_SIZE); -- CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - receive frame failed: {} ({})", __FUNCTION__, -- err, ret); -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - buffersink get frame failed: {} ({})", -+ __FUNCTION__, err, ret); - return VC_ERROR; - } - -+ return VC_PICTURE; -+} -+ -+CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::GetPicture(VideoPicture* pVideoPicture) -+{ -+ if (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN) -+ Drain(); -+ -+ if (pVideoPicture->videoBuffer) -+ { -+ pVideoPicture->videoBuffer->Release(); -+ pVideoPicture->videoBuffer = nullptr; -+ } -+ -+ auto result = ProcessFilterOut(); -+ if (result != VC_PICTURE) -+ { -+ int ret = avcodec_receive_frame(m_pCodecContext, m_pFrame); -+ if (ret == AVERROR(EAGAIN)) -+ return VC_BUFFER; -+ else if (ret == AVERROR_EOF) -+ return VC_EOF; -+ else if (ret) -+ { -+ char err[AV_ERROR_MAX_STRING_SIZE] = {}; -+ av_strerror(ret, err, AV_ERROR_MAX_STRING_SIZE); -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - receive frame failed: {} ({})", -+ __FUNCTION__, err, ret); -+ return VC_ERROR; -+ } -+ -+ result = ProcessFilterIn(); -+ if (result != VC_PICTURE) -+ return result; -+ } -+ - SetPictureParams(pVideoPicture); - - if (IsSupportedHwFormat(static_cast(m_pFrame->format))) ---- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h -+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h -@@ -14,6 +14,11 @@ - - #include - -+extern "C" -+{ -+#include -+} -+ - class CDVDVideoCodecDRMPRIME : public CDVDVideoCodec - { - public: -@@ -35,6 +40,8 @@ protected: - void Drain(); - void SetPictureParams(VideoPicture* pVideoPicture); - void UpdateProcessInfo(struct AVCodecContext* avctx, const enum AVPixelFormat fmt); -+ CDVDVideoCodec::VCReturn ProcessFilterIn(); -+ CDVDVideoCodec::VCReturn ProcessFilterOut(); - static enum AVPixelFormat GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt); - static int GetBuffer(struct AVCodecContext* avctx, AVFrame* frame, int flags); - -@@ -44,5 +51,8 @@ protected: - double m_DAR = 1.0; - AVCodecContext* m_pCodecContext = nullptr; - AVFrame* m_pFrame = nullptr; -+ AVFilterGraph* m_pFilterGraph = nullptr; -+ AVFilterContext* m_pFilterIn = nullptr; -+ AVFilterContext* m_pFilterOut = nullptr; - std::shared_ptr m_videoBufferPool; - }; diff --git a/projects/Rockchip/patches/kodi/0002-WIP-DRMPRIME-deinterlace-filter.patch b/projects/Rockchip/patches/kodi/0002-WIP-DRMPRIME-deinterlace-filter.patch deleted file mode 100644 index a47580b675..0000000000 --- a/projects/Rockchip/patches/kodi/0002-WIP-DRMPRIME-deinterlace-filter.patch +++ /dev/null @@ -1,497 +0,0 @@ -From 58f2acdc63d85eb9818d783a9a858b1ecc267fa7 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 26 Dec 2019 11:01:51 +0100 -Subject: [PATCH 2/2] WIP: DRMPRIME deinterlace filter - ---- - .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 368 +++++++++++++++--- - .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.h | 9 +- - 2 files changed, 322 insertions(+), 55 deletions(-) - ---- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -79,12 +79,15 @@ CDVDVideoCodecDRMPRIME::CDVDVideoCodecDR - : CDVDVideoCodec(processInfo) - { - m_pFrame = av_frame_alloc(); -+ m_pFilterFrame = av_frame_alloc(); - m_videoBufferPool = std::make_shared(); - } - - CDVDVideoCodecDRMPRIME::~CDVDVideoCodecDRMPRIME() - { - av_frame_free(&m_pFrame); -+ av_frame_free(&m_pFilterFrame); -+ FilterClose(); - avcodec_free_context(&m_pCodecContext); - } - -@@ -341,8 +344,19 @@ bool CDVDVideoCodecDRMPRIME::Open(CDVDSt - } - - UpdateProcessInfo(m_pCodecContext, m_pCodecContext->pix_fmt); -- m_processInfo.SetVideoDeintMethod("none"); -+ m_processInfo.SetVideoInterlaced(false); - m_processInfo.SetVideoDAR(hints.aspect); -+ m_processInfo.SetVideoDeintMethod("none"); -+ -+ FilterTest(); -+ -+ if (!m_deintFilterName.empty()) -+ { -+ std::list methods; -+ methods.push_back(EINTERLACEMETHOD::VS_INTERLACEMETHOD_DEINTERLACE); -+ m_processInfo.UpdateDeinterlacingMethods(methods); -+ m_processInfo.SetDeinterlacingMethodDefault(EINTERLACEMETHOD::VS_INTERLACEMETHOD_DEINTERLACE); -+ } - - return true; - } -@@ -418,6 +432,8 @@ void CDVDVideoCodecDRMPRIME::Reset() - return; - - Drain(); -+ m_filters.clear(); -+ FilterClose(); - - do - { -@@ -465,7 +481,7 @@ void CDVDVideoCodecDRMPRIME::Drain() - av_packet_free(&avpkt); - } - --void CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) -+bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) - { - pVideoPicture->iWidth = m_pFrame->width; - pVideoPicture->iHeight = m_pFrame->height; -@@ -559,13 +575,232 @@ void CDVDVideoCodecDRMPRIME::SetPictureP - ? DVD_NOPTS_VALUE - : static_cast(pts) * DVD_TIME_BASE / AV_TIME_BASE; - pVideoPicture->dts = DVD_NOPTS_VALUE; -+ -+ if (IsSupportedHwFormat(static_cast(m_pFrame->format))) -+ { -+ CVideoBufferDRMPRIMEFFmpeg* buffer = -+ dynamic_cast(m_videoBufferPool->Get()); -+ buffer->SetPictureParams(*pVideoPicture); -+ buffer->SetRef(m_pFrame); -+ pVideoPicture->videoBuffer = buffer; -+ } -+ else if (m_pFrame->opaque) -+ { -+ CVideoBufferDMA* buffer = static_cast(m_pFrame->opaque); -+ buffer->SetPictureParams(*pVideoPicture); -+ buffer->Acquire(); -+ buffer->SyncEnd(); -+ buffer->SetDimensions(m_pFrame->width, m_pFrame->height); -+ -+ pVideoPicture->videoBuffer = buffer; -+ av_frame_unref(m_pFrame); -+ } -+ -+ if (!pVideoPicture->videoBuffer) -+ { -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - videoBuffer:nullptr format:{}", __FUNCTION__, -+ av_get_pix_fmt_name(static_cast(m_pFrame->format))); -+ av_frame_unref(m_pFrame); -+ return false; -+ } -+ -+ return true; - } - --CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterIn() -+void CDVDVideoCodecDRMPRIME::FilterTest() -+{ -+ const AVFilter* filter; -+ void* opaque{}; -+ -+ m_deintFilterName.clear(); -+ -+ while ((filter = av_filter_iterate(&opaque)) != nullptr) -+ { -+ std::string name(filter->name); -+ -+ if (name.find("deinterlace") != std::string::npos) -+ { -+ if (FilterOpen(name, true)) -+ { -+ m_deintFilterName = name; -+ -+ CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::{} - found deinterlacing filter {}", -+ __FUNCTION__, name); -+ -+ return; -+ } -+ } -+ } -+ -+ CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::{} - no deinterlacing filter found", -+ __FUNCTION__); -+} -+ -+bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) - { -- if (!m_pFilterIn) -- return VC_PICTURE; -+ int result; -+ -+ if (m_pFilterGraph) -+ FilterClose(); -+ -+ if (filters.empty()) -+ return true; -+ -+ if (!(m_pFilterGraph = avfilter_graph_alloc())) -+ { -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - unable to alloc filter graph"); -+ return false; -+ } - -+ const AVFilter* srcFilter = avfilter_get_by_name("buffer"); -+ const AVFilter* outFilter = avfilter_get_by_name("buffersink"); -+ enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NONE }; -+ -+ std::string args = StringUtils::Format("video_size={}x{}:pix_fmt={}:time_base={}/{}:" -+ "pixel_aspect={}/{}", -+ m_pCodecContext->width, -+ m_pCodecContext->height, -+ m_pCodecContext->pix_fmt, -+ m_pCodecContext->time_base.num ? -+ m_pCodecContext->time_base.num : 1, -+ m_pCodecContext->time_base.num ? -+ m_pCodecContext->time_base.den : 1, -+ m_pCodecContext->sample_aspect_ratio.num != 0 ? -+ m_pCodecContext->sample_aspect_ratio.num : 1, -+ m_pCodecContext->sample_aspect_ratio.num != 0 ? -+ m_pCodecContext->sample_aspect_ratio.den : 1); -+ -+ result = avfilter_graph_create_filter(&m_pFilterIn, srcFilter, "src", -+ args.c_str(), NULL, m_pFilterGraph); -+ if (result < 0) -+ { -+ char err[AV_ERROR_MAX_STRING_SIZE] = {}; -+ av_strerror(result, err, AV_ERROR_MAX_STRING_SIZE); -+ CLog::Log(LOGERROR, -+ "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_create_filter: src: {} ({})", -+ err, result); -+ return false; -+ } -+ -+ AVBufferSrcParameters *par = av_buffersrc_parameters_alloc(); -+ if (!par) -+ { -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - unable to alloc buffersrc"); -+ return false; -+ } -+ -+ memset(par, 0, sizeof(*par)); -+ par->format = AV_PIX_FMT_NONE; -+ par->hw_frames_ctx = m_pCodecContext->hw_device_ctx; -+ -+ result = av_buffersrc_parameters_set(m_pFilterIn, par); -+ if (result < 0) -+ { -+ char err[AV_ERROR_MAX_STRING_SIZE] = {}; -+ av_strerror(result, err, AV_ERROR_MAX_STRING_SIZE); -+ CLog::Log(LOGERROR, -+ "CDVDVideoCodecDRMPRIME::FilterOpen - av_buffersrc_parameters_set: {} ({})", -+ err, result); -+ return false; -+ } -+ av_freep(&par); -+ -+ result = avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", -+ NULL, NULL, m_pFilterGraph); -+ if (result < 0) -+ { -+ char err[AV_ERROR_MAX_STRING_SIZE] = {}; -+ av_strerror(result, err, AV_ERROR_MAX_STRING_SIZE); -+ CLog::Log(LOGERROR, -+ "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_create_filter: out: {} ({})", -+ err, result); -+ return false; -+ } -+ -+ result = av_opt_set_int_list(m_pFilterOut, "pix_fmts", &pix_fmts[0], -+ AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN); -+ if (result < 0) -+ { -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - failed settings pix formats"); -+ return false; -+ } -+ -+ AVFilterInOut* outputs = avfilter_inout_alloc(); -+ AVFilterInOut* inputs = avfilter_inout_alloc(); -+ -+ outputs->name = av_strdup("in"); -+ outputs->filter_ctx = m_pFilterIn; -+ outputs->pad_idx = 0; -+ outputs->next = nullptr; -+ -+ inputs->name = av_strdup("out"); -+ inputs->filter_ctx = m_pFilterOut; -+ inputs->pad_idx = 0; -+ inputs->next = nullptr; -+ -+ result = avfilter_graph_parse_ptr(m_pFilterGraph, filters.c_str(), &inputs, &outputs, NULL); -+ avfilter_inout_free(&outputs); -+ avfilter_inout_free(&inputs); -+ -+ if (result < 0) -+ { -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_parse"); -+ return false; -+ } -+ -+ if ((result = avfilter_graph_config(m_pFilterGraph, nullptr)) < 0) -+ { -+ char err[AV_ERROR_MAX_STRING_SIZE] = {}; -+ av_strerror(result, err, AV_ERROR_MAX_STRING_SIZE); -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_config: {} ({})", -+ err, result); -+ return false; -+ } -+ -+ if (test) -+ { -+ FilterClose(); -+ return true; -+ } -+ -+ if (filters.find("deinterlace") != std::string::npos) -+ { -+ m_processInfo.SetVideoDeintMethod(filters); -+ } -+ else -+ { -+ m_processInfo.SetVideoDeintMethod("none"); -+ } -+ -+ if (CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO)) -+ { -+ char* graphDump = avfilter_graph_dump(m_pFilterGraph, nullptr); -+ if (graphDump) -+ { -+ CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::FilterOpen - Final filter graph:\n{}", -+ graphDump); -+ av_freep(&graphDump); -+ } -+ } -+ -+ return true; -+} -+ -+void CDVDVideoCodecDRMPRIME::FilterClose() -+{ -+ if (m_pFilterGraph) -+ { -+ CLog::Log(LOGDEBUG, LOGVIDEO, "CDVDVideoCodecDRMPRIME::FilterClose - Freeing filter graph"); -+ avfilter_graph_free(&m_pFilterGraph); -+ -+ // Disposed by above code -+ m_pFilterIn = nullptr; -+ m_pFilterOut = nullptr; -+ } -+} -+ -+CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterIn() -+{ - int ret = av_buffersrc_add_frame(m_pFilterIn, m_pFrame); - if (ret < 0) - { -@@ -581,21 +816,14 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecD - - CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterOut() - { -- if (!m_pFilterOut) -- return VC_EOF; -- -- int ret = av_buffersink_get_frame(m_pFilterOut, m_pFrame); -+ int ret = av_buffersink_get_frame(m_pFilterOut, m_pFilterFrame); - if (ret == AVERROR(EAGAIN)) - return VC_BUFFER; - else if (ret == AVERROR_EOF) - { -- if (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN) -- { -- CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::{} - flush buffers", __FUNCTION__); -- avcodec_flush_buffers(m_pCodecContext); -- SetCodecControl(m_codecControlFlags & ~DVD_CODEC_CTRL_DRAIN); -- } -- return VC_EOF; -+ ret = av_buffersink_get_frame(m_pFilterOut, m_pFilterFrame); -+ if (ret < 0) -+ return VC_BUFFER; - } - else if (ret) - { -@@ -606,9 +834,27 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecD - return VC_ERROR; - } - -+ av_frame_unref(m_pFrame); -+ av_frame_move_ref(m_pFrame, m_pFilterFrame); -+ - return VC_PICTURE; - } - -+std::string CDVDVideoCodecDRMPRIME::GetFilterChain(bool interlaced) -+{ -+ // ask codec to do deinterlacing if possible -+ EINTERLACEMETHOD mInt = m_processInfo.GetVideoSettings().m_InterlaceMethod; -+ std::string filterChain; -+ -+ if (!m_processInfo.Supports(mInt)) -+ mInt = m_processInfo.GetFallbackDeintMethod(); -+ -+ if (mInt != VS_INTERLACEMETHOD_NONE && interlaced && !m_deintFilterName.empty()) -+ filterChain += m_deintFilterName; -+ -+ return filterChain; -+} -+ - CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::GetPicture(VideoPicture* pVideoPicture) - { - if (m_codecControlFlags & DVD_CODEC_CTRL_DRAIN) -@@ -620,57 +866,71 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecD - pVideoPicture->videoBuffer = nullptr; - } - -- auto result = ProcessFilterOut(); -- if (result != VC_PICTURE) -+ if (m_pFilterGraph) - { -- int ret = avcodec_receive_frame(m_pCodecContext, m_pFrame); -- if (ret == AVERROR(EAGAIN)) -- return VC_BUFFER; -- else if (ret == AVERROR_EOF) -- return VC_EOF; -- else if (ret) -+ auto ret = ProcessFilterOut(); -+ if (ret == VC_PICTURE) - { -- char err[AV_ERROR_MAX_STRING_SIZE] = {}; -- av_strerror(ret, err, AV_ERROR_MAX_STRING_SIZE); -- CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - receive frame failed: {} ({})", -- __FUNCTION__, err, ret); -- return VC_ERROR; -+ if (!SetPictureParams(pVideoPicture)) -+ return VC_ERROR; -+ return VC_PICTURE; - } -+ else if (ret != VC_BUFFER) -+ { -+ return ret; -+ } -+ } - -- result = ProcessFilterIn(); -- if (result != VC_PICTURE) -- return result; -+ int ret = avcodec_receive_frame(m_pCodecContext, m_pFrame); -+ if (ret == AVERROR(EAGAIN)) -+ return VC_BUFFER; -+ else if (ret == AVERROR_EOF) -+ return VC_EOF; -+ else if (ret) -+ { -+ char err[AV_ERROR_MAX_STRING_SIZE] = {}; -+ av_strerror(ret, err, AV_ERROR_MAX_STRING_SIZE); -+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - receive frame failed: {} ({})", -+ __FUNCTION__, err, ret); -+ return VC_ERROR; - } - -- SetPictureParams(pVideoPicture); -+ if (!m_processInfo.GetVideoInterlaced() && m_pFrame->interlaced_frame) -+ m_processInfo.SetVideoInterlaced(true); - -- if (IsSupportedHwFormat(static_cast(m_pFrame->format))) -+ std::string filterChain = GetFilterChain(m_pFrame->interlaced_frame); -+ if (!filterChain.empty()) - { -- CVideoBufferDRMPRIMEFFmpeg* buffer = -- dynamic_cast(m_videoBufferPool->Get()); -- buffer->SetPictureParams(*pVideoPicture); -- buffer->SetRef(m_pFrame); -- pVideoPicture->videoBuffer = buffer; -+ bool reopenFilter = false; -+ if (m_filters != filterChain) -+ reopenFilter = true; -+ -+ if (m_pFilterGraph && -+ (m_pFilterIn->outputs[0]->w != m_pCodecContext->width || -+ m_pFilterIn->outputs[0]->h != m_pCodecContext->height)) -+ reopenFilter = true; -+ -+ if (reopenFilter) -+ { -+ m_filters = filterChain; -+ if (!FilterOpen(filterChain, false)) -+ FilterClose(); -+ } -+ -+ if (m_pFilterGraph) -+ { -+ if (ProcessFilterIn() != VC_PICTURE) -+ return VC_NONE; -+ } - } -- else if (m_pFrame->opaque) -+ else - { -- CVideoBufferDMA* buffer = static_cast(m_pFrame->opaque); -- buffer->SetPictureParams(*pVideoPicture); -- buffer->Acquire(); -- buffer->SyncEnd(); -- buffer->SetDimensions(m_pFrame->width, m_pFrame->height); -- -- pVideoPicture->videoBuffer = buffer; -- av_frame_unref(m_pFrame); -+ m_filters.clear(); -+ FilterClose(); - } - -- if (!pVideoPicture->videoBuffer) -- { -- CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - videoBuffer:nullptr format:{}", __FUNCTION__, -- av_get_pix_fmt_name(static_cast(m_pFrame->format))); -- av_frame_unref(m_pFrame); -+ if (!SetPictureParams(pVideoPicture)) - return VC_ERROR; -- } - - return VC_PICTURE; - } ---- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h -+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h -@@ -38,19 +38,26 @@ public: - - protected: - void Drain(); -- void SetPictureParams(VideoPicture* pVideoPicture); -+ bool SetPictureParams(VideoPicture* pVideoPicture); - void UpdateProcessInfo(struct AVCodecContext* avctx, const enum AVPixelFormat fmt); - CDVDVideoCodec::VCReturn ProcessFilterIn(); - CDVDVideoCodec::VCReturn ProcessFilterOut(); - static enum AVPixelFormat GetFormat(struct AVCodecContext* avctx, const enum AVPixelFormat* fmt); - static int GetBuffer(struct AVCodecContext* avctx, AVFrame* frame, int flags); -+ bool FilterOpen(const std::string& filters, bool test); -+ void FilterClose(); -+ void FilterTest(); -+ std::string GetFilterChain(bool interlaced); - - std::string m_name; -+ std::string m_deintFilterName; -+ std::string m_filters; - int m_codecControlFlags = 0; - CDVDStreamInfo m_hints; - double m_DAR = 1.0; - AVCodecContext* m_pCodecContext = nullptr; - AVFrame* m_pFrame = nullptr; -+ AVFrame* m_pFilterFrame = nullptr; - AVFilterGraph* m_pFilterGraph = nullptr; - AVFilterContext* m_pFilterIn = nullptr; - AVFilterContext* m_pFilterOut = nullptr;