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

📄 mjpeg_avi_filewriter.c

📁 ADI blackfin DSP的基于device friver的jpeg压缩算法
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    for(lFRN=0;lFRN < AVIFileHandle->avih.dwTotalFrames;lFRN++) 
    {
    	IndexEntry.dwChunkLength=ltharray[lFRN];
    	if(fwrite(&IndexEntry, 1, sizeof(MJPEG_AVI_INDEXENTRY), AVIFileHandle->filePtr) != 
    	sizeof(MJPEG_AVI_INDEXENTRY)) 
    		return MJPEG_AVI_RETURN_ERROR;      	
    	lIndexEntry.dwChunkOffset += sizeof(MJPEG_AVI_INDEXENTRY);
    	IndexEntry.dwChunkOffset  += IndexEntry.dwChunkLength + 8;
    }    
    free(ltharray);

    if(fclose(AVIFileHandle->filePtr) != 0)      
    	return MJPEG_AVI_RETURN_ERROR;  
    	
    free(AVIFileHandle);   
#endif 
    return MJPEG_AVI_RETURN_OK	;
}





/*
*******************************************************************************
Name            : MJPEG_AVI_OpenStreamWrite
Description     : Creates and opens an MJPEG AVI output stream  
Parameter       : MJPEG AVI file handle
				: Pointer to stream handle
				: Pointer to stream information
Return Value    : MJPEG_AVI_RETURN_OK 		if stream opened OK
				: MJPEG_AVI_RETURN_ERROR 	otherwise
*******************************************************************************
*/
section ("MJPEGENC_P0") // All code
int32 MJPEG_AVI_OpenStreamWrite(uint32 AVIFileHandleParam,
                                uint32 *pAVIStreamHandleParam,
                                tMJPEG_AVI_STREAMINFO *pStreamInfo)
{
#ifndef MJPEGREWIND 	
    tMJPEG_AVI_FILEHANDLE AVIFileHandle = (tMJPEG_AVI_FILEHANDLE) AVIFileHandleParam;
    tMJPEG_AVI_STREAMHANDLEWRITE *pAVIStreamHandle = (tMJPEG_AVI_STREAMHANDLEWRITE *)pAVIStreamHandleParam;

    if(pStreamInfo == NULL)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
	  
    (*pAVIStreamHandle) = (tMJPEG_AVI_STREAMHANDLEWRITE) malloc(sizeof(tMJPEG_AVI_StreamWrite));
    if((*pAVIStreamHandle) == 0)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    (*pAVIStreamHandle)->AVIFileHandle = AVIFileHandle;
    (*pAVIStreamHandle)->AVIStreamInfo = *pStreamInfo;
    (*pAVIStreamHandle)->streamId = AVIFileHandle->avih.dwStreams++;
#else
    uint16 temp;
    tMJPEG_AVI_FILEHANDLE AVIFileHandle = (tMJPEG_AVI_FILEHANDLE) AVIFileHandleParam;
    tMJPEG_AVI_STREAMHANDLEWRITE *pAVIStreamHandle = (tMJPEG_AVI_STREAMHANDLEWRITE *)pAVIStreamHandleParam;
    if(pStreamInfo == NULL)        return MJPEG_AVI_RETURN_ERROR;    
    memset(pStreamInfo,sizeof(tMJPEG_AVI_STREAMINFO),0);
    strcpy(pStreamInfo->szName,"JUNK");
    pStreamInfo->dwScale = 1;
	pStreamInfo->rcFrame.bottom = (int16) RIFFHDR[45];  
    pStreamInfo->rcFrame.right  = (int16) RIFFHDR[44];
    pStreamInfo->fccType    = RIFFHDR[27];
    pStreamInfo->fccHandler = RIFFHDR[28];    
    pStreamInfo->dwRate = RIFFHDR[33];        
    (*pAVIStreamHandle) = (tMJPEG_AVI_STREAMHANDLEWRITE) malloc(sizeof(tMJPEG_AVI_StreamWrite));
    if((*pAVIStreamHandle) == 0)   return MJPEG_AVI_RETURN_ERROR;    
    (*pAVIStreamHandle)->AVIFileHandle = AVIFileHandle;
    (*pAVIStreamHandle)->AVIStreamInfo = *pStreamInfo;
    (*pAVIStreamHandle)->streamId = AVIFileHandle->avih.dwStreams++;        
    temp = (((*pAVIStreamHandle)->streamId & 0xff) << 8) + (((*pAVIStreamHandle)->streamId & 0xff00) >> 8) + 0x3030;
    if((*pAVIStreamHandle)->AVIStreamInfo.fccType == MJPEG_AVI_StreamTypeVIDEO) 
    ltmp[0] = lIndexEntry.ckid = temp  + 0x63640000;     
    else  ltmp[0] = lIndexEntry.ckid = temp + 0x62770000;  
#endif    
    return MJPEG_AVI_RETURN_OK;
}

/*
*******************************************************************************
Name            : MJPEG_AVI_CloseStreamWrite
Description     : Closes and destroys an MJPEG AVI output stream
Parameter       : MJPEG AVI stream handle
Return Value    : MJPEG_AVI_RETURN_OK 		if stream closed OK
				: MJPEG_AVI_RETURN_ERROR 	otherwise
*******************************************************************************
*/
section ("MJPEGENC_P0") // All code
int32 MJPEG_AVI_CloseStreamWrite(uint32 AVIStreamHandleParam)
{
    tMJPEG_AVI_STREAMHANDLEWRITE AVIStreamHandle = (tMJPEG_AVI_STREAMHANDLEWRITE) AVIStreamHandleParam;
    if(AVIStreamHandle == NULL)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    free(AVIStreamHandle);
    return MJPEG_AVI_RETURN_OK;
}

/*
*******************************************************************************
Name            : MJPEG_AVI_SetFormat
Description     : Writes the given MJPEG AVI stream format information to a
				  given position in the stream.
				  Note: Currently, only lPos=0 is supported
Parameter       : AVI Stream handle
				  Stream position to write format info
				  Pointer to format information to write
				  Length of the format information
Return Value    : MJPEG_AVI_RETURN_OK 		if format set OK
				  MJPEG_AVI_RETURN_ERROR 	otherwise
*******************************************************************************
*/
section ("MJPEGENC_P0") // All code
int32 MJPEG_AVI_SetFormat(uint32 AVIStreamHandleParam, uint32 lPos,
                            uint8 *formatData, uint32 formatDataLength)
{
#ifndef MJPEGREWIND 	
    FILE *fp;
    tMJPEG_AVI_STREAMINFO *pStreamInfo;
    MJPEG_AVI_StreamHeader lStrHeader;
    uint32 ListstrlChunkLength, strhChunkLength, strfChunkLength;

    tMJPEG_AVI_STREAMHANDLEWRITE AVIStreamHandle = (tMJPEG_AVI_STREAMHANDLEWRITE) AVIStreamHandleParam;
    if(lPos != 0 || AVIStreamHandle == NULL || formatData == NULL)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }

    pStreamInfo = &AVIStreamHandle->AVIStreamInfo;

    lStrHeader.dwFlags = pStreamInfo->dwFlags;
    lStrHeader.dwInitialFrames = pStreamInfo->dwInitialFrames;
    lStrHeader.dwLength = pStreamInfo->dwLength;
    lStrHeader.dwQuality = pStreamInfo->dwQuality;
    lStrHeader.dwRate = pStreamInfo->dwRate;
    lStrHeader.dwSampleSize = pStreamInfo->dwSampleSize;
    lStrHeader.dwScale = pStreamInfo->dwScale;
    lStrHeader.dwStart = pStreamInfo->dwStart;
    lStrHeader.dwSuggestedBufferSize = pStreamInfo->dwSuggestedBufferSize;
    lStrHeader.rcFrame = pStreamInfo->rcFrame;
    lStrHeader.wLanguage = pStreamInfo->wLanguage;
    lStrHeader.wPriority = pStreamInfo->wPriority;

    lStrHeader.fccType = pStreamInfo->fccType;
    lStrHeader.fccHandler = pStreamInfo->fccHandler;

    fp = AVIStreamHandle->AVIFileHandle->filePtr;

    strhChunkLength = sizeof(MJPEG_AVI_StreamHeader);
    strfChunkLength = formatDataLength;
    ListstrlChunkLength = strhChunkLength + 8 + strfChunkLength + 8 + 4;

	if(fwrite("LIST",1,4,fp) != 4)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    if(fwrite(&ListstrlChunkLength,1,4,fp) != 4)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
	if(fwrite("strl",1,4,fp) != 4)
	{
        return MJPEG_AVI_RETURN_ERROR;
    }
	if(fwrite("strh",1,4,fp) != 4)
	{
        return MJPEG_AVI_RETURN_ERROR;
    }
    if(fwrite(&strhChunkLength,1,4,fp) != 4)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    if(fwrite(&lStrHeader,1,sizeof(MJPEG_AVI_StreamHeader),fp) != sizeof(MJPEG_AVI_StreamHeader))
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    if(fwrite("strf",1,4,fp) != 4)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    if(fwrite(&strfChunkLength,1,4,fp) != 4)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    if(fwrite(formatData,1,formatDataLength,fp) != formatDataLength)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
#endif    
    return MJPEG_AVI_RETURN_OK;
}

/*
*******************************************************************************
Name            : MJPEG_AVI_WriteStream
Description     : Write the given data to the MJPEG AVI stream.  
				: If IsKeyFrame = 1, a keyframe is set at the current position.
Parameter       : MJPEG AVI stream handle, 
		        : Pointer to data buffer
				: Length of data buffer 
				: IsKeyFrame = 1: Set a keyframe at the current location
Return Value    : MJPEG_AVI_RETURN_OK 		if data written OK
				: MJPEG_AVI_RETURN_EVALUATIONLIMITREACHED if evaluation limit reached
				: MJPEG_AVI_RETURN_ERROR 	otherwise
*******************************************************************************
*/
section ("MJPEGENC_P0") // All code
int32 MJPEG_AVI_WriteStream(uint32 AVIStreamHandleParam,  
							uint8 *pDataBuffer, uint32 dataLength, 
							uint8 IsKeyFrame)
{
#ifndef MJPEGREWIND 	 
	tMJPEG_AVI_STREAMHANDLEWRITE AVIStreamHandle = (tMJPEG_AVI_STREAMHANDLEWRITE) AVIStreamHandleParam;
    uint16 temp;     
    uint32 ListhdrlChunkLength, lTempOffset;
    MJPEG_AVI_INDEXENTRY lIndexEntry;
    FILE *fp = AVIStreamHandle->AVIFileHandle->filePtr;
    int8 lTemp = 0;
    
#ifdef ISEVALUATION
	/* Limit evaluation version to a given number of encoded frames */
	static unsigned int _Axx = 0;		
	if (++_Axx > EVALUATIONMAXFRAMES)
	{
		return MJPEG_AVI_RETURN_EVALUATIONLIMITREACHED; 
	}
#endif

    if(AVIStreamHandle->AVIFileHandle->writingDataStarted == 0)
    {
        AVIStreamHandle->AVIFileHandle->writingDataStarted = 1;
        AVIStreamHandle->AVIFileHandle->ListmoviChunkOffset = ftell(fp);
        
		if(fwrite("LIST0000movi",1,12,fp) != 12)
        {
            return MJPEG_AVI_RETURN_ERROR;
        }

        lTempOffset = ftell(fp);
        ListhdrlChunkLength = AVIStreamHandle->AVIFileHandle->ListmoviChunkOffset
            - AVIStreamHandle->AVIFileHandle->ListhdrlChunkOffset - 8;

		if(fseek(fp, AVIStreamHandle->AVIFileHandle->ListhdrlChunkOffset + 4, SEEK_SET) != 0)
        {
            return MJPEG_AVI_RETURN_ERROR;
        }

        if(fwrite(&ListhdrlChunkLength, 1, 4, fp) != 4)
        {
            return MJPEG_AVI_RETURN_ERROR;
        }

		if(fseek(fp, lTempOffset,SEEK_SET) != 0)
        {
            return MJPEG_AVI_RETURN_ERROR;
        }
    }

    AVIStreamHandle->AVIFileHandle->avih.dwTotalFrames++;
    temp = AVIStreamHandle->streamId + 0x3030;

    if(AVIStreamHandle->AVIStreamInfo.fccType == MJPEG_AVI_StreamTypeVIDEO)
    {
        lIndexEntry.ckid = (temp << 16) + 0x6463; /*0x6463 is hex representation of dc*/
    }
    else 
    {
        /* Means this is of type MJPEG_AVI_StreamTypeAUDIO */
        lIndexEntry.ckid = (temp << 16) + 0x7762; /*0x7762 is hex representation of wb*/
    }
    lIndexEntry.ckid = SWAP_BYTE(lIndexEntry.ckid);
    /* Chunk length is even */
    lIndexEntry.dwChunkLength = dataLength + (dataLength % 2);
    pDataBuffer[dataLength] = 0; // clear buffer tail
    lIndexEntry.dwChunkOffset = ftell(fp);
    lIndexEntry.dwFlags = 0;
    if(IsKeyFrame == 1)
    {
        lIndexEntry.dwFlags |= MJPEG_AVIIF_KEYFRAME;
    }

    if(fwrite(&lIndexEntry, 1, sizeof(MJPEG_AVI_INDEXENTRY), AVIStreamHandle->AVIFileHandle->indexFilePtr) != sizeof(MJPEG_AVI_INDEXENTRY))
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    
    if(fwrite(&lIndexEntry.ckid, 1, 4, fp) != 4)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
    if(fwrite(&lIndexEntry.dwChunkLength,1,4,fp) != 4)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }
	if(fwrite(pDataBuffer,1,lIndexEntry.dwChunkLength,fp) != lIndexEntry.dwChunkLength)       return MJPEG_AVI_RETURN_ERROR;    
/*
    if(fwrite(pDataBuffer,1,dataLength,fp) != dataLength)
    {
        return MJPEG_AVI_RETURN_ERROR;
    }

    if(lIndexEntry.dwChunkLength != dataLength)
    {
        if(fwrite(&lTemp,1,1,fp) != 1)
        {
            return MJPEG_AVI_RETURN_ERROR;
        }
    }
*/    
#else
	tMJPEG_AVI_STREAMHANDLEWRITE AVIStreamHandle = (tMJPEG_AVI_STREAMHANDLEWRITE) AVIStreamHandleParam;    
    FILE *fp = AVIStreamHandle->AVIFileHandle->filePtr;   
#ifdef ISEVALUATION	
	static unsigned int _Axx = 0;		
	if (++_Axx > EVALUATIONMAXFRAMES) return MJPEG_AVI_RETURN_EVALUATIONLIMITREACHED; 	
#endif    
    ltmp[1] = lIndexEntry.dwChunkLength = dataLength + (dataLength % 2); /* Chunk length is even */
    pDataBuffer[dataLength] = 0;       
	AVIStreamHandle->AVIFileHandle->avih.dwTotalFrames++;    
    if(fwrite(ltmp, 1, 8, fp) != 8)        return MJPEG_AVI_RETURN_ERROR;    
    if(fwrite(pDataBuffer,1,lIndexEntry.dwChunkLength,fp) != lIndexEntry.dwChunkLength)       
    return MJPEG_AVI_RETURN_ERROR;        
    lIndexEntry.dwChunkOffset += lIndexEntry.dwChunkLength + 8;    
#endif    
    return MJPEG_AVI_RETURN_OK;
}


/*
*******************************************************************************
Name            : MJPEG_AVI_SetStreamParams
Description     : Set the stream parameters to the supplied values
Parameter       : Pointer to stream information
				: Pointer to JPEG image parameters
				: Frame rate (frames/second)
Return Value    : MJPEG_AVI_RETURN_OK 		if parameters set OK
				  MJPEG_AVI_RETURN_ERROR 	otherwise
*******************************************************************************
*/
section ("MJPEGENC_P0") // All code
int32 MJPEG_AVI_SetStreamParams (tMJPEG_AVI_STREAMINFO *MJPEG_AVI_StreamInfo, 
								 tJpegParam *ImageParam,  
								 uint32 FrameRate)
{
#ifndef MJPEGREWIND 	
	MJPEG_AVI_StreamInfo->dwCaps = 0;
    MJPEG_AVI_StreamInfo->dwEditCount = 0;
    MJPEG_AVI_StreamInfo->dwFlags = 0;
    MJPEG_AVI_StreamInfo->dwFormatChangeCount = 0;
    MJPEG_AVI_StreamInfo->dwInitialFrames = 0;
    MJPEG_AVI_StreamInfo->dwLength = 0;
    MJPEG_AVI_StreamInfo->dwQuality = 0;
    MJPEG_AVI_StreamInfo->dwRate = FrameRate;
    MJPEG_AVI_StreamInfo->dwSampleSize = 0;
    MJPEG_AVI_StreamInfo->dwScale = 1;
	MJPEG_AVI_StreamInfo->dwStart = 0;
    MJPEG_AVI_StreamInfo->dwSuggestedBufferSize = 0;
    MJPEG_AVI_StreamInfo->fccHandler = MJPEG_AVI_FOURCC('M','J','P','G');
    MJPEG_AVI_StreamInfo->fccType = MJPEG_AVI_FOURCC('v','i','d','s');
    MJPEG_AVI_StreamInfo->rcFrame.bottom = ImageParam->height;
    MJPEG_AVI_StreamInfo->rcFrame.top = 0;
    MJPEG_AVI_StreamInfo->rcFrame.left = 0;
    MJPEG_AVI_StreamInfo->rcFrame.right = ImageParam->width;

	strcpy(MJPEG_AVI_StreamInfo->szName,"JUNK");
	MJPEG_AVI_StreamInfo->wLanguage = 0;
    MJPEG_AVI_StreamInfo->wPriority = 0;
#endif
	return MJPEG_AVI_RETURN_OK;
};

/*
*******************************************************************************
Name            : MJPEG_AVI_CopyParams
Description     : Copies JPEG image information to a bitmap header
Parameter       : Pointer to bitmap header 
				: JPEG image parameters
Return Value    : MJPEG_AVI_RETURN_OK 		if parameters copied OK
				: MJPEG_AVI_RETURN_ERROR 	otherwise
*******************************************************************************
*/
section ("MJPEGENC_P0") // All code
int32 MJPEG_AVI_CopyParams (tMJPEG_AVI_BITMAPINFO *Format, 
							tJpegParam *ImageParam)
{
#ifndef MJPEGREWIND 	
    Format->bmiHeader.biSize = sizeof(tMJPEG_AVI_BITMAPINFOHEADER);
    Format->bmiHeader.biWidth = ImageParam->width;
    Format->bmiHeader.biHeight = ImageParam->height;
    Format->bmiHeader.biPlanes = 1;
    Format->bmiHeader.biBitCount = 24;
    Format->bmiHeader.biCompression = MJPEG_AVI_FOURCC('M','J','P','G');
    Format->bmiHeader.biSizeImage = 0;
    Format->bmiHeader.biXPelsPerMeter = 0;
    Format->bmiHeader.biYPelsPerMeter = 0;
    Format->bmiHeader.biClrUsed = 0;
    Format->bmiHeader.biClrImportant = 0;

    Format->bmiColors[0].rgbBlue = 0;
    Format->bmiColors[0].rgbGreen = 0;
    Format->bmiColors[0].rgbRed = 0;
    Format->bmiColors[0].rgbReserved = 0;
#endif	
	return MJPEG_AVI_RETURN_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -