?? mjpeg_avi_filewriter.c
字號:
/*****************************************************************************
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_FileWriter.c,v $
$Revision: 1.1 $
$Date: 2006/07/17 07:44:02 $
Project: MJPEG_AVI MOVING IMAGE CODEC
Title: MJPEG_AVI Main API
Author(s): CJ
Revised by:
Description:
Application Programming Interface code for MJPEG_AVI library
References:
******************************************************************************
Tab Setting: 4
Target Processor: Blackfin
Target Tools Revision: ccblkfn C/C++ compiler 7.0.3.2
easmblkfn BlackFin assembler 2.6.3.4
elfar ELF Librarian/Archive Utility 4.4.1.2
linker Linker 3.2.1.0
******************************************************************************
Modification History:
====================
$Log: MJPEG_AVI_FileWriter.c,v $
Revision 1.1 2006/07/17 07:44:02 bmk
JPEG-MJPEG User access files
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "MJPEG_AVI_FileWriter.h"
#include "JPEG_memalloc.h"
#pragma align 4
section ("sdram0_bank1_cache")
static char fileiobuff[16384]; // fileio buffer (in cached SDRAM)
/**/
/* Defines */
/* TEMP_FILE_NAME: Valid pathname for temp file to hold AVI header info */
#define TEMP_FILE_NAME "AVIWRITE_TEMP.tmp"
/**/
/* 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>
unsigned RIFFHDR[58] = {
MJPEG_AVI_FOURCC('R','I','F','F'), 0,//MJPEG_AVI_FOURCC('0','0','0','0'),
MJPEG_AVI_FOURCC('A','V','I',' '), MJPEG_AVI_FOURCC('L','I','S','T'), 196,
MJPEG_AVI_FOURCC('h','d','r','l'), MJPEG_AVI_FOURCC('a','v','i','h'),
sizeof(MJPEG_AVI_MainAVIHeader), 0, 0, //10
0, MJPEG_AVIF_HASINDEX, 0, 0, 0, 0, 0, 0, 0, 0, //20
0, 0, MJPEG_AVI_FOURCC('L','I','S','T'),
sizeof(MJPEG_AVI_StreamHeader) + sizeof(tMJPEG_AVI_BITMAPINFO) + 20,
MJPEG_AVI_FOURCC('s','t','r','l'), MJPEG_AVI_FOURCC('s','t','r','h'),
sizeof(MJPEG_AVI_StreamHeader),
MJPEG_AVI_FOURCC('v','i','d','s'), MJPEG_AVI_FOURCC('M','J','P','G'), 0,//30
0,0,1,0,0,0,0,0,0,0,//40
0, MJPEG_AVI_FOURCC('s','t','r','f'), sizeof(tMJPEG_AVI_BITMAPINFO),
sizeof(tMJPEG_AVI_BITMAPINFOHEADER),0,0,0x00180001,
MJPEG_AVI_FOURCC('M','J','P','G'),0,0,//50
0,0,0,0,
MJPEG_AVI_FOURCC('L','I','S','T'), 0,// MJPEG_AVI_FOURCC('0','0','0','0'),
MJPEG_AVI_FOURCC('m','o','v','i'), 0};
MJPEG_AVI_INDEXENTRY lIndexEntry = {0,0,0,0};
unsigned ltmp[2];
#endif
/*
*******************************************************************************
Name : MJPEG_AVI_OpenFileWrite
Description : Opens an MJPEG AVI file output file for encoding
Parameter : Pointer to the output file handle
: Pointer to the null-terminated filename
Return Value : MJPEG_AVI_RETURN_OK if file opened OK
MJPEG_AVI_RETURN_ERROR otherwise
*******************************************************************************
*/
#ifndef MJPEGREWIND
section ("MJPEGENC_P0") // All code
int32 MJPEG_AVI_OpenFileWrite(uint32 *pAVIFileHandleParam, uint8 *fileName)
{
FILE *fp, *fp_index;
uint32 lIndex, ListhdrlChunkLength, avihChunkLength;
tMJPEG_AVI_FILEHANDLE *pAVIFileHandle = (tMJPEG_AVI_FILEHANDLE *)pAVIFileHandleParam;
*pAVIFileHandle = (tMJPEG_AVI_FILEHANDLE) malloc(sizeof(tMJPEG_AVI_FileWrite));
fp = (FILE*) fopen((char*)fileName,"wb");
if( fp == NULL)
{
goto RETURN_ERROR;
}
setvbuf((FILE*)fp, fileiobuff, _IOLBF, sizeof(fileiobuff));
(*pAVIFileHandle)->filePtr = fp;
if(fwrite("RIFF0000AVI ",1,12,fp) != 12)
{
goto RETURN_ERROR;
}
(*pAVIFileHandle)->ListmoviChunkOffset = 0;
(*pAVIFileHandle)->writingDataStarted = 0;
(*pAVIFileHandle)->avih.dwMicroSecPerFrame = 0;
(*pAVIFileHandle)->avih.dwMaxBytesPerSec = 0;
(*pAVIFileHandle)->avih.dwPaddingGranularity = 0;
(*pAVIFileHandle)->avih.dwFlags = MJPEG_AVIF_HASINDEX;
(*pAVIFileHandle)->avih.dwTotalFrames = 0;
(*pAVIFileHandle)->avih.dwInitialFrames = 0;
(*pAVIFileHandle)->avih.dwStreams = 0;
(*pAVIFileHandle)->avih.dwSuggestedBufferSize = 0;
(*pAVIFileHandle)->avih.dwWidth = 0;
(*pAVIFileHandle)->avih.dwHeight = 0;
for(lIndex = 0; lIndex < 4; lIndex++)
{
(*pAVIFileHandle)->avih.dwReserved[lIndex] = 0;
}
ListhdrlChunkLength = 0;
(*pAVIFileHandle)->ListhdrlChunkOffset = ftell(fp);
if(fwrite("LIST",1,4,fp) != 4)
{
goto RETURN_ERROR;
}
if(fwrite(&ListhdrlChunkLength,1,4,fp) != 4)
{
goto RETURN_ERROR;
}
if(fwrite("hdrl",1,4,fp) != 4)
{
goto RETURN_ERROR;
}
avihChunkLength = sizeof(MJPEG_AVI_MainAVIHeader);
(*pAVIFileHandle)->avihChunkOffset = ftell(fp);
if(fwrite("avih",1,4,fp) != 4)
{
goto RETURN_ERROR;
}
if(fwrite(&avihChunkLength,1,4,fp) != 4)
{
goto RETURN_ERROR;
}
if(fwrite(&((*pAVIFileHandle)->avih),1,sizeof(MJPEG_AVI_MainAVIHeader),fp) != sizeof(MJPEG_AVI_MainAVIHeader))
{
goto RETURN_ERROR;
}
fp_index = fopen(TEMP_FILE_NAME,"wb+");
if( fp_index == NULL)
{
goto RETURN_ERROR;
}
(*pAVIFileHandle)->indexFilePtr = fp_index;
if(fwrite("idx10000",1,8,fp_index) != 8)
{
goto RETURN_ERROR;
}
return (MJPEG_AVI_RETURN_OK);
RETURN_ERROR :
if(fp != NULL)
{
fclose(fp);
}
if(fp_index != NULL)
{
fclose(fp_index);
}
free(*pAVIFileHandle);
*pAVIFileHandle = NULL;
return MJPEG_AVI_RETURN_ERROR;
}
#else
section ("MJPEGENC_P0")
int32 MJPEG_AVI_OpenFileWrite(uint32 *pAVIFileHandleParam, uint8 *fileName,tJpegParam *ImageParam, uint32 FrameRate) {
FILE *fp, *fp_index;
tMJPEG_AVI_FILEHANDLE *pAVIFileHandle = (tMJPEG_AVI_FILEHANDLE *)pAVIFileHandleParam;
*pAVIFileHandle = (tMJPEG_AVI_FILEHANDLE) malloc(sizeof(tMJPEG_AVI_FileWrite));
fp = (FILE*) fopen((char*)fileName,"wb+");
if( fp == NULL) goto RETURN_ERROR;
setvbuf((FILE*)fp, fileiobuff, _IOLBF, sizeof(fileiobuff));
(*pAVIFileHandle)->filePtr = fp;
memset(&RIFFHDR[8],0,sizeof(MJPEG_AVI_MainAVIHeader));
RIFFHDR[11]=MJPEG_AVIF_HASINDEX;
strncpy ((char *)&((*pAVIFileHandle)->avih), (const char *) &RIFFHDR[8],sizeof(MJPEG_AVI_MainAVIHeader));
(*pAVIFileHandle)->ListhdrlChunkOffset = 12;
RIFFHDR[44] = ImageParam->width;
RIFFHDR[45] = ImageParam->height;
RIFFHDR[40] = RIFFHDR[44] + (RIFFHDR[45] << 16);
RIFFHDR[33] = FrameRate;
if(fwrite(RIFFHDR,1,228,fp) != 228) goto RETURN_ERROR;
lIndexEntry.dwChunkOffset = 228;
(*pAVIFileHandle)->writingDataStarted = 1;
(*pAVIFileHandle)->ListmoviChunkOffset = 216;
(*pAVIFileHandle)->avihChunkOffset = 24;
// fp_index = fopen(TEMP_FILE_NAME,"wb+");
// if( fp_index == NULL) goto RETURN_ERROR;
// (*pAVIFileHandle)->indexFilePtr = fp_index;
return (MJPEG_AVI_RETURN_OK);
RETURN_ERROR :
if(fp != NULL) fclose(fp);
// if(fp_index != NULL) fclose(fp_index);
free(*pAVIFileHandle);
*pAVIFileHandle = NULL;
return MJPEG_AVI_RETURN_ERROR;
}
#endif
/*
*******************************************************************************
Name : MJPEG_AVI_CloseFileWrite
Description : Closes the MJPEG AVI output file
Parameter : MJPEG AVI output file handle
Return Value : MJPEG_AVI_RETURN_OK if file closed OK
: MJPEG_AVI_RETURN_ERROR otherwise
*******************************************************************************
*/
section ("MJPEGENC_P0") // All code
int32 MJPEG_AVI_CloseFileWrite(uint32 AVIFileHandleParam)
{
#ifndef MJPEGREWIND
uint32 fileLength, RiffAviChunkLength, ListMoviChunkLength;
uint32 indexChunkLength, indexFileLength, lResult;
int8 *lpBuffer;
MemObjHandle *StreamBuffer_Obj;
tMJPEG_AVI_FILEHANDLE AVIFileHandle = (tMJPEG_AVI_FILEHANDLE) AVIFileHandleParam;
if(AVIFileHandle == NULL)
{
return MJPEG_AVI_RETURN_ERROR;
}
ListMoviChunkLength = ftell(AVIFileHandle->filePtr)
- AVIFileHandle->ListmoviChunkOffset - 8;
indexFileLength = ftell(AVIFileHandle->indexFilePtr);
indexChunkLength = indexFileLength - 8;
if(fseek(AVIFileHandle->indexFilePtr, 4, SEEK_SET) != 0)
{
return MJPEG_AVI_RETURN_ERROR;
}
if(fwrite(&indexChunkLength,1,4,AVIFileHandle->indexFilePtr) != 4)
{
return MJPEG_AVI_RETURN_ERROR;
}
if(fseek(AVIFileHandle->indexFilePtr, 0, SEEK_SET) != 0)
{
return MJPEG_AVI_RETURN_ERROR;
}
//lpBuffer = (int8 *)malloc(indexFileLength);
StreamBuffer_Obj = JPEG_MemAlloc_NEW(indexFileLength,1,MEM_TYPE_DATA);
if(StreamBuffer_Obj == NULL)
{
return MJPEG_AVI_RETURN_ERROR;
}
lpBuffer = (int8*)JPEG_MemAlloc_ADDRESS(StreamBuffer_Obj);
lResult = fread(lpBuffer, 1, indexFileLength, AVIFileHandle->indexFilePtr);
if(lResult != indexFileLength)
{
return MJPEG_AVI_RETURN_ERROR;
}
if(fwrite(lpBuffer, 1, indexFileLength, AVIFileHandle->filePtr) != indexFileLength)
{
return MJPEG_AVI_RETURN_ERROR;
}
JPEG_MemAlloc_DELETE(StreamBuffer_Obj);
AVIFileHandle->avih.dwFlags |= MJPEG_AVIF_HASINDEX;
fileLength = ftell(AVIFileHandle->filePtr);
RiffAviChunkLength = fileLength - 8;
if(fseek(AVIFileHandle->filePtr,4, SEEK_SET) != 0)
{
return MJPEG_AVI_RETURN_ERROR;
}
if(fwrite(&RiffAviChunkLength,1,4,AVIFileHandle->filePtr) != 4)
{
return MJPEG_AVI_RETURN_ERROR;
}
if(AVIFileHandle->ListmoviChunkOffset != 0)
{
if(fseek(AVIFileHandle->filePtr,AVIFileHandle->ListmoviChunkOffset + 4, SEEK_SET) != 0)
{
return MJPEG_AVI_RETURN_ERROR;
}
if(fwrite(&ListMoviChunkLength,1,4,AVIFileHandle->filePtr) != 4)
{
return MJPEG_AVI_RETURN_ERROR;
}
}
if(AVIFileHandle->avihChunkOffset != 0)
{
if(fseek(AVIFileHandle->filePtr,AVIFileHandle->avihChunkOffset + 8, SEEK_SET) != 0)
{
return MJPEG_AVI_RETURN_ERROR;
}
if(fwrite(&AVIFileHandle->avih,1,sizeof(MJPEG_AVI_MainAVIHeader),AVIFileHandle->filePtr) != sizeof(MJPEG_AVI_MainAVIHeader))
{
return MJPEG_AVI_RETURN_ERROR;
}
}
if(fclose(AVIFileHandle->indexFilePtr) != 0)
{
return MJPEG_AVI_RETURN_ERROR;
}
if(fclose(AVIFileHandle->filePtr) != 0)
{
return MJPEG_AVI_RETURN_ERROR;
}
free(AVIFileHandle);
#else
uint32 lFRN,RiffAviChunkLength,ListMoviChunkLength,*ltharray;
MJPEG_AVI_INDEXENTRY IndexEntry;
uint32 indexhead[2] = { MJPEG_AVI_FOURCC('i','d','x','1'),0};
tMJPEG_AVI_FILEHANDLE AVIFileHandle = (tMJPEG_AVI_FILEHANDLE) AVIFileHandleParam;
if(AVIFileHandle == NULL)
return MJPEG_AVI_RETURN_ERROR;
indexhead[1] = AVIFileHandle->avih.dwTotalFrames * sizeof(MJPEG_AVI_INDEXENTRY);
RiffAviChunkLength = lIndexEntry.dwChunkOffset + indexhead[1];
ListMoviChunkLength = lIndexEntry.dwChunkOffset - AVIFileHandle->ListmoviChunkOffset - 8;
AVIFileHandle->avih.dwFlags |= MJPEG_AVIF_HASINDEX;
if(fseek(AVIFileHandle->filePtr,4, SEEK_SET) != 0)
return MJPEG_AVI_RETURN_ERROR;
if(fwrite(&RiffAviChunkLength,1,4,AVIFileHandle->filePtr) != 4)
return MJPEG_AVI_RETURN_ERROR;
if(fseek(AVIFileHandle->filePtr,AVIFileHandle->ListmoviChunkOffset + 4, SEEK_SET) != 0)
return MJPEG_AVI_RETURN_ERROR;
if(fwrite(&ListMoviChunkLength,1,4,AVIFileHandle->filePtr) != 4)
return MJPEG_AVI_RETURN_ERROR;
if(fseek(AVIFileHandle->filePtr,AVIFileHandle->avihChunkOffset + 8, SEEK_SET) != 0)
return MJPEG_AVI_RETURN_ERROR;
if(fwrite(&AVIFileHandle->avih,1,sizeof(MJPEG_AVI_MainAVIHeader),AVIFileHandle->filePtr) !=
sizeof(MJPEG_AVI_MainAVIHeader))
return MJPEG_AVI_RETURN_ERROR;
IndexEntry.dwChunkOffset = 228;
if (fseek(AVIFileHandle->filePtr,232,SEEK_SET) != 0)
return MJPEG_AVI_RETURN_ERROR;
IndexEntry.ckid = lIndexEntry.ckid;
IndexEntry.dwFlags = 0;
ltharray = (uint32 *) malloc(AVIFileHandle->avih.dwTotalFrames * 4);
for(lFRN=0;lFRN < AVIFileHandle->avih.dwTotalFrames;lFRN++)
{
if (fread(<harray[lFRN] , 1, 4, AVIFileHandle->filePtr) != 4)
return MJPEG_AVI_RETURN_ERROR;
IndexEntry.dwChunkOffset += ltharray[lFRN] + 8;
if (fseek(AVIFileHandle->filePtr,IndexEntry.dwChunkOffset + 4,SEEK_SET) != 0)
return MJPEG_AVI_RETURN_ERROR;
}
IndexEntry.dwChunkOffset = 228;
if (fseek(AVIFileHandle->filePtr,lIndexEntry.dwChunkOffset,SEEK_SET) != 0)
return MJPEG_AVI_RETURN_ERROR;
if (fwrite(indexhead, 1, 8, AVIFileHandle->filePtr) != 8)
return MJPEG_AVI_RETURN_ERROR;
lIndexEntry.dwChunkOffset += 8;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -