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