Properly schedule psmfplayer video finish.

Fixes #2251, hurray.
This commit is contained in:
Unknown W. Brackets 2014-05-22 23:40:44 -07:00
parent b9ede6aade
commit 75e4575ffe

View file

@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Core/HLE/HLE.h"
#include "Core/HLE/HLEHelperThread.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Common/ChunkFile.h"
#include "Core/Reporting.h"
@ -207,6 +208,19 @@ public:
~PsmfPlayer() { if (mediaengine) delete mediaengine; pspFileSystem.CloseFile(filehandle);}
void DoState(PointerWrap &p);
void ScheduleFinish(u32 handle) {
if (!finishThread) {
finishThread = new HLEHelperThread("scePsmfPlayer", "scePsmfPlayer", "__PsmfPlayerFinish", playbackThreadPriority, 0x100);
finishThread->Start(handle, 0);
}
}
void AbortFinish() {
if (finishThread) {
delete finishThread;
finishThread = NULL;
}
}
u32 filehandle;
u32 fileoffset;
int readSize;
@ -236,7 +250,8 @@ public:
SceMpegAu psmfPlayerAvcAu;
PsmfPlayerStatus status;
MediaEngine* mediaengine;
MediaEngine *mediaengine;
HLEHelperThread *finishThread;
};
class PsmfStream {
@ -352,6 +367,7 @@ PsmfPlayer::PsmfPlayer(const PsmfPlayerCreateData *data) {
totalDurationTimestamp = 0;
status = PSMF_PLAYER_STATUS_INIT;
mediaengine = new MediaEngine;
finishThread = NULL;
filehandle = 0;
fileoffset = 0;
readSize = 0;
@ -406,7 +422,7 @@ void Psmf::DoState(PointerWrap &p) {
}
void PsmfPlayer::DoState(PointerWrap &p) {
auto s = p.Section("PsmfPlayer", 1, 5);
auto s = p.Section("PsmfPlayer", 1, 6);
if (!s)
return;
@ -463,6 +479,11 @@ void PsmfPlayer::DoState(PointerWrap &p) {
p.Do(psmfPlayerAtracAu);
}
p.Do(psmfPlayerAvcAu);
if (s >= 6) {
p.Do(finishThread);
} else {
finishThread = NULL;
}
}
void Psmf::setStreamNum(int num) {
@ -1018,6 +1039,7 @@ int scePsmfPlayerStop(u32 psmfPlayer)
ERROR_LOG(ME, "scePsmfPlayerStop(%08x): not initialized", psmfPlayer);
return ERROR_PSMFPLAYER_INVALID_STATUS;
}
psmfplayer->AbortFinish();
INFO_LOG(ME, "scePsmfPlayerStop(%08x)", psmfPlayer);
psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY;
@ -1038,6 +1060,7 @@ int scePsmfPlayerBreak(u32 psmfPlayer)
ERROR_LOG(ME, "scePsmfPlayerBreak(%08x): not initialized", psmfPlayer);
return ERROR_PSMFPLAYER_INVALID_STATUS;
}
psmfplayer->AbortFinish();
// Fix everybody stress buster
psmfplayer->status = PSMF_PLAYER_STATUS_INIT;
@ -1308,6 +1331,7 @@ int scePsmfPlayerStart(u32 psmfPlayer, u32 psmfPlayerData, int initPts)
WARN_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %d)", psmfPlayer, psmfPlayerData, initPts);
psmfplayer->AbortFinish();
psmfplayer->mediaengine->setVideoStream(playerData->videoStreamNum);
psmfplayer->videoCodec = playerData->videoCodec;
psmfplayer->videoStreamNum = playerData->videoStreamNum;
@ -1397,8 +1421,10 @@ int scePsmfPlayerUpdate(u32 psmfPlayer)
DEBUG_LOG(ME, "scePsmfPlayerUpdate(%08x)", psmfPlayer);
if ((s64)psmfplayer->psmfPlayerAvcAu.pts >= (s64)psmfplayer->totalDurationTimestamp - VIDEO_FRAME_DURATION_TS) {
if (videoLoopStatus == PSMF_PLAYER_CONFIG_NO_LOOP && psmfplayer->videoStep >= 1) {
INFO_LOG(ME, "video end reached");
psmfplayer->status = PSMF_PLAYER_STATUS_PLAYING_FINISHED;
if (psmfplayer->status != PSMF_PLAYER_STATUS_PLAYING_FINISHED) {
psmfplayer->ScheduleFinish(psmfPlayer);
INFO_LOG(ME, "scePsmfPlayerUpdate(%08x): video end scheduled", psmfPlayer);
}
}
}
psmfplayer->videoStep++;
@ -1934,6 +1960,22 @@ u32 scePsmfPlayerConfigPlayer(u32 psmfPlayer, int configMode, int configAttr)
return 0;
}
int __PsmfPlayerFinish(u32 psmfPlayer) {
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
if (!psmfplayer) {
ERROR_LOG_REPORT(ME, "__PsmfPlayerFinish(%08x): invalid psmf player", psmfPlayer);
return ERROR_PSMFPLAYER_INVALID_STATUS;
}
if (psmfplayer->status != PSMF_PLAYER_STATUS_PLAYING) {
ERROR_LOG_REPORT(ME, "__PsmfPlayerFinish(%08x): unexpected status %d", psmfPlayer, psmfplayer->status);
return ERROR_PSMFPLAYER_INVALID_STATUS;
}
INFO_LOG(ME, "__PsmfPlayerFinish(%08x): video end reached", psmfPlayer);
psmfplayer->status = PSMF_PLAYER_STATUS_PLAYING_FINISHED;
return 0;
}
const HLEFunction scePsmf[] = {
{0xc22c8327, WrapU_UU<scePsmfSetPsmf>, "scePsmfSetPsmf"},
{0xC7DB3A5B, WrapU_UUU<scePsmfGetCurrentStreamType>, "scePsmfGetCurrentStreamType"},
@ -1992,6 +2034,8 @@ const HLEFunction scePsmfPlayer[] =
{0x76C0F4AE, WrapI_UCI<scePsmfPlayerSetPsmfOffset>, "scePsmfPlayerSetPsmfOffset"},
{0xA72DB4F9, WrapI_UCI<scePsmfPlayerSetPsmfOffsetCB>, "scePsmfPlayerSetPsmfOffsetCB"},
{0x340c12cb, 0, "scePsmfPlayer_340C12CB"},
// Fake function for PPSSPP's use.
{0x05b193b7, WrapI_U<__PsmfPlayerFinish>, "__PsmfPlayerFinish"},
};
void Register_scePsmf() {