unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ComCtrls, inifiles, GL,glu, FFStructs;
type
TParams=record
name:string;
t:dword; default:string;
displayvalue:string;
actualvalue:single;
end;
TfmMain = class(TForm)
odAVI: TOpenDialog;
tPlay: TTimer;
lAPIversion: TLabel;
previewpanel: TPanel;
ebAVIFilename: TEdit;
bBrowse: TButton;
GroupBox2: TGroupBox;
lVideoWidth: TLabel;
lVideoHeight: TLabel;
lBitDepth: TLabel;
lOrientation: TLabel;
pnInfo: TPanel;
lProfile: TLabel;
Label3: TLabel;
cbPlugins: TComboBox;
bProcessFrame: TButton;
bPlayAndProcess: TButton;
cbPluginProcessFrames: TCheckBox;
bDeInitPlugin: TButton;
bStop: TButton;
Memo1: TMemo;
lbParams: TListBox;
sbParam: TScrollBar;
lbpname: TLabel;
lbpvalue: TLabel;
Label2: TLabel;
btnReload: TButton;
Panel1: TPanel;
Label1: TLabel;
cbVerify: TCheckBox;
cbTest32Bit: TCheckBox;
cbCheckers: TCheckBox;
btnGrabFrame: TButton;
Panel2: TPanel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Panel3: TPanel;
PaintBox1: TPaintBox;
Panel4: TPanel;
glpanel: TPanel;
Panel5: TPanel;
pbRGB: TPaintBox;
Panel6: TPanel;
pbAlpha: TPaintBox;
Memo2: TMemo;
lbAviStatus: TLabel;
Label7: TLabel;
sbTime: TScrollBar;
lbTime: TLabel;
sbATime: TScrollBar;
Label8: TLabel;
Label9: TLabel;
cbATime: TCheckBox;
Memo3: TMemo;
procedure ebAVIFilenameChange(Sender: TObject);
procedure bProcessFrameClick(Sender: TObject);
procedure cbPluginsChange(Sender: TObject);
procedure bBrowseClick(Sender: TObject);
procedure bPlayAndProcessClick(Sender: TObject);
procedure tPlayTimer(Sender: TObject);
procedure bStopClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
procedure sbParamChange(Sender: TObject);
procedure lbParamsClick(Sender: TObject);
procedure cbVerifyClick(Sender: TObject);
procedure cbTest32BitClick(Sender: TObject);
procedure cbCheckersClick(Sender: TObject);
procedure btnGrabFrameClick(Sender: TObject);
procedure btnReloadClick(Sender: TObject);
procedure bDeInitPluginClick(Sender: TObject);
procedure sbTimeChange(Sender: TObject);
private
exepath:string;
lpBitmapInfoHeader: pBitmapInfoHeader;
CurrentPlug:thandle;
PluginInstance:dword; InstanceReady:boolean;
currentParam:integer;
Params: array of TParams;
skipdefaults:boolean;
verifyParam:boolean;
NumParams: dword;
PluginLoaded: boolean;
glplugin:boolean;
supportstime:boolean;
glinit:boolean;
framestore:pointer;
DC:HDC;
RC:HGLRC;
tpot:integer;
tex24bit:gluint; tex32bit:gluint;
checks:gluint; checksangle:integer;
checksenabled:boolean;
test32bit:boolean;
framedump:TMemoryStream;
absoluteTime:double; timeAccel:single;
procedure GetPlugins;
procedure LoadAVI;
procedure LoadPlugin;
procedure collectInfo;
procedure CollectParamNames;
procedure CollectParamTypes;
function paramTypeString(t:dword):string;
procedure CollectParamDefaults;
procedure CollectParamValues;
procedure CollectParamDisplay;
function initplugin:dword;
procedure DeInitPlugin;
procedure DisplayFrame(lpbitmapinfoheader: pbitmapinfoheader; channel: integer);
procedure Process;
procedure ProfileAndProcessFrame(pFrame: pointer; PluginInstance: dword); procedure ProfileAndProcessGLFrame(pFrame: pointer; PluginInstance: dword);
function setupPixelFormat(DC:HDC):boolean;
procedure InitGL;
procedure InitTexture(w,h:integer);
procedure RefreshGLDisplay;
procedure UploadFrame(bits:pointer;w,h:integer);
public
AHDC: HDC; end;
const
AppVersion: string='2.03';
APIversion: string='1.5';
var
fmMain: TfmMain;
CurrentFrame: array [0..1] of integer;
NumFrames: array [0..1] of integer;
bits: pointer;
lpBitmapInfoHeader: pBitmapInfoHeader;
implementation
uses pluginHost, avi, utils;
var
p32bitFrame: pointer;
procedure TfmMain.FormCreate(Sender: TObject);
var
inifile: TInifile;
tempFilename: string;
tempPluginname:string;
index:integer;
begin
exepath:=extractfilepath(application.exename);
CurrentPlug:=0;
CurrentParam:=0;
setlength(params,0);
PluginLoaded:=false;
verifyParam:=true;
fmMain.Caption:='FreeFrame Plugin Tester v'+AppVersion;
lAPIversion.Caption:='for FreeFrame API v'+APIversion;
inifile:=Tinifile.Create(exepath+'FreeFrame.ini');
with inifile do begin
tempFilename:=ReadString('Filenames','CurrentAVI','');
tempPluginname:=ReadString('Filenames','CurrentDll','');
end;
inifile.Free;
checks:=0;
checksenabled:=false;
test32bit:=false;
InitGL;
if fileExists(tempFilename) then begin
ebAVIfilename.Text:=tempFilename;
loadAVI;
end;
PluginInstance:=0;
getPlugins;
currentPlug:=0;
if (cbPlugins.Items.Count>0) then begin
if not avi.AVIopen[0] then begin
showmessage('Sorry, Unable to Load Plugin, until a Avi File has successfully loaded');
exit;
end else begin
currentPlug:=0;
if tempPluginname<>'' then begin
if not fileExists(exepath+'plugins\'+tempPluginname) then begin
showmessage('Sorry, Unable to find '+tempPluginname+', loading first plugin in list');
end else begin
index:=cbPlugins.Items.IndexOf(tempPluginname);
if index>-1 then begin
cbPlugins.OnChange:=nil;
cbPlugins.ItemIndex:=index;
cbPlugins.OnChange:=cbPLuginsChange;
end;
end;
end;
LoadPlugin;
end;
end;
framedump:=TMemoryStream.Create;
framedump.SetSize(glpanel.Width*glpanel.Height*4);
end;
procedure TfmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
inifile: TInifile;
begin
if tPlay.Enabled then tPlay.Enabled:=false;
if VideoInfoStruct.bitdepth=2 then utils.free32bitBuffer(p32bitFrame, VideoInfoStruct);
if pluginloaded then begin
deinitPlugin;
end;
inifile:=Tinifile.Create(exepath+'FreeFrame.ini');
inifile.WriteString('Filenames','CurrentDll',cbPlugins.items[cbPlugins.itemindex]);
inifile.Free;
framedump.Free;
if avi.AVIopen[0] then avi.CloseAVI(0);
CanClose:=true;
end;
procedure TfmMain.GetPlugins;
function checkValid(name: string):boolean;
const
functionName = 'plugMain';
var
h: thandle;
proc: pointer;
begin
result:=false;
if not (compareText(copy(name,length(name)-3,4),'.dll')=0) then exit; h := LoadLibrary(pchar(name));
if h <> 0 then begin Proc := GetProcAddress(h, functionName);
if Proc <> nil then result:=true;
FreeLibrary(h);
end;
end;
var
plugins: string;
t: TSearchRec;
begin
cbPlugins.OnChange:=nil;
cbPlugins.items.clear;
plugins := exepath+'plugins\';
if findfirst(plugins+'*.dll', faAnyFile, t) = 0 then begin
if checkValid(plugins+t.name) then cbPlugins.items.add(t.name);
while findnext(t) = 0 do if checkValid(plugins+t.name) then cbPlugins.items.add(t.name);
findclose(t);
end;
if cbPlugins.Items.Count>0 then cbPlugins.ItemIndex:=0;
cbPlugins.OnChange:=fmMain.cbPluginsChange;
end;
procedure TfmMain.LoadAVI;
begin
if tPlay.Enabled then tPlay.Enabled:=false;
deinitplugin;
if AVIopen[0] then DeInit;
lbAvistatus.Caption:='Avi Status: Loading';
AVI.Init;
CurrentFrame[0]:=0;
PluginHost.VideoInfoStruct:=AVI.OpenAVI(ebAVIfilename.text,0);
if AVIopen[0] then begin
lVideoWidth.caption:=inttostr(PluginHost.VideoInfoStruct.FrameWidth);
lVideoHeight.caption:=inttostr(PluginHost.VideoInfoStruct.FrameHeight);
case PluginHost.VideoInfoStruct.BitDepth of
0: lBitDepth.Caption:='16 bit';
1: lBitDepth.Caption:='24 bit';
2: lBitDepth.Caption:='32 bit';
end;
case VideoInfoStruct.orientation of
1: lOrientation.caption:='Right Way Up';
2: lOrientation.caption:='Upside Down';
end;
inc(currentFrame[0]);
lpbitmapinfoheader:=AVI.GetFrame(currentFrame[0],0);
displayframe(lpbitmapinfoheader,0);
lbAvistatus.Caption:='Avi Status: Ready';
end;
end;
procedure TfmMain.LoadPlugin;
var
filename:pchar;
begin
tPlay.Enabled:=false;
deinitplugin;
if cbPlugins.itemindex<0 then exit;
plugMain:=nil;
if currentPlug<>0 then freeLibrary(currentPlug);
try
filename:=pchar(exepath+'plugins\'+cbPlugins.items[cbPlugins.itemindex]);
copyfile(filename,pchar(exepath+'tempplugincopy.dll'),false);
currentPlug := LoadLibrary(pchar(exepath+'tempplugincopy.dll'));
if currentPlug <> 0 then begin try
plugMain := GetProcAddress(currentPlug, 'plugMain');
if @plugMain = nil then begin
FreeLibrary(currentPlug);
currentPlug:=0;
end;
except
memo1.Lines.Add('** Exception during while discovering plugMain');
end;
end;
if not assigned(plugMain) then begin
showmessage('Sorry, Failed to find procAddress for plugMain');
exit;
end;
except
memo1.Lines.Add('** Exception during while loading plugin');
end;
skipdefaults:=false;
if initplugin=0 then PluginLoaded:=true;
end;
procedure TfmMain.collectInfo;
var
pc16,pc24,pc32:integer;
i: integer;
result,names,defaults:dword;
text:string;
begin
memo1.Clear;
memo1.Lines.Add('[ PluginInfoStruct ]');
memo1.Lines.Add(' ');
result:=PluginHost.GetInfo;
if result=FF_FAIL then begin
memo1.Lines.Add('ERROR');
end else begin
memo1.Lines.Add('API MajorVersion: '+inttostr(PluginHost.PluginInfoStruct.APIMajorVersion));
memo1.Lines.Add('API Minor Version: '+inttostr(PluginHost.PluginInfoStruct.APIMinorVersion));
memo1.Lines.Add('Unique ID: '+PluginHost.PluginInfoStruct.PluginUniqueID);
memo1.Lines.Add('Name : '+PluginHost.PluginInfoStruct.PluginName);
case PluginHost.PluginInfoStruct.PluginType of
0: memo1.Lines.Add('Type: Effect');
1: memo1.Lines.Add('Type: Source');
end;
end;
memo1.Lines.Add(' ');
memo1.Lines.Add('[ Plugin Capabilities ]');
memo1.Lines.Add(' ');
result:=integer(PluginHost.GetPluginCaps(0));
if result=FF_FAIL then memo1.lines.add('16bit: ERROR')
else if result=0 then memo1.lines.add('16bit: No') else memo1.lines.add('16bit: Yes');
pc16:=result;
result:=integer(PluginHost.GetPluginCaps(1));
if result=FF_FAIL then memo1.lines.add('24bit: ERROR')
else if result=0 then memo1.lines.add('24bit: No') else memo1.lines.add('24bit: Yes');
pc24:=result;
result:=integer(PluginHost.GetPluginCaps(2));
if result=FF_FAIL then memo1.lines.add('32bit: ERROR')
else if result=0 then memo1.lines.add('32bit: No') else memo1.lines.add('32bit: Yes');
pc32:=result;
if (pc24=0) and (pc32=1) then begin
VideoInfoStruct.BitDepth:=2;
lBitDepth.Caption:='32 bit';
end;
p32bitFrame:=Utils.Make32bitBuffer(VideoInfoStruct);
result:=integer(PluginHost.GetPluginCaps(3));
if result=FF_FAIL then memo1.lines.add('ProcessFrameCopy: Error')
else if result=0 then memo1.lines.add('ProcessFrameCopy: No') else memo1.lines.add('ProcessFrameCopy: Yes');
glplugin:=false;
result:=integer(PluginHost.GetPluginCaps(4));
if result=FF_FAIL then memo1.lines.add('ProcessOpenGL: Error')
else if result=0 then begin
memo1.lines.add('ProcessOpenGL: No');
end else begin
memo1.lines.add('ProcessOpenGL: Yes');
glplugin:=true;
end;
if glplugin then begin
if ((pc16<>0) or (pc24<>0) or (pc32<>0)) then memo1.lines.add('* WARNING: Plugin SHOULD NOT report 16/24/32bit caps *');
end else begin
if ((pc16=0) and (pc24=0) and (pc32=0)) then memo1.lines.add('* ERROR: Plugin IS NOT reporting 16/24/32bit caps *');
end;
supportstime:=false;
result:=integer(PluginHost.GetPluginCaps(5));
if result=FF_FAIL then memo1.lines.add('Supports SetTime: Error')
else if result=0 then begin
memo1.lines.add('Supports SetTime: No');
lbTime.Visible:=false;
sbTime.Visible:=false;
cbATime.Visible:=false;
sbATime.Visible:=false;
end else begin
memo1.lines.add('Supports SetTime: Yes');
supportstime:=true;
timeAccel:=1.0;
lbTime.Visible:=true;
sbTime.Visible:=true;
sbTime.Position:=0;
cbATime.Checked:=false;
cbATime.Visible:=true;
sbATime.Visible:=true;
end;
result:=integer(PluginHost.GetPluginCaps(10));
if result=FF_FAIL then memo1.lines.add('Min InputFrames: Error')
else memo1.lines.add('Min InputFrames: '+inttostr(result));
result:=integer(PluginHost.GetPluginCaps(11));
if result=FF_FAIL then memo1.lines.add('Max InputFrames: Error')
else memo1.lines.add('Max InputFrames: '+inttostr(result));
result:=integer(PluginHost.GetPluginCaps(15));
if result=FF_FAIL then memo1.lines.add('Optimization: Error')
else begin
case result of
0: memo1.lines.add('Optimization: FF_CAP_PREFER_NONE');
1: memo1.lines.add('Optimization: FF_CAP_PREFER_INPLACE');
2: memo1.lines.add('Optimization: FF_CAP_PREFER_COPY');
3: memo1.lines.add('Optimization: FF_CAP_PREFER_BOTH');
end;
end;
memo1.Lines.Add(' ');
VideoInfoStruct.orientation:=2;
lOrientation.caption:='Upside Down';
memo1.Lines.Add('[ ExtendedInfoStruct ]');
memo1.Lines.Add(' ');
result:=PluginHost.getExtendedInfo;
if result=FF_FAIL then begin
memo1.Lines.Add('ERROR');
end else begin
memo1.lines.add('Plugin Major Version: '+inttostr(PluginHost.PluginExtendedInfoStruct.PluginMajorVersion));
memo1.lines.add('Plugin Minor Version: '+inttostr(PluginHost.PluginExtendedInfoStruct.PluginMinorVersion));
end;
memo1.Lines.Add(' ');
memo1.Lines.Add('[ Parameters ]');
memo1.Lines.Add(' ');
setlength(params,0);
sbParam.Enabled:=false;
NumParams:=PluginHost.GetNumParameters;
if NumParams=FF_FAIL then begin
memo1.Lines.Add('GetNumParameters: ERROR');
NumParams:=0;
exit;
end else begin
memo1.Lines.Add('Num Parameters: '+inttostr(NumParams));
if NumParams>0 then begin
setlength(params,NumParams);
for i:=0 to NumParams-1 do begin
Params[i].name:='Unknown';
Params[i].default:='UnKnown';
Params[i].displayvalue:='Unknown';
Params[i].actualvalue:=0;
Params[i].t:=9999;
end;
names:=0;
try
text:=PluginHost.GetParameterName(0);
except
names:=FF_FAIL;
end;
if names=FF_FAIL then memo1.Lines.Add('GetParameterName: ERROR (might not be global)')
else CollectParamNames;
try
result:=PluginHost.GetParameterType(0);
except
result:=FF_FAIL;
end;
if result=FF_FAIL then memo1.Lines.Add('GetParameterType: ERROR (might not be global)')
else CollectParamTypes;
defaults:=0;
try
PluginHost.GetParameterDefault(0);
except
defaults:=FF_FAIL;
end;
if defaults=FF_FAIL then begin
memo1.Lines.Add('GetParameterDefault: ERROR (might not be global)');
end else CollectParamDefaults;
if ((names=0) or (defaults=0)) then begin
memo1.Lines.Add(' ');
memo1.Lines.Add('Parameter Details discovered before Instantiating');
for i:=0 to NumParams-1 do begin
text:=Params[i].name;
text:=text+' t('+paramTypeString(Params[i].t)+')';
text:=text+' d('+Params[i].default+')';
memo1.Lines.Add(text);
end;
end;
end;
end;
memo1.Lines.Add(' ');
end;
procedure TfmMain.CollectParamNames;
var
i:integer;
text:string;
begin
memo1.Lines.Add('GetParameter Names');
for i:=0 to NumParams-1 do begin
try
text:=PluginHost.GetParameterName(i);
Params[i].name:=text;
except
memo1.Lines.Add('** Exception during GetParameterName **');
Params[i].name:='ERROR';
end;
end;
end;
procedure TfmMain.CollectParamTypes;
var
i:integer;
result:dword;
begin
memo1.Lines.Add('GetParameter Types');
for i:=0 to NumParams-1 do begin
try
result:=PluginHost.GetParameterType(i);
Params[i].t:=result;
except
memo1.Lines.Add('** Exception during GetParameterType **');
Params[i].t:=FF_FAIL;
end;
end;
end;
function TfmMain.paramTypeString(t:dword):string;
begin
result:='Unknown';
case t of
0: result:='Boolean';
1: result:='Event';
2: result:='Red';
3: result:='Green';
4: result:='Blue';
5: result:='XPos';
6: result:='YPos';
10: result:='Stanard';
11: result:='Alpha';
100: result:='Text';
FF_FAIL: result:='ERROR';
end;
end;
procedure TfmMain.CollectParamDefaults;
var
i:integer;
s:single;
begin
memo1.Lines.Add('GetParameter Defaults');
for i:=0 to NumParams-1 do begin
try
if not skipdefaults then begin
s:=PluginHost.GetParameterDefault(i);
Params[i].default:=floattostr(s);
end else begin
Params[i].default:='no default';
end;
except
memo1.Lines.Add('** Exception during GetParameterDefault **');
Params[i].default:='ERROR';
end;
end;
end;
procedure TfmMain.CollectParamValues;
var
i:integer;
s:single;
begin
memo1.Lines.Add('GetParameter Values');
for i:=0 to NumParams-1 do begin
try
s:=PluginHost.GetParameter(i,PluginInstance);
Params[i].actualvalue:=s;
except
memo1.Lines.Add('** Exception during GetParameter '+inttostr(currentparam)+' **');
Params[i].actualvalue:=0;
end;
end;
end;
procedure TfmMain.CollectParamDisplay;
var
i:integer;
text:string;
begin
memo1.Lines.Add('GetParameterDisplay Values');
for i:=0 to NumParams-1 do begin
try
text:=PluginHost.GetParameterDisplay(i,PluginInstance);
Params[i].displayvalue:=text;
except
memo1.Lines.Add('** Exception during GetParameterDisplay '+inttostr(currentparam)+' **');
Params[i].displayvalue:='ERROR';
end;
end;
end;
function TfmMain.initplugin:dword;
var
i:integer;
text:string;
begin
memo1.Lines.Add('[ Initialsing Plugin ]');
memo1.Lines.Add(' ');
result:=PluginHost.InitialisePlugin;
if result=FF_FAIL then begin
memo1.Lines.Add('ERROR');
exit;
end;
memo1.Lines.Add('OK');
memo1.Lines.Add(' ');
collectInfo;
memo1.Lines.Add('[ Instantiating a plugin instance ]');
memo1.Lines.Add(' ');
if not glplugin then begin
try
PluginInstance:=PluginHost.InstantiatePlugin(VideoInfoStruct);
except
end;
if PluginInstance=0 then begin
memo1.Lines.Add('InstantiatePlugin FAILED');
exit;
end;
end else begin
InitGL;
InitTexture(VideoInfoStruct.FrameWidth,VideoInfoStruct.FrameHeight);
GLViewportStruct.X:=0;
GLViewportStruct.Y:=0;
GLViewportStruct.Width:=glPanel.Width;
GLViewportStruct.Height:=glPanel.Height;
try
PluginInstance:=PluginHost.InstantiateGLPlugin(GLViewportStruct);
except
end;
if PluginInstance=0 then begin
memo1.Lines.Add('InstantiateGLPlugin FAILED');
exit;
end;
end;
InstanceReady:=true;
collectParamNames;
collectParamTypes;
collectParamDefaults;
collectParamValues;
CollectParamDisplay;
memo1.Lines.Add(' ');
memo1.Lines.Add('Parameter Details discovered after Instantiating');
for i:=0 to NumParams-1 do begin
text:=Params[i].name;
text:=text+' t('+paramTypeString(Params[i].t)+')';
text:=text+' d('+Params[i].default+')';
memo1.Lines.Add(text);
end;
memo1.Lines.Add(' ');
lbParams.Clear;
if NumParams>0 then begin
currentparam:=0;
for i:=0 to NumParams-1 do begin
lbParams.Items.Strings[i]:=Params[i].name+' = '+floattostr(params[i].actualvalue)+' ('+params[i].displayvalue+')';
end;
sbparam.Position:=round(Params[0].actualvalue*100);
sbparam.Enabled:=true;
lbpname.Caption:=Params[0].name;
lbpvalue.Caption:=floattostr(Params[0].actualvalue);
end;
result:=0;
end;
procedure TfmMain.DeInitPlugin;
var
result:dword;
begin
if not PluginLoaded then exit;
if PluginInstance>0 then begin
try
result:=PluginHost.DeInstantiatePlugin(PluginInstance);
if result=FF_FAIL then memo1.Lines.Add('DeInstantiate Plugin ERROR')
else memo1.Lines.Add('DeInstantiate Plugin OK');
except
memo1.Lines.Add('** Exception during DeInstantiate Plugin');
end;
end;
try
result:=PluginHost.DeInitialisePlugin;
if result=FF_FAIL then memo1.Lines.Add('DeInitalise Plugin ERROR')
else memo1.Lines.Add('DeInitalise Plugin OK');
except
memo1.Lines.Add('** Exception during DeInitalise Plugin');
end;
memo1.Lines.Add('');
end;
procedure TfmMain.DisplayFrame(lpbitmapinfoheader: pbitmapinfoheader; channel: integer);
type
pdw = ^dword;
var
hbmp:thandle;
bits:pdw;
tempBitmap: TBitmap;
begin
AHDC := getdc(fmMain.handle);
try
bits := Pointer(Integer(lpBitmapInfoHeader) + sizeof(TBITMAPINFOHEADER));
hBmp := CreateDIBitmap(ahdc, lpBitmapInfoHeader^, CBM_INIT, pointer(bits), PBITMAPINFO(lpBitmapInfoHeader)^, DIB_RGB_COLORS ); tempBitmap:=TBitmap.create;
try
tempBitmap.Handle:=hBmp;
case channel of
0: with PaintBox1 do Canvas.StretchDraw(rect(0,0,width,height),tempBitmap);
end;
finally
tempBitmap.free;
end;
finally
releaseDC(fmMain.handle,AHDC);
end;
end;
procedure TfmMain.ProfileAndProcessFrame(pFrame: pointer; PluginInstance: dword); var
before: integer;
pFrameToProcess: pointer;
result:dword;
begin
pFrameToProcess:=pFrame;
if VideoInfoStruct.BitDepth=2 then begin
Utils.Convert24to32(pFrameToProcess, p32bitFrame, VideoInfoStruct);
pFrameToProcess:=p32bitFrame;
end;
before:=gettickcount;
result:=0;
try
PluginHost.ProcessFrame(pFrameToProcess, PluginInstance); except
memo1.Lines.Add('Exception during ProcessFrame');
result:=FF_FAIL;
end;
if result=FF_FAIL then begin
memo1.Lines.Add('ProcessFrame FAILED');
if tPlay.Enabled then tplay.Enabled:=false;
end;
lProfile.Caption:=inttostr(gettickcount-before)+' msec/frame';
if VideoInfoStruct.BitDepth=2 then Utils.Convert32to24(p32bitFrame, pFrame, VideoInfoStruct);
end;
procedure TfmMain.ProfileAndProcessGLFrame(pFrame: pointer; PluginInstance: dword);
var
before: integer;
pFrameToProcess: pointer;
ProcessOpenGLStruct:TProcessOpenGLStruct;
inputTex1:TPluginGLTextureStruct;
inputTexs:array[0..1] of pointer;
result:dword;
begin
pFrameToProcess:=pFrame;
UploadFrame(pFrameToProcess,VideoInfoStruct.FrameWidth,VideoInfoStruct.FrameHeight);
inputTex1.Width:=tpot; inputTex1.Height:=tpot; inputTex1.HardwareWidth:=tpot;
inputTex1.HardwareHeight:=tpot;
if test32bit then begin
inputTex1.Handle:=tex32bit;
end else begin
inputTex1.Handle:=tex24bit;
end;
inputTexs[0]:=@inputTex1;
ProcessOpenGLStruct.numInputTextures:=1;
ProcessOpenGLStruct.ppInputTextures:=dword(@inputTexs);
ProcessOpenGLStruct.HostFBO:=0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
before:=gettickcount;
try
result:=PluginHost.ProcessOpenGL(@ProcessOpenGLStruct, PluginInstance);
except
memo1.Lines.Add('Exception during ProcessOpenGL');
result:=FF_FAIL;
end;
if result=FF_FAIL then begin
memo1.Lines.Add('ProcessOpenGL FAILED');
if tPlay.Enabled then tplay.Enabled:=false;
end;
lProfile.Caption:=inttostr(gettickcount-before)+' msec/frame';
end;
procedure TfmMain.tPlayTimer(Sender: TObject);
begin
if not AVI.AVIopen[0] then exit;
if not PluginLoaded then exit;
if not InstanceReady then exit;
Process;
end;
procedure TfmMain.Process;
var
pFrameToProcess, pBits: pointer;
now:double;
result:dword;
begin
if InstanceReady then begin
if supportstime then begin
if cbATime.Checked then begin
now:=sbATime.Position/1000;
end else begin
absoluteTime:=absoluteTime+(40*timeAccel); now:=absoluteTime/1000;
end;
try
result:=PluginHost.SetTime(now, PluginInstance);
except
memo1.Lines.Add('Exception during SetTime');
bStop.Click;
exit;
end;
end;
inc(currentFrame[0]);
if currentFrame[0]>(numFrames[0]-1) then currentFrame[0]:=1;
case plugininfostruct.PluginType of
0: begin lpbitmapinfoheader:=AVI.GetFrame(currentFrame[0],0);
pBits:=Pointer(Integer(lpBitmapInfoHeader) + sizeof(TBITMAPINFOHEADER));
pFrameToProcess:=pBits;
end;
1: begin pBits:=Pointer(Integer(lpBitmapInfoHeader) + sizeof(TBITMAPINFOHEADER));
pFrameToProcess:=pBits;
end;
end;
if not glplugin then begin
if cbPluginProcessFrames.Checked then ProfileAndProcessFrame(pFrameToProcess, PluginInstance);
end else begin
RefreshGLDisplay;
ProfileAndProcessGLFrame(pFrameToProcess,PluginInstance);
SwapBuffers(DC);
end;
DisplayFrame(lpbitmapinfoheader,0);
end;
end;
function TfmMain.setupPixelFormat(DC:HDC):boolean;
const
pfd:TPIXELFORMATDESCRIPTOR = (
nSize:sizeof(TPIXELFORMATDESCRIPTOR); nVersion:1; dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or
PFD_DOUBLEBUFFER; iPixelType:PFD_TYPE_RGBA; cColorBits:24; cRedBits:0; cRedShift:0; cGreenBits:0; cGreenShift:0;
cBlueBits:0; cBlueShift:0;
cAlphaBits:8; cAlphaShift:0; cAccumBits: 0;
cAccumRedBits: 0; cAccumGreenBits: 0; cAccumBlueBits: 0;
cAccumAlphaBits: 0;
cDepthBits:24; cStencilBits:0; cAuxBuffers:0; iLayerType:PFD_MAIN_PLANE; bReserved: 0;
dwLayerMask: 0;
dwVisibleMask: 0;
dwDamageMask: 0; );
var pixelFormat:integer;
begin
result:=false;
pixelFormat := ChoosePixelFormat(DC, @pfd);
if (pixelFormat = 0) then exit;
if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then exit;
result:=true;
end;
procedure TfmMain.InitGL;
var
bmp:TBitmap;
mem,dst:pointer;
y:integer;
begin
DC:=GetDC(glPanel.Handle); if not SetupPixelFormat(DC) then begin showmessage('FAILED to create openGL surface');exit;end;
RC:=wglCreateContext(DC); WglMakeCurrent(DC, RC);
glViewport(0,0,glPanel.Width,glPanel.Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(65,glPanel.Width/glPanel.Height,1.0,-1.0);
glReadBuffer(GL_BACK);
glClearColor(0,0,0,0);
if fileexists(exepath+'checks.bmp') then begin
bmp:=TBitmap.Create;
try
bmp.LoadFromFile(exepath+'checks.bmp');
getmem(mem,32*32*3);
dst:=mem;
for y:=0 to 31 do begin
copymemory(dst,bmp.ScanLine[y],32*3);
dst:=pointer(integer(dst)+(32*3));
end;
glGenTextures(1,@checks);
glBindTexture(GL_TEXTURE_2D,checks);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, 32,32, GL_BGR_EXT, GL_UNSIGNED_BYTE, mem);
finally
bmp.Free;
end;
end;
glinit:=true;
end;
procedure TfmMain.InitTexture(w,h:integer);
begin
glDeleteTextures(1,@tex24bit);
glDeleteTextures(1,@tex32bit);
tpot:=32; if w>h then begin
while h>(tpot*2) do tpot:=tpot*2;
end else begin
while w>(tpot*2) do tpot:=tpot*2;
end;
if assigned(framestore) then freemem(framestore);
getmem(framestore,tpot*tpot*4);
glGenTextures(1,@tex24bit);
glBindTexture(GL_TEXTURE_2D,tex24bit);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, tpot, tpot, GL_BGR_EXT, GL_UNSIGNED_BYTE, framestore);
glGenTextures(1,@tex32bit);
glBindTexture(GL_TEXTURE_2D,tex32bit);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tpot, tpot, GL_BGRA_EXT, GL_UNSIGNED_BYTE, framestore);
end;
procedure TfmMain.UploadFrame(bits:pointer;w,h:integer);
var
src,dst:pointer;
x,y:integer;
r,g,b,a:byte;
begin
if not test32bit then begin
dst:=framestore;
for y:=0 to tpot-1 do begin
src:=pointer(integer(bits)+((w*3)*y));
copymemory(dst,src,tpot*3);
dst:=pointer(integer(dst)+tpot*3);
end;
glBindTexture(GL_TEXTURE_2D, tex24bit);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,tpot,tpot,GL_BGR_EXT,GL_UNSIGNED_BYTE,framestore);
end else begin
dst:=framestore;
for y:=0 to tpot-1 do begin
src:=pointer(integer(bits)+((w*3)*y));
for x:=0 to tpot-1 do begin
r:=byte(src^);src:=pointer(integer(src)+1);
g:=byte(src^);src:=pointer(integer(src)+1);
b:=byte(src^);src:=pointer(integer(src)+1);
if (x mod 16)<8 then a:=255 else a:=0;
integer(dst^):=(a shl 24)+(b shl 16)+(g shl 8)+(r);
dst:=pointer(integer(dst)+4);
end;
end;
glBindTexture(GL_TEXTURE_2D, tex32bit);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,tpot,tpot,GL_BGRA_EXT,GL_UNSIGNED_BYTE,framestore);
end;
end;
procedure TfmMain.RefreshGLDisplay;
begin
inc(checksangle);if checksangle=360 then checksangle:=0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glMatrixMode(GL_TEXTURE);
glLoadIdentity;
glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glColor4f(1,1,1,1);
if ((checks>0) and (checksenabled)) then begin
glTranslatef(0.5,0.5,0.0);
glRotatef(checksangle,0,0,1);
glTranslatef(-0.5,-0.5,0.0);
glBindTexture(GL_TEXTURE_2D,checks);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex2f(-1,-1);
glTexCoord2f(1,0); glVertex2f(1,-1);
glTexCoord2f(1,1); glVertex2f(1,1);
glTexCoord2f(0,1); glVertex2f(-1,1);
glEnd();
glDisable(GL_TEXTURE_2D);
glLoadIdentity;
end else begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
end;
end;
procedure TfmMain.cbPluginsChange(Sender: TObject); begin
LoadPlugin;
end;
procedure TfmMain.bBrowseClick(Sender: TObject);
var
inifile: TInifile;
begin
tPlay.Enabled:=false;
if odAVI.Execute then begin
ebAVIfilename.text:=odAVI.FileName;
inifile:=Tinifile.Create(exepath+'FreeFrame.ini');
inifile.WriteString('Filenames','CurrentAVI',odAVI.filename);
inifile.Free;
loadAVI;
LoadPlugin;
end;
end;
procedure TfmMain.bProcessFrameClick(Sender: TObject);
begin
Process;
end;
procedure TfmMain.bPlayAndProcessClick(Sender: TObject);
begin
if not AVI.AVIopen[0] then exit;
if not PluginLoaded then exit;
if not InstanceReady then exit;
currentFrame[0]:=0;
absoluteTime:=0;
tPlay.Enabled:=true;
end;
procedure TfmMain.sbParamChange(Sender: TObject);
var
s: single;
text:string;
begin
if PluginInstance>0 then begin
if currentparam=-1 then exit;
s:=sbParam.position/100;
try
PluginHost.SetParameter(currentparam,s,PluginInstance);
params[currentparam].actualvalue:=s;
except
memo1.Lines.Add('Exception during SetParameter '+inttostr(currentparam)+' ('+floattostr(s)+')');
end;
try
text:=GetParameterDisplay(currentparam,PluginInstance);
params[currentparam].displayvalue:=text;
except
memo1.Lines.Add('Exception during GetParameterDisplay '+inttostr(currentparam));
end;
if verifyParam then begin
try
s:=pluginHost.GetParameter(currentparam,PluginInstance);
if params[currentparam].actualvalue<>s then memo1.Lines.Add('get value '+floattostr(s)+' is NOT value set '+floattostr(params[currentparam].actualvalue));
except
memo1.Lines.Add('Exception during GetParameter '+inttostr(currentparam));
end;
end;
lbParams.Items.Strings[currentparam]:=Params[currentparam].name+' = '+floattostr(params[currentparam].actualvalue)+' ('+params[currentparam].displayvalue+')';
lbpvalue.Caption:=floattostr(Params[currentparam].actualvalue)+' ('+Params[currentparam].displayvalue+')';
end;
end;
procedure TfmMain.bStopClick(Sender: TObject);
begin
tPlay.Enabled:=false;
end;
procedure TfmMain.ebAVIFilenameChange(Sender: TObject);
begin
AVI.AVIfilename:=ebAVIfilename.Text;
end;
procedure TfmMain.lbParamsClick(Sender: TObject);
begin
if ((lbParams.ItemIndex>-1) and (lbParams.ItemIndex<NumParams)) then begin
currentparam:=lbParams.ItemIndex;
lbpname.Caption:=Params[currentparam].name;
lbpvalue.Caption:=floattostr(Params[currentparam].actualvalue)+' ('+Params[currentparam].displayvalue+')';
sbparam.Enabled:=false;
sbparam.Position:=round(Params[currentparam].actualvalue*100);
sbparam.Enabled:=true;
end;
end;
procedure TfmMain.cbVerifyClick(Sender: TObject);
begin
verifyParam:=cbVerify.checked;
end;
procedure TfmMain.cbTest32BitClick(Sender: TObject);
begin
test32bit:=cbTest32Bit.checked;
end;
procedure TfmMain.cbCheckersClick(Sender: TObject);
begin
checksenabled:=cbCheckers.Checked;
end;
procedure TfmMain.btnGrabFrameClick(Sender: TObject);
var
x,y:integer;
c:integer;
src:pointer;
wasplaying:boolean;
r,g,b,a:integer;
begin
wasplaying:=tplay.Enabled;
if tplay.Enabled then tplay.Enabled:=false;
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0,glpanel.Width,0,glpanel.Height,1.0,-1.0);
glReadPixels(0,0,glpanel.Width,glpanel.Height,GL_RGBA,GL_UNSIGNED_BYTE,framedump.Memory);
for y:=0 to glpanel.Height-1 do begin
src:=pointer(integer(framedump.Memory)+((glpanel.width*4)*y));
for x:=0 to glpanel.Width-1 do begin
c:=integer(src^);
a:=(c and $ff000000);
b:=(c and $ff0000);
g:=(c and $ff00);
r:=(c and $ff);
c:=r+g+b;
pbRGB.Canvas.Pixels[x,glpanel.Height-y]:=c;
pbAlpha.Canvas.Pixels[x,glpanel.Height-y]:=(a shr 8)+(a shr 16)+(a shr 24);
src:=pointer(integer(src)+4);
end;
end;
tplay.Enabled:=wasplaying;
end;
procedure TfmMain.btnReloadClick(Sender: TObject);
begin
deinitplugin;
loadplugin;
end;
procedure TfmMain.bDeInitPluginClick(Sender: TObject);
begin
deinitplugin;
PluginLoaded:=false;
end;
procedure TfmMain.sbTimeChange(Sender: TObject);
begin
if sbTime.Position>=0 then begin
timeAccel:=1+(sbTime.Position*0.1);
lbTime.Caption:='Time Acceleration ('+FloatToStrF(timeAccel,ffFixed,7,2)+')';
end else begin
timeAccel:=1+(sbTime.Position*0.01);
lbTime.Caption:='Time Acceleration ('+FloatToStrF(timeAccel,ffFixed,7,2)+')';
end;
end;
end.