Page 1 of 2

(AVIFIL32) new question (see newest post)

Posted: Sun Jan 23, 2011 12:10 am
by Zach
I have tried and tried to write the code correctly but I guess I just don't understand how to interact with this library.

I've consulted the MSDN, API-Guide, guides in other languages that I've tried to mirror... My first problem was getting it to recognize the required szFile parameter, which is supposed to be a null terminated string containing the path to the file.... It wouldn't compile unless I gave it a pointer (I think I did it right?), because it only accepts numbers and not string input (how retarded???)

So now the code will compile but it gives me an error "Invalid memory access (write error at address 0)"... I have never used pointers so maybe I am doing something wrong.. If anyone could write an example application that opens a file and tells you it did so successfully, I would appreciate it.

For what its worth, here is my horribly n00bish attempt at code .
There is some commented out code and other unused stuff atm because I was just building a quick and dirty GUI with the Visual Designer.. the plan was to have it run the AVI_Open procedure after the window was closed, and then echo a debug output (stupid way to build a trigger I know), just to see if I could get it to run and close without complaining at all.

Code: Select all

; PureBasic Visual Designer v3.95 build 1485 (PB4Code)


;- Window Constants
;
Enumeration
  #Window_0
  #Lib
EndEnumeration

;- Gadget Constants
;
Enumeration
  #Image_0
EndEnumeration

;- Image Plugins

;- Image Globals
Global Image0

Global avifile.s

avifile.s = "C:\Program Files (x86)\AutoIt3\Examples\GUI\sampleAVI.avi"
Global *pAviFile = @avifile
Global hFile.l

OpenLibrary(#Lib, "AVIFIL32.DLL")     ;// Open AVIFIL32 DLL and give it the handle #Lib
CallFunction (#Lib, "AVIFileInit")    ;// Initialize the library
;- Catch Images
;Image0 = CatchImage(0, ?Image0)

;- Images
;DataSection
;Image0:
;  IncludeBinary ""
;EndDataSection

Procedure Open_Window_0()
  If OpenWindow(#Window_0, 303, 160, 619, 488, "New window ( 0 )",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
    
    ImageGadget(#Image_0, 140, 50, 350, 310, Image0)
    
    

    
   
    ;Repeat this loop to keep the window open until the user closes it
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
      
  EndIf

EndProcedure


Procedure Open_AVI()
  
  CallFunction(#Lib, "AVIFileOpen", hFile, *pAviFile, #OF_READ, #Null)
  
  CallFunction(#Lib, "AVIFileRelease", hFile)
  CallFunction(#Lib, "AVIFileExit")
  

EndProcedure

Open_Window_0()
Open_AVI()

Re: Having Trouble..could use an example (AVIFIL32)

Posted: Sun Jan 23, 2011 3:25 am
by IdeasVacuum
Not entirely sure what you are trying to do - in theory, you are trying to extract frames from an avi file, is that correct?

Re: Having Trouble..could use an example (AVIFIL32)

Posted: Sun Jan 23, 2011 4:03 am
by Zach
At this point, I really just want to get the darn thing open :oops:

But yes I want to test getting properties from the video stream, see how well it might work with Avisynth scripts; if it works good with them the plan is to implement a navigation interface that will display the first frame, and then advance at various frame intervals, etc..

Difficult as it is for me to get this working, it seemed a much less complicated avenue to try, versus Inc's Avisynth wrapper..

Pretty new to pointers / API, etc..

Re: Having Trouble..could use an example (AVIFIL32)

Posted: Sun Jan 23, 2011 6:22 am
by Paul
Maybe this will get you started...

Code: Select all

Structure AVI_FILE_INFO
  dwMaxBytesPerSecond.l
  dwFlags.l
  dwCaps.l
  dwStreams.l
  dwSuggestedBufferSize.l
  dwWidth.l
  dwHeight.l
  dwScale.l
  dwRate.l
  dwLength.l
  dwEditCount.l
  szFileType.s{64}
EndStructure
fileinfo.AVI_FILE_INFO

file$="S:\temp\tree.avi"
pAVIFileIn.l=0



hDll=OpenLibrary(#PB_Any, "AVIFIL32.DLL")
If hDll
  CallFunction(hDll,"AVIFileInit")
  If CallFunction(hDll,"AVIFileOpen",@pAVIFileIn,@file$,#OF_READ,#Null)=0
    CallFunction(hDll,"AVIFileInfo",pAVIFileIn,fileinfo.AVI_FILE_INFO,SizeOf(fileinfo))
  
    Debug fileinfo\dwWidth
    Debug fileinfo\dwHeight
    Debug fileinfo\szFileType
  
    CallFunction(hDll,"AVIFileRelease",pAVIFileIn)
  EndIf
  
  CallFunction(hDll,"AVIFileExit")  
  CloseLibrary(hDll)
EndIf

Re: Having Trouble..could use an example (AVIFIL32)

Posted: Sun Jan 23, 2011 7:50 pm
by Zach
It's definitely good to see a working example. I can see where I went wrong in a few areas. Although if you feel like adding some comments, I would appreciate that also.
Just some basic things really , "we have to call this like this, or it won't work; Do it this way, whenever you do this remember you need to..." etc..

Kind of a mini-lesson on properly building my procedure calls I guess. I can see for instance, the pointer to the file was initialized instead of simply declared, like I had done. (I meant to use a @ in my pasted code as well, but forgot to change it back from my messing around trying to get it to work)

I do appreciate the structure example too, as I hadn't bothered with that in the beginning, when I should have.

Code: Select all

szFileType.s{64}
64 character limit? (Is that what it means?)

Re: Having Trouble..could use an example (AVIFIL32)

Posted: Mon Jan 24, 2011 1:28 am
by Zach
Making Progress I think! This is Debug output from loading an Avisynth Script.
AVI Width: 640
AVI Height: 480
File Handler: Avisynth
Streams Inside: 2
First Frame: 0
Total Frames: 43948
FourCC: 1935960438
Stream Rate: 0
Stream Scale: 10000000
Stream Start: 43948
Stream Length: 0
Stream Sample Size: 0
Stream Description: ynth video #1
Stream Frame-Left: 0
Stream Frame-Top: 640
Stream Frame-Right: 480
Stream Frame-Bottom: 0
Seems like a lot of the StreamInfo tags are rather useless though.. Not sure why the Stream Description is left-truncated (weird?) like that. Or why I get funny results from stuff like the Stream Length, or Stream Start. Stream Rate always seems to be 0 for some reason even on real AVI files.. some of this stuff definitely seems like useless information but getting 0's for some of them still bothers me, but I guess it really isn't that important since I don't need that information anyway...

But hopefully I will next be able to figure out how to grab a single frame from the start of the file, and then use a slider to show one frame at a time... We'll see I guess..


Source code thus far..

Code: Select all

#streamtypeVIDEO = 1935960438
#streamtypeAUDIO = 1935963489
#streamtypeMIDI = 1935960429
#streamtypeTEXT = 1937012852 



Structure AVI_FILE_INFO;  Structure to hold information returned by AVIFILEINFO
  dwMaxBytesPerSecond.l
  dwFlags.l
  dwCaps.l
  dwStreams.l
  dwSuggestedBufferSize.l
  dwWidth.l
  dwHeight.l
  dwScale.l
  dwRate.l
  dwLength.l
  dwEditCount.l
  szFileType.s{64}
EndStructure
fileinfo.AVI_FILE_INFO;   Variable instance of AVI_FILE_INFO Structure

Structure AVI_RECT ; for use with AVI_STREAM_INFO field "rcFrame"
  left.l
  top.l
  right.l
  bottom.l
EndStructure


Structure AVI_STREAM_INFO;  Structure to hold information returned by AVISTREAMINFO
  fccType.l
  fccHandler.l
  dwFlags.l
  dwCaps.l
  wPriority.i
  wLanguage.i
  dwScale.l
  dwRate.l
  dwStart.l
  dwLength.l
  swInitialFrames.l
  dwSuggestedBufferSize.l
  dwQuality.l
  dwSampleSize.l
  rcFrame.AVI_RECT
  dwEditCount.l
  dwFormatChangeCount.l
  szName.s{64}
EndStructure
streaminfo.AVI_STREAM_INFO; Variable instance of AVI_STREAM_INFO structure.


;file$="C:\Windows\winsxs\amd64_microsoft-windows-t..flicklearningwizard_31bf3856ad364e35_6.1.7600.16385_none_69769fd78b751ad3\FlickAnimation.avi"
file$="N:\Anime\Iczer 1\script.avs"
pAVIFileIn.l=0; Pointer to AVI File being opened
pAVIStream.l=0; Pointer to AVI File Stream


hDll=OpenLibrary(#PB_Any, "AVIFIL32.DLL")
If hDll
  CallFunction(hDll,"AVIFileInit")
  If CallFunction(hDll,"AVIFileOpen",@pAVIFileIn,@file$,#OF_READ,#Null)=0
    CallFunction(hDll,"AVIFileInfo",pAVIFileIn,fileinfo.AVI_FILE_INFO,SizeOf(fileinfo))
    CallFunction(hDll,"AVIFileGetStream", pAVIFileIn, @pAVIStream, #streamtypeVIDEO, 0)
    
    FirstFrame.l = CallFunction(hDll, "AVIStreamStart", pAVIStream)
    NumFrames.l = CallFunction(hDll, "AVIStreamLength", pAVIStream)
    CallFunction(hDll, "AVIStreamInfo",pAVIStream,streaminfo.AVI_STREAM_INFO,SizeOf(streaminfo))
 
    Debug "AVI Width: " + Str(fileinfo\dwWidth)
    Debug "AVI Height: " + Str(fileinfo\dwHeight)
    Debug "File Handler: " + fileinfo\szFileType
    Debug "Streams Inside: " + Str(fileinfo\dwStreams)
    Debug "First Frame: " + Str(FirstFrame)
    Debug "Total Frames: " + Str(NumFrames)
    
    Debug "FourCC: " + Str(streaminfo\fccType)
    Debug "Stream Rate: " + Str(streaminfo\dwRate)
    Debug "Stream Scale: " + Str(streaminfo\dwScale)
    Debug "Stream Start: " + Str(streaminfo\dwStart)
    Debug "Stream Length: " + Str(streaminfo\dwLength)
    Debug "Stream Sample Size: " + Str(streaminfo\dwSampleSize)
    Debug "Stream Description: " + streaminfo\szName
    Debug "Stream Frame-Left: " + Str(streaminfo\rcFrame\left)
    Debug "Stream Frame-Top: " + Str(streaminfo\rcFrame\top)
    Debug "Stream Frame-Right: " + Str(streaminfo\rcFrame\right)
    Debug "Stream Frame-Bottom: " + Str(streaminfo\rcFrame\bottom)
    
    CallFunction(hDll,"AVIStreamRelease", pAVIStream)
    CallFunction(hDll,"AVIFileRelease",pAVIFileIn)
  EndIf
 
  CallFunction(hDll,"AVIFileExit") 
  CloseLibrary(hDll)
EndIf

Re: Having Trouble..could use an example (AVIFIL32)

Posted: Sat Jan 29, 2011 9:23 pm
by Zach
Well I seem to be stuck again. I have gone over the AVIFIL MSDN stuff, and it shows you what to do to get a frame from a stream, which I believe is returned as a packed DIB, with a pointer containing the address in memory of the packed DIB.


But beyond that I have been unable to find information, or examples in any language, on how to handle the data after that.. To summarize.

I have a pointer to a packed DIB (I assume), but I have no idea how to manipulate that DIB and display it on the screen, be it on an image control or a video playback form, or whatever. I have been unable to find any tutorials that discuss doing what I want to do, despite many hours of searching.. Maybe I suck at searching for information, I don't know? All the examples I come across for playing/manipulating AVI files either discuss how to open and play a file using MCI commands, or Microsoft specific animation controls (ActiveX, DirectX, MFC based type stuff) or only discuss AVIFIL32.DLL and its API as far as opening a file and then saving frames to a bitmap..

Whereas I need to:
Open a file (Accomplished)
Get information such as number of frames, width/height (Accomplished)
Open the video stream and get a pointer to a single frame (I think this is accomplished)
Display that frame on the screen somehow (Where I'm stuck)

I just don't know the actual procedure on how to accomplish this task, and what other structures or commands might be involved.

If anyone can provide further assistance or ideas, that would be appreciated. I am currently trying to find useful information about DIBs on MSDN and see if there is something in there about how to get a DIB displayed on screen.

Re: (AVIFIL32) new question (see newest post)

Posted: Mon Jan 31, 2011 6:27 pm
by idle
this works

edit added playback time

Code: Select all

Structure AVI_RECT
    left.l
    top.l
    right.l
    bottom.l
EndStructure

Structure AVI_STREAM_INFO
    fccType.l
    fccHandler.l
    dwFlags.l
    dwCaps.l
    wPriority.w
    wLanguage.w
    dwScale.l
    dwRate.l
    dwStart.l
    dwLength.l
    dwInitialFrames.l
    dwSuggestedBufferSize.l
    dwQuality.l
    dwSampleSize.l
    rcFrame.AVI_RECT
    dwEditCount .l
    dwFormatChangeCount.l
    szName.s{64}
EndStructure

Global pavi.l
Global psi.AVI_STREAM_INFO
Global pgf.l
Global gSizeAVIData
Global *pAviData
Global gmpf.l
Global srcImg.l
Global glastframe.l
Global gbPlay.l
Global srcAviWidth.l,srcAviHeight.l 
 

Import #PB_Compiler_Home + "Purelibraries\windows\libraries\avifil32.lib"

AVIStreamOpenFromFileA.l(*avi,szFile.s,fccType.l,lParam.l,mode.l,*clsidHandler)
AVIStreamSampleToTime.l(*avi,lSample.l)
AVIFileInit()
AVIStreamGetFrameOpen.l(*AVIStream,bih.l)
AVIStreamGetFrame.l(*GetFrameObj,lPos.l)
AVIStreamGetFrameClose.l(*GetFrameObj)
AVIStreamInfoA.l(*AVIStream,*psi,lSize.l)
AVIStreamStart.l(*avi)
AVIStreamLength.l(*avi)
AVIStreamRelease.l(*avi)
AVIFileRelease.l(*file)
AVIFileExit()

EndImport


#streamtypeVIDEO = 1935960438

Procedure CopyMemoryToImage(Memory, ImageNumber)
 
  Protected TemporaryDC.L, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
 
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
 
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
 
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 24
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
 
  SetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
 
  DeleteDC_(TemporaryDC)
 
EndProcedure

Procedure OpenAVI()
    
    Protected aret
    sfile$ =  OpenFileRequester("open file","","*.avi",1)
    
    If sfile$
        
        AVIFileInit()
          
        AVIStreamOpenFromFileA(@pavi, sFile$, #streamtypeVIDEO, 0, #OF_READ, #Null)  
        If pavi 
        
        AVIStreamInfoA(pavi, @psi, SizeOf(psi))
        srcAviWidth = psi\rcFrame\right - psi\rcFrame\left
        srcAviHeight = psi\rcFrame\bottom - psi\rcFrame\top
              
        glastframe = AVIStreamLength(pavi)
    
        gmpf = AVIStreamSampleToTime(pavi, glastframe) / glastframe
        gSizeAVIData = srcAviWidth * srcAviHeight * 3
        
        srcImg  = CreateImage(#PB_Any,srcAviWidth,srcAviHeight,24)
                
        *pAVIdata = AllocateMemory(gSizeAVIData)
        
        pgf = AVIStreamGetFrameOpen(pavi, $0)
        
           aret = #True 
        Else 
          aret = #False
        
        EndIf 
    
    Else
       aret = #False
    EndIf    

    ProcedureReturn aret
    
  EndProcedure
  
Procedure CloseAVI()
    If pgf 
      AVIStreamGetFrameClose(pgf)
      AVIStreamRelease(pavi)
      AVIFileExit()
      pgf=0
    EndIf 
EndProcedure

Procedure GrabAVIFrame(frame.l)
    lpbi.l
    mybi.BITMAPINFOHEADER
    gbPlay = #True 
    lt = ElapsedMilliseconds()        
    While gbPlay And a < glastframe 
      If ElapsedMilliseconds() > lt
         a+1
         lt + gmpf
         lpbi = AVIStreamGetFrame(pgf, a)
        If lpbi
          CopyMemory(lpbi,@mybi,SizeOf(mybi))
          Offset = mybi\biSize + (mybi\biClrUsed * 4)
          CopyMemoryToImage(lpbi+offset,srcimg)
          SetGadgetState(2,ImageID(srcImg))
        EndIf
     EndIf   
     Delay(1)
    Wend
        
    CloseAVI()
    
EndProcedure


Define tavi 

If OpenWindow(0, 300, 200, 640, 500, "test",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
    
   ButtonGadget(1,10, 480, 50, 20, "open")
   ButtonGadget(3,70, 480, 50, 20, "stop")
   ImageGadget(2,0,0,640,480,0)
      
   Repeat
   
   Event = WaitWindowEvent() 
   GadgetID = EventGadget()
   
   If Event = #PB_Event_Gadget
      Select GadgetID 
      Case 1 
        If Not IsThread(tavi)
          If openAvi()
            tavi = CreateThread(@GrabAVIFrame(),1)
          EndIf   
        Else 
          gbPlay = 0 
          WaitThread(tavi)  
          
          If openAvi()
            tavi = CreateThread(@GrabAVIFrame(),1)
          EndIf   
        EndIf   
      Case 3 
        gbplay = #False  
        If IsThread(tavi)
         WaitThread(tavi)
        EndIf        
      EndSelect      
   
   EndIf 
   
   Until Event = #PB_Event_CloseWindow 

EndIf 

Re: (AVIFIL32) new question (see newest post)

Posted: Mon Jan 31, 2011 7:30 pm
by Zach
Thanks for that. I will do my best to study it and try to learn.

Just one thing - I do not appear to have avifil32.lib in my libraries folder.. Where do I get this?

I saw in a forum search it came with an earlier version of PB, although I have 4.51 and feel a little dubious about installing another version. If I can find a way to get the file would it be compatible with 4.51? I wonder why it was taken out :?

Although if it comes down to it, I think I can adapt it to my current method of using the DLL.

Re: (AVIFIL32) new question (see newest post)

Posted: Mon Jan 31, 2011 7:58 pm
by idle
changed to prototypes

Code: Select all

;Play Avi no audio  
Structure AVI_RECT
    left.l
    top.l
    right.l
    bottom.l
EndStructure

Structure AVI_STREAM_INFO
    fccType.l
    fccHandler.l
    dwFlags.l
    dwCaps.l
    wPriority.w
    wLanguage.w
    dwScale.l
    dwRate.l
    dwStart.l
    dwLength.l
    dwInitialFrames.l
    dwSuggestedBufferSize.l
    dwQuality.l
    dwSampleSize.l
    rcFrame.AVI_RECT
    dwEditCount .l
    dwFormatChangeCount.l
    szName.s{64}
EndStructure

Global pavi.i
Global psi.AVI_STREAM_INFO
Global pgf.i
Global gSizeAVIData
Global *pAviData
Global gmpf.i
Global srcImg.i
Global glastframe.i
Global gbPlay.i
Global srcAviWidth.i,srcAviHeight.i 
Global gSeek.i
 
Prototype AVIStreamOpenFromFileA(*avi,szFile.s,fccType.l,lParam.l,mode.l,*clsidHandler)
Prototype AVIStreamSampleToTime(*avi,lSample.l)
Prototype AVIFileInit()
Prototype AVIStreamGetFrameOpen(*AVIStream,bih.l)
Prototype AVIStreamGetFrame(*GetFrameObj,lPos.l)
Prototype AVIStreamGetFrameClose(*GetFrameObj)
Prototype AVIStreamInfoA(*AVIStream,*psi,lSize.l)
Prototype AVIStreamStart(*avi)
Prototype AVIStreamLength(*avi)
Prototype AVIStreamRelease(*avi)
Prototype AVIFileRelease(*file)
Prototype AVIFileExit()
Prototype AVIStreamReadFormat(*AVIStream,lPos,*lpFormat,*lpcbFormat) 

Global AVIStreamOpenFromFileA.AVIStreamOpenFromFileA 
Global AVIStreamSampleToTime.AVIStreamSampleToTime
Global AVIFileInit.AVIFileInit
Global AVIStreamGetFrameOpen.AVIStreamGetFrameOpen
Global AVIStreamGetFrame.AVIStreamGetFrame
Global AVIStreamGetFrameClose.AVIStreamGetFrameClose
Global AVIStreamInfoA.AVIStreamInfoA
Global AVIStreamStart.AVIStreamStart
Global AVIStreamLength.AVIStreamLength
Global AVIStreamRelease.AVIStreamRelease
Global AVIFileRelease.AVIFileRelease
Global AVIFileExit.AVIFileExit
Global AVIStreamReadFormat.AVIStreamReadFormat

Procedure.i avifil32_LoadDLL()
  Protected hDLL.i

  hDLL = OpenLibrary(#PB_Any, "avifil32.dll")
  If hDLL <> 0
    
    AVIStreamOpenFromFileA = GetFunction(hDLL, "AVIStreamOpenFromFileA") 
    AVIStreamSampleToTime = GetFunction(hDLL, "AVIStreamSampleToTime")
    AVIFileInit= GetFunction(hDLL, "AVIFileInit")
    AVIStreamGetFrameOpen = GetFunction(hDLL, "AVIStreamGetFrameOpen")
    AVIStreamGetFrame = GetFunction(hDLL, "AVIStreamGetFrame")
    AVIStreamGetFrameClose = GetFunction(hDLL, "AVIStreamGetFrameClose")
    AVIStreamInfoA = GetFunction(hDLL, "AVIStreamInfoA")
    AVIStreamStart = GetFunction(hDLL, "AVIStreamStart")
    AVIStreamLength = GetFunction(hDLL, "AVIStreamLength")
    AVIStreamRelease = GetFunction(hDLL, "AVIStreamRelease")
    AVIFileRelease = GetFunction(hDLL, "AVIFileRelease")
    AVIFileExit = GetFunction(hDLL, "AVIFileExit")
    AVIStreamReadFormat = GetFunction(hDLL, "AVIStreamReadFormat")
     ProcedureReturn hDLL
  EndIf

  ProcedureReturn #False
EndProcedure

#StreamTypeVIDEO = 1935960438

Procedure CopyMemoryToImage(Memory, ImageNumber)
 
  Protected TemporaryDC.L, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
 
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
 
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
 
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 24
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
 
  SetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, Memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
 
  DeleteDC_(TemporaryDC)
 
EndProcedure

Procedure OpenAVI(window)
    
  Protected aret=#False,bih.BITMAPINFOHEADER  
   
  sfile$ =  OpenFileRequester("open file","","AVI (*.avi)|*.avi",1)
  
  If sfile$
      
    AVIFileInit()
    AVIStreamOpenFromFileA(@pavi, sFile$, #streamtypeVIDEO, 0, #OF_READ, #Null)  
    If pavi 
      AVIStreamInfoA(pavi, @psi, SizeOf(psi))
       
      srcAviWidth = psi\rcFrame\right - psi\rcFrame\left
      srcAviHeight = psi\rcFrame\bottom - psi\rcFrame\top
      offset = GetSystemMetrics_(#SM_CYMENU)*2
      ResizeWindow(window,WindowX(window),WindowY(window),srcAviWidth,srcAviHeight+offset) 
      ResizeGadget(3,#PB_Ignore,WindowHeight(window)-(offset),WindowWidth(window)-6,#PB_Ignore)
      glastframe = AVIStreamLength(pavi)
      SetGadgetAttribute(3,#PB_TrackBar_Maximum,glastframe)   
      gmpf = AVIStreamSampleToTime(pavi, glastframe) / glastframe
      gSizeAVIData = srcAviWidth * srcAviHeight * 3
      srcImg  = CreateImage(#PB_Any,srcAviWidth,srcAviHeight,24)
      *pAVIdata = AllocateMemory(gSizeAVIData)
      With bih
        \biBitCount = 24
        \biClrImportant = 0
        \biClrUsed = 0
        \biCompression = #BI_RGB
        \biHeight = psi\rcFrame\bottom - psi\rcFrame\top
        \biPlanes = 1
        \biSize = 40
        \biWidth = psi\rcFrame\right - psi\rcFrame\left
        \biXPelsPerMeter = 0
        \biYPelsPerMeter = 0
        \biSizeImage = (((\biWidth * 3) + 3) & $FFFC) * \biHeight 
      EndWith
      pgf = AVIStreamGetFrameOpen(pavi,@bih)
      aret = #True 
    EndIf 
 EndIf    

 ProcedureReturn aret
    
EndProcedure
  
Procedure CloseAVI()
  If pgf 
    AVIStreamGetFrameClose(pgf)
    AVIStreamRelease(pavi)
    AVIFileExit()
    pgf=0
  EndIf 
EndProcedure

Procedure GrabAVIFrame(frame.l)
  Protected lpbi.i,mybi.BITMAPINFOHEADER,lt
  gbPlay = #True 
  lt = ElapsedMilliseconds()
  gseek = frame 
  While gbPlay And gSeek < glastframe 
    If ElapsedMilliseconds() > lt
       gSeek+1
       lt + gmpf
       lpbi = AVIStreamGetFrame(pgf, gSeek)
      If lpbi
        CopyMemory(lpbi,@mybi,SizeOf(mybi))
        Offset = mybi\biSize + (mybi\biClrUsed * 4)
        CopyMemoryToImage(lpbi+offset,srcImg)
        SetGadgetState(2,ImageID(srcImg))
        SetGadgetState(3,gseek)
      EndIf
   EndIf   
   Delay(1)
  Wend
  CloseAVI()
EndProcedure


Define tavi,Event,Evg,MenuID 

If avifil32_LoadDLL()

  If OpenWindow(0, 300, 200, 640, 480, "test",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
     CreateMenu(0, WindowID(0))
     MenuTitle("file") 
     MenuItem(1,"open")
     MenuItem(2,"stop")
     ImageGadget(2,0,0,640,480,0)
     TrackBarGadget(3,3,480-(GetSystemMetrics_(#SM_CYMENU)+20),640-6,20,1,1000)
   
     Repeat
     
     Event = WaitWindowEvent() 
     MenuID = EventMenu()
     EVG = EventGadget()
     
     If Event = #PB_Event_Menu
        Select MenuID 
        Case 1 
          If Not IsThread(tavi)
            If openAvi(0)
              tavi = CreateThread(@GrabAVIFrame(),1)
            EndIf   
          Else 
            gbPlay = #False  
            WaitThread(tavi)  
            
            If openAvi(0)
              tavi = CreateThread(@GrabAVIFrame(),1)
            EndIf   
          EndIf   
        Case 2 
          gbplay = #False  
          If IsThread(tavi)
           WaitThread(tavi)
          EndIf        
        EndSelect      
      ElseIf event = #PB_Event_Gadget 
        If EVG = 3 
          gSeek = GetGadgetState(3) 
        EndIf   
     EndIf 
     
     Until Event = #PB_Event_CloseWindow 
  
   EndIf 
   
 EndIf 

Re: (AVIFIL32) new question (see newest post)

Posted: Mon Jan 31, 2011 8:54 pm
by Zach
Thank you for doing that :)

Weird behavior when I opened an MKV. It doesn't play it but if I open an AVI, stop it, then open an MKV it will halt with invalid memory access (read error at a memory address). Loads AVI's fine though from what I can tell (playback speed needs to be tweaked I think), AVS scripts come up blank as well.

But I think I can work that stuff out though, now that I have a working example. I'm actually not looking for playback functionality though, as I'll be setting up a scroll bar, for frame based navigation at 1, 5, 10, and user defined frame increments.

Thanks again for your help!

Re: (AVIFIL32) new question (see newest post)

Posted: Mon Jan 31, 2011 9:55 pm
by idle
just edited previous post, fixed it so it will return 24 bit format regardless of the source file

Re: (AVIFIL32) new question (see newest post)

Posted: Sat Apr 06, 2013 4:09 pm
by mpz
Hello,

i have a question about the AVIFile32 with PB x86 and PB x64. The examplecode from idle works fine with Purbasic 5.11 x86. If i use this code with PB 5.11 x64 you can open a avi file, see the stream, infromationa about the solution etc etc, but the needet command

pgf = AVIStreamGetFrameOpen(pavi,#AVIGETFRAMEF_BESTDISPLAYFMT)

brings all times pgf = 0 and then you cant make a image from the Frame. Is there a solution to get a frame with PB x64? I have tested much think, but nothing works... Hope anybody can help...

Greetings Michael

Re: (AVIFIL32) new question (see newest post)

Posted: Sat Apr 06, 2013 6:15 pm
by mpz
Hi,

i am sorry, it was my fault. The code works with PB 5.11 x64 fine. The problem is if you use a x64 program you must use a x64 video codec too. So the function
pgf = 0
means that there is no (x64) divx avi codec is installed. I have installed the last xvid codec (Xvid-1.3.2-20110601.exe) for x64 and now i can see divx avi files with the old avifile32 ...

The next question i have is there a solution to include a video as binary file in an exe file? The only solution i found ist to write the avi as file, open it nad delete it later....

Greetings Michael

Re: (AVIFIL32) new question (see newest post)

Posted: Sun Apr 07, 2013 5:21 am
by idle
Don't know if that's possible to do it another way.