⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmfplayer.c

📁 psp下pmf文件播放器源码
💻 C
字号:
#include <pspkernel.h>
#include <pspsdk.h>


#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "libmpeg/pspmpeg.h"
#include "pmfplayer.h"

#define printf pspDebugScreenPrintf

char *pmfplayer_GetLastError(PMFPLAYER_STRUCT *p)
{
	return p->m_LastError;
}

void pmfplayer_safe_constructor(PMFPLAYER_STRUCT *p)
{
	p->m_RingbufferData	= NULL;
	p->m_MpegMemData		= NULL;

	p->m_FileHandle		= -1;

	p->m_MpegStreamAVC		= NULL;
	p->m_MpegStreamAtrac	= NULL;

	p->m_pEsBufferAVC		= NULL;
	p->m_pEsBufferAtrac	= NULL;
}

SceInt32 RingbufferCallback(ScePVoid pData, SceInt32 iNumPackets, ScePVoid pParam)
{
	int retVal, iPackets;
	SceUID hFile = *(SceUID*)pParam;

	retVal = sceIoRead(hFile, pData, iNumPackets * 2048);
	if(retVal < 0)
		return -1;

	iPackets = retVal / 2048;

	return iPackets;
}

SceInt32 pmfplayer_initialize(PMFPLAYER_STRUCT *p, SceInt32 nPackets)
{
//	pspDebugScreenInit();
	printf("pmfplayer_initialize\n");	
	pmfplayer_safe_constructor(p);
	
	int retVal = -1;
	p->m_RingbufferPackets = nPackets;
	
//	printf("sceMpegInit addr: 0x%x\n", &sceMpegInit);	
	retVal = sceMpegInit();
//	printf("retval: %d\n", retVal);
	if(retVal != 0)
	{
		sprintf(p->m_LastError, "sceMpegInit() failed: 0x%08X", retVal);
		goto error;
	}

	retVal = sceMpegRingbufferQueryMemSize(p->m_RingbufferPackets);
	if(retVal < 0)
	{
//		printf("sceMpegRingbufferQueryMemSize err\n");
		sprintf(p->m_LastError, "sceMpegRingbufferQueryMemSize(%d) failed: 0x%08X", (int)nPackets, retVal);
		goto finish;
	}
	
	p->m_RingbufferSize = retVal;

	retVal = sceMpegQueryMemSize(0);
	if(retVal < 0)
	{
//		printf("sceMpegQueryMemSize err\n");
		sprintf(p->m_LastError, "sceMpegQueryMemSize() failed: 0x%08X", retVal);
		goto finish;
	}
		
	p->m_MpegMemSize = retVal;

	p->m_RingbufferData = malloc(p->m_RingbufferSize);
	if(p->m_RingbufferData == NULL)
	{
//		printf("malloc err\n");
		sprintf(p->m_LastError, "malloc() failed!");
		goto finish;
	}
	
	p->m_MpegMemData = malloc(p->m_MpegMemSize);
	if(p->m_MpegMemData == NULL)
	{
//		printf("malloc err\n");
		sprintf(p->m_LastError, "malloc() failed!");
		goto freeringbuffer;
	}
	
	retVal = sceMpegRingbufferConstruct(&p->m_Ringbuffer, p->m_RingbufferPackets, p->m_RingbufferData, p->m_RingbufferSize, &RingbufferCallback, &p->m_FileHandle);
	if(retVal != 0)
	{
//		printf("sceMpegRingbufferConstruct err\n");
		sprintf(p->m_LastError, "sceMpegRingbufferConstruct() failed: 0x%08X", retVal);
		goto freempeg;
	}
	
	retVal = sceMpegCreate(&p->m_Mpeg, p->m_MpegMemData, p->m_MpegMemSize, &p->m_Ringbuffer, BUFFER_WIDTH, 0, 0);
	if(retVal != 0)
	{
//		printf("sceMpegCreate err\n");
		sprintf(p->m_LastError, "sceMpegCreate() failed: 0x%08X", retVal);
		goto destroyringbuffer;
	}
	
	SceMpegAvcMode m_MpegAvcMode;
	m_MpegAvcMode.iUnk0 = -1;
	m_MpegAvcMode.iUnk1 = 3;

	sceMpegAvcDecodeMode(&p->m_Mpeg, &m_MpegAvcMode);
	
	return 0;
	
destroyringbuffer:
	sceMpegRingbufferDestruct(&p->m_Ringbuffer);

freempeg:
	free(p->m_MpegMemData);

freeringbuffer:
	free(p->m_RingbufferData);

finish:
	sceMpegFinish();

error:
	return -1;
}

SceInt32 pmfplayer_parseheader(PMFPLAYER_STRUCT *p)
{
	int retVal;
	char pHeader[2048];

	sceIoLseek(p->m_FileHandle, 0, SEEK_SET);

	retVal = sceIoRead(p->m_FileHandle, pHeader, 2048);
	if(retVal < 2048)
	{
		sprintf(p->m_LastError, "sceIoRead() failed!");
		goto error;
	}

	// AHMAN
	if (pHeader[0x81] == 0x01)
		p->m_AudioStreamExist = 0;
	else
		p->m_AudioStreamExist = 1;
	p->m_MovieWidth = ((unsigned int) pHeader[0x8E]) * 0x10;
	p->m_MovieHeight = ((unsigned int) pHeader[0x8F]) * 0x10;

	retVal = sceMpegQueryStreamOffset(&p->m_Mpeg, pHeader, &p->m_MpegStreamOffset);
	if(retVal != 0)
	{
		sprintf(p->m_LastError, "sceMpegQueryStreamOffset() failed: 0x%08X", retVal);
		goto error;
	}

	retVal = sceMpegQueryStreamSize(pHeader, &p->m_MpegStreamSize);
	if(retVal != 0)
	{
		sprintf(p->m_LastError, "sceMpegQueryStreamSize() failed: 0x%08X", retVal);
		goto error;
	}

	p->m_iLastTimeStamp = *(int*)(pHeader + 80 + 12);
	p->m_iLastTimeStamp = SWAPINT(p->m_iLastTimeStamp);

	sceIoLseek(p->m_FileHandle, p->m_MpegStreamOffset, SEEK_SET);

	return 0;

error:
	return -1;
}

SceInt32 pmfplaer_load(PMFPLAYER_STRUCT *p, char* pFileName)
{
	int retVal;
	int i;	// AHMAN
	
	p->m_PmfScaling = 0;			//you can set 1 or 0;
//	pspDebugScreenInit();
	printf("open file :%s\n", pFileName);
	
	p->m_FileHandle = sceIoOpen(pFileName, PSP_O_RDONLY, 0777);
	if(p->m_FileHandle < 0)
	{
		sprintf(p->m_LastError, "sceIoOpen() failed!!!! %s", pFileName);
		return -1;
	}
	
	if(pmfplayer_parseheader(p) < 0)
		return -1;
		
	p->m_MpegStreamAVC = sceMpegRegistStream(&p->m_Mpeg, 0, 0);
	if(p->m_MpegStreamAVC == NULL)
	{
		sprintf(p->m_LastError, "sceMpegRegistStream() failed!");
		return -1;
	}
	
	if (p->m_AudioStreamExist) {
		p->m_MpegStreamAtrac = sceMpegRegistStream(&p->m_Mpeg, 1, 0);
		if(p->m_MpegStreamAtrac == NULL)
		{
			sprintf(p->m_LastError, "sceMpegRegistStream() failed!");
			return -1;
		}
	} else {
		p->m_MpegStreamAtrac = NULL;
		p->m_MpegAtracEsSize = 0;
		p->m_MpegAtracOutSize = 0;
		p->m_pEsBufferAtrac = NULL;
		p->Audio.m_AudioChannel = 0;
		p->Audio.m_ThreadID = 0;
		p->Audio.m_SemaphoreStart = 0;
		p->Audio.m_SemaphoreLock = 0;
		p->Audio.m_iNumBuffers = 0;
		p->Audio.m_iFullBuffers = 0;
		p->Audio.m_iPlayBuffer = 0;
		p->Audio.m_iDecodeBuffer = 0;
		p->Audio.m_iAbort = 0;
		p->Audio.m_LastError = 0;
		for(i = 0; i < 4; i++)
		{
			p->Audio.m_pAudioBuffer[i] = NULL;
			p->Audio.m_iBufferTimeStamp[i] = 0;
		}
	}
	
	p->m_pEsBufferAVC = sceMpegMallocAvcEsBuf(&p->m_Mpeg);
	if(p->m_pEsBufferAVC == NULL)
	{
		sprintf(p->m_LastError, "sceMpegMallocAvcEsBuf() failed!");
		return -1;
	}

	retVal = sceMpegInitAu(&p->m_Mpeg, p->m_pEsBufferAVC, &p->m_MpegAuAVC);
	if(retVal != 0)
	{
		sprintf(p->m_LastError, "sceMpegInitAu() failed: 0x%08X", retVal);
		return -1;
	}
	
	if (p->m_AudioStreamExist) {
		retVal = sceMpegQueryAtracEsSize(&p->m_Mpeg, &p->m_MpegAtracEsSize, &p->m_MpegAtracOutSize);
		if(retVal != 0)
		{
			sprintf(p->m_LastError, "sceMpegQueryAtracEsSize() failed: 0x%08X", retVal);
			return -1;
		}

		p->m_pEsBufferAtrac = memalign(64, p->m_MpegAtracEsSize);
		if(p->m_pEsBufferAtrac == NULL)
		{
			sprintf(p->m_LastError, "malloc() failed!");
			return -1;
		}

		retVal = sceMpegInitAu(&p->m_Mpeg, p->m_pEsBufferAtrac, &p->m_MpegAuAtrac);
		if(retVal != 0)
		{
			sprintf(p->m_LastError, "sceMpegInitAu() failed: 0x%08X", retVal);
			return -1;
		}
	}

	return 0;
}

SceVoid pmfplayer_Shutdown(PMFPLAYER_STRUCT *p)
{
	if(p->m_pEsBufferAtrac != NULL)
		free(p->m_pEsBufferAtrac);

	if(p->m_pEsBufferAVC != NULL)
		sceMpegFreeAvcEsBuf(&p->m_Mpeg, p->m_pEsBufferAVC);

	if(p->m_MpegStreamAVC != NULL)
		sceMpegUnRegistStream(&p->m_Mpeg, p->m_MpegStreamAVC);

	if(p->m_MpegStreamAtrac != NULL)
		sceMpegUnRegistStream(&p->m_Mpeg, p->m_MpegStreamAtrac);

	if(p->m_FileHandle > -1)
		sceIoClose(p->m_FileHandle);

	sceMpegDelete(&p->m_Mpeg);

	sceMpegRingbufferDestruct(&p->m_Ringbuffer);

	sceMpegFinish();

	if(p->m_RingbufferData != NULL)
		free(p->m_RingbufferData);

	if(p->m_MpegMemData != NULL)
		free(p->m_MpegMemData);
}

SceInt32 pmfplayer_Play(PMFPLAYER_STRUCT *p)
{
	int retVal, fail = 0;

	retVal = InitReader(p);
	if(retVal < 0)
	{
		fail++;
		goto exit_reader;
	}
	
	retVal = InitVideo(p);
	if(retVal < 0)
	{
		fail++;
		goto exit_video;
	}

	// AHMAN
	if (p->m_AudioStreamExist) {
		retVal = InitAudio(p);
		if(retVal < 0)
		{
			fail++;
			goto exit_audio;
		}
	}

	retVal = InitDecoder(p);
	if(retVal < 0)
	{
		fail++;
		goto exit_decoder;
	}

	ReaderThreadData* TDR = &p->Reader;
	DecoderThreadData* TDD = &p->Decoder;
	
	printf("start thread\n");
	printf("p->Reader.m_ThreadID:%d\n", p->Reader.m_ThreadID);
	sceKernelStartThread(p->Reader.m_ThreadID,  sizeof(void*), &TDR);
	if (p->m_AudioStreamExist) {
	printf("p->Audio.m_ThreadID:%d\n", p->Audio.m_ThreadID);
	sceKernelStartThread(p->Audio.m_ThreadID,   sizeof(void*), &TDD);
	}
	printf("p->Video.m_ThreadID:%d\n", p->Video.m_ThreadID);
	sceKernelStartThread(p->Video.m_ThreadID,   sizeof(void*), &TDD);
	printf("p->Decoder.m_ThreadID:%d\n", p->Decoder.m_ThreadID);
	sceKernelStartThread(p->Decoder.m_ThreadID, sizeof(void*), &TDD);
	printf("start thread done\n");
	
	sceKernelWaitThreadEnd(p->Decoder.m_ThreadID, 0);
	sceKernelWaitThreadEnd(p->Video.m_ThreadID, 0);
	sceKernelWaitThreadEnd(p->Audio.m_ThreadID, 0);
	sceKernelWaitThreadEnd(p->Reader.m_ThreadID, 0);
	printf("wait thread\n");
	
		
	ShutdownDecoder(p);
exit_decoder:
	ShutdownAudio(p);
exit_audio:
	ShutdownVideo(p);
exit_video:
	ShutdownReader(p);
exit_reader:

	if(fail > 0)
		return -1;
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -