From bd5bff321e3bc00246e8d74c692413d586d35273 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 12 Apr 2022 20:48:55 +0200 Subject: [PATCH] cellVdecDecodeAuEx2: some REd guesswork --- rpcs3/Emu/Cell/Modules/cellVdec.cpp | 50 +++++++++++++++++++++++++++-- rpcs3/Emu/Cell/Modules/cellVdec.h | 13 ++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index a784626d95..e72f6b8ab9 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -1029,7 +1029,7 @@ error_code cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptrtype != 3) || + if ((mode == (CELL_VDEC_DEC_MODE_B_SKIP | CELL_VDEC_DEC_MODE_PB_SKIP) && vdec->type != 3) || (mode == CELL_VDEC_DEC_MODE_PB_SKIP && vdec->type != CELL_VDEC_CODEC_TYPE_AVC)) { return { CELL_VDEC_ERROR_ARG, fmt::format("mode=%d, type=%d", +mode, vdec->type) }; @@ -1045,9 +1045,53 @@ error_code cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr auInfo) { - UNIMPLEMENTED_FUNC(cellVdec); + cellVdec.todo("cellVdecDecodeAuEx2(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, +mode, auInfo); + + const auto vdec = idm::get(handle); + + if (!vdec || !auInfo || !auInfo->pts.upper || !auInfo->startAddr) + { + return { CELL_VDEC_ERROR_ARG, fmt::format("vdec=%d, auInfo=%d, upper=%d, startAddr=0x%x", !!vdec, !!auInfo, auInfo ? auInfo->pts.upper.value() : 0, auInfo ? auInfo->startAddr.value() : 0) }; + } + + { + std::lock_guard lock{vdec->mutex}; + + if (vdec->seq_state != sequence_state::ready) + { + return { CELL_VDEC_ERROR_SEQ, vdec->seq_state.load() }; + } + } + + if (mode < 0 || mode > (CELL_VDEC_DEC_MODE_B_SKIP | CELL_VDEC_DEC_MODE_PB_SKIP)) + { + return { CELL_VDEC_ERROR_ARG, fmt::format("mode=%d", +mode) }; + } + + // TODO: what does the 3 stand for ? + if ((mode == (CELL_VDEC_DEC_MODE_B_SKIP | CELL_VDEC_DEC_MODE_PB_SKIP) && vdec->type != 3) || + (mode == CELL_VDEC_DEC_MODE_PB_SKIP && vdec->type != CELL_VDEC_CODEC_TYPE_AVC)) + { + return { CELL_VDEC_ERROR_ARG, fmt::format("mode=%d, type=%d", +mode, vdec->type) }; + } + + if (!vdec->au_count.try_inc(4)) + { + return CELL_VDEC_ERROR_BUSY; + } + + CellVdecAuInfo au_info{}; + au_info.startAddr = auInfo->startAddr; + au_info.size = auInfo->size; + au_info.pts = auInfo->pts; + au_info.dts = auInfo->dts; + au_info.userData = auInfo->userData; + au_info.codecSpecificData = auInfo->codecSpecificData; + + // TODO: check info + vdec->in_cmd.push(vdec_cmd(vdec_cmd_type::au_decode, mode, au_info)); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.h b/rpcs3/Emu/Cell/Modules/cellVdec.h index 07b588106f..e09695bcc3 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.h +++ b/rpcs3/Emu/Cell/Modules/cellVdec.h @@ -144,6 +144,19 @@ struct CellVdecAuInfo be_t codecSpecificData; }; +// Access Unit Information +struct CellVdecAuInfoEx2 // Speculative name +{ + be_t startAddr; + be_t unk1; // Speculative + be_t size; + be_t unk2; // Speculative + CellCodecTimeStamp pts; + CellCodecTimeStamp dts; + be_t userData; + be_t codecSpecificData; +}; + // Output Picture Information struct CellVdecPicItem {