From be55a113373cbd5eea229ed9d78bc1de5ed93069 Mon Sep 17 00:00:00 2001 From: brunzelchen Date: Thu, 7 Oct 2010 16:17:05 +0000 Subject: - switching UVideo back to rev 2609 (without decoding thread) - performance mode is now disabled by default git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/1.0.1 Challenge MOD@2639 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UIni.pas | 2 +- Game/Code/Classes/UVideo.pas | 503 +++++++++++++++++--------------------- Game/Code/Screens/UScreenSing.pas | 2 +- 3 files changed, 223 insertions(+), 284 deletions(-) diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas index 6ea24653..682016b8 100644 --- a/Game/Code/Classes/UIni.pas +++ b/Game/Code/Classes/UIni.pas @@ -400,7 +400,7 @@ begin if Tekst = IAspectCorrect[Pet] then Ini.AspectCorrect := Pet; // PerformanceMode - Tekst := IniFile.ReadString('Graphics', 'PerformanceMode', IPerformanceMode[1]); + Tekst := IniFile.ReadString('Graphics', 'PerformanceMode', IPerformanceMode[0]); for Pet := 0 to High(IPerformanceMode) do if Tekst = IPerformanceMode[Pet] then Ini.PerformanceMode := Pet; diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas index d54ca5c7..b89f5cc0 100644 --- a/Game/Code/Classes/UVideo.pas +++ b/Game/Code/Classes/UVideo.pas @@ -9,6 +9,7 @@ //{$define Info} + unit UVideo; interface @@ -28,15 +29,13 @@ uses SDL, glu, glext, SysUtils, - SyncObjs, {$ifdef DebugDisplay} {$ifdef win32} dialogs, {$endif} {$ENDIF} UIni, - UTime, - windows; + UTime; type TAspectCorrection = (acoStretch, acoCrop, acoLetterBox); //from 1.1 @@ -51,37 +50,20 @@ type ZoomFaktor: real; end; - TFrameThread = class(TThread) - private - Time: Extended; - Gap: Single; - Start: Single; - - iSkip: Boolean; - iDecode: Boolean; - - procedure DoDecode; - procedure DoSkip; - protected - constructor Create; - procedure Execute; override; - public - procedure Update(); - end; - procedure Init; procedure acOpenFile(FileName: pAnsiChar); procedure acClose; procedure acGetFrame(Time: Extended); +function acSearch(Time: Extended): integer; procedure acDrawGL(Screen: integer; DoDraw: boolean); procedure acDrawGLi(Screen: integer; Window: TRectCoords; Blend: real; DoDraw: boolean); procedure acTogglePause; +procedure acSkip(Gap: Single; Start: Single); procedure acSkip2(Gap: Single; Start: Single); procedure ToggleAspectCorrection; procedure GetVideoRect(var ScreenRect, TexRect: TRectCoords; Window: TRectCoords); procedure SetAspectCorrection(aspect: TAspectCorrection); procedure ResetAspectCorrection; -procedure UploadNewFrame; Const MIN_FPS = 40; @@ -136,16 +118,6 @@ var EnableVideoDraw: boolean; - FrameData: Pointer; - NewFrame: boolean; - SetTime: Extended; - SetGap: Single; - SetStart: Single; - SetSkip: boolean; - - FrameThread: TFrameThread; - - EventDecode: TEvent; implementation @@ -161,7 +133,7 @@ end; function seek_proc(sender: Pointer; pos: int64; whence: integer): int64; cdecl; begin - result := fs.Seek(pos, TSeekOrigin(whence)); + result := fs.Seek(pos, TSeekOrigin(whence)) end; procedure Init; @@ -189,19 +161,6 @@ begin PIXEL_FORMAT := GL_RGBA; EnableVideoDraw := true; - - SetTime := 0; - if(FrameData<>nil) then - FreeMem(FrameData); - FrameData := nil; - - if (FrameThread<>nil) then - begin - FrameThread.Terminate; - FrameThread.WaitFor; - FrameThread.Free; - FrameThread := nil; - end; end; procedure acOpenFile(FileName: pAnsiChar); @@ -209,7 +168,6 @@ var I: integer; begin - acClose; VideoPaused := False; VideoTimeBase := 0; @@ -217,6 +175,7 @@ begin LastFrameTime := 0; TimeDifference := 0; Counter := 0; + acClose; if not FileExists(FileName) then Exit; //TODO: error.log @@ -275,8 +234,6 @@ begin dataX := Round(Power(2, Ceil(Log2(TexX)))); dataY := Round(Power(2, Ceil(Log2(TexY)))); - GetMem(FrameData, numBytes*TexX*TexY); - // calculate some information for video display VideoAspect:=videodecoder^.stream_info.additional_info.video_info.pixel_aspect; if (VideoAspect = 0) then @@ -311,42 +268,11 @@ begin end; mmfps := (MAX_FPS-MIN_FPS)/2; - - SetTime := 0; - NewFrame := false; - SetSkip := false; - - if (EventDecode = nil) then - EventDecode := TEvent.Create(nil, false, false, ''); - - if (FrameThread = nil) then - FrameThread := TFrameThread.Create(); - - FrameThread.Resume; end; procedure acClose; begin - if VideoOpened then - begin - if (FrameThread<>nil) then - begin - FrameThread.Suspend; - //Framethread.WaitFor; - end; - - {if (FrameThread<>nil) then - begin - FrameThread.Terminate; - FrameThread.WaitFor; - FrameThread.Free; - FrameThread := nil; - end; - - FreeAndNil(EventDecode);} - - NewFrame := false; - SetSkip := false; + if VideoOpened then begin if videodecoder <> nil then ac_free_decoder(videodecoder); @@ -360,10 +286,6 @@ begin VideoOpened:=False; fName := ''; - - if(FrameData<>nil) then - FreeMem(FrameData); - FrameData := nil; end; end; @@ -375,22 +297,117 @@ end; procedure acSkip2(Gap: Single; Start: Single); begin - SetGap := Gap; - SetStart := Start; - SetSkip := true; - EventDecode.SetEvent; + VideoSkiptime:=Gap; + NegativeSkipTime:=Start+Gap; + if Start+Gap > 0 then + begin + VideoTime:=Start+Gap; + try + ac_seek(videodecoder, -1, Floor((Start+Gap)*1000)); + except + Log.LogError('Error seeking Video "acSkip2" on video ('+fName+')'); + acClose; + end; + end else + begin + try + ac_seek(videodecoder, 0, 0); + except + Log.LogError('Error seeking Video "acSkip2" on video ('+fName+')'); + acClose; + end; + VideoTime:=0; + end; end; -procedure acGetFrame(Time: Extended); +procedure acSkip(Gap: Single; Start: Single); begin - SetTime := Time; - EventDecode.SetEvent; + VideoSkiptime:=Gap; + NegativeSkipTime:=Start+Gap; + if Start+Gap > 0 then + begin + VideoTime:=0; + ac_seek(videodecoder, -1, Floor((Start+Gap)*1000)); + if (acSearch(Gap+Start)=0) then + begin + ac_seek(videodecoder, 0, 0); + VideoTime:=0; + acSearch(Gap+Start); + end; + end else + begin + ac_seek(videodecoder, 0, 0); + VideoTime:=0; + end; +end; + +function acSearch(Time: Extended): integer; +var + FrameFinished: Integer; + errnum: Integer; + FrameDataPtr: PByteArray; + myTime: Extended; + +begin + Result := 0; + if not VideoOpened then Exit; + if (NegativeSkipTime < 0)and(Time+NegativeSkipTime>=0) then + NegativeSkipTime:=0; + + myTime:=Time+VideoSkipTime; + TimeDifference:=myTime-VideoTime; + + if (VideoTime <> 0) and (TimeDifference <= VideoTimeBase) then begin + Exit;// we don't need a new frame now + end; + + pack := ac_read_package(inst); + FrameFinished:=0; + // read packets until we have a finished frame (or there are no more packets) + while ((VideoTime < Time-VideoTimeBase)) and (pack <> nil) do + begin + // if we got a packet from the video stream, then decode it + if (videodecoder^.stream_index = pack^.stream_index) then + begin + FrameFinished := ac_decode_package(pack, videodecoder); + VideoTime := videodecoder^.timecode; + ac_free_package(pack); + if ((VideoTime < Time-VideoTimeBase)) then + pack := ac_read_package(inst); + end else + begin + ac_free_package(pack); + pack := ac_read_package(inst); + end; + end; + if (pack<>nil) then + ac_free_package(pack); + + // if we did not get an new frame, there's nothing more to do + if Framefinished=0 then + begin + Exit; + end; + + errnum:=1; //TODO!! + if errnum >=0 then begin + FrameDataPtr:=Pointer(videodecoder^.buffer); + Result := 1; + glBindTexture(GL_TEXTURE_2D, VideoTex); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, PIXEL_FORMAT, GL_UNSIGNED_BYTE, @FrameDataPtr[0]); + + if Ini.Debug = 1 then + begin + //frame decode debug display + GoldenRec.Spawn(200,85,1,16,0,-1,ColoredStar,$ffff00,0); + end; + + end; end; -procedure TFrameThread.DoDecode; +procedure acGetFrame(Time: Extended); Const MAX = 3000; - FRAMEDROPCOUNT=3; var FrameFinished: Integer; @@ -400,8 +417,16 @@ var myTime: Extended; DropFrame: Boolean; droppedFrames: Integer; + I: Integer; + glError: glEnum; + glErrorStr: String; +const + FRAMEDROPCOUNT=3; begin + if not VideoOpened then Exit; + if VideoPaused then Exit; + mmfps := (Display.mFPS+mmfps)/2; if(Ini.PerformanceMode=1) then begin @@ -436,27 +461,38 @@ begin myTime:=Time+VideoSkipTime; TimeDifference:=myTime-VideoTime; + if Ini.Debug = 1 then + begin + timediff_str:= 't-diff: ' + FormatFloat('#0.00', TimeDifference); + mtime_str:= 'mytime: ' + FormatFloat('#0.00', myTime); + end; + DropFrame:=False; - if (VideoTime <> 0) and (TimeDifference <= VideoTimeBase) then - Exit; + if (VideoTime <> 0) and (TimeDifference <= VideoTimeBase) then begin + if Ini.Debug = 1 then + begin + // frame delay debug display + GoldenRec.Spawn(200,65,1,16,0,-1,ColoredStar,$00ff00,0); + end; + Exit;// we don't need a new frame now + end; + + if TimeDifference >= (FRAMEDROPCOUNT-1)*VideoTimeBase then begin // skip frames + if Ini.Debug = 1 then + begin + //frame drop debug display + GoldenRec.Spawn(200,105,1,16,0,-1,ColoredStar,$ff0000,0); + end; - if TimeDifference >= (FRAMEDROPCOUNT-1)*VideoTimeBase then - begin // skip frames DropFrame:=True; end; - if terminated then - Exit; - pack := ac_read_package(inst); FrameFinished:=0; // read packets until we have a finished frame (or there are no more packets) while (FrameFinished=0) and (pack <> nil) do begin - if terminated then - Exit; - // if we got a packet from the video stream, then decode it if (videodecoder^.stream_index = pack^.stream_index) then begin @@ -477,16 +513,11 @@ begin //acSearch(Time); for droppedFrames:=1 to FRAMEDROPCOUNT do begin - if terminated then - Exit; pack := ac_read_package(inst); FrameFinished:=0; // read packets until we have a finished frame (or there are no more packets) while (FrameFinished=0) and (pack <> nil) do begin - if terminated then - Exit; - // if we got a packet from the video stream, then decode it if (videodecoder^.stream_index = pack^.stream_index) then begin @@ -506,99 +537,105 @@ begin // if we did not get an new frame, there's nothing more to do if Framefinished=0 then begin - //acClose; +// GoldenRec.Spawn(220,15,1,16,0,-1,ColoredStar,$0000ff); + acClose; Exit; end; errnum:=1; //TODO!! if errnum >=0 then begin - FrameDataPtr := FrameData; - FrameDataPtr2:=Pointer(videodecoder^.buffer); - - if terminated then - Exit; + if(not pbo_supported) then + begin + FrameDataPtr:=Pointer(videodecoder^.buffer); - move(FrameDataPtr2[0], FrameDataPtr[0], numBytes*TexX*TexY); + glBindTexture(GL_TEXTURE_2D, VideoTex); - VideoTime := videodecoder^.timecode; + if(SkipLines>0)then + begin + for I := 0 to TexY - 1 do + begin + if(I mod (SkipLines+1) = 0) then + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (I div (SkipLines+1)), TexX, 1, + PIXEL_FORMAT, GL_UNSIGNED_BYTE, @FrameDataPtr[I*numBytes*TexX]); + end; + end else + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, + PIXEL_FORMAT, GL_UNSIGNED_BYTE, @FrameDataPtr[0]); + end else + begin + glGetError(); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); - NewFrame := true; - end; -end; + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose; + Log.LogError('Error drawing Video "glBindBuffer"'); + Exit; + end; -procedure TFrameThread.DoSkip; -var - SkipTime: Extended; + FrameDataPtr := glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY); + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose; + Log.LogError('Error drawing Video pbo "glMapBuffer"'); + Exit; + end; -begin - VideoSkiptime:=Gap; - NegativeSkipTime:=Start+Gap; - SkipTime := Start+Gap; - - if SkipTime > 0 then - begin - VideoTime:=SkipTime; - try - ac_seek(videodecoder, -1, Floor((SkipTime)*1000)); - except - Log.LogError('Error seeking Video "acSkip2" on video ('+fName+')'); - end; - end else - begin - try - ac_seek(videodecoder, 0, 0); - except - Log.LogError('Error seeking Video "acSkip2" on video ('+fName+')'); - end; - VideoTime:=0; - end; -end; + FrameDataPtr2:=Pointer(videodecoder^.buffer); + move(FrameDataPtr2[0], FrameDataPtr[0], numBytes*TexX*TexY); -constructor TFrameThread.Create; -begin - inherited Create(true); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose; + Log.LogError('Error drawing Video pbo "glUnmapBuffer"'); + Exit; + end; - //Self.Priority := tpLower; - Self.FreeOnTerminate := false; + glBindTexture(GL_TEXTURE_2D, VideoTex); + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose; + Log.LogError('Error drawing Video pbo "glBindTexture"'); + Exit; + end; - Time := 0; - iDecode := false; - iSkip := false; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, + PIXEL_FORMAT, GL_UNSIGNED_BYTE, nil); - Self.Resume; -end; + glError := glGetError; + if glError <> GL_NO_ERROR then + begin + acClose; + case glError of + GL_INVALID_ENUM: glErrorStr:='INVALID_ENUM'; + GL_INVALID_VALUE: glErrorStr:='INVALID_VALUE'; + GL_INVALID_OPERATION: glErrorStr:='INVALID_OPERATION'; + GL_STACK_OVERFLOW: glErrorStr:='STACK_OVERFLOW'; + GL_STACK_UNDERFLOW: glErrorStr:='STACK_UNDERFLOW'; + GL_OUT_OF_MEMORY: glErrorStr:='OUT_OF_MEMORY'; + else glErrorStr:='unknown error'; + end; + Log.LogError('Error drawing Video pbo "glTexSubImage2D" ('+glErrorStr+')'); + Exit; + end; + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); + end; + VideoTime := videodecoder^.timecode; -procedure TFrameThread.Execute; -begin - while not terminated do - begin - if (EventDecode.WaitFor(100) = wrSignaled) then + if Ini.Debug = 1 then begin - try - if iSkip then - DoSkip; - - if iDecode then - DoDecode(); - except - - end; - end; - if not terminated then - Synchronize(Update); - end; -end; + //frame decode debug display + GoldenRec.Spawn(200,85,1,16,0,-1,ColoredStar,$ffff00,0); + end; -procedure TFrameThread.Update; -begin - Time := SetTime; - iDecode := VideoOpened and not VideoPaused and not NewFrame; - iSkip := SetSkip; - SetSkip := false; - Gap := SetGap; - Start := SetStart; - UploadNewFrame(); + end; end; procedure ToggleAspectCorrection(); @@ -733,104 +770,6 @@ begin acDrawGLi(Screen, Window, 1, DoDraw); end; -procedure UploadNewFrame; -var - FrameDataPtr: PByteArray; - FrameDataPtr2: PByteArray; - I: Integer; - glError: glEnum; - glErrorStr: String; - -begin - if VideoOpened and NewFrame then - begin - if (not pbo_supported) then - begin - FrameDataPtr:=FrameData; - - glBindTexture(GL_TEXTURE_2D, VideoTex); - - if(SkipLines>0)then - begin - for I := 0 to TexY - 1 do - begin - if(I mod (SkipLines+1) = 0) then - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (I div (SkipLines+1)), TexX, 1, - PIXEL_FORMAT, GL_UNSIGNED_BYTE, @FrameDataPtr[I*numBytes*TexX]); - end; - end else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, - PIXEL_FORMAT, GL_UNSIGNED_BYTE, @FrameDataPtr[0]); - end else - begin - glGetError(); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); - - glError := glGetError; - if glError <> GL_NO_ERROR then - begin - acClose; - Log.LogError('Error drawing Video "glBindBuffer"'); - Exit; - end; - - FrameDataPtr := glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY); - glError := glGetError; - if glError <> GL_NO_ERROR then - begin - acClose; - Log.LogError('Error drawing Video pbo "glMapBuffer"'); - Exit; - end; - - FrameDataPtr2:=FrameData; - move(FrameDataPtr2[0], FrameDataPtr[0], numBytes*TexX*TexY); - - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); - glError := glGetError; - if glError <> GL_NO_ERROR then - begin - acClose; - Log.LogError('Error drawing Video pbo "glUnmapBuffer"'); - Exit; - end; - - glBindTexture(GL_TEXTURE_2D, VideoTex); - glError := glGetError; - if glError <> GL_NO_ERROR then - begin - acClose; - Log.LogError('Error drawing Video pbo "glBindTexture"'); - Exit; - end; - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, - PIXEL_FORMAT, GL_UNSIGNED_BYTE, nil); - - glError := glGetError; - if glError <> GL_NO_ERROR then - begin - acClose; - case glError of - GL_INVALID_ENUM: glErrorStr:='INVALID_ENUM'; - GL_INVALID_VALUE: glErrorStr:='INVALID_VALUE'; - GL_INVALID_OPERATION: glErrorStr:='INVALID_OPERATION'; - GL_STACK_OVERFLOW: glErrorStr:='STACK_OVERFLOW'; - GL_STACK_UNDERFLOW: glErrorStr:='STACK_UNDERFLOW'; - GL_OUT_OF_MEMORY: glErrorStr:='OUT_OF_MEMORY'; - else glErrorStr:='unknown error'; - end; - Log.LogError('Error drawing Video pbo "glTexSubImage2D" ('+glErrorStr+')'); - Exit; - end; - glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); - end; - NewFrame := false; - EventDecode.SetEvent; - end; -end; - procedure acDrawGLi(Screen: integer; Window: TRectCoords; Blend: real; DoDraw: boolean); var ScreenRect, TexRect: TRectCoords; diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas index 402e24aa..2f8ee68f 100644 --- a/Game/Code/Screens/UScreenSing.pas +++ b/Game/Code/Screens/UScreenSing.pas @@ -1908,7 +1908,7 @@ begin if ShowFinish and AktSong.VideoLoaded then begin try - acGetFrame(Czas.Teraz); + acGetFrame(Music.Position); acDrawGL(ScreenAct, not WebCam); // this only draws except //If an Error occurs drawing: prevent Video from being Drawn again and Close Video -- cgit v1.2.3