コード例 #1
0
ファイル: scePsmf.cpp プロジェクト: Clim15/ppsspp
int scePsmfPlayerCreate(u32 psmfPlayer, u32 psmfPlayerDataAddr) 
{
	WARN_LOG(HLE, "scePsmfPlayerCreate(%08x, %08x)", psmfPlayer, psmfPlayerDataAddr);
	PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
	if (!psmfplayer) {
		// TODO: This is the wrong data.  PsmfPlayer needs a new interface.
		psmfplayer = new PsmfPlayer(psmfPlayerDataAddr);
		psmfPlayerMap[psmfPlayer] = psmfplayer;
	}

	if (Memory::IsValidAddress(psmfPlayerDataAddr)) {
		psmfplayer->displayBuffer = Memory::Read_U32(psmfPlayerDataAddr);          
		psmfplayer->displayBufferSize = Memory::Read_U32(psmfPlayerDataAddr + 4);     
		psmfplayer->playbackThreadPriority = Memory::Read_U32(psmfPlayerDataAddr + 8);
	}

	psmfplayer->psmfMaxAheadTimestamp = getMaxAheadTimestamp(581);
	psmfplayer->status = PSMF_PLAYER_STATUS_INIT;
	return 0;
}
コード例 #2
0
ファイル: sceMpeg.cpp プロジェクト: Chalky2013/ppsspp
int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
{
	MpegContext *ctx = getMpegCtx(mpeg);
	if (!ctx) {
		WARN_LOG(HLE, "sceMpegGetAvcAu(%08x, %08x, %08x, %08x): bad mpeg handle", mpeg, streamId, auAddr, attrAddr);
		return -1;
	}

	SceMpegRingBuffer mpegRingbuffer;
	Memory::ReadStruct(ctx->mpegRingbufferAddr, &mpegRingbuffer);

	SceMpegAu sceAu;
	sceAu.read(auAddr);

	if (mpegRingbuffer.packetsRead == 0 || mpegRingbuffer.packetsFree == mpegRingbuffer.packets) {
		DEBUG_LOG(HLE, "PSP_ERROR_MPEG_NO_DATA=sceMpegGetAvcAu(%08x, %08x, %08x, %08x)", mpeg, streamId, auAddr, attrAddr);
		// TODO: Does this really reschedule?
		return hleDelayResult(PSP_ERROR_MPEG_NO_DATA, "mpeg get avc", mpegDecodeErrorDelayMs);
	}

	auto streamInfo = ctx->streamMap.find(streamId);
	if (streamInfo == ctx->streamMap.end())
	{
		ERROR_LOG(HLE, "sceMpegGetAvcAu - bad stream id %i", streamId);
		return -1;
	}

	if (streamInfo->second.needsReset)
	{
		sceAu.pts = 0;
		streamInfo->second.needsReset = false;
	}

	// Wait for audio if too much ahead
	if (ctx->atracRegistered && (sceAu.pts > sceAu.pts + getMaxAheadTimestamp(mpegRingbuffer)))
	{
		ERROR_LOG(HLE, "sceMpegGetAvcAu - video too much ahead");
		// TODO: Does this really reschedule?
		return hleDelayResult(PSP_ERROR_MPEG_NO_DATA, "mpeg get avc", mpegDecodeErrorDelayMs);
	}

	int result = 0;

	// read the au struct from ram
	// TODO: For now, always checking, since readVideoAu() is stubbed.
	if (!ctx->mediaengine->readVideoAu(&sceAu) || true) {
		// Only return this after the video already ended.
		if (ctx->endOfVideoReached) {
			if (mpegRingbuffer.packetsFree < mpegRingbuffer.packets) {
				mpegRingbuffer.packetsFree = mpegRingbuffer.packets;
				Memory::WriteStruct(ctx->mpegRingbufferAddr, &mpegRingbuffer);
			}
			result = PSP_ERROR_MPEG_NO_DATA;
		}
		if (ctx->mpegLastTimestamp <= 0 || sceAu.pts >= ctx->mpegLastTimestamp) {
			NOTICE_LOG(HLE, "End of video reached");
			ctx->endOfVideoReached = true;
		} else {
			ctx->endOfAudioReached = false;
		}
	}

	// The avcau struct may have been modified by mediaengine, write it back.
	sceAu.write(auAddr);

	if (Memory::IsValidAddress(attrAddr)) {
		Memory::Write_U32(1, attrAddr);
	}

	DEBUG_LOG(HLE, "%x=sceMpegGetAvcAu(%08x, %08x, %08x, %08x)", result, mpeg, streamId, auAddr, attrAddr);
	// TODO: sceMpegGetAvcAu seems to modify esSize, and delay when it's > 1000 or something.
	// There's definitely more to it, but ultimately it seems games should expect it to delay randomly.
	return hleDelayResult(result, "mpeg get avc", 100);
}