mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-15 22:21:25 +00:00
cellVdecGetPicture improved
This commit is contained in:
parent
4874a81dc5
commit
be48a330b4
@ -554,6 +554,11 @@ s32 cellAdecOpenEx(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res,
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _nid_df982d2c(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res, vm::ptr<CellAdecCb> cb, vm::ptr<u32> handle)
|
||||
{
|
||||
return cellAdecOpenEx(type, res, cb, handle);
|
||||
}
|
||||
|
||||
s32 cellAdecClose(u32 handle)
|
||||
{
|
||||
cellAdec.Warning("cellAdecClose(handle=0x%x)", handle);
|
||||
@ -874,6 +879,7 @@ Module cellAdec("cellAdec", []()
|
||||
REG_FUNC(cellAdec, cellAdecQueryAttr);
|
||||
REG_FUNC(cellAdec, cellAdecOpen);
|
||||
REG_FUNC(cellAdec, cellAdecOpenEx);
|
||||
REG_UNNAMED(cellAdec, df982d2c);
|
||||
REG_FUNC(cellAdec, cellAdecClose);
|
||||
REG_FUNC(cellAdec, cellAdecStartSeq);
|
||||
REG_FUNC(cellAdec, cellAdecEndSeq);
|
||||
|
@ -12,6 +12,7 @@ extern "C"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libswscale/swscale.h"
|
||||
}
|
||||
|
||||
#include "Emu/CPU/CPUThreadManager.h"
|
||||
@ -678,7 +679,7 @@ s32 cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::
|
||||
|
||||
const auto vdec = Emu.GetIdManager().GetIDData<VideoDecoder>(handle);
|
||||
|
||||
if (!vdec)
|
||||
if (!vdec || !format)
|
||||
{
|
||||
return CELL_VDEC_ERROR_ARG;
|
||||
}
|
||||
@ -704,9 +705,21 @@ s32 cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::
|
||||
|
||||
if (outBuff)
|
||||
{
|
||||
if (format->formatType != CELL_VDEC_PICFMT_YUV420_PLANAR)
|
||||
const auto f = vdec->ctx->pix_fmt;
|
||||
const auto w = vdec->ctx->width;
|
||||
const auto h = vdec->ctx->height;
|
||||
|
||||
auto out_f = AV_PIX_FMT_YUV420P;
|
||||
|
||||
std::unique_ptr<u8> alpha_plane;
|
||||
|
||||
switch (const auto type = format->formatType.value())
|
||||
{
|
||||
cellVdec.Fatal("cellVdecGetPicture: unknown formatType(%d)", format->formatType);
|
||||
case CELL_VDEC_PICFMT_ARGB32_ILV: out_f = AV_PIX_FMT_ARGB; alpha_plane.reset(new u8[w * h]); break;
|
||||
case CELL_VDEC_PICFMT_RGBA32_ILV: out_f = AV_PIX_FMT_RGBA; alpha_plane.reset(new u8[w * h]); break;
|
||||
case CELL_VDEC_PICFMT_UYVY422_ILV: out_f = AV_PIX_FMT_UYVY422; break;
|
||||
case CELL_VDEC_PICFMT_YUV420_PLANAR: out_f = AV_PIX_FMT_YUV420P; break;
|
||||
default: cellVdec.Fatal("cellVdecGetPicture: unknown formatType(%d)", type);
|
||||
}
|
||||
|
||||
if (format->colorMatrixType != CELL_VDEC_COLOR_MATRIX_TYPE_BT709)
|
||||
@ -714,20 +727,68 @@ s32 cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::
|
||||
cellVdec.Fatal("cellVdecGetPicture: unknown colorMatrixType(%d)", format->colorMatrixType);
|
||||
}
|
||||
|
||||
const u32 buf_size = align(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1), 128);
|
||||
|
||||
// TODO: zero padding bytes
|
||||
|
||||
int err = av_image_copy_to_buffer(outBuff.get_ptr(), buf_size, frame->data, frame->linesize, vdec->ctx->pix_fmt, frame->width, frame->height, 1);
|
||||
if (err < 0)
|
||||
if (alpha_plane)
|
||||
{
|
||||
cellVdec.Fatal("cellVdecGetPicture: av_image_copy_to_buffer failed (err=0x%x)", err);
|
||||
memset(alpha_plane.get(), format->alpha, w * h);
|
||||
}
|
||||
|
||||
auto in_f = AV_PIX_FMT_YUV420P;
|
||||
|
||||
switch (f)
|
||||
{
|
||||
case AV_PIX_FMT_YUV420P: in_f = alpha_plane ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P; break;
|
||||
default: cellVdec.Fatal("cellVdecGetPicture: unknown pix_fmt(%d)", f);
|
||||
}
|
||||
|
||||
std::unique_ptr<SwsContext, void(*)(SwsContext*)> sws(sws_getContext(w, h, in_f, w, h, out_f, SWS_POINT, NULL, NULL, NULL), sws_freeContext);
|
||||
|
||||
u8* in_data[4] = { frame->data[0], frame->data[1], frame->data[2], alpha_plane.get() };
|
||||
int in_line[4] = { frame->linesize[0], frame->linesize[1], frame->linesize[2], w * 1 };
|
||||
u8* out_data[4] = { outBuff.get_ptr() };
|
||||
int out_line[4] = { w * 4 };
|
||||
|
||||
if (!alpha_plane)
|
||||
{
|
||||
out_data[1] = out_data[0] + w * h;
|
||||
out_data[2] = out_data[0] + w * h * 5 / 4;
|
||||
out_line[0] = w;
|
||||
out_line[1] = w / 2;
|
||||
out_line[2] = w / 2;
|
||||
}
|
||||
|
||||
sws_scale(sws.get(), in_data, frame->linesize, 0, h, out_data, out_line);
|
||||
|
||||
//const u32 buf_size = align(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1), 128);
|
||||
|
||||
//// TODO: zero padding bytes
|
||||
|
||||
//int err = av_image_copy_to_buffer(outBuff.get_ptr(), buf_size, frame->data, frame->linesize, vdec->ctx->pix_fmt, frame->width, frame->height, 1);
|
||||
//if (err < 0)
|
||||
//{
|
||||
// cellVdec.Fatal("cellVdecGetPicture: av_image_copy_to_buffer failed (err=0x%x)", err);
|
||||
//}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _nid_a21aa896(PPUThread& CPU, u32 handle, vm::ptr<const CellVdecPicFormat2> format2, vm::ptr<u8> outBuff, u32 arg4)
|
||||
{
|
||||
cellVdec.Warning("_nid_a21aa896(handle=0x%x, format2=*0x%x, outBuff=*0x%x, arg4=*0x%x)", handle, format2, outBuff, arg4);
|
||||
|
||||
if (arg4 || format2->unk0 || format2->unk1)
|
||||
{
|
||||
cellVdec.Fatal("_nid_a21aa896(): unknown arguments (arg4=*0x%x, unk0=0x%x, unk1=0x%x)", arg4, format2->unk0, format2->unk1);
|
||||
}
|
||||
|
||||
vm::stackvar<CellVdecPicFormat> format(CPU);
|
||||
format->formatType = format2->formatType;
|
||||
format->colorMatrixType = format2->colorMatrixType;
|
||||
format->alpha = format2->alpha;
|
||||
|
||||
return cellVdecGetPicture(handle, format, outBuff);
|
||||
}
|
||||
|
||||
s32 cellVdecGetPicItem(u32 handle, vm::ptr<vm::bptr<CellVdecPicItem>> picItem)
|
||||
{
|
||||
cellVdec.Log("cellVdecGetPicItem(handle=0x%x, picItem=**0x%x)", handle, picItem);
|
||||
@ -903,6 +964,7 @@ Module cellVdec("cellVdec", []()
|
||||
REG_FUNC(cellVdec, cellVdecEndSeq);
|
||||
REG_FUNC(cellVdec, cellVdecDecodeAu);
|
||||
REG_FUNC(cellVdec, cellVdecGetPicture);
|
||||
REG_UNNAMED(cellVdec, a21aa896);
|
||||
REG_FUNC(cellVdec, cellVdecGetPicItem);
|
||||
REG_FUNC(cellVdec, cellVdecSetFrameRate);
|
||||
});
|
||||
|
@ -163,6 +163,15 @@ struct CellVdecPicFormat
|
||||
u8 alpha;
|
||||
};
|
||||
|
||||
struct CellVdecPicFormat2
|
||||
{
|
||||
be_t<CellVdecPicFormatType> formatType;
|
||||
be_t<CellVdecColorMatrixType> colorMatrixType;
|
||||
be_t<u32> unk0;
|
||||
u8 alpha;
|
||||
be_t<u32> unk1;
|
||||
};
|
||||
|
||||
typedef u32(CellVdecCbMsg)(u32 handle, CellVdecMsgType msgType, s32 msgData, u32 cbArg);
|
||||
|
||||
// Callback Function Information
|
||||
|
@ -1156,7 +1156,7 @@ s32 _sys_printf(vm::ptr<const char> fmt) // va_args...
|
||||
sysPrxForUser.Todo("_sys_printf(fmt=*0x%x, ...)", fmt);
|
||||
|
||||
// probably, assertion failed
|
||||
sysPrxForUser.Warning("_sys_printf: \n%s", fmt.get_ptr());
|
||||
sysPrxForUser.Fatal("_sys_printf: \n%s", fmt.get_ptr());
|
||||
Emu.Pause();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user