📄 pmfplayer.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 + -