📄 vid_sp4_play.c
字号:
//=============================================================
// 文件名称: MP4_DecodeEncode.c
// 功能描述: SP4格式文件播放程序
// 维护记录: 2007-01-16 v1.0
//=============================================================
#include "SPCE3200_Register.h"
#include "SPCE3200_Constant.h"
#include "vid_sp4_play.h"
//mp3
extern unsigned int *MP3_Addr;
extern unsigned char *g_pSP4_MP3Address;
extern unsigned int *KFAudioEnd;
extern unsigned int MP3_Isr;
extern unsigned int samplerate;
extern short SP4_TempPCM[];
extern int SP4_MP3Need_PCM_Flag;
extern void SP4_FillSoftFIFO(unsigned short *SP4_TempPCM);
//mp4
KF_NODE g_pKF_List[Max_KF_Amount];
KEY_FRAME_INFO *g_pKFAddress;
unsigned int *g_pKFOffset; //add by ww
unsigned int g_pKFOffset1[Max_KF_of_File+2]; //add by ww
unsigned int g_pKFOffset2[Max_KF_of_File+2]; //add by ww
unsigned int g_ulKFLength = 0;
unsigned int *g_pulMp4Data;
unsigned int g_ulTotalKF, g_ulWidth, g_ulHeight;
unsigned int g_ulKFIdx, g_ulFrameIdx;
unsigned int MP4_State_Flag = 0;
unsigned int g_ulNextIdx, g_ulStartIdx;
unsigned int g_ulReadPort, g_ulWritePort, g_ulCurrentBufferLen, g_ulDataSize, g_ulBufferKFCount;
unsigned int g_ulFrameRate = 0;
unsigned int g_ulTotalFrame = 0;
unsigned int g_ulEOF = 0;
unsigned int g_uldiff_node;
unsigned int g_ulW_NodeIdx, g_ulRA_NodeIdx, g_ulRV_NodeIdx;
KEY_FRAME_INFO *g_pAKFAddress, *g_pVKFAddress;
PKF_NODE g_pKF_Node;
unsigned char g_ucTimerOff=0;
//Add by ww
unsigned char g_ucDataAReady=0;
unsigned char g_ucDataBReady=0;
unsigned int gl_FilePtrCur;
unsigned int g_ulDataASizes;
unsigned int g_ulDataBSizes;
unsigned char g_ucABBufferFlag = 0;
unsigned char g_ucMP3IrqFlag = 0;
unsigned int g_ulSP4counter = 0;
unsigned int g_ulFreeNode;
int g_nfp1, g_nfp2;
unsigned int g_ulStartFramNum = 0;
unsigned int g_ulEndFramNum = 0;
unsigned int g_ulKFSizes;
unsigned int g_ulStartOfFrame=0;
unsigned int g_ulRepeatFrameA=0;
unsigned int g_ulRepeatFrameB=0;
//add by ww end
void vidSP4_FindIdx(unsigned int *KF_address, unsigned int *start_address,unsigned int *end_address,unsigned int *VOPAddress,unsigned int total_frame)
{
unsigned int index = 0;
unsigned int begin_address = (unsigned int)KF_address;
unsigned int *ptr;
ptr = start_address;
if (*ptr == idx1)
{
ptr +=2;
while((ptr<end_address)&&(index<total_frame))
{
if ((*ptr == PictureFlag1) || (*ptr == PictureFlag2))
{
ptr ++;
VOPAddress[index]= begin_address + *ptr;
ptr ++; // framedata length
index++;
}
ptr ++;
}
}
}
unsigned int vidSP4_CheckBufferSpace(int fp, unsigned int ulKF_Start_index, unsigned int *FileKFOffset, unsigned int *pulKFcount, unsigned int *pulDataSize)
{
unsigned int j;
unsigned int ulKF_New_Start_index = ulKF_Start_index;
g_ulCurrentBufferLen = (g_ulReadPort - g_ulWritePort - BUFFER_GUARD_BAND) & MP4_Buffer_Mask;
for (j = ulKF_Start_index; j <= g_ulKFSizes; j++)
{
if ((FileKFOffset[j]-FileKFOffset[ulKF_Start_index]) >= g_ulCurrentBufferLen)
{
if ((FileKFOffset[j]-FileKFOffset[ulKF_Start_index]) == g_ulCurrentBufferLen)
{
ulKF_New_Start_index = j;
}
else
{
ulKF_New_Start_index = j - 1;
}
break;
}
else
{
ulKF_New_Start_index = j + 1;
}
}
*pulKFcount = ulKF_New_Start_index - ulKF_Start_index;
*pulDataSize = FileKFOffset[ulKF_New_Start_index]-FileKFOffset[ulKF_Start_index];
return ulKF_New_Start_index;
}
unsigned int g_ulKFOffset=0;
int vidSP4_LoadData(int fp, unsigned int ulBufferAddress, unsigned int ulDataSize, unsigned int ulcount)
{
unsigned int ulLoadedData;
int status;
ulLoadedData = Data_Length * ulcount;
//read data to buffer
if (ulDataSize >= ulLoadedData + Data_Length)
{
status = read(fp, (unsigned char *)(ulBufferAddress + ulLoadedData), Data_Length);
}
else if(ulDataSize>ulLoadedData)
{
status = read(fp, (unsigned char *)(ulBufferAddress + ulLoadedData), ulDataSize - ulLoadedData);
}
else
{
status = 0; //finished
}
return status;
}
void vidSP4_FillKFInfo(unsigned int ulKF_Start_index, unsigned int *FileKFOffset, KF_NODE *pKFNode, unsigned int ulBufferAddress, unsigned int ulKFcount)
{
unsigned int i, *pAddr, ulKFStar, ulTableLen;
PKF_NODE pKFTemp;
pKFTemp = pKFNode;
for (i=0; i < ulKFcount; i++)
{
//Get KF offset relative to the write port
pKFTemp->KFData.ulKFOffsetAddress = ulBufferAddress + FileKFOffset[ulKF_Start_index + i] - FileKFOffset[ulKF_Start_index];
//fill Key Frame info
pAddr = (unsigned int *)(pKFTemp->KFData.ulKFOffsetAddress);
pKFTemp->KFData.ulVideoIndexTableOffset = *(pAddr+1);
pKFTemp->KFData.ulAudioOffset = *(pAddr+2);
pKFTemp->KFData.ulAudioSize = *(pAddr+3);
pKFTemp->KFData.ulMP4FrameRate = *(pAddr+4);
pKFTemp->KFData.ulTotalFrame = *(pAddr+5);
//fill video data address of the key frame
ulKFStar = pKFTemp->KFData.ulKFOffsetAddress;
ulTableLen = (pKFTemp->KFData.ulMP4FrameRate * 12) + 8;
vidSP4_FindIdx((unsigned *)ulKFStar, (unsigned *)(ulKFStar + pKFTemp->KFData.ulVideoIndexTableOffset), (unsigned int *)(ulKFStar + pKFTemp->KFData.ulVideoIndexTableOffset + ulTableLen - 1),
pKFTemp->KFData.pulVideoData, pKFTemp->KFData.ulTotalFrame);
pKFTemp->ulReady = 1;
pKFTemp = pKFNode->pKFNode_Next;
}
}
int vidSP4_Preload(int fp, unsigned int ulLoadAddress,unsigned int StartOfFrame)
{
unsigned int ulIdxAddr;
unsigned int *pAddr;
int status;
//Add by ww
g_ucDataAReady=0;
g_ucDataBReady=0;
g_ucABBufferFlag=0;
g_ulReadPort=0;
g_ulWritePort=0;
g_ulCurrentBufferLen=0;
g_ulDataSize=0;
g_ulBufferKFCount=0;
g_ulFrameRate = 0;
g_ulTotalFrame = 0;
g_ulEOF = 0;
g_ucDataAReady=0;
g_ucDataBReady=0;
gl_FilePtrCur=0;
g_ulDataASizes=0;
g_ulDataBSizes=0;
g_ucABBufferFlag = 0;
g_ucMP3IrqFlag = 0;
g_ulKFLength = 0;
g_ulTotalKF=0;
g_ulWidth=0;
g_ulHeight=0;
g_ulKFIdx=0;
g_ulFrameIdx=0;
g_ulNextIdx=0;
g_ulStartIdx=0;
g_ulSP4counter = 0;
g_ulFreeNode=0;
g_ulKFSizes=0;
MP4_State_Flag = 0;
//End
//read header and KF offset info to the buffer
status = read(fp, (void *)ulLoadAddress, 0x100000);
pAddr = (unsigned int *)ulLoadAddress;
//Check header flag
if (*pAddr != SPMP)
{
return status = -1;
}
pAddr++;
//Get total KF number
g_ulTotalKF = *pAddr;
pAddr++;
//Get width and height
g_ulWidth = *pAddr;
pAddr++;
g_ulHeight = *pAddr;
pAddr++;
//Get KF length in per sec
g_ulKFLength = *pAddr;
pAddr++;
//Parsing ver.
if (*pAddr == SPver0101)
{
pAddr++;
//Get KF offset flag address
ulIdxAddr = *pAddr;
g_ulEOF = ulIdxAddr;
vidSP4_GetpKFOffset(g_nfp2,g_ulStartFramNum,g_ulEndFramNum,SET_FRAME_START_END_ON, ulIdxAddr+4);
}
else
{
status = lseek(fp, 0, SEEK_END);
g_ulEOF = (unsigned int) (status);
vidSP4_GetpKFOffset(g_nfp2,g_ulStartFramNum,g_ulEndFramNum,SET_FRAME_START_END_ON, 20);
}
return status;
}
unsigned int vidSP4_RequestBuffer(unsigned int ulBufferAddress, unsigned int ulDataSize)
{
unsigned int ulContinueBufferLen, ulWritePort;
ulContinueBufferLen = MP4_Buffer_Size - g_ulWritePort;
g_ulCurrentBufferLen = (g_ulReadPort - g_ulWritePort - BUFFER_GUARD_BAND) & MP4_Buffer_Mask;
if(ulContinueBufferLen >=ulDataSize)
{
if (g_ulCurrentBufferLen >=ulDataSize)
{
g_ulCurrentBufferLen -= ulDataSize;
ulWritePort = ulBufferAddress + g_ulWritePort;
g_ulWritePort = (g_ulWritePort + ulDataSize) & MP4_Buffer_Mask;
return ulWritePort;
}
else
{
//Buffer is not enough
return 0xFFFFFFFF;
}
}
else
{
if (g_ulCurrentBufferLen >= ulContinueBufferLen)
{
g_ulCurrentBufferLen -= ulContinueBufferLen;
g_ulWritePort = ulWritePort = 0;
}
else
{
//Buffer is not enough
return 0xFFFFFFFF;
}
if (g_ulCurrentBufferLen >= ulDataSize)
{
ulWritePort = ulBufferAddress;
g_ulWritePort = ulDataSize;
g_ulCurrentBufferLen -= ulDataSize;
return ulWritePort;
}
else
{
//Buffer is not enough
return 0xFFFFFFFF;
}
}
}
void vidSP4_InitKFList(KF_NODE *pKFNode)
{
unsigned int i;
//initial KF Node
memset(pKFNode, 0, (sizeof(KF_NODE)*Max_KF_Amount));
for(i = 0; i < Max_KF_Amount; i++)
{
if (i != (Max_KF_Amount-1))
{
(pKFNode + i)->pKFNode_Next = (pKFNode + i+1);
}
else
{
(pKFNode + i)->pKFNode_Next = pKFNode;
}
}
}
void vidSP4Stop()
{
MP4_State_Flag =0;
SP4_Stop_MP3();
}
void vidSP4Pause()
{
MP4_State_Flag |= MASK_MP4_PAUSE;
SP4_Pause_MP3();
}
void vidSP4Resume()
{
MP4_State_Flag &= ~MASK_MP4_PAUSE;
MP4_State_Flag |= MASK_MP4_PLAY;
SP4_Resume_MP3();
while (!(MP4_State_Flag & MASK_MP4_AUDIO_READY))
{
SP4_MP3_Service_Loop();
}
}
unsigned int vidSP4_GetpKFOffset(int fp,unsigned int ulStartFramNum,unsigned int ulEndFramNum,unsigned char ucSwithOnOFF, unsigned int offset)
{
static unsigned int i;
int status=0,ret=0;
static unsigned int ulResidueKF;
unsigned int ultemp;
unsigned int ulBufferA=0,ulBufferB=0;
static unsigned int ulStartFrame,ulEndFrame;
if(ucSwithOnOFF==SET_FRAME_START_END_ON)
{
i = ulStartFrame = ulStartFramNum;
ulEndFrame = ulEndFramNum;
}
if((g_ucDataAReady==0) || (g_ucDataBReady==0))
{
if(i==ulStartFrame)
{
ulResidueKF = g_ulTotalKF - ulStartFrame;
g_pKFOffset = (unsigned int *) g_pKFOffset1;
g_ucABBufferFlag = 0;
g_ucDataAReady = 0;
g_ucDataBReady = 0;
status = lseek(fp, offset + i*4, SEEK_SET);
}
else if(i>=ulEndFrame && ulEndFrame!=0)
{
i = ulStartFrame;
ulResidueKF = g_ulTotalKF - ulStartFrame;
g_ucABBufferFlag = 0;
g_ucDataAReady = 0;
g_ucDataBReady = 0;
status = lseek(fp, offset + i*4, SEEK_SET);
ret = MPEG4_B_POINT;
}
else
{
//
}
g_ulStartIdx=0;
g_ulNextIdx=0;
if(ulResidueKF<Max_KF_of_File)
{
ultemp = ulResidueKF;
}
else
{
ultemp = Max_KF_of_File;
}
//gl_FilePtrCur = lseek(fp, 0, SEEK_CUR);
if(ulResidueKF!=0)
{
//status = lseek(fp, (5+i)*4, SEEK_SET);
}
if(g_ucDataAReady==0)
{
g_ucDataAReady = 1;
if(ulResidueKF>0)
{
ulBufferA = 1;
if(i==ulStartFrame)
{
status = read(fp, (void *) g_pKFOffset1, (ultemp+2)*4);
// g_pKFOffset1[ultemp]=0;
}
else
{
status = read(fp, (void *) g_pKFOffset1+4, (ultemp+1)*4);
g_pKFOffset1[0] = g_pKFOffset2[g_ulDataBSizes+1];
}
g_ulDataASizes = ultemp;
if(i==ulStartFrame)
{
ulResidueKF = ulResidueKF - ultemp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -