mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-29 05:36:47 +00:00
kodi (RPi): add patches to support arbitrary pixel formats
Signed-off-by: Matthias Reichl <hias@horus.com>
This commit is contained in:
parent
98490c3218
commit
c1fd8cdbe6
@ -1,7 +1,7 @@
|
||||
From 97d39a46091b65e4355ce7e545bdec46ff2f87de Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 11 Sep 2021 14:03:05 +0100
|
||||
Subject: [PATCH 1/4] CDVDVideoCodecDRMPRIME: Also support YUV420 buffers
|
||||
Subject: [PATCH 1/7] CDVDVideoCodecDRMPRIME: Also support YUV420 buffers
|
||||
|
||||
CDVDVideoCodecDRMPRIME: Add support for deinterlace of sw decoded buffers
|
||||
|
||||
@ -50,5 +50,5 @@ index 20a5c24f53..a36107c515 100644
|
||||
if (ret < 0)
|
||||
{
|
||||
--
|
||||
2.39.0
|
||||
2.39.2
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 42b30508bfe5451d4dc2884acfde9e0ec2d58c92 Mon Sep 17 00:00:00 2001
|
||||
From: Dom Cobley <popcornmix@gmail.com>
|
||||
Date: Fri, 3 Dec 2021 16:00:50 +0000
|
||||
Subject: [PATCH 2/4] gbm: Set max bpc for high bit depth videos
|
||||
Subject: [PATCH 2/7] gbm: Set max bpc for high bit depth videos
|
||||
|
||||
---
|
||||
.../HwDecRender/VideoLayerBridgeDRMPRIME.cpp | 16 ++++++++++++++++
|
||||
@ -42,5 +42,5 @@ index 4b8ee5afbb..bd6623e8d1 100644
|
||||
|
||||
void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect)
|
||||
--
|
||||
2.39.0
|
||||
2.39.2
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 0b9b204c6560f3aff39697f92616b48102840dfe Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Rusak <lorusak@gmail.com>
|
||||
Date: Mon, 29 Apr 2019 18:48:45 -0700
|
||||
Subject: [PATCH 3/4] CVideoLayerBridgeDRMPRIME add colourspace connector
|
||||
Subject: [PATCH 3/7] CVideoLayerBridgeDRMPRIME add colourspace connector
|
||||
property
|
||||
|
||||
---
|
||||
@ -83,5 +83,5 @@ index bd6623e8d1..a1342595c6 100644
|
||||
|
||||
void CVideoLayerBridgeDRMPRIME::SetVideoPlane(CVideoBufferDRMPRIME* buffer, const CRect& destRect)
|
||||
--
|
||||
2.39.0
|
||||
2.39.2
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 518d8487d090af854fb72a7d0e5efc075d97228c Mon Sep 17 00:00:00 2001
|
||||
From: Dom Cobley <popcornmix@gmail.com>
|
||||
Date: Wed, 18 Jan 2023 16:41:00 +0000
|
||||
Subject: [PATCH 4/4] CDVDVideoCodecDRMPRIME: Adjust av formats to match recent
|
||||
Subject: [PATCH 4/7] CDVDVideoCodecDRMPRIME: Adjust av formats to match recent
|
||||
ffmpeg changes
|
||||
|
||||
---
|
||||
@ -45,5 +45,5 @@ index a36107c515..d5b3289680 100644
|
||||
if (ret < 0)
|
||||
{
|
||||
--
|
||||
2.39.0
|
||||
2.39.2
|
||||
|
||||
|
@ -0,0 +1,93 @@
|
||||
From a11461db2d442e0648ebb9255a2399a647d8f5be Mon Sep 17 00:00:00 2001
|
||||
From: Dom Cobley <popcornmix@gmail.com>
|
||||
Date: Wed, 25 Jan 2023 18:42:24 +0000
|
||||
Subject: [PATCH 5/7] DVDVideoCodecDRMPRIME: Support YUV422 and YUV444 formats
|
||||
|
||||
See: https://github.com/xbmc/xbmc/issues/20017
|
||||
|
||||
We currently can't play YUV422 and YUV444 videos with drm
|
||||
but they can be made to work with straightforward plumbing
|
||||
---
|
||||
.../Buffers/VideoBufferPoolDMA.cpp | 6 +++++
|
||||
.../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 27 +++++++++++++++----
|
||||
2 files changed, 28 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/xbmc/cores/VideoPlayer/Buffers/VideoBufferPoolDMA.cpp b/xbmc/cores/VideoPlayer/Buffers/VideoBufferPoolDMA.cpp
|
||||
index fb2dfc6c78..e6b071117e 100644
|
||||
--- a/xbmc/cores/VideoPlayer/Buffers/VideoBufferPoolDMA.cpp
|
||||
+++ b/xbmc/cores/VideoPlayer/Buffers/VideoBufferPoolDMA.cpp
|
||||
@@ -123,6 +123,12 @@ uint32_t CVideoBufferPoolDMA::TranslateFormat(AVPixelFormat format)
|
||||
case AV_PIX_FMT_YUV420P:
|
||||
case AV_PIX_FMT_YUVJ420P:
|
||||
return DRM_FORMAT_YUV420;
|
||||
+ case AV_PIX_FMT_YUV422P:
|
||||
+ case AV_PIX_FMT_YUVJ422P:
|
||||
+ return DRM_FORMAT_YUV422;
|
||||
+ case AV_PIX_FMT_YUV444P:
|
||||
+ case AV_PIX_FMT_YUVJ444P:
|
||||
+ return DRM_FORMAT_YUV444;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
index d5b3289680..4af903ecf5 100644
|
||||
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
@@ -142,7 +142,8 @@ static bool IsSupportedHwFormat(const enum AVPixelFormat fmt)
|
||||
|
||||
static bool IsSupportedSwFormat(const enum AVPixelFormat fmt)
|
||||
{
|
||||
- return fmt == AV_PIX_FMT_YUV420P || fmt == AV_PIX_FMT_YUVJ420P;
|
||||
+ return fmt == AV_PIX_FMT_YUV420P || fmt == AV_PIX_FMT_YUVJ420P || fmt == AV_PIX_FMT_YUV422P ||
|
||||
+ fmt == AV_PIX_FMT_YUVJ422P || fmt == AV_PIX_FMT_YUV444P || fmt == AV_PIX_FMT_YUVJ444P;
|
||||
}
|
||||
|
||||
static const AVCodecHWConfig* FindHWConfig(const AVCodec* codec)
|
||||
@@ -206,7 +207,14 @@ enum AVPixelFormat CDVDVideoCodecDRMPRIME::GetFormat(struct AVCodecContext* avct
|
||||
}
|
||||
}
|
||||
|
||||
- CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - unsupported pixel format", __FUNCTION__);
|
||||
+ std::vector<std::string> formats;
|
||||
+ for (int n = 0; fmt[n] != AV_PIX_FMT_NONE; n++)
|
||||
+ {
|
||||
+ formats.emplace_back(av_get_pix_fmt_name(fmt[n]));
|
||||
+ }
|
||||
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::{} - no supported pixel formats: {}", __FUNCTION__,
|
||||
+ StringUtils::Join(formats, ", "));
|
||||
+
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
@@ -226,6 +234,14 @@ int CDVDVideoCodecDRMPRIME::GetBuffer(struct AVCodecContext* avctx, AVFrame* fra
|
||||
case AV_PIX_FMT_YUVJ420P:
|
||||
size = width * height * 3 / 2;
|
||||
break;
|
||||
+ case AV_PIX_FMT_YUV422P:
|
||||
+ case AV_PIX_FMT_YUVJ422P:
|
||||
+ size = width * height * 2;
|
||||
+ break;
|
||||
+ case AV_PIX_FMT_YUV444P:
|
||||
+ case AV_PIX_FMT_YUVJ444P:
|
||||
+ size = width * height * 3;
|
||||
+ break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -512,9 +528,10 @@ bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture)
|
||||
(static_cast<int>(lrint(pVideoPicture->iWidth / aspect_ratio))) & -3;
|
||||
}
|
||||
|
||||
- pVideoPicture->color_range = m_pFrame->color_range == AVCOL_RANGE_JPEG ||
|
||||
- m_pFrame->format == AV_PIX_FMT_YUVJ420P ||
|
||||
- m_hints.colorRange == AVCOL_RANGE_JPEG;
|
||||
+ pVideoPicture->color_range =
|
||||
+ m_pFrame->color_range == AVCOL_RANGE_JPEG || m_pFrame->format == AV_PIX_FMT_YUVJ420P ||
|
||||
+ m_pFrame->format == AV_PIX_FMT_YUVJ422P || m_pFrame->format == AV_PIX_FMT_YUVJ444P ||
|
||||
+ m_hints.colorRange == AVCOL_RANGE_JPEG;
|
||||
pVideoPicture->color_primaries = m_pFrame->color_primaries == AVCOL_PRI_UNSPECIFIED
|
||||
? m_hints.colorPrimaries
|
||||
: m_pFrame->color_primaries;
|
||||
--
|
||||
2.39.2
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 7b820fa6812e8389613238c6ab3a12fc1dee0276 Mon Sep 17 00:00:00 2001
|
||||
From: Dom Cobley <popcornmix@gmail.com>
|
||||
Date: Tue, 31 Jan 2023 14:13:00 +0000
|
||||
Subject: [PATCH 6/7] VideoBufferDMA: Support exporting YCbCr444 buffers
|
||||
|
||||
The current code assumes chroma is decimated by two, but that is not necessarily the case.
|
||||
DRMPRIME decode with EGL rendering of YCbCr444 video will have corrupted colours.
|
||||
|
||||
Ask ffmpeg what the chroma decimation is.
|
||||
---
|
||||
.../VideoPlayer/Buffers/VideoBufferDMA.cpp | 21 ++++++++++++-------
|
||||
1 file changed, 14 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDMA.cpp b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDMA.cpp
|
||||
index 2dd7c1341d..3e6bf0dc7a 100644
|
||||
--- a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDMA.cpp
|
||||
+++ b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDMA.cpp
|
||||
@@ -119,20 +119,27 @@ bool CVideoBufferDMA::Alloc()
|
||||
|
||||
void CVideoBufferDMA::Export(AVFrame* frame, uint32_t width, uint32_t height)
|
||||
{
|
||||
- m_planes = av_pix_fmt_count_planes(static_cast<AVPixelFormat>(frame->format));
|
||||
+ AVPixelFormat pix_fmt = static_cast<AVPixelFormat>(frame->format);
|
||||
+ m_planes = av_pix_fmt_count_planes(pix_fmt);
|
||||
+ int h_shift;
|
||||
+ int v_shift;
|
||||
|
||||
- if (m_planes < 2)
|
||||
- throw std::runtime_error(
|
||||
- "non-planar formats not supported: " +
|
||||
- std::string(av_get_pix_fmt_name(static_cast<AVPixelFormat>(frame->format))));
|
||||
+ if (av_pix_fmt_get_chroma_sub_sample(pix_fmt, &h_shift, &v_shift))
|
||||
+ throw std::runtime_error("unable to determine chroma_sub_sample: " +
|
||||
+ std::string(av_get_pix_fmt_name(pix_fmt)));
|
||||
+
|
||||
+ if (m_planes < 2 || m_planes > 3)
|
||||
+ throw std::runtime_error("only 2 or 3 plane formats supported: " +
|
||||
+ std::string(av_get_pix_fmt_name(pix_fmt)));
|
||||
|
||||
for (uint32_t plane = 0; plane < m_planes; plane++)
|
||||
{
|
||||
m_strides[plane] =
|
||||
av_image_get_linesize(static_cast<AVPixelFormat>(frame->format), width, plane);
|
||||
- m_offsets[plane] =
|
||||
- plane == 0 ? 0 : (m_offsets[plane - 1] + m_strides[plane - 1] * (height >> (plane - 1)));
|
||||
}
|
||||
+ m_offsets[0] = 0;
|
||||
+ m_offsets[1] = m_strides[0] * height;
|
||||
+ m_offsets[2] = m_offsets[1] + (m_strides[1] * height >> v_shift);
|
||||
|
||||
if (CServiceBroker::GetLogging().CanLogComponent(LOGVIDEO))
|
||||
{
|
||||
--
|
||||
2.39.2
|
||||
|
@ -0,0 +1,332 @@
|
||||
From ae91030c1a84693fd0d34b919f9f8434b08e00c9 Mon Sep 17 00:00:00 2001
|
||||
From: Dom Cobley <popcornmix@gmail.com>
|
||||
Date: Mon, 6 Feb 2023 15:19:51 +0000
|
||||
Subject: [PATCH 7/7] DVDVideoCodecDRMPRIME: Add support for arbitrary output
|
||||
pixel formats
|
||||
|
||||
This enables any ffmpeg pixel formats to be supported by DRMPRIME decoder
|
||||
by creating a scale ffmpeg filter to convert it to a supported format.
|
||||
|
||||
This allows formats like h264 Hi10P and hevc 12-bit 444 to be software decoded,
|
||||
converted and displayed through DRM.
|
||||
|
||||
This will be a cheaper path than disabling DRMPRIME, which is also
|
||||
software decode, convert, but then needs convert to texture and display through GL.
|
||||
|
||||
And it happens automatically without requiring user video settings
|
||||
---
|
||||
.../DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp | 124 +++++++++++-------
|
||||
.../DVDCodecs/Video/DVDVideoCodecDRMPRIME.h | 3 +-
|
||||
2 files changed, 77 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
index 4af903ecf5..92a182608d 100644
|
||||
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.cpp
|
||||
@@ -199,7 +199,7 @@ enum AVPixelFormat CDVDVideoCodecDRMPRIME::GetFormat(struct AVCodecContext* avct
|
||||
{
|
||||
for (int n = 0; fmt[n] != AV_PIX_FMT_NONE; n++)
|
||||
{
|
||||
- if (IsSupportedHwFormat(fmt[n]) || IsSupportedSwFormat(fmt[n]))
|
||||
+ //if (IsSupportedHwFormat(fmt[n]) || IsSupportedSwFormat(fmt[n]))
|
||||
{
|
||||
CDVDVideoCodecDRMPRIME* ctx = static_cast<CDVDVideoCodecDRMPRIME*>(avctx->opaque);
|
||||
ctx->UpdateProcessInfo(avctx, fmt[n]);
|
||||
@@ -220,7 +220,8 @@ enum AVPixelFormat CDVDVideoCodecDRMPRIME::GetFormat(struct AVCodecContext* avct
|
||||
|
||||
int CDVDVideoCodecDRMPRIME::GetBuffer(struct AVCodecContext* avctx, AVFrame* frame, int flags)
|
||||
{
|
||||
- if (IsSupportedSwFormat(static_cast<AVPixelFormat>(frame->format)))
|
||||
+ AVPixelFormat pix_fmt = static_cast<AVPixelFormat>(frame->format);
|
||||
+ if (IsSupportedSwFormat(pix_fmt))
|
||||
{
|
||||
int width = frame->width;
|
||||
int height = frame->height;
|
||||
@@ -228,7 +229,7 @@ int CDVDVideoCodecDRMPRIME::GetBuffer(struct AVCodecContext* avctx, AVFrame* fra
|
||||
AlignedSize(avctx, width, height);
|
||||
|
||||
int size;
|
||||
- switch (avctx->pix_fmt)
|
||||
+ switch (pix_fmt)
|
||||
{
|
||||
case AV_PIX_FMT_YUV420P:
|
||||
case AV_PIX_FMT_YUVJ420P:
|
||||
@@ -248,13 +249,12 @@ int CDVDVideoCodecDRMPRIME::GetBuffer(struct AVCodecContext* avctx, AVFrame* fra
|
||||
|
||||
CDVDVideoCodecDRMPRIME* ctx = static_cast<CDVDVideoCodecDRMPRIME*>(avctx->opaque);
|
||||
auto buffer = dynamic_cast<CVideoBufferDMA*>(
|
||||
- ctx->m_processInfo.GetVideoBufferManager().Get(avctx->pix_fmt, size, nullptr));
|
||||
+ ctx->m_processInfo.GetVideoBufferManager().Get(pix_fmt, size, nullptr));
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
- frame->opaque = static_cast<void*>(buffer);
|
||||
frame->opaque_ref =
|
||||
- av_buffer_create(nullptr, 0, ReleaseBuffer, frame->opaque, AV_BUFFER_FLAG_READONLY);
|
||||
+ av_buffer_create(nullptr, 0, ReleaseBuffer, static_cast<void*>(buffer), AV_BUFFER_FLAG_READONLY);
|
||||
|
||||
buffer->Export(frame, width, height);
|
||||
buffer->SyncStart();
|
||||
@@ -608,9 +608,9 @@ bool CDVDVideoCodecDRMPRIME::SetPictureParams(VideoPicture* pVideoPicture)
|
||||
buffer->SetRef(m_pFrame);
|
||||
pVideoPicture->videoBuffer = buffer;
|
||||
}
|
||||
- else if (m_pFrame->opaque)
|
||||
+ else if (IsSupportedSwFormat(static_cast<AVPixelFormat>(m_pFrame->format)))
|
||||
{
|
||||
- CVideoBufferDMA* buffer = static_cast<CVideoBufferDMA*>(m_pFrame->opaque);
|
||||
+ CVideoBufferDMA* buffer = static_cast<CVideoBufferDMA*>(av_buffer_get_opaque(m_pFrame->buf[0]));
|
||||
buffer->SetPictureParams(*pVideoPicture);
|
||||
buffer->Acquire();
|
||||
buffer->SyncEnd();
|
||||
@@ -644,13 +644,13 @@ void CDVDVideoCodecDRMPRIME::FilterTest()
|
||||
|
||||
if (name.find("deinterlace") != std::string::npos)
|
||||
{
|
||||
- if (FilterOpen(name, true))
|
||||
+ bool ret = FilterOpen(name, false, true);
|
||||
+ FilterClose();
|
||||
+ if (ret)
|
||||
{
|
||||
m_deintFilterName = name;
|
||||
-
|
||||
CLog::Log(LOGDEBUG, "CDVDVideoCodecDRMPRIME::{} - found deinterlacing filter {}",
|
||||
__FUNCTION__, name);
|
||||
-
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -660,14 +660,31 @@ void CDVDVideoCodecDRMPRIME::FilterTest()
|
||||
__FUNCTION__);
|
||||
}
|
||||
|
||||
-bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||
+AVFrame *CDVDVideoCodecDRMPRIME::alloc_filter_frame(AVFilterContext * ctx, void * v, int w, int h)
|
||||
+{
|
||||
+ int result;
|
||||
+ CDVDVideoCodecDRMPRIME* me = static_cast<CDVDVideoCodecDRMPRIME*>(v);
|
||||
+ AVFrame *frame = av_frame_alloc();
|
||||
+ frame->width = w;
|
||||
+ frame->height = h;
|
||||
+ frame->format = AV_PIX_FMT_YUV420P;
|
||||
+
|
||||
+ if ((result = CDVDVideoCodecDRMPRIME::GetBuffer(me->m_pCodecContext, frame, 0)) < 0)
|
||||
+ {
|
||||
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::alloc_filter_frame - failed to GetBuffer ({})", result);
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ return frame;
|
||||
+}
|
||||
+
|
||||
+bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool scale, bool test)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (m_pFilterGraph)
|
||||
FilterClose();
|
||||
|
||||
- if (filters.empty())
|
||||
+ if (filters.empty() && !scale)
|
||||
return true;
|
||||
|
||||
if (!(m_pFilterGraph = avfilter_graph_alloc()))
|
||||
@@ -678,13 +695,13 @@ 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");
|
||||
- enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NONE };
|
||||
+ enum AVPixelFormat pix_fmts[] = { scale ? AV_PIX_FMT_YUV420P : 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,
|
||||
- AV_PIX_FMT_DRM_PRIME,
|
||||
+ scale ? m_pCodecContext->pix_fmt : AV_PIX_FMT_DRM_PRIME,
|
||||
m_pCodecContext->time_base.num ?
|
||||
m_pCodecContext->time_base.num : 1,
|
||||
m_pCodecContext->time_base.num ?
|
||||
@@ -703,7 +720,6 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||
CLog::Log(LOGERROR,
|
||||
"CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_create_filter: src: {} ({})",
|
||||
err, result);
|
||||
- FilterClose();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -711,7 +727,6 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||
if (!par)
|
||||
{
|
||||
CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - unable to alloc buffersrc");
|
||||
- FilterClose();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -727,7 +742,6 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||
CLog::Log(LOGERROR,
|
||||
"CDVDVideoCodecDRMPRIME::FilterOpen - av_buffersrc_parameters_set: {} ({})",
|
||||
err, result);
|
||||
- FilterClose();
|
||||
return false;
|
||||
}
|
||||
av_freep(&par);
|
||||
@@ -741,7 +755,6 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||
CLog::Log(LOGERROR,
|
||||
"CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_create_filter: out: {} ({})",
|
||||
err, result);
|
||||
- FilterClose();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -750,32 +763,46 @@ bool CDVDVideoCodecDRMPRIME::FilterOpen(const std::string& filters, bool test)
|
||||
if (result < 0)
|
||||
{
|
||||
CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - failed settings pix formats");
|
||||
- FilterClose();
|
||||
return false;
|
||||
}
|
||||
|
||||
- AVFilterInOut* outputs = avfilter_inout_alloc();
|
||||
- AVFilterInOut* inputs = avfilter_inout_alloc();
|
||||
+ if (!filters.empty())
|
||||
+ {
|
||||
+ 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;
|
||||
+ 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;
|
||||
+ 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);
|
||||
+ result = avfilter_graph_parse_ptr(m_pFilterGraph, filters.c_str(), &inputs, &outputs, NULL);
|
||||
+ avfilter_inout_free(&outputs);
|
||||
+ avfilter_inout_free(&inputs);
|
||||
|
||||
- if (result < 0)
|
||||
+ if (result < 0)
|
||||
+ {
|
||||
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_parse");
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
{
|
||||
- CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_graph_parse");
|
||||
- FilterClose();
|
||||
- return false;
|
||||
+ if ((result = av_buffersink_set_alloc_video_frame(m_pFilterOut, alloc_filter_frame, static_cast<void*>(this))) < 0)
|
||||
+ {
|
||||
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - av_buffersink_set_alloc_video_frame = {}", result);
|
||||
+ return result;
|
||||
+ }
|
||||
+ if ((result = avfilter_link(m_pFilterIn, 0, m_pFilterOut, 0)) < 0)
|
||||
+ {
|
||||
+ CLog::Log(LOGERROR, "CDVDVideoCodecDRMPRIME::FilterOpen - avfilter_link");
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
|
||||
if ((result = avfilter_graph_config(m_pFilterGraph, nullptr)) < 0)
|
||||
@@ -784,15 +811,11 @@ 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);
|
||||
- FilterClose();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test)
|
||||
- {
|
||||
- FilterClose();
|
||||
return true;
|
||||
- }
|
||||
|
||||
m_processInfo.SetVideoDeintMethod(filters);
|
||||
|
||||
@@ -827,16 +850,16 @@ void CDVDVideoCodecDRMPRIME::FilterClose()
|
||||
CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::ProcessFilterIn()
|
||||
{
|
||||
// sw decoded buffers need cache flush and for descripter to be set
|
||||
- if (!IsSupportedHwFormat(static_cast<AVPixelFormat>(m_pFrame->format)) && m_pFrame->opaque != nullptr)
|
||||
+ if (!IsSupportedHwFormat(static_cast<AVPixelFormat>(m_pFrame->format)) && IsSupportedSwFormat(static_cast<AVPixelFormat>(m_pFrame->format)))
|
||||
{
|
||||
- CVideoBufferDMA* buffer = static_cast<CVideoBufferDMA*>(m_pFrame->opaque);
|
||||
+ CVideoBufferDMA* buffer = static_cast<CVideoBufferDMA*>(av_buffer_get_opaque(m_pFrame->buf[0]));
|
||||
buffer->SetDimensions(m_pFrame->width, m_pFrame->height);
|
||||
buffer->SyncEnd();
|
||||
auto descriptor = buffer->GetDescriptor();
|
||||
m_pFrame->data[0] = reinterpret_cast<uint8_t*>(descriptor);
|
||||
+ m_pFrame->format = AV_PIX_FMT_DRM_PRIME;
|
||||
}
|
||||
|
||||
- m_pFrame->format = AV_PIX_FMT_DRM_PRIME;
|
||||
int ret = av_buffersrc_add_frame(m_pFilterIn, m_pFrame);
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -929,25 +952,28 @@ CDVDVideoCodec::VCReturn CDVDVideoCodecDRMPRIME::GetPicture(VideoPicture* pVideo
|
||||
return VC_ERROR;
|
||||
}
|
||||
|
||||
+ // we need to scale if the buffer isn't in DRM_PRIME format
|
||||
+ bool need_scale = !IsSupportedSwFormat(static_cast<AVPixelFormat>(m_pFrame->format)) && !IsSupportedHwFormat(static_cast<AVPixelFormat>(m_pFrame->format));
|
||||
+
|
||||
if (!m_processInfo.GetVideoInterlaced() && m_pFrame->interlaced_frame)
|
||||
m_processInfo.SetVideoInterlaced(true);
|
||||
|
||||
std::string filterChain = GetFilterChain(m_pFrame->interlaced_frame);
|
||||
- if (!filterChain.empty())
|
||||
+ if (!filterChain.empty() || need_scale)
|
||||
{
|
||||
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))
|
||||
+ (m_pFilterIn->outputs[0]->w != m_pFrame->width ||
|
||||
+ m_pFilterIn->outputs[0]->h != m_pFrame->height))
|
||||
reopenFilter = true;
|
||||
|
||||
- if (reopenFilter)
|
||||
+ if (reopenFilter || (need_scale && m_pFilterGraph == nullptr))
|
||||
{
|
||||
m_filters = filterChain;
|
||||
- if (!FilterOpen(filterChain, false))
|
||||
+ if (!FilterOpen(filterChain, need_scale, false))
|
||||
FilterClose();
|
||||
}
|
||||
|
||||
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
|
||||
index fab3431d40..bb88fde1f9 100644
|
||||
--- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
|
||||
+++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecDRMPRIME.h
|
||||
@@ -44,7 +44,8 @@ protected:
|
||||
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);
|
||||
+ static AVFrame *alloc_filter_frame(AVFilterContext * ctx, void * v, int w, int h);
|
||||
+ bool FilterOpen(const std::string& filters, bool scale, bool test);
|
||||
void FilterClose();
|
||||
void FilterTest();
|
||||
std::string GetFilterChain(bool interlaced);
|
||||
--
|
||||
2.39.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user