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

📄 vid_sp4_play.c

📁 凌阳SPCE3200多媒体开发板自带源程序。共安排了32个子目录
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
 *
 *     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 + -