📄 im-avisynth.cpp
字号:
#include "prTypes.h"
#include "prStructs.h"
#include "prImport.h"
#include <vfw.h>
struct FileInfo {
PAVIFILE file;
PAVISTREAM video, audio;
PGETFRAME getframe;
unsigned char shift;
};
int ImGetInfo(imStdParms* stdparms, imFileAccessRec* fileInfo, imFileInfoRec* imFileInfo) {
FileInfo fi;
if (FAILED(AVIFileOpen(&fi.file, fileInfo->filespec.name, OF_READ, NULL)))
return imBadFile;
fi.video = 0;
AVIFileGetStream(fi.file, &fi.video, streamtypeVIDEO, 0);
fi.audio = 0;
AVIFileGetStream(fi.file, &fi.audio, streamtypeAUDIO, 0);
if (!fi.video && !fi.audio)
return imNoContent;
imFileInfo->hasVideo = false;
imFileInfo->hasAudio = false;
if (fi.video) {
imFileInfo->hasVideo = true;
AVISTREAMINFO asi;
if (FAILED(AVIStreamInfo(fi.video, &asi, sizeof(asi))))
return imBadFile;
imFileInfo->vidInfo.imageWidth = asi.rcFrame.right;
imFileInfo->vidInfo.imageHeight = asi.rcFrame.bottom;
// imFileInfo->vidInfo.pixelAspect = ???
imFileInfo->vidInfo.depth = 32;
imFileInfo->vidInfo.subType = imUncompressed;
// imFileInfo->vidInfo.fieldType = fieldsNone;
// imFileInfo->vidInfo.fieldsStacked = false;
// imFileInfo->vidInfo.hasPulldown = false;
// imFileInfo->vidInfo.pulldownPhase = 0;
imFileInfo->vidInfo.alphaType = alphaNone;
imFileInfo->vidInfo.isVectors = false;
imFileInfo->vidInfo.isStill = false;
imFileInfo->vidInfo.noDuration = false;
imFileInfo->vidInfo.isFramestore = false;
imFileInfo->vidScale = int(double(asi.dwRate) * 500 / asi.dwScale + 0.5);
imFileInfo->vidSampleSize = 500;
imFileInfo->vidDuration = asi.dwLength * 500;
imFileInfo->canDraw = false;
BITMAPINFOHEADER bi;
memset(&bi, 0, sizeof(bi));
bi.biSize = sizeof(bi);
bi.biWidth = asi.rcFrame.right;
bi.biHeight = asi.rcFrame.bottom;
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = BI_RGB;
fi.getframe = AVIStreamGetFrameOpen(fi.video, &bi);
if (!fi.getframe)
return imBadCodec;
}
if (fi.audio) {
imFileInfo->hasAudio = true;
AVISTREAMINFO asi;
if (FAILED(AVIStreamInfo(fi.audio, &asi, sizeof(asi))))
return imBadFile;
WAVEFORMATEX wfx;
long size = sizeof(wfx);
if (FAILED(AVIStreamReadFormat(fi.audio, 0, &wfx, &size)))
return imBadFile;
imFileInfo->audInfo.audStereo = wfx.nChannels-1;
imFileInfo->audInfo.aud16 = (wfx.wBitsPerSample>>3)-1;
fi.shift = imFileInfo->audInfo.audStereo + imFileInfo->audInfo.aud16;
imFileInfo->audInfo.twosComp = imFileInfo->audInfo.aud16;
imFileInfo->audInfo.subType = imUncompressed;
imFileInfo->audScale = wfx.nSamplesPerSec;
imFileInfo->audSampleSize = 1;
imFileInfo->audDuration = asi.dwLength;
imFileInfo->canDraw = false;
}
imFileInfo->privatedata = long(new FileInfo(fi));
imFileInfo->prefs = 0;
imFileInfo->hasDataRate = false;
return imNoErr;
}
int ImImportImage(imStdParms* stdparms, imFileRef ref, imImportImageRec* imageRec) {
FileInfo* pfi = (FileInfo*)imageRec->privatedata;
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pfi->getframe, imageRec->pos / 500);
if (!lpbi)
return imBadFile;
const int width = lpbi->biWidth, height = lpbi->biHeight;
if (width != imageRec->dstWidth || height != imageRec->dstHeight)
return imOtherErr;
char* src = (char*)lpbi + lpbi->biSize;
int* dst = (int*)imageRec->pix;
for (int y=height; y; --y) {
for (int x=0; x<width; ++x)
dst[x] = src[x*3+0] + src[x*3+1] * 256 + src[x*3+2]*65536;
dst += width;
src += width*3;
}
return imNoErr;
}
int ImImportAudio(imStdParms* stdparms, imFileRef ref, imImportAudioRec* audioRec) {
FileInfo* pfi = (FileInfo*)audioRec->privatedata;
long bytes=0, samples=0;
if (FAILED(AVIStreamRead(pfi->audio, audioRec->sample >> pfi->shift, audioRec->size >> pfi->shift,
audioRec->buffer, audioRec->size, &bytes, &samples)) || bytes != audioRec->size)
{
return imBadFile;
}
return imNoErr;
}
int ImInit(imStdParms* stdParms, imImportInfoRec* importInfo) {
importInfo->canOpen = false;
importInfo->canSave = false;
importInfo->canDelete = false;
importInfo->canResize = false;
importInfo->canDoSubsize = false;
importInfo->canDoContinuousTime = false;
importInfo->noFile = false;
importInfo->addToMenu = imMenuNew;
importInfo->hasSetup = false;
importInfo->dontCache = false;
importInfo->setupOnDblClk = false;
importInfo->keepLoaded = false;
importInfo->priority = 0;
return imNoErr;
}
int ImGetIndFormat(imStdParms* stdparms, int index, imIndFormatRec* ifrec) {
if (index != 0)
return imBadFormatIndex;
ifrec->filetype = ' SVA';
ifrec->flags = xfCanOpen | xfCanImport | xfCanReplace | xfIsMovie;
lstrcpy(ifrec->FormatName, "Avisynth/VirtualDub file");
lstrcpy(ifrec->FormatShortName, "Avisynth/VirtualDub file");
memcpy(ifrec->PlatformExtension, "AVS\0VDR\0", 9);
return imNoErr;
}
PREMPLUGENTRY xImportEntry(int selector, imStdParms* stdParms, long param1, long param2) {
switch (selector) {
case imInit:
return ImInit(stdParms, (imImportInfoRec *)param1);
case imImportImage:
return ImImportImage(stdParms, (imFileRef)param1, (imImportImageRec *)param2);
case imImportAudio:
return ImImportAudio(stdParms, (imFileRef)param1, (imImportAudioRec *)param2);
case imGetInfo:
return ImGetInfo(stdParms, (imFileAccessRec *)param1, (imFileInfoRec *)param2);
case imGetIndFormat:
return ImGetIndFormat(stdParms, param1, (imIndFormatRec *)param2);
default:
return imNoErr;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -