cellVdec: Improve cellVdecQuery and cellVdecOpen

This commit is contained in:
Eladash 2020-02-01 14:14:06 +02:00 committed by Ivan
parent 32df809626
commit e57c01907e

View File

@ -4,6 +4,7 @@
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/lv2/sys_sync.h"
#include "Emu/Cell/lv2/sys_ppu_thread.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "sysPrxForUser.h"
#ifdef _MSC_VER
@ -430,25 +431,81 @@ static void vdecEntry(ppu_thread& ppu, u32 vid)
ppu.state += cpu_flag::exit;
}
static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0 */, vm::ptr<CellVdecAttr> attr)
static error_code vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0 */, CellVdecAttr* attr)
{
if (!attr)
{
return CELL_VDEC_ERROR_ARG;
}
// Write 0 at start
attr->memSize = 0;
switch (type) // TODO: check profile levels
u32 decoderVerLower;
u32 memSize = 0;
const bool new_sdk = g_ps3_process_info.sdk_ver > 0x20FFFF;
switch (type)
{
case CELL_VDEC_CODEC_TYPE_AVC: cellVdec.warning("cellVdecQueryAttr: AVC (profile=%d)", profile); break;
case CELL_VDEC_CODEC_TYPE_MPEG2: cellVdec.warning("cellVdecQueryAttr: MPEG2 (profile=%d)", profile); break;
case CELL_VDEC_CODEC_TYPE_DIVX: cellVdec.warning("cellVdecQueryAttr: DivX (profile=%d)", profile); break;
case CELL_VDEC_CODEC_TYPE_AVC:
{
cellVdec.warning("cellVdecQueryAttr: AVC (profile=%d)", profile);
switch (profile)
{
case CELL_VDEC_AVC_LEVEL_1P0: memSize = new_sdk ? 0x70167D : 0xA014FD ; break;
case CELL_VDEC_AVC_LEVEL_1P1: memSize = new_sdk ? 0x86CB7D : 0xB6C9FD ; break;
case CELL_VDEC_AVC_LEVEL_1P2: memSize = new_sdk ? 0x9E307D : 0xCE2D7D ; break;
case CELL_VDEC_AVC_LEVEL_1P3: memSize = new_sdk ? 0xA057FD : 0xD054FD ; break;
case CELL_VDEC_AVC_LEVEL_2P0: memSize = new_sdk ? 0xA057FD : 0xD054FD ; break;
case CELL_VDEC_AVC_LEVEL_2P1: memSize = new_sdk ? 0xE90DFD : 0x1190AFD; break;
case CELL_VDEC_AVC_LEVEL_2P2: memSize = new_sdk ? 0x14E49FD : 0x17E46FD; break;
case CELL_VDEC_AVC_LEVEL_3P0: memSize = new_sdk ? 0x155B5FD : 0x185B17D; break;
case CELL_VDEC_AVC_LEVEL_3P1: memSize = new_sdk ? 0x1CD327D : 0x1FD2AFD; break;
case CELL_VDEC_AVC_LEVEL_3P2: memSize = new_sdk ? 0x2397B7D : 0x2696F7D; break;
case CELL_VDEC_AVC_LEVEL_4P0: memSize = new_sdk ? 0x33A5FFD : 0x36A527D; break;
case CELL_VDEC_AVC_LEVEL_4P1: memSize = new_sdk ? 0x33A5FFD : 0x36A527D; break;
case CELL_VDEC_AVC_LEVEL_4P2: memSize = new_sdk ? 0x33A5FFD : 0x36A527D; break;
default: return CELL_VDEC_ERROR_ARG;
}
decoderVerLower = 0x11300;
break;
}
case CELL_VDEC_CODEC_TYPE_MPEG2:
{
cellVdec.warning("cellVdecQueryAttr: MPEG2 (profile=%d)", profile);
switch (profile)
{
case CELL_VDEC_MPEG2_MP_LL : memSize = new_sdk ? 0x11290B : 0x2A610B; break;
case CELL_VDEC_MPEG2_MP_ML : memSize = new_sdk ? 0x2DFB8B : 0x47110B; break;
case CELL_VDEC_MPEG2_MP_H14: memSize = new_sdk ? 0xA0270B : 0xB8F90B; break;
case CELL_VDEC_MPEG2_MP_HL : memSize = new_sdk ? 0xD2F40B : 0xEB990B; break;
default: return CELL_VDEC_ERROR_ARG;
}
decoderVerLower = 0x1030000;
break;
}
case CELL_VDEC_CODEC_TYPE_DIVX:
{
cellVdec.warning("cellVdecQueryAttr: DivX (profile=%d)", profile);
switch (profile)
{
case CELL_VDEC_DIVX_QMOBILE : memSize = new_sdk ? 0x11B720 : 0x1DEF30; break;
case CELL_VDEC_DIVX_MOBILE : memSize = new_sdk ? 0x19A740 : 0x26DED0; break;
case CELL_VDEC_DIVX_HOME_THEATER: memSize = new_sdk ? 0x386A60 : 0x498060; break;
case CELL_VDEC_DIVX_HD_720 : memSize = new_sdk ? 0x692070 : 0x805690; break;
case CELL_VDEC_DIVX_HD_1080 : memSize = new_sdk ? 0xD78100 : 0xFC9870; break;
default: return CELL_VDEC_ERROR_ARG;
}
decoderVerLower = 0x30806;
break;
}
default: return CELL_VDEC_ERROR_ARG;
}
// TODO: check values
attr->decoderVerLower = 0x280000; // from dmux
attr->decoderVerUpper = 0x260000;
attr->memSize = 4 * 1024 * 1024; // 4 MB
attr->decoderVerLower = decoderVerLower;
attr->decoderVerUpper = 0x4840010;
attr->memSize = verify(HERE, memSize);
attr->cmdDepth = 4;
return CELL_OK;
}
@ -462,7 +519,7 @@ error_code cellVdecQueryAttr(vm::cptr<CellVdecType> type, vm::ptr<CellVdecAttr>
return CELL_VDEC_ERROR_ARG;
}
return vdecQueryAttr(type->codecType, type->profileLevel, 0, attr);
return vdecQueryAttr(type->codecType, type->profileLevel, 0, attr.get_ptr());
}
error_code cellVdecQueryAttrEx(vm::cptr<CellVdecTypeEx> type, vm::ptr<CellVdecAttr> attr)
@ -474,7 +531,7 @@ error_code cellVdecQueryAttrEx(vm::cptr<CellVdecTypeEx> type, vm::ptr<CellVdecAt
return CELL_VDEC_ERROR_ARG;
}
return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr);
return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr.get_ptr());
}
template <typename T, typename U>
@ -485,8 +542,15 @@ static error_code vdecOpen(ppu_thread& ppu, T type, U res, vm::cptr<CellVdecCb>
return CELL_VDEC_ERROR_ARG;
}
if (u32(res->ppuThreadPriority) > 3071 || u32(res->spuThreadPriority) > 255 || res->ppuThreadStackSize < 4096
|| u32(type->codecType) > 0xd)
if (res->ppuThreadPriority + 0u > 3071 || res->spuThreadPriority + 0u > 255 || res->ppuThreadStackSize < 4096
|| type->codecType + 0u > 0xd)
{
return CELL_VDEC_ERROR_ARG;
}
if (CellVdecAttr attr{};
vdecQueryAttr(type->codecType, type->profileLevel, 0, &attr) != CELL_OK ||
attr.memSize > res->memSize)
{
return CELL_VDEC_ERROR_ARG;
}