kodi (RPi): add patches to support arbitrary pixel formats

Signed-off-by: Matthias Reichl <hias@horus.com>
This commit is contained in:
Matthias Reichl 2023-03-21 17:46:17 +01:00
parent 98490c3218
commit c1fd8cdbe6
7 changed files with 488 additions and 8 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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