📄 vid_sp4_play.c
字号:
i = i + ultemp;
if(ulResidueKF<Max_KF_of_File)
{
ultemp = ulResidueKF;
}
else
{
ultemp = Max_KF_of_File;
}
// status = lseek(fp, (5+i)*4, SEEK_SET);
}
}
g_ulKFSizes = g_ulDataBSizes;
g_pKFOffset = (unsigned int *) g_pKFOffset2;
}
if(g_ucDataBReady==0)
{
g_ucDataBReady = 1;
if(ulResidueKF>0)
{
ulBufferB = 1;
status = read(fp, (void *) g_pKFOffset2+4, (ultemp+1)*4);
g_pKFOffset2[0] = g_pKFOffset1[g_ulDataASizes+1];
g_ulDataBSizes = ultemp;
}
if(ulResidueKF==0)
{
g_ucDataBReady = 1;
}
g_ulKFSizes = g_ulDataASizes;
g_pKFOffset = (unsigned int *) g_pKFOffset1;
}
if(ulResidueKF!=0)
{
ulResidueKF = ulResidueKF - ultemp;
i = i + ultemp;
}
if(ulResidueKF==0)
{
if(ulBufferA==1 && ulBufferB==0)
{
g_pKFOffset1[g_ulDataASizes+1] = g_ulEOF;
g_pKFOffset1[g_ulDataASizes+2] = g_ulEOF;
}
if(ulBufferB==1 && ulBufferA==0)
{
g_pKFOffset2[g_ulDataBSizes+1] = g_ulEOF;
g_pKFOffset2[g_ulDataBSizes+2] = g_ulEOF;
}
if(ulBufferA==1 && ulBufferB==1)
{
g_pKFOffset2[g_ulDataBSizes+1] = g_ulEOF;
g_pKFOffset2[g_ulDataBSizes+2] = g_ulEOF;
}
}
//status = lseek(fp, gl_FilePtrCur, SEEK_SET);
}
//return status;
if(ret==MPEG4_B_POINT)
{
status = lseek(fp, g_pKFOffset[0], SEEK_SET);
}
return ret;
}
int vidSP4Play(int fp, unsigned int ulBufferAddress)
{
unsigned int i, j, k, ultemp, ulDataLen, ulcount, unVOPTimeIncLen;
unsigned int ulWritePort, ulLoadingFlag = 0;
int status;
//initial
g_ulKFOffset = 0;
g_ucTimerOff = 0;
g_ulKFIdx = 0;
i = 0;
j = 0;
k = 0;
g_ulW_NodeIdx = g_ulRA_NodeIdx = g_ulRV_NodeIdx =0;
g_ulFreeNode = 0;
//Preloading data to buffer and parsing KF offset address
status = vidSP4_Preload(fp, ulBufferAddress, g_ulStartOfFrame);
if (status == -1)
{
while (1);
}
mp4_SetRunMode(NORMAL_MODE);
vidSP4_InitKFList(g_pKF_List);
//moving file pointer to the first KF as start point
status = lseek(fp, g_pKFOffset[0], SEEK_SET);
if (status == -1) //if invalid
{
return status;
}
//Load data into Buffer...1st load
g_ulNextIdx = vidSP4_CheckBufferSpace(fp, g_ulStartIdx, g_pKFOffset, &g_ulBufferKFCount, &g_ulDataSize);
if (g_ulNextIdx >= Max_KF_Amount)
{
ulcount = Max_KF_Amount;
g_ulNextIdx = Max_KF_Amount;
}
else
{
ulcount = g_ulBufferKFCount;
}
for (i = g_ulStartIdx; i < ulcount; i++)
{
ulDataLen = g_pKFOffset[i + 1] - g_pKFOffset[i];
ulWritePort = vidSP4_RequestBuffer(ulBufferAddress, ulDataLen);
if (ulWritePort != 0xFFFFFFFF)
{
ultemp = ulDataLen/Data_Length + 1;
for (j=0; j<ultemp; j++)
{
vidSP4_LoadData(fp, ulWritePort, ulDataLen, j);
}
vidSP4_FillKFInfo(i, g_pKFOffset, (g_pKF_List + i), ulWritePort, 1);
}
else
{
return status = -1; //buffer is not enough
}
}
g_ulW_NodeIdx = i & (Max_KF_Amount - 1);
g_ulFreeNode = (g_ulRV_NodeIdx - g_ulW_NodeIdx) & (Max_KF_Amount - 1);
g_pKF_Node = g_pKF_List;
g_pAKFAddress = g_pVKFAddress = g_pKFAddress = &(g_pKF_Node->KFData);
g_pulMp4Data = g_pKFAddress->pulVideoData;
g_ulFrameRate = g_pKFAddress->ulMP4FrameRate;
g_ulTotalFrame = g_pKFAddress->ulTotalFrame;
if (g_ulFrameRate <=16)
{
unVOPTimeIncLen = 0x03;
}
else
{
unVOPTimeIncLen = 0x04;
}
ultemp = g_ulWidth * g_ulHeight * 2; //buffer size
mp4_deocder_prepare(g_ulWidth,g_ulHeight,P_FRAME_NUMBER,unVOPTimeIncLen); //VOPTimeIncrementLen, from VOL info.
mp4_set_decode_frame_buffer_address(BUFFER_START_ADDRESS,BUFFER_START_ADDRESS_TV,ultemp);
mp4_switch_decode_frame_buffer(0); //add by ww
//decode one frame first
mp4_decompress(*g_pulMp4Data);
if ((g_ulWidth <= 320) && (g_ulHeight <= 240))
{
*P_TV_MODE_CTRL = 0x1000|0x0800|0x0010; //open TV encoder with Y4U4V4 mode, VGA=0, interlace=0
}
else //640*480
{
*P_TV_MODE_CTRL = 0x1000|0x0800|0x0010|0x0004; //open TV encoder with Y4U4V4 mode, VGA=1, interlace=0
}
//decide timer IRQ by frame rate
status = vidSP4_InitTimer(g_ulFrameRate);
g_ucTimerOff = 0;
if (status == -1)
{
return status; //this frame rate is not supported.
}
//g_pAKFAddress = g_pVKFAddress = g_pKFAddress;
i = 0;
if (g_pKFAddress->ulAudioSize)
{
MP4_State_Flag |= MASK_MP4_AUDIO_TRACK;
MP3_Addr = (unsigned int *)(g_pAKFAddress->ulKFOffsetAddress + g_pAKFAddress->ulAudioOffset);
KFAudioEnd = (unsigned int *)(g_pAKFAddress->ulKFOffsetAddress + g_pAKFAddress->ulAudioOffset + g_pAKFAddress->ulAudioSize);
}
if((g_ulKFIdx == 0)&& (MP4_State_Flag & MASK_MP4_AUDIO_TRACK))
{
SP4_Play_MP3();
while (!(MP4_State_Flag & MASK_MP4_AUDIO_READY))
{
SP4_MP3_Service_Loop();
}
}
MP4_State_Flag |= MASK_MP4_PLAY;
//Start playing....
while((g_ulKFIdx < g_ulTotalKF) && (MP4_State_Flag & MASK_MP4_PLAY))
{
while ((MP4_State_Flag & MASK_MP4_PLAY) && !(MP4_State_Flag & MASK_MP4_PAUSE))
{
vidSP4_Change_Buffer();
*P_TIMER2_MODE_CTRL = C_TIMER_INT_FLAG;
if(g_ucMP3IrqFlag==1)
{
*P_DAC_INT_STATUS = 0x0000 | 0x0004 | 0x0003; // for stereo, 8KBytes //NO_IRQ
SP4_MP3_Service_Loop();
SP4_MP3_Service_Loop();
SP4_MP3_Service_Loop();
SP4_MP3_Service_Loop();
SP4_MP3_Service_Loop();
SP4_MP3_Service_Loop();
*P_DAC_INT_STATUS = 0xC000 | 0x0004 | 0x0003; // for stereo, 8KBytes //NO_IRQ
g_ucMP3IrqFlag=0;
}
*P_TIMER2_MODE_CTRL = C_TIMER_CTRL_EN | C_TIMER_INT_EN | C_TIMER_INT_FLAG;
//Audio part:
if ((MP4_State_Flag & MASK_MP4_AUDIO_TRACK) && (MP4_State_Flag & MASK_MP4_AUDIO_NEED))
{
MP4_State_Flag &= ~MASK_MP4_AUDIO_NEXT_KF;
g_uldiff_node = (g_ulRA_NodeIdx-g_ulRV_NodeIdx) & 31;
if ((g_pKF_Node->pKFNode_Next->ulReady) && (g_uldiff_node<=1))
//if ((g_pKF_Node->pKFNode_Next->ulReady))
{
g_pAKFAddress = &((g_pKF_List + g_ulRA_NodeIdx)->pKFNode_Next->KFData);
if (g_pAKFAddress->ulAudioSize)
{
MP4_State_Flag |= MASK_MP4_AUDIO_TRACK;
MP3_Addr = (unsigned int *)(g_pAKFAddress->ulKFOffsetAddress + g_pAKFAddress->ulAudioOffset);
KFAudioEnd = (unsigned int *)(g_pAKFAddress->ulKFOffsetAddress + g_pAKFAddress->ulAudioOffset + g_pAKFAddress->ulAudioSize);
g_pSP4_MP3Address = (unsigned char *)MP3_Addr;
g_ulRA_NodeIdx = (g_ulRA_NodeIdx + 1)& (Max_KF_Amount - 1);
}
else
{
MP4_State_Flag &= ~MASK_MP4_AUDIO_TRACK;
//SP4_Pause_MP3();
}
}
else
{
MP4_State_Flag &= ~MASK_MP4_AUDIO_TRACK;
//SP4_Pause_MP3();
}
}//~if audio need
//Video part:
if (g_ulFrameIdx >= g_ulTotalFrame)
//if (g_ulFrameIdx >= g_pVKFAddress->ulTotalFrame)
{
if (g_pKF_Node->pKFNode_Next->ulReady)
{
g_ulRV_NodeIdx = (g_ulRV_NodeIdx + 1)& (Max_KF_Amount - 1);
g_ulFreeNode = (g_ulRV_NodeIdx - g_ulW_NodeIdx) & (Max_KF_Amount - 1);
g_ulKFIdx++;
g_pKF_Node->ulReady = 0;
g_pKF_Node = (g_pKF_List + g_ulRV_NodeIdx);
g_ulReadPort = (g_pKF_Node->KFData.ulKFOffsetAddress - ulBufferAddress) & MP4_Buffer_Mask;
g_pVKFAddress = &(g_pKF_Node->KFData);
g_ulFrameIdx = 0;
g_pulMp4Data = g_pVKFAddress->pulVideoData;
}
else
{
//if(g_ulNextIdx>=(g_ulTotalKF-1-GUARD_BAND))
MP4_State_Flag &= ~MASK_MP4_PLAY;
}
}//~if video data
//If threr is any free node, then check buffer space.
if ((g_ulFreeNode > 0) && (ulLoadingFlag == 0) && (MP4_State_Flag & MASK_MP4_PLAY))
{
g_ulStartIdx = g_ulNextIdx;
g_ulNextIdx = vidSP4_CheckBufferSpace(fp, g_ulStartIdx, g_pKFOffset, &g_ulBufferKFCount, &g_ulDataSize);
if (g_ulNextIdx != g_ulStartIdx) //there is free space in the buffer.
{
//Only add one KF
g_ulNextIdx = g_ulStartIdx + 1;
ulDataLen = g_pKFOffset[g_ulNextIdx] - g_pKFOffset[g_ulStartIdx];
ulWritePort = vidSP4_RequestBuffer(ulBufferAddress, ulDataLen);
if (ulWritePort != 0xFFFFFFFF)
{
ulLoadingFlag = 0x10; //change flag state to "loading..."
}
else
{
//buffer is not enough...
//if(g_ulNextIdx!=Max_KF_of_File)
g_ulNextIdx--;
}
}//~if (g_ulNextIdx != g_ulStartIdx)
}//~if (g_ulFreeNode > 0)
//loadind data...
if (ulLoadingFlag == 0x10)
{
status = vidSP4_LoadData(fp, ulWritePort, ulDataLen, k);
if (status > 0)
{
k++;
}
}//~if (ulLoadingFlag == 0x10)
//loading is finished.
if ((ulLoadingFlag == 0x10) && (status == 0))
{
vidSP4_FillKFInfo(g_ulStartIdx, g_pKFOffset, (g_pKF_List + g_ulW_NodeIdx), ulWritePort, 1);
g_ulW_NodeIdx = (g_ulW_NodeIdx + 1) & (Max_KF_Amount - 1);
g_ulFreeNode = (g_ulRV_NodeIdx - g_ulW_NodeIdx) & (Max_KF_Amount - 1);
ulLoadingFlag = 0;
k = 0;
}//~if ((ulBuffer1_Flag == 0x10) && (status == 0))
}//~while((MP4_State_Flag & MASK_MP4_PLAY) && !(MP4_State_Flag & MASK_MP4_PAUSE))
}//~while(g_ulKFIdx < g_ulTotalKF)
//Ending....
SP4_Stop_MP3();
MP4_State_Flag = 0;
*P_TIMER2_MODE_CTRL = 0x00000000;
*P_TIMER3_MODE_CTRL = 0x00000000;
return status = 1;
}
void vidSP4_Change_Buffer(void)
{
if(g_ulStartIdx==(Max_KF_of_File+1))
{
if(g_ucABBufferFlag==0)
{
g_ucDataAReady = 0;
g_ucABBufferFlag = 1;
}
else
{
g_ucDataBReady = 0;
g_ucABBufferFlag = 0;
}
}
vidSP4_GetpKFOffset(g_nfp2,0,0,0, 0);
}
int vidSP4_InitTimer(unsigned int ulFrameRate)
{
unsigned int ulPreload = 0;
int status = 0;
switch(ulFrameRate)
{
case 30:
ulPreload = 0xDF72;
break;
case 29:
ulPreload = 0xDE53;
break;
case 28:
ulPreload = 0xDD1F;
break;
case 27:
ulPreload = 0xDBD4;
break;
case 26:
ulPreload = 0xDA70;
break;
case 25:
ulPreload = 0xD8EF;
break;
case 24:
ulPreload = 0xD74F;
break;
case 23:
ulPreload = 0xD58A;
break;
case 22:
ulPreload = 0xD39C;
break;
case 21:
ulPreload = 0xD17F;
break;
case 20:
ulPreload = 0xCF2B;
break;
case 15:
ulPreload = 0xBEE5;
break;
case 10:
ulPreload = 0x9E57;
break;
default:
ulPreload = 0;
return status = -1;
break;
}
*P_TIMER3_CLK_CONF = 0x00000000;
*P_TIMER3_CLK_CONF = 0x00000003;
*P_TIMER_CLK_SEL = 0x0000006B;//0x0000001A;
*P_TIMER3_PRELOAD_DATA = ulPreload;// set timer cycle
*P_TIMER3_CCP_CTRL = C_TIMER_NOR_MODE; // normal mode*
*P_TIMER3_MODE_CTRL = C_TIMER_CTRL_EN | C_TIMER_INT_EN | C_TIMER_INT_FLAG;
//ADD by ww
*P_TIMER2_CLK_CONF = 0x00000000;
*P_TIMER2_CLK_CONF = 0x00000003;
*P_TIMER_CLK_SEL = 0x0000006B;//0x0000001A;
*P_TIMER2_PRELOAD_DATA = 0xFE00;// set timer cycle
*P_TIMER2_CCP_CTRL = C_TIMER_NOR_MODE; // normal mode*
*P_TIMER2_MODE_CTRL = C_TIMER_CTRL_EN | C_TIMER_INT_EN | C_TIMER_INT_FLAG;
//End
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -