cellVdec: cache alpha channel per thread and only fill it on change

This commit is contained in:
Megamouse
2026-09-30 16:33:05 +02:00
parent 1fe12b7778
commit a8fabaf570
+13 -9
View File
@@ -1827,12 +1827,14 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
AVPixelFormat out_f = AV_PIX_FMT_YUV420P;
std::unique_ptr<u8[]> alpha_plane;
thread_local std::vector<u8> alpha_plane;
thread_local u8 alpha = 0;
bool use_alpha = false;
switch (const u32 type = format->formatType)
{
case CELL_VDEC_PICFMT_ARGB32_ILV: out_f = AV_PIX_FMT_ARGB; alpha_plane.reset(new u8[w * h]); break;
case CELL_VDEC_PICFMT_RGBA32_ILV: out_f = AV_PIX_FMT_RGBA; alpha_plane.reset(new u8[w * h]); break;
case CELL_VDEC_PICFMT_ARGB32_ILV: out_f = AV_PIX_FMT_ARGB; use_alpha = true; break;
case CELL_VDEC_PICFMT_RGBA32_ILV: out_f = AV_PIX_FMT_RGBA; use_alpha = true; break;
case CELL_VDEC_PICFMT_UYVY422_ILV: out_f = AV_PIX_FMT_UYVY422; break;
case CELL_VDEC_PICFMT_YUV420_PLANAR: out_f = AV_PIX_FMT_YUV420P; break;
default:
@@ -1843,9 +1845,11 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
// TODO: color matrix
if (alpha_plane)
if (use_alpha && (alpha != format->alpha || static_cast<s32>(alpha_plane.size()) != w * h))
{
std::memset(alpha_plane.get(), format->alpha, w * h);
alpha = format->alpha;
alpha_plane.resize(w * h, alpha);
std::memset(alpha_plane.data(), format->alpha, alpha_plane.size());
}
AVPixelFormat in_f = AV_PIX_FMT_YUV420P;
@@ -1856,17 +1860,17 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
cellVdec.error("cellVdecGetPictureExt: experimental AVPixelFormat (handle=0x%x, seq_id=%d, cmd_id=%d, format=%d). This may cause suboptimal video quality.", handle, frame.seq_id, frame.cmd_id, frame->format);
[[fallthrough]];
case AV_PIX_FMT_YUV420P:
in_f = alpha_plane ? AV_PIX_FMT_YUVA420P : static_cast<AVPixelFormat>(frame->format);
in_f = false ? AV_PIX_FMT_YUVA420P : static_cast<AVPixelFormat>(frame->format);
break;
default:
fmt::throw_exception("cellVdecGetPictureExt: Unknown frame format (%d)", frame->format);
}
cellVdec.trace("cellVdecGetPictureExt: handle=0x%x, seq_id=%d, cmd_id=%d, w=%d, h=%d, frameFormat=%d, formatType=%d, in_f=%d, out_f=%d, alpha_plane=%d, alpha=%d, colorMatrixType=%d", handle, frame.seq_id, frame.cmd_id, w, h, frame->format, format->formatType, +in_f, +out_f, !!alpha_plane, format->alpha, format->colorMatrixType);
cellVdec.trace("cellVdecGetPictureExt: handle=0x%x, seq_id=%d, cmd_id=%d, w=%d, h=%d, frameFormat=%d, formatType=%d, in_f=%d, out_f=%d, use_alpha=%d, alpha=%d, colorMatrixType=%d", handle, frame.seq_id, frame.cmd_id, w, h, frame->format, format->formatType, +in_f, +out_f, use_alpha, format->alpha, format->colorMatrixType);
vdec->sws = sws_getCachedContext(vdec->sws, w, h, in_f, w, h, out_f, SWS_POINT, nullptr, nullptr, nullptr);
const u8* in_data[4] = { frame->data[0], frame->data[1], frame->data[2], alpha_plane.get() };
const u8* in_data[4] = { frame->data[0], frame->data[1], frame->data[2], use_alpha ? alpha_plane.data() : nullptr };
const int in_line[4] = { frame->linesize[0], frame->linesize[1], frame->linesize[2], w * 1 };
u8* out_data[4] = { outBuff.get_ptr() };
int out_line[4] = { w * 4 }; // RGBA32 or ARGB32
@@ -1875,7 +1879,7 @@ error_code cellVdecGetPictureExt(ppu_thread& ppu, u32 handle, vm::cptr<CellVdecP
// It's possible that we need to align the pitch to 128 here.
// PS HOME seems to rely on this somehow in certain cases.
if (!alpha_plane)
if (!use_alpha)
{
// YUV420P or UYVY422
out_data[1] = out_data[0] + w * h;