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

📄 vid_sp4_play.c

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