📄 mpeg4contrl.c
字号:
/********************************************************************************************
Copyright (C), 2007, Fuzhou Rockchip Co.,Ltd.
File:
Mpeg4Contrl.c
Description:
Mpeg4 Contrl.
Note:
None.
Author:
ljn
$Log: Mpeg4Contrl.c,v $
Revision 1.12 2008/07/03 07:48:21 HZF
退出显示最后一屏
Revision 1.11 2008/06/24 02:03:18 HZF
屏幕扩展优化
Revision 1.10 2008/06/19 04:42:31 Administrator
代码整理!
Revision 1.9 2008/06/13 08:44:08 HZF
暂停后快进问题
Revision 1.8 2008/06/13 08:08:30 HXY
提交hjk的TV-OUT bug修改
Revision 1.7 2008/06/12 06:34:13 HZF
Avi暂停后快进问题
Revision 1.6 2008/06/12 03:05:48 HXY
提交nzy修改的Screen接口调用(增加TV-OUT版本)
Revision 1.5 2008/06/06 09:21:51 HJK
增加TVOUT功能
Revision 1.4 2008/05/20 12:00:27 HZF
avi文件播放提交
Revision 1.3 2008/05/14 05:01:53 HZF
no message
Revision 1.2 2008/05/14 03:18:08 HZF
增加读取时间位置和AAC音频文件频率
Revision 1.1.1.1 2008/05/07 04:14:52 Administrator
no message
Revision 1.2 2008/03/07 11:50:07 Hanjiang
加入tvout
Revision 1.1.1.1 2008/03/06 13:28:26 Lingzhaojun
no message
Revision 1.12 2008/01/10 09:25:33 Lingzhaojun
发布0110版本
Revision 1.11 2008/01/08 12:19:17 Lingzhaojun
合并蓝魔970代码
Revision 1.9 2008/01/04 12:21:44 Lingzhaojun
no message
Revision 1.8 2007/12/28 14:06:39 Nizhenyu
支持RGB刷屏修改
Revision 1.7 2007/12/26 01:54:46 Huangzufang
视频修改提交
Revision 1.6 2007/12/24 07:54:38 Lingzhaojun
同步蓝魔版本基本模块
Revision 1.2 2007/12/21 10:06:55 Lingzhaojun
蓝魔二合一初步
Revision 1.1.1.1 2007/12/21 02:33:37 Lingzhaojun
12.21
Revision 1.4 2007/12/11 12:13:47 Huangzufang
video提交
Revision 1.2 2007/11/21 10:13:22 Linjiangnan
*** empty log message ***
********************************************************************************************/
#define _IN_MPEG4CONTRL_H
#include "include.h"
#include "fs.h"
#include "hw_include.h"
#include "videowin.h"
#include "DualCoreApi.h"
#include "AviFile.h"
#include "Mpeg4Contrl.h"
#include "AudioControl.h"
#include "../audio/include/audio_globals.h"
int aviTimeOut;
//MY_FILE *pfBitStream;
//char pathName[] = "D:\\bits0.dat";
int lastYuvBufId = 0;
/********************************************************************************************
Func:
ShareDataInit()
Description:
share Data init.
Param:
None.
Return:
None
Author:
ljn
Date:
2007-11-1 10:01
Log:
********************************************************************************************/
void AviShareDataInit(void)
{
int i;
/* initialize share memory. */
ShareMemInit((unsigned int *)bitStreamBuf, (unsigned int *)yuvBuf, (unsigned int *)mbMvInfoBuf, 0, avih.dwWidth, avih.dwHeight);
/* get start address of frame list. */
frameList = (unsigned short *)GetFrameList();
timerIsrTimes = 5; /* for normal frame display control. */
lcdUpdateTimer = 4; /* use this timer to ensure last frame is diaplayed. */
aviTimerCounter = 0; /* timer counter. */
filledBlockNum = 0;
curFrame = 0; /* current frame ID in frame list for display. */
displayedYuvBuffer = 0; /* use this one to redress lcd update delay in the begining. */
dispFrameNum = 0; /* counter of displayed frame. */
dispInterval = TIMER_ISR_NUM_PER_FRAME; /* use this one to control lcd update speed. */
ffd_ffw_times = 0; /* ffd/ffw times counter. */
fillBitStreamOff = FALSE;
lastYuvBufId = -1;
aviTimeOut = 0;
isAudioPlayEnd = FALSE;
//pfBitStream = (MY_FILE *)RKFSFileOpenW(pathName);
}
/********************************************************************************************
Func:
FillBitStreamForDecoder()
Description:
Fill BitStream For Decoder .
Param:
None.
Return:
0: OK
-1: File end.
Author:
ljn
Date:
2007-11-1 10:24
Log:
********************************************************************************************/
int AviFillBitStreamForDecoder(void *param)
{
DWORD size = BITSREAM_BUFFER_SIZE;
//unsigned int tempVideoChunkNum;
idx1 chunkInfo;
if ((fillBitStreamOff == TRUE) || (aviPlayState == AVI_STATE_STOP))
return 0;
/* use only one bit stream buffer when ffd/ffw. */
if ((((aviPlayState == AVI_STATE_FFD) || (aviPlayState == AVI_STATE_FFW)) && (!AllBufEmpty(filledBlockNum))))
{
return 0;
}
if ((!AllBufFull(filledBlockNum)))
{
filledBlockNum ++;
if (AviVideoGetDataToSDRAM(&aviPointer, (char *)(bitStreamBuf + ((filledBlockNum - 1)&0xf)*BITSREAM_BUFFER_SIZE), &size))
{
/* use this to prevent decoder from exiting when ffd/ffw. */
if ((aviPlayState == AVI_STATE_FFD) || (aviPlayState == AVI_STATE_FFW))
{
AviVideoGetPreIChunk(&aviPointer, &chunkInfo, 0, 2);
//AviResume(0);
return 0;
}
/* send last block to decoder */
SendBlock(filledBlockNum);
SendLastBlockInfo(size);
return -1;
}
#if 0 /* For debug. */
if (tempVal)
{
RKFSFileWrite((char *)(bitStreamBuf + ((filledBlockNum - 1)&0xf)*BITSREAM_BUFFER_SIZE), size, pfBitStream);
}
#endif
/* send filled block number to decoder */
SendBlock(filledBlockNum);
}
return 0;
}
/********************************************************************************************
Func:
CreateVideoScreen()
Description:
Create video screens .
Param:
None.
Return:
None
Author:
ljn
Date:
2007-11-1 10:37
Log:
********************************************************************************************/
extern SCALEMODE ScreenMode;
extern INT16 ScreenModeSetSign ;
void AviCreateVideoScreen(MainAVIHeader *avihdr)
{
int i, width = avihdr->dwWidth, height = avihdr->dwHeight;
for (i = 0; i < YUV_BUFFER_NUM; i++)
{
Screen_CreatVideo(&aviVideoScreen[i], &aviVideoLLPList[i*1000], (unsigned long)((unsigned long)(yuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(i)), width,
height, FullScreen);
Screen_CreatVideo(&aviVideoScreenTemp[i], &aviVideoLLPListTemp[i*1000], (unsigned long)((unsigned long)(yuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(i)), width,
height, LineArity);
}
Screen_CreatVideo(&aviVideoScreen[YUV_BUFFER_NUM], &aviVideoLLPList[YUV_BUFFER_NUM*1000], (unsigned long)((unsigned long)(yuvBuf) + (unsigned long)(YUV_BUFFER_SIZE)*(unsigned long)(YUV_BUFFER_NUM)), width,
height, FullScreen);
}
/********************************************************************************************
Func:
ShowVideoFrame()
Description:
Show video frame.
NOTE: This is timer interrupt service program. We have better not do many things here
such as reading file or seeking file.
Param:
None.
Return:
None
Author:
ljn
Date:
2007-11-1 10:56
Log:
********************************************************************************************/
void AviShowVideoFrame(void)
{
int numJumped;
if (aviPlayState == AVI_STATE_STOP)
{
return ;
}
/********************************************
[1] Add 1 to timer counter.
*********************************************/
timerIsrTimes++;
lcdUpdateTimer++;
aviTimerCounter++;
/********************************************
[2] Check if it is the time to update lcd.
*********************************************/
if ((timerIsrTimes < dispInterval) || (lcdUpdateTimer < 3))
return;
/**********************************************
[3] Skip frames control. We will skip 2 frames
when more than 3 frames are delayed.
***********************************************/
if ((timerIsrTimes > (TIMER_ISR_NUM_PER_FRAME*3)) //skip mode @LJN
&& aviPlayState == AVI_STATE_PALYING)
{
if (GetDiscrepancy() < 2) /* skip B frames only */
{
dispFrameNum += 2;
SendSkipFrameNum(2);
timerIsrTimes -= TIMER_ISR_NUM_PER_FRAME * 2;
}
else if (timerIsrTimes > (TIMER_ISR_NUM_PER_FRAME*5)) /* jump to next I frame */
{
#if 1
numJumped = AviJump2NextIChunk(&aviPointer, timerIsrTimes / TIMER_ISR_NUM_PER_FRAME);
dispFrameNum += numJumped;
timerIsrTimes -= TIMER_ISR_NUM_PER_FRAME * numJumped;
#endif
}
}
/**************************************************
[4] Check if the current YUV buffer is ready.
***************************************************/
if (IsYuvReady(curFrame))
{
/* Buffer ID in frame list is wrong. */
if (frameList[curFrame] >= YUV_BUFFER_NUM)
{
return;
}
/* Change screen and update lcd. */
if (ScreenMode == FullScreen)
Screen_Change(&aviVideoScreen[frameList[curFrame]]);
else if (ScreenMode == LineArity)
Screen_Change(&aviVideoScreenTemp[frameList[curFrame]]);
#ifdef MCU_PANEL
while (Lcdctrl_GetStatus() == 1);
LCDC_UpDate();
#endif
/* Redress lcd update delay in the begining. */
if (displayedYuvBuffer < 2)
{
displayedYuvBuffer ++;
}
else
{
SendYuvFinish(curFrame);
}
/* save last buffer id for video cap. */
lastYuvBufId = frameList[curFrame];
/* Change to next. */
curFrame = (++curFrame) % YUV_BUFFER_NUM;
dispFrameNum ++;
lcdUpdateTimer = 0;
timerIsrTimes -= dispInterval;
}
/****************************************************
[5] Syn video to audio. Run this at interval of 100
frames.
*****************************************************/
if ((aviTimerCounter % (TIMER_ISR_NUM_PER_FRAME * 100) == 0) && (aviTimerCounter / (TIMER_ISR_NUM_PER_FRAME * 100)))
{
if (aviPlayState == AVI_STATE_PALYING)
{
/* We subtract 2 from 'dispFrameNum' to redress lcd update delay. */
timerIsrTimes += TIMER_ISR_NUM_PER_FRAME * (AviSynVideo2Audio((dispFrameNum - 2)/* - (GetDiscrepancy())*/ + timerIsrTimes / TIMER_ISR_NUM_PER_FRAME));
}
}
}
/********************************************************************************************
Func:
DecodeEnd()
Description:
Decoder exit.
Param:
None.
Return:
None
Author:
ljn
Date:
2007-11-1 13:15
Log:
********************************************************************************************/
UINT32 gAviFunPmu;
extern BOOLEAN gSDModeFlag;
void AviDecodeEnd(void *param)
{
int timeOutCnt = 0;
if (aviPlayState == AVI_STATE_STOP)
return;
fillBitStreamOff = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -