mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-11 09:18:40 +12:00
Fix cellVdecGetPicItem
Fix potential overflow, race condition and correctness fixes for picInfo_addr
This commit is contained in:
parent
1a78e0e80c
commit
acc7320cae
1 changed files with 24 additions and 12 deletions
|
@ -833,11 +833,18 @@ error_code cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
|
||||||
|
|
||||||
// TODO: return CELL_VDEC_ERROR_SEQ
|
// TODO: return CELL_VDEC_ERROR_SEQ
|
||||||
|
|
||||||
|
struct all_info_t
|
||||||
|
{
|
||||||
|
CellVdecPicItem picItem;
|
||||||
|
std::aligned_union_t<0, CellVdecAvcInfo, CellVdecDivxInfo, CellVdecMpeg2Info> picInfo;
|
||||||
|
};
|
||||||
|
|
||||||
AVFrame* frame{};
|
AVFrame* frame{};
|
||||||
u64 pts;
|
u64 pts;
|
||||||
u64 dts;
|
u64 dts;
|
||||||
u64 usrd;
|
u64 usrd;
|
||||||
u32 frc;
|
u32 frc;
|
||||||
|
vm::ptr<CellVdecPicItem> info;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(vdec->mutex);
|
std::lock_guard lock(vdec->mutex);
|
||||||
|
|
||||||
|
@ -851,6 +858,17 @@ error_code cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
|
||||||
dts = picture.dts;
|
dts = picture.dts;
|
||||||
usrd = picture.userdata;
|
usrd = picture.userdata;
|
||||||
frc = picture.frc;
|
frc = picture.frc;
|
||||||
|
info.set(vdec->mem_addr + vdec->mem_bias);
|
||||||
|
|
||||||
|
constexpr u64 size_needed = sizeof(all_info_t);
|
||||||
|
|
||||||
|
if (vdec->mem_bias + size_needed >= vdec->mem_size / size_needed * size_needed)
|
||||||
|
{
|
||||||
|
vdec->mem_bias = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vdec->mem_bias += size_needed;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -862,14 +880,6 @@ error_code cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
|
||||||
return CELL_VDEC_ERROR_EMPTY;
|
return CELL_VDEC_ERROR_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vm::ptr<CellVdecPicItem> info = vm::cast(vdec->mem_addr + vdec->mem_bias);
|
|
||||||
|
|
||||||
vdec->mem_bias += 512;
|
|
||||||
if (vdec->mem_bias + 512 > vdec->mem_size)
|
|
||||||
{
|
|
||||||
vdec->mem_bias = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
info->codecType = vdec->type;
|
info->codecType = vdec->type;
|
||||||
info->startAddr = 0x00000123; // invalid value (no address for picture)
|
info->startAddr = 0x00000123; // invalid value (no address for picture)
|
||||||
const int buffer_size = av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1);
|
const int buffer_size = av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1);
|
||||||
|
@ -888,11 +898,13 @@ error_code cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
|
||||||
info->auUserData[1] = 0;
|
info->auUserData[1] = 0;
|
||||||
info->status = CELL_OK;
|
info->status = CELL_OK;
|
||||||
info->attr = CELL_VDEC_PICITEM_ATTR_NORMAL;
|
info->attr = CELL_VDEC_PICITEM_ATTR_NORMAL;
|
||||||
info->picInfo_addr = info.addr() + u32{sizeof(CellVdecPicItem)};
|
|
||||||
|
const vm::addr_t picinfo_addr{info.addr() + ::offset32(&all_info_t::picInfo)};
|
||||||
|
info->picInfo_addr = picinfo_addr;
|
||||||
|
|
||||||
if (vdec->type == CELL_VDEC_CODEC_TYPE_AVC)
|
if (vdec->type == CELL_VDEC_CODEC_TYPE_AVC)
|
||||||
{
|
{
|
||||||
const vm::ptr<CellVdecAvcInfo> avc = vm::cast(info.addr() + u32{sizeof(CellVdecPicItem)});
|
const vm::ptr<CellVdecAvcInfo> avc = picinfo_addr;
|
||||||
|
|
||||||
avc->horizontalSize = frame->width;
|
avc->horizontalSize = frame->width;
|
||||||
avc->verticalSize = frame->height;
|
avc->verticalSize = frame->height;
|
||||||
|
@ -948,7 +960,7 @@ error_code cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
|
||||||
}
|
}
|
||||||
else if (vdec->type == CELL_VDEC_CODEC_TYPE_DIVX)
|
else if (vdec->type == CELL_VDEC_CODEC_TYPE_DIVX)
|
||||||
{
|
{
|
||||||
const vm::ptr<CellVdecDivxInfo> dvx = vm::cast(info.addr() + u32{sizeof(CellVdecPicItem)});
|
const vm::ptr<CellVdecDivxInfo> dvx = picinfo_addr;
|
||||||
|
|
||||||
switch (s32 pct = frame->pict_type)
|
switch (s32 pct = frame->pict_type)
|
||||||
{
|
{
|
||||||
|
@ -984,7 +996,7 @@ error_code cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
|
||||||
}
|
}
|
||||||
else if (vdec->type == CELL_VDEC_CODEC_TYPE_MPEG2)
|
else if (vdec->type == CELL_VDEC_CODEC_TYPE_MPEG2)
|
||||||
{
|
{
|
||||||
const vm::ptr<CellVdecMpeg2Info> mp2 = vm::cast(info.addr() + u32{sizeof(CellVdecPicItem)});
|
const vm::ptr<CellVdecMpeg2Info> mp2 = picinfo_addr;
|
||||||
|
|
||||||
std::memset(mp2.get_ptr(), 0, sizeof(CellVdecMpeg2Info));
|
std::memset(mp2.get_ptr(), 0, sizeof(CellVdecMpeg2Info));
|
||||||
mp2->horizontal_size = frame->width;
|
mp2->horizontal_size = frame->width;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue