2012-11-01 16:19:01 +01:00
|
|
|
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
2012-11-04 23:01:49 +01:00
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
2012-11-01 16:19:01 +01:00
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official git repository and contact information can be found at
|
|
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
|
2013-05-19 17:54:14 -07:00
|
|
|
#include "Core/HLE/HLE.h"
|
2014-03-15 11:22:19 -07:00
|
|
|
#include "Core/HLE/FunctionWrappers.h"
|
2013-05-19 17:54:14 -07:00
|
|
|
#include "Common/ChunkFile.h"
|
|
|
|
#include "Core/Reporting.h"
|
2012-11-01 16:19:01 +01:00
|
|
|
|
2013-12-30 00:11:29 +01:00
|
|
|
#include "Core/System.h"
|
2013-12-29 23:28:31 +01:00
|
|
|
#include "Core/FileSystems/MetaFileSystem.h"
|
2013-05-19 17:54:14 -07:00
|
|
|
#include "Core/HLE/scePsmf.h"
|
|
|
|
#include "Core/HLE/sceMpeg.h"
|
2013-06-02 01:30:51 +08:00
|
|
|
#include "Core/HW/MediaEngine.h"
|
2013-06-08 04:50:36 -07:00
|
|
|
#include "GPU/GPUInterface.h"
|
|
|
|
#include "GPU/GPUState.h"
|
2012-11-13 18:05:26 +01:00
|
|
|
|
|
|
|
#include <map>
|
2013-09-17 00:48:14 -04:00
|
|
|
#include <algorithm>
|
2012-11-01 16:19:01 +01:00
|
|
|
|
|
|
|
// "Go Sudoku" is a good way to test this code...
|
2012-11-13 18:05:26 +01:00
|
|
|
const int PSMF_VIDEO_STREAM_ID = 0xE0;
|
|
|
|
const int PSMF_AUDIO_STREAM_ID = 0xBD;
|
|
|
|
const int PSMF_AVC_STREAM = 0;
|
|
|
|
const int PSMF_ATRAC_STREAM = 1;
|
|
|
|
const int PSMF_PCM_STREAM = 2;
|
|
|
|
const int PSMF_DATA_STREAM = 3;
|
|
|
|
const int PSMF_AUDIO_STREAM = 15;
|
2013-01-18 18:05:51 +08:00
|
|
|
const int PSMF_PLAYER_VERSION_FULL = 0;
|
|
|
|
const int PSMF_PLAYER_VERSION_BASIC = 1;
|
|
|
|
const int PSMF_PLAYER_VERSION_NET = 2;
|
|
|
|
const int PSMF_PLAYER_CONFIG_LOOP = 0;
|
|
|
|
const int PSMF_PLAYER_CONFIG_NO_LOOP = 1;
|
|
|
|
const int PSMF_PLAYER_CONFIG_MODE_LOOP = 0;
|
|
|
|
const int PSMF_PLAYER_CONFIG_MODE_PIXEL_TYPE = 1;
|
|
|
|
|
|
|
|
int psmfMaxAheadTimestamp = 40000;
|
|
|
|
int audioSamples = 2048;
|
|
|
|
int audioSamplesBytes = audioSamples * 4;
|
2014-02-14 18:45:12 +08:00
|
|
|
int videoPixelMode = GE_CMODE_32BIT_ABGR8888;
|
2013-09-22 21:19:59 -07:00
|
|
|
int videoLoopStatus = PSMF_PLAYER_CONFIG_NO_LOOP;
|
2012-11-01 16:19:01 +01:00
|
|
|
|
2014-02-16 23:21:32 +08:00
|
|
|
enum PsmfPlayerError {
|
2014-03-03 11:16:53 -05:00
|
|
|
ERROR_PSMF_NOT_INITIALIZED = 0x80615001,
|
|
|
|
ERROR_PSMF_BAD_VERSION = 0x80615002,
|
|
|
|
ERROR_PSMF_NOT_FOUND = 0x80615025,
|
|
|
|
ERROR_PSMF_INVALID_ID = 0x80615100,
|
|
|
|
ERROR_PSMF_INVALID_VALUE = 0x806151fe,
|
|
|
|
ERROR_PSMF_INVALID_TIMESTAMP = 0x80615500,
|
|
|
|
ERROR_PSMF_INVALID_PSMF = 0x80615501,
|
2014-04-20 00:01:16 -07:00
|
|
|
|
2014-04-20 08:17:56 -07:00
|
|
|
ERROR_PSMFPLAYER_INVALID_STATUS = 0x80616001,
|
2014-04-20 23:14:45 -07:00
|
|
|
ERROR_PSMFPLAYER_INVALID_STREAM = 0x80616003,
|
2014-04-20 00:01:16 -07:00
|
|
|
ERROR_PSMFPLAYER_BUFFER_SIZE = 0x80616005,
|
2014-04-20 19:19:12 -07:00
|
|
|
ERROR_PSMFPLAYER_INVALID_CONFIG = 0x80616006,
|
2014-04-20 00:01:16 -07:00
|
|
|
ERROR_PSMFPLAYER_INVALID_PARAM = 0x80616008,
|
2014-03-03 11:16:53 -05:00
|
|
|
ERROR_PSMFPLAYER_NO_MORE_DATA = 0x8061600c,
|
2014-02-16 23:21:32 +08:00
|
|
|
};
|
|
|
|
|
2013-01-06 22:15:47 -08:00
|
|
|
enum PsmfPlayerStatus {
|
2014-03-03 11:16:53 -05:00
|
|
|
PSMF_PLAYER_STATUS_NONE = 0x0,
|
|
|
|
PSMF_PLAYER_STATUS_INIT = 0x1,
|
|
|
|
PSMF_PLAYER_STATUS_STANDBY = 0x2,
|
|
|
|
PSMF_PLAYER_STATUS_PLAYING = 0x4,
|
|
|
|
PSMF_PLAYER_STATUS_ERROR = 0x100,
|
2013-01-06 22:15:47 -08:00
|
|
|
PSMF_PLAYER_STATUS_PLAYING_FINISHED = 0x200,
|
|
|
|
};
|
|
|
|
|
2014-02-14 10:43:53 +08:00
|
|
|
enum PsmfPlayerMode {
|
2014-03-03 11:16:53 -05:00
|
|
|
PSMF_PLAYER_MODE_PLAY = 0,
|
2014-02-14 10:43:53 +08:00
|
|
|
PSMF_PLAYER_MODE_SLOWMOTION = 1,
|
2014-03-03 11:16:53 -05:00
|
|
|
PSMF_PLAYER_MODE_STEPFRAME = 2,
|
|
|
|
PSMF_PLAYER_MODE_PAUSE = 3,
|
|
|
|
PSMF_PLAYER_MODE_FORWARD = 4,
|
|
|
|
PSMF_PLAYER_MODE_REWIND = 5,
|
2014-02-14 10:43:53 +08:00
|
|
|
};
|
|
|
|
|
2012-11-01 16:19:01 +01:00
|
|
|
struct PsmfData {
|
2013-07-27 15:53:30 -07:00
|
|
|
u32_le version;
|
|
|
|
u32_le headerSize;
|
|
|
|
u32_le headerOffset;
|
|
|
|
u32_le streamSize;
|
|
|
|
u32_le streamOffset;
|
|
|
|
u32_le streamNum;
|
|
|
|
u32_le unk1;
|
|
|
|
u32_le unk2;
|
2013-01-18 18:05:51 +08:00
|
|
|
};
|
|
|
|
|
2014-04-20 00:01:16 -07:00
|
|
|
struct PsmfPlayerCreateData {
|
|
|
|
PSPPointer<u8> buffer;
|
|
|
|
u32 bufferSize;
|
|
|
|
int threadPriority;
|
|
|
|
};
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
struct PsmfPlayerData {
|
2013-07-27 15:53:30 -07:00
|
|
|
s32_le videoCodec;
|
|
|
|
s32_le videoStreamNum;
|
|
|
|
s32_le audioCodec;
|
|
|
|
s32_le audioStreamNum;
|
|
|
|
s32_le playMode;
|
|
|
|
s32_le playSpeed;
|
|
|
|
// TODO: Was "long", which is 32, but should this be 64? Not even used?
|
|
|
|
s32_le psmfPlayerLastTimestamp;
|
2012-11-13 18:05:26 +01:00
|
|
|
};
|
|
|
|
|
2014-04-20 13:48:45 -07:00
|
|
|
struct PsmfInfo {
|
|
|
|
u32_le lengthTS;
|
|
|
|
s32_le numVideoStreams;
|
|
|
|
s32_le numAudioStreams;
|
|
|
|
s32_le numPCMStreams;
|
|
|
|
s32_le playerVersion;
|
|
|
|
};
|
|
|
|
|
2012-11-13 18:05:26 +01:00
|
|
|
struct PsmfEntry {
|
|
|
|
int EPPts;
|
|
|
|
int EPOffset;
|
2014-01-01 13:23:19 -08:00
|
|
|
int EPIndex;
|
|
|
|
int EPPicOffset;
|
2012-11-13 18:05:26 +01:00
|
|
|
};
|
|
|
|
|
2013-02-10 23:01:18 +10:00
|
|
|
int getMaxAheadTimestamp(int packets) {return std::max(40000, packets * 700);}
|
2013-01-18 18:05:51 +08:00
|
|
|
|
2012-11-13 18:05:26 +01:00
|
|
|
class PsmfStream;
|
|
|
|
|
|
|
|
// This does NOT match the raw structure. Due to endianness etc,
|
|
|
|
// we read it manually.
|
|
|
|
// TODO: Change to work directly with the data in RAM instead of this
|
|
|
|
// JPSCP-esque class.
|
2012-12-29 03:19:13 -08:00
|
|
|
typedef std::map<int, PsmfStream *> PsmfStreamMap;
|
2013-01-05 18:10:13 +01:00
|
|
|
|
2012-12-29 03:19:13 -08:00
|
|
|
class Psmf {
|
|
|
|
public:
|
2013-02-04 01:31:02 -08:00
|
|
|
// For savestates only.
|
|
|
|
Psmf() {}
|
2012-12-29 03:19:13 -08:00
|
|
|
Psmf(u32 data);
|
|
|
|
~Psmf();
|
|
|
|
void DoState(PointerWrap &p);
|
2013-06-05 21:24:14 +02:00
|
|
|
|
|
|
|
bool isValidCurrentStreamNumber() {
|
2013-07-07 18:10:55 -07:00
|
|
|
return currentStreamNum >= 0 && currentStreamNum < (int)streamMap.size(); // urgh, checking size isn't really right here.
|
2013-06-05 21:24:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void setStreamNum(int num);
|
|
|
|
bool setStreamWithType(int type, int channel);
|
2012-12-29 03:19:13 -08:00
|
|
|
|
2014-01-01 13:23:19 -08:00
|
|
|
int FindEPWithTimestamp(int pts);
|
|
|
|
|
2012-11-13 18:05:26 +01:00
|
|
|
u32 magic;
|
|
|
|
u32 version;
|
|
|
|
u32 streamOffset;
|
|
|
|
u32 streamSize;
|
2013-01-18 18:05:51 +08:00
|
|
|
u32 headerSize;
|
2012-11-13 18:05:26 +01:00
|
|
|
u32 headerOffset;
|
2013-01-18 18:05:51 +08:00
|
|
|
u32 streamType;
|
|
|
|
u32 streamChannel;
|
2012-11-13 18:05:26 +01:00
|
|
|
// 0x50
|
|
|
|
u32 streamDataTotalSize;
|
|
|
|
u32 presentationStartTime;
|
|
|
|
u32 presentationEndTime;
|
|
|
|
u32 streamDataNextBlockSize;
|
|
|
|
u32 streamDataNextInnerBlockSize;
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int numStreams;
|
2012-11-13 18:05:26 +01:00
|
|
|
int currentStreamNum;
|
|
|
|
int currentAudioStreamNum;
|
|
|
|
int currentVideoStreamNum;
|
|
|
|
|
|
|
|
// parameters gotten from streams
|
|
|
|
// I guess this is the seek information?
|
|
|
|
u32 EPMapOffset;
|
|
|
|
u32 EPMapEntriesNum;
|
|
|
|
int videoWidth;
|
|
|
|
int videoHeight;
|
|
|
|
int audioChannels;
|
|
|
|
int audioFrequency;
|
2014-01-01 13:23:19 -08:00
|
|
|
std::vector<PsmfEntry> EPMap;
|
2012-11-13 18:05:26 +01:00
|
|
|
|
2012-12-28 23:29:24 -08:00
|
|
|
PsmfStreamMap streamMap;
|
2012-11-01 16:19:01 +01:00
|
|
|
};
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
class PsmfPlayer {
|
|
|
|
public:
|
2013-02-04 01:31:02 -08:00
|
|
|
// For savestates only.
|
2013-06-16 03:27:14 +08:00
|
|
|
PsmfPlayer() { mediaengine = new MediaEngine; filehandle = 0;}
|
2014-04-20 00:01:16 -07:00
|
|
|
PsmfPlayer(const PsmfPlayerCreateData *data);
|
2013-06-16 03:27:14 +08:00
|
|
|
~PsmfPlayer() { if (mediaengine) delete mediaengine; pspFileSystem.CloseFile(filehandle);}
|
2013-01-19 21:05:05 +08:00
|
|
|
void DoState(PointerWrap &p);
|
2013-01-18 18:05:51 +08:00
|
|
|
|
2013-06-16 03:27:14 +08:00
|
|
|
u32 filehandle;
|
2013-06-18 16:05:15 +08:00
|
|
|
u32 fileoffset;
|
2013-06-27 23:46:26 +08:00
|
|
|
int readSize;
|
|
|
|
int streamSize;
|
2013-06-18 16:05:15 +08:00
|
|
|
u8 tempbuf[0x10000];
|
2013-06-16 03:27:14 +08:00
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int videoCodec;
|
2013-01-24 19:21:32 +08:00
|
|
|
int videoStreamNum;
|
|
|
|
int audioCodec;
|
|
|
|
int audioStreamNum;
|
|
|
|
int playMode;
|
|
|
|
int playSpeed;
|
2013-01-24 19:40:26 +08:00
|
|
|
long psmfPlayerLastTimestamp;
|
2013-01-18 18:05:51 +08:00
|
|
|
|
|
|
|
int displayBuffer;
|
|
|
|
int displayBufferSize;
|
|
|
|
int playbackThreadPriority;
|
|
|
|
int psmfMaxAheadTimestamp;
|
2014-04-20 11:53:59 -07:00
|
|
|
int totalVideoStreams;
|
|
|
|
int totalAudioStreams;
|
|
|
|
int playerVersion;
|
2013-01-18 18:05:51 +08:00
|
|
|
|
|
|
|
SceMpegAu psmfPlayerAtracAu;
|
|
|
|
SceMpegAu psmfPlayerAvcAu;
|
2013-03-06 01:00:26 -08:00
|
|
|
PsmfPlayerStatus status;
|
2013-06-02 01:30:51 +08:00
|
|
|
|
|
|
|
MediaEngine* mediaengine;
|
2013-01-18 18:05:51 +08:00
|
|
|
};
|
|
|
|
|
2012-11-13 18:05:26 +01:00
|
|
|
class PsmfStream {
|
|
|
|
public:
|
2013-02-04 01:31:02 -08:00
|
|
|
// Used for save states.
|
|
|
|
PsmfStream() {
|
|
|
|
}
|
|
|
|
|
2012-11-13 18:05:26 +01:00
|
|
|
PsmfStream(int type, int channel) {
|
|
|
|
this->type = type;
|
|
|
|
this->channel = channel;
|
|
|
|
}
|
|
|
|
|
2014-01-10 12:57:40 -08:00
|
|
|
void readMPEGVideoStreamParams(u32 addr, u32 data, Psmf *psmf) {
|
2012-11-13 18:05:26 +01:00
|
|
|
int streamId = Memory::Read_U8(addr);
|
|
|
|
int privateStreamId = Memory::Read_U8(addr + 1);
|
|
|
|
// two unknowns here
|
2013-10-28 17:23:51 +01:00
|
|
|
psmf->EPMapOffset = bswap32(Memory::Read_U32(addr + 4));
|
|
|
|
psmf->EPMapEntriesNum = bswap32(Memory::Read_U32(addr + 8));
|
2012-11-13 18:05:26 +01:00
|
|
|
psmf->videoWidth = Memory::Read_U8(addr + 12) * 16;
|
|
|
|
psmf->videoHeight = Memory::Read_U8(addr + 13) * 16;
|
|
|
|
|
2014-01-01 13:23:19 -08:00
|
|
|
const u32 EP_MAP_STRIDE = 1 + 1 + 4 + 4;
|
|
|
|
psmf->EPMap.clear();
|
|
|
|
for (u32 i = 0; i < psmf->EPMapEntriesNum; i++) {
|
2014-01-10 12:57:40 -08:00
|
|
|
const u32 entryAddr = data + psmf->EPMapOffset + EP_MAP_STRIDE * i;
|
2014-01-01 13:23:19 -08:00
|
|
|
PsmfEntry entry;
|
|
|
|
entry.EPIndex = Memory::Read_U8(entryAddr + 0);
|
|
|
|
entry.EPPicOffset = Memory::Read_U8(entryAddr + 1);
|
2014-01-10 12:57:40 -08:00
|
|
|
entry.EPPts = *(u32_be*) Memory::GetPointer(entryAddr + 2);
|
|
|
|
entry.EPOffset = *(u32_be*) Memory::GetPointer(entryAddr + 6);
|
2014-01-01 13:23:19 -08:00
|
|
|
psmf->EPMap.push_back(entry);
|
|
|
|
}
|
|
|
|
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "PSMF MPEG data found: id=%02x, privid=%02x, epmoff=%08x, epmnum=%08x, width=%i, height=%i", streamId, privateStreamId, psmf->EPMapOffset, psmf->EPMapEntriesNum, psmf->videoWidth, psmf->videoHeight);
|
2012-11-13 18:05:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void readPrivateAudioStreamParams(u32 addr, Psmf *psmf) {
|
|
|
|
int streamId = Memory::Read_U8(addr);
|
|
|
|
int privateStreamId = Memory::Read_U8(addr + 1);
|
|
|
|
psmf->audioChannels = Memory::Read_U8(addr + 14);
|
|
|
|
psmf->audioFrequency = Memory::Read_U8(addr + 15);
|
|
|
|
// two unknowns here
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "PSMF private audio found: id=%02x, privid=%02x, channels=%i, freq=%i", streamId, privateStreamId, psmf->audioChannels, psmf->audioFrequency);
|
2012-11-13 18:05:26 +01:00
|
|
|
}
|
|
|
|
|
2012-12-28 23:29:24 -08:00
|
|
|
void DoState(PointerWrap &p) {
|
2013-09-14 20:23:03 -07:00
|
|
|
auto s = p.Section("PsmfStream", 1);
|
|
|
|
if (!s)
|
|
|
|
return;
|
|
|
|
|
2012-12-29 03:19:13 -08:00
|
|
|
p.Do(type);
|
|
|
|
p.Do(channel);
|
2012-12-28 23:29:24 -08:00
|
|
|
}
|
|
|
|
|
2013-06-05 21:24:14 +02:00
|
|
|
|
2012-11-13 18:05:26 +01:00
|
|
|
int type;
|
|
|
|
int channel;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Psmf::Psmf(u32 data) {
|
|
|
|
headerOffset = data;
|
|
|
|
magic = Memory::Read_U32(data);
|
|
|
|
version = Memory::Read_U32(data + 4);
|
2013-10-28 17:23:51 +01:00
|
|
|
streamOffset = bswap32(Memory::Read_U32(data + 8));
|
|
|
|
streamSize = bswap32(Memory::Read_U32(data + 12));
|
|
|
|
streamDataTotalSize = bswap32(Memory::Read_U32(data + 0x50));
|
2013-06-18 23:58:52 -07:00
|
|
|
presentationStartTime = getMpegTimeStamp(Memory::GetPointer(data + PSMF_FIRST_TIMESTAMP_OFFSET));
|
|
|
|
presentationEndTime = getMpegTimeStamp(Memory::GetPointer(data + PSMF_LAST_TIMESTAMP_OFFSET));
|
2013-10-28 17:23:51 +01:00
|
|
|
streamDataNextBlockSize = bswap32(Memory::Read_U32(data + 0x6A));
|
|
|
|
streamDataNextInnerBlockSize = bswap32(Memory::Read_U32(data + 0x7C));
|
|
|
|
numStreams = bswap16(Memory::Read_U16(data + 0x80));
|
2014-01-01 13:24:05 -08:00
|
|
|
// TODO: Always?
|
|
|
|
headerSize = 0x800;
|
2012-11-13 18:05:26 +01:00
|
|
|
|
|
|
|
currentStreamNum = -1;
|
|
|
|
currentAudioStreamNum = -1;
|
|
|
|
currentVideoStreamNum = -1;
|
|
|
|
|
|
|
|
for (int i = 0; i < numStreams; i++) {
|
|
|
|
PsmfStream *stream = 0;
|
|
|
|
u32 currentStreamAddr = data + 0x82 + i * 16;
|
|
|
|
int streamId = Memory::Read_U8(currentStreamAddr);
|
|
|
|
if ((streamId & PSMF_VIDEO_STREAM_ID) == PSMF_VIDEO_STREAM_ID) {
|
2013-06-16 01:35:47 +08:00
|
|
|
stream = new PsmfStream(PSMF_AVC_STREAM, ++currentVideoStreamNum);
|
2014-01-10 12:57:40 -08:00
|
|
|
stream->readMPEGVideoStreamParams(currentStreamAddr, data, this);
|
2012-11-13 18:05:26 +01:00
|
|
|
} else if ((streamId & PSMF_AUDIO_STREAM_ID) == PSMF_AUDIO_STREAM_ID) {
|
2013-06-16 01:35:47 +08:00
|
|
|
stream = new PsmfStream(PSMF_ATRAC_STREAM, ++currentAudioStreamNum);
|
2012-11-13 18:05:26 +01:00
|
|
|
stream->readPrivateAudioStreamParams(currentStreamAddr, this);
|
|
|
|
}
|
|
|
|
if (stream) {
|
|
|
|
currentStreamNum++;
|
|
|
|
streamMap[currentStreamNum] = stream;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-28 23:29:24 -08:00
|
|
|
Psmf::~Psmf() {
|
|
|
|
for (auto it = streamMap.begin(), end = streamMap.end(); it != end; ++it) {
|
|
|
|
delete it->second;
|
|
|
|
}
|
|
|
|
streamMap.clear();
|
|
|
|
}
|
|
|
|
|
2014-04-20 00:01:16 -07:00
|
|
|
PsmfPlayer::PsmfPlayer(const PsmfPlayerCreateData *data) {
|
2014-04-20 20:21:37 -07:00
|
|
|
videoCodec = -1;
|
|
|
|
videoStreamNum = -1;
|
|
|
|
audioCodec = -1;
|
|
|
|
audioStreamNum = -1;
|
2014-04-20 00:01:16 -07:00
|
|
|
playMode = 0;
|
2014-04-25 20:30:05 -07:00
|
|
|
playSpeed = 1;
|
2014-04-20 00:01:16 -07:00
|
|
|
psmfPlayerLastTimestamp = 0;
|
2013-03-06 01:00:26 -08:00
|
|
|
status = PSMF_PLAYER_STATUS_INIT;
|
2013-06-02 01:30:51 +08:00
|
|
|
mediaengine = new MediaEngine;
|
2013-06-16 03:27:14 +08:00
|
|
|
filehandle = 0;
|
2013-06-18 16:05:15 +08:00
|
|
|
fileoffset = 0;
|
2013-06-27 23:46:26 +08:00
|
|
|
readSize = 0;
|
|
|
|
streamSize = 0;
|
2014-04-20 00:01:16 -07:00
|
|
|
|
|
|
|
displayBuffer = data->buffer.ptr;
|
|
|
|
displayBufferSize = data->bufferSize;
|
|
|
|
playbackThreadPriority = data->threadPriority;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
|
2012-12-28 23:29:24 -08:00
|
|
|
void Psmf::DoState(PointerWrap &p) {
|
2014-01-01 13:23:19 -08:00
|
|
|
auto s = p.Section("Psmf", 1, 2);
|
2013-09-14 20:23:03 -07:00
|
|
|
if (!s)
|
|
|
|
return;
|
|
|
|
|
2012-12-29 03:19:13 -08:00
|
|
|
p.Do(magic);
|
|
|
|
p.Do(version);
|
|
|
|
p.Do(streamOffset);
|
|
|
|
p.Do(streamSize);
|
|
|
|
p.Do(headerOffset);
|
|
|
|
p.Do(streamDataTotalSize);
|
|
|
|
p.Do(presentationStartTime);
|
|
|
|
p.Do(presentationEndTime);
|
|
|
|
p.Do(streamDataNextBlockSize);
|
|
|
|
p.Do(streamDataNextInnerBlockSize);
|
|
|
|
p.Do(numStreams);
|
|
|
|
|
|
|
|
p.Do(currentStreamNum);
|
|
|
|
p.Do(currentAudioStreamNum);
|
|
|
|
p.Do(currentVideoStreamNum);
|
|
|
|
|
|
|
|
p.Do(EPMapOffset);
|
|
|
|
p.Do(EPMapEntriesNum);
|
|
|
|
p.Do(videoWidth);
|
|
|
|
p.Do(videoHeight);
|
|
|
|
p.Do(audioChannels);
|
|
|
|
p.Do(audioFrequency);
|
2012-12-28 23:29:24 -08:00
|
|
|
|
2014-01-01 13:23:19 -08:00
|
|
|
if (s >= 2) {
|
|
|
|
p.Do(EPMap);
|
|
|
|
}
|
|
|
|
|
2013-02-04 01:31:02 -08:00
|
|
|
p.Do(streamMap);
|
2012-12-28 23:29:24 -08:00
|
|
|
}
|
|
|
|
|
2013-01-19 21:05:05 +08:00
|
|
|
void PsmfPlayer::DoState(PointerWrap &p) {
|
2014-04-20 11:53:59 -07:00
|
|
|
auto s = p.Section("PsmfPlayer", 1, 2);
|
2013-09-14 20:23:03 -07:00
|
|
|
if (!s)
|
|
|
|
return;
|
|
|
|
|
2013-01-19 21:05:05 +08:00
|
|
|
p.Do(videoCodec);
|
2013-01-24 19:40:26 +08:00
|
|
|
p.Do(videoStreamNum);
|
|
|
|
p.Do(audioCodec);
|
|
|
|
p.Do(audioStreamNum);
|
|
|
|
p.Do(playMode);
|
|
|
|
p.Do(playSpeed);
|
2013-01-19 21:05:05 +08:00
|
|
|
|
|
|
|
p.Do(displayBuffer);
|
|
|
|
p.Do(displayBufferSize);
|
|
|
|
p.Do(playbackThreadPriority);
|
|
|
|
p.Do(psmfMaxAheadTimestamp);
|
|
|
|
p.Do(psmfPlayerLastTimestamp);
|
2014-04-20 11:53:59 -07:00
|
|
|
if (s >= 2) {
|
|
|
|
p.Do(totalVideoStreams);
|
|
|
|
p.Do(totalAudioStreams);
|
|
|
|
p.Do(playerVersion);
|
|
|
|
}
|
2013-06-02 01:30:51 +08:00
|
|
|
p.DoClass(mediaengine);
|
2013-06-16 03:27:14 +08:00
|
|
|
p.Do(filehandle);
|
2013-06-18 16:05:15 +08:00
|
|
|
p.Do(fileoffset);
|
2013-06-27 23:46:26 +08:00
|
|
|
p.Do(readSize);
|
|
|
|
p.Do(streamSize);
|
2013-01-19 21:05:05 +08:00
|
|
|
|
2013-06-18 04:08:48 +08:00
|
|
|
p.Do(status);
|
|
|
|
p.Do(psmfPlayerAvcAu);
|
2013-01-19 21:05:05 +08:00
|
|
|
}
|
|
|
|
|
2013-06-05 21:24:14 +02:00
|
|
|
void Psmf::setStreamNum(int num) {
|
|
|
|
currentStreamNum = num;
|
|
|
|
if (!isValidCurrentStreamNumber())
|
|
|
|
return;
|
|
|
|
PsmfStreamMap::iterator iter = streamMap.find(currentStreamNum);
|
|
|
|
if (iter == streamMap.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
int type = iter->second->type;
|
|
|
|
int channel = iter->second->channel;
|
|
|
|
switch (type) {
|
|
|
|
case PSMF_AVC_STREAM:
|
|
|
|
if (currentVideoStreamNum != num) {
|
2014-01-14 19:31:09 +01:00
|
|
|
// TODO: Tell video mediaengine or something about channel.
|
2013-06-05 21:24:14 +02:00
|
|
|
currentVideoStreamNum = num;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PSMF_ATRAC_STREAM:
|
|
|
|
case PSMF_PCM_STREAM:
|
|
|
|
if (currentAudioStreamNum != num) {
|
2014-01-14 19:31:09 +01:00
|
|
|
// TODO: Tell audio mediaengine or something about channel.
|
2013-06-05 21:24:14 +02:00
|
|
|
currentAudioStreamNum = num;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Psmf::setStreamWithType(int type, int channel) {
|
|
|
|
for (PsmfStreamMap::iterator iter = streamMap.begin(); iter != streamMap.end(); ++iter) {
|
2013-07-01 14:02:12 +08:00
|
|
|
if (iter->second->type == type && iter->second->channel == channel) {
|
2013-06-05 21:24:14 +02:00
|
|
|
setStreamNum(iter->first);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-01 13:23:19 -08:00
|
|
|
int Psmf::FindEPWithTimestamp(int pts) {
|
|
|
|
int best = -1;
|
|
|
|
int bestPts = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)EPMap.size(); ++i) {
|
|
|
|
const int matchPts = EPMap[i].EPPts;
|
|
|
|
if (matchPts == pts) {
|
|
|
|
// Exact match, take it.
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
// TODO: Does it actually do fuzzy matching?
|
|
|
|
if (matchPts < pts && matchPts >= bestPts) {
|
|
|
|
best = i;
|
|
|
|
bestPts = matchPts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return best;
|
|
|
|
}
|
|
|
|
|
2013-06-05 21:24:14 +02:00
|
|
|
|
2013-01-06 22:15:47 -08:00
|
|
|
static std::map<u32, Psmf *> psmfMap;
|
2013-01-18 18:05:51 +08:00
|
|
|
static std::map<u32, PsmfPlayer *> psmfPlayerMap;
|
2012-11-13 18:05:26 +01:00
|
|
|
|
2012-12-24 10:44:40 -08:00
|
|
|
Psmf *getPsmf(u32 psmf)
|
|
|
|
{
|
2013-12-16 23:47:34 -08:00
|
|
|
auto psmfstruct = PSPPointer<PsmfData>::Create(psmf);
|
2013-07-01 03:52:35 +08:00
|
|
|
if (!psmfstruct.IsValid())
|
|
|
|
return 0;
|
|
|
|
auto iter = psmfMap.find(psmfstruct->headerOffset);
|
2012-11-13 18:05:26 +01:00
|
|
|
if (iter != psmfMap.end())
|
|
|
|
return iter->second;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
PsmfPlayer *getPsmfPlayer(u32 psmfplayer)
|
|
|
|
{
|
2014-04-20 08:22:51 -07:00
|
|
|
auto iter = psmfPlayerMap.find(Memory::Read_U32(psmfplayer));
|
2013-01-18 18:05:51 +08:00
|
|
|
if (iter != psmfPlayerMap.end())
|
|
|
|
return iter->second;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-24 10:44:40 -08:00
|
|
|
void __PsmfInit()
|
|
|
|
{
|
2014-02-14 10:43:53 +08:00
|
|
|
videoPixelMode = GE_CMODE_32BIT_ABGR8888;
|
2013-09-22 21:19:59 -07:00
|
|
|
videoLoopStatus = PSMF_PLAYER_CONFIG_NO_LOOP;
|
2012-12-24 10:44:40 -08:00
|
|
|
}
|
|
|
|
|
2012-12-28 23:29:24 -08:00
|
|
|
void __PsmfDoState(PointerWrap &p)
|
|
|
|
{
|
2013-09-14 20:23:03 -07:00
|
|
|
auto s = p.Section("scePsmf", 1);
|
|
|
|
if (!s)
|
|
|
|
return;
|
2012-12-28 23:29:24 -08:00
|
|
|
|
2013-09-14 20:23:03 -07:00
|
|
|
p.Do(psmfMap);
|
2012-12-28 23:29:24 -08:00
|
|
|
}
|
|
|
|
|
2013-01-20 16:16:57 +08:00
|
|
|
void __PsmfPlayerDoState(PointerWrap &p)
|
|
|
|
{
|
2013-09-14 20:23:03 -07:00
|
|
|
auto s = p.Section("scePsmfPlayer", 1);
|
|
|
|
if (!s)
|
|
|
|
return;
|
|
|
|
|
2013-02-04 01:31:02 -08:00
|
|
|
p.Do(psmfPlayerMap);
|
2013-06-27 23:46:26 +08:00
|
|
|
p.Do(videoPixelMode);
|
|
|
|
p.Do(videoLoopStatus);
|
2013-01-20 16:16:57 +08:00
|
|
|
}
|
|
|
|
|
2012-12-24 10:44:40 -08:00
|
|
|
void __PsmfShutdown()
|
|
|
|
{
|
|
|
|
for (auto it = psmfMap.begin(), end = psmfMap.end(); it != end; ++it)
|
|
|
|
delete it->second;
|
2013-03-06 01:00:26 -08:00
|
|
|
for (auto it = psmfPlayerMap.begin(), end = psmfPlayerMap.end(); it != end; ++it)
|
|
|
|
delete it->second;
|
2012-12-24 10:44:40 -08:00
|
|
|
psmfMap.clear();
|
2013-03-06 01:00:26 -08:00
|
|
|
psmfPlayerMap.clear();
|
2012-12-24 10:44:40 -08:00
|
|
|
}
|
2012-11-01 16:19:01 +01:00
|
|
|
|
2014-02-14 10:19:38 +08:00
|
|
|
bool isPlayingStatus(u32 status) {
|
|
|
|
if (status != PSMF_PLAYER_STATUS_PLAYING && status != PSMF_PLAYER_STATUS_PLAYING_FINISHED) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isInitializedStatus(u32 status) {
|
|
|
|
if (status == PSMF_PLAYER_STATUS_NONE) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-11-01 16:19:01 +01:00
|
|
|
u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData)
|
|
|
|
{
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "scePsmfSetPsmf(%08x, %08x)", psmfStruct, psmfData);
|
2012-11-13 18:05:26 +01:00
|
|
|
|
|
|
|
Psmf *psmf = new Psmf(psmfData);
|
|
|
|
|
2012-12-24 10:44:40 -08:00
|
|
|
PsmfData data = {0};
|
|
|
|
data.version = psmf->version;
|
|
|
|
data.headerSize = 0x800;
|
2012-11-13 18:05:26 +01:00
|
|
|
data.streamSize = psmf->streamSize;
|
|
|
|
data.streamNum = psmf->numStreams;
|
2013-07-01 04:25:04 +08:00
|
|
|
data.headerOffset = psmf->headerOffset;
|
2013-07-01 04:17:09 +08:00
|
|
|
auto iter = psmfMap.find(data.headerOffset);
|
|
|
|
if (iter != psmfMap.end())
|
|
|
|
delete iter->second;
|
2013-07-01 03:52:35 +08:00
|
|
|
psmfMap[data.headerOffset] = psmf;
|
2012-12-24 10:44:40 -08:00
|
|
|
Memory::WriteStruct(psmfStruct, &data);
|
|
|
|
return 0;
|
2012-11-01 16:19:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfGetNumberOfStreams(u32 psmfStruct)
|
|
|
|
{
|
2012-11-13 18:05:26 +01:00
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetNumberOfStreams(%08x): invalid psmf", psmfStruct);
|
2012-11-13 18:05:26 +01:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetNumberOfStreams(%08x)", psmfStruct);
|
2013-01-18 18:05:51 +08:00
|
|
|
return psmf->numStreams;
|
2012-11-01 16:19:01 +01:00
|
|
|
}
|
|
|
|
|
2013-07-07 18:10:55 -07:00
|
|
|
u32 scePsmfGetNumberOfSpecificStreams(u32 psmfStruct, int streamType)
|
2012-11-01 16:19:01 +01:00
|
|
|
{
|
2012-11-13 18:05:26 +01:00
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetNumberOfSpecificStreams(%08x, %08x): invalid psmf", psmfStruct, streamType);
|
2012-11-13 18:05:26 +01:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
WARN_LOG(ME, "scePsmfGetNumberOfSpecificStreams(%08x, %08x)", psmfStruct, streamType);
|
2013-06-15 01:39:56 +08:00
|
|
|
int streamNum = 0;
|
2013-06-16 01:35:47 +08:00
|
|
|
int type = (streamType == PSMF_AUDIO_STREAM ? PSMF_ATRAC_STREAM : streamType);
|
2013-07-22 19:22:21 +02:00
|
|
|
for (int i = (int)psmf->streamMap.size() - 1; i >= 0; i--) {
|
2013-06-16 01:35:47 +08:00
|
|
|
if (psmf->streamMap[i]->type == type)
|
2013-06-15 01:39:56 +08:00
|
|
|
streamNum++;
|
|
|
|
}
|
|
|
|
return streamNum;
|
2012-11-01 16:19:01 +01:00
|
|
|
}
|
|
|
|
|
2012-12-17 18:48:32 +01:00
|
|
|
u32 scePsmfSpecifyStreamWithStreamType(u32 psmfStruct, u32 streamType, u32 channel)
|
2012-11-01 16:19:01 +01:00
|
|
|
{
|
2013-06-05 21:24:14 +02:00
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfSpecifyStreamWithStreamType(%08x, %08x, %i): invalid psmf", psmfStruct, streamType, channel);
|
2013-06-05 21:24:14 +02:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "scePsmfSpecifyStreamWithStreamType(%08x, %08x, %i)", psmfStruct, streamType, channel);
|
2013-06-05 21:24:14 +02:00
|
|
|
if (!psmf->setStreamWithType(streamType, channel)) {
|
|
|
|
psmf->setStreamNum(-1);
|
|
|
|
}
|
2012-12-24 10:44:40 -08:00
|
|
|
return 0;
|
2012-11-01 16:19:01 +01:00
|
|
|
}
|
|
|
|
|
2012-12-17 18:48:32 +01:00
|
|
|
u32 scePsmfSpecifyStreamWithStreamTypeNumber(u32 psmfStruct, u32 streamType, u32 typeNum)
|
|
|
|
{
|
2013-06-05 21:24:14 +02:00
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfSpecifyStreamWithStreamTypeNumber(%08x, %08x, %08x): invalid psmf", psmfStruct, streamType, typeNum);
|
2013-06-05 21:24:14 +02:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG_REPORT(ME, "scePsmfSpecifyStreamWithStreamTypeNumber(%08x, %08x, %08x)", psmfStruct, streamType, typeNum);
|
2013-07-01 14:02:12 +08:00
|
|
|
// right now typeNum and channel are the same...
|
|
|
|
if (!psmf->setStreamWithType(streamType, typeNum)) {
|
|
|
|
psmf->setStreamNum(-1);
|
|
|
|
}
|
2012-12-17 18:48:32 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-06-05 21:24:14 +02:00
|
|
|
u32 scePsmfSpecifyStream(u32 psmfStruct, int streamNum) {
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfSpecifyStream(%08x, %i): invalid psmf", psmfStruct, streamNum);
|
2013-06-05 21:24:14 +02:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "scePsmfSpecifyStream(%08x, %i)", psmfStruct, streamNum);
|
2013-06-05 21:24:14 +02:00
|
|
|
psmf->setStreamNum(streamNum);
|
2013-06-05 19:56:36 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-05 18:10:13 +01:00
|
|
|
u32 scePsmfGetVideoInfo(u32 psmfStruct, u32 videoInfoAddr) {
|
2012-11-13 18:05:26 +01:00
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetVideoInfo(%08x, %08x): invalid psmf", psmfStruct, videoInfoAddr);
|
2012-11-13 18:05:26 +01:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "scePsmfGetVideoInfo(%08x, %08x)", psmfStruct, videoInfoAddr);
|
2012-11-13 18:05:26 +01:00
|
|
|
if (Memory::IsValidAddress(videoInfoAddr)) {
|
|
|
|
Memory::Write_U32(psmf->videoWidth, videoInfoAddr);
|
2013-06-13 22:12:16 -07:00
|
|
|
Memory::Write_U32(psmf->videoHeight, videoInfoAddr + 4);
|
2012-11-13 18:05:26 +01:00
|
|
|
}
|
2012-12-24 10:44:40 -08:00
|
|
|
return 0;
|
2012-11-13 18:05:26 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 18:10:13 +01:00
|
|
|
u32 scePsmfGetAudioInfo(u32 psmfStruct, u32 audioInfoAddr) {
|
2012-11-13 18:05:26 +01:00
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetAudioInfo(%08x, %08x): invalid psmf", psmfStruct, audioInfoAddr);
|
2012-11-13 18:05:26 +01:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "scePsmfGetAudioInfo(%08x, %08x)", psmfStruct, audioInfoAddr);
|
2012-11-13 18:05:26 +01:00
|
|
|
if (Memory::IsValidAddress(audioInfoAddr)) {
|
|
|
|
Memory::Write_U32(psmf->audioChannels, audioInfoAddr);
|
|
|
|
Memory::Write_U32(psmf->audioFrequency, audioInfoAddr + 4);
|
|
|
|
}
|
2012-12-24 10:44:40 -08:00
|
|
|
return 0;
|
2012-11-13 18:05:26 +01:00
|
|
|
}
|
|
|
|
|
2013-01-05 18:10:13 +01:00
|
|
|
u32 scePsmfGetCurrentStreamType(u32 psmfStruct, u32 typeAddr, u32 channelAddr) {
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetCurrentStreamType(%08x, %08x, %08x): invalid psmf", psmfStruct, typeAddr, channelAddr);
|
2013-01-05 18:10:13 +01:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "scePsmfGetCurrentStreamType(%08x, %08x, %08x)", psmfStruct, typeAddr, channelAddr);
|
2013-01-05 18:10:13 +01:00
|
|
|
if (Memory::IsValidAddress(typeAddr)) {
|
|
|
|
u32 type = 0, channel = 0;
|
|
|
|
if (psmf->streamMap.find(psmf->currentStreamNum) != psmf->streamMap.end())
|
|
|
|
type = psmf->streamMap[psmf->currentStreamNum]->type;
|
|
|
|
if (psmf->streamMap.find(psmf->currentStreamNum) != psmf->streamMap.end())
|
|
|
|
channel = psmf->streamMap[psmf->currentStreamNum]->channel;
|
|
|
|
Memory::Write_U32(type, typeAddr);
|
|
|
|
Memory::Write_U32(channel, channelAddr);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2012-11-13 18:05:26 +01:00
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
u32 scePsmfGetStreamSize(u32 psmfStruct, u32 sizeAddr)
|
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetStreamSize(%08x, %08x): invalid psmf", psmfStruct, sizeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetStreamSize(%08x, %08x)", psmfStruct, sizeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
if (Memory::IsValidAddress(sizeAddr)) {
|
|
|
|
Memory::Write_U32(psmf->streamSize, sizeAddr);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-03-29 01:05:11 -07:00
|
|
|
u32 scePsmfQueryStreamOffset(u32 bufferAddr, u32 offsetAddr)
|
|
|
|
{
|
2013-09-07 22:02:55 +02:00
|
|
|
WARN_LOG(ME, "scePsmfQueryStreamOffset(%08x, %08x)", bufferAddr, offsetAddr);
|
2013-03-29 01:05:11 -07:00
|
|
|
if (Memory::IsValidAddress(offsetAddr)) {
|
2013-10-28 17:23:51 +01:00
|
|
|
Memory::Write_U32(bswap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_OFFSET_OFFSET)), offsetAddr);
|
2013-03-29 01:05:11 -07:00
|
|
|
}
|
2013-06-07 01:27:15 -07:00
|
|
|
return 0;
|
2013-03-29 01:05:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfQueryStreamSize(u32 bufferAddr, u32 sizeAddr)
|
|
|
|
{
|
2013-09-07 22:02:55 +02:00
|
|
|
WARN_LOG(ME, "scePsmfQueryStreamSize(%08x, %08x)", bufferAddr, sizeAddr);
|
2013-03-29 01:05:11 -07:00
|
|
|
if (Memory::IsValidAddress(sizeAddr)) {
|
2013-10-28 17:23:51 +01:00
|
|
|
Memory::Write_U32(bswap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_SIZE_OFFSET)), sizeAddr);
|
2013-03-29 01:05:11 -07:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
u32 scePsmfGetHeaderSize(u32 psmfStruct, u32 sizeAddr)
|
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetHeaderSize(%08x, %08x): invalid psmf", psmfStruct, sizeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetHeaderSize(%08x, %08x)", psmfStruct, sizeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
if (Memory::IsValidAddress(sizeAddr)) {
|
|
|
|
Memory::Write_U32(psmf->headerSize, sizeAddr);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfGetPsmfVersion(u32 psmfStruct)
|
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2014-01-01 13:31:47 -08:00
|
|
|
ERROR_LOG(ME, "scePsmfGetPsmfVersion(%08x): invalid psmf", psmfStruct);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetPsmfVersion(%08x)", psmfStruct);
|
2013-01-18 18:05:51 +08:00
|
|
|
return psmf->version;
|
|
|
|
}
|
|
|
|
|
2013-01-29 01:28:51 +01:00
|
|
|
u32 scePsmfVerifyPsmf(u32 psmfAddr)
|
|
|
|
{
|
2013-07-07 18:10:55 -07:00
|
|
|
u32 magic = Memory::Read_U32(psmfAddr);
|
2013-06-14 07:15:57 +08:00
|
|
|
if (magic != PSMF_MAGIC) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfVerifyPsmf(%08x): bad magic %08x", psmfAddr, magic);
|
2013-06-14 07:15:57 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
int version = Memory::Read_U32(psmfAddr + PSMF_STREAM_VERSION_OFFSET);
|
|
|
|
if (version < 0) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfVerifyPsmf(%08x): bad version %08x", psmfAddr, version);
|
2013-06-14 07:15:57 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2014-03-02 01:15:00 -08:00
|
|
|
// Kurohyou 2 (at least the demo) uses an uninitialized value that happens to be zero on the PSP.
|
|
|
|
// It appears to be written by scePsmfVerifyPsmf(), so we write some bytes into the stack here.
|
|
|
|
Memory::Memset(currentMIPS->r[MIPS_REG_SP] - 0x20, 0, 0x20);
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfVerifyPsmf(%08x)", psmfAddr);
|
2013-01-29 01:28:51 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
u32 scePsmfGetNumberOfEPentries(u32 psmfStruct)
|
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetNumberOfEPentries(%08x): invalid psmf", psmfStruct);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetNumberOfEPentries(%08x)", psmfStruct);
|
2013-01-18 18:05:51 +08:00
|
|
|
return psmf->EPMapEntriesNum;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfGetPresentationStartTime(u32 psmfStruct, u32 startTimeAddr)
|
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetPresentationStartTime(%08x, %08x): invalid psmf", psmfStruct, startTimeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetPresentationStartTime(%08x, %08x)", psmfStruct, startTimeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
if (Memory::IsValidAddress(startTimeAddr)) {
|
|
|
|
Memory::Write_U32(psmf->presentationStartTime, startTimeAddr);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfGetPresentationEndTime(u32 psmfStruct, u32 endTimeAddr)
|
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetPresentationEndTime(%08x, %08x): invalid psmf", psmfStruct, endTimeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetPresentationEndTime(%08x, %08x)", psmfStruct, endTimeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
if (Memory::IsValidAddress(endTimeAddr)) {
|
|
|
|
Memory::Write_U32(psmf->presentationEndTime, endTimeAddr);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfGetCurrentStreamNumber(u32 psmfStruct)
|
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetCurrentStreamNumber(%08x): invalid psmf", psmfStruct);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetCurrentStreamNumber(%08x)", psmfStruct);
|
2013-01-18 18:05:51 +08:00
|
|
|
return psmf->currentStreamNum;
|
|
|
|
}
|
|
|
|
|
2014-01-10 19:15:35 +08:00
|
|
|
u32 scePsmfCheckEPMap(u32 psmfStruct)
|
2013-06-24 18:58:36 +02:00
|
|
|
{
|
2014-01-10 19:15:35 +08:00
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
|
|
|
ERROR_LOG(ME, "scePsmfCheckEPMap(%08x): invalid psmf", psmfStruct);
|
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG_LOG(ME, "scePsmfCheckEPMap(%08x)", psmfStruct);
|
2014-01-10 12:57:40 -08:00
|
|
|
return psmf->EPMap.empty() ? ERROR_PSMF_NOT_FOUND : 0;
|
2013-06-24 18:58:36 +02:00
|
|
|
}
|
|
|
|
|
2014-01-01 13:23:19 -08:00
|
|
|
u32 scePsmfGetEPWithId(u32 psmfStruct, int epid, u32 entryAddr)
|
2013-01-18 18:05:51 +08:00
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2014-01-01 13:23:19 -08:00
|
|
|
ERROR_LOG(ME, "scePsmfGetEPWithId(%08x, %i, %08x): invalid psmf", psmfStruct, epid, entryAddr);
|
2014-03-02 01:15:00 -08:00
|
|
|
return ERROR_PSMF_NOT_INITIALIZED;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-01-01 13:23:19 -08:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetEPWithId(%08x, %i, %08x)", psmfStruct, epid, entryAddr);
|
2014-01-09 21:37:01 +08:00
|
|
|
|
2014-01-08 14:20:20 +01:00
|
|
|
if (epid < 0 || epid >= (int)psmf->EPMap.size()) {
|
2014-01-09 22:34:02 +08:00
|
|
|
ERROR_LOG(ME, "scePsmfGetEPWithId(%08x, %i): invalid id", psmfStruct, epid);
|
2014-03-02 01:15:00 -08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
2014-01-01 13:23:19 -08:00
|
|
|
}
|
|
|
|
if (Memory::IsValidAddress(entryAddr)) {
|
|
|
|
Memory::WriteStruct(entryAddr, &psmf->EPMap[epid]);
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-22 23:44:23 -08:00
|
|
|
u32 scePsmfGetEPWithTimestamp(u32 psmfStruct, u32 ts, u32 entryAddr)
|
2013-01-18 18:05:51 +08:00
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i, %08x): invalid psmf", psmfStruct, ts, entryAddr);
|
2014-03-02 01:15:00 -08:00
|
|
|
return ERROR_PSMF_NOT_INITIALIZED;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i, %08x)", psmfStruct, ts, entryAddr);
|
2014-01-09 21:37:01 +08:00
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
if (ts < psmf->presentationStartTime) {
|
2014-01-09 22:34:02 +08:00
|
|
|
ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i): invalid timestamp", psmfStruct, ts);
|
2014-03-02 01:15:00 -08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-01-01 13:23:19 -08:00
|
|
|
|
|
|
|
int epid = psmf->FindEPWithTimestamp(ts);
|
2014-01-08 14:20:20 +01:00
|
|
|
if (epid < 0 || epid >= (int)psmf->EPMap.size()) {
|
2014-03-02 15:12:50 +08:00
|
|
|
ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i): invalid id", psmfStruct, epid);
|
2014-03-02 01:15:00 -08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
2014-01-01 13:23:19 -08:00
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
if (Memory::IsValidAddress(entryAddr)) {
|
2014-01-01 13:23:19 -08:00
|
|
|
Memory::WriteStruct(entryAddr, &psmf->EPMap[epid]);
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-22 23:44:23 -08:00
|
|
|
u32 scePsmfGetEPidWithTimestamp(u32 psmfStruct, u32 ts)
|
2013-01-18 18:05:51 +08:00
|
|
|
{
|
|
|
|
Psmf *psmf = getPsmf(psmfStruct);
|
|
|
|
if (!psmf) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfGetEPidWithTimestamp(%08x, %i): invalid psmf", psmfStruct, ts);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfGetEPidWithTimestamp(%08x, %i)", psmfStruct, ts);
|
2014-01-09 21:37:01 +08:00
|
|
|
|
2014-01-10 19:15:35 +08:00
|
|
|
if (psmf->EPMap.empty()) {
|
|
|
|
ERROR_LOG(ME, "scePsmfGetEPidWithTimestamp(%08x): EPMap is empty", psmfStruct);
|
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
if (ts < psmf->presentationStartTime) {
|
2014-01-09 21:37:01 +08:00
|
|
|
ERROR_LOG(ME, "scePsmfGetEPidWithTimestamp(%08x, %i): invalid timestamp", psmfStruct, ts);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_INVALID_TIMESTAMP;
|
|
|
|
}
|
|
|
|
|
2014-01-01 13:23:19 -08:00
|
|
|
int epid = psmf->FindEPWithTimestamp(ts);
|
2014-01-08 14:20:20 +01:00
|
|
|
if (epid < 0 || epid >= (int)psmf->EPMap.size()) {
|
2014-01-09 21:37:01 +08:00
|
|
|
ERROR_LOG(ME, "scePsmfGetEPidWithTimestamp(%08x, %i): invalid id", psmfStruct, epid);
|
2014-01-09 21:30:49 +08:00
|
|
|
return ERROR_PSMF_INVALID_ID;
|
2014-01-01 13:23:19 -08:00
|
|
|
}
|
2014-01-10 19:15:35 +08:00
|
|
|
|
2014-01-01 13:23:19 -08:00
|
|
|
return epid;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
|
2014-04-20 00:01:16 -07:00
|
|
|
int scePsmfPlayerCreate(u32 psmfPlayer, u32 dataPtr)
|
2013-01-18 18:05:51 +08:00
|
|
|
{
|
2014-04-20 00:01:16 -07:00
|
|
|
auto player = PSPPointer<u32>::Create(psmfPlayer);
|
|
|
|
const auto data = PSPPointer<const PsmfPlayerCreateData>::Create(dataPtr);
|
|
|
|
|
|
|
|
if (!player.IsValid() || !data.IsValid()) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): bad pointers", psmfPlayer, dataPtr);
|
|
|
|
// Crashes on a PSP.
|
|
|
|
return SCE_KERNEL_ERROR_ILLEGAL_ADDRESS;
|
|
|
|
}
|
|
|
|
if (!data->buffer.IsValid()) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): invalid buffer address %08x", psmfPlayer, dataPtr, data->buffer.ptr);
|
|
|
|
// Also crashes on a PSP.
|
|
|
|
*player = 0;
|
|
|
|
return SCE_KERNEL_ERROR_ILLEGAL_ADDRESS;
|
|
|
|
}
|
|
|
|
if (data->bufferSize < 0x00300000) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): buffer too small %08x", psmfPlayer, dataPtr, data->bufferSize);
|
|
|
|
*player = 0;
|
|
|
|
return ERROR_PSMFPLAYER_BUFFER_SIZE;
|
|
|
|
}
|
|
|
|
if (data->threadPriority < 0x10 || data->threadPriority >= 0x6E) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): bad thread priority %02x", psmfPlayer, dataPtr, data->threadPriority);
|
|
|
|
*player = 0;
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_PARAM;
|
|
|
|
}
|
|
|
|
if (!psmfPlayerMap.empty()) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): already have an active player", psmfPlayer, dataPtr);
|
|
|
|
// TODO: Tests show this is what we should do. Leaving it off for now to see if safe.
|
|
|
|
//*player = 0;
|
|
|
|
//return ERROR_MPEG_ALREADY_INIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
INFO_LOG(ME, "scePsmfPlayerCreate(%08x, %08x)", psmfPlayer, dataPtr);
|
2013-01-18 18:05:51 +08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2014-04-20 00:01:16 -07:00
|
|
|
psmfplayer = new PsmfPlayer(data);
|
2014-03-30 13:14:17 -07:00
|
|
|
if (psmfPlayerMap.find(psmfPlayer) != psmfPlayerMap.end())
|
|
|
|
delete psmfPlayerMap[psmfPlayer];
|
2013-01-27 19:41:56 -08:00
|
|
|
psmfPlayerMap[psmfPlayer] = psmfplayer;
|
2014-04-20 08:22:51 -07:00
|
|
|
|
|
|
|
// Write something there to identify it with.
|
|
|
|
*player = psmfPlayer;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2013-01-24 19:40:26 +08:00
|
|
|
|
2014-04-20 19:19:12 -07:00
|
|
|
// These really shouldn't be globals. But, you can only have one psmfplayer anyway.
|
|
|
|
videoPixelMode = GE_CMODE_32BIT_ABGR8888;
|
|
|
|
videoLoopStatus = PSMF_PLAYER_CONFIG_NO_LOOP;
|
|
|
|
|
2013-01-24 19:40:26 +08:00
|
|
|
psmfplayer->psmfMaxAheadTimestamp = getMaxAheadTimestamp(581);
|
2013-03-06 01:00:26 -08:00
|
|
|
psmfplayer->status = PSMF_PLAYER_STATUS_INIT;
|
2014-04-20 00:01:16 -07:00
|
|
|
return hleDelayResult(0, "player create", 20000);
|
2013-01-06 22:15:47 -08:00
|
|
|
}
|
|
|
|
|
2014-01-08 14:20:20 +01:00
|
|
|
int scePsmfPlayerStop(u32 psmfPlayer)
|
2013-01-18 18:05:51 +08:00
|
|
|
{
|
2013-03-06 01:00:26 -08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
2014-02-05 22:33:44 +08:00
|
|
|
if (!psmfplayer) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerStop(%08x): invalid psmf player", psmfPlayer);
|
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2014-02-14 10:19:38 +08:00
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
|
|
|
if (!isInitialized) {
|
2014-02-13 20:22:56 +08:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerStop(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-13 20:22:56 +08:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:33:44 +08:00
|
|
|
INFO_LOG(ME, "scePsmfPlayerStop(%08x)", psmfPlayer);
|
|
|
|
psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY;
|
2013-01-06 22:15:47 -08:00
|
|
|
return 0;
|
2012-11-07 19:10:52 +01:00
|
|
|
}
|
|
|
|
|
2014-01-08 14:20:20 +01:00
|
|
|
int scePsmfPlayerBreak(u32 psmfPlayer)
|
2013-01-18 18:05:51 +08:00
|
|
|
{
|
2014-02-16 23:21:32 +08:00
|
|
|
WARN_LOG(ME, "scePsmfPlayerBreak(%08x)", psmfPlayer);
|
2013-03-06 01:00:26 -08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
2014-02-05 22:33:44 +08:00
|
|
|
if (!psmfplayer) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerBreak(%08x): invalid psmf player", psmfPlayer);
|
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2014-02-14 10:19:38 +08:00
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
|
|
|
if (!isInitialized) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerBreak(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:33:44 +08:00
|
|
|
// Fix everybody stress buster
|
|
|
|
psmfplayer->status = PSMF_PLAYER_STATUS_INIT;
|
2013-01-06 22:15:47 -08:00
|
|
|
return 0;
|
2012-11-07 19:10:52 +01:00
|
|
|
}
|
|
|
|
|
2013-06-27 23:46:26 +08:00
|
|
|
int _PsmfPlayerFillRingbuffer(PsmfPlayer *psmfplayer) {
|
2014-02-25 00:22:52 -05:00
|
|
|
if (!psmfplayer->filehandle)
|
2013-06-27 23:46:26 +08:00
|
|
|
return -1;
|
|
|
|
u8* buf = psmfplayer->tempbuf;
|
2014-01-04 01:23:44 -08:00
|
|
|
int tempbufSize = (int)sizeof(psmfplayer->tempbuf);
|
2013-06-27 23:46:26 +08:00
|
|
|
int size;
|
2014-01-04 01:23:44 -08:00
|
|
|
// Let's not burn a bunch of time adding data all at once.
|
|
|
|
int addMax = std::max(2048 * 100, tempbufSize);
|
2013-06-27 23:46:26 +08:00
|
|
|
do {
|
2014-01-04 01:23:44 -08:00
|
|
|
size = std::min(psmfplayer->mediaengine->getRemainSize(), tempbufSize);
|
2014-01-04 01:25:42 -08:00
|
|
|
size = std::min(psmfplayer->mediaengine->getAudioRemainSize(), size);
|
2013-06-27 23:46:26 +08:00
|
|
|
size = std::min(psmfplayer->streamSize - psmfplayer->readSize, size);
|
|
|
|
if (size <= 0)
|
|
|
|
break;
|
2013-07-22 19:22:21 +02:00
|
|
|
size = (int)pspFileSystem.ReadFile(psmfplayer->filehandle, buf, size);
|
2013-06-28 05:44:57 +08:00
|
|
|
psmfplayer->readSize += size;
|
2013-06-27 23:46:26 +08:00
|
|
|
psmfplayer->mediaengine->addStreamData(buf, size);
|
2014-01-04 01:23:44 -08:00
|
|
|
addMax -= size;
|
|
|
|
if (addMax <= 0)
|
|
|
|
break;
|
2013-06-27 23:46:26 +08:00
|
|
|
} while (size > 0);
|
|
|
|
if (psmfplayer->readSize >= psmfplayer->streamSize && videoLoopStatus == PSMF_PLAYER_CONFIG_LOOP) {
|
|
|
|
// start looping
|
|
|
|
psmfplayer->readSize = 0;
|
|
|
|
pspFileSystem.SeekFile(psmfplayer->filehandle, psmfplayer->fileoffset, FILEMOVE_BEGIN);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-20 08:45:40 -07:00
|
|
|
int _PsmfPlayerSetPsmfOffset(u32 psmfPlayer, const char *filename, int offset, bool docallback) {
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer || psmfplayer->status != PSMF_PLAYER_STATUS_INIT) {
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
|
|
|
}
|
|
|
|
if (!filename) {
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_PARAM;
|
|
|
|
}
|
2013-06-18 16:05:15 +08:00
|
|
|
psmfplayer->filehandle = pspFileSystem.OpenFile(filename, (FileAccess) FILEACCESS_READ);
|
2014-04-20 08:45:40 -07:00
|
|
|
if (!psmfplayer->filehandle) {
|
|
|
|
return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT;
|
|
|
|
}
|
|
|
|
|
2013-06-18 16:05:15 +08:00
|
|
|
if (psmfplayer->filehandle && psmfplayer->tempbuf) {
|
2014-04-20 08:45:40 -07:00
|
|
|
if (offset != 0)
|
2013-06-27 23:46:26 +08:00
|
|
|
pspFileSystem.SeekFile(psmfplayer->filehandle, offset, FILEMOVE_BEGIN);
|
2014-04-20 08:45:40 -07:00
|
|
|
u8 *buf = psmfplayer->tempbuf;
|
2014-01-04 01:25:42 -08:00
|
|
|
int tempbufSize = (int)sizeof(psmfplayer->tempbuf);
|
2013-07-22 19:22:21 +02:00
|
|
|
int size = (int)pspFileSystem.ReadFile(psmfplayer->filehandle, buf, 2048);
|
2014-04-20 08:55:30 -07:00
|
|
|
const u32 magic = *(u32_le *)buf;
|
|
|
|
if (magic != PSMF_MAGIC) {
|
|
|
|
// TODO: Let's keep trying as we were before.
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSetPsmf*: incorrect PSMF magic, bad data");
|
|
|
|
//return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT;
|
|
|
|
}
|
2014-04-20 11:53:59 -07:00
|
|
|
|
|
|
|
// TODO: Merge better with Psmf.
|
|
|
|
u16 numStreams = *(u16_be *)(buf + 0x80);
|
|
|
|
psmfplayer->totalVideoStreams = 0;
|
|
|
|
psmfplayer->totalAudioStreams = 0;
|
|
|
|
psmfplayer->playerVersion = PSMF_PLAYER_VERSION_FULL;
|
|
|
|
for (u16 i = 0; i < numStreams; i++) {
|
|
|
|
const u8 *currentStreamAddr = buf + 0x82 + i * 16;
|
|
|
|
const int streamId = *currentStreamAddr;
|
|
|
|
if ((streamId & PSMF_VIDEO_STREAM_ID) == PSMF_VIDEO_STREAM_ID) {
|
|
|
|
++psmfplayer->totalVideoStreams;
|
|
|
|
// If we don't have EP info for /any/ video stream, revert to BASIC.
|
|
|
|
const u32 epOffset = *(const u32_be *)(currentStreamAddr + 4);
|
|
|
|
const u32 epEntries = *(const u32_be *)(currentStreamAddr + 8);
|
|
|
|
// TODO: Actually, if these don't match, it seems to be an invalid PSMF.
|
|
|
|
if (epOffset == 0 || epEntries == 0) {
|
|
|
|
psmfplayer->playerVersion = PSMF_PLAYER_VERSION_BASIC;
|
|
|
|
}
|
|
|
|
} else if ((streamId & PSMF_AUDIO_STREAM_ID) == PSMF_AUDIO_STREAM_ID) {
|
|
|
|
++psmfplayer->totalAudioStreams;
|
|
|
|
} else {
|
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerSetPsmf*: unexpected streamID %x", streamId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO: It seems like it's invalid if there's not at least 1 video stream.
|
|
|
|
|
2014-04-20 08:55:30 -07:00
|
|
|
int mpegoffset = bswap32(*(u32_le *)(buf + PSMF_STREAM_OFFSET_OFFSET));
|
2013-06-27 23:46:26 +08:00
|
|
|
psmfplayer->readSize = size - mpegoffset;
|
2014-04-20 08:55:30 -07:00
|
|
|
psmfplayer->streamSize = bswap32(*(u32_le *)(buf + PSMF_STREAM_SIZE_OFFSET));
|
2013-06-27 23:46:26 +08:00
|
|
|
psmfplayer->fileoffset = offset + mpegoffset;
|
2014-01-04 01:25:42 -08:00
|
|
|
psmfplayer->mediaengine->loadStream(buf, 2048, std::max(2048 * 500, tempbufSize));
|
2013-06-27 23:46:26 +08:00
|
|
|
_PsmfPlayerFillRingbuffer(psmfplayer);
|
2013-06-18 16:05:15 +08:00
|
|
|
psmfplayer->psmfPlayerLastTimestamp = psmfplayer->mediaengine->getLastTimeStamp();
|
|
|
|
}
|
2014-04-20 08:55:30 -07:00
|
|
|
|
|
|
|
psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY;
|
|
|
|
|
2013-06-18 16:05:15 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int scePsmfPlayerSetPsmf(u32 psmfPlayer, const char *filename)
|
|
|
|
{
|
2014-04-20 08:45:40 -07:00
|
|
|
int result = _PsmfPlayerSetPsmfOffset(psmfPlayer, filename, 0, false);
|
|
|
|
if (result == ERROR_PSMFPLAYER_INVALID_STATUS) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSetPsmf(%08x, %s): invalid psmf player or status", psmfPlayer, filename);
|
|
|
|
} else if (result == ERROR_PSMFPLAYER_INVALID_PARAM) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetPsmf(%08x, %s): invalid filename", psmfPlayer, filename);
|
|
|
|
} else if (result == SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetPsmf(%08x, %s): invalid file data or does not exist", psmfPlayer, filename);
|
|
|
|
} else {
|
|
|
|
INFO_LOG(ME, "scePsmfPlayerSetPsmf(%08x, %s)", psmfPlayer, filename);
|
|
|
|
}
|
|
|
|
return result;
|
2013-01-06 22:15:47 -08:00
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int scePsmfPlayerSetPsmfCB(u32 psmfPlayer, const char *filename)
|
|
|
|
{
|
2013-06-13 22:33:59 -07:00
|
|
|
// TODO: hleCheckCurrentCallbacks?
|
2014-04-20 08:45:40 -07:00
|
|
|
int result = _PsmfPlayerSetPsmfOffset(psmfPlayer, filename, 0, true);
|
|
|
|
if (result == ERROR_PSMFPLAYER_INVALID_STATUS) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSetPsmfCB(%08x, %s): invalid psmf player or status", psmfPlayer, filename);
|
|
|
|
} else if (result == ERROR_PSMFPLAYER_INVALID_PARAM) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetPsmfCB(%08x, %s): invalid filename", psmfPlayer, filename);
|
|
|
|
} else if (result == SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetPsmfCB(%08x, %s): invalid file data or does not exist", psmfPlayer, filename);
|
|
|
|
} else {
|
|
|
|
INFO_LOG(ME, "scePsmfPlayerSetPsmfCB(%08x, %s)", psmfPlayer, filename);
|
|
|
|
}
|
|
|
|
return result;
|
2013-01-06 22:15:47 -08:00
|
|
|
}
|
|
|
|
|
2013-06-18 16:05:15 +08:00
|
|
|
int scePsmfPlayerSetPsmfOffset(u32 psmfPlayer, const char *filename, int offset)
|
|
|
|
{
|
2014-04-20 08:45:40 -07:00
|
|
|
int result = _PsmfPlayerSetPsmfOffset(psmfPlayer, filename, offset, false);
|
|
|
|
if (result == ERROR_PSMFPLAYER_INVALID_STATUS) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSetPsmfOffset(%08x, %s): invalid psmf player or status", psmfPlayer, filename);
|
|
|
|
} else if (result == ERROR_PSMFPLAYER_INVALID_PARAM) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetPsmfOffset(%08x, %s): invalid filename", psmfPlayer, filename);
|
|
|
|
} else if (result == SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetPsmfOffset(%08x, %s): invalid file data or does not exist", psmfPlayer, filename);
|
|
|
|
} else {
|
|
|
|
INFO_LOG(ME, "scePsmfPlayerSetPsmfOffset(%08x, %s)", psmfPlayer, filename);
|
|
|
|
}
|
|
|
|
return result;
|
2013-06-18 16:05:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int scePsmfPlayerSetPsmfOffsetCB(u32 psmfPlayer, const char *filename, int offset)
|
|
|
|
{
|
|
|
|
// TODO: hleCheckCurrentCallbacks?
|
2014-04-20 08:45:40 -07:00
|
|
|
int result = _PsmfPlayerSetPsmfOffset(psmfPlayer, filename, offset, true);
|
|
|
|
if (result == ERROR_PSMFPLAYER_INVALID_STATUS) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSetPsmfOffsetCB(%08x, %s): invalid psmf player or status", psmfPlayer, filename);
|
|
|
|
} else if (result == ERROR_PSMFPLAYER_INVALID_PARAM) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetPsmfOffsetCB(%08x, %s): invalid filename", psmfPlayer, filename);
|
|
|
|
} else if (result == SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetPsmfOffsetCB(%08x, %s): invalid file data or does not exist", psmfPlayer, filename);
|
|
|
|
} else {
|
|
|
|
INFO_LOG(ME, "scePsmfPlayerSetPsmfOffsetCB(%08x, %s)", psmfPlayer, filename);
|
|
|
|
}
|
|
|
|
return result;
|
2013-01-06 22:15:47 -08:00
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int scePsmfPlayerGetAudioOutSize(u32 psmfPlayer)
|
|
|
|
{
|
2014-02-14 10:19:38 +08:00
|
|
|
WARN_LOG(ME, "%i = scePsmfPlayerGetAudioOutSize(%08x)", audioSamplesBytes, psmfPlayer);
|
2013-01-18 18:05:51 +08:00
|
|
|
return audioSamplesBytes;
|
2013-01-06 22:15:47 -08:00
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int scePsmfPlayerStart(u32 psmfPlayer, u32 psmfPlayerData, int initPts)
|
|
|
|
{
|
2014-02-16 23:21:32 +08:00
|
|
|
WARN_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %08x)", psmfPlayer, psmfPlayerData, initPts);
|
2013-01-18 18:05:51 +08:00
|
|
|
|
2013-01-22 23:44:23 -08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
2014-02-14 10:19:38 +08:00
|
|
|
|
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
|
|
|
if (!isInitialized) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerStart(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2013-06-02 01:30:51 +08:00
|
|
|
if (Memory::IsValidAddress(psmfPlayerData)) {
|
|
|
|
PsmfPlayerData data = {0};
|
|
|
|
Memory::ReadStruct(psmfPlayerData, &data);
|
|
|
|
psmfplayer->videoCodec = data.videoCodec;
|
|
|
|
psmfplayer->videoStreamNum = data.videoStreamNum;
|
|
|
|
psmfplayer->audioCodec = data.audioCodec;
|
|
|
|
psmfplayer->audioStreamNum = data.audioStreamNum;
|
|
|
|
psmfplayer->playMode = data.playMode;
|
|
|
|
psmfplayer->playSpeed = data.playSpeed;
|
|
|
|
/*data.videoCodec = psmfplayer->videoCodec;
|
|
|
|
data.videoStreamNum = psmfplayer->videoStreamNum;
|
|
|
|
data.audioCodec = psmfplayer->audioCodec;
|
|
|
|
data.audioStreamNum = psmfplayer->audioStreamNum;
|
|
|
|
data.playMode = psmfplayer->playMode;
|
|
|
|
data.playSpeed = psmfplayer->playSpeed;
|
|
|
|
data.psmfPlayerLastTimestamp = psmfplayer->psmfPlayerLastTimestamp;
|
|
|
|
Memory::WriteStruct(psmfPlayerData, &data);*/
|
|
|
|
}
|
2013-01-18 18:05:51 +08:00
|
|
|
|
|
|
|
psmfplayer->psmfPlayerAtracAu.dts = initPts;
|
2013-01-24 19:21:32 +08:00
|
|
|
psmfplayer->psmfPlayerAtracAu.pts = initPts;
|
|
|
|
psmfplayer->psmfPlayerAvcAu.dts = initPts;
|
|
|
|
psmfplayer->psmfPlayerAvcAu.pts = initPts;
|
2013-01-18 18:05:51 +08:00
|
|
|
|
2013-03-06 01:00:26 -08:00
|
|
|
psmfplayer->status = PSMF_PLAYER_STATUS_PLAYING;
|
2013-06-11 19:04:14 +08:00
|
|
|
|
|
|
|
psmfplayer->mediaengine->openContext();
|
2013-01-06 22:15:47 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int scePsmfPlayerDelete(u32 psmfPlayer)
|
|
|
|
{
|
2013-03-06 01:00:26 -08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
2014-02-05 22:33:44 +08:00
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerDelete(%08x): invalid psmf player", psmfPlayer);
|
2014-02-05 22:33:44 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
2013-03-29 00:54:04 -07:00
|
|
|
}
|
2014-02-05 22:33:44 +08:00
|
|
|
|
2014-02-14 10:19:38 +08:00
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
|
|
|
if (!isInitialized) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerDelete(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:33:44 +08:00
|
|
|
INFO_LOG(ME, "scePsmfPlayerDelete(%08x)", psmfPlayer);
|
|
|
|
delete psmfplayer;
|
|
|
|
psmfPlayerMap.erase(psmfPlayer);
|
|
|
|
|
2013-01-06 22:15:47 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int scePsmfPlayerUpdate(u32 psmfPlayer)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerUpdate(%08x): invalid psmf player", psmfPlayer);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2014-02-14 10:19:38 +08:00
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
|
|
|
if (!isInitialized) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerUpdate(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:55:46 +08:00
|
|
|
bool psmfplayerstatus = isPlayingStatus(psmfplayer->status);
|
|
|
|
if (!psmfplayerstatus) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerUpdate(%08x): psmf not playing", psmfPlayer);
|
|
|
|
return ERROR_PSMF_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfPlayerUpdate(%08x)", psmfPlayer);
|
2013-01-24 19:40:26 +08:00
|
|
|
if (psmfplayer->psmfPlayerAvcAu.pts > 0) {
|
2013-06-27 23:46:26 +08:00
|
|
|
if (psmfplayer->mediaengine->IsVideoEnd()) {
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "video end reached");
|
2013-03-06 01:00:26 -08:00
|
|
|
psmfplayer->status = PSMF_PLAYER_STATUS_PLAYING_FINISHED;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2013-01-22 23:44:23 -08:00
|
|
|
}
|
2014-02-05 22:55:46 +08:00
|
|
|
|
2013-06-08 00:27:31 +08:00
|
|
|
return 0;
|
2013-01-06 22:15:47 -08:00
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int scePsmfPlayerReleasePsmf(u32 psmfPlayer)
|
|
|
|
{
|
2013-03-06 01:00:26 -08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
2014-02-05 22:33:44 +08:00
|
|
|
if (!psmfplayer) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerReleasePsmf(%08x): invalid psmf player", psmfPlayer);
|
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2014-02-14 10:19:38 +08:00
|
|
|
|
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
2014-02-15 18:38:38 +08:00
|
|
|
if (!isInitialized) {
|
2014-02-14 10:19:38 +08:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerReleasePsmf(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-13 20:22:56 +08:00
|
|
|
}
|
|
|
|
|
2014-02-16 23:21:32 +08:00
|
|
|
WARN_LOG(ME, "scePsmfPlayerReleasePsmf(%08x)", psmfPlayer);
|
2014-02-05 22:33:44 +08:00
|
|
|
psmfplayer->status = PSMF_PLAYER_STATUS_INIT;
|
2013-01-06 22:15:47 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-03-29 00:54:04 -07:00
|
|
|
int scePsmfPlayerGetVideoData(u32 psmfPlayer, u32 videoDataAddr)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetVideoData(%08x, %08x): invalid psmf player", psmfPlayer, videoDataAddr);
|
2013-03-29 00:54:04 -07:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2014-02-14 10:19:38 +08:00
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
|
|
|
if (!isInitialized) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetVideoData(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:55:46 +08:00
|
|
|
bool psmfplayerstatus = isPlayingStatus(psmfplayer->status);
|
|
|
|
if (!psmfplayerstatus) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetVideoData(%08x): psmf not playing", psmfPlayer);
|
|
|
|
return ERROR_PSMF_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
2014-02-14 10:43:53 +08:00
|
|
|
if (psmfplayer->playMode == PSMF_PLAYER_MODE_PAUSE) {
|
|
|
|
INFO_LOG(HLE, "scePsmfPlayerGetVideoData(%08x): paused mode", psmfPlayer);
|
|
|
|
return 0;
|
|
|
|
}
|
2014-02-15 18:07:19 +08:00
|
|
|
|
2013-06-02 01:30:51 +08:00
|
|
|
if (Memory::IsValidAddress(videoDataAddr)) {
|
|
|
|
int frameWidth = Memory::Read_U32(videoDataAddr);
|
|
|
|
u32 displaybuf = Memory::Read_U32(videoDataAddr + 4);
|
|
|
|
int displaypts = Memory::Read_U32(videoDataAddr + 8);
|
2013-06-08 04:50:36 -07:00
|
|
|
if (psmfplayer->mediaengine->stepVideo(videoPixelMode)) {
|
2013-12-11 08:21:01 -08:00
|
|
|
int displaybufSize = psmfplayer->mediaengine->writeVideoImage(displaybuf, frameWidth, videoPixelMode);
|
2013-06-08 04:50:36 -07:00
|
|
|
gpu->InvalidateCache(displaybuf, displaybufSize, GPU_INVALIDATE_SAFE);
|
|
|
|
}
|
2013-06-08 00:27:31 +08:00
|
|
|
psmfplayer->psmfPlayerAvcAu.pts = psmfplayer->mediaengine->getVideoTimeStamp();
|
2013-06-02 01:30:51 +08:00
|
|
|
Memory::Write_U32(psmfplayer->psmfPlayerAvcAu.pts, videoDataAddr + 8);
|
|
|
|
}
|
2013-06-10 01:07:43 +08:00
|
|
|
|
2013-06-27 23:46:26 +08:00
|
|
|
_PsmfPlayerFillRingbuffer(psmfplayer);
|
2013-10-19 14:02:47 -07:00
|
|
|
int ret = psmfplayer->mediaengine->IsVideoEnd() ? (int)ERROR_PSMFPLAYER_NO_MORE_DATA : 0;
|
2013-06-10 01:07:43 +08:00
|
|
|
|
2014-02-12 23:32:05 +08:00
|
|
|
DEBUG_LOG(ME, "%08x=scePsmfPlayerGetVideoData(%08x, %08x)", ret, psmfPlayer, videoDataAddr);
|
2013-06-08 00:27:31 +08:00
|
|
|
s64 deltapts = psmfplayer->mediaengine->getVideoTimeStamp() - psmfplayer->mediaengine->getAudioTimeStamp();
|
|
|
|
int delaytime = 3000;
|
2013-07-02 17:20:46 +08:00
|
|
|
if (deltapts > 0 && !psmfplayer->mediaengine->IsNoAudioData())
|
2013-06-08 00:27:31 +08:00
|
|
|
delaytime = deltapts * 1000000 / 90000;
|
2013-06-10 01:07:43 +08:00
|
|
|
if (!ret)
|
|
|
|
return hleDelayResult(ret, "psmfPlayer video decode", delaytime);
|
|
|
|
else
|
|
|
|
return hleDelayResult(ret, "psmfPlayer all data decoded", 3000);
|
2013-03-29 00:54:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int scePsmfPlayerGetAudioData(u32 psmfPlayer, u32 audioDataAddr)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetAudioData(%08x, %08x): invalid psmf player", psmfPlayer, audioDataAddr);
|
2013-03-29 00:54:04 -07:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2014-02-14 10:19:38 +08:00
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
|
|
|
if (!isInitialized) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetAudioData(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:55:46 +08:00
|
|
|
bool psmfplayerstatus = isPlayingStatus(psmfplayer->status);
|
|
|
|
if (!psmfplayerstatus) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetAudioData(%08x): psmf not playing", psmfPlayer);
|
|
|
|
return ERROR_PSMF_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
2014-02-14 10:43:53 +08:00
|
|
|
if (psmfplayer->playMode == PSMF_PLAYER_MODE_PAUSE) {
|
|
|
|
INFO_LOG(HLE, "scePsmfPlayerGetAudioData(%08x): paused mode", psmfPlayer);
|
2014-02-15 17:49:35 +08:00
|
|
|
// Clear the audio when paused.
|
2014-02-15 18:37:34 +08:00
|
|
|
if (Memory::IsValidAddress(audioDataAddr)) {
|
|
|
|
Memory::Memset(audioDataAddr, 0, audioSamplesBytes);
|
|
|
|
}
|
2014-02-14 10:43:53 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2014-02-15 18:07:19 +08:00
|
|
|
|
2014-02-15 18:37:34 +08:00
|
|
|
if (Memory::IsValidAddress(audioDataAddr)) {
|
|
|
|
psmfplayer->mediaengine->getAudioSamples(audioDataAddr);
|
|
|
|
}
|
2014-02-15 18:15:44 +08:00
|
|
|
|
2013-10-19 14:02:47 -07:00
|
|
|
int ret = psmfplayer->mediaengine->IsNoAudioData() ? (int)ERROR_PSMFPLAYER_NO_MORE_DATA : 0;
|
2014-02-12 23:32:05 +08:00
|
|
|
DEBUG_LOG(ME, "%08x=scePsmfPlayerGetAudioData(%08x, %08x)", ret, psmfPlayer, audioDataAddr);
|
2013-06-10 01:07:43 +08:00
|
|
|
return hleDelayResult(ret, "psmfPlayer audio decode", 3000);
|
2013-03-29 00:54:04 -07:00
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
int scePsmfPlayerGetCurrentStatus(u32 psmfPlayer)
|
|
|
|
{
|
2013-03-06 00:50:42 -08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-12-19 00:18:29 -08:00
|
|
|
// Mana Khemia and other games call this even when not necessary.
|
|
|
|
// It's annoying so the logging is verbose'd out.
|
|
|
|
VERBOSE_LOG(ME, "scePsmfPlayerGetCurrentStatus(%08x): invalid psmf player", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-03-06 00:50:42 -08:00
|
|
|
}
|
2014-02-14 10:19:38 +08:00
|
|
|
|
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
|
|
|
if (!isInitialized) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetCurrentStatus(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "%d=scePsmfPlayerGetCurrentStatus(%08x)", psmfplayer->status, psmfPlayer);
|
2013-03-06 01:00:26 -08:00
|
|
|
return psmfplayer->status;
|
2013-01-06 22:15:47 -08:00
|
|
|
}
|
2012-11-07 19:10:52 +01:00
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
u32 scePsmfPlayerGetCurrentPts(u32 psmfPlayer, u32 currentPtsAddr)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x, %08x): invalid psmf player", psmfPlayer, currentPtsAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2014-02-05 22:33:44 +08:00
|
|
|
|
2014-02-14 10:19:38 +08:00
|
|
|
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
2014-02-15 18:07:19 +08:00
|
|
|
if (!isInitialized || psmfplayer->status < PSMF_PLAYER_STATUS_STANDBY) {
|
2014-02-14 10:19:38 +08:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x): not initialized", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x, %08x)", psmfPlayer, currentPtsAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
|
|
|
|
if (Memory::IsValidAddress(currentPtsAddr)) {
|
2013-06-10 01:07:43 +08:00
|
|
|
Memory::Write_U32(psmfplayer->psmfPlayerAvcAu.pts, currentPtsAddr);
|
2013-04-28 07:41:40 +08:00
|
|
|
}
|
2013-01-18 18:05:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerGetPsmfInfo(u32 psmfPlayer, u32 psmfInfoAddr)
|
|
|
|
{
|
2014-04-20 13:48:45 -07:00
|
|
|
auto info = PSPPointer<PsmfInfo>::Create(psmfInfoAddr);
|
|
|
|
if (!Memory::IsValidAddress(psmfPlayer) || !info.IsValid()) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetPsmfInfo(%08x, %08x): invalid addresses", psmfPlayer, psmfInfoAddr);
|
|
|
|
// PSP would crash.
|
|
|
|
return SCE_KERNEL_ERROR_ILLEGAL_ADDRESS;
|
|
|
|
}
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetPsmfInfo(%08x, %08x): invalid psmf player", psmfPlayer, psmfInfoAddr);
|
2014-04-20 13:48:45 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-04-20 13:48:45 -07:00
|
|
|
if (psmfplayer->status < PSMF_PLAYER_STATUS_STANDBY) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetPsmfInfo(%08x): psmf not set yet", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2013-09-07 22:02:55 +02:00
|
|
|
DEBUG_LOG(ME, "scePsmfPlayerGetPsmfInfo(%08x, %08x)", psmfPlayer, psmfInfoAddr);
|
2014-04-20 13:48:45 -07:00
|
|
|
info->lengthTS = psmfplayer->psmfPlayerLastTimestamp - 3003;
|
|
|
|
info->numVideoStreams = psmfplayer->totalVideoStreams;
|
|
|
|
info->numAudioStreams = psmfplayer->totalAudioStreams;
|
|
|
|
// pcm stream num?
|
|
|
|
info->numPCMStreams = 0;
|
|
|
|
info->playerVersion = psmfplayer->playerVersion;
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerGetCurrentPlayMode(u32 psmfPlayer, u32 playModeAddr, u32 playSpeedAddr)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetCurrentPlayMode(%08x, %08x, %08x): invalid psmf player", psmfPlayer, playModeAddr, playSpeedAddr);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-04-25 20:30:05 -07:00
|
|
|
DEBUG_LOG(ME, "scePsmfPlayerGetCurrentPlayMode(%08x, %08x, %08x)", psmfPlayer, playModeAddr, playSpeedAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
if (Memory::IsValidAddress(playModeAddr)) {
|
2014-02-05 22:33:44 +08:00
|
|
|
Memory::Write_U32(psmfplayer->playMode, playModeAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
if (Memory::IsValidAddress(playSpeedAddr)) {
|
2014-02-05 22:33:44 +08:00
|
|
|
Memory::Write_U32(psmfplayer->playSpeed, playSpeedAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerGetCurrentVideoStream(u32 psmfPlayer, u32 videoCodecAddr, u32 videoStreamNumAddr)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetCurrentVideoStream(%08x, %08x, %08x): invalid psmf player", psmfPlayer, videoCodecAddr, videoStreamNumAddr);
|
2014-04-20 20:21:37 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-04-20 20:21:37 -07:00
|
|
|
if (psmfplayer->status == PSMF_PLAYER_STATUS_INIT) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetCurrentVideoStream(%08x): psmf not yet set", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-04-20 20:21:37 -07:00
|
|
|
DEBUG_LOG(ME, "scePsmfPlayerGetCurrentVideoStream(%08x, %08x, %08x)", psmfPlayer, videoCodecAddr, videoStreamNumAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
if (Memory::IsValidAddress(videoCodecAddr)) {
|
2014-04-20 20:21:37 -07:00
|
|
|
Memory::Write_U32(psmfplayer->videoCodec == 0x0E ? 0 : psmfplayer->videoCodec, videoCodecAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
if (Memory::IsValidAddress(videoStreamNumAddr)) {
|
2014-04-20 20:21:37 -07:00
|
|
|
Memory::Write_U32(psmfplayer->videoStreamNum, videoStreamNumAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerGetCurrentAudioStream(u32 psmfPlayer, u32 audioCodecAddr, u32 audioStreamNumAddr)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetCurrentAudioStream(%08x, %08x, %08x): invalid psmf player", psmfPlayer, audioCodecAddr, audioStreamNumAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
return ERROR_PSMF_NOT_FOUND;
|
|
|
|
}
|
2014-04-20 20:21:37 -07:00
|
|
|
if (psmfplayer->status == PSMF_PLAYER_STATUS_INIT) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerGetCurrentVideoStream(%08x): psmf not yet set", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-04-20 20:21:37 -07:00
|
|
|
DEBUG_LOG(ME, "scePsmfPlayerGetCurrentAudioStream(%08x, %08x, %08x)", psmfPlayer, audioCodecAddr, audioStreamNumAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
if (Memory::IsValidAddress(audioCodecAddr)) {
|
2014-04-20 20:21:37 -07:00
|
|
|
Memory::Write_U32(psmfplayer->audioCodec == 0x0F ? 1 : psmfplayer->audioCodec, audioCodecAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
if (Memory::IsValidAddress(audioStreamNumAddr)) {
|
2014-04-20 20:21:37 -07:00
|
|
|
Memory::Write_U32(psmfplayer->audioStreamNum, audioStreamNumAddr);
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-03-12 11:54:52 +08:00
|
|
|
int scePsmfPlayerSetTempBuf(u32 psmfPlayer, u32 tempBufAddr, u32 tempBufSize)
|
2013-01-18 18:05:51 +08:00
|
|
|
{
|
2013-03-06 01:00:26 -08:00
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
2014-02-05 22:33:44 +08:00
|
|
|
if (!psmfplayer) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSetTempBuf(%08x, %08x, %08x): invalid psmf player", psmfPlayer, tempBufAddr, tempBufSize);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-06-16 03:27:14 +08:00
|
|
|
}
|
2014-04-20 08:17:56 -07:00
|
|
|
if (psmfplayer->status != PSMF_PLAYER_STATUS_INIT) {
|
2014-04-20 08:45:40 -07:00
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSetTempBuf(%08x, %08x, %08x): invalid status %x", psmfPlayer, tempBufAddr, tempBufSize, psmfplayer->status);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
|
|
|
}
|
|
|
|
if (tempBufSize < 0x00010000) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSetTempBuf(%08x, %08x, %08x): buffer too small", psmfPlayer, tempBufAddr, tempBufSize);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_PARAM;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:33:44 +08:00
|
|
|
INFO_LOG(ME, "scePsmfPlayerSetTempBuf(%08x, %08x, %08x)", psmfPlayer, tempBufAddr, tempBufSize);
|
|
|
|
// fake it right now, use tempbuf from memory directly
|
|
|
|
//psmfplayer->tempbuf = tempBufAddr;
|
|
|
|
//psmfplayer->tempbufSize = tempBufSize;
|
|
|
|
|
2013-01-18 18:05:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerChangePlayMode(u32 psmfPlayer, int playMode, int playSpeed)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i): invalid psmf player", psmfPlayer, playMode, playSpeed);
|
2014-04-25 20:30:05 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-04-25 20:30:05 -07:00
|
|
|
if (psmfplayer->status < PSMF_PLAYER_STATUS_PLAYING) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i): not playing yet", psmfPlayer, playMode, playSpeed);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
2014-04-25 20:30:05 -07:00
|
|
|
if (playMode < 0 || playMode > (int)PSMF_PLAYER_MODE_REWIND) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i): invalid mode", psmfPlayer, playMode, playSpeed);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_CONFIG;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (playMode) {
|
|
|
|
case PSMF_PLAYER_MODE_FORWARD:
|
|
|
|
case PSMF_PLAYER_MODE_REWIND:
|
|
|
|
if (psmfplayer->playerVersion == PSMF_PLAYER_VERSION_BASIC) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i): no EP data for FORWARD/REWIND", psmfPlayer, playMode, playSpeed);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
|
|
|
psmfplayer->playSpeed = playSpeed;
|
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i): unsupported playMode", psmfPlayer, playMode, playSpeed);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PSMF_PLAYER_MODE_PLAY:
|
|
|
|
case PSMF_PLAYER_MODE_PAUSE:
|
|
|
|
if (psmfplayer->playSpeed != playSpeed) {
|
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i): play speed not changed", psmfPlayer, playMode, playSpeed);
|
|
|
|
} else {
|
|
|
|
DEBUG_LOG(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i)", psmfPlayer, playMode, playSpeed);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (psmfplayer->playSpeed != playSpeed) {
|
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i): play speed not changed", psmfPlayer, playMode, playSpeed);
|
|
|
|
}
|
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerChangePlayMode(%08x, %i, %i): unsupported playMode", psmfPlayer, playMode, playSpeed);
|
|
|
|
break;
|
|
|
|
}
|
2014-02-14 10:19:38 +08:00
|
|
|
|
2013-03-30 00:42:12 -04:00
|
|
|
psmfplayer->playMode = playMode;
|
2013-01-18 18:05:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerSelectAudio(u32 psmfPlayer)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSelectAudio(%08x): invalid psmf player", psmfPlayer);
|
2014-04-20 23:14:45 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-04-20 23:14:45 -07:00
|
|
|
if (psmfplayer->status != PSMF_PLAYER_STATUS_PLAYING) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSelectAudio(%08x): not playing", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-04-20 23:14:45 -07:00
|
|
|
int next = psmfplayer->audioStreamNum + 1;
|
|
|
|
if (next >= psmfplayer->totalAudioStreams)
|
|
|
|
next = 0;
|
|
|
|
|
|
|
|
if (next == psmfplayer->audioStreamNum || !psmfplayer->mediaengine->setAudioStream(next)) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectAudio(%08x): no stream to switch to", psmfPlayer);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerSelectAudio(%08x)", psmfPlayer);
|
|
|
|
psmfplayer->audioStreamNum = next;
|
2013-01-18 18:05:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerSelectVideo(u32 psmfPlayer)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSelectVideo(%08x): invalid psmf player", psmfPlayer);
|
2014-04-20 23:14:45 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-04-20 23:14:45 -07:00
|
|
|
if (psmfplayer->status != PSMF_PLAYER_STATUS_PLAYING) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSelectVideo(%08x): not playing", psmfPlayer);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
|
|
|
|
2014-04-20 23:14:45 -07:00
|
|
|
int next = psmfplayer->videoStreamNum + 1;
|
|
|
|
if (next >= psmfplayer->totalVideoStreams)
|
|
|
|
next = 0;
|
|
|
|
|
|
|
|
if (next == psmfplayer->videoStreamNum || !psmfplayer->mediaengine->setVideoStream(next)) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectVideo(%08x): no stream to switch to", psmfPlayer);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerSelectVideo(%08x)", psmfPlayer);
|
|
|
|
psmfplayer->videoStreamNum = next;
|
2013-01-18 18:05:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerSelectSpecificVideo(u32 psmfPlayer, int videoCodec, int videoStreamNum)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i): invalid psmf player", psmfPlayer, videoCodec, videoStreamNum);
|
2014-04-20 23:57:32 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-04-20 23:57:32 -07:00
|
|
|
if (psmfplayer->status != PSMF_PLAYER_STATUS_PLAYING) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i): not playing", psmfPlayer, videoCodec, videoStreamNum);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
2014-04-20 23:57:32 -07:00
|
|
|
if (psmfplayer->totalVideoStreams < 2) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i): unable to change stream", psmfPlayer, videoCodec, videoStreamNum);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
|
|
|
if (videoStreamNum < 0 || videoStreamNum >= psmfplayer->totalVideoStreams) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i): bad stream num param", psmfPlayer, videoCodec, videoStreamNum);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_CONFIG;
|
|
|
|
}
|
|
|
|
if (videoCodec != 0x0E && videoCodec != 0x00) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i): invalid codec", psmfPlayer, videoCodec, videoStreamNum);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
|
|
|
if (psmfplayer->totalVideoStreams < 2 || !psmfplayer->mediaengine->setVideoStream(videoStreamNum)) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i): unable to change stream", psmfPlayer, videoCodec, videoStreamNum);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
2014-02-14 10:19:38 +08:00
|
|
|
|
2014-04-20 23:57:32 -07:00
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificVideo(%08x, %i, %i)", psmfPlayer, videoCodec, videoStreamNum);
|
|
|
|
if (psmfplayer->videoStreamNum != videoStreamNum) {
|
|
|
|
hleDelayResult(0, "psmf select video", 100);
|
|
|
|
}
|
2013-03-30 00:42:12 -04:00
|
|
|
psmfplayer->videoCodec = videoCodec;
|
|
|
|
psmfplayer->videoStreamNum = videoStreamNum;
|
2013-01-18 18:05:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-20 23:57:32 -07:00
|
|
|
// WARNING: This function appears to be buggy in most libraries.
|
2013-01-18 18:05:51 +08:00
|
|
|
u32 scePsmfPlayerSelectSpecificAudio(u32 psmfPlayer, int audioCodec, int audioStreamNum)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i): invalid psmf player", psmfPlayer, audioCodec, audioStreamNum);
|
2014-04-20 23:57:32 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
2014-04-20 23:57:32 -07:00
|
|
|
if (psmfplayer->status != PSMF_PLAYER_STATUS_PLAYING) {
|
|
|
|
ERROR_LOG(ME, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i): not playing", psmfPlayer, audioCodec, audioStreamNum);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
2014-04-20 23:57:32 -07:00
|
|
|
if (psmfplayer->totalAudioStreams < 2) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i): unable to change stream", psmfPlayer, audioCodec, audioStreamNum);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
|
|
|
if (audioStreamNum < 0 || audioStreamNum >= psmfplayer->totalAudioStreams) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i): bad stream num param", psmfPlayer, audioCodec, audioStreamNum);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_CONFIG;
|
|
|
|
}
|
|
|
|
if (audioCodec != 0x0F && audioCodec != 0x01) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i): invalid codec", psmfPlayer, audioCodec, audioStreamNum);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
|
|
|
if (psmfplayer->totalAudioStreams < 2 || !psmfplayer->mediaengine->setAudioStream(audioStreamNum)) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i): unable to change stream", psmfPlayer, audioCodec, audioStreamNum);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
|
|
|
}
|
2014-02-14 10:19:38 +08:00
|
|
|
|
2014-04-20 23:57:32 -07:00
|
|
|
WARN_LOG_REPORT(ME, "scePsmfPlayerSelectSpecificAudio(%08x, %i, %i)", psmfPlayer, audioCodec, audioStreamNum);
|
|
|
|
if (psmfplayer->audioStreamNum != audioStreamNum) {
|
|
|
|
hleDelayResult(0, "psmf select audio", 100);
|
|
|
|
}
|
2013-03-30 00:42:12 -04:00
|
|
|
psmfplayer->audioCodec = audioCodec;
|
|
|
|
psmfplayer->audioStreamNum = audioStreamNum;
|
2013-01-18 18:05:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 scePsmfPlayerConfigPlayer(u32 psmfPlayer, int configMode, int configAttr)
|
|
|
|
{
|
|
|
|
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
|
|
|
if (!psmfplayer) {
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG(ME, "scePsmfPlayerConfigPlayer(%08x, %i, %i): invalid psmf player", psmfPlayer, configMode, configAttr);
|
2014-04-20 08:17:56 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
2014-02-14 10:19:38 +08:00
|
|
|
}
|
2014-04-20 19:19:12 -07:00
|
|
|
// This one works in any status as long as it's created.
|
2014-02-14 10:19:38 +08:00
|
|
|
|
2014-02-05 22:33:44 +08:00
|
|
|
switch (configMode) {
|
|
|
|
case PSMF_PLAYER_CONFIG_MODE_LOOP:
|
2014-04-20 19:19:12 -07:00
|
|
|
if (configAttr != 0 && configAttr != 1) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerConfigPlayer(%08x, loop, %i): invalid value", psmfPlayer, configAttr);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_PARAM;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "scePsmfPlayerConfigPlayer(%08x, loop, %i)", psmfPlayer, configAttr);
|
2013-01-18 18:05:51 +08:00
|
|
|
videoLoopStatus = configAttr;
|
2014-02-05 22:33:44 +08:00
|
|
|
break;
|
|
|
|
case PSMF_PLAYER_CONFIG_MODE_PIXEL_TYPE:
|
2014-04-20 19:19:12 -07:00
|
|
|
if (configAttr < -1 || configAttr > 3) {
|
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerConfigPlayer(%08x, pixelType, %i): invalid value", psmfPlayer, configAttr);
|
|
|
|
return ERROR_PSMFPLAYER_INVALID_PARAM;
|
|
|
|
}
|
2013-09-07 22:02:55 +02:00
|
|
|
INFO_LOG(ME, "scePsmfPlayerConfigPlayer(%08x, pixelType, %i)", psmfPlayer, configAttr);
|
2013-06-02 13:52:11 -07:00
|
|
|
// Does -1 mean default or something?
|
|
|
|
if (configAttr != -1) {
|
|
|
|
videoPixelMode = configAttr;
|
2014-04-20 19:19:12 -07:00
|
|
|
} else {
|
|
|
|
// TODO: At least for one video, this was the same as 8888.
|
|
|
|
videoPixelMode = GE_CMODE_32BIT_ABGR8888;
|
2013-06-02 13:52:11 -07:00
|
|
|
}
|
2014-02-05 22:33:44 +08:00
|
|
|
break;
|
|
|
|
default:
|
2013-09-07 22:02:55 +02:00
|
|
|
ERROR_LOG_REPORT(ME, "scePsmfPlayerConfigPlayer(%08x, %i, %i): unknown parameter", psmfPlayer, configMode, configAttr);
|
2014-04-20 19:19:12 -07:00
|
|
|
return ERROR_PSMFPLAYER_INVALID_CONFIG;
|
2013-01-18 18:05:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-01-24 19:40:26 +08:00
|
|
|
const HLEFunction scePsmf[] = {
|
|
|
|
{0xc22c8327, WrapU_UU<scePsmfSetPsmf>, "scePsmfSetPsmf"},
|
|
|
|
{0xC7DB3A5B, WrapU_UUU<scePsmfGetCurrentStreamType>, "scePsmfGetCurrentStreamType"},
|
|
|
|
{0x28240568, WrapU_U<scePsmfGetCurrentStreamNumber>, "scePsmfGetCurrentStreamNumber"},
|
|
|
|
{0x1E6D9013, WrapU_UUU<scePsmfSpecifyStreamWithStreamType>, "scePsmfSpecifyStreamWithStreamType"},
|
|
|
|
{0x0C120E1D, WrapU_UUU<scePsmfSpecifyStreamWithStreamTypeNumber>, "scePsmfSpecifyStreamWithStreamTypeNumber"},
|
2013-03-12 00:17:24 +01:00
|
|
|
{0x4BC9BDE0, WrapU_UI<scePsmfSpecifyStream>, "scePsmfSpecifyStream"},
|
2013-01-24 19:40:26 +08:00
|
|
|
{0x76D3AEBA, WrapU_UU<scePsmfGetPresentationStartTime>, "scePsmfGetPresentationStartTime"},
|
|
|
|
{0xBD8AE0D8, WrapU_UU<scePsmfGetPresentationEndTime>, "scePsmfGetPresentationEndTime"},
|
|
|
|
{0xEAED89CD, WrapU_U<scePsmfGetNumberOfStreams>, "scePsmfGetNumberOfStreams"},
|
|
|
|
{0x7491C438, WrapU_U<scePsmfGetNumberOfEPentries>, "scePsmfGetNumberOfEPentries"},
|
|
|
|
{0x0BA514E5, WrapU_UU<scePsmfGetVideoInfo>, "scePsmfGetVideoInfo"},
|
|
|
|
{0xA83F7113, WrapU_UU<scePsmfGetAudioInfo>, "scePsmfGetAudioInfo"},
|
2013-06-24 18:58:36 +02:00
|
|
|
{0x971A3A90, WrapU_U<scePsmfCheckEPMap>, "scePsmfCheckEPmap"},
|
2013-07-07 18:10:55 -07:00
|
|
|
{0x68d42328, WrapU_UI<scePsmfGetNumberOfSpecificStreams>, "scePsmfGetNumberOfSpecificStreams"},
|
2013-03-29 01:05:11 -07:00
|
|
|
{0x5b70fcc1, WrapU_UU<scePsmfQueryStreamOffset>, "scePsmfQueryStreamOffset"},
|
|
|
|
{0x9553cc91, WrapU_UU<scePsmfQueryStreamSize>, "scePsmfQueryStreamSize"},
|
2013-01-24 19:40:26 +08:00
|
|
|
{0xB78EB9E9, WrapU_UU<scePsmfGetHeaderSize>, "scePsmfGetHeaderSize"},
|
|
|
|
{0xA5EBFE81, WrapU_UU<scePsmfGetStreamSize>, "scePsmfGetStreamSize"},
|
|
|
|
{0xE1283895, WrapU_U<scePsmfGetPsmfVersion>, "scePsmfGetPsmfVersion"},
|
2013-01-29 01:28:51 +01:00
|
|
|
{0x2673646B, WrapU_U<scePsmfVerifyPsmf>, "scePsmfVerifyPsmf"},
|
2013-01-24 19:40:26 +08:00
|
|
|
{0x4E624A34, WrapU_UIU<scePsmfGetEPWithId>, "scePsmfGetEPWithId"},
|
|
|
|
{0x7C0E7AC3, WrapU_UUU<scePsmfGetEPWithTimestamp>, "scePsmfGetEPWithTimestamp"},
|
|
|
|
{0x5F457515, WrapU_UU<scePsmfGetEPidWithTimestamp>, "scePsmfGetEPidWithTimestamp"},
|
2013-12-02 23:36:55 -08:00
|
|
|
{0x43ac7dbb, 0, "scePsmfGetPsmfMark"},
|
|
|
|
{0xde78e9fc, 0, "scePsmfGetNumberOfPsmfMarks"},
|
2013-01-24 19:40:26 +08:00
|
|
|
};
|
|
|
|
|
2012-11-01 16:19:01 +01:00
|
|
|
const HLEFunction scePsmfPlayer[] =
|
|
|
|
{
|
2013-01-06 22:15:47 -08:00
|
|
|
{0x235d8787, WrapI_UU<scePsmfPlayerCreate>, "scePsmfPlayerCreate"},
|
|
|
|
{0x1078c008, WrapI_U<scePsmfPlayerStop>, "scePsmfPlayerStop"},
|
2013-01-18 18:05:51 +08:00
|
|
|
{0x1e57a8e7, WrapU_UII<scePsmfPlayerConfigPlayer>, "scePsmfPlayerConfigPlayer"},
|
2013-01-06 22:15:47 -08:00
|
|
|
{0x2beb1569, WrapI_U<scePsmfPlayerBreak>, "scePsmfPlayerBreak"},
|
|
|
|
{0x3d6d25a9, WrapI_UC<scePsmfPlayerSetPsmf>,"scePsmfPlayerSetPsmf"},
|
|
|
|
{0x58B83577, WrapI_UC<scePsmfPlayerSetPsmfCB>, "scePsmfPlayerSetPsmfCB"},
|
|
|
|
{0x3ea82a4b, WrapI_U<scePsmfPlayerGetAudioOutSize>, "scePsmfPlayerGetAudioOutSize"},
|
2013-01-18 18:05:51 +08:00
|
|
|
{0x3ed62233, WrapU_UU<scePsmfPlayerGetCurrentPts>, "scePsmfPlayerGetCurrentPts"},
|
2013-03-29 00:54:04 -07:00
|
|
|
{0x46f61f8b, WrapI_UU<scePsmfPlayerGetVideoData>, "scePsmfPlayerGetVideoData"},
|
2013-01-18 18:05:51 +08:00
|
|
|
{0x68f07175, WrapU_UUU<scePsmfPlayerGetCurrentAudioStream>, "scePsmfPlayerGetCurrentAudioStream"},
|
|
|
|
{0x75f03fa2, WrapU_UII<scePsmfPlayerSelectSpecificVideo>, "scePsmfPlayerSelectSpecificVideo"},
|
|
|
|
{0x85461eff, WrapU_UII<scePsmfPlayerSelectSpecificAudio>, "scePsmfPlayerSelectSpecificAudio"},
|
|
|
|
{0x8a9ebdcd, WrapU_U<scePsmfPlayerSelectVideo>, "scePsmfPlayerSelectVideo"},
|
|
|
|
{0x95a84ee5, WrapI_UUI<scePsmfPlayerStart>, "scePsmfPlayerStart"},
|
2013-01-06 22:15:47 -08:00
|
|
|
{0x9b71a274, WrapI_U<scePsmfPlayerDelete>, "scePsmfPlayerDelete"},
|
2013-01-18 18:05:51 +08:00
|
|
|
{0x9ff2b2e7, WrapU_UUU<scePsmfPlayerGetCurrentVideoStream>, "scePsmfPlayerGetCurrentVideoStream"},
|
2013-01-06 22:15:47 -08:00
|
|
|
{0xa0b8ca55, WrapI_U<scePsmfPlayerUpdate>, "scePsmfPlayerUpdate"},
|
2013-01-18 18:05:51 +08:00
|
|
|
{0xa3d81169, WrapU_UII<scePsmfPlayerChangePlayMode>, "scePsmfPlayerChangePlayMode"},
|
|
|
|
{0xb8d10c56, WrapU_U<scePsmfPlayerSelectAudio>, "scePsmfPlayerSelectAudio"},
|
2013-03-29 00:54:04 -07:00
|
|
|
{0xb9848a74, WrapI_UU<scePsmfPlayerGetAudioData>, "scePsmfPlayerGetAudioData"},
|
2013-01-18 18:05:51 +08:00
|
|
|
{0xdf089680, WrapU_UU<scePsmfPlayerGetPsmfInfo>, "scePsmfPlayerGetPsmfInfo"},
|
2013-01-06 22:15:47 -08:00
|
|
|
{0xe792cd94, WrapI_U<scePsmfPlayerReleasePsmf>, "scePsmfPlayerReleasePsmf"},
|
2013-01-18 18:05:51 +08:00
|
|
|
{0xf3efaa91, WrapU_UUU<scePsmfPlayerGetCurrentPlayMode>, "scePsmfPlayerGetCurrentPlayMode"},
|
2013-01-06 22:15:47 -08:00
|
|
|
{0xf8ef08a6, WrapI_U<scePsmfPlayerGetCurrentStatus>, "scePsmfPlayerGetCurrentStatus"},
|
2013-03-12 09:51:50 +01:00
|
|
|
{0x2D0E4E0A, WrapI_UUU<scePsmfPlayerSetTempBuf>, "scePsmfPlayerSetTempBuf"},
|
2013-06-18 16:05:15 +08:00
|
|
|
{0x76C0F4AE, WrapI_UCI<scePsmfPlayerSetPsmfOffset>, "scePsmfPlayerSetPsmfOffset"},
|
|
|
|
{0xA72DB4F9, WrapI_UCI<scePsmfPlayerSetPsmfOffsetCB>, "scePsmfPlayerSetPsmfOffsetCB"},
|
2013-06-30 11:40:52 -07:00
|
|
|
{0x340c12cb, 0, "scePsmfPlayer_340C12CB"},
|
2012-11-01 16:19:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
void Register_scePsmf() {
|
2012-12-24 10:44:40 -08:00
|
|
|
RegisterModule("scePsmf",ARRAY_SIZE(scePsmf),scePsmf);
|
2012-11-01 16:19:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Register_scePsmfPlayer() {
|
2012-12-24 10:44:40 -08:00
|
|
|
RegisterModule("scePsmfPlayer",ARRAY_SIZE(scePsmfPlayer),scePsmfPlayer);
|
2012-11-01 16:19:01 +01:00
|
|
|
}
|