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

📄 asfvideocontrol.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************************
 Copyright (C), 2007, Fuzhou Rockchip Co.,Ltd.
 File:
  AsfVideoControl.c
 Description:
  Asf video control.
 Note:
  None.
 Author:
  ljn
 $Log: AsfVideoControl.c,v $
 Revision 1.7  2008/07/03 07:48:12  HZF
 退出显示最后一屏

 Revision 1.6  2008/06/24 02:03:09  HZF
 屏幕扩展优化

 Revision 1.5  2008/06/19 04:42:31  Administrator
 代码整理!

 Revision 1.4  2008/06/12 03:05:37  HXY
 提交nzy修改的Screen接口调用(增加TV-OUT版本)

 Revision 1.3  2008/06/06 09:21:42  HJK
 增加TVOUT功能

 Revision 1.2  2008/05/24 09:35:26  HZF
 WMV 7/8/9的支持;

 Revision 1.1  2008/05/20 12:01:41  HZF
 asf文件播放提交


********************************************************************************************/

#include "include.h"
#include "fs.h"
#include "hw_include.h"
#include "videowin.h"
#include "DualCoreApi.h"
#include "Mpeg4Contrl.h"
#include "AsfVideoControl.h"
#include "AsfFile.h"
#include "../VideoCodecs/VideoCodecs.h"

#define WMV3_RES_PATH   "C:\\SYSTEM\\wmv3_tab.bin"
#define WMV2_RES_PATH   "C:\\SYSTEM\\wmv2_tab.bin"

#define ASF_DEC_EXIT  2

#define ASF_FFD_FFW_MIN_INTERVAL        3000
#define ASF_TIME_OUT                    (0x2fffff)
#define ASF_TIMER_TICK                  10

#define ASF_HURRY_MIN_DELAY             400
#define ASF_HURRY_UP_ADD_TIME           350
#define ASF_HURRY_UP_MAX_AHEAD          1500

unsigned int asfCurFrame, asfCurTime, lastSeekTime, timerCnt;
int asffilledBlock, dispYuvNum;
int asfTimeOut, hurry, videoDecErrCnt;

char *asfBitStreamBuf;
char *asfYuvBuf;
char *asfVideoBufRemain;
char *asfMbMvInfoBuf;
BACKGRND *asfVideoScreen;
DWDMALLP *asfVideoLLPList;

BACKGRND *asfVideoScreenTemp;
DWDMALLP *asfVideoLLPListTemp;
extern unsigned short *frameList;
extern int lastYuvBufId ;

extern __inline int AsfAudioSeek(int msTime);
extern __inline int AsfAudioGetCurTime(void);
extern BOOLEAN   gSDModeFlag;
UINT16   gasfFunPmu;
static void AsfVideoHurryUp(void);


//int tempVal = 1;
//MY_FILE  *pfBitStream;

static int WmvDecLoadRes(char *addr)
{
    AsfFILE *pfRes = 0;

    switch (asf.m_video_stream->m_type_specific.m_video.m_encoding)
    {
        case fccWMV3:
            pfRes = AsfFopen(WMV3_RES_PATH, "rb");
            break;
        case fccWMV2:
        case fccWMV1:
            pfRes = AsfFopen(WMV2_RES_PATH, "rb");
            break;
        default:
            return -1;
    }

    if (!pfRes)
        return -1;

    if (AsfFread(addr, 1, pfRes->FileSize, pfRes) <= 0)
        return -1;

    AsfFClose(pfRes);
    return 0;
}

void AsfCtrlInit(void)
{
    /* initialize share memory. */
    ShareMemInit((unsigned int *)asfBitStreamBuf, (unsigned int *)asfYuvBuf, (unsigned int *)asfMbMvInfoBuf, 1, 0, 0);

    /* get start address of frame list. */
    frameList = (unsigned short *)GetFrameList();

    asffilledBlock = 0;
    asfCurFrame = 0;
    asfCurTime = 0;
    lastSeekTime = 0;
    ffd_ffw_times = 0;
    dispYuvNum = 0;
    timerCnt = 0;
    lastYuvBufId = -1;
    //asfDispInterval = TIMER_ISR_NUM_PER_FRAME;
    asfTimeOut = 0;
    hurry = FALSE;
}

int AsfFillBitStream(void)
{
    gulong size = BITSREAM_BUFFER_SIZE;
    idx1 chunkInfo;

    if ((asfPlayState == ASF_STATE_STOP) || (asfPlayState == ASF_STATE_INITIALIZING))
        return 0;
    if ((asfPlayState != ASF_STATE_PLAYING) && (!AllBufEmpty(asffilledBlock)))      //use only one bit stream buf when ffd/ffw
    {
        return 0;
    }
    if (!AllBufFull(asffilledBlock))
    {
        asffilledBlock ++;
        /* hurry up */
        if (hurry == TRUE)
        {
            AsfVideoHurryUp();
        }
        if (AsfVideoGetDataToSDRAM(&asf, (char *)(asfBitStreamBuf + ((asffilledBlock - 1)&0xf)*BITSREAM_BUFFER_SIZE), &size))
        {
            if ((asfPlayState == ASF_STATE_FFD) || (asfPlayState == ASF_STATE_FFW))
            {
                asffilledBlock --;
                return 0;
            }

            SendBlock(asffilledBlock);
            SendLastBlockInfo(size);
            return -1;
        }

        SendBlock(asffilledBlock);
    }
    return 0;
}
extern SCALEMODE ScreenMode;
extern INT16  ScreenModeSetSign ;
void AsfCreateVideoScreen(void)
{
    int i, width = asf.m_width, height = asf.m_height;

    for (i = 0; i < YUV_BUFFER_NUM; i++)
    {
        Screen_CreatVideo(&asfVideoScreen[i], &asfVideoLLPList[i*1000], (unsigned long)((unsigned long)(asfYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(i)), width, height, FullScreen);
        Screen_CreatVideo(&asfVideoScreenTemp[i], &asfVideoLLPListTemp[i*1000], (unsigned long)((unsigned long)(asfYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(i)), width, height, LineArity);

    }
    Screen_CreatVideo(&asfVideoScreen[YUV_BUFFER_NUM], &asfVideoLLPList[YUV_BUFFER_NUM*1000], (unsigned long)((unsigned long)(asfYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(YUV_BUFFER_NUM)), width, height, FullScreen);
}

void AsfTimerCallBack(void)
{
    int audioTime;

    if ((asfPlayState == ASF_STATE_STOP) || (asfPlayState == ASF_STATE_INITIALIZING))
    {
        return ;
    }

    timerCnt += ASF_TIMER_TICK;

    if (IsYuvReady(asfCurFrame))
    {
#if 0
        /* Buffer ID in frame list is wrong. */
        if (frameList[asfCurFrame] >= YUV_BUFFER_NUM)
        {
            return;
        }
#endif
        asfCurTime = GetFrameTime(asfCurFrame);
        if (asfPlayState == ASF_STATE_PLAYING)
        {
            audioTime = AsfAudioGetCurTime();
            if (!audioTime)
                audioTime = timerCnt;
            if ((audioTime) && (asfCurTime > (audioTime + asf.m_start_position_time)))
                return;

            /**********************************************
            Skip frames control. We will skip 2 frames
            when more than 150 ms are delayed.
            ***********************************************/
            if ((audioTime + asf.m_start_position_time > asfCurTime + 150)
                    && (GetDiscrepancy() < 2))
            {
                SendSkipFrameNum(2);
            }
            else if (audioTime + asf.m_start_position_time > asfCurTime + ASF_HURRY_MIN_DELAY)
            {
                /* start hurry-up mode to ensure picture-sound synchronization */
                hurry = TRUE;
            }
        }

        /* Change screen and update lcd. */
        if (ScreenMode == FullScreen)
            Screen_Change(&asfVideoScreen[frameList[asfCurFrame]]);
        else if (ScreenMode == LineArity)
            Screen_Change(&asfVideoScreenTemp[frameList[asfCurFrame]]);
#ifdef  MCU_PANEL
        while (Lcdctrl_GetStatus() == 1);
        LCDC_UpDate();

#endif
        if ((asfPlayState == ASF_STATE_FFW_TEMP) && (asfCurTime < asf.m_seek_seg.object_start + 1000))
            asfPlayState = ASF_STATE_PLAYING;


        /* Redress lcd update delay in the begining. */
        if (dispYuvNum < 2)
        {
            dispYuvNum ++;
        }
        else
        {
            SendYuvFinish(asfCurFrame);
        }

        /* save last buffer id for video cap. */
        lastYuvBufId = frameList[asfCurFrame];

        /* Change to next. */
        asfCurFrame = (++asfCurFrame) % YUV_BUFFER_NUM;

        asfTimeOut = 0;
    }
}

void AsfDecExit(void)
{
    int timeOutCnt = 0;

    if (asfPlayState == ASF_STATE_STOP)
        return;


    /* Stop frame display timer. */
    Timer_PowerOffDeinit(0);

    /* Close video file. */
    AsfFileClose(&asf);
    //RKFSFileClose(pfBitStream);

#if 1
    if (asfPlayState != ASF_STATE_INITIALIZING)
    {

        /* set dsp nmi interrupt to exit. */
        ClrRegBit32(0x1801c028, 16);
        delay_nops(300);
        SetRegBit32(0x1801c028, 16);    /* nmi interrupt. */
        delay_nops(2000);
        ClrRegBit32(0x1801c028, 16);

        /* wating for decoder exit. */
        while ((GetDecStatus()) != ASF_DEC_EXIT)
        {
            delay_nops(300);
            if ((timeOutCnt++) > 0x1ffff)
            {
                break;
            }
        }
    }
#endif

    asfPlayState = ASF_STATE_STOP;

    /* Disable Dsp */
    //PMU_ExitModule(PMU_VIDEOHIGH);
    if (gSDModeFlag == 0)
    {
        if (gasfFunPmu == 2)
            PMU_ExitModule(PMU_VIDEOMEDLOW);
        else if (gasfFunPmu == 3)
            PMU_ExitModule(PMU_VIDEOMED);
        else if (gasfFunPmu == 4)
            PMU_ExitModule(PMU_VIDEOMEDHIGH);
        else if (gasfFunPmu == 5)
            PMU_ExitModule(PMU_VIDEOHIGH);
        else if (gasfFunPmu == 6)
            PMU_ExitModule(PMU_VIDEOLOWL);
        else if (gasfFunPmu == 7)
            PMU_ExitModule(PMU_VIDEOLOWLL);
        gasfFunPmu = 0;
    }
    else if (gSDModeFlag == 1)
    {
        PMU_ExitModule(PMU_VIDEOHIGH);
    }
    if ((asfYuvBuf == NULL) || (lastYuvBufId == -1))
        return;
    memcpy((asfYuvBuf+(YUV_BUFFER_NUM) * YUV_BUFFER_SIZE),(asfYuvBuf+(lastYuvBufId) * YUV_BUFFER_SIZE),YUV_BUFFER_SIZE);
    Screen_Change(&asfVideoScreen[YUV_BUFFER_NUM]);

}

void AsfFrameDispCtrl(void)
{
    /* set timer tick .  */
    StartHWVideoTimer(ASF_TIMER_TICK * 1000, AsfTimerCallBack);
}

int AsfIsLastFrame(void)
{
    if ((asfPlayState != ASF_STATE_PLAYING) || (asfTimeOut++ > ASF_TIME_OUT)
            || (asfCurTime >= asf.m_time_stamp_bak - 200) || (GetDecStatus() == ASF_DEC_EXIT))
        return 1;

    return 0;
}

int AsfVideoDecBufMalloc(void)
{
#if 0   /* use malloc. */
    if ((asfBitStreamBuf = MALLOC(BITSREAM_BUFFER_SIZE * MAX_BITSREAM_BLOCK_NUM)) == 0)
        return -1;

    if ((asfYuvBuf = MALLOC(YUV_BUFFER_NUM * YUV_BUFFER_SIZE)) == 0)
        return -1;

    //if((asfMbMvInfoBuf = MALLOC(((asf.width + 15)>>4)*((asf.height + 15)>>4)*32)) == 0)
    // return -1;

    if ((asfVideoScreen = (BACKGRND *)MALLOC(YUV_BUFFER_NUM * (sizeof(BACKGRND)))) == 0)
        return -1;

    if ((asfVideoLLPList = (DWDMALLP *)MALLOC(YUV_BUFFER_NUM * 1000 * (sizeof(DWDMALLP)))) == 0)
        return -1;

#else   /* use fixed buffer. */

    /* bit stream buffer for video decoder. */
    asfBitStreamBuf = gVideoBufferMix;

    /* yuv buffer for decoder output.  */
    asfYuvBuf = gVideoBufferMix + (BITSREAM_BUFFER_SIZE * MAX_BITSREAM_BLOCK_NUM);

    /* mb/mv information buffer for decoder. */
    asfMbMvInfoBuf = asfYuvBuf + ((YUV_BUFFER_NUM+1) * YUV_BUFFER_SIZE);

    /* video screen buffer for lcd update. */
    asfVideoScreen = (BACKGRND *)(asfMbMvInfoBuf + (((asf.m_width + 15) >> 4) * ((asf.m_height + 15) >> 4) * 32));

    /* dwdma llp list for each video screen. */
    asfVideoLLPList = (DWDMALLP *)((char *)asfVideoScreen + ((YUV_BUFFER_NUM+1) * (sizeof(BACKGRND))));

    asfVideoScreenTemp = (BACKGRND *)((char*)asfVideoLLPList + ((YUV_BUFFER_NUM+1) * 1000 * (sizeof(DWDMALLP))));
    asfVideoLLPListTemp = (DWDMALLP *)((char *)asfVideoScreenTemp + (YUV_BUFFER_NUM * (sizeof(BACKGRND))));
    /* buffer remain. */
    asfVideoBufRemain = (char *)((char *)asfVideoLLPListTemp + (YUV_BUFFER_NUM * 1000 * (sizeof(DWDMALLP))));


#endif
    return 0;
}

int AsfFileInit(char *path)
{
    int err;

    asfPlayState = ASF_STATE_INITIALIZING;

    /* open video stream file. */
    if (AsfFileOpen(&asf, path))
    {
        asfPlayState = ASF_STATE_STOP;
        AsfFileClose(&asf);
        return ASF_FILE_OPEN_ERR;
    }

    /* parse video file. */
    if ((err = AsfFileParsing(&asf)))
    {
        if (err == ASF_FILE_AUDIO_CODEC_ERR)     /* audio codec error is allowable. */
        {
            goto parse_ok;
        }
        AsfFileClose(&asf);
        asfPlayState = ASF_STATE_STOP;
        return err;
    }

parse_ok:
    /* load vld table for decoder. */
    if (WmvDecLoadRes((char *)(gVideoBufferMix + SYSCFG_VIDEOBUF_LEN - (150*1024))))
    {
        AsfFileClose(&asf);
        return ASF_FILE_OPEN_ERR;
    }

    return err;
}

int AsfVideoDecInit(void)
{
    int i;

    if (asfPlayState != ASF_STATE_INITIALIZING)
        return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -