📄 vid_sp4_play.c
字号:
/******************************************************************************
*
* The information contained herein is the exclusive property of
* Sunplus Technology Co. And shall not be distributed, reproduced,
* or disclosed in whole in part without prior written permission.
*
* (C) COPYRIGHT 2005 SUNPLUS TECHNOLOGY CO.
* ALL RIGHTS RESERVED
*
* The entire notice above must be reproduced on all authorized copies.
*
*****************************************************************************/
/******************************************************************************
* Filename: vid_sp4_play.c
* Author:
* Tel:
* Date: 2006-07-18
* Description: all API functions of SP4
* Reference:
* Version history:
*-----------------------------------------------------------------------------
* Version YYYY-MM-DD-INDEX Modified By Description
* 1.0.0 2006-07-18 rex.wu Create
*
*****************************************************************************/
#include "vid_sp4_play.h"
//mp3
extern U32 *MP3_Addr;
extern U8 *g_pSP4_MP3Address;
extern U32 *KFAudioEnd;
extern U32 MP3_Isr;
extern U32 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;
U32 *g_pKFOffset; //add by ww
#ifdef CDROM_DEVICE
U32 g_pKFOffsetCD[Max_KF_of_File];
#endif
#ifdef SD_CARD_DEVICE
U32 g_pKFOffset1[Max_KF_of_File+2]; //add by ww
U32 g_pKFOffset2[Max_KF_of_File+2]; //add by ww
#endif
U32 g_ulKFLength = 0;
U32 *g_pulMp4Data;
U32 g_ulTotalKF, g_ulWidth, g_ulHeight;
U32 g_ulKFIdx, g_ulFrameIdx;
U32 MP4_State_Flag = 0;
U32 g_ulNextIdx, g_ulStartIdx;
U32 g_ulReadPort, g_ulWritePort, g_ulCurrentBufferLen, g_ulDataSize, g_ulBufferKFCount;
U32 g_ulFrameRate = 0;
U32 g_ulTotalFrame = 0;
U32 g_ulEOF = 0;
U32 g_uldiff_node;
U32 g_ulW_NodeIdx, g_ulRA_NodeIdx, g_ulRV_NodeIdx;
KEY_FRAME_INFO *g_pAKFAddress, *g_pVKFAddress;
PKF_NODE g_pKF_Node;
U8 g_ucTimerOff=0;
//Add by ww
U8 g_ucDataAReady=0;
U8 g_ucDataBReady=0;
U32 gl_FilePtrCur;
U32 g_ulDataASizes;
U32 g_ulDataBSizes;
U8 g_ucABBufferFlag = 0;
U8 g_ucMP3IrqFlag = 0;
U32 g_ulSP4counter = 0;
U32 g_ulFreeNode;
S32 g_nfp1, g_nfp2;
U32 g_ulStartFramNum = 0;
U32 g_ulEndFramNum = 0;
U32 g_ulKFSizes;
U32 g_ulStartOfFrame=0;
U32 g_ulRepeatFrameA=0;
U32 g_ulRepeatFrameB=0;
//add by ww end
void vidSP4_FindIdx(U32 *KF_address, U32 *start_address,U32 *end_address,U32 *VOPAddress,U32 total_frame)
{
U32 index = 0;
U32 add = 0;
U32 begin_address = (U32)KF_address;
U8 *ptr;
U8 temp1,temp2,temp3,temp4;
ptr = start_address;
while((ptr<end_address)&&(index<total_frame))
{
temp1 = temp2;
temp2 = temp3;
temp3 = temp4;
temp4 = *ptr;
ptr++;
if((temp1=='i')&&(temp2=='d')&&(temp3=='x')&&(temp4=='1'))
{
ptr += 4;
break;
}//idx1
}//while(ptr<end_address)
while((ptr<end_address)&&(index<total_frame))
{
temp1 = temp2;
temp2 = temp3;
temp3 = temp4;
temp4 = *ptr;
ptr++;
if((temp1=='0')&&(temp2=='0')&&(temp3=='d')&&((temp4=='b')||(temp4=='c')))
{
//Frame offset
temp1 = *ptr;
ptr++;
temp2 = *ptr;
ptr++;
temp3 = *ptr;
ptr++;
temp4 = *ptr;
ptr++;
add = (U32)temp4;
add = add<<8;
add += (U32)temp3;
add = add<<8;
add += (U32)temp2;
add = add<<8;
add += (U32)temp1;
VOPAddress[index]=begin_address + add;
index++;
ptr += 4;//dwChunkLength
}//00db,00dc
}//while(ptr<end_address)
return 0;
}
void vidSP4_FindIdx2(U32 *KF_address, U32 *start_address,U32 *end_address,U32 *VOPAddress,U32 total_frame)
{
U32 index = 0;
U32 add = 0;
U32 begin_address = (U32)KF_address;
U32 *ptr;
#ifdef VIEW_FRAM_RATE
U32 ulFrameRate[4];
static U32 ulBiggerValue;
static U32 ulAverageValue=0;
U32 i;
static U32 ulTime=0;
#endif
ptr = start_address;
#ifdef VIEW_FRAM_RATE
ulFrameRate[0]= *(ptr+4);
ulFrameRate[1]= *(ptr+7);
ulFrameRate[2]= *(ptr+10);
ulFrameRate[3]= *(ptr+13);
if(ulTime>10)
{
for(i=0;i<4;i++)
{
if(i<3)
{
if(ulFrameRate[i]<=ulFrameRate[i+1])
{
if(ulBiggerValue<ulFrameRate[i+1])
{
ulBiggerValue = ulFrameRate[i+1];
}
}
else
{
if(ulBiggerValue<ulFrameRate[i])
{
ulBiggerValue = ulFrameRate[i];
}
}
}
if(ulFrameRate[i]>1024)
{
ulAverageValue += ulFrameRate[i];
}
else
{
ulAverageValue += 1024;
}
}
}
ulTime++;
if(ulTime>10000)
{
ulTime-=11;
ulAverageValue = ulAverageValue / (ulTime*4);
}
#endif
#ifdef CDROM_DEVICE
(U32) ptr &= ~0x03;
#endif
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 ++;
}
}
}
U32 vidSP4_CheckBufferSpace(int fp, U32 ulKF_Start_index, U32 *FileKFOffset, U32 *pulKFcount, U32 *pulDataSize)
{
U32 i, j;
U32 ulKF_New_Start_index = ulKF_Start_index;
g_ulCurrentBufferLen = (g_ulReadPort - g_ulWritePort - BUFFER_GUARD_BAND) & MP4_Buffer_Mask;
#ifdef SD_CARD_DEVICE
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;
}
}
#endif
#ifdef CDROM_DEVICE
for (j = ulKF_Start_index; j < g_ulTotalKF; 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;
}
}
#endif
*pulKFcount = ulKF_New_Start_index - ulKF_Start_index;
*pulDataSize = FileKFOffset[ulKF_New_Start_index]-FileKFOffset[ulKF_Start_index];
return ulKF_New_Start_index;
}
U32 g_ulKFOffset=0;
int vidSP4_LoadData(int fp, U32 ulBufferAddress, U32 ulDataSize, U32 ulcount)
{
U32 ulLoadedData;
int status;
//ADD by WW
U32 *ptr;
U8 Repeat_count;
//End
#ifdef IO_TEST
*P_ADC_GPIO_SETUP |= 0x00000004; // Output high at ADC bit7
#endif
ulLoadedData = Data_Length * ulcount;
//read data to buffer
if (ulDataSize >= ulLoadedData + Data_Length)
{
#ifdef SD_CARD_DEVICE
status = read(fp, ulBufferAddress + ulLoadedData, Data_Length);
#endif
#ifdef CDROM_DEVICE
status = iso_read(fp, ulBufferAddress + ulLoadedData, Data_Length);
#endif
}
else if(ulDataSize>ulLoadedData)
{
#ifdef SD_CARD_DEVICE
status = read(fp, ulBufferAddress + ulLoadedData, ulDataSize - ulLoadedData);
#endif
#ifdef CDROM_DEVICE
status = iso_read(fp, ulBufferAddress + ulLoadedData, ulDataSize - ulLoadedData);
#endif
}
else
{
status = 0; //finished
}
#ifdef IO_TEST
*P_ADC_GPIO_SETUP &= ~0x00000004; // Output high at ADC bit7
#endif
#ifdef CDROM_DEVICE
//ADD by WW
ptr = (U32 *) (ulBufferAddress + ulLoadedData);
Repeat_count=0;
while((*ptr != 0x504d5053) && (ulcount==0))
{
status = iso_lseek(fp, g_pKFOffset[g_ulKFOffset], SEEK_SET);
//read data to buffer
if (ulDataSize >= ulLoadedData + Data_Length)
{
status = iso_read(fp, ulBufferAddress + ulLoadedData, Data_Length);
}
else if(ulDataSize>ulLoadedData)
{
status = iso_read(fp, ulBufferAddress + ulLoadedData, ulDataSize - ulLoadedData);
}
else
{
status = 0; //finished
}
Repeat_count++;
if(Repeat_count>10)
{
MP4_State_Flag &= ~MASK_MP4_PLAY;
break;
}
}
if(ulcount==0)
{
g_ulKFOffset++;
}//End
#endif
return status;
}
void vidSP4_FillKFInfo(U32 ulKF_Start_index, U32 *FileKFOffset, KF_NODE *pKFNode, U32 ulBufferAddress, U32 ulKFcount)
{
U32 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 = (U32 *)(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_FindIdx2(ulKFStar, (ulKFStar + pKFTemp->KFData.ulVideoIndexTableOffset), (ulKFStar + pKFTemp->KFData.ulVideoIndexTableOffset + ulTableLen - 1),
pKFTemp->KFData.pulVideoData,pKFTemp->KFData.ulTotalFrame);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -