Skip to content

Commit 87f3cf5

Browse files
committed
Merge pull request #8793 from unknownbrackets/psmf
Correct some scePsmf info retrieval funcs and error handling
2 parents cab2c29 + 91887ad commit 87f3cf5

File tree

1 file changed

+125
-83
lines changed

1 file changed

+125
-83
lines changed

Core/HLE/scePsmf.cpp

+125-83
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,12 @@ class Psmf {
161161
void DoState(PointerWrap &p);
162162

163163
bool isValidCurrentStreamNumber() const {
164-
return currentStreamNum >= 0 && currentStreamNum < (int)streamMap.size(); // urgh, checking size isn't really right here.
164+
return currentStreamNum >= 0 && streamMap.find(currentStreamNum) != streamMap.end();
165165
}
166166

167-
void setStreamNum(int num);
167+
bool setStreamNum(int num);
168168
bool setStreamWithType(int type, int channel);
169+
bool setStreamWithTypeNumber(int type, int n);
169170

170171
int FindEPWithTimestamp(int pts) const;
171172

@@ -186,6 +187,8 @@ class Psmf {
186187

187188
int numStreams;
188189
int currentStreamNum;
190+
int currentStreamType;
191+
int currentStreamChannel;
189192
int currentAudioStreamNum;
190193
int currentVideoStreamNum;
191194

@@ -312,6 +315,13 @@ class PsmfStream {
312315
INFO_LOG(ME, "PSMF private audio found: id=%02x, privid=%02x, channels=%i, freq=%i", streamId, privateStreamId, psmf->audioChannels, psmf->audioFrequency);
313316
}
314317

318+
bool matchesType(int ty) {
319+
if (ty == PSMF_AUDIO_STREAM) {
320+
return type == PSMF_ATRAC_STREAM || type == PSMF_PCM_STREAM;
321+
}
322+
return type == ty;
323+
}
324+
315325
void DoState(PointerWrap &p) {
316326
auto s = p.Section("PsmfStream", 1);
317327
if (!s)
@@ -343,6 +353,8 @@ Psmf::Psmf(const u8 *ptr, u32 data) {
343353
headerSize = 0x800;
344354

345355
currentStreamNum = -1;
356+
currentStreamType = -1;
357+
currentStreamChannel = -1;
346358
currentAudioStreamNum = -1;
347359
currentVideoStreamNum = -1;
348360

@@ -351,17 +363,26 @@ Psmf::Psmf(const u8 *ptr, u32 data) {
351363
const u8 *const currentStreamAddr = ptr + 0x82 + i * 16;
352364
int streamId = currentStreamAddr[0];
353365
if ((streamId & PSMF_VIDEO_STREAM_ID) == PSMF_VIDEO_STREAM_ID) {
354-
stream = new PsmfStream(PSMF_AVC_STREAM, ++currentVideoStreamNum);
366+
stream = new PsmfStream(PSMF_AVC_STREAM, streamId & 0x0F);
355367
stream->readMPEGVideoStreamParams(currentStreamAddr, ptr, this);
356368
} else if ((streamId & PSMF_AUDIO_STREAM_ID) == PSMF_AUDIO_STREAM_ID) {
357-
stream = new PsmfStream(PSMF_ATRAC_STREAM, ++currentAudioStreamNum);
369+
int type = PSMF_ATRAC_STREAM;
370+
int privateStreamId = currentStreamAddr[1];
371+
if ((privateStreamId & 0xF0) != 0) {
372+
WARN_LOG_REPORT(ME, "Unknown private stream type, assuming PCM: %02x", privateStreamId);
373+
type = PSMF_PCM_STREAM;
374+
}
375+
stream = new PsmfStream(type, privateStreamId & 0x0F);
358376
stream->readPrivateAudioStreamParams(currentStreamAddr, this);
359377
}
360378
if (stream) {
361379
currentStreamNum++;
362380
streamMap[currentStreamNum] = stream;
363381
}
364382
}
383+
384+
// Default to the first stream.
385+
currentStreamNum = 0;
365386
}
366387

367388
Psmf::~Psmf() {
@@ -401,7 +422,7 @@ PsmfPlayer::PsmfPlayer(const PsmfPlayerCreateData *data) {
401422
}
402423

403424
void Psmf::DoState(PointerWrap &p) {
404-
auto s = p.Section("Psmf", 1, 2);
425+
auto s = p.Section("Psmf", 1, 3);
405426
if (!s)
406427
return;
407428

@@ -433,6 +454,18 @@ void Psmf::DoState(PointerWrap &p) {
433454
}
434455

435456
p.Do(streamMap);
457+
if (s >= 3) {
458+
p.Do(currentStreamType);
459+
p.Do(currentStreamChannel);
460+
} else {
461+
currentStreamType = -1;
462+
currentStreamChannel = -1;
463+
auto streamInfo = streamMap.find(currentStreamNum);
464+
if (streamInfo != streamMap.end()) {
465+
currentStreamType = streamInfo->second->type;
466+
currentStreamChannel = streamInfo->second->channel;
467+
}
468+
}
436469
}
437470

438471
void PsmfPlayer::DoState(PointerWrap &p) {
@@ -507,39 +540,55 @@ void PsmfPlayer::DoState(PointerWrap &p) {
507540
}
508541
}
509542

510-
void Psmf::setStreamNum(int num) {
543+
bool Psmf::setStreamNum(int num) {
511544
currentStreamNum = num;
545+
currentStreamType = -1;
546+
currentStreamChannel = -1;
512547
if (!isValidCurrentStreamNumber())
513-
return;
548+
return false;
514549
PsmfStreamMap::iterator iter = streamMap.find(currentStreamNum);
515550
if (iter == streamMap.end())
516-
return;
551+
return false;
517552

553+
// TODO: This information is *probably* only for the scePsmf lookups?
554+
// Not sure if we need to communicate with the media engine.
518555
int type = iter->second->type;
519-
int channel = iter->second->channel;
520556
switch (type) {
521557
case PSMF_AVC_STREAM:
522-
if (currentVideoStreamNum != num) {
523-
// TODO: Tell video mediaengine or something about channel.
524-
currentVideoStreamNum = num;
525-
}
558+
currentVideoStreamNum = num;
526559
break;
527560

528561
case PSMF_ATRAC_STREAM:
529562
case PSMF_PCM_STREAM:
530-
if (currentAudioStreamNum != num) {
531-
// TODO: Tell audio mediaengine or something about channel.
532-
currentAudioStreamNum = num;
533-
}
563+
currentAudioStreamNum = num;
534564
break;
535565
}
566+
567+
currentStreamType = type;
568+
currentStreamChannel = iter->second->channel;
569+
return true;
536570
}
537571

538572
bool Psmf::setStreamWithType(int type, int channel) {
539-
for (PsmfStreamMap::iterator iter = streamMap.begin(); iter != streamMap.end(); ++iter) {
540-
if (iter->second->type == type && iter->second->channel == channel) {
541-
setStreamNum(iter->first);
542-
return true;
573+
for (auto iter : streamMap) {
574+
// Note: this does NOT support PSMF_AUDIO_STREAM.
575+
if (iter.second->type == type && iter.second->channel == channel) {
576+
return setStreamNum(iter.first);
577+
}
578+
}
579+
return false;
580+
}
581+
582+
bool Psmf::setStreamWithTypeNumber(int type, int n) {
583+
for (auto iter : streamMap) {
584+
if (iter.second->matchesType(type)) {
585+
if (n != 0) {
586+
// Keep counting...
587+
n--;
588+
continue;
589+
}
590+
// Okay, this is the one.
591+
return setStreamNum(iter.first);
543592
}
544593
}
545594
return false;
@@ -652,72 +701,67 @@ static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData)
652701
return 0;
653702
}
654703

655-
static u32 scePsmfGetNumberOfStreams(u32 psmfStruct)
656-
{
704+
static u32 scePsmfGetNumberOfStreams(u32 psmfStruct) {
657705
Psmf *psmf = getPsmf(psmfStruct);
658706
if (!psmf) {
659-
ERROR_LOG(ME, "scePsmfGetNumberOfStreams(%08x): invalid psmf", psmfStruct);
660-
return ERROR_PSMF_NOT_FOUND;
707+
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
661708
}
662-
DEBUG_LOG(ME, "scePsmfGetNumberOfStreams(%08x)", psmfStruct);
663-
return psmf->numStreams;
709+
return hleLogSuccessI(ME, psmf->numStreams);
664710
}
665711

666-
static u32 scePsmfGetNumberOfSpecificStreams(u32 psmfStruct, int streamType)
667-
{
712+
static u32 scePsmfGetNumberOfSpecificStreams(u32 psmfStruct, int streamType) {
668713
Psmf *psmf = getPsmf(psmfStruct);
669714
if (!psmf) {
670-
ERROR_LOG(ME, "scePsmfGetNumberOfSpecificStreams(%08x, %08x): invalid psmf", psmfStruct, streamType);
671-
return ERROR_PSMF_NOT_FOUND;
715+
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
672716
}
673-
WARN_LOG(ME, "scePsmfGetNumberOfSpecificStreams(%08x, %08x)", psmfStruct, streamType);
717+
674718
int streamNum = 0;
675-
int type = (streamType == PSMF_AUDIO_STREAM ? PSMF_ATRAC_STREAM : streamType);
676-
for (int i = (int)psmf->streamMap.size() - 1; i >= 0; i--) {
677-
if (psmf->streamMap[i]->type == type)
719+
for (auto it : psmf->streamMap) {
720+
bool match = false;
721+
if (it.second->matchesType(streamType)) {
678722
streamNum++;
723+
}
679724
}
680-
return streamNum;
725+
726+
return hleLogSuccessI(ME, streamNum);
681727
}
682728

683-
static u32 scePsmfSpecifyStreamWithStreamType(u32 psmfStruct, u32 streamType, u32 channel)
684-
{
729+
static u32 scePsmfSpecifyStreamWithStreamType(u32 psmfStruct, u32 streamType, u32 channel) {
685730
Psmf *psmf = getPsmf(psmfStruct);
686731
if (!psmf) {
687-
ERROR_LOG(ME, "scePsmfSpecifyStreamWithStreamType(%08x, %08x, %i): invalid psmf", psmfStruct, streamType, channel);
688-
return ERROR_PSMF_NOT_FOUND;
732+
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
689733
}
690-
INFO_LOG(ME, "scePsmfSpecifyStreamWithStreamType(%08x, %08x, %i)", psmfStruct, streamType, channel);
691734
if (!psmf->setStreamWithType(streamType, channel)) {
692-
psmf->setStreamNum(-1);
735+
// An invalid type seems to make the stream number invalid, but retain the old type/channel.
736+
psmf->currentStreamNum = ERROR_PSMF_INVALID_ID;
737+
// Also, returns 0 even when no stream found.
738+
return hleLogWarning(ME, 0, "no stream found");
693739
}
694-
return 0;
740+
return hleLogSuccessI(ME, 0);
695741
}
696742

697-
static u32 scePsmfSpecifyStreamWithStreamTypeNumber(u32 psmfStruct, u32 streamType, u32 typeNum)
698-
{
743+
static u32 scePsmfSpecifyStreamWithStreamTypeNumber(u32 psmfStruct, u32 streamType, u32 typeNum) {
699744
Psmf *psmf = getPsmf(psmfStruct);
700745
if (!psmf) {
701-
ERROR_LOG(ME, "scePsmfSpecifyStreamWithStreamTypeNumber(%08x, %08x, %08x): invalid psmf", psmfStruct, streamType, typeNum);
702-
return ERROR_PSMF_NOT_FOUND;
746+
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
703747
}
704-
INFO_LOG_REPORT(ME, "scePsmfSpecifyStreamWithStreamTypeNumber(%08x, %08x, %08x)", psmfStruct, streamType, typeNum);
705-
// right now typeNum and channel are the same...
706-
if (!psmf->setStreamWithType(streamType, typeNum)) {
707-
psmf->setStreamNum(-1);
748+
if (!psmf->setStreamWithTypeNumber(streamType, typeNum)) {
749+
// Don't update stream, just bail out.
750+
return hleLogWarning(ME, ERROR_PSMF_INVALID_ID, "no stream found");
708751
}
709-
return 0;
752+
return hleLogSuccessI(ME, 0);
710753
}
711754

712755
static u32 scePsmfSpecifyStream(u32 psmfStruct, int streamNum) {
713756
Psmf *psmf = getPsmf(psmfStruct);
714757
if (!psmf) {
715-
ERROR_LOG(ME, "scePsmfSpecifyStream(%08x, %i): invalid psmf", psmfStruct, streamNum);
716-
return ERROR_PSMF_NOT_FOUND;
758+
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
717759
}
718-
INFO_LOG(ME, "scePsmfSpecifyStream(%08x, %i)", psmfStruct, streamNum);
719-
psmf->setStreamNum(streamNum);
720-
return 0;
760+
if (!psmf->setStreamNum(streamNum)) {
761+
psmf->setStreamNum(ERROR_PSMF_NOT_INITIALIZED);
762+
return hleLogWarning(ME, ERROR_PSMF_INVALID_ID, "bad stream id");
763+
}
764+
return hleLogSuccessI(ME, 0);
721765
}
722766

723767
static u32 scePsmfGetVideoInfo(u32 psmfStruct, u32 videoInfoAddr) {
@@ -751,20 +795,19 @@ static u32 scePsmfGetAudioInfo(u32 psmfStruct, u32 audioInfoAddr) {
751795
static u32 scePsmfGetCurrentStreamType(u32 psmfStruct, u32 typeAddr, u32 channelAddr) {
752796
Psmf *psmf = getPsmf(psmfStruct);
753797
if (!psmf) {
754-
ERROR_LOG(ME, "scePsmfGetCurrentStreamType(%08x, %08x, %08x): invalid psmf", psmfStruct, typeAddr, channelAddr);
755-
return ERROR_PSMF_NOT_FOUND;
798+
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
756799
}
757-
INFO_LOG(ME, "scePsmfGetCurrentStreamType(%08x, %08x, %08x)", psmfStruct, typeAddr, channelAddr);
758-
if (Memory::IsValidAddress(typeAddr)) {
759-
u32 type = 0, channel = 0;
760-
if (psmf->streamMap.find(psmf->currentStreamNum) != psmf->streamMap.end())
761-
type = psmf->streamMap[psmf->currentStreamNum]->type;
762-
if (psmf->streamMap.find(psmf->currentStreamNum) != psmf->streamMap.end())
763-
channel = psmf->streamMap[psmf->currentStreamNum]->channel;
764-
Memory::Write_U32(type, typeAddr);
765-
Memory::Write_U32(channel, channelAddr);
800+
if (psmf->currentStreamNum == ERROR_PSMF_NOT_INITIALIZED) {
801+
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "no stream set");
766802
}
767-
return 0;
803+
if (!Memory::IsValidAddress(typeAddr) || !Memory::IsValidAddress(channelAddr)) {
804+
return hleLogError(ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "bad pointers");
805+
}
806+
if (psmf->currentStreamType != -1) {
807+
Memory::Write_U32(psmf->currentStreamType, typeAddr);
808+
Memory::Write_U32(psmf->currentStreamChannel, channelAddr);
809+
}
810+
return hleLogSuccessI(ME, 0);
768811
}
769812

770813
static u32 scePsmfGetStreamSize(u32 psmfStruct, u32 sizeAddr)
@@ -882,16 +925,15 @@ static u32 scePsmfGetPresentationEndTime(u32 psmfStruct, u32 endTimeAddr)
882925
return 0;
883926
}
884927

885-
static u32 scePsmfGetCurrentStreamNumber(u32 psmfStruct)
886-
{
928+
static u32 scePsmfGetCurrentStreamNumber(u32 psmfStruct) {
887929
Psmf *psmf = getPsmf(psmfStruct);
888930
if (!psmf) {
889-
ERROR_LOG(ME, "scePsmfGetCurrentStreamNumber(%08x): invalid psmf", psmfStruct);
890-
return ERROR_PSMF_NOT_FOUND;
931+
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
891932
}
892-
893-
DEBUG_LOG(ME, "scePsmfGetCurrentStreamNumber(%08x)", psmfStruct);
894-
return psmf->currentStreamNum;
933+
if (psmf->currentStreamNum < 0) {
934+
return hleLogError(ME, psmf->currentStreamNum, "invalid stream");
935+
}
936+
return hleLogSuccessI(ME, psmf->currentStreamNum);
895937
}
896938

897939
static u32 scePsmfCheckEPMap(u32 psmfStruct)
@@ -1987,19 +2029,19 @@ static int __PsmfPlayerFinish(u32 psmfPlayer) {
19872029

19882030
const HLEFunction scePsmf[] = {
19892031
{0XC22C8327, &WrapU_UU<scePsmfSetPsmf>, "scePsmfSetPsmf", 'x', "xx" },
1990-
{0XC7DB3A5B, &WrapU_UUU<scePsmfGetCurrentStreamType>, "scePsmfGetCurrentStreamType", 'x', "xxx"},
1991-
{0X28240568, &WrapU_U<scePsmfGetCurrentStreamNumber>, "scePsmfGetCurrentStreamNumber", 'x', "x" },
1992-
{0X1E6D9013, &WrapU_UUU<scePsmfSpecifyStreamWithStreamType>, "scePsmfSpecifyStreamWithStreamType", 'x', "xxx"},
1993-
{0X0C120E1D, &WrapU_UUU<scePsmfSpecifyStreamWithStreamTypeNumber>, "scePsmfSpecifyStreamWithStreamTypeNumber", 'x', "xxx"},
1994-
{0X4BC9BDE0, &WrapU_UI<scePsmfSpecifyStream>, "scePsmfSpecifyStream", 'x', "xi" },
2032+
{0XC7DB3A5B, &WrapU_UUU<scePsmfGetCurrentStreamType>, "scePsmfGetCurrentStreamType", 'i', "xpp"},
2033+
{0X28240568, &WrapU_U<scePsmfGetCurrentStreamNumber>, "scePsmfGetCurrentStreamNumber", 'i', "x" },
2034+
{0X1E6D9013, &WrapU_UUU<scePsmfSpecifyStreamWithStreamType>, "scePsmfSpecifyStreamWithStreamType", 'i', "xii"},
2035+
{0X0C120E1D, &WrapU_UUU<scePsmfSpecifyStreamWithStreamTypeNumber>, "scePsmfSpecifyStreamWithStreamTypeNumber", 'i', "xii"},
2036+
{0X4BC9BDE0, &WrapU_UI<scePsmfSpecifyStream>, "scePsmfSpecifyStream", 'i', "xi" },
19952037
{0X76D3AEBA, &WrapU_UU<scePsmfGetPresentationStartTime>, "scePsmfGetPresentationStartTime", 'x', "xx" },
19962038
{0XBD8AE0D8, &WrapU_UU<scePsmfGetPresentationEndTime>, "scePsmfGetPresentationEndTime", 'x', "xx" },
1997-
{0XEAED89CD, &WrapU_U<scePsmfGetNumberOfStreams>, "scePsmfGetNumberOfStreams", 'x', "x" },
2039+
{0XEAED89CD, &WrapU_U<scePsmfGetNumberOfStreams>, "scePsmfGetNumberOfStreams", 'i', "x" },
19982040
{0X7491C438, &WrapU_U<scePsmfGetNumberOfEPentries>, "scePsmfGetNumberOfEPentries", 'x', "x" },
19992041
{0X0BA514E5, &WrapU_UU<scePsmfGetVideoInfo>, "scePsmfGetVideoInfo", 'x', "xx" },
20002042
{0XA83F7113, &WrapU_UU<scePsmfGetAudioInfo>, "scePsmfGetAudioInfo", 'x', "xx" },
20012043
{0X971A3A90, &WrapU_U<scePsmfCheckEPMap>, "scePsmfCheckEPmap", 'x', "x" },
2002-
{0X68D42328, &WrapU_UI<scePsmfGetNumberOfSpecificStreams>, "scePsmfGetNumberOfSpecificStreams", 'x', "xi" },
2044+
{0X68D42328, &WrapU_UI<scePsmfGetNumberOfSpecificStreams>, "scePsmfGetNumberOfSpecificStreams", 'i', "xi" },
20032045
{0X5B70FCC1, &WrapU_UU<scePsmfQueryStreamOffset>, "scePsmfQueryStreamOffset", 'x', "xx" },
20042046
{0X9553CC91, &WrapU_UU<scePsmfQueryStreamSize>, "scePsmfQueryStreamSize", 'x', "xx" },
20052047
{0XB78EB9E9, &WrapU_UU<scePsmfGetHeaderSize>, "scePsmfGetHeaderSize", 'x', "xx" },

0 commit comments

Comments
 (0)