Log in

View Full Version : Aquaplaning's Vidframe.dll and VB6


NiTroGen
23rd March 2003, 02:46
I've tried to use Aquaplaning's vidframe.dll with Visual Basic 6, but I couldn't do it. Vidframe.dll (which can be found here (http://aquaplaning.20m.com)) is a dll created for Delphi to view, resize and crop frames from any direct show source. Here is the Delphi unit which uses the dll to access video frames:
unit vidframe;

interface

uses SysUtils, Graphics;

type
float = Double;

TMyColor = record
case Integer of
0: (c: TColor);
1: (r, g, b, x: byte);
2: (l: LongInt);
end;

TVideoInfo = record
width, height, // width=0 means no video
fps_numerator, fps_denominator, num_frames: integer;
pixel_type: word; // UNKNOWN=0, YUY2=2, BGR24=3 }
audio_samples_per_second, // 0 means no audio
num_audio_samples: integer;
stereo, sixteen_bit, field_based: boolean;
end;
PVideoInfo = ^TVideoInfo;

var videoInfo: PVideoInfo;
frameBM: TBitMap;
isVideoOpen: boolean;

// capsulated functions for delphi, recommended for use
procedure openDirectShow(name: String);
procedure openAVI(name: String);
procedure closeVideo;
procedure getFrame(frame: integer);
function getWidth: integer;
function getHeight: integer;
function getFrameCount: integer;
function getFPS: float;

// direct access to DLL function's
function openDirectShowDll(name: PChar): PVideoInfo; cdecl;
function openAVIDll(name: PChar): PVideoInfo; cdecl;
procedure closeVideoDll; cdecl;
function getFrameDll(frame: integer): PByteArray; cdecl;
function getWidthDLL: integer; cdecl;
function getHeightDLL: integer; cdecl;
function getFramecountDLL: integer; cdecl;

implementation

function openDirectShowDll(name: PChar): PVideoInfo; cdecl; external 'vidframe.dll' name '?openDirectShow@@YAPAUVideoInfo@@PAD@Z';
function openAVIDll(name: PChar): PVideoInfo; cdecl; external 'vidframe.dll' name '?openAVI@@YAPAUVideoInfo@@PAD@Z';
procedure closeVideoDll; cdecl; external 'vidframe.dll' name '?closeVideo@@YAXXZ';
function getFrameDll(frame: integer): PByteArray; cdecl; external 'vidframe.dll' name '?getFrame@@YAPAEH@Z';
function getWidthDLL: integer; cdecl; external 'vidframe.dll' name '?getWidth@@YAHXZ';
function getHeightDLL: integer; cdecl; external 'vidframe.dll' name '?getHeight@@YAHXZ';
function getFramecountDLL: integer; cdecl; external 'vidframe.dll' name '?getFramecount@@YAHXZ';

procedure initFrameBM;
begin
if frameBM <> nil then frameBM.Destroy;
frameBM := TBitMap.Create;
frameBM.Width := videoinfo.width;
frameBM.Height := videoinfo.height;
frameBM.PixelFormat := pf24bit;
isVideoOpen := True;
end;

procedure openDirectShow(name: String);
begin
videoinfo := openDirectShowDll( PChar(name) );
initFrameBM;
end;

procedure openAVI(name: String);
begin
videoinfo := openDirectShowDll( PChar(name) );
initFrameBM;
end;

procedure closeVideo;
begin
if frameBM <> nil then
begin
frameBM.Destroy;
frameBM := nil;
end;
videoinfo := nil;
if isVideoOpen then
begin
closeVideoDll;
isVideoOpen := False;
end;
end;

procedure getFrame(frame: integer);
var p, sl: PByteArray;
y: integer;
begin
p := getFrameDLL(frame);
for y := 0 to videoinfo.height-1 do
begin
sl := frameBM.ScanLine[videoinfo.height - y - 1];
move(p[y * videoinfo.width * 3], sl[0], videoinfo.width * 3);
end;
end;

function getWidth: integer;
begin
if videoinfo = nil then
getWidth := 0
else
getWidth := videoinfo.width;
end;

function getHeight: integer;
begin
if videoinfo = nil then
getHeight := 0
else
getHeight := videoinfo.height;
end;

function getFrameCount: integer;
begin
if videoinfo = nil then
getFrameCount := 0
else
getFrameCount := videoinfo.num_frames;
end;

function getFPS: float;
begin
if videoinfo = nil then
getFPS := 0.0
else
getFPS := videoinfo.fps_numerator / videoinfo.fps_denominator;
end;

begin
isVideoOpen := False;
videoinfo := nil;
frameBM := nil;
end.

Can anyone help me to translate these routines (especially the ones that access the dll) to Visual Basic? I've tried that, but my knowledge on VB and Delphi is still limited. Thanks in advance.

PS. On Aquaplaning's web page (http://aquaplaning.20m.com), you can find an example code on how to use this Delphi unit, in this file (http://aquaplaning.20m.com/vidframe_sources.zip).

vhelp
23rd March 2003, 22:44
hi NiTroGen,

I've worked in VB, and importing DLL's within them too, but my choise
is Delphi. Anyways..

I've create some minor DLL's in delphi and made got them working
in c++ builder and VBA (didn't have VB, but had MS Access) and
was able to use Delphi created DLL's in both languages.

Once you've properly called the Library in your VB environment,
you should have no trouble w/ accessing the functions in the DLL.

One of the most issues, is the parameter type calling for EAch
function. If no-one else has any suggestions at this time, I would
suggest that you start w/ one function, and see if your VB will
compile it successfully. Don't always go by the finished compile
though. Actually RUN the app. If you get by w/ no errors, then you
know you are in the ball-park.

That's all I have for now. I'm taking a look at this source now, as
I write this, but I have many other things going on, and plus other
duties around the house.

Good luck.
-vhelp

vhelp
24th March 2003, 02:35
hi NiTroGen,

I seem to have no trouble w/ using the source code as-is in Delphi 6, so that make
me a bit happy.

I took another look at the app I created as an excercise (at kvcd) as I did
lots of experiments with DLL'ing around.

As for the test sample that I compiled.. will open an AVI file and play it
but w/ reduced color ie, output looks like a solor-flare, and seems to
be using the wrong color-space, but another thing I noticed was that the
video flickered. I quickly fixed this in the source and NOW the video is
snooth and flickerless :)
But, it does not open/play divX. ..probably a straight AVI reader only.
I suspect that you will have this color issue as well, once you get this DLL
to work under VB 6, so do bare that in mind, unless a fix is made.

As far as VB goes, (based on my VBA experience [ms access vba]) ..

[Public | Private] Declare Sub name Lib "libname" [Alias "aliasname"] [([arglist])]

Alias
Optional. Indicates that the procedure being called has another name
in the DLL. This is useful when the external procedure name is the
same as a keyword. You can also use Alias when a DLL procedure has
the same name as a public variable, constant, or any other procedure
in the same scope. Alias is also useful if any characters in the DLL
procedure name aren't allowed by the DLL naming convention.

Below is an excert of a piece of code from my Excercise DLL app that I used
in a VBA code. The snip was used in the Module area, while the actual
calling of the function vMax() was in the main body of the code:

Public Declare Function vMax Lib "d:\vmath.dll" (ByVal x As Integer, ByVal y As Integer) As Integer


perhaps the above needs to be observed. I noticed a few odd "naming " going on.
So, you might want to try addint Alias "filename " to your Lib
syntax.

Good luck so far.
-vhelp

NiTroGen
26th March 2003, 05:34
Thanks a lot for your answer, vhelp, but I still can't do it. :( This is the code I've used:
Private Type TVideoInfo
width As Integer ' width=0 means no video
height As Integer
fps_numerator As Integer
fps_denominator As Integer
num_frames As Integer
pixel_type As Integer ' UNKNOWN=0, YUY2=2, BGR24=3 }
audio_samples_per_second As Integer ' 0 means no audio
num_audio_samples As Integer
stereo As Boolean
sixteen_bit As Boolean
field_based As Boolean
End Type

Private Declare Function openDirectShowDll Lib "vidframe.dll" Alias "?openDirectShow@@YAPAUVideoInfo@@PAD@Z" (name As String) As TVideoInfo
Private Declare Function openAVIDll Lib "vidframe.dll" Alias "?openAVI@@YAPAUVideoInfo@@PAD@Z" (ByVal name As String) As TVideoInfo
Private Declare Sub closeVideoDll Lib "vidframe.dll" Alias "?closeVideo@@YAXXZ" ()

Dim T As TVideoInfo

Private Sub Form_Load()
On Local Error GoTo ErrLine:
T = openAVIDll("C:\test.avi")
closeVideoDll
Exit Sub

ErrLine:
Call MsgBox("Error " + Str$(Err.Number) + ": " + Err.Description + " occured.", vbCritical + vbOKOnly, "Error")
Err.Clear
Resume Next
Exit Sub
End Sub

This code always crushes the VB IDE as well as the executable. I think the problem is that openAVIDll returns a pointer to TVideoInfo (PVideoInfo = ^TVideoInfo), but I don't know how to use pointers with Visual Basic. :( Any idea on how to do it?

PS. If I just call "closeVideoDll" without "openAVIDll" there is no error, so I think the external function declarations are OK.