📄 mpegvideocontrol.c
字号:
/********************************************************************************************
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 + -