View Full Version : How can I parse avs script name to avisynth.dll
Prodater64
13th August 2005, 07:44
I trying to obtain framecount, fps, width, height, etc. linking avisynth.dll from VB6 or WIL but I can't figure out how to parse avs script name to the dll.
doom9 point me in this way in http://forum.doom9.org/showthread.php?p=697970#post697970 but I couldnt find out what I am searching (all night indeed)
Thanks.
Zeul
13th August 2005, 09:19
Private Const OF_SHARE_DENY_WRITE As Long = &H20
Private Type AviFileInfo
dwMaxBytesPerSec As Long
dwFlags As Long
dwCaps As Long
dwStreams As Long
dwSuggestedBufferSize As Long
dwWidth As Long
dwHeight As Long
dwScale As Long
dwRate As Long
dwLength As Long
dwEditCount As Long
szFileType As String * 64
End Type
Private Type SHITEMID
Cb As Long
abID As Byte
End Type
Private Type ITEMIDLIST
mkid As SHITEMID
End Type
Private Declare Function AVIFileOpen Lib "avifil32" Alias "AVIFileOpenA" (ppfile As Long, ByVal szFile As String, ByVal Mode As Long, pclsidHandler As Any) As Long
Private Declare Function AVIFileRelease Lib "avifil32" (ByVal pfile As Long) As Long
Private Declare Function AviFileInfo Lib "avifil32" Alias "AVIFileInfoA" (ByVal pfile As Long, pfi As AviFileInfo, ByVal lSize As Long) As Long
Private Declare Sub AVIFileInit Lib "avifil32" ()
Private Declare Sub AVIFileExit Lib "avifil32" ()
Function OpenAviFile(AVSScript As String) As Long
Dim hFile As Long, AviInfo As AviFileInfo
AVIFileInit
If AVIFileOpen(hFile, AVSScript, OF_SHARE_DENY_WRITE, ByVal 0&) = 0 Then
If AviFileInfo(hFile, AviInfo, Len(AviInfo)) = 0 Then
' here you would put get the info for example
fps = (AviInfo.dwRate / AviInfo.dwScale) * 1000
framecount = AviInfo.dwLength
height = AviInfor.dwHeight
End If
AVIFileRelease hFile
End If
AVIFileExit
End Function
Doom9
13th August 2005, 11:52
actually, he meant getting that info from a d2v or I misread the question. The above is using AVIFile (which is a good way to use to get that info from an AviSynth script.. but you need a compatible VfW decoder installed for it to work.. Helix YV12, XviD with YV12 or DivX with YV12 support come to mind.. without those this whole thing will be a nogo).
By the way, you'll find a lot of useful code for handling d2vs in Gordian Knot. I know it's not your language, it's not mine either, but I learned a lot from it nontheless. You can also look in the MeGUI sources (once again not your language, but that really shouldn't stop anyone.. it gives you a lot of good starting points) for dealing with AviSynth scripts and D2V scripts (including getting bitmaps.. unlike many open source projects I comment my code..)
Prodater64
13th August 2005, 13:47
@Zeul: Thanks. Must I put some of the code in a module?
@Doom9: Thanks you also, but I just wanted that Zeul post. Anyway I'll take a look to that you pointed me.
When you said me (in another thread) that I must to take a look to avisynth.h I thought than I could call avisynth.dll straight from my code and not using avifil32. I was indeed taking a look to this last dll, but I didnt know its functions. (I have not high skills in programming)
Thanks you both again.
Prodater64
13th August 2005, 15:24
Neither
Private Sub Form_Load()
OpenAviFile (Chr(34) + "E:\DVD Authoring Working Folder\Pitch Black\Pitch Black.avs" + Chr(34))
Text1.Text = framecount
End Sub
nor
Private Sub Form_Load()
OpenAviFile ("E:\DVD Authoring Working Folder\Pitch Black\Pitch Black.avs")
Text1.Text = framecount
End Sub
shows framecount in text1.
Inc
13th August 2005, 18:57
When you said me (in another thread) that I must to take a look to avisynth.h I thought than I could call avisynth.dll straight from my code
Doom9 refered only to the VideoInfo Structure and its ordering of Longs.
The same order is used when calling Mpeg2Source().
Its a simple structure, means a given byte order at a given memory adress point. Parsing Values out of avisynth most comfortable is given via AviFileInfo().
Open The stream, load the AVIFILEINFO structure values via AviFileInfo into the *memorypointer.AVIFILEINFO where you can parse out the structure AVIFILEINFO Easely.
a vfw decoder has to be installed in the system anyway as IMHO avisynths Avisource() for example also uses vfw for decoding for example.
Also you could have a look at Aquaplaning's sources, he created an avisynth.dll wrappercalled avswarp.dll. Delphi Sources for calling that avswarp.dll are included. avswarp.dll is coded in c++ as if you want to access avisynth.dll you have to have a proper translated avisynth.h header file in YOUR progr.environment language.
Other way is the usage of mediainfo.dll in VB to get the needed avs file based output info.
And finally if its just the framecount you want, you can parse that using MCISendstring commands.
Prodater64
13th August 2005, 19:40
Other way is the usage of mediainfo.dll in VB to get the needed avs file based output info.
As I know mediainfo.dll dont manage avs files at the moment. Im following its thread and waiting developer do it (I think it will be soon).
The previous VB6 code is ok, it don't give me any error when testing in the IDE, but I cant get the values I want, showed in a text box with test purposes. (not only framecount, but all possible useful info)
Could you explain me further MCISendstring command?
Prodater64
13th August 2005, 21:27
VB6 posted code doesn't work but I have find out this similar one that yes do it.
Private Const OF_SHARE_DENY_WRITE As Long = &H20
Private Type AVIFILEINFO
dwMaxBytesPerSec As Long
dwFlags As Long
dwCaps As Long
dwStreams As Long
dwSuggestedBufferSize As Long
dwWidth As Long
dwHeight As Long
dwScale As Long
dwRate As Long
dwLength As Long
dwEditCount As Long
szFileType As String * 64
End Type
Private Declare Function AVIFileOpen Lib "avifil32" Alias "AVIFileOpenA" (ppfile As Long, ByVal szFile As String, ByVal mode As Long, pclsidHandler As Any) As Long
Private Declare Function AVIFileRelease Lib "avifil32" (ByVal pfile As Long) As Long
Private Declare Function AVIFileInfo Lib "avifil32" Alias "AVIFileInfoA" (ByVal pfile As Long, pfi As AVIFILEINFO, ByVal lSize As Long) As Long
Private Declare Sub AVIFileInit Lib "avifil32" ()
Private Declare Sub AVIFileExit Lib "avifil32" ()
Private Sub Form_Load()
'KPD-Team 2001
'URL: http://www.allapi.net/
'E-Mail: KPDTeam@Allapi.net
Dim hFile As Long, AviInfo As AVIFILEINFO
'initialize the AVIFile library
AVIFileInit
'create a handle to the AVI file
If AVIFileOpen(hFile, "C:\SIERRA\Half-Life\valve\media\sierra.avi", OF_SHARE_DENY_WRITE, ByVal 0&) = 0 Then
'retrieve the AVI information
If AVIFileInfo(hFile, AviInfo, Len(AviInfo)) = 0 Then
MsgBox "AVI dimensions: " + CStr(AviInfo.dwWidth) + "x" + CStr(AviInfo.dwHeight)
Else
MsgBox "Error while retrieving AVI information... :("
End If
'release the file handle
AVIFileRelease hFile
Else
MsgBox "Error while opening the AVI file... :("
End If
'exit the AVIFile library and decrement the reference count for the library
AVIFileExit
End Sub
Inc
13th August 2005, 22:30
Im not that in VB but you call AviFileInfo() right behind the AviFileOpen() call.
You have to determine the stream to handle after opening the file via AviFileGetStream(). Then AviFileInfo() knows which Values to parse.
Heres a Purebasic Codexample, very easy to port to VB.:
First we do determine the AVIFILEINFO Structure:
Structure AVIFILEINFO
dwMaxBytesPerSec.l
dwFlags.l
dwCaps.l
dwStreams.l
dwSuggestedBufferSize.l
dwWidth.l
dwHeight.l
dwScale.l
dwRate.l
dwLength.l
dwEditCount.l
szFileType.b[64]
EndStructure
If you also want to parse out the fccHandler (like 'XVID' or in case of Avisynth input the Clorspace like 'YUY2'), the you also have to build a shrinked AVISTREAMINFO Structure:
Structure fourcc
a.b
b.b
c.b
d.b
EndStructure
Structure AVISTREAMINFO
fccTypea.l
fccHandler.fourcc ; Use the 4 Bytes from the Structure fourcc as seen above
EndStructure
Now the API calling incl. showing parsed values at the end via debugger:
avifile.s = "D:\My_avs_File.avs"
AVIFileInit()
AVIFileOpen (pAVIFile, avifile.s, #OF_SHARE_DENY_WRITE, 0 )
AVIFileGetStream (pAVIFile, *pAVIStream, #streamtypeVIDEO, 0 )
firstFrame.l = AVIStreamStart (pAVIStream )
numFrames.l = AVIStreamLength (pAVIStream )
AVIFileInfo (pAVIFile, *AVIFILEINFO1.AVIFILEINFO, SizeOf(AVIFILEINFO)) ; getting the data from AVIFILEINFO the the pointer *AVIFILEINFO1
AVIStreamInfo (pAVIStream, *AVISTREAMINFO1.AVISTREAMINFO, SizeOf(AVISTREAMINFO)) ; Getting AVISTREAMINFO Values
AVIFileRelease(pAVIFile )
AVIFileExit( )
;--------------- Here the debugging (use something similair in VB
Debug "Stream starts at:"+Str(firstFrame)
Debug "Stream gots:"+Str(numFrames)+" Frames"
Debug " "
Debug " "
Debug "AviFileInfo:"
Debug " "
Debug "dwMaxBytesPerSec="+Str(AVIFILEINFO1\dwMaxBytesPerSec)
Debug "dwFlags="+Str(AVIFILEINFO1\dwFlags)
Debug "dwCaps="+Str(AVIFILEINFO1\dwCaps)
Debug "dwStreams="+Str(AVIFILEINFO1\dwStreams)
Debug "dwSuggestedBufferSize ="+Str(AVIFILEINFO1\dwSuggestedBufferSize)
Debug "dwWidth="+Str(AVIFILEINFO1\dwWidth)
Debug "dwHeight="+Str(AVIFILEINFO1\dwHeight)
Debug "dwScale="+Str(AVIFILEINFO1\dwScale)
Debug "dwRate="+Str(AVIFILEINFO1\dwRate)
Debug "dwLength="+Str(AVIFILEINFO1\dwLength)
Debug "dwEditCount="+Str(AVIFILEINFO1\dwEditCount)
Debug " "
Debug " "
Debug "AviStreamInfo:"
Debug " "
fcct.s="Streamtype Unknown"
If AVISTREAMINFO1\fccTypea = #streamtypeVIDEO : fcct.s="Streamtype VIDEO"
EndIf
If AVISTREAMINFO1\fccTypea = #streamtypeAUDIO : fcct.s="Streamtype Audio"
EndIf
Debug "fccType="+fcct.s
Debug "fccHandler="+UCase(Chr(AVISTREAMINFO1\fccHandler\a)+Chr(AVISTREAMINFO1\fccHandler\b)+Chr(AVISTREAMINFO1\fccHandler\c)+Chr(AVISTREAMINFO1\fccHandler\d))
Zeul
13th August 2005, 22:51
The code i posted does work, but framecount, fps, height must be public dimmed in the module header to use it. I put them there as an example.
ie
Public FrameCount as long
public FPS as double
public Height as integer
also you do not need to pass the chr$(34)
use like
openavifile "c:\test.avs"
obviously my function was an example and so the return type could be anything. As you know public vars are not good programming practice.
Prodater64
13th August 2005, 23:03
The code i posted does work, but framecount, fps, height must be public dimmed in the module header to use it. I put them there as an example.
ie
Public FrameCount as long
public FPS as double
public Height as integer
also you do not need to pass the chr$(34)
use like
openavifile "c:\test.avs"
obviously my function was an example and so the return type could be anything. As you know public vars are not good programming practice.
Thanks.
Prodater64
18th August 2005, 05:27
@Zeul: What does it mean in your code?
Private Type ITEMIDLIST
mkid As SHITEMID
End Type
Zeul
18th August 2005, 12:58
oops
should have left those out. that is part of s def type that is used elsewhere in my module - it has no bearing on avs.
Private Type SHITEMID
Cb As Long
abID As Byte
End Type
Private Type ITEMIDLIST
mkid As SHITEMID
End Type
remove both these types
Prodater64
18th August 2005, 18:02
oops
should have left those out. that is part of s def type that is used elsewhere in my module - it has no bearing on avs.
Private Type SHITEMID
Cb As Long
abID As Byte
End Type
Private Type ITEMIDLIST
mkid As SHITEMID
End Type
remove both these types
Thanks.
vBulletin® v3.8.4, Copyright ©2000-2009, Jelsoft Enterprises Ltd.