mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-28 10:51:06 +00:00
Merge pull request #6073 from unknownbrackets/psmfplayer
Cleanup psmfplayer pts/frame/audio sync, handle start parameters
This commit is contained in:
commit
a127ca8680
@ -49,6 +49,8 @@ const int PSMF_PLAYER_CONFIG_MODE_PIXEL_TYPE = 1;
|
||||
|
||||
const int PSMF_PLAYER_WARMUP_FRAMES = 3;
|
||||
|
||||
static const int VIDEO_FRAME_DURATION_TS = 3003;
|
||||
|
||||
int psmfMaxAheadTimestamp = 40000;
|
||||
int audioSamples = 2048;
|
||||
int audioSamplesBytes = audioSamples * 4;
|
||||
@ -117,7 +119,7 @@ struct PsmfPlayerData {
|
||||
};
|
||||
|
||||
struct PsmfInfo {
|
||||
u32_le lengthTS;
|
||||
u32_le lastFrameTS;
|
||||
s32_le numVideoStreams;
|
||||
s32_le numAudioStreams;
|
||||
s32_le numPCMStreams;
|
||||
@ -217,7 +219,7 @@ public:
|
||||
int audioStreamNum;
|
||||
int playMode;
|
||||
int playSpeed;
|
||||
u64 lastTimestamp;
|
||||
u64 totalDurationTimestamp;
|
||||
|
||||
int displayBuffer;
|
||||
int displayBufferSize;
|
||||
@ -346,7 +348,7 @@ PsmfPlayer::PsmfPlayer(const PsmfPlayerCreateData *data) {
|
||||
audioStreamNum = -1;
|
||||
playMode = 0;
|
||||
playSpeed = 1;
|
||||
lastTimestamp = 0;
|
||||
totalDurationTimestamp = 0;
|
||||
status = PSMF_PLAYER_STATUS_INIT;
|
||||
mediaengine = new MediaEngine;
|
||||
filehandle = 0;
|
||||
@ -356,6 +358,11 @@ PsmfPlayer::PsmfPlayer(const PsmfPlayerCreateData *data) {
|
||||
videoStep = 0;
|
||||
warmUp = 0;
|
||||
|
||||
psmfPlayerAtracAu.dts =-1;
|
||||
psmfPlayerAtracAu.pts = -1;
|
||||
psmfPlayerAvcAu.dts = -1;
|
||||
psmfPlayerAvcAu.pts = -1;
|
||||
|
||||
displayBuffer = data->buffer.ptr;
|
||||
displayBufferSize = data->bufferSize;
|
||||
playbackThreadPriority = data->threadPriority;
|
||||
@ -413,11 +420,11 @@ void PsmfPlayer::DoState(PointerWrap &p) {
|
||||
p.Do(playbackThreadPriority);
|
||||
p.Do(psmfMaxAheadTimestamp);
|
||||
if (s >= 4) {
|
||||
p.Do(lastTimestamp);
|
||||
p.Do(totalDurationTimestamp);
|
||||
} else {
|
||||
long oldTimestamp;
|
||||
p.Do(oldTimestamp);
|
||||
lastTimestamp = oldTimestamp;
|
||||
totalDurationTimestamp = oldTimestamp;
|
||||
}
|
||||
if (s >= 2) {
|
||||
p.Do(totalVideoStreams);
|
||||
@ -1104,13 +1111,13 @@ int _PsmfPlayerSetPsmfOffset(u32 psmfPlayer, const char *filename, int offset, b
|
||||
}
|
||||
// TODO: It seems like it's invalid if there's not at least 1 video stream.
|
||||
|
||||
int mpegoffset = bswap32(*(u32_le *)(buf + PSMF_STREAM_OFFSET_OFFSET));
|
||||
int mpegoffset = *(s32_be *)(buf + PSMF_STREAM_OFFSET_OFFSET);
|
||||
psmfplayer->readSize = size - mpegoffset;
|
||||
psmfplayer->streamSize = bswap32(*(u32_le *)(buf + PSMF_STREAM_SIZE_OFFSET));
|
||||
psmfplayer->streamSize = *(s32_be *)(buf + PSMF_STREAM_SIZE_OFFSET);
|
||||
psmfplayer->fileoffset = offset + mpegoffset;
|
||||
psmfplayer->mediaengine->loadStream(buf, 2048, std::max(2048 * 500, tempbufSize));
|
||||
_PsmfPlayerFillRingbuffer(psmfplayer);
|
||||
psmfplayer->lastTimestamp = psmfplayer->mediaengine->getLastTimeStamp();
|
||||
psmfplayer->totalDurationTimestamp = psmfplayer->mediaengine->getLastTimeStamp();
|
||||
}
|
||||
|
||||
psmfplayer->status = PSMF_PLAYER_STATUS_STANDBY;
|
||||
@ -1186,37 +1193,94 @@ int scePsmfPlayerGetAudioOutSize(u32 psmfPlayer)
|
||||
return audioSamplesBytes;
|
||||
}
|
||||
|
||||
int scePsmfPlayerStart(u32 psmfPlayer, u32 psmfPlayerData, int initPts)
|
||||
int scePsmfPlayerStart(u32 psmfPlayer, u32 psmfPlayerData, int initPts)
|
||||
{
|
||||
WARN_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %08x)", psmfPlayer, psmfPlayerData, initPts);
|
||||
|
||||
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
||||
|
||||
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
||||
if (!isInitialized) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerStart(%08x): not initialized", psmfPlayer);
|
||||
if (!psmfplayer) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %d): invalid psmf player", psmfPlayer, psmfPlayerData, initPts);
|
||||
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
||||
}
|
||||
if (psmfplayer->status == PSMF_PLAYER_STATUS_INIT) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %d): psmf not yet set", psmfPlayer, psmfPlayerData, initPts);
|
||||
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
||||
}
|
||||
|
||||
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;
|
||||
auto playerData = PSPPointer<PsmfPlayerData>::Create(psmfPlayerData);
|
||||
if (!playerData.IsValid()) {
|
||||
// Crashes on a PSP.
|
||||
ERROR_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %d): bad data address", psmfPlayer, psmfPlayerData, initPts);
|
||||
return SCE_KERNEL_ERROR_ILLEGAL_ADDRESS;
|
||||
}
|
||||
if (playerData->playMode < 0 || playerData->playMode > (int)PSMF_PLAYER_MODE_REWIND) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %d): invalid mode", psmfPlayer, psmfPlayerData, initPts);
|
||||
return ERROR_PSMFPLAYER_INVALID_PARAM;
|
||||
}
|
||||
if (initPts >= psmfplayer->mediaengine->getLastTimeStamp()) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %d): pts is outside video", psmfPlayer, psmfPlayerData, initPts);
|
||||
return ERROR_PSMFPLAYER_INVALID_PARAM;
|
||||
}
|
||||
|
||||
psmfplayer->psmfPlayerAtracAu.dts = initPts;
|
||||
psmfplayer->psmfPlayerAtracAu.pts = initPts;
|
||||
psmfplayer->psmfPlayerAvcAu.dts = initPts;
|
||||
psmfplayer->psmfPlayerAvcAu.pts = initPts;
|
||||
if (psmfplayer->totalAudioStreams > 0) {
|
||||
if (playerData->audioCodec != 0x0F && playerData->audioCodec != 0x01) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerStart(%08x, %08x, %d): invalid audio codec %02x", psmfPlayer, psmfPlayerData, initPts, playerData->audioCodec);
|
||||
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
||||
}
|
||||
if (playerData->audioStreamNum >= psmfplayer->totalAudioStreams) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerStart(%08x, %08x, %d): unable to change audio stream to %d", psmfPlayer, psmfPlayerData, initPts, playerData->audioStreamNum);
|
||||
return ERROR_PSMFPLAYER_INVALID_CONFIG;
|
||||
}
|
||||
}
|
||||
if (playerData->videoCodec != 0x0E && playerData->videoCodec != 0x00) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerStart(%08x, %08x, %d): invalid video codec %02x", psmfPlayer, psmfPlayerData, initPts, playerData->videoCodec);
|
||||
return ERROR_PSMFPLAYER_INVALID_STREAM;
|
||||
}
|
||||
if (playerData->videoStreamNum < 0 || playerData->videoStreamNum >= psmfplayer->totalVideoStreams) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerStart(%08x, %08x, %d): unable to change video stream to %d", psmfPlayer, psmfPlayerData, initPts, playerData->videoStreamNum);
|
||||
return ERROR_PSMFPLAYER_INVALID_CONFIG;
|
||||
}
|
||||
|
||||
WARN_LOG(ME, "scePsmfPlayerStart(%08x, %08x, %d)", psmfPlayer, psmfPlayerData, initPts);
|
||||
|
||||
psmfplayer->mediaengine->setVideoStream(playerData->videoStreamNum);
|
||||
psmfplayer->videoCodec = playerData->videoCodec;
|
||||
psmfplayer->videoStreamNum = playerData->videoStreamNum;
|
||||
if (!psmfplayer->mediaengine->IsNoAudioData()) {
|
||||
psmfplayer->mediaengine->setAudioStream(playerData->audioStreamNum);
|
||||
psmfplayer->audioCodec = playerData->audioCodec;
|
||||
psmfplayer->audioStreamNum = playerData->audioStreamNum;
|
||||
}
|
||||
psmfplayer->playMode = playerData->playMode;
|
||||
psmfplayer->playSpeed = playerData->playSpeed;
|
||||
|
||||
// Does not alter current pts, it just catches up when Update()/etc. get there.
|
||||
|
||||
psmfplayer->status = PSMF_PLAYER_STATUS_PLAYING;
|
||||
psmfplayer->warmUp = 0;
|
||||
|
||||
psmfplayer->mediaengine->openContext();
|
||||
if (initPts < psmfplayer->mediaengine->getVideoTimeStamp()) {
|
||||
// When seeking backwards, we just start populating the stream from the start.
|
||||
// There's probably smarter ways, but haven't seen any games actually do this.
|
||||
pspFileSystem.SeekFile(psmfplayer->filehandle, 0, FILEMOVE_BEGIN);
|
||||
|
||||
u8 *buf = psmfplayer->tempbuf;
|
||||
int tempbufSize = (int)sizeof(psmfplayer->tempbuf);
|
||||
int size = (int)pspFileSystem.ReadFile(psmfplayer->filehandle, buf, 2048);
|
||||
psmfplayer->mediaengine->loadStream(buf, 2048, std::max(2048 * 500, tempbufSize));
|
||||
|
||||
int mpegoffset = *(s32_be *)(buf + PSMF_STREAM_OFFSET_OFFSET);
|
||||
psmfplayer->readSize = size - mpegoffset;
|
||||
psmfplayer->readSize = 0;
|
||||
|
||||
_PsmfPlayerFillRingbuffer(psmfplayer);
|
||||
}
|
||||
// TODO: It would be better to spread this out into the Update() calls.
|
||||
while (!psmfplayer->mediaengine->seekTo(initPts, videoPixelMode)) {
|
||||
_PsmfPlayerFillRingbuffer(psmfplayer);
|
||||
if (psmfplayer->mediaengine->IsVideoEnd()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1292,6 +1356,14 @@ int scePsmfPlayerReleasePsmf(u32 psmfPlayer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __PsmfUpdatePts(PsmfPlayer *psmfplayer, PsmfVideoData *videoData) {
|
||||
// getVideoTimestamp() includes the frame duration, remove it for this frame's pts.
|
||||
psmfplayer->psmfPlayerAvcAu.pts = psmfplayer->mediaengine->getVideoTimeStamp() - VIDEO_FRAME_DURATION_TS;
|
||||
if (videoData) {
|
||||
videoData->displaypts = (u32)psmfplayer->psmfPlayerAvcAu.pts;
|
||||
}
|
||||
}
|
||||
|
||||
int scePsmfPlayerGetVideoData(u32 psmfPlayer, u32 videoDataAddr)
|
||||
{
|
||||
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
||||
@ -1333,16 +1405,21 @@ int scePsmfPlayerGetVideoData(u32 psmfPlayer, u32 videoDataAddr)
|
||||
auto videoData = PSPPointer<PsmfVideoData>::Create(videoDataAddr);
|
||||
if (videoData.IsValid()) {
|
||||
if (!psmfplayer->mediaengine->IsNoAudioData()) {
|
||||
const s64 deltapts = psmfplayer->mediaengine->getVideoTimeStamp() - psmfplayer->mediaengine->getAudioTimeStamp();
|
||||
s64 deltapts = psmfplayer->mediaengine->getVideoTimeStamp() - psmfplayer->mediaengine->getAudioTimeStamp();
|
||||
if (deltapts > 0) {
|
||||
// Don't advance, just return the same frame again.
|
||||
// TODO: This also seems somewhat based on Update() calls, but audio is involved too...
|
||||
int displaybufSize = psmfplayer->mediaengine->writeVideoImage(videoData->displaybuf, videoData->frameWidth, videoPixelMode);
|
||||
// Need to invalidate, even if it didn't change, to trigger upload to framebuffer.
|
||||
gpu->InvalidateCache(videoData->displaybuf, displaybufSize, GPU_INVALIDATE_SAFE);
|
||||
psmfplayer->psmfPlayerAvcAu.pts = psmfplayer->mediaengine->getVideoTimeStamp();
|
||||
videoData->displaypts = (u32)psmfplayer->psmfPlayerAvcAu.pts;
|
||||
__PsmfUpdatePts(psmfplayer, videoData);
|
||||
return hleDelayResult(0, "psmfPlayer behind audio", 3000);
|
||||
} else {
|
||||
// This is an approximation, it should allow a certain amount ahead before skipping frames.
|
||||
while (deltapts <= -(VIDEO_FRAME_DURATION_TS * 5)) {
|
||||
psmfplayer->mediaengine->stepVideo(videoPixelMode);
|
||||
deltapts = psmfplayer->mediaengine->getVideoTimeStamp() - psmfplayer->mediaengine->getAudioTimeStamp();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No audio, based on Update() calls. playSpeed doesn't seem to matter?
|
||||
@ -1358,8 +1435,7 @@ int scePsmfPlayerGetVideoData(u32 psmfPlayer, u32 videoDataAddr)
|
||||
int displaybufSize = psmfplayer->mediaengine->writeVideoImage(videoData->displaybuf, videoData->frameWidth, videoPixelMode);
|
||||
gpu->InvalidateCache(videoData->displaybuf, displaybufSize, GPU_INVALIDATE_SAFE);
|
||||
}
|
||||
psmfplayer->psmfPlayerAvcAu.pts = psmfplayer->mediaengine->getVideoTimeStamp();
|
||||
videoData->displaypts = (u32)psmfplayer->psmfPlayerAvcAu.pts;
|
||||
__PsmfUpdatePts(psmfplayer, videoData);
|
||||
}
|
||||
|
||||
_PsmfPlayerFillRingbuffer(psmfplayer);
|
||||
@ -1448,20 +1524,21 @@ u32 scePsmfPlayerGetCurrentPts(u32 psmfPlayer, u32 currentPtsAddr)
|
||||
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
||||
if (!psmfplayer) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x, %08x): invalid psmf player", psmfPlayer, currentPtsAddr);
|
||||
return ERROR_PSMF_NOT_FOUND;
|
||||
}
|
||||
|
||||
bool isInitialized = isInitializedStatus(psmfplayer->status);
|
||||
if (!isInitialized || psmfplayer->status < PSMF_PLAYER_STATUS_STANDBY) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x): not initialized", psmfPlayer);
|
||||
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
||||
}
|
||||
if (psmfplayer->status < PSMF_PLAYER_STATUS_STANDBY) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x, %08x): not initialized", psmfPlayer, currentPtsAddr);
|
||||
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
||||
}
|
||||
if (psmfplayer->psmfPlayerAvcAu.pts < 0) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x, %08x): no frame yet", psmfPlayer, currentPtsAddr);
|
||||
return ERROR_PSMFPLAYER_NO_MORE_DATA;
|
||||
}
|
||||
|
||||
DEBUG_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x, %08x)", psmfPlayer, currentPtsAddr);
|
||||
|
||||
if (Memory::IsValidAddress(currentPtsAddr)) {
|
||||
Memory::Write_U32(psmfplayer->psmfPlayerAvcAu.pts, currentPtsAddr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1485,7 +1562,8 @@ u32 scePsmfPlayerGetPsmfInfo(u32 psmfPlayer, u32 psmfInfoAddr)
|
||||
}
|
||||
|
||||
DEBUG_LOG(ME, "scePsmfPlayerGetPsmfInfo(%08x, %08x)", psmfPlayer, psmfInfoAddr);
|
||||
info->lengthTS = psmfplayer->lastTimestamp - 3003;
|
||||
// The first frame is at 0, so subtract one frame's duration to get the last frame's timestamp.
|
||||
info->lastFrameTS = psmfplayer->totalDurationTimestamp - VIDEO_FRAME_DURATION_TS;
|
||||
info->numVideoStreams = psmfplayer->totalVideoStreams;
|
||||
info->numAudioStreams = psmfplayer->totalAudioStreams;
|
||||
// pcm stream num?
|
||||
@ -1540,7 +1618,7 @@ u32 scePsmfPlayerGetCurrentAudioStream(u32 psmfPlayer, u32 audioCodecAddr, u32 a
|
||||
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
||||
if (!psmfplayer) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerGetCurrentAudioStream(%08x, %08x, %08x): invalid psmf player", psmfPlayer, audioCodecAddr, audioStreamNumAddr);
|
||||
return ERROR_PSMF_NOT_FOUND;
|
||||
return ERROR_PSMFPLAYER_INVALID_STATUS;
|
||||
}
|
||||
if (psmfplayer->status == PSMF_PLAYER_STATUS_INIT) {
|
||||
ERROR_LOG(ME, "scePsmfPlayerGetCurrentVideoStream(%08x): psmf not yet set", psmfPlayer);
|
||||
|
@ -359,6 +359,28 @@ int MediaEngine::addStreamData(u8* buffer, int addSize) {
|
||||
return size;
|
||||
}
|
||||
|
||||
bool MediaEngine::seekTo(s64 timestamp, int videoPixelMode) {
|
||||
if (timestamp <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Just doing it the not so great way to be sure audio is in sync.
|
||||
int timeout = 1000;
|
||||
while (getVideoTimeStamp() < timestamp - 3003) {
|
||||
if (getAudioTimeStamp() < getVideoTimeStamp()) {
|
||||
getNextAudioFrame(NULL, NULL, NULL);
|
||||
}
|
||||
if (!stepVideo(videoPixelMode)) {
|
||||
return false;
|
||||
}
|
||||
if (--timeout <= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MediaEngine::setVideoStream(int streamNum, bool force) {
|
||||
if (m_videoStream == streamNum && !force) {
|
||||
// Yay, nothing to do.
|
||||
@ -656,7 +678,7 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
|
||||
data += m_desWidth * sizeof(u32);
|
||||
imgbuf += frameWidth * sizeof(u32);
|
||||
#ifndef MOBILE_DEVICE
|
||||
CBreakPoints::ExecMemCheck(bufferPtr + frameWidth * sizeof(u32), true, width * sizeof(u32), currentMIPS->pc);
|
||||
CBreakPoints::ExecMemCheck(bufferPtr + y * frameWidth * sizeof(u32), true, width * sizeof(u32), currentMIPS->pc);
|
||||
#endif
|
||||
}
|
||||
videoImageSize = frameWidth * sizeof(u32) * m_desHeight;
|
||||
@ -669,7 +691,7 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
|
||||
data += m_desWidth * sizeof(u16);
|
||||
imgbuf += frameWidth * sizeof(u16);
|
||||
#ifndef MOBILE_DEVICE
|
||||
CBreakPoints::ExecMemCheck(bufferPtr + frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
|
||||
CBreakPoints::ExecMemCheck(bufferPtr + y * frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
|
||||
#endif
|
||||
}
|
||||
videoImageSize = frameWidth * sizeof(u16) * m_desHeight;
|
||||
@ -682,7 +704,7 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
|
||||
data += m_desWidth * sizeof(u16);
|
||||
imgbuf += frameWidth * sizeof(u16);
|
||||
#ifndef MOBILE_DEVICE
|
||||
CBreakPoints::ExecMemCheck(bufferPtr + frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
|
||||
CBreakPoints::ExecMemCheck(bufferPtr + y * frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
|
||||
#endif
|
||||
}
|
||||
videoImageSize = frameWidth * sizeof(u16) * m_desHeight;
|
||||
@ -695,7 +717,7 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
|
||||
data += m_desWidth * sizeof(u16);
|
||||
imgbuf += frameWidth * sizeof(u16);
|
||||
#ifndef MOBILE_DEVICE
|
||||
CBreakPoints::ExecMemCheck(bufferPtr + frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
|
||||
CBreakPoints::ExecMemCheck(bufferPtr + y * frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
|
||||
#endif
|
||||
}
|
||||
videoImageSize = frameWidth * sizeof(u16) * m_desHeight;
|
||||
@ -733,6 +755,16 @@ int MediaEngine::getAudioRemainSize() {
|
||||
return m_demux->getRemainSize();
|
||||
}
|
||||
|
||||
int MediaEngine::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2) {
|
||||
// When getting a frame, increment pts
|
||||
m_audiopts += 4180;
|
||||
|
||||
// Demux now (rather than on add data) so that we select the right stream.
|
||||
m_demux->demux(m_audioStream);
|
||||
|
||||
return m_demux->getNextAudioFrame(buf, headerCode1, headerCode2);
|
||||
}
|
||||
|
||||
int MediaEngine::getAudioSamples(u32 bufferPtr) {
|
||||
if (!Memory::IsValidAddress(bufferPtr)) {
|
||||
ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr);
|
||||
@ -743,15 +775,9 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When getting a frame, increment pts
|
||||
m_audiopts += 4180;
|
||||
|
||||
// Demux now (rather than on add data) so that we select the right stream.
|
||||
m_demux->demux(m_audioStream);
|
||||
|
||||
u8 *audioFrame = 0;
|
||||
int headerCode1, headerCode2;
|
||||
int frameSize = m_demux->getNextAudioFrame(&audioFrame, &headerCode1, &headerCode2);
|
||||
int frameSize = getNextAudioFrame(&audioFrame, &headerCode1, &headerCode2);
|
||||
if (frameSize == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
|
||||
// Returns number of packets actually added. I guess the buffer might be full.
|
||||
int addStreamData(u8* buffer, int addSize);
|
||||
bool seekTo(s64 timestamp, int videoPixelMode);
|
||||
|
||||
bool setVideoStream(int streamNum, bool force = false);
|
||||
// TODO: Return false if the stream doesn't exist.
|
||||
@ -93,6 +94,7 @@ public:
|
||||
|
||||
private:
|
||||
void updateSwsFormat(int videoPixelMode);
|
||||
int getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2);
|
||||
|
||||
public: // TODO: Very little of this below should be public.
|
||||
|
||||
|
@ -248,7 +248,9 @@ int MpegDemux::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2)
|
||||
audioPos = gotsize;
|
||||
}
|
||||
m_audioStream.pop_front(0, audioPos);
|
||||
*buf = m_audioFrame + 8;
|
||||
if (buf) {
|
||||
*buf = m_audioFrame + 8;
|
||||
}
|
||||
return frameSize - 8;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user