?? avifile.c
字號(hào):
/********************************************************************************************
Copyright (C), 2007, Fuzhou Rockchip Co.,Ltd.
File:
AviFile.c
Description:
Parse and demux AVI file.
Note:
None.
Author:
ljn
$Log: AviFile.c,v $
Revision 1.7 2008/07/08 12:50:42 HZF
增加PCM解碼
Revision 1.6 2008/06/19 04:42:31 Administrator
代碼整理!
Revision 1.5 2008/06/13 08:44:42 HZF
總幀數(shù)不對(duì)的片源處理
Revision 1.4 2008/06/04 09:55:58 HZF
Seek時(shí)間不準(zhǔn)問題
Revision 1.3 2008/05/30 09:47:25 HZF
avibug
Revision 1.2 2008/05/20 12:00:56 HZF
avi文件播放提交
Revision 1.1.1.1 2008/05/07 04:14:50 Administrator
no message
Revision 1.1.1.1 2008/03/06 13:28:26 Lingzhaojun
no message
Revision 1.4 2007/12/11 12:13:47 Huangzufang
video提交
Revision 1.3 2007/11/21 10:12:41 Linjiangnan
*** empty log message ***
Revision 1.1 2007/11/16 14:43:19 Huangxinyu
提交ljn的video
********************************************************************************************/
#define _IN_AVIFILE_H
#include "system.h"
#include "AviFile.h"
CurChunk videoChunkSkipTo;
unsigned int beingSkip, audioChunkNum, audioTimePerChunk, NDCodeRemain, moviCkSize, skipResume, audioBytePos, lastSkipPoint, audioSteamID;
char NDCode[] = {0xb7, 0x01, 0x00, 0x00};
idx1 chunkList[AVI_CHUNK_LIST_NUM];
unsigned long indexSize;
extern int isAudioPlayEnd;
/********************************************************************************************
Func:
AviSeek()
Description:
Seek the AVI file for a requested chunk .
Param:
MY_FILE *file - pointer of avi file.
FOURCC ckID - sign of chunk to seek.
Return:
0: Fail.
>1: Size of the chunk.
Author:
ljn
Date:
2007-9-17 15:38
Log:
********************************************************************************************/
#if 0
int AviSeek(MY_FILE *file, FOURCC ckID)
{
struct
{
FOURCC CkID;
DWORD Size;
} chunk;
if (AviFread(&chunk, sizeof(chunk), 1, file) < sizeof(chunk))
return 0;
while (chunk.CkID != ckID)
{
AviFseek(file, chunk.Size, SEEK_CUR);
if (AviFread(&chunk, sizeof(chunk), 1, file) < sizeof(chunk))
return 0;
}
return chunk.Size;
}
#else
int AviSeek(MY_FILE *file, FOURCC ckID)
{
int timeOut = 0;
struct
{
FOURCC CkID;
DWORD Size;
} chunk;
if (AviFread(&chunk, sizeof(chunk), 1, file) < sizeof(chunk))
return 0;
while (chunk.CkID != ckID)
{
/* skip chunk. */
AviFseek(file, chunk.Size, SEEK_CUR);
/* read chunk head. */
if (AviFread(&chunk, sizeof(chunk), 1, file) < sizeof(chunk))
return 0;
chunk.Size += (chunk.Size & 0x1); //NOTICE: 2-align@jianhuan
/* time out control. */
if ((timeOut++) > 1000)
return 0;
}
return chunk.Size;
}
#endif
/********************************************************************************************
Func:
AviGetChunkPointer()
Description:
Get file pointer of chunks.
Param:
MY_FILE *file - pointer of avi file.
FOURCC ckID - sign of chunk to seek (only hdrl, movi and idx1 is supported).
Return:
0: OK.
-1: failed.
Author:
ljn
Date:
2007-12-07 13:38
Log:
********************************************************************************************/
int AviGetChunkPointer(AVI_FILE *file, FOURCC ckID)
{
DWORD riffType;
struct
{
FOURCC CkID;
DWORD Size;
DWORD Type;
} list;
AviFseek(file, 0, SEEK_SET);
/* Check if it is a riff file. */
if (!AviSeek(file, SIGN_RIFF))
return -1;
if (AviFread(&riffType, 1, sizeof(riffType), file) < sizeof(riffType))
return -1;
/* Check if it is a avi riff file. */
if (riffType != SIGN_AVI_)
return -1;
switch (ckID)
{
case SIGN_IDX1:
{
/* Seek 'idx1'. */
if ((indexSize = AviSeek(file, ckID)) == 0)
return -1;
}
break;
case SIGN_HDRL:
case SIGN_MOVI:
{
/* Find list. */
if (AviFread(&list, 1, sizeof(list), file) < sizeof(list))
return -1;
list.Size += (list.Size & 0x1); //NOTICE: 2-align @ jianhuan
while (list.Type != ckID)
{
AviFseek(file, list.Size - 4, SEEK_CUR);
if (AviFread(&list, 1, sizeof(list), file) < sizeof(list))
return -1;
}
if (list.Type == SIGN_MOVI)
moviCkSize = list.Size;
}
break;
default:
return -1;
}
return 0;
}
/********************************************************************************************
Func:
AviCreateSeekTab()
Description:
Create seek table.
Param:
AviFilePointer *aviPointer - avi file pointer.
unsigned int idx1Size - index size.
Return:
0: OK.
-1: failed.
Author:
ljn
Date:
2007-12-07 13:38
Log:
********************************************************************************************/
extern char gVideoBufferMix[];
int AviCreateSeekTab(AviFilePointer *aviPointer, unsigned int idx1Size)
{
idx1 *indexBuf;
unsigned int i, j = 0, audioCkNum = 0, videoCkNum = 0, totalCkNum = 0, keyFrmNum = 0, audioByteNum = 0;
unsigned int bufSize = (0x20000 * sizeof(idx1)), ckNumRead = 0x200000, audioInfoStep = 0;
int readSize;
/* buffer initialize */
#if 0
keyFrameList = (KeyFrame *)MALLOC(6000 * (sizeof(KeyFrame)));
indexBuf = (idx1 *)MALLOC(bufSize);
#else
keyFrameList = (KeyFrame *)(gVideoBufferMix + SYSCFG_VIDEOBUF_LEN - 6000 * (sizeof(KeyFrame)));
/* temporary buffer for avi index, this buffer will be used as yuv buffer affter decoder is started. */
indexBuf = (idx1 *)gVideoBufferMix;
#endif
/* Get step length to save audio information. */
if (audioChunkNum < AVI_AUDIO_POS_INFO_NUM)
audioInfoStep = 1;
else
audioInfoStep = (audioChunkNum >> 6) + 1;
for (;idx1Size > 0; idx1Size -= readSize)
{
/* Read index */
if (idx1Size > bufSize)
{
readSize = AviFread(indexBuf, 1, bufSize, aviPointer->VideoIndex);
}
else
{
readSize = AviFread(indexBuf, 1, idx1Size, aviPointer->VideoIndex);
}
if (readSize <= 0)
break;
ckNumRead = readSize / (sizeof(idx1));
/* create table. */
for (i = 0; i < ckNumRead; i++)
{
totalCkNum ++;
if (IS_VIDEO_IDX(indexBuf[i].dwChunkid))
{
/* video index. */
videoCkNum ++;
if ((indexBuf[i].dwFlags & 0x00000010) == 0x10) /* save key frame information. */
{
keyFrameList[keyFrmNum].dwSize = indexBuf[i].dwSize;
keyFrameList[keyFrmNum].dwOffset = indexBuf[i].dwOffset;
if (stream_supported_flag.VideoCodecLib == VIDEO_CODEC_LIB_DIV3)
{
keyFrameList[keyFrmNum].dwSize += (8 + (indexBuf[i].dwSize & 0x1)); //將00dc和chunk size計(jì)算在內(nèi);
keyFrameList[keyFrmNum].dwOffset -= 8;
}
else if (stream_supported_flag.VideoCodecLib == VIDEO_CODEC_LIB_MJPG)
{
keyFrameList[keyFrmNum].dwSize += (4 + (indexBuf[i].dwSize & 0x1)); //將00dc和chunk size計(jì)算在內(nèi);
keyFrameList[keyFrmNum].dwOffset -= 4;
}
keyFrameList[keyFrmNum].dwNumber = totalCkNum;
keyFrameList[keyFrmNum].dwVideoFrameNum = videoCkNum;
keyFrmNum++;
}
#ifdef ON_RKFS
if ((videoCkNum % (avih.dwTotalFrames / AVI_VIDEO_POS_INFO_NUM + 1)) == 0) /* save video positon information. */
{
j = videoCkNum / (avih.dwTotalFrames / AVI_VIDEO_POS_INFO_NUM + 1);
AviFseek(aviPointer->VideoData, (long)(indexBuf[i].dwOffset + moviPos.Offset) - (long)(aviPointer->VideoData->Offset), SEEK_CUR);
videoDataPosInfo[j].Clus = aviPointer->VideoData->Clus;
videoDataPosInfo[j].Offset = aviPointer->VideoData->Offset;
}
}
else if ((stream_supported_flag.AudioSupportedFlag == TRUE) && (IS_AUDIO_NO1_IDX(indexBuf[i].dwChunkid))) //jianhuan
{
/* audio index. save audio pos info for fast positioning. */
audioCkNum ++;
audioByteNum += indexBuf[i].dwSize;
/* if((audioCkNum % (audioInfoStep)) == 0){
j = (audioCkNum)/(audioInfoStep);*/
j = (audioCkNum) / (audioInfoStep);
if ((j < AVI_AUDIO_POS_INFO_NUM) && (audioCkNum % (audioInfoStep)) == 0)
{
/* seek to current index pos. */
AviFseek(aviPointer->AudioIndex, (long)(totalCkNum * sizeof(idx1) + idx1Pos.Offset) - (long)(aviPointer->AudioIndex->Offset), SEEK_CUR);
/* save file pointer and audio data information. */
audioIndexPosInfo[j].filePos.Clus = aviPointer->AudioIndex->Clus;
audioIndexPosInfo[j].filePos.Offset = aviPointer->AudioIndex->Offset;
audioIndexPosInfo[j].streamChunkNum = audioCkNum;
audioIndexPosInfo[j].audioBytePos = audioByteNum;
}
#endif
}
}
}
/* Initialize key frame number. */
totalKeyFrmNum = keyFrmNum;
/* redress total frames. */
avih.dwTotalFrames = videoCkNum;
//FREE(keyFrameList);
//FREE(indexBuf);
return 0;
}
int AviIdxOffset(AVI_FILE *file)
{
unsigned long tmpLong[4];
memset(tmpLong, 0, 4*sizeof(unsigned long));
AviFread(&tmpLong, 4*sizeof(unsigned long), 1, file);
AviFseek(file, -4*sizeof(unsigned long), SEEK_CUR);
if (tmpLong[0] == fcc7Fxx)
return 1;
return 0;
}
int IsOdmlAvi(AVI_FILE *AviIdxFile, AVI_FILE *AviVideoFile)
{
FILE_POS tmpIdxFile, tmpVideoFile;
idx1 tmpIndex;
int readSize;
FOURCC tmpFcc;
tmpIdxFile.Clus = AviIdxFile->Clus;
tmpIdxFile.Offset = AviIdxFile->Offset;
tmpVideoFile.Clus = AviVideoFile->Clus;
tmpVideoFile.Offset = AviVideoFile->Offset;
memset(&tmpIndex, 0, sizeof(idx1));
do
{
readSize = AviFread(&tmpIndex, sizeof(tmpIndex), 1, AviIdxFile);
}
while (!IS_VIDEO_IDX(tmpIndex.dwChunkid));
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -