?? mjpeg_avi_filereader.c
字號(hào):
/*****************************************************************************
Copyright(c) 2005 Analog Devices, Inc. All Rights Reserved. This software is
proprietary and confidential to Analog Devices, Inc. and its licensors.
******************************************************************************
$RCSfile: MJPEG_AVI_FileReader.c,v $
$Revision: 1.1 $
$Date: 2006/07/17 07:44:02 $
Project: MJPEG Decoder
Title: AVI File reader
Author(s): P.V.R.B
Revised by:
Description : Header file of AVI File Reader.
References:
******************************************************************************
Tab Setting: 4
Target Processor: Blackfin
Target Tools Revision: VDSP++ 4.0
******************************************************************************
Modification History:
====================
$Log: MJPEG_AVI_FileReader.c,v $
Revision 1.1 2006/07/17 07:44:02 bmk
JPEG-MJPEG User access files
******************************************************************************/
#include <stdlib.h>
#include "MJPEG_AVI_Common.h"
#include "MJPEG_AVI_FileReader.h"
// Changed to smaller size to work better with the post June update tools
#pragma align 4
section ("sdram0_bank1_cache")
static char fileiobuff[16384]; // fileio buffer (in cached SDRAM)
/**/
/* Evaluation version limiting */
/* Limit evaluation version to encoding/decoding 100 frames */
/* Define ISEVALUATION in project to activate */
#ifdef ISEVALUATION
#define EVALUATIONMAXFRAMES 100
#warning *** EVALUATION MODE - Number of encoding/decoding frames is limited ***
#endif
#ifdef MJPEGREWIND
#include <string.h>
#define MAXINDEXBUFFERSIZE 10
#pragma align 4
section ("sdram0_bank1_cache")
static MJPEG_AVI_INDEXENTRY *FrameIndex;
#pragma align 4
section ("sdram0_bank1_cache")
static int FrameCount;
#pragma align 4
section ("sdram0_bank1_cache")
static uint32 frameheader[2];
#endif
/*
*******************************************************************************
Name : fseek_workaround
Description : Seeks to a specified point in file by doing freads
: This function is used to get around the fseek problem in VDSP
: 4 (June and Sept updates). Call this function only when using
: SEEK_CUR option.
Parameter : pFile : file pointer to the file to do the seek
: bytes : number of bytes to seek from current
: position
: origin : same as that of normal fseek
Return Value : returns 0 if successful, -1 if failed
*******************************************************************************
*/
section ("MJPEGDEC_P0") // All code
int fseek_workaround(FILE *pFile,int bytes,int origin)
{
long pos;
if (origin != SEEK_CUR)
return(fseek(pFile,bytes,origin));
pos = ftell(pFile);
if (pos == -1)
return -1;
bytes += pos;
return (fseek(pFile,bytes,SEEK_SET));
}
/*
*******************************************************************************
Name : MJPEG_AVI_OpenFileRead
Description : Opens the MJPEG AVI file for reading
: The index table (i.e. idx1 chunk) is assumed to be present in
: the file.
Parameter : pAVIFileHandle : pointer to receive the AVI File Handle.
: fileName : Name of the AVI file to be opened.
Return Value : MJPEG_AVI_RETURN_OK if file opened OK
` MJPEG_AVI_RETURN_OUTOFMEMORY
if memory could not be allocated when opening the file
MJPEG_AVI_RETURN_FILEOPENFAIL
if the input file could not be opened
MJPEG_AVI_RETURN_FILEREADFAIL
if the input file could not be read
MJPEG_AVI_RETURN_FILEINCORRECTFORMAT
if the input file was not in MJPEG AVI format
MJPEG_AVI_RETURN_FILESEEKFAIL
if the seek operation on the input file failed
MJPEG_AVI_RETURN_ERROR otherwise
*******************************************************************************
*/
section ("MJPEGDEC_P0") // All code
int32 MJPEG_AVI_OpenFileRead(uint32 *pAVIFileHandleParam, int8 *fileName)
{
FILE *fp;
uint32 ListhdrlChunkLength, avihChunkLength, ListmoviChunkLength;
tMJPEG_AVI_FILEHANDLEREAD *pAVIFileHandle
= (tMJPEG_AVI_FILEHANDLEREAD *)pAVIFileHandleParam;
tMJPEG_AVI_RIFFHEADER lAviRiff;
uint32 fileLength, lChunkId;
int32 lResult;
*pAVIFileHandle = (tMJPEG_AVI_FILEHANDLEREAD) malloc(sizeof(tMJPEG_AVI_FileRead));
if(*pAVIFileHandle == NULL)
{
return MJPEG_AVI_RETURN_OUTOFMEMORY;
}
fp = fopen((const char *)fileName,"rb");
if( fp == NULL)
{
lResult = MJPEG_AVI_RETURN_FILEOPENFAIL;
goto RETURN_ERROR;
}
setvbuf((FILE*)fp, fileiobuff, _IOLBF, sizeof(fileiobuff));
(*pAVIFileHandle)->filePtr = fp;
fseek(fp, 0, SEEK_END);
fileLength = ftell(fp);
fseek(fp, 0, SEEK_SET);
if(fread(&lAviRiff, 1, 12, fp) != 12)
{
lResult = MJPEG_AVI_RETURN_FILEREADFAIL;
goto RETURN_ERROR;
}
if(lAviRiff.riffCkid != MJPEG_AVI_FOURCC('R','I','F','F')
|| lAviRiff.aviCkid != MJPEG_AVI_FOURCC('A','V','I',' ')
|| lAviRiff.chunkLength != (fileLength - 8))
{
lResult = MJPEG_AVI_RETURN_FILEINCORRECTFORMAT;
goto RETURN_ERROR;
}
/* Getting the ListhdrlChunkOffset */
while(1)
{
if(fread(&lChunkId, 1, 4, fp) != 4
|| fread(&ListhdrlChunkLength, 1, 4, fp) != 4)
{
lResult = MJPEG_AVI_RETURN_FILEREADFAIL;
goto RETURN_ERROR;
}
if(lChunkId != MJPEG_AVI_FOURCC('L','I','S','T'))
{
// workaround for fseek issues
if(fseek_workaround(fp, ListhdrlChunkLength, SEEK_CUR) != 0)
{
lResult = MJPEG_AVI_RETURN_FILESEEKFAIL;
goto RETURN_ERROR;
}
continue;
}
if(fread(&lChunkId, 1, 4, fp) != 4)
{
lResult = MJPEG_AVI_RETURN_FILESEEKFAIL;
goto RETURN_ERROR;
}
if(lChunkId != MJPEG_AVI_FOURCC('h','d','r','l'))
{
// workaround for fseek issues
if(fseek_workaround(fp, ListhdrlChunkLength-4, SEEK_CUR) != 0)
{
lResult = MJPEG_AVI_RETURN_FILESEEKFAIL;
goto RETURN_ERROR;
}
continue;
}
(*pAVIFileHandle)->ListhdrlChunkOffset = ftell(fp) - 12;
break;
}
(*pAVIFileHandle)->avihChunkOffset = ftell(fp);
if(fread(&lChunkId, 1, 4, fp) != 4)
{
lResult = MJPEG_AVI_RETURN_FILEREADFAIL;
goto RETURN_ERROR;
}
if(lChunkId != MJPEG_AVI_FOURCC('a','v','i','h'))
{
lResult = MJPEG_AVI_RETURN_FILEINCORRECTFORMAT;
goto RETURN_ERROR;
}
if(fread(&avihChunkLength, 1, 4, fp) != 4)
{
lResult = MJPEG_AVI_RETURN_FILEREADFAIL;
goto RETURN_ERROR;
}
if(avihChunkLength != sizeof(MJPEG_AVI_MainAVIHeader))
{
lResult = MJPEG_AVI_RETURN_FILEINCORRECTFORMAT;
goto RETURN_ERROR;
}
if(fread(&((*pAVIFileHandle)->avih),1,sizeof(MJPEG_AVI_MainAVIHeader),fp)
!= sizeof(MJPEG_AVI_MainAVIHeader))
{
lResult = MJPEG_AVI_RETURN_FILEREADFAIL;
goto RETURN_ERROR;
}
/* Getting the ListmoviChunkOffset */
if(fseek(fp, (*pAVIFileHandle)->ListhdrlChunkOffset+ListhdrlChunkLength+8,
SEEK_SET) != 0)
{
lResult = MJPEG_AVI_RETURN_FILESEEKFAIL;
goto RETURN_ERROR;
}
while(1)
{
if(fread(&lChunkId, 1, 4, fp) != 4
|| fread(&ListmoviChunkLength, 1, 4, fp) != 4)
{
lResult = MJPEG_AVI_RETURN_FILEREADFAIL;
goto RETURN_ERROR;
}
if(lChunkId != MJPEG_AVI_FOURCC('L','I','S','T'))
{
// workaround for fseek issues
if(fseek_workaround(fp, ListmoviChunkLength, SEEK_CUR) != 0)
{
lResult = MJPEG_AVI_RETURN_FILESEEKFAIL;
goto RETURN_ERROR;
}
continue;
}
if(fread(&lChunkId, 1, 4, fp) != 4)
{
lResult = MJPEG_AVI_RETURN_FILEREADFAIL;
goto RETURN_ERROR;
}
if(lChunkId != MJPEG_AVI_FOURCC('m','o','v','i'))
{
// workaround for fseek issues
if(fseek_workaround(fp, ListmoviChunkLength-4, SEEK_CUR) != 0)
{
lResult = MJPEG_AVI_RETURN_FILESEEKFAIL;
goto RETURN_ERROR;
}
continue;
}
(*pAVIFileHandle)->ListmoviChunkOffset = ftell(fp) - 12;
break;
}
// workaround for fseek issues
if(fseek_workaround(fp, ListmoviChunkLength-4, SEEK_CUR) != 0)
{
lResult = MJPEG_AVI_RETURN_FILESEEKFAIL;
goto RETURN_ERROR;
}
/* Getting idx1 chunk offset */
while(1)
{
if(fread(&lChunkId, 1, 4, fp) != 4
|| fread(&(*pAVIFileHandle)->indexChunkLength, 1, 4, fp) != 4)
{
lResult = MJPEG_AVI_RETURN_FILEREADFAIL;
goto RETURN_ERROR;
}
if(lChunkId != MJPEG_AVI_FOURCC('i','d','x','1'))
{
// workaround for fseek issues
if(fseek_workaround(fp, (*pAVIFileHandle)->indexChunkLength, SEEK_CUR) != 0)
{
lResult = MJPEG_AVI_RETURN_FILESEEKFAIL;
goto RETURN_ERROR;
}
continue;
}
(*pAVIFileHandle)->indexChunkOffset = ftell(fp) - 8;
#ifdef MJPEGREWIND
if(((*pAVIFileHandle)->indexChunkLength/sizeof(MJPEG_AVI_INDEXENTRY)) < MAXINDEXBUFFERSIZE) {
FrameIndex=(MJPEG_AVI_INDEXENTRY *) malloc((*pAVIFileHandle)->indexChunkLength);
if(fread(FrameIndex,1,(*pAVIFileHandle)->indexChunkLength,fp) != ((*pAVIFileHandle)->indexChunkLength))
{ free(FrameIndex); lResult = MJPEG_AVI_RETURN_FILEREADFAIL; goto RETURN_ERROR; }
for(FrameCount=1;FrameCount < ((*pAVIFileHandle)->indexChunkLength / sizeof(MJPEG_AVI_INDEXENTRY)); FrameCount++){
if(FrameIndex[0].dwChunkLength<FrameIndex[FrameCount].dwChunkLength)
FrameIndex[0].dwChunkLength=FrameIndex[FrameCount].dwChunkLength;
}
} else {
FrameIndex=(MJPEG_AVI_INDEXENTRY *) malloc(sizeof(MJPEG_AVI_INDEXENTRY) * 2);
if(fread(FrameIndex,1,sizeof(MJPEG_AVI_INDEXENTRY) * 2,fp) != (sizeof(MJPEG_AVI_INDEXENTRY) * 2))
{ free(FrameIndex); lResult = MJPEG_AVI_RETURN_FILEREADFAIL; goto RETURN_ERROR; }
if(FrameIndex[0].dwChunkLength<FrameIndex[1].dwChunkLength) FrameIndex[0].dwChunkLength=FrameIndex[1].dwChunkLength;
for(FrameCount=2; FrameCount < ((*pAVIFileHandle)->indexChunkLength / sizeof(MJPEG_AVI_INDEXENTRY)); FrameCount++){
if(fread(&FrameIndex[1],1,sizeof(MJPEG_AVI_INDEXENTRY) ,fp) != sizeof(MJPEG_AVI_INDEXENTRY))
{ free(FrameIndex); lResult = MJPEG_AVI_RETURN_FILEREADFAIL; goto RETURN_ERROR; }
if(FrameIndex[0].dwChunkLength < FrameIndex[1].dwChunkLength)
FrameIndex[0].dwChunkLength = FrameIndex[1].dwChunkLength;
}
}
FrameCount=0;
FrameIndex[0].dwChunkLength += 8;// maximum stream size
#endif
break;
}
(*pAVIFileHandle)->openStreamCount = 0;
return MJPEG_AVI_RETURN_OK;
RETURN_ERROR :
if(fp != NULL)
{
fclose(fp);
}
free(*pAVIFileHandle);
*pAVIFileHandle = NULL;
return lResult;
}
/*
*******************************************************************************
Name : MJPEG_AVI_CloseFileRead
Description : Closes the AVI file.
Parameter : AVI File Handle.
Return Value : MJPEG_AVI_RETURN_OK if file closed OK
MJPEG_AVI_RETURN_ERROR otherwise.
*******************************************************************************
*/
section ("MJPEGDEC_P0") // All code
int32 MJPEG_AVI_CloseFileRead(uint32 AVIFileHandleParam)
{
tMJPEG_AVI_FILEHANDLEREAD AVIFileHandle = (tMJPEG_AVI_FILEHANDLEREAD) AVIFileHandleParam;
if(AVIFileHandle == NULL
|| AVIFileHandle->openStreamCount != 0
|| fclose(AVIFileHandle->filePtr) != 0)
{
return MJPEG_AVI_RETURN_ERROR;
}
free(AVIFileHandle);
return MJPEG_AVI_RETURN_OK;
}
/*
*******************************************************************************
Name : MJPEG_AVI_OpenStreamRead
Description : Opens a AVI Stream for read mode.
Parameter :
AVIFileHandleParam : AVI File Handle.
pAVIStreamHandleParam : pointer to receive, opened stream handle.
fccTypeParam : fcc type of the stream to be opened.
index : index of the stream to be opened.
Return Value : MJPEG_AVI_RETURN_OK if stream opened OK
` MJPEG_AVI_RETURN_OUTOFMEMORY
if memory could not be allocated when opening the stream
MJPEG_AVI_RETURN_FILEOPENFAIL
if the input stream could not be opened
MJPEG_AVI_RETURN_FILEREADFAIL
if the input stream could not be read
MJPEG_AVI_RETURN_FILEINCORRECTFORMAT
if the input stream was not in MJPEG AVI format
MJPEG_AVI_RETURN_FILESEEKFAIL
if the seek operation on the input stream failed
MJPEG_AVI_RETURN_ERROR otherwise
Limitations :
1. index is supported only for value 0.
2. fccTypeParam is supported for values "MJPEG_AVI_StreamTypeVIDEO" and
"MJPEG_AVI_StreamTypeAUDIO"
Assumptions :
1. The strl chunk index in the avih header is same as the corresponding
stream's stream identifier.
*******************************************************************************
*/
section ("MJPEGDEC_P0") // All code
int32 MJPEG_AVI_OpenStreamRead (uint32 AVIFileHandleParam,
uint32 *pAVIStreamHandleParam,
uint32 fccTypeParam,
int32 index)
{
uint32 lListstrlOffset, lListstrlChunkLength, lstrhChunkLength, lStreamId;
uint32 lChunkId, lTemp;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -