Hi,
bin gerade einen Avi Player am erstellen, der mittels der avifil32.dll und deren Funktion "AVIStreamGetFrame" die einzelnen Frames rausholt und sie als PB Imagefolge im Imagegadget ablaufen lässt.
Jetzt kommts aber auf die Geschwindigkeit an.
Lasse ich normal die Frames hintereinander mittels For I =x to y Next Schleife aus dem Avi rausholen und die Framefolge im Imagegadget anzeigen habe ich niemals die richtigen FPS, mit welchen der Stream abgespielt werden sollte.
Lasse ich in der Schleife einen Delay(x) werkeln, müsste man doch den Wert x irgendwie herausbekommen. So wie ich es verstanden habe ist der Delay in milisekunden angegeben. bei 25 FPS (pal) wären das doch .... hmmm
1000/25 = 40
und bei 29.97 fps (ntsc)
1000/29.97 = 33,367
klappt aber nicht, so würden die Filme viel zu langsam abfahren.
Delay(25) bei 25fps PAL wäre (bei meinem Rechner) perfekt. Delay(29.97) würde einen 29,97fps NTSC Film jedoch nicht richtig sondern im Gegenteil noch weit langsamer ablaufen lassen (ist ja logisch), daher ist das Nonsense.
Entweder ich sollte mal die 3te Klasse wiederholen oder hier habe ich was simples vergessen, was z.B. noch den Wert im Delay beeinflusst - z.B. die Zeit, welche die CPU für dein eigentlichen Prozess braucht!?.
Jemand ne Idee?
Vielen Dank
Inc.
Delay() bei abspielen von einzelnen Frames mit richtiger FPS
Ich nehme aber nicht an, dass das Decoding/displaying die Rate von Delay(40) auf Delay(25) runterholt?
Beim Decoden habe ich eine CPU Usage von 10-15%, daher meine Vermutung.
Hier mal der Code (habs versucht übersichtlich zu halten).
Ab "----- Starting getting frames ----" geht die Schleife zum Auslesen und Darstellen los.
Habe was mit
- Starttime=Elapsedmiliseconds()
- Schleife startet
- Hier die Frames die geholt und dargestellt werden
- repeat
- WindowEvent()
- delay(1)
- until (starttime-Elapsedmiliseconds()) > 39
- Zurück zur Schleife
Wird aber alles SEHR langsam und das CPU Meter knallt hoch (wegen Repeat/Until nehme ich an)
Beim Decoden habe ich eine CPU Usage von 10-15%, daher meine Vermutung.
Hier mal der Code (habs versucht übersichtlich zu halten).
Ab "----- Starting getting frames ----" geht die Schleife zum Auslesen und Darstellen los.
Habe was mit
- Starttime=Elapsedmiliseconds()
- Schleife startet
- Hier die Frames die geholt und dargestellt werden
- repeat
- WindowEvent()
- delay(1)
- until (starttime-Elapsedmiliseconds()) > 39
- Zurück zur Schleife
Wird aber alles SEHR langsam und das CPU Meter knallt hoch (wegen Repeat/Until nehme ich an)
Code: Alles auswählen
;Main Soucreparts taken from didges AVI2BMP Procedure
;http://forums.purebasic.com/english/viewtopic.php?t=7648
Enumeration
#Window_0
#Source
#Image_0
EndEnumeration
Procedure Open_Window()
If OpenWindow(#Window_0, 224, 9, 980, 708, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Test FPS Playback via avifil32.dll")
If CreateGadgetList(WindowID())
ButtonGadget(#Source, 20, 20, 160, 20, "Load Source")
ImageGadget(#Image_0, 230, 40, 704, 576, 0, #PB_Image_Border); The Image Display Window
EndIf
EndIf
EndProcedure
; -------------------------------- Procedure GETFRAMES --------------------------------
Procedure GETFRAMES ( avifile.s )
#streamtypeVIDEO = $73646976
#AVIGETFRAMEF_BESTDISPLAYFMT = 1
#AVI_ERR_OK = 0
#Lib = 0
res = CallFunction( #Lib, "AVIFileOpen", @pAVIFile, @avifile.s, #OF_SHARE_DENY_WRITE, 0 )
If res = #AVI_ERR_OK
res = CallFunction( #Lib, "AVIFileGetStream", pAVIFile, @pAVIStream, #streamtypeVIDEO, 0 )
If res = #AVI_ERR_OK
firstFrame = CallFunction( #Lib, "AVIStreamStart", pAVIStream )
numFrames = CallFunction( #Lib, "AVIStreamLength", pAVIStream )
pGetFrameObj = CallFunction( #Lib, "AVIStreamGetFrameOpen", pAVIStream, #AVIGETFRAMEF_BESTDISPLAYFMT )
ImgID = CreateImage ( #PB_Any, 704, 576 )
hBmp = UseImage(ImgID)
start = ElapsedMilliseconds()
; ------------------- Starting getting frames -----------------
For a = firstFrame To ( numFrames - 1 ) - firstFrame
*bih.BITMAPINFOHEADER = CallFunction( AviDll, "AVIStreamGetFrame", pGetFrameObj, a )
tempstart= ElapsedMilliseconds()
WindowEvent()
;Delay(25)
If *bih
hdc = GetDC_(#Null)
hCDC = CreateCompatibleDC_(hdc)
If hCDC
SelectObject_( hCDC, hBmp )
SetDIBits_( hCDC, hBmp, 0, *bih\biHeight, *bih + SizeOf(BITMAPINFOHEADER), *bih, #DIB_RGB_COLORS)
DeleteDC_(hCDC)
EndIf
ReleaseDC_(#Null, hdc)
EndIf
SetGadgetState(#Image_0, hBmp); Displaying the Framecontent on the Imagewindow
Next a
; --------------------- End getting frames -----------------
CallFunction( #Lib, "AVIStreamGetFrameClose", pGetFrameObj )
EndIf
CallFunction( #Lib, "AVIFileRelease", pAVIFile )
EndIf
stop=ElapsedMilliseconds()
total = stop-start
MessageRequester( "Time needed to playback", Str(total/1000) + " ms", 0 )
EndProcedure
; -------------------------------- Appl.Window --------------------------------
Open_Window()
Repeat
Event = WaitWindowEvent()
If Event = #PB_EventGadget
GadgetID = EventGadgetID()
If GadgetID = #Source
OpenLibrary ( #Lib , "AVIFIL32.DLL")
CallFunction ( #Lib, "AVIFileInit" )
avifile.s = OpenFileRequester ( "Select AVI File", "", "Video|*.avi", 0 )
If avifile : GETFRAMES( avifile ) : EndIf
CallFunction( #Lib, "AVIFileExit" )
CloseLibrary( #Lib )
EndIf
EndIf
Until Event = #PB_EventCloseWindow
EndHabe mich mal hier umgesehen und was mit Repead gefunden und eingebaut:
Scheint sehr gut zu klappen, jedoch geht die CPU Anzeige eben wegen des Repeats auf 100.
Hmmmm ...
Code: Alles auswählen
For a = firstFrame To ( numFrames - 1 ) - firstFrame
tempstart= ElapsedMilliseconds()
*bih.BITMAPINFOHEADER = CallFunction( AviDll, "AVIStreamGetFrame", pGetFrameObj, a )
WindowEvent()
;Delay(25)
If *bih
hdc = GetDC_(#Null)
hCDC = CreateCompatibleDC_(hdc)
If hCDC
SelectObject_( hCDC, hBmp )
SetDIBits_( hCDC, hBmp, 0, *bih\biHeight, *bih + SizeOf(BITMAPINFOHEADER), *bih, #DIB_RGB_COLORS)
DeleteDC_(hCDC)
EndIf
ReleaseDC_(#Null, hdc)
EndIf
SetGadgetState(#Image_0, hBmp); Displaying the Framecontent on the Imagewindow
Repeat
While abs(tempstart-ElapsedMilliseconds())<39
;40ms = 25 FPS maximal
Wend
Break
ForEver
Next a
; Hmmmm ...
Wenn du ein Delay(0) einfügst bleibt zwar die hohe Prozessorauslastung, die anderen Programme kriegen jedoch auf Anfrage was davon ab. Bei delay(1) sollte die Auslastung runtergehen, aber ich weiß nicht ob du das bei dir verwenden kannst.
Windows XP Pro SP2 - PB 4.00Ich bin Ausländer - fast überall
-
Kaeru Gaman
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
- Andre
- PureBasic Team
- Beiträge: 1765
- Registriert: 11.09.2004 16:35
- Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10 - Wohnort: Saxony / Deutscheinsiedel
- Kontaktdaten:
Dazu gibts im engl. Forum eine ausführliche Beschreibung:
Tips & Tricks: Delay(0)
Tips & Tricks: Delay(0)