コード例 #1
0
void testDecodeVideo() {
	checkpointNext("testDecodeVideo:");

	const int PACKETS_PER_RUN = 24;
	const int MAX_FRAMES = 180;

	void *vbuffer = memalign(64, 512 * 272 * 4);
	void *abuffer;

	SceInt32 atracParamNotTestedYet = 1;
	SceInt32 avcParamNotSureYet = 6;
	// TODO: Possible a struct?  Or wrong?
	SceInt32 decodeParamNotSureYet = 512;

	int j;
	for (j = 0; j < MAX_FRAMES; ++j) {
		checkpointNext("Next frame");

		int freePackets = sceMpegRingbufferAvailableSize((SceMpegRingbuffer *) &g_ringbuffer);
		checkpoint("  sceMpegRingbufferAvailableSize: %d", freePackets);
		int result = sceMpegRingbufferPut((SceMpegRingbuffer *) &g_ringbuffer, PACKETS_PER_RUN, freePackets);
		checkpoint("  sceMpegRingbufferPut: %08x", result);
		freePackets = sceMpegRingbufferAvailableSize((SceMpegRingbuffer *) &g_ringbuffer);
		checkpoint("  sceMpegRingbufferAvailableSize: %d", freePackets);

		result = sceMpegGetAtracAu(&g_mpeg, g_atrac_stream, &g_atrac_au, &abuffer);
		checkpoint("  sceMpegGetAtracAu: %08x (at %08x from %08x)", result, abuffer, g_atracData);
		schedfAu(&g_atrac_au);

		result = sceMpegAtracDecode(&g_mpeg, &g_atrac_au, abuffer, atracParamNotTestedYet);
		checkpoint("  sceMpegAtracDecode: %08x", result);
		schedfAu(&g_atrac_au);

		result = sceMpegGetAvcAu(&g_mpeg, g_avc_stream, &g_avc_au, &avcParamNotSureYet);
		checkpoint("  sceMpegGetAvcAu: %08x (%08x)", result, avcParamNotSureYet);
		schedfAu(&g_avc_au);

		SceInt32 *decodeParamNotSureYetp = &decodeParamNotSureYet;
		result = sceMpegAvcDecode(&g_mpeg, &g_avc_au, 512, &vbuffer, (SceInt32 *) &decodeParamNotSureYetp);
		checkpoint("  sceMpegAvcDecode: %08x (%08x, %08x)", result, decodeParamNotSureYet, decodeParamNotSureYetp);
		schedfAu(&g_avc_au);

		checkpoint(" *** Frame: %d ***", j);
	}

	checkpoint("  sceMpegAvcDecodeFlush: %08x", sceMpegAvcDecodeFlush(&g_mpeg));

	free(vbuffer);
}
コード例 #2
0
ファイル: decoder.cpp プロジェクト: admiz1975/jpcsp
SceInt32 IsRingbufferFull(ReaderThreadData* D)
{
	if(D->m_Status == ReaderThreadData::READER_EOF)
		return 1;

	if(sceMpegRingbufferAvailableSize(D->m_Ringbuffer) > 0)
		return 0;

	return 1;
}
コード例 #3
0
ファイル: decoder.cpp プロジェクト: admiz1975/jpcsp
int T_Decoder(SceSize _args, void *_argp)
{
	int retVal;
	int oldButtons = 0;
	SceCtrlData pad;
#if DEBUG_TIMING
	int start, end;
	char s[200];
#endif

	int iInitAudio = 1;
	SceInt32 iVideoStatus = 0;
	int videoFrameCount = 0;
	int audioFrameCount = 0;

	SceInt32 unknown = 0;

	int iThreadsRunning = 0;

	SceInt32 m_iAudioCurrentTimeStamp = 0;
	SceInt32 m_iVideoCurrentTimeStamp = 0;
	SceInt32 m_iVideoLastTimeStamp = 0;

	DecoderThreadData* D = *((DecoderThreadData**)_argp);

	SceUInt32 m_iLastPacketsWritten = D->Reader->m_Ringbuffer->iUnk1;
	SceInt32  m_iLastPacketsAvailable = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer);

	D->Connector->initConnector();

	for(;;)
	{
		sceKernelDelayThread(1);

		scePowerTick(0);

		sceCtrlReadBufferPositive(&pad, 1);
		int buttonDown = (oldButtons ^ pad.Buttons) & pad.Buttons;

		if (buttonDown & PSP_CTRL_CIRCLE)
		{
			break;
		}

		if( iThreadsRunning == 0 &&
			IsRingbufferFull(D->Reader) &&
			D->Video->m_iNumBuffers == D->Video->m_iFullBuffers)
		{
			iThreadsRunning = 1;
			sceKernelSignalSema(D->Video->m_SemaphoreStart, 1);
			sceKernelSignalSema(D->Audio->m_SemaphoreStart, 1);
		}

		if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
		{
			break;
		}
		else if(D->Reader->m_Status == ReaderThreadData::READER_EOF)
		{
			retVal = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer);

			if(retVal == D->Reader->m_RingbufferPackets)
				break;
		}

		if(!IsRingbufferFull(D->Reader))
		{
			sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

			if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
				break;
		}

		if (DEBUG_USERDATA)
		{
			SceInt32 unknown2[2];
			SceUInt32 i;
			unknown2[0] = 0x12345678;
			unknown2[1] = 0xABCDEF98;
			retVal = sceMpegGetUserdataAu(&D->m_Mpeg, D->m_MpegStreamUserdata, D->m_MpegAuUserdata, unknown2);

			u8 *esBuffer = (u8 *) D->m_MpegAuUserdata->iEsBuffer;
			SceUInt32 esSize = D->m_MpegAuUserdata->iAuSize;

			sprintf(s, "sceMpegGetUserdataAu result 0x%08X", retVal);
			debug(s);

			if (retVal == 0)
			{
				sprintf(s, "sceMpegGetUserdataAu unknown[0]=0x%08X, unknown[1]=0x%08X, esBuffer=0x%08X, esSize=0x%X", unknown2[0], unknown2[1], D->m_MpegAuUserdata->iEsBuffer, esSize);
				debug(s);
				debug(D->m_MpegAuUserdata);
				for (i = 0; i < esSize; i += 8)
				{
					sprintf(s, "0x%08X: %02X %02X %02X %02X %02X %02X %02X %02X", D->m_MpegAuUserdata->iEsBuffer + i, esBuffer[i], esBuffer[i+1], esBuffer[i+2], esBuffer[i+3], esBuffer[i+4], esBuffer[i+5], esBuffer[i+6], esBuffer[i+7]);
					debug(s);
				}
			}
		}

		if(D->Audio->m_iFullBuffers < D->Audio->m_iNumBuffers)
		{
#if DEBUG_TIMING
			start = sceKernelGetSystemTimeLow();
#endif
			retVal = sceMpegGetAtracAu(&D->m_Mpeg, D->m_MpegStreamAtrac, D->m_MpegAuAtrac, &unknown);
#if DEBUG_TIMING
			end = sceKernelGetSystemTimeLow();
			sprintf(s, "Duration sceMpegGetAtracAu %d, return %X, presentation timeStamp %d (%d), decode timeStamp %d", end - start, retVal, D->m_MpegAuAtrac->iPts, m_iAudioCurrentTimeStamp + D->m_iAudioFrameDuration, D->m_MpegAuAtrac->iDts);
			debug(s);
			debug(D->m_MpegAuAtrac);
			debug(D->Reader->m_Ringbuffer);
#endif
			if(retVal != 0)
			{
				if(!IsRingbufferFull(D->Reader))
				{
					sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

					if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
						break;
				}
			}
			else
			{
				if(m_iAudioCurrentTimeStamp >= D->m_iLastTimeStamp - D->m_iVideoFrameDuration)
					break;

#if DEBUG_TIMING
				start = sceKernelGetSystemTimeLow();
#endif
				retVal = sceMpegAtracDecode(&D->m_Mpeg, D->m_MpegAuAtrac, D->Audio->m_pAudioBuffer[D->Audio->m_iDecodeBuffer], iInitAudio);
#if DEBUG_TIMING
				end = sceKernelGetSystemTimeLow();
				sprintf(s, "Duration sceMpegAtracDecode %d, return %X", end - start, retVal);
				debug(s);
				debug(D->Reader->m_Ringbuffer);
#endif
				if(retVal != 0)
				{
					sprintf(D->m_LastError, "sceMpegAtracDecode() failed: 0x%08X", retVal);
					break;
				}

				if(D->m_MpegAuAtrac->iPts == 0xFFFFFFFF)
					m_iAudioCurrentTimeStamp += D->m_iAudioFrameDuration;
				else
					m_iAudioCurrentTimeStamp = D->m_MpegAuAtrac->iPts;

				if(m_iAudioCurrentTimeStamp <= 0x15F90 /* video start ts */ - D->m_iAudioFrameDuration)
					iInitAudio = 1;

				D->Audio->m_iBufferTimeStamp[D->Audio->m_iDecodeBuffer] = m_iAudioCurrentTimeStamp;

				if(iInitAudio == 0)
				{
					D->Connector->sendAudioFrame(audioFrameCount, D->Audio->m_pAudioBuffer[D->Audio->m_iDecodeBuffer], D->m_MpegAtracOutSize, m_iAudioCurrentTimeStamp);
					audioFrameCount++;

					sceKernelWaitSema(D->Audio->m_SemaphoreLock, 1, 0);

					D->Audio->m_iFullBuffers++;

					sceKernelSignalSema(D->Audio->m_SemaphoreLock, 1);

					D->Audio->m_iDecodeBuffer = (D->Audio->m_iDecodeBuffer + 1) % D->Audio->m_iNumBuffers;
				}

				iInitAudio = 0;
			}
		}

		if(!IsRingbufferFull(D->Reader))
		{
			sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

			if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
				break;
		}

		if(D->Video->m_iFullBuffers < D->Video->m_iNumBuffers)
		{
#if DEBUG_TIMING
			start = sceKernelGetSystemTimeLow();
#endif
			retVal = sceMpegGetAvcAu(&D->m_Mpeg, D->m_MpegStreamAVC, D->m_MpegAuAVC, &unknown);
#if DEBUG_TIMING
			end = sceKernelGetSystemTimeLow();
			sprintf(s, "Duration sceMpegGetAvcAu %d, return %X, presentation timeStamp %d (%d), decode timeStamp %d", end - start, retVal, D->m_MpegAuAVC->iPts, m_iVideoCurrentTimeStamp + 3004, D->m_MpegAuAVC->iDts);
			debug(s);
			debug(D->m_MpegAuAVC);
			debug(D->Reader->m_Ringbuffer);
#endif
			if((SceUInt32)retVal == 0x80618001)
			{
				if(!IsRingbufferFull(D->Reader))
				{
					sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

					if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
						break;
				}
			}
			else if(retVal != 0)
			{
				sprintf(D->m_LastError, "sceMpegGetAvcAu() failed: 0x%08X", retVal);
				break;
			}
			else
			{
				if(m_iVideoCurrentTimeStamp >= D->m_iLastTimeStamp - D->m_iVideoFrameDuration)
					break;

#if DEBUG_TIMING
				start = sceKernelGetSystemTimeLow();
#endif
				retVal = sceMpegAvcDecode(&D->m_Mpeg, D->m_MpegAuAVC, BUFFER_WIDTH, &D->Video->m_pVideoBuffer[D->Video->m_iPlayBuffer], &iVideoStatus);
#if DEBUG_TIMING
				end = sceKernelGetSystemTimeLow();
				sprintf(s, "Duration sceMpegAvcDecode %d, return %X", end - start, retVal);
				debug(s);
				debug(D->Reader->m_Ringbuffer);
#endif
				if(retVal != 0)
				{
					sprintf(D->m_LastError, "sceMpegAvcDecode() failed: 0x%08X", retVal);
					break;
				}

				if(D->m_MpegAuAVC->iPts == 0xFFFFFFFF)
					m_iVideoCurrentTimeStamp += 0x0BBC;
				else
					m_iVideoCurrentTimeStamp = D->m_MpegAuAVC->iPts;

				if(iVideoStatus == 1)
				{
					SceUInt32 m_iPacketsWritten = D->Reader->m_Ringbuffer->iUnk1;
					SceInt32  m_iPacketsAvailable = sceMpegRingbufferAvailableSize(D->Reader->m_Ringbuffer);

					SceInt32  m_iDeltaPacketsWritten = m_iPacketsWritten - m_iLastPacketsWritten;
					if (m_iDeltaPacketsWritten < 0)
					{
						m_iDeltaPacketsWritten += D->Reader->m_Ringbuffer->iPackets;
					}
					SceInt32 m_iDeltaPacketsAvailable = m_iPacketsAvailable - m_iLastPacketsAvailable;
					SceInt32 m_iConsumedPackets = m_iDeltaPacketsAvailable + m_iDeltaPacketsWritten;

					m_iLastPacketsWritten = m_iPacketsWritten;
					m_iLastPacketsAvailable = m_iPacketsAvailable;

					D->Connector->sendVideoFrame(videoFrameCount, D->Video->m_pVideoBuffer[D->Video->m_iPlayBuffer], m_iVideoCurrentTimeStamp, D->Reader, m_iConsumedPackets);
					videoFrameCount++;

					D->Video->m_iBufferTimeStamp[D->Video->m_iPlayBuffer] = m_iVideoLastTimeStamp;

					sceKernelWaitSema(D->Video->m_SemaphoreLock, 1, 0);

					D->Video->m_iFullBuffers++;

					sceKernelSignalSema(D->Video->m_SemaphoreLock, 1);
				}

				m_iVideoLastTimeStamp = m_iVideoCurrentTimeStamp;
			}
		}

		if(!IsRingbufferFull(D->Reader))
		{
			sceKernelWaitSema(D->Reader->m_Semaphore, 1, 0);

			if(D->Reader->m_Status == ReaderThreadData::READER_ABORT)
				break;
		}

	}

	D->Connector->exitConnector();

	sceKernelSignalSema(D->Audio->m_SemaphoreStart, 1);
	sceKernelSignalSema(D->Video->m_SemaphoreStart, 1);

	D->Reader->m_Status = ReaderThreadData::READER_ABORT;

	D->Audio->m_iAbort = 1;

	while(D->Video->m_iFullBuffers > 0)
	{
		sceKernelWaitSema(D->Video->m_SemaphoreWait, 1, 0);
		sceKernelSignalSema(D->Video->m_SemaphoreLock, 1);
	}

	sceMpegAvcDecodeStop(&D->m_Mpeg, BUFFER_WIDTH, D->Video->m_pVideoBuffer, &iVideoStatus);

	if(iVideoStatus > 0)
	{
		sceKernelWaitSema(D->Video->m_SemaphoreLock, 1, 0);

		D->Video->m_iFullBuffers++;

		sceKernelSignalSema(D->Video->m_SemaphoreLock, 1);
	}

	D->Video->m_iAbort = 1;

	sceMpegFlushAllStream(&D->m_Mpeg);

	sceKernelExitThread(0);

	return 0;
}