From f7420b1993dd36154498caee65ff8ab4818c1194 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 16 Jul 2022 12:10:42 +0200 Subject: [PATCH] RPi: use common kodi drmprime filter patches Signed-off-by: Matthias Reichl --- packages/mediacenter/kodi/package.mk | 2 +- .../patches/kodi/kodi-001-deinterlace.patch | 751 +----------------- 2 files changed, 31 insertions(+), 722 deletions(-) diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index 4dc9f1475d..70e17cc9f2 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -203,7 +203,7 @@ configure_package() { fi fi - if [ "${PROJECT}" = "Allwinner" -o "${PROJECT}" = "Rockchip" ]; then + if [ "${PROJECT}" = "Allwinner" -o "${PROJECT}" = "Rockchip" -o "${PROJECT}" = "RPi" ]; then PKG_PATCH_DIRS+=" drmprime-filter" fi diff --git a/projects/RPi/patches/kodi/kodi-001-deinterlace.patch b/projects/RPi/patches/kodi/kodi-001-deinterlace.patch index bd340b4ead..96628405b3 100644 --- a/projects/RPi/patches/kodi/kodi-001-deinterlace.patch +++ b/projects/RPi/patches/kodi/kodi-001-deinterlace.patch @@ -1,698 +1,7 @@ -From d0b6b68794a58a375921c36c5a5457754edb220a Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Sun, 20 Oct 2019 17:10:07 +0000 -Subject: [PATCH 1/8] WIP: DVDVideoCodecDRMPRIME: add support for filters - ---- - .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 68 ++++++++++++++++--- - .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.h | 10 +++ - 2 files changed, 69 insertions(+), 9 deletions(-) - -diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -index ff0f9f5fcf..88c951f59b 100644 ---- 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 -@@ -573,18 +575,30 @@ void CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) - 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) -@@ -601,11 +615,47 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::GetPicture(VideoPicture* pVideo - { - 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))) -diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h -index db49d165e7..b5cacf1a3c 100644 ---- 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; - }; --- -2.30.2 - - -From 036f7a437d977c3d2ed322b8525250ff8f538cb6 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 26 Dec 2019 11:01:51 +0100 -Subject: [PATCH 2/8] WIP: DRMPRIME deinterlace filter - ---- - .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 368 +++++++++++++++--- - .../DVDCodecs/Video/DVDVideoCodecDRMPRIME.h | 9 +- - 2 files changed, 322 insertions(+), 55 deletions(-) - -diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -index 88c951f59b..846b14b555 100644 ---- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -80,12 +80,15 @@ CDVDVideoCodecDRMPRIME::CDVDVideoCodecDRMPRIME(CProcessInfo& processInfo) - : 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); - } - -@@ -354,8 +357,19 @@ bool CDVDVideoCodecDRMPRIME::Open(CDVDStreamInfo& hints, CDVDCodecOptions& optio - } - - 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; - } -@@ -431,6 +445,8 @@ void CDVDVideoCodecDRMPRIME::Reset() - return; - - Drain(); -+ m_filters.clear(); -+ FilterClose(); - - do - { -@@ -478,7 +494,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; -@@ -573,13 +589,232 @@ void CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) - ? 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) -+{ -+ 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=%dx%d:pix_fmt=%d:time_base=%d/%d:" -+ "pixel_aspect=%d/%d:sws_param=flags=2", -+ 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%s", -+ graphDump); -+ av_freep(&graphDump); -+ } -+ } -+ -+ return true; -+} -+ -+void CDVDVideoCodecDRMPRIME::FilterClose() - { -- if (!m_pFilterIn) -- return VC_PICTURE; -+ 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) - { -@@ -595,21 +830,14 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterIn() - - 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) - { -@@ -620,9 +848,27 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterOut() - 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) -@@ -634,57 +880,71 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::GetPicture(VideoPicture* pVideo - 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; - } -diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h -index b5cacf1a3c..fab3431d40 100644 ---- 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; --- -2.30.2 - - -From 78951d3e00b305150cccc509528e36dd8f427b49 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Wed, 24 Nov 2021 20:22:41 +0000 -Subject: [PATCH 3/8] CDVDVideoCodecDRMPRIME: Fix Format calls and some logging - ---- - .../VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -index 846b14b555..1501177dc3 100644 ---- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -670,8 +670,8 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) - 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=%dx%d:pix_fmt=%d:time_base=%d/%d:" -- "pixel_aspect=%d/%d:sws_param=flags=2", -+ std::string args = StringUtils::Format("video_size={}x{}:pix_fmt={}:time_base={}/{}:" -+ "pixel_aspect={}/{}:sws_param=flags=2", - m_pCodecContext->width, - m_pCodecContext->height, - m_pCodecContext->pix_fmt, -@@ -791,7 +791,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) - char* graphDump = avfilter_graph_dump(m_pFilterGraph, nullptr); - if (graphDump) - { -- CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::FilterOpen - Final filter graph:\n%s", -+ CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::FilterOpen - Final filter graph:\n{}", - graphDump); - av_freep(&graphDump); - } --- -2.30.2 - - -From 172b17993cce657e98cd2464d10a59d4e7a774bc Mon Sep 17 00:00:00 2001 +From 312239e6fcd892b1c3e9dbb86d89a1b5079f445e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 27 Aug 2021 20:29:50 +0100 -Subject: [PATCH 4/8] DVDVideoCodecDRMPRIME: Avoid exception with +Subject: [PATCH 1/5] DVDVideoCodecDRMPRIME: Avoid exception with AV_PIX_FMT_NONE --- @@ -700,10 +9,10 @@ Subject: [PATCH 4/8] DVDVideoCodecDRMPRIME: Avoid exception with 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -index 1501177dc3..0f9e02fba1 100644 +index cb801defc2..7e970bd9a6 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -613,7 +613,7 @@ bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) +@@ -599,7 +599,7 @@ bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) if (!pVideoPicture->videoBuffer) { CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - videoBuffer:nullptr format:{}", __FUNCTION__, @@ -716,10 +25,10 @@ index 1501177dc3..0f9e02fba1 100644 2.30.2 -From 897ea0d5fe258740cdaeeaa6a9384ebd5fef0b22 Mon Sep 17 00:00:00 2001 +From a57ab9736249fff9971ca194a50e8aee5f163883 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 11 Sep 2021 14:03:05 +0100 -Subject: [PATCH 5/8] CDVDVideoCodecDRMPRIME: Also support YUV420 buffers +Subject: [PATCH 2/5] CDVDVideoCodecDRMPRIME: Also support YUV420 buffers CDVDVideoCodecDRMPRIME: Add support for deinterlace of sw decoded buffers @@ -729,10 +38,10 @@ Need to call SetDimensions earlier and store the drm descriptor in expected plac 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -index 0f9e02fba1..9bae86ef26 100644 +index 7e970bd9a6..78d61e1aa2 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -590,7 +590,7 @@ bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) +@@ -576,7 +576,7 @@ bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture) : static_cast(pts) * DVD_TIME_BASE / AV_TIME_BASE; pVideoPicture->dts = DVD_NOPTS_VALUE; @@ -741,7 +50,7 @@ index 0f9e02fba1..9bae86ef26 100644 { CVideoBufferDRMPRIMEFFmpeg* buffer = dynamic_cast(m_videoBufferPool->Get()); -@@ -668,7 +668,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -654,7 +654,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) const AVFilter* srcFilter = avfilter_get_by_name("buffer"); const AVFilter* outFilter = avfilter_get_by_name("buffersink"); @@ -749,8 +58,8 @@ index 0f9e02fba1..9bae86ef26 100644 + enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }; std::string args = StringUtils::Format("video_size={}x{}:pix_fmt={}:time_base={}/{}:" - "pixel_aspect={}/{}:sws_param=flags=2", -@@ -815,6 +815,16 @@ void CDVDVideoCodecDRMPRIME::FilterClose() + "pixel_aspect={}/{}", +@@ -801,6 +801,16 @@ void CDVDVideoCodecDRMPRIME::FilterClose() CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterIn() { @@ -771,10 +80,10 @@ index 0f9e02fba1..9bae86ef26 100644 2.30.2 -From 0c8f2a50221f3ae7b68851873d4267748247509c Mon Sep 17 00:00:00 2001 +From 6981e216d4ef5c3ca16fe00edeef0dbcb4ef8bd7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 17 Sep 2021 15:23:16 +0100 -Subject: [PATCH 6/8] DVDVideoCodecDRMPRIME: Leave deinterlace filter active on +Subject: [PATCH 3/5] DVDVideoCodecDRMPRIME: Leave deinterlace filter active on a progressive frame Interlaced content often has strange mixtures of interlace and progressive frames (e.g. IIPPPPIIPPPP) @@ -787,10 +96,10 @@ be just copied by deinterlace filter 1 file changed, 4 insertions(+) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -index 9bae86ef26..9d4e2c8821 100644 +index 78d61e1aa2..dde55de7d4 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -873,6 +873,10 @@ std::string CDVDVideoCodecDRMPRIME::GetFilterChain(bool interlaced) +@@ -859,6 +859,10 @@ std::string CDVDVideoCodecDRMPRIME::GetFilterChain(bool interlaced) if (!m_processInfo.Supports(mInt)) mInt = m_processInfo.GetFallbackDeintMethod(); @@ -805,10 +114,10 @@ index 9bae86ef26..9d4e2c8821 100644 2.30.2 -From 96193817b2075055f134c32be424dd4a2a25b0de Mon Sep 17 00:00:00 2001 +From f86e4d66f8f49e7ca08679eb1b3de6742f92a1af Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Tue, 30 Nov 2021 16:05:06 +0000 -Subject: [PATCH 7/8] SetVideoInterlaced: Set and unset deinterlace method name +Subject: [PATCH 4/5] SetVideoInterlaced: Set and unset deinterlace method name reported --- @@ -816,10 +125,10 @@ Subject: [PATCH 7/8] SetVideoInterlaced: Set and unset deinterlace method name 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -index 9d4e2c8821..85e1b7ec0c 100644 +index dde55de7d4..2d33a73492 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -777,14 +777,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -763,14 +763,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) return true; } @@ -835,7 +144,7 @@ index 9d4e2c8821..85e1b7ec0c 100644 if (CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO)) { -@@ -802,6 +795,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -788,6 +781,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) void CDVDVideoCodecDRMPRIME::FilterClose() { @@ -847,10 +156,10 @@ index 9d4e2c8821..85e1b7ec0c 100644 2.30.2 -From 15f7f37d237db347265530699f90297fdaa065ea Mon Sep 17 00:00:00 2001 +From c9bd447122ae81919339e2a9583d7798db571b48 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Wed, 24 Nov 2021 20:21:28 +0000 -Subject: [PATCH 8/8] DVDVideoCodecDRMPRIME: Close deinterlace filter on error +Subject: [PATCH 5/5] DVDVideoCodecDRMPRIME: Close deinterlace filter on error Otherwise we crash later with an invalid m_pFilterGraph pointer --- @@ -858,10 +167,10 @@ Otherwise we crash later with an invalid m_pFilterGraph pointer 1 file changed, 7 insertions(+) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -index 85e1b7ec0c..b2b941f355 100644 +index 2d33a73492..998ae5f05c 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp -@@ -693,6 +693,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -679,6 +679,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_create_filter: src: {} ({})", err, result); @@ -869,7 +178,7 @@ index 85e1b7ec0c..b2b941f355 100644 return false; } -@@ -700,6 +701,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -686,6 +687,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) if (!par) { CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - unable to alloc buffersrc"); @@ -877,7 +186,7 @@ index 85e1b7ec0c..b2b941f355 100644 return false; } -@@ -715,6 +717,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -701,6 +703,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - av_buffersrc_parameters_set: {} ({})", err, result); @@ -885,7 +194,7 @@ index 85e1b7ec0c..b2b941f355 100644 return false; } av_freep(&par); -@@ -728,6 +731,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -714,6 +717,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_create_filter: out: {} ({})", err, result); @@ -893,7 +202,7 @@ index 85e1b7ec0c..b2b941f355 100644 return false; } -@@ -736,6 +740,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -722,6 +726,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) if (result < 0) { CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - failed settings pix formats"); @@ -901,7 +210,7 @@ index 85e1b7ec0c..b2b941f355 100644 return false; } -@@ -759,6 +764,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -745,6 +750,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) if (result < 0) { CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_parse"); @@ -909,7 +218,7 @@ index 85e1b7ec0c..b2b941f355 100644 return false; } -@@ -768,6 +774,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) +@@ -754,6 +760,7 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test) av_strerror(result, err, AV_ERROR_MAX_STRING_SIZE); CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_config: {} ({})", err, result);