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

📄 mpegvideocontrol.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************************
Copyright (C), 2007, Fuzhou Rockchip Co.,Ltd.
File:
 MpegVideoControl.c
Description:
 Mpeg video control.
Note:
 None.
Author:
 ljn
$Log: MpegVideoControl.c,v $
Revision 1.11  2008/07/17 09:00:29  HZF
缩短退出时间

Revision 1.10  2008/07/09 10:13:52  HZF
接口更改

Revision 1.9  2008/07/09 10:06:41  HZF
更改接口

Revision 1.8  2008/07/08 07:30:09  HZF
修改M peg2接口

Revision 1.7  2008/07/03 07:48:39  HZF
退出显示最后一屏

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

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

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

Revision 1.3  2008/06/06 09:22:08  HJK
增加TVOUT功能

Revision 1.2  2008/05/24 09:37:05  HZF
MPEG-1/2的支持

Revision 1.1  2008/05/20 12:02:22  HZF
mpg文件播放提交


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

#include "include.h"
#include "fs.h"
#include "hw_include.h"
#include "videowin.h"
#include "DualCoreApi.h"
#include "Mpeg4Contrl.h"
#include "MpegVideoControl.h"
#include "MpegFile.h"
#include "../VideoCodecs/VideoCodecs.h"
#include "../audio/include/audio_globals.h"

#define MPEG_DEC_EXIT  2
#define MPEG_TIMER_TICK  15

unsigned int mpegCurFrame, mpegTimeOut, skipFrms;
int mpegfilledBlock;
static int mpegLastYuvID, redressTime, mpegCurTime;

char *mpegBitStreamBuf;
char *mpegYuvBuf;
char *mpegVideoBufRemain;
char *mpegMbMvInfoBuf;
BACKGRND *mpegVideoScreen;
DWDMALLP *mpegVideoLLPList;

BACKGRND *mpegVideoScreenTemp;
DWDMALLP *mpegVideoLLPListTemp;
extern unsigned short *frameList;
extern unsigned int timerCnt;
extern int dispYuvNum;
UINT16   gMpgFunPmu;
extern BOOLEAN   gSDModeFlag;


void MpegCtrlInit(void)
{
    /* initialize share memory. */
    ShareMemInit((unsigned int *)mpegBitStreamBuf, (unsigned int *)mpegYuvBuf, (unsigned int *)mpegMbMvInfoBuf, 0, 0, 0);

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

    mpegfilledBlock = 0;
    mpegCurFrame = 0;
    dispYuvNum = 0;
    timerCnt = mpeg.startTime;
    skipFrms = 0;
    redressTime = 0;
    mpegLastYuvID = -1;
    mpegTimeOut = 0x3fffff;
}

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

    if ((mpegPlayState == MPEG_STATE_STOP) || (mpegPlayState == MPEG_STATE_INITIALIZING))
        return 0;
    if ((mpegPlayState != MPEG_STATE_PLAYING) && (!AllBufEmpty(mpegfilledBlock)))      //use only one bit stream buf when ffd/ffw
    {
        return 0;
    }
    if (!AllBufFull(mpegfilledBlock))
    {
        mpegfilledBlock ++;
        if (MpegVideoGetDataToSDRAM(&mpeg, (char *)(mpegBitStreamBuf + ((mpegfilledBlock - 1)&0xf)*BITSREAM_BUFFER_SIZE), &size))
        {
            if ((mpegPlayState == MPEG_STATE_FFD) || (mpegPlayState == MPEG_STATE_FFW))
            {
                //MpegResume();//return 0;
                mpegfilledBlock --;
                LCDC_UpDate();
                return 0;
            }
            SendBlock(mpegfilledBlock);
            SendLastBlockInfo(size);
            return -1;
        }

        SendBlock(mpegfilledBlock);
    }
    return 0;
}

extern SCALEMODE ScreenMode;
extern INT16  ScreenModeSetSign ;
void MpegCreateVideoScreen(void)
{
    int i, width = mpeg.width, height = mpeg.height;

    for (i = 0; i < YUV_BUFFER_NUM; i++)
    {
        Screen_CreatMPEG2(&mpegVideoScreen[i], &mpegVideoLLPList[i*1000], (unsigned long)((unsigned long)(mpegYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(i)), NULL,width, height,FullScreen);
        Screen_CreatMPEG2(&mpegVideoScreenTemp[i], &mpegVideoLLPListTemp[i*1000], (unsigned long)((unsigned long)(mpegYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(i)),NULL, width, height,LineArity);

    }
    Screen_CreatMPEG2(&mpegVideoScreen[YUV_BUFFER_NUM], &mpegVideoLLPList[YUV_BUFFER_NUM*1000], (unsigned long)((unsigned long)(mpegYuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(YUV_BUFFER_NUM)),NULL, width, height,FullScreen);
}

void MpegTimerCallBack(void)
{

    if ((mpegPlayState == MPEG_STATE_STOP) || (mpegPlayState == MPEG_STATE_INITIALIZING))
    {
        return ;
    }

    timerCnt += MPEG_TIMER_TICK;
    mpeg.auCurTime += MPEG_TIMER_TICK;

    if (IsYuvReady(mpegCurFrame))
    {
        mpegCurTime = GetFrameTime(mpegCurFrame);
        if (1)  //(mpegPlayState == MPEG_STATE_PLAYING){
        {
            if ((!mpeg.auCodec) || (!mpeg.auCurTime))
                mpeg.auCurTime = timerCnt;

            /* get redress time */
            if (!redressTime)
            {
                if (mpegCurTime != mpeg.startTime)
                {
                    //redressTime = ((mpegCurTime < mpeg.startTime) ? (mpeg.startTime - mpegCurTime) : 1);
                    redressTime = (int)mpeg.startTime - (int)mpegCurTime;
                }
                else
                {
                    redressTime = 1;
                }
            }

            if (skipFrms)
                skipFrms--;
            else if ((mpeg.auCurTime) && (mpegCurTime + redressTime > (int)mpeg.auCurTime))
                return;

            /**********************************************
            Skip frames control. We will skip 2 frames
            when more than 70 ms are delayed.
            ***********************************************/
            if ((mpegCurTime) && (mpeg.auCurTime > mpegCurTime + redressTime + 70)
                    && (GetDiscrepancy() < 2))
            {
                SendSkipFrameNum(2);
            }

        }

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

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

        /* save last buffer id for video cap. */
        mpegLastYuvID = frameList[mpegCurFrame];

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

void MpegDecExit(void)
{
    int timeOutCnt = 0;

    if (mpegPlayState == MPEG_STATE_STOP)
        return;

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

    /* Close video file. */
    MpegFileClose(&mpeg);

#if 1
    if (mpegPlayState != MPEG_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()) != MPEG_DEC_EXIT)
        {
            delay_nops(300);
            if ((timeOutCnt++) > 0x8fff)   // chang by hzf 0x1fffff
            {
                break;
            }
        }
    }
#endif

    mpegPlayState = MPEG_STATE_STOP;

    /* Disable Dsp */
    //PMU_ExitModule(PMU_VIDEOHIGH);
    if (CODEC_AC3_DEC == CurrentCodec)
        PMU_ExitModule(PMU_VIDEOLOW);
    if (gSDModeFlag == 0)
    {
        if (gMpgFunPmu == 2)
            PMU_ExitModule(PMU_VIDEOMEDLOW);
        else if (gMpgFunPmu == 3)
            PMU_ExitModule(PMU_VIDEOMED);
        else if (gMpgFunPmu == 4)
            PMU_ExitModule(PMU_VIDEOMEDHIGH);
        else if (gMpgFunPmu == 5)
            PMU_ExitModule(PMU_VIDEOHIGH);
        else if (gMpgFunPmu == 6)
            PMU_ExitModule(PMU_VIDEOLOWL);
        else if (gMpgFunPmu == 7)
            PMU_ExitModule(PMU_VIDEOLOWLL);
        gMpgFunPmu = 0;
    }
    else if (gSDModeFlag == 1)
    {
        PMU_ExitModule(PMU_VIDEOHIGH);
    }
    if ((mpegYuvBuf == NULL) || (mpegLastYuvID == -1))
        return;
    memcpy((mpegYuvBuf+(YUV_BUFFER_NUM) * YUV_BUFFER_SIZE),(mpegYuvBuf+(mpegLastYuvID) * YUV_BUFFER_SIZE),YUV_BUFFER_SIZE);
    Screen_Change(&mpegVideoScreen[YUV_BUFFER_NUM]);

}

void MpegFrameDispCtrl(void)
{
    //if(mpeg.frameRate <= 0.0)
    //    return;

    /* set timer tick .  */
    //(((1000000 + mpeg.frameRate/2)/mpeg.frameRate + (TIMER_ISR_NUM_PER_FRAME>>1))/TIMER_ISR_NUM_PER_FRAME)
    StartHWVideoTimer(MPEG_TIMER_TICK * 1000, MpegTimerCallBack);
}

int MpegIsLastFrame(void)
{
    if ((mpegPlayState != MPEG_STATE_PLAYING) || (mpegTimeOut == 0) || (GetDecStatus() == MPEG_DEC_EXIT))
        return 1;

    mpegTimeOut--;
    return 0;
}

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

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

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

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

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

#else   /* use fixed buffer. */

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

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

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

    /* video screen buffer for lcd update. */
    mpegVideoScreen = (BACKGRND *)(mpegMbMvInfoBuf + (((mpeg.width + 15) >> 4) * ((mpeg.height + 15) >> 4) * 32));

⌨️ 快捷键说明

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