📄 mjpeg_avi_filewriter.c
字号:
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 + -