📄 realfunctions.c
字号:
#include "include.h"
#include "system.h"
#include "driver\mailbox\hw_mailbox.h"
#include "../browser/BrowserStruct.h"
#include "VideoWin.h"
#include "../audio/include/audio_globals.h"
#include "../video/avi/avifile.h"
#include "AudioControl.h"
#include "TypeDef.h"
#include "Mpeg4Contrl.h"
#include "RealFun.h"
#include "pRMDec.h"
#define MAX_REAL_VIDEOBIT_NUM 4
#define REAL_YUV_BUFFER_SIZE (720*576*3/2)
unsigned short *RealDecTab;
long long volatile real_timer_tick = 0;
long long showed_time = 0;
AVI_FILE *RealFile;
OutPutFrame *FreshFrame;
short FrameInputIndex;
short FrameOutputIndex;
short PreIndex;
short PrePreIndex;
short PrePrePreIndex;
volatile short FramesInBuff;
unsigned short RealSkipState;
short Real_SendMailDisable;
short ScreenChangeEnable;
short Real_PicWidth;
short Real_PicHeight;
volatile short RealExitState;
short RealDecoderCnt;
unsigned short RealVideoSkipEnble;
unsigned short Real_DecodeState;
long Real_CurrentSeekingTime;
unsigned char *RealVideobitStream[MAX_REAL_VIDEOBIT_NUM];
short RealLcdWaitCnt;
BACKGRND *RealVideoScreen;//[YUV_BUFFER_NUM];
DWDMALLP *RealVideoLLPList;//[YUV_BUFFER_NUM][1000];
InterruptHandler BackSaveForReal;
unsigned short SyncEnable;
unsigned long SyncTime;
unsigned short RealFileEnd;
unsigned short RV_SeekEnd_AudioEN;
unsigned short RV_SkipFrameEn;
unsigned short RV_AddDecodeSpeed;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
extern BACKGRND gScreen[2];
extern LCDCDEV LCDCDev;
extern MY_FILE *pRawFileCache;
extern unsigned long buff[0xc000];
extern INT16U AudioPlayState;
extern unsigned char gAudioReq ;
extern SYS_FILE_INFO VideoFileInfo;
extern unsigned short RealAudioExist;
extern unsigned short Real_FrameTimerEn;
extern unsigned short Real_InitEnable;
extern void RVDeInit(void);
extern unsigned long Real_GetVideoVersion(void);
extern long RV_GetNextFrameTime(unsigned long Time);
extern unsigned long PosSeekVal;
BACKGRND *RealVideoScreenTemp;
DWDMALLP *RealVideoLLPListTemp;
/****************************************/
/* 创建视频输出帧屏幕 */
/****************************************/
extern SCALEMODE ScreenMode;
extern INT16 ScreenModeSetSign ;
void CreateRealScreen(short Width, short Height)
{
int i;
for (i = 0; i < YUV_BUFFER_NUM; i++)
{
Screen_CreatVideo(&RealVideoScreen[i], &RealVideoLLPList[i*1000], (unsigned long)((unsigned long)(yuvBuf) + (unsigned long)REAL_YUV_BUFFER_SIZE*(unsigned long)(i)), Width,
Height, FullScreen);
Screen_CreatVideo(&RealVideoScreenTemp[i], &RealVideoLLPListTemp[i*1000], (unsigned long)((unsigned long)(yuvBuf) + (unsigned long)REAL_YUV_BUFFER_SIZE*(unsigned long)(i)), Width,
Height, LineArity);
}
Screen_CreatVideo(&RealVideoScreen[YUV_BUFFER_NUM], &RealVideoLLPList[YUV_BUFFER_NUM*1000], (unsigned long)((unsigned long)(yuvBuf) + (unsigned long)REAL_YUV_BUFFER_SIZE*(unsigned long)(YUV_BUFFER_NUM)), Width,
Height, FullScreen);
}
extern void DspEnable(void);
/****************************************/
/* 根据版本载入ZSP解码器 */
/****************************************/
BOOLEAN LoadDecoder(unsigned long Verion)
{
MY_FILE *fpTemp;
long DataSize[8];
char *ZspData;
SetRegBit32(0x1801C000 + 0x28, 18); //disable
DspEnable();
//Pll_SetARMFreq(192, HCLK_DIV2 , PCLK_DIV2 );
//PMU_EnterModule(PMU_VIDEOHIGH);
//ClrRegBit32(0x1801C000 + 0x14, 1); //clear SLOW MODE
//Scu_ClockEnable(DSP_CLOCK);
//ClrRegBit32(0x1801C000 + 0x1c, 5); //reset zsp500P
fpTemp = (MY_FILE *)RKFSFileOpen("C:\\SYSTEM\\REALOBJ.BIN", "rb");
if (fpTemp == NULL)
return FALSE;
RKFSFileRead(DataSize, 32, fpTemp);
RKFSFileRead(RealDecTab, DataSize[0], fpTemp);
if (Verion == RAW_RV9_MAJOR_VERSION)
{
if ((ZspData = (char*)MALLOC(DataSize[1])) == 0)
return FALSE;
RKFSFileRead(ZspData, DataSize[1], fpTemp);
memcpy((char *)(IMEM_ADDR_AHB0), ZspData, DataSize[1]);
RKFSFileRead(ZspData, DataSize[2], fpTemp);
memcpy((char *)(0x30000000), ZspData, DataSize[2]);
FREE(ZspData);
}
else
{
RKFSFileSeek(fpTemp, DataSize[1] + DataSize[2], SEEK_CUR);
if ((ZspData = (char*)MALLOC(DataSize[3])) == 0)
return FALSE;
RKFSFileRead(ZspData, DataSize[3], fpTemp);
memcpy((char *)(IMEM_ADDR_AHB0), ZspData, DataSize[3]);
RKFSFileRead(ZspData, DataSize[4], fpTemp);
memcpy((char *)(0x30000000), ZspData, DataSize[4]);
FREE(ZspData);
}
RKFSFileClose(fpTemp);
Scu_ModuleReset(DSP_C_RESET , FALSE);
return TRUE;
}
/****************************************/
/* Real 输出帧管理入帧队列 */
/****************************************/
void RealPutFrameToFIFO(unsigned long State, unsigned long Index, unsigned long Time)
{
FramesInBuff ++;
FreshFrame[FrameInputIndex].PicNo = Index;
FreshFrame[FrameInputIndex].Time = Time;
if (ScreenChangeEnable)
{
FreshFrame[Index].ChangScreen = 1;
ScreenChangeEnable = 0;
}
FreshFrame[FrameInputIndex].State = State;
FrameInputIndex++;
if (FrameInputIndex == YUV_BUFFER_NUM)
FrameInputIndex = 0;
}
/****************************************/
/* Real 输出帧管理出帧队列 */
/****************************************/
short RealGetFrameFromFIFO()
{
short IndexTemp;
showed_time = FreshFrame[FrameOutputIndex].Time;
if (Real_DecodeState == REAL_DECODE_STATE_PAUSE) //暂停状态不允许输出帧
return 13;
RV_AddDecodeSpeed = 0;
IndexTemp = FrameOutputIndex + 1;
if (IndexTemp == YUV_BUFFER_NUM)
IndexTemp = 0;
if (FreshFrame[IndexTemp].State != 2) //帧状态不是可以输出帧时不输出
IndexTemp = 13;
else if (SyncEnable)
{
long CurrentVideoTime = (long)FreshFrame[IndexTemp].Time;
long CurrentAudioTime = (long)real_timer_tick + (long)GetRASeekedTime();//(long)GetRASeekedTime();
if ((CurrentVideoTime <= CurrentAudioTime))
{
showed_time = FreshFrame[IndexTemp].Time;
FrameOutputIndex = IndexTemp;
FreshFrame[IndexTemp].State = 1;
FramesInBuff--;
if (CurrentAudioTime >= CurrentVideoTime + 50)
RV_AddDecodeSpeed = 1;
if (CurrentAudioTime >= CurrentVideoTime + 120)
RV_AddDecodeSpeed = 2;
//if (!isTVOutMode)
{
if (CurrentAudioTime >= CurrentVideoTime + 200)
RV_AddDecodeSpeed = 3;
}
if (Real_DecodeState == REAL_DECODE_STATE_PLAYING) /////
{
if ((CurrentAudioTime >= CurrentVideoTime + 500) && Real_SeekEnable && RV_SkipFrameEn) // 1000ms为最小不同步域值,超过该范围进行跳帧调整
{
long TempDistance, TempCur;
TempCur = RV_GetNextFrameTime(CurrentAudioTime);
TempDistance = TempCur - CurrentAudioTime;
if ((TempDistance >= 0) && (TempDistance <= 250)) //500ms为跳帧的音频时间与视频时间的差值,越大引起的视频不连续越大,画面会比较卡
{
Real_DecodeState = REAL_DECODE_STATE_POSSEEKSTART;
PosSeekVal = (unsigned long)TempCur;
RV_SeekEnd_AudioEN = 0;
SyncDisable();
}
}
}
}
else
{
IndexTemp = 13;
}
}
else //快进快退时不做同步
{
showed_time = FreshFrame[IndexTemp].Time;
FrameOutputIndex = IndexTemp;
FreshFrame[IndexTemp].State = 1;
FramesInBuff--;
if ((abs(SyncTime - showed_time)) <= 200)
SyncEnable = 1;
}
return IndexTemp;
}
/****************************************/
/* MAILBOX初始化,清空所有通道*/
/****************************************/
void Real_InitMailBox(void)
{
ReadReg32(AHB0_MAILBOX_BASE + 0X54);
ReadReg32(AHB0_MAILBOX_BASE + 0X5c);
ReadReg32(AHB0_MAILBOX_BASE + 0X64);
ReadReg32(AHB0_MAILBOX_BASE + 0X6c);
}
/****************************************/
/* 通过MAILBOX向ZSP发送消息 */
/****************************************/
void SendMsg2ZSp(MailBoxMSG *Msg)
{
unsigned long State;
unsigned long SendMsgTime = 0;;
if (Real_SendMailDisable)
return;
State = ReadReg32(AHB0_MAILBOX_BASE + 0x10);
while (State)
{
SendMsgTime ++;
State = ReadReg32(AHB0_MAILBOX_BASE + 0x10);
if (SendMsgTime >= 5000)
{
Msg->CMD = NULL;
RockOSSendMsg(MBGUI, AS_VIGU_VideoDecodeEnd, NULL);
return;
}
}
WriteReg32(AHB0_MAILBOX_BASE + 0x20, Msg->DAT0);
WriteReg32(AHB0_MAILBOX_BASE + 0x28, Msg->DAT1);
WriteReg32(AHB0_MAILBOX_BASE + 0x30, Msg->DAT2);
WriteReg32(AHB0_MAILBOX_BASE + 0x38, Msg->DAT3);
WriteReg32(AHB0_MAILBOX_BASE + 0x24, Msg->CMD);
Msg->CMD = NULL;
}
/****************************************/
/* MAILBOX中断处理函数 */
/* 处理ZSP发送过来的消息 */
/****************************************/
void MailBoxISR(void)
{
MailBoxMSG Msg;
//RealDecoderCnt = 0;
Msg.DAT0 = ReadReg32(AHB0_MAILBOX_BASE + 0X50);
Msg.DAT1 = ReadReg32(AHB0_MAILBOX_BASE + 0X58);
Msg.DAT2 = ReadReg32(AHB0_MAILBOX_BASE + 0X60);
Msg.DAT3 = ReadReg32(AHB0_MAILBOX_BASE + 0X68);
Msg.CMD = ReadReg32(AHB0_MAILBOX_BASE + 0X54);
switch (Msg.CMD)
{
case MSG_ZSP2ARM_SYSINTCMP:
Msg.CMD = MSG_ARM2ZSP_INIT;
Msg.DAT0 = (unsigned long)yuvBuf;
Msg.DAT1 = (unsigned long)YUV_BUFFER_NUM;
Msg.DAT2 = (unsigned long)RealDecTab;
SendMsg2ZSp(&Msg);
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoFillBuf, (void*)0);
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoFillBuf, (void*)1);
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoFillBuf, (void*)2);
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoFillBuf, (void*)3);
RealVideoSkipEnble = 1;
WriteReg32(0x3000fff0, 1);// 1:DEBLIOCING,0,no
break;
case MSG_ZSP2ARM_DATAEMPTY: //shuju
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoFillBuf, (void*)Msg.DAT0);
break;
case MSG_ZSP2ARM_OUTPUTFRAME: //frame
RealPutFrameToFIFO(2, (short)Msg.DAT0, Msg.DAT1);
break;
case MSG_ZSP2ARM_DEBUG:
//RockOSSendMsg(MBVIDEO,AS_GUVI_RealDeBug, NULL);
break;
case MSG_ZSP2ARM_INITFRAME:
ScreenChangeEnable = 1;
Real_PicWidth = (short)Msg.DAT0;
Real_PicHeight = (short)Msg.DAT1;
break;
case MSG_ZSP2ARM_EXITDECODER:
RealExitState = 1;
if (!Real_InitEnable)
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoStop, NULL);
break;
default:
break;
}
}
/****************************************/
/* 输出帧控制时间中断管理 */
/****************************************/
void real_timer_counter()
{
short indextemp;
MailBoxMSG Msg;
//MailBoxMSG *Msg;
real_timer_tick += 4;
RealLcdWaitCnt += 4;
if (RealLcdWaitCnt < 16)
return;
if (Screen_GetMCUIFStatus() != IDLE)
return;
indextemp = RealGetFrameFromFIFO();
if (indextemp != 13)
{
RealLcdWaitCnt = 0;
if (FreshFrame[indextemp].ChangScreen)
{
FreshFrame[indextemp].ChangScreen = 0;
CreateRealScreen(Real_PicWidth, Real_PicHeight);
LCDCDev.ReConfig = 1;
}
if (ScreenMode == FullScreen)
Screen_Change(&RealVideoScreen[FreshFrame[indextemp].PicNo]);
else if (ScreenMode == LineArity)
Screen_Change(&RealVideoScreenTemp[FreshFrame[indextemp].PicNo]);
#ifdef MCU_PANEL
while (Lcdctrl_GetStatus() == 1);
LCDC_UpDate();
#endif
if (PrePrePreIndex != -1)
{
//Msg = Real_GetEmptyMailBox();
Msg.CMD = MSG_ARM2ZSP_EMPTYFRAME;
Msg.DAT0 = FreshFrame[PrePrePreIndex].PicNo;
FreshFrame[PrePrePreIndex].State = 0;
SendMsg2ZSp(&Msg);
//SendMsg2ZSp(Msg);
//RockOSSendMsg(MBVIDEO, AS_GUVI_RealSendMsg, (void*)Msg);
}
PrePrePreIndex = PrePreIndex;
PrePreIndex = PreIndex;
PreIndex = indextemp;
if (RealVideoSkipEnble)
{
if ((FramesInBuff < 1) && RV_AddDecodeSpeed)
{
if (RealSkipState == 0)
{
RealSkipState = 1;
Msg.CMD = MSG_ARM2ZSP_SKIPSTART;
Msg.DAT0 = RealSkipState;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -