www.pudn.com > RK225_Dict_08_28.rar > AviFile.c, change:2005-07-13,size:35005b
/*
********************************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* File name : avifile.c
* Author: Jiliu Huang
* Description: Parse .avi file, get the startaddress of video and audio data in this
* file.
* Others:
* Function list: AviFileIndentify(),GetNextAudioChunk(),
* GetNextVideoChunk(),
* GetNextVideoIFrameChunk(), GetPreVideoIFrameChunk().
* History:
* <author> <time> <version> <desc>
* Jiliu Huang 05/11/01 1.0 ORG
* Jiliu Huang 06/04/10 2.0 修改了快进快退功能的方式,以改进快进快退后
* 不同步的问题。
********************************************************************************************
* [1] 只有音频:正常播放、快进、快退均按CHUNK进行,但正常播放时计算Offset的方法不一样
* 因为在进行快进快退时不进行解码,即不要读取文件数据,因此在进行下一次操作时;
* 【GetNextAudioChunk,GetFFWAudioChunk,GetFFDAudioChunk】
* [2] 只有视频:正常播放时,按CHUNK进行;快进、快退按关键帧进行播放,即只有关键帧才送屏;
* 【GetNextVideoChunk,GetPrevAudioChunk】
* [3] 两者都有:正常播放时,按各自的CHUNK顺序进行;快进、快退按视频的关键帧进行。
*********************************************************************************************
*/
#define _IN_AVIFILE
//*******************************************************************************************
#include "avistruct.h"
#include "aviglobal.h"
#include "config.h"
#include "AviMacro.h"
#include "avistruct.h"
extern signed char hAudioIndex;
extern signed char hVideoIndex;
/********************************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* Function name : AviFileIdentify()
* Author: Jiliu Huang
* Description: Parse an .AVI file
* Input: Handle, avi_file_information
* Output: struct :avi_file_information
* Return: 0: can be decoded file; 1: file too short; 2: file format error
* Others:
* History:
* <author> <time> <version> <desc>
* Jiliu Huang 05/11/01 1.0 ORG
*
********************************************************************************************/
__attribute__((section(".avi_v_text, \"ax\"")))
int AviFileIdentify(signed char Handle,AVI_STREAM_INFO *avi_file_information)
{
signed char hAVIFile;
unsigned char tmpDataReadout[8];
unsigned char ReadoutNum;
unsigned long MicroSecPerFrame;
unsigned int blHaveIndex;
unsigned int AudioVedioInfo = 0;
unsigned long TotalFrames;
unsigned int TotalStreams;
int i;
unsigned long Seektmp;
unsigned long SeekSmall;
unsigned long MoviStartPos = 0;
unsigned long IndexStartPos = 0;
avi_file_information -> AviFileFormat = 0; // Set it has no audio stream or video stream
hAVIFile = Handle;
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
if(ReadoutNum < 8){
return 0x01; // File too short
}
if ((tmpDataReadout[0] != 'R') || (tmpDataReadout[1] != 'I')
||(tmpDataReadout[2] != 'F') || (tmpDataReadout[3] != 'F')){
return 0x02; // Not right AVI file
}
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
if(ReadoutNum < 8){
return 0x01; // File too short
}
if((tmpDataReadout[0] != 'A') || (tmpDataReadout[1] != 'V') || (tmpDataReadout[2] != 'I')){
return 0x02; // Not right AVI file
}
if ((tmpDataReadout[4] != 'L') || (tmpDataReadout[5] != 'I')
|| (tmpDataReadout[6] != 'S') || (tmpDataReadout[7] != 'T')){
return 0x02;
}
ReadoutNum = FileRead(tmpDataReadout, 4, hAVIFile); // Read out the LIST size
MoviStartPos += 4;
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
if ((tmpDataReadout[0] != 'h') || (tmpDataReadout[1] != 'd')
||(tmpDataReadout[2] != 'r') || (tmpDataReadout[3] != 'l')){
return 0x02; // Not right AVI file
}
if ((tmpDataReadout[4] != 'a') || (tmpDataReadout[5] != 'v')
|| (tmpDataReadout[6] != 'i') || (tmpDataReadout[7] != 'h')){
return 0x02;
}
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
MicroSecPerFrame = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 16;
if((((((unsigned long)((tmpDataReadout[3] << 8) | tmpDataReadout[2]))<< 16)
| ((tmpDataReadout[1] << 8) | tmpDataReadout[0])) & 0x00000010) != 0){
blHaveIndex = 1; // Have index chunk
}
else
return -1; // 如果没有INDEX部分,暂不支持. 20060313@hjl
TotalFrames = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
TotalStreams = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
ReadoutNum = FileRead(tmpDataReadout, 4, hAVIFile); // Read out dwSuggestedBufferSize
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 12;
if((((((unsigned long)((tmpDataReadout[3] << 8) | tmpDataReadout[2]))<< 16)
| ((tmpDataReadout[1] << 8) | tmpDataReadout[0])) != 224)
|| (((((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4])) != 176)){
return 0x02; // width not equal 160 or heigth not equal 120
}
FileSeek(16, SEEK_CUR, hAVIFile); // dwReserved[4]
MoviStartPos += 16;
for(i=0; i<TotalStreams; i++){
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile); // 'LIST' and list length
MoviStartPos += 8;
Seektmp = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
Seektmp -= 8;
if ((tmpDataReadout[0] != 's') || (tmpDataReadout[1] != 't')
|| (tmpDataReadout[2] != 'r') || (tmpDataReadout[3] != 'l')){
return 0x02;
}
if ((tmpDataReadout[4] != 's') || (tmpDataReadout[5] != 't')
|| (tmpDataReadout[6] != 'r') || (tmpDataReadout[7] != 'h')){
return 0x02;
}
ReadoutNum = FileRead(tmpDataReadout, 4, hAVIFile); // Read out size of 'strh'
SeekSmall = (((unsigned long)((tmpDataReadout[3] << 8) | tmpDataReadout[2]))<< 16)
| ((tmpDataReadout[1] << 8) | tmpDataReadout[0]);
MoviStartPos += 4;
Seektmp -= 4;
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
Seektmp -= 8;
SeekSmall -= 8;
if ((tmpDataReadout[0] == 'v') && (tmpDataReadout[1] == 'i')
&& (tmpDataReadout[2] == 'd') && (tmpDataReadout[3] == 's')){
if ((tmpDataReadout[4] != 'X') || (tmpDataReadout[5] != 'V')
|| (tmpDataReadout[6] != 'I') || (tmpDataReadout[7] != 'D')){
return 0x02; // Video format is not supported
}
(avi_file_information -> AviFileFormat) |= 2; // Have Video stream, set the flag
}
else if((tmpDataReadout[0] == 'a') && (tmpDataReadout[1] == 'u')
&& (tmpDataReadout[2] == 'd') && (tmpDataReadout[3] == 's')){
FileSeek(SeekSmall, SEEK_CUR, hAVIFile);
MoviStartPos += SeekSmall;
Seektmp -= SeekSmall;
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
Seektmp -= 8;
if ((tmpDataReadout[0] != 's') || (tmpDataReadout[1] != 't')
|| (tmpDataReadout[2] != 'r') || (tmpDataReadout[3] != 'f')){
return 0x02; // File format error
}
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
Seektmp -= 8;
if ((tmpDataReadout[0] != 0x50) || (tmpDataReadout[1] != 0)){
return 0x02; // Audio format is not supported
}
avi_file_information -> AudioSamplingRate = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
(avi_file_information -> AviFileFormat) |= 1; // Have audio stream, set the flag
// ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
// MoviStartPos += 8;
// Seektmp -= 8;
}
else{
return 0x02;
}
FileSeek(Seektmp, SEEK_CUR, hAVIFile);
MoviStartPos += Seektmp;
while(1){
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
if(ReadoutNum < 8){
return 0x02;
}
//MoviStartPos += 8;
if ((tmpDataReadout[0] == 'J') && (tmpDataReadout[1] == 'U')
&&(tmpDataReadout[2] == 'N') && (tmpDataReadout[3] == 'K')){
Seektmp = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
FileSeek(Seektmp, SEEK_CUR, hAVIFile);
MoviStartPos += (Seektmp + 8);
}
else{
FileSeek(-8, SEEK_CUR, hAVIFile); // 如果不是JUNK,则恢复到读8字节之前的文件位置
break;
}
}
}
////////////// Find movi chunk ////////////////
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
while(!FileEof(hAVIFile)){
if ((tmpDataReadout[0] == 'L') && (tmpDataReadout[1] == 'I')
&&(tmpDataReadout[2] == 'S') && (tmpDataReadout[3] == 'T')){
Seektmp = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += 8;
Seektmp -= 8;
if ((tmpDataReadout[0] == 'm') && (tmpDataReadout[1] == 'o')
&&(tmpDataReadout[2] == 'v') && (tmpDataReadout[3] == 'i')){
IndexStartPos = Seektmp + MoviStartPos;
break; // Find FOURCC 'movi'
}
FileSeek(Seektmp, SEEK_CUR, hAVIFile);
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += (8 + Seektmp);
}
else if ((tmpDataReadout[0] == 'J') && (tmpDataReadout[1] == 'U')
&&(tmpDataReadout[2] == 'N') && (tmpDataReadout[3] == 'K')){
Seektmp = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
FileSeek(Seektmp, SEEK_CUR, hAVIFile);
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += (8 + Seektmp);
}
else {
Seektmp = (((unsigned long)((tmpDataReadout[7] << 8) | tmpDataReadout[6]))<< 16)
| ((tmpDataReadout[5] << 8) | tmpDataReadout[4]);
FileSeek(Seektmp, SEEK_CUR, hAVIFile);
ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile);
MoviStartPos += (8 + Seektmp);
}
}
if(FileEof(hAVIFile)){ // If find 'movi' in the end of file ,return error.
return -1;
}
if (((avi_file_information -> AviFileFormat) & 0x3) == 0){
return -1; // No audio and video stream, not support it
}
//返回数据相对于'movi'的起始地址,4为数据长度(不能参与解码)
avi_file_information -> StartDataPos = MoviStartPos + 4;
if(blHaveIndex = 1){
avi_file_information -> StartIndexPos = (IndexStartPos + 8);
//初始化Audio和Video的index文件指针
FileSeek(avi_file_information -> StartIndexPos, SEEK_SET, hAudioIndex);
FileRefSet(hAudioIndex);
if(FileEof(hAudioIndex)){
return -1;
}
FileSeek(avi_file_information -> StartIndexPos, SEEK_SET, hVideoIndex);
FileRefSet(hVideoIndex);
VideoIndexBuff_valid = 0;
VideoIndexBuff_ptr = 0;
AudioIndexBuff_ptr = 0;
AudioIndexBuff_valid = 0;
FFDWFramecount = 200; //10s
if(FileEof(hVideoIndex)){
return -1;
}
VideoIndexCount = 0; //清除视频的INDEX记数器,该记数器主要用于快退的结束的判断
AudioIndexCount = 0;
}
else{
avi_file_information -> StartIndexPos = 0; // AVI文件没有index 部分
//return -1; // 如果没有INDEX部分,暂不支持. 20060313@hjl
}
//初始化音视频相对于'movi'的偏移量
AudioFilePos = 4;
VideoFilePos = 4;
AudioChunkLen = 0;
VideoChunkLen = 0;
avi_file_information -> TotalFrameCount = TotalFrames;
avi_file_information -> MicroSecondPerFrame = MicroSecPerFrame / 10;
return 0;
//FileSeek(IndexStartPos, SEEK_SET, hAVIFile);
//ReadoutNum = FileRead(tmpDataReadout, 8, hAVIFile); // For test only,read out data for confirming
}
/******************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* Function name : GetNextAudioChunk()
* Author: Jiliu Huang
* Description:
* Input: 要有全局变量hAudioIndex的支持
* Output:
* Return:
* Others:
* History:
* <author> <time> <version> <desc>
* Jiliu Huang 05/11/01 1.0 ORG
*
******************************************************************************/
__attribute__((section(".avi_v_text, \"ax\"")))
int GetNextAudioChunk(unsigned long *AudioChunkOffset, unsigned long *ChunkLen)
{
unsigned long tmpAudioFilePos;
unsigned long tmpAudioChunkLen;
int i;
*AudioChunkOffset = 0;
tmpAudioFilePos = AudioFilePos; //保存Audio的index值
tmpAudioChunkLen = AudioChunkLen; //保存上次的Chunk长度,用于计算偏移量
while((!FileEof(hAudioIndex))||(AudioIndexBuff_ptr<AudioIndexBuff_valid)){ // hAudioIndex:全局变量
i = AudioIndexBuff_ptr;
for(; i < AudioIndexBuff_valid; i+=16){
AudioIndexBuff_ptr+=16;
AudioIndexCount++;
if ((AudioIndexBuff[i+2] == 'w') && (AudioIndexBuff[i+3] == 'b')){
AviAudioCurrFrameNum++;
AudioFilePos = (((unsigned long)((AudioIndexBuff[i+11] << 8) | AudioIndexBuff[i+10]))<< 16)
| ((AudioIndexBuff[i+9] << 8) | AudioIndexBuff[i+8]);
AudioChunkLen = (((unsigned long)((AudioIndexBuff[i+15] << 8) | AudioIndexBuff[i+14]))<< 16)
| ((AudioIndexBuff[i+13] << 8) | AudioIndexBuff[i+12]);
// 本次音频的偏移量=本次的文件位置-上次文件的位置+上次的Chunk长度
*AudioChunkOffset = AudioFilePos - tmpAudioFilePos - tmpAudioChunkLen;
*ChunkLen = AudioChunkLen;
return 0;
}else if((AudioIndexBuff[i+2] != 'd') || (AudioIndexBuff[i+3] != 'c')){
return -1;
}
}
AudioIndexBuff_ptr =0;
if(!(AudioIndexBuff_valid = FileRead(AudioIndexBuff, 512, hAudioIndex))){
return -1;
}
}
return -1; //直到文件结束处没找到音频INDEX标记
}
/******************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* Function name : GetNextVideoChunk()
* Author: Jiliu Huang
* Description:
* Input: 要有全局变量hVideoIndex的支持
* Output:
* Return: 0: P/N; 1: I; -1:Error
* Others: VideoFilePos.视频
* History:
* <author> <time> <version> <desc>
* Jiliu Huang 05/11/01 1.0 ORG
* modify zcs 06/04/22
******************************************************************************/
__attribute__((section(".avi_v_text, \"ax\"")))
int GetNextVideoChunk(unsigned long *VideoChunkOffset, unsigned long *ChunkLen)
{
unsigned long tmpVideoFilePos;
unsigned long tmpVideoChunkLen;
unsigned long tmpFrameFlag; //
int i;
*VideoChunkOffset = 0;
tmpVideoFilePos = VideoFilePos; //保存Video的index值
tmpVideoChunkLen = VideoChunkLen; //保存上次的Chunk长度,用于计算偏移量
while((!FileEof(hVideoIndex))||(VideoIndexBuff_ptr<VideoIndexBuff_valid)){
i = VideoIndexBuff_ptr;
for(; i < VideoIndexBuff_valid; i+=16){
VideoIndexBuff_ptr+=16;
VideoIndexCount++;
if ((VideoIndexBuff[i+2] == 'd') && (VideoIndexBuff[i+3] == 'c')){
AviCurrFrameNum++;
VideoFilePos = (((unsigned long)((VideoIndexBuff[i+11] << 8) | VideoIndexBuff[i+10]))<< 16)
| ((VideoIndexBuff[i+9] << 8) | VideoIndexBuff[i+8]);
VideoChunkLen = (((unsigned long)((VideoIndexBuff[i+15] << 8) | VideoIndexBuff[i+14]))<< 16)
| ((VideoIndexBuff[i+13] << 8) | VideoIndexBuff[i+12]);
// 本次视频的偏移量=本次的文件位置-上次文件的位置+上次的Chunk长度
*VideoChunkOffset = VideoFilePos - tmpVideoFilePos - tmpVideoChunkLen;
*ChunkLen = VideoChunkLen;
if((((((unsigned long)((VideoIndexBuff[i+7] << 8) | VideoIndexBuff[i+6]))<< 16)
| ((VideoIndexBuff[i+5] << 8) | VideoIndexBuff[i+4]))
&& 0x00000010) != 0){
return 1; // I
}
else{
return 0; // P/N
}
}
else if((VideoIndexBuff[i+2] != 'w') || (VideoIndexBuff[i+3] != 'b')){
return -1;
}
}
VideoIndexBuff_ptr =0;
if(!(VideoIndexBuff_valid = FileRead(VideoIndexBuff, 512, hVideoIndex))){
return -1;
}
}
return -1; //直到文件结束处没找到视频INDEX标记
}
/******************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* Function name : GetPreVideoIFrameChunk()
* Author: Jiliu Huang
* Description:
* Input:
* Output:
* Return:
* Others:
* History:
* <author> <time> <version> <desc>
* Jiliu Huang 05/11/14 1.0 ORG
* Jiliu Huang 06/04/10 2.0 修改了快进快退功能的方式,以改进快进快退后
* 不同步的问题。
******************************************************************************/
__attribute__((section(".avi_v_text, \"ax\"")))
int GetNextVideoIFrameChunk(unsigned long *VideoChunkOffset, unsigned long *ChunkLen)
{
unsigned long tmpVideoFilePos;
unsigned long tmpVideoChunkLen;
unsigned long tmpFrameFlag = 0; // 0:不是I帧
unsigned long tmpVideoChunkLenLeft;
int i;
unsigned int Framecount;
*VideoChunkOffset = 0;
tmpVideoFilePos = VideoFilePos; //保存Video的index值
tmpVideoChunkLen = VideoChunkLen; //保存上次的Chunk长度,用于计算偏移量
// 记录流媒体的当前位置,因为当解码程序中如果没有读取完上次的数据长度,则可能会出错。
tmpVideoChunkLenLeft = *ChunkLen;
Framecount =0;
while((!FileEof(hVideoIndex))||(VideoIndexBuff_ptr<VideoIndexBuff_valid)){
i = VideoIndexBuff_ptr;
for(; i < VideoIndexBuff_valid; i+=16){
VideoIndexBuff_ptr+=16;
VideoIndexCount++;
if ((VideoIndexBuff[i+2] == 'd') && (VideoIndexBuff[i+3] == 'c')){
AviCurrFrameNum++;
AviCurr_IFrameNum_FrameNum = AviCurrFrameNum;
Framecount++;
if(((((((unsigned long)((VideoIndexBuff[i+7] << 8) | VideoIndexBuff[i+6]))<< 16)
| ((VideoIndexBuff[i+5] << 8) | VideoIndexBuff[i+4]))
&& 0x00000010) != 0)){
VideoFilePos = (((unsigned long)((VideoIndexBuff[i+11] << 8) | VideoIndexBuff[i+10]))<< 16)
| ((VideoIndexBuff[i+9] << 8) | VideoIndexBuff[i+8]);
VideoChunkLen = (((unsigned long)((VideoIndexBuff[i+15] << 8) | VideoIndexBuff[i+14]))<< 16)
| ((VideoIndexBuff[i+13] << 8) | VideoIndexBuff[i+12]);
// 本次视频的偏移量=本次的文件位置-上次文件的位置-上次的Chunk长度
*VideoChunkOffset = VideoFilePos - tmpVideoFilePos - tmpVideoChunkLen + tmpVideoChunkLenLeft;
*ChunkLen = VideoChunkLen;
if(Framecount > FFDWFramecount){
return 0; // 找到了I帧
}
}
}
else if((VideoIndexBuff[i+2] != 'w') || (VideoIndexBuff[i+3] != 'b')){
return -1;
}
}
VideoIndexBuff_ptr =0;
if(!(VideoIndexBuff_valid = FileRead(VideoIndexBuff, 512, hVideoIndex))){
return -1;
}
}
return -1; //直到文件结束处没找到视频INDEX标记
}
/******************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* Function name : GetNextVideoIFrameChunk()
* Author: Jiliu Huang
* Description:
* Input:
* Output:
* Return: 0.找到了视频I帧及相应的音频帧
* 1.找到了视频I帧但没有音频帧
* -1.没有找到视频I帧
* Others:
* History:
* <author> <time> <version> <desc>
* Jiliu Huang 05/11/14 1.0 ORG
* Jiliu Huang 06/04/10 2.0 修改了快进快退功能的方式,以改进快进快退后
* 不同步的问题。
******************************************************************************/
__attribute__((section(".avi_v_text, \"ax\"")))
int GetPreVideoIFrameChunk( unsigned long *VideoChunkOffset,
unsigned long *ChunkLen)
{
unsigned long tmp;
unsigned long tmpVideoFilePos;
unsigned long tmpVideoChunkLen;
unsigned long tmpFrameFlag; //
int i;
unsigned int Framecount,IFrame_count;
*VideoChunkOffset = 0;
IFrame_count = 0;
Framecount = 0;
tmpVideoFilePos = VideoFilePos; //保存Video的index值
tmpVideoChunkLen = VideoChunkLen; //保存上次的Chunk长度,用于计算偏移量
tmp = 512;
while(VideoIndexCount){
i = VideoIndexBuff_ptr-16;
for(; i >= 0; i-=16){
VideoIndexBuff_ptr-=16;
VideoIndexCount--;
if ((VideoIndexBuff[i+2] == 'd') && (VideoIndexBuff[i+3] == 'c')){
Framecount++;
AviCurrFrameNum--; //ke nen cun zai wenti
AviCurr_IFrameNum_FrameNum = AviCurrFrameNum;
if((((((unsigned long)((VideoIndexBuff[i+7] << 8) | VideoIndexBuff[i+6]))<< 16)
| ((VideoIndexBuff[i+5] << 8) | VideoIndexBuff[i+4]))
&& 0x00000010) != 0){
VideoFilePos = (((unsigned long)((VideoIndexBuff[i+11] << 8) | VideoIndexBuff[i+10]))<< 16)
| ((VideoIndexBuff[i+9] << 8) | VideoIndexBuff[i+8]);
VideoChunkLen = (((unsigned long)((VideoIndexBuff[i+15] << 8) | VideoIndexBuff[i+14]))<< 16)
| ((VideoIndexBuff[i+13] << 8) | VideoIndexBuff[i+12]);
// 本次视频的偏移量=本次的文件位置-上次文件的位置+上次的Chunk长度
*VideoChunkOffset = VideoFilePos + AviStreamInfo.StartDataPos - 4;
*ChunkLen = VideoChunkLen;
if((IFrame_count == 1) && (Framecount > FFDWFramecount)){
return 0; // I
}else{
IFrame_count = 1;
}
}
}
else if((VideoIndexBuff[i+2] != 'w') || (VideoIndexBuff[i+3] != 'b')){
return -1;
}
}
FileSeek((-tmp-VideoIndexBuff_valid), SEEK_REF, hVideoIndex);
if(!(VideoIndexBuff_valid = FileRead(VideoIndexBuff, 512, hVideoIndex))){
return -1;
}
VideoIndexBuff_ptr = VideoIndexBuff_valid;
}
if(IFrame_count == 0){
return -1; //直到文件结束处没找到视频INDEX标记
}else{
return 0;
}
}
/******************************************************************************
* Copyright (C),2004-2005, Fuzhou Rockchip Co.,Ltd.
* Function name : SynAudio2VideoChunk()
* Author: Jiliu Huang
* Description: 当GetNextVideoIFrameChunk()或GetPreVideoIFrameChunk()两个函数
* 后,必须执行该函数来同步音频信号。
* Input:
* Output:
* Return: 0.找到了快进或快退后与视频帧对应的音频帧
* -1.没有找到了快进或快退后与视频帧对应的音频帧
* Others:
* History:
* <author> <time> <version> <desc>
* Jiliu Huang 06/04/10 1.0 ORG
******************************************************************************/
__attribute__((section(".avi_v_text, \"ax\"")))
int SynAudio2VideoChunk(unsigned long *AudioChunkOffset,
unsigned long *ChunkLen,
unsigned long *CurrAviFrameNum,
unsigned long *AviLastChunkNum,
AVI_STREAM_INFO *avi_file_information)
{
unsigned long tmpAudioFilePos;
unsigned long tmpAudioChunkLen;
unsigned long tmpAudioChunkLenLeft;
tmpAudioFilePos = AudioFilePos;
tmpAudioChunkLen = AudioChunkLen;
tmpAudioChunkLenLeft = *ChunkLen;
unsigned long uiAudioJumpBackChunksNeeded;
int i;
unsigned long uiAudioChunkJumped = 0;
unsigned long tmp;
unsigned long ulAudioPosition;
//ulAudioPosition = (((*CurrAviFrameNum)*5) * (avi_file_information -> MicroSecondPerFrame)) / AVI_AUDIO_FRAME_TIME;// + 20;
//ulAudioPosition = ((ulAudioPosition<<8) - (ulAudioPosition>>8))>>8;
ulAudioPosition = ((*CurrAviFrameNum)*245)>>7;
if(ulAudioPosition >= AviAudioCurrFrameNum){
uiAudioJumpBackChunksNeeded = ulAudioPosition - AviAudioCurrFrameNum;
while((!FileEof(hAudioIndex))||(AudioIndexBuff_ptr<AudioIndexBuff_valid)){ // hAudioIndex:全局变量
i = AudioIndexBuff_ptr;
for(; i < AudioIndexBuff_valid; i+=16){
AudioIndexBuff_ptr+=16;
AudioIndexCount++;
if ((AudioIndexBuff[i+2] == 'w') && (AudioIndexBuff[i+3] == 'b')){
uiAudioChunkJumped++;
AviAudioCurrFrameNum++;
m_audio_framenum = AviAudioCurrFrameNum;
if(uiAudioChunkJumped >= uiAudioJumpBackChunksNeeded){
AudioFilePos = (((unsigned long)((AudioIndexBuff[i+11] << 8) | AudioIndexBuff[i+10]))<< 16)
| ((AudioIndexBuff[i+9] << 8) | AudioIndexBuff[i+8]);
AudioChunkLen = (((unsigned long)((AudioIndexBuff[i+15] << 8) | AudioIndexBuff[i+14]))<< 16)
| ((AudioIndexBuff[i+13] << 8) | AudioIndexBuff[i+12]);
// 本次音频的偏移量=本次的文件位置-上次文件的位置+上次的Chunk长度
*AudioChunkOffset = AudioFilePos - tmpAudioFilePos - tmpAudioChunkLen + tmpAudioChunkLenLeft;
*ChunkLen = AudioChunkLen;
return 0;
}
}else if((AudioIndexBuff[i+2] != 'd') || (AudioIndexBuff[i+3] != 'c')){
return -1;
}
}
AudioIndexBuff_ptr =0;
if(!(AudioIndexBuff_valid = FileRead(AudioIndexBuff, 512, hAudioIndex))){
return -1;
}
}
return -1; //直到文件结束处没找到音频INDEX标记
}else{
FileRefReset(hAudioIndex);
// FileSeek(avi_file_information -> StartIndexPos, SEEK_SET, hAudioIndex);
// tmpAudioChunkLenLeft =0;
uiAudioJumpBackChunksNeeded = ulAudioPosition;
AviAudioCurrFrameNum = 0;
AudioIndexCount = 0;
AudioIndexBuff_ptr =0;
AudioIndexBuff_valid =0;
Timeadjust = 0;
m_audio_framenum = 0;
while((!FileEof(hAudioIndex))||(AudioIndexBuff_ptr<AudioIndexBuff_valid)){ // hAudioIndex:全局变量
i = AudioIndexBuff_ptr;
for(; i < AudioIndexBuff_valid; i+=16){
AudioIndexBuff_ptr+=16;
AudioIndexCount++;
if ((AudioIndexBuff[i+2] == 'w') && (AudioIndexBuff[i+3] == 'b')){
uiAudioChunkJumped++;
AviAudioCurrFrameNum++;
m_audio_framenum = AviAudioCurrFrameNum;
if(uiAudioChunkJumped >= uiAudioJumpBackChunksNeeded){
AudioFilePos = (((unsigned long)((AudioIndexBuff[i+11] << 8) | AudioIndexBuff[i+10]))<< 16)
| ((AudioIndexBuff[i+9] << 8) | AudioIndexBuff[i+8]);
AudioChunkLen = (((unsigned long)((AudioIndexBuff[i+15] << 8) | AudioIndexBuff[i+14]))<< 16)
| ((AudioIndexBuff[i+13] << 8) | AudioIndexBuff[i+12]);
// 本次音频的偏移量=本次的文件位置-上次文件的位置+上次的Chunk长度
*AudioChunkOffset = AudioFilePos + avi_file_information -> StartDataPos - 4;
*ChunkLen = AudioChunkLen;
return 0;
}
}else if((AudioIndexBuff[i+2] != 'd') || (AudioIndexBuff[i+3] != 'c')){
return -1;
}
}
AudioIndexBuff_ptr =0;
if(!(AudioIndexBuff_valid = FileRead(AudioIndexBuff, 512, hAudioIndex))){
return -1;
}
}
return -1; //直到文件结束处没找到音频INDEX标记
}
return -1;
}
/* }else{
tmp=512;
uiAudioJumpBackChunksNeeded = AviAudioCurrFrameNum - ulAudioPosition;
while(AudioIndexCount){ // hAudioIndex:全局变量
i = (AudioIndexBuff_ptr-16);
for(; i >= 0; i-=16){
AudioIndexBuff_ptr-=16;
AudioIndexCount--;
if((AudioIndexBuff[i+2] == 'w') && (AudioIndexBuff[i+3] == 'b')){
uiAudioChunkJumped++;
AviAudioCurrFrameNum--;
if(uiAudioChunkJumped >= uiAudioJumpBackChunksNeeded){
AudioFilePos = (((unsigned long)(( AudioIndexBuff[i+11] << 8) | AudioIndexBuff[i+10]))<< 16)
| ((AudioIndexBuff[i+9] << 8) | AudioIndexBuff[i+8]);
AudioChunkLen = (((unsigned long)(( AudioIndexBuff[i+15] << 8) | AudioIndexBuff[i+14]))<< 16)
| ((AudioIndexBuff[i+13] << 8) | AudioIndexBuff[i+12]);
*AudioChunkOffset = AudioFilePos + AviStreamInfo.StartDataPos - 4;
*ChunkLen = AudioChunkLen;
return 0;
}
}
else if((AudioIndexBuff[i+2] != 'd') || (AudioIndexBuff[i+3] != 'c')){
return -1;
}
}
FileSeek((-tmp-AudioIndexBuff_valid), SEEK_CUR, hAudioIndex);
AudioIndexBuff_valid = FileRead(AudioIndexBuff, 512, hAudioIndex);
AudioIndexBuff_ptr = AudioIndexBuff_valid;
}
}
return -1;
}*/