📄 avifile.cpp
字号:
#include <afxwin.h>
#include <windowsx.h>
#include <memory.h>
#include <mmsystem.h>
#include <vfw.h>
#include "avifile.h"
BOOL CAVIFile::Compress()
{
HRESULT hr;
hr = AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL);
if (hr != AVIERR_OK)
return FALSE;
AVIFileRelease(pfile);
return TRUE;
}
static HANDLE MakeDib( HBITMAP hbitmap, UINT bits )
{
HANDLE hdib ;
HDC hdc ;
BITMAP bitmap ;
UINT wLineLen ;
DWORD dwSize ;
DWORD wColSize ;
LPBITMAPINFOHEADER lpbi ;
LPBYTE lpBits ;
GetObject(hbitmap,sizeof(BITMAP),&bitmap) ;
//
// DWORD align the width of the DIB
// Figure out the size of the colour table
// Calculate the size of the DIB
//
wLineLen = (bitmap.bmWidth*bits+31)/32 * 4;
wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<<bits : 0);
dwSize = sizeof(BITMAPINFOHEADER) + wColSize +
(DWORD)(UINT)wLineLen*(DWORD)(UINT)bitmap.bmHeight;
//
// Allocate room for a DIB and set the LPBI fields
//
hdib = GlobalAlloc(GHND,dwSize);
if (!hdib)
return hdib ;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib) ;
lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
lpbi->biWidth = bitmap.bmWidth ;
lpbi->biHeight = bitmap.bmHeight ;
lpbi->biPlanes = 1 ;
lpbi->biBitCount = (WORD) bits ;
lpbi->biCompression = BI_RGB ;
lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize ;
lpbi->biXPelsPerMeter = 0 ;
lpbi->biYPelsPerMeter = 0 ;
lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
lpbi->biClrImportant = 0 ;
//
// Get the bits from the bitmap and stuff them after the LPBI
//
lpBits = (LPBYTE)(lpbi+1)+wColSize ;
hdc = CreateCompatibleDC(NULL) ;
GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
// Fix this if GetDIBits messed it up....
lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
DeleteDC(hdc) ;
GlobalUnlock(hdib);
return hdib ;
}
TCLAVIFile::TCLAVIFile(CString tcl_name,LPCTSTR lpszFileName,LPBITMAPINFO bitmapinfo,long microsecperframe, int xdim, int ydim):
CAVIFile(lpszFileName,bitmapinfo, xdim, ydim) {
tclname=tcl_name;
Add(this);
_timer=new AVITimer(microsecperframe);
}
bool TCLAVIFile::AddFrame(LPVOID lpdata,int datalen) {
return CAVIFile::AddFrame(lpdata,datalen,_timer->AddFrame());
}
CAVIFile::CAVIFile(LPCTSTR lpszFileName,LPBITMAPINFO bitmapinfo, int xdim, int ydim)
: FName(lpszFileName),
xDim(xdim), yDim(ydim), bOK(true), nFrames(0)
{
bmpinfo=*bitmapinfo;
pfile = NULL;
ps = NULL;
psCompressed = NULL;
psText = NULL;
aopts[0] = &opts;
WORD wVer = HIWORD(VideoForWindowsVersion());
if (wVer < 0x010A)
{
// oops, we are too old, blow out of here
bOK = false;
}
else
{
AVIFileInit();
}
}
TCLAVIFile::~TCLAVIFile() {
CAVIFile::~CAVIFile();
delete _timer;
Remove(this);
}
CAVIFile::~CAVIFile() {
if (ps)
AVIStreamClose(ps);
if (psCompressed)
AVIStreamClose(psCompressed);
if (psText)
AVIStreamClose(psText);
if (pfile)
AVIFileClose(pfile);
WORD wVer = HIWORD(VideoForWindowsVersion());
if (wVer >= 0x010A)
{
AVIFileExit();
}
}
bool CAVIFile::AddFrame(LPVOID lpdata,int datalen,DWORD time)
{
HRESULT hr;
LPBITMAPINFOHEADER alpbi=&(bmpinfo.bmiHeader);
if (!bOK)
return false;
if (alpbi == NULL)
return false;
if (nFrames == 0)
{
hr = AVIFileOpen(&pfile, // returned file pointer
FName, // file name
OF_WRITE | OF_CREATE, // mode to open file with
NULL); // use handler determined
// from file extension....
if (hr != AVIERR_OK)
{
bOK = false;
return false;
}
_fmemset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 15; // 15 fps
strhdr.dwSuggestedBufferSize = alpbi->biSizeImage;
SetRect(&strhdr.rcFrame, 0, 0, // rectangle for stream
(int) alpbi->biWidth,
(int) alpbi->biHeight);
// And create the stream;
hr = AVIFileCreateStream(pfile, // file pointer
&ps, // returned stream pointer
&strhdr); // stream header
if (hr != AVIERR_OK)
{
bOK = false;
return false;
}
hr = AVIStreamSetFormat(ps, 0,
&bmpinfo, // stream format
sizeof(bmpinfo));
if (hr != AVIERR_OK)
{
bOK = false;
return false;
}
}
hr = AVIStreamWrite(ps, // stream pointer
time, // time of this frame
1, // number to write
lpdata,
datalen, // size of this frame
AVIIF_KEYFRAME, // flags....
NULL,
NULL);
if (hr != AVIERR_OK)
{
bOK = false;
return false;
}
nFrames++;
return true;
}
bool CAVIFile::AddFrame(CBitmap& bmp,LPBITMAPINFO lpbi,DWORD time)
{
HRESULT hr;
if (!bOK)
return false;
LPBITMAPINFOHEADER alpbi = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(bmp, 8));
if (alpbi == NULL)
return false;
if (xDim>=0 && xDim != alpbi->biWidth)
{
GlobalFreePtr(alpbi);
return false;
}
if (yDim>=0 && yDim != alpbi->biHeight)
{
GlobalFreePtr(alpbi);
return false;
}
xDim = alpbi->biWidth;
yDim = alpbi->biHeight;
if (nFrames == 0)
{
hr = AVIFileOpen(&pfile, // returned file pointer
FName, // file name
OF_WRITE | OF_CREATE, // mode to open file with
NULL); // use handler determined
// from file extension....
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
bOK = false;
return false;
}
_fmemset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 15; // 15 fps
strhdr.dwSuggestedBufferSize = alpbi->biSizeImage;
SetRect(&strhdr.rcFrame, 0, 0, // rectangle for stream
(int) alpbi->biWidth,
(int) alpbi->biHeight);
// And create the stream;
hr = AVIFileCreateStream(pfile, // file pointer
&ps, // returned stream pointer
&strhdr); // stream header
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
bOK = false;
return false;
}
_fmemset(&opts, 0, sizeof(opts));
if (!AVISaveOptions(NULL, 0, 1, &ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
{
GlobalFreePtr(alpbi);
bOK = false;
return false;
}
hr = AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL);
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
bOK = false;
return false;
}
hr = AVIStreamSetFormat(psCompressed, 0,
alpbi, // stream format
alpbi->biSize + // format size
alpbi->biClrUsed * sizeof(RGBQUAD));
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
bOK = false;
return false;
}
}
hr = AVIStreamWrite(psCompressed, // stream pointer
time , // time of this frame
1, // number to write
(LPBYTE) alpbi + // pointer to data
alpbi->biSize +
alpbi->biClrUsed * sizeof(RGBQUAD),
alpbi->biSizeImage, // size of this frame
AVIIF_KEYFRAME, // flags....
NULL,
NULL);
if (hr != AVIERR_OK)
{
GlobalFreePtr(alpbi);
bOK = false;
return false;
}
GlobalFreePtr(alpbi);
nFrames++;
return true;
}
TCLAVIFile::cell* TCLAVIFile::_allAVFs=0;
TCLAVIFile *TCLAVIFile::Find(const CString tclname) {
cell *c=_allAVFs;
while (c) {
if (c->avf->tclname==tclname) {
return c->avf;
}
c=c->suiv;
}
return NULL;
}
void TCLAVIFile::Add(TCLAVIFile* avf) {
_allAVFs=new cell(avf,_allAVFs);
}
void TCLAVIFile::Remove(const TCLAVIFile *avf) {
cell *c=_allAVFs,*p=NULL;
while (c) {
if (c->avf==avf) {
if (p) {
p->suiv=c->suiv;
} else {
_allAVFs=c->suiv;
}
delete c;
return;
}
p=c;
c=c->suiv;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -