From 5c1ce9cbefd4c228e6194c6267873813f05377c5 Mon Sep 17 00:00:00 2001 From: digant73 Date: Mon, 28 Sep 2026 20:21:37 +0200 Subject: [PATCH 1/2] cellVdec: Report the userdata of the AU each picture was decoded from --- rpcs3/Emu/Cell/Modules/cellVdec.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 59eb427698..503a660e41 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -275,6 +275,11 @@ struct vdec_context final fmt::throw_exception("avcodec_alloc_context3() failed (type=0x%x)", type); } +#ifdef AV_CODEC_FLAG_COPY_OPAQUE + // Carry the AU userdata from each packet to the picture decoded from it, across the frame reordering + ctx->flags |= AV_CODEC_FLAG_COPY_OPAQUE; +#endif + AVDictionary* opts = nullptr; std::lock_guard lock(g_mutex_avcodec_open2); @@ -420,6 +425,7 @@ struct vdec_context final packet.size = au_size; packet.pts = au_pts != umax ? au_pts : s64{smin}; packet.dts = au_dts != umax ? au_dts : s64{smin}; + packet.opaque = reinterpret_cast(au_usrd); if (next_pts == 0 && au_pts != umax) { @@ -508,7 +514,11 @@ struct vdec_context final frame.pts = next_pts; frame.dts = next_dts; +#ifdef AV_CODEC_FLAG_COPY_OPAQUE + frame.userdata = reinterpret_cast(frame->opaque); +#else frame.userdata = au_usrd; +#endif frame.attr = attr; u64 amend = 0; From 1707d7fc883ef48ff21bdcbb0141a3211ae09cb2 Mon Sep 17 00:00:00 2001 From: digant73 Date: Mon, 28 Sep 2026 21:06:23 +0200 Subject: [PATCH 2/2] remove unnecessary #ifdef --- rpcs3/Emu/Cell/Modules/cellVdec.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 503a660e41..33e7e29004 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -212,7 +212,6 @@ struct vdec_context final u32 frc_set{}; // Frame Rate Override u64 next_pts{}; u64 next_dts{}; - u64 last_au_usrd{}; // Userdata of the last decoded AU, used for the drained pictures atomic_t ppu_tid{}; std::deque out_queue; @@ -275,10 +274,8 @@ struct vdec_context final fmt::throw_exception("avcodec_alloc_context3() failed (type=0x%x)", type); } -#ifdef AV_CODEC_FLAG_COPY_OPAQUE // Carry the AU userdata from each packet to the picture decoded from it, across the frame reordering ctx->flags |= AV_CODEC_FLAG_COPY_OPAQUE; -#endif AVDictionary* opts = nullptr; @@ -419,7 +416,7 @@ struct vdec_context final const u32 au_size = cmd->au.size; const u64 au_pts = u64{cmd->au.pts.upper} << 32 | cmd->au.pts.lower; const u64 au_dts = u64{cmd->au.dts.upper} << 32 | cmd->au.dts.lower; - au_usrd = drain ? last_au_usrd : cmd->au.userData.value(); + au_usrd = cmd->au.userData; packet.data = vm::_ptr(au_addr); packet.size = au_size; @@ -454,8 +451,6 @@ struct vdec_context final fmt::throw_exception("AU queuing error (handle=0x%x, seq_id=%d, cmd_id=%d, error=0x%x): %s", handle, cmd->seq_id, cmd->id, ret, utils::av_error_to_string(ret)); } - last_au_usrd = au_usrd; - while (!abort_decode && seq_id == cmd->seq_id) { // Keep receiving frames @@ -514,11 +509,7 @@ struct vdec_context final frame.pts = next_pts; frame.dts = next_dts; -#ifdef AV_CODEC_FLAG_COPY_OPAQUE frame.userdata = reinterpret_cast(frame->opaque); -#else - frame.userdata = au_usrd; -#endif frame.attr = attr; u64 amend = 0;