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

📄 flvvideocontrol.c

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

 Revision 1.8  2008/06/24 02:03:34  HZF
 屏幕扩展优化

 Revision 1.7  2008/06/19 04:42:32  Administrator
 代码整理!

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

 Revision 1.5  2008/06/06 09:22:00  HJK
 增加TVOUT功能

 Revision 1.4  2008/05/24 09:35:46  HZF
  FLV选时错误的bug。

 Revision 1.3  2008/05/20 12:02:53  HZF
 flv文件播放提交

 Revision 1.2  2008/05/14 03:18:36  HZF
 增加读取时间位置

 Revision 1.1.1.1  2008/05/07 04:14:52  Administrator
 no message

 Revision 1.1.1.1  2008/03/06 13:28:26  Lingzhaojun
 no message


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

#include "include.h"
#include "fs.h"
#include "hw_include.h"
#include "videowin.h"
#include "DualCoreApi.h"
#include "Mpeg4Contrl.h"
#include "FlvVideoControl.h"
#include "FlvFile.h"

#define FLV_DEC_EXIT  2

unsigned int flvTimerCounter, flvCurFrame, flvDispTime, flvTimeOut, flvFrmPass;
int flvfilledBlock, flvTimerIsrTimes, flvTimerIsrTimes, flvSkipTimer, flvDispYuvNum, flvDispFrameNum, flvDispInterval;
int flvLastYuvID;

char *flvBitStreamBuf;
char *flvYuvBuf;
char *flvMbMvInfoBuf;
char *flvVideoBufRemain;
BACKGRND *flvVideoScreen;
DWDMALLP *flvVideoLLPList;

BACKGRND *flvVideoScreenTemp;
DWDMALLP *flvVideoLLPListTemp;
extern BOOLEAN gVideoPmuFlag;
extern unsigned short *frameList;

void FlvCtrlInit(void)
{
    /* initialize share memory. */
    ShareMemInit((unsigned int *)flvBitStreamBuf, (unsigned int *)flvYuvBuf, (unsigned int *)flvMbMvInfoBuf, 0, 0, 0);

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

    flvTimerIsrTimes = 0;
    flvTimerCounter = 0;
    flvSkipTimer = 0;
    flvfilledBlock = 0;
    flvCurFrame = 0;
    flvDispYuvNum = 0;
    flvDispFrameNum = 0;
    flvDispTime = 0;
    flvDispInterval = TIMER_ISR_NUM_PER_FRAME;
    flvLastYuvID = -1;
    flvTimeOut = 0x3fffff;
    flvFrmPass = 0;
}

int FlvFillBitStream(void)
{
    DWORD size = BITSREAM_BUFFER_SIZE;
    idx1 chunkInfo;

    if ((flvPlayState == FLV_STATE_STOP) || (flvPlayState == FLV_STATE_INITIALIZING))
        return 0;
    if ((flvPlayState != FLV_STATE_PLAYING) && (!AllBufEmpty(flvfilledBlock)))      //use only one bit stream buf when ffd/ffw
    {
        return 0;
    }
    if (!AllBufFull(flvfilledBlock))
    {
        flvfilledBlock ++;
        if (FlvVideoGetDataToSDRAM(&flv, (char *)(flvBitStreamBuf + ((flvfilledBlock - 1)&0xf)*BITSREAM_BUFFER_SIZE), &size))
        {
            if ((flvPlayState == FLV_STATE_FFD) || (flvPlayState == FLV_STATE_FFW))
            {
                //FlvResume();//return 0;
                flvfilledBlock --;
                LCDC_UpDate();
                return 0;
            }
            SendBlock(flvfilledBlock);
            SendLastBlockInfo(size);
            return -1;
        }

        SendBlock(flvfilledBlock);
    }
    return 0;
}
extern SCALEMODE ScreenMode;
extern INT16  ScreenModeSetSign ;
void FlvCreateVideoScreen(void)
{
    int i, width = flv.width, height = flv.height;

    for (i = 0; i < YUV_BUFFER_NUM; i++)
    {
        Screen_CreatVideo(&flvVideoScreen[i], &flvVideoLLPList[i*1000], (unsigned long)((unsigned long)(flvYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(i)), width, height, FullScreen);
        Screen_CreatVideo(&flvVideoScreenTemp[i], &flvVideoLLPListTemp[i*1000], (unsigned long)((unsigned long)(flvYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(i)), width, height, LineArity);

    }
    Screen_CreatVideo(&flvVideoScreen[YUV_BUFFER_NUM], &flvVideoLLPList[YUV_BUFFER_NUM*1000], (unsigned long)((unsigned long)(flvYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(YUV_BUFFER_NUM)), width, height, FullScreen);
}

void FlvTimerCallBack(void)
{
    int frmTime;

    if ((flvPlayState == FLV_STATE_STOP) || (flvPlayState == FLV_STATE_INITIALIZING))
    {
        return ;
    }

    /********************************************
     [1] Add 1 to timer counter.
    *********************************************/
    flvTimerIsrTimes++;
    flvTimerCounter++;

    /********************************************
     [2] Check if it is the time to update lcd.
    *********************************************/
//#if 0
    if (((!flv.audioFlag) || (flvFrmPass)) && (flvTimerIsrTimes < flvDispInterval))
        return;
//#else
    frmTime = GetFrameTime(flvCurFrame);

    if ((flv.audioFlag) && (frmTime > flv.curAudio.time) && (flvPlayState == FLV_STATE_PLAYING) && (!flvFrmPass))
        return;

//#endif

    /**************************************************
     [3] Check if the current YUV buffer is ready.
    ***************************************************/
    if (IsYuvReady(flvCurFrame))
    {

        /* Buffer ID in frame list is wrong. */
        if (frameList[flvCurFrame] >= YUV_BUFFER_NUM)
        {
            return;
        }

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


        flvDispTime = frmTime;

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

        /* save last buffer id for video cap. */
        flvLastYuvID = frameList[flvCurFrame];

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

        flvDispFrameNum ++;
        flvTimerIsrTimes -= flvDispInterval;
    }
}

UINT32 gFlvFunPmu;
extern BOOLEAN gSDModeFlag;

void FlvDecExit(void)
{
    int timeOutCnt = 0;
    if (flvPlayState == FLV_STATE_STOP)
        return;

    dispFrameNum = 0;

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

    /* Close video file. */
    FlvFileClose(&flv);

#if 1
    if (flvPlayState != FLV_STATE_INITIALIZING)
    {

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

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

    flvPlayState = FLV_STATE_STOP;

    if (gSDModeFlag == 0)
    {
        if (gFlvFunPmu == 2)
            PMU_ExitModule(PMU_VIDEOMEDLOW);
        else if (gFlvFunPmu == 3)
            PMU_ExitModule(PMU_VIDEOMED);
        else if (gFlvFunPmu == 4)
            PMU_ExitModule(PMU_VIDEOMEDHIGH);
        else if (gFlvFunPmu == 5)
            PMU_ExitModule(PMU_VIDEOHIGH);
        else if (gFlvFunPmu == 6)
            PMU_ExitModule(PMU_VIDEOLOWL);
        else if (gFlvFunPmu == 7)
            PMU_ExitModule(PMU_VIDEOLOWLL);
        gFlvFunPmu = 0;
    }
    else if (gSDModeFlag == 1)
    {
        PMU_ExitModule(PMU_VIDEOHIGH);
    }
    if ((flvYuvBuf == NULL) || (flvLastYuvID == -1))
        return;
    memcpy((flvYuvBuf+(YUV_BUFFER_NUM) * YUV_BUFFER_SIZE),(flvYuvBuf+(flvLastYuvID) * YUV_BUFFER_SIZE),YUV_BUFFER_SIZE);
    Screen_Change(&flvVideoScreen[YUV_BUFFER_NUM]);

}

void FlvFrameDispCtrl(void)
{
    if (!flv.frameRate)
        return;
    /* set timer tick - 5 times per frame.  */
    StartHWVideoTimer((((1000000 + flv.frameRate / 2) / flv.frameRate + (TIMER_ISR_NUM_PER_FRAME >> 1)) / TIMER_ISR_NUM_PER_FRAME), FlvTimerCallBack);
}

int FlvIsLastFrame(void)
{

    if ((flvPlayState != FLV_STATE_PLAYING) || (flvTimeOut == 0))
        return 1;

    /* frame number is subtracted by 1, because of the video decoder may not decode the last frame. */
    if ((IsLastBlockGot(flvfilledBlock)) && (flvDispTime >= flv.curVideo.time - 200))
    {
        return 1;
    }
    else if (GetFrameTime(flvCurFrame) > flv.curAudio.time)
    {
        flvFrmPass = 1;
    }
    flvTimeOut --;
    return 0;
}

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

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

    if ((flvMbMvInfoBuf = MALLOC(((flv.width + 15) >> 4) * ((flv.height + 15) >> 4) * 32)) == 0)
        return -1;

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

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

#else   /* use fixed buffer. */

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

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

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

    /* video screen buffer for lcd update. */
    flvVideoScreen = (BACKGRND *)(flvMbMvInfoBuf + (((flv.width + 15) >> 4) * ((flv.height + 15) >> 4) * 32));

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

    flvVideoScreenTemp = (BACKGRND*)((char *)flvVideoLLPList + ((YUV_BUFFER_NUM +1) * 1000 * (sizeof(DWDMALLP))));
    flvVideoLLPListTemp = (DWDMALLP *)((char *)flvVideoScreenTemp + (YUV_BUFFER_NUM * (sizeof(BACKGRND))));

    /* buffer remain. */
    flvVideoBufRemain = (char *)((char *)flvVideoLLPListTemp + (YUV_BUFFER_NUM * 1000 * (sizeof(DWDMALLP))));

    //flv.keyFrm = (FlvKeyFrame *)((char*)flvVideoBufRemain + 64 * 1024);
#endif
    return 0;
}

int FlvFileInit(char *path)
{
    int err;

    flvPlayState = FLV_STATE_INITIALIZING;

    memset(&flv, 0, sizeof(FlvDemux));
    flv.keyFrm = (FlvKeyFrame *)((char *)gVideoBufferMix + SYSCFG_VIDEOBUF_LEN - 128 * 1024);

    /* open flv file. */
    if (FlvFileOpen(&flv, path))
    {
        flvPlayState = FLV_STATE_STOP;
        FlvFileClose(&flv);
        return FLV_FILE_OPEN_ERR;
    }

    /* parse flv file. */
    if ((err = FlvFileParsing(&flv)))

⌨️ 快捷键说明

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