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

📄 vid_sp4_play.c

📁 凌阳SPCE3200 系统开发板随机自带源程序。共安排了32个子目录
💻 C
📖 第 1 页 / 共 2 页
字号:
//=============================================================
// 文件名称:	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 + -