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

📄 realfunctions.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -