From 9a27cc94422dcc4a97ef7d6dfa439e2207991bbb Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 2 Jan 2020 16:46:52 +0100 Subject: [PATCH] cellVdec: improve error checks --- rpcs3/Emu/Cell/Modules/cellVdec.cpp | 66 +++++++++++++++++++++++++---- rpcs3/Emu/Cell/Modules/cellVdec.h | 8 ++-- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 7396ea965a..d38bfaec5b 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -432,6 +432,11 @@ static void vdecEntry(ppu_thread& ppu, u32 vid) static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0 */, vm::ptr attr) { + if (!attr) + { + return CELL_VDEC_ERROR_ARG; + } + switch (type) // TODO: check profile levels { case CELL_VDEC_CODEC_TYPE_AVC: cellVdec.warning("cellVdecQueryAttr: AVC (profile=%d)", profile); break; @@ -452,6 +457,11 @@ error_code cellVdecQueryAttr(vm::cptr type, vm::ptr { cellVdec.warning("cellVdecQueryAttr(type=*0x%x, attr=*0x%x)", type, attr); + if (!type || !attr) + { + return CELL_VDEC_ERROR_ARG; + } + return vdecQueryAttr(type->codecType, type->profileLevel, 0, attr); } @@ -459,6 +469,11 @@ error_code cellVdecQueryAttrEx(vm::cptr type, vm::ptrcodecType, type->profileLevel, type->codecSpecificInfo_addr, attr); } @@ -524,6 +539,8 @@ error_code cellVdecClose(ppu_thread& ppu, u32 handle) return CELL_VDEC_ERROR_ARG; } + // TODO: return CELL_VDEC_ERROR_SEQ + lv2_obj::sleep(ppu); vdec->out_max = 0; vdec->in_cmd.push(vdec_close); @@ -549,6 +566,8 @@ error_code cellVdecStartSeq(u32 handle) return CELL_VDEC_ERROR_ARG; } + // TODO: return CELL_VDEC_ERROR_SEQ + vdec->in_cmd.push(vdec_start_seq); return CELL_OK; } @@ -564,6 +583,8 @@ error_code cellVdecEndSeq(u32 handle) return CELL_VDEC_ERROR_ARG; } + // TODO: return CELL_VDEC_ERROR_SEQ + vdec->in_cmd.push(vdec_cmd{-1}); return CELL_OK; } @@ -574,7 +595,7 @@ error_code cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr(handle); - if (mode < 0 || mode > CELL_VDEC_DEC_MODE_PB_SKIP || !vdec) + if (!auInfo || !vdec || mode < 0 || mode > CELL_VDEC_DEC_MODE_PB_SKIP) { return CELL_VDEC_ERROR_ARG; } @@ -601,11 +622,24 @@ error_code cellVdecGetPicture(u32 handle, vm::cptr format, vm const auto vdec = idm::get(handle); - if (!format || !vdec || format->formatType > 4 || (format->formatType <= CELL_VDEC_PICFMT_RGBA32_ILV && format->colorMatrixType > CELL_VDEC_COLOR_MATRIX_TYPE_BT709)) + if (!vdec || !format) { return CELL_VDEC_ERROR_ARG; } + // TODO: return CELL_VDEC_ERROR_SEQ + + if (format->formatType > 4 || (format->formatType <= CELL_VDEC_PICFMT_RGBA32_ILV && format->colorMatrixType > CELL_VDEC_COLOR_MATRIX_TYPE_BT709)) + { + return CELL_VDEC_ERROR_ARG; + } + + // TODO: something like this is checked here, maybe only if outBuff[0] != 0 + //if (outBuff && outBuff[0] != 8 && outBuff[0] != 12) + //{ + // return CELL_VDEC_ERROR_ARG; + //} + vdec_frame frame; bool notify = false; { @@ -725,11 +759,13 @@ error_code cellVdecGetPicItem(u32 handle, vm::pptr picItem) const auto vdec = idm::get(handle); - if (!vdec) + if (!vdec || !picItem) { return CELL_VDEC_ERROR_ARG; } + // TODO: return CELL_VDEC_ERROR_SEQ + AVFrame* frame{}; u64 pts; u64 dts; @@ -925,19 +961,21 @@ error_code cellVdecGetPicItem(u32 handle, vm::pptr picItem) return CELL_OK; } -error_code cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc) +error_code cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frameRateCode) { - cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, +frc); + cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frameRateCode=0x%x)", handle, +frameRateCode); const auto vdec = idm::get(handle); // 0x80 seems like a common prefix - if (!vdec || (frc & 0xf0) != 0x80) + if (!vdec || (frameRateCode & 0xf0) != 0x80) { return CELL_VDEC_ERROR_ARG; } - vdec->in_cmd.push(CellVdecFrameRate{frc & 0x87}); + // TODO: return CELL_VDEC_ERROR_SEQ + + vdec->in_cmd.push(CellVdecFrameRate{ frameRateCode & 0x87 }); return CELL_OK; } @@ -971,9 +1009,19 @@ error_code cellVdecSetFrameRateExt() return CELL_OK; } -error_code cellVdecSetPts() +error_code cellVdecSetPts(u32 handle, vm::ptr unk) { - UNIMPLEMENTED_FUNC(cellVdec); + cellVdec.error("cellVdecSetPts(handle=0x%x, unk=*0x%x)", handle, unk); + + const auto vdec = idm::get(handle); + + if (!vdec || !unk) + { + return CELL_VDEC_ERROR_ARG; + } + + // TODO: return CELL_VDEC_ERROR_SEQ + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.h b/rpcs3/Emu/Cell/Modules/cellVdec.h index b99b4ccb98..3f9e00a718 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.h +++ b/rpcs3/Emu/Cell/Modules/cellVdec.h @@ -24,10 +24,10 @@ enum CellVdecCodecType : s32 // Callback Messages enum CellVdecMsgType : s32 { - CELL_VDEC_MSG_TYPE_AUDONE, // decoding finished - CELL_VDEC_MSG_TYPE_PICOUT, // picture done - CELL_VDEC_MSG_TYPE_SEQDONE, // finishing done - CELL_VDEC_MSG_TYPE_ERROR, + CELL_VDEC_MSG_TYPE_AUDONE = 0, // decoding finished + CELL_VDEC_MSG_TYPE_PICOUT = 1, // picture done + CELL_VDEC_MSG_TYPE_SEQDONE = 2, // finishing done + CELL_VDEC_MSG_TYPE_ERROR = 3, // fatal error }; // Decoder Operation Mode