diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 59eb427698..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,6 +274,9 @@ struct vdec_context final fmt::throw_exception("avcodec_alloc_context3() failed (type=0x%x)", type); } + // Carry the AU userdata from each packet to the picture decoded from it, across the frame reordering + ctx->flags |= AV_CODEC_FLAG_COPY_OPAQUE; + AVDictionary* opts = nullptr; std::lock_guard lock(g_mutex_avcodec_open2); @@ -414,12 +416,13 @@ 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; 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) { @@ -448,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 @@ -508,7 +509,7 @@ struct vdec_context final frame.pts = next_pts; frame.dts = next_dts; - frame.userdata = au_usrd; + frame.userdata = reinterpret_cast(frame->opaque); frame.attr = attr; u64 amend = 0;