⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mjpeg_avi_filewriter.c

📁 ADI blackfin DSP的基于device friver的jpeg压缩算法
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
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(&ltharray[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 + -