mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-25 20:06:17 +00:00
Struct update fixes (#3087)
Neither sceVideodec2Decode or sceVideodec2Flush should be modifying the output's `thisSize`, doing so breaks older games now that we have the updated structs. We should also only set frameFormat and framePitchInBytes if the game inputted the newer struct, since otherwise we're modifying memory the game never gave us. These changes might fix the regression in Hatsune Miku Project Diva X, though it's hard to tell due to some weird caching issue with Windows, and the ancient regression this game had on Linux.
This commit is contained in:
parent
34a1ffbcda
commit
69a50fa713
1 changed files with 20 additions and 6 deletions
|
@ -44,11 +44,14 @@ s32 VdecDecoder::Decode(const OrbisVideodec2InputData& inputData,
|
||||||
OrbisVideodec2FrameBuffer& frameBuffer,
|
OrbisVideodec2FrameBuffer& frameBuffer,
|
||||||
OrbisVideodec2OutputInfo& outputInfo) {
|
OrbisVideodec2OutputInfo& outputInfo) {
|
||||||
frameBuffer.isAccepted = false;
|
frameBuffer.isAccepted = false;
|
||||||
outputInfo.thisSize = sizeof(OrbisVideodec2OutputInfo);
|
|
||||||
outputInfo.isValid = false;
|
outputInfo.isValid = false;
|
||||||
outputInfo.isErrorFrame = true;
|
outputInfo.isErrorFrame = true;
|
||||||
outputInfo.pictureCount = 0;
|
outputInfo.pictureCount = 0;
|
||||||
outputInfo.frameFormat = 0;
|
|
||||||
|
// Only set frameFormat if the game uses the newer struct version.
|
||||||
|
if (outputInfo.thisSize == sizeof(OrbisVideodec2OutputInfo)) {
|
||||||
|
outputInfo.frameFormat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!inputData.auData) {
|
if (!inputData.auData) {
|
||||||
return ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT_POINTER;
|
return ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT_POINTER;
|
||||||
|
@ -107,7 +110,6 @@ s32 VdecDecoder::Decode(const OrbisVideodec2InputData& inputData,
|
||||||
outputInfo.frameWidth = frame->width;
|
outputInfo.frameWidth = frame->width;
|
||||||
outputInfo.frameHeight = frame->height;
|
outputInfo.frameHeight = frame->height;
|
||||||
outputInfo.framePitch = frame->linesize[0];
|
outputInfo.framePitch = frame->linesize[0];
|
||||||
outputInfo.framePitchInBytes = frame->linesize[0];
|
|
||||||
outputInfo.frameBufferSize = frameBuffer.frameBufferSize;
|
outputInfo.frameBufferSize = frameBuffer.frameBufferSize;
|
||||||
outputInfo.frameBuffer = frameBuffer.frameBuffer;
|
outputInfo.frameBuffer = frameBuffer.frameBuffer;
|
||||||
|
|
||||||
|
@ -115,6 +117,11 @@ s32 VdecDecoder::Decode(const OrbisVideodec2InputData& inputData,
|
||||||
outputInfo.isErrorFrame = false;
|
outputInfo.isErrorFrame = false;
|
||||||
outputInfo.pictureCount = 1; // TODO: 2 pictures for interlaced video
|
outputInfo.pictureCount = 1; // TODO: 2 pictures for interlaced video
|
||||||
|
|
||||||
|
// Only set framePitchInBytes if the game uses the newer struct version.
|
||||||
|
if (outputInfo.thisSize == sizeof(OrbisVideodec2OutputInfo)) {
|
||||||
|
outputInfo.framePitchInBytes = frame->linesize[0];
|
||||||
|
}
|
||||||
|
|
||||||
if (outputInfo.isValid) {
|
if (outputInfo.isValid) {
|
||||||
OrbisVideodec2AvcPictureInfo pictureInfo = {};
|
OrbisVideodec2AvcPictureInfo pictureInfo = {};
|
||||||
|
|
||||||
|
@ -142,11 +149,14 @@ s32 VdecDecoder::Decode(const OrbisVideodec2InputData& inputData,
|
||||||
s32 VdecDecoder::Flush(OrbisVideodec2FrameBuffer& frameBuffer,
|
s32 VdecDecoder::Flush(OrbisVideodec2FrameBuffer& frameBuffer,
|
||||||
OrbisVideodec2OutputInfo& outputInfo) {
|
OrbisVideodec2OutputInfo& outputInfo) {
|
||||||
frameBuffer.isAccepted = false;
|
frameBuffer.isAccepted = false;
|
||||||
outputInfo.thisSize = sizeof(OrbisVideodec2OutputInfo);
|
|
||||||
outputInfo.isValid = false;
|
outputInfo.isValid = false;
|
||||||
outputInfo.isErrorFrame = true;
|
outputInfo.isErrorFrame = true;
|
||||||
outputInfo.pictureCount = 0;
|
outputInfo.pictureCount = 0;
|
||||||
outputInfo.frameFormat = 0;
|
|
||||||
|
// Only set frameFormat if the game uses the newer struct version.
|
||||||
|
if (outputInfo.thisSize == sizeof(OrbisVideodec2OutputInfo)) {
|
||||||
|
outputInfo.frameFormat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
AVFrame* frame = av_frame_alloc();
|
AVFrame* frame = av_frame_alloc();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
|
@ -178,7 +188,6 @@ s32 VdecDecoder::Flush(OrbisVideodec2FrameBuffer& frameBuffer,
|
||||||
outputInfo.frameWidth = frame->width;
|
outputInfo.frameWidth = frame->width;
|
||||||
outputInfo.frameHeight = frame->height;
|
outputInfo.frameHeight = frame->height;
|
||||||
outputInfo.framePitch = frame->linesize[0];
|
outputInfo.framePitch = frame->linesize[0];
|
||||||
outputInfo.framePitchInBytes = frame->linesize[0];
|
|
||||||
outputInfo.frameBufferSize = frameBuffer.frameBufferSize;
|
outputInfo.frameBufferSize = frameBuffer.frameBufferSize;
|
||||||
outputInfo.frameBuffer = frameBuffer.frameBuffer;
|
outputInfo.frameBuffer = frameBuffer.frameBuffer;
|
||||||
|
|
||||||
|
@ -186,6 +195,11 @@ s32 VdecDecoder::Flush(OrbisVideodec2FrameBuffer& frameBuffer,
|
||||||
outputInfo.isErrorFrame = false;
|
outputInfo.isErrorFrame = false;
|
||||||
outputInfo.pictureCount = 1; // TODO: 2 pictures for interlaced video
|
outputInfo.pictureCount = 1; // TODO: 2 pictures for interlaced video
|
||||||
|
|
||||||
|
// Only set framePitchInBytes if the game uses the newer struct version.
|
||||||
|
if (outputInfo.thisSize == sizeof(OrbisVideodec2OutputInfo)) {
|
||||||
|
outputInfo.framePitchInBytes = frame->linesize[0];
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Should we add picture info here too?
|
// FIXME: Should we add picture info here too?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue