diff options
Diffstat (limited to 'src/media')
-rw-r--r-- | src/media/UVideo.pas | 209 |
1 files changed, 46 insertions, 163 deletions
diff --git a/src/media/UVideo.pas b/src/media/UVideo.pas index 994a0321..c7d59fc8 100644 --- a/src/media/UVideo.pas +++ b/src/media/UVideo.pas @@ -50,20 +50,19 @@ interface type {** - * acoStretch: Stretch to screen width and height + * vacStretch: Stretch to screen width and height * - ignores aspect * + no borders * + no image data loss - * acoCrop: Stretch to screen width or height, crop the other dimension + * vacCrop: Stretch to screen width or height, crop the other dimension * + keeps aspect * + no borders * - frame borders are cropped (image data loss) - * acoLetterBox: Stretch to screen width, add bars at or crop top and bottom + * vacLetterBox: Stretch to screen width, add bars at or crop top and bottom * + keeps aspect * - borders at top and bottom * o top/bottom is cropped if width < height (unusual) *} - TAspectCorrection = (acoStretch, acoCrop, acoLetterBox); @@ -115,14 +114,8 @@ const type TRectCoords = record - Left, Right: double; - Upper, Lower: double; - Windowed: boolean; //draw video in a window instead of full screen - //full screen means black background without blending - Reflection: boolean; - ReflectionSpacing: real; - TargetAspect: TAspectCorrection; //for zooming/aspect-switching - ZoomFactor: double; //0..1 ==> 0..100% + Left, Right: double; + Upper, Lower: double; end; IVideo_FFmpeg = interface (IVideo) @@ -169,7 +162,7 @@ type function DecodeFrame(): boolean; procedure SynchronizeTime(Frame: PAVFrame; var pts: double); - procedure GetVideoRect(var ScreenRect, TexRect: TRectCoords; Window: TRectCoords); + procedure GetVideoRect(var ScreenRect, TexRect: TRectCoords); procedure ShowDebugInfo(); @@ -191,8 +184,7 @@ type function GetPosition: real; procedure GetFrame(Time: Extended); - procedure DrawGL(Screen: integer); overload; - procedure DrawGL(Screen: integer; Window: TRectCoords; Blend: real); overload; + procedure DrawGL(Screen: integer); end; TVideoPlayback_FFmpeg = class( TInterfacedObject, IVideoPlayback ) @@ -893,87 +885,47 @@ begin {$ENDIF} end; -procedure TVideo_FFmpeg.GetVideoRect(var ScreenRect, TexRect: TRectCoords; Window: TRectCoords); +procedure TVideo_FFmpeg.GetVideoRect(var ScreenRect, TexRect: TRectCoords); var - RectS, RectT: TRectCoords; - - procedure GetCoords(var SRect: TRectCoords; Win: TRectCoords; Aspect: TAspectCorrection); - var - ScreenAspect: double; // aspect of screen resolution - ScaledVideoWidth: double; - ScaledVideoHeight: double; - rW, rH: double; - - begin - // Three aspects to take into account: - // 1. Screen/display resolution (e.g. 1920x1080 -> 16:9) - // 2. Render aspect (fixed to 800x600 -> 4:3) - // 3. Movie aspect (video frame aspect stored in fAspect) - if (Win.windowed) then - begin - rW := (Win.Right-Win.Left); - rH := (Win.Lower-Win.Upper); - ScreenAspect := rW*((ScreenW/Screens)/RenderW)/(rH*(ScreenH/RenderH)); - end else - begin - rW := RenderW; - rH := RenderH; - ScreenAspect := (ScreenW/Screens) / ScreenH; + ScreenAspect: double; // aspect of screen resolution + ScaledVideoWidth, ScaledVideoHeight: double; +begin + // Three aspects to take into account: + // 1. Screen/display resolution (e.g. 1920x1080 -> 16:9) + // 2. Render aspect (fixed to 800x600 -> 4:3) + // 3. Movie aspect (video frame aspect stored in fAspect) + ScreenAspect := ScreenW / ScreenH; + + case fAspectCorrection of + acoStretch: begin + ScaledVideoWidth := RenderW; + ScaledVideoHeight := RenderH; end; - - case Aspect of - acoStretch: begin - ScaledVideoWidth := rW; - ScaledVideoHeight := rH; - end; - - acoCrop: begin - if (ScreenAspect >= fAspect) then - begin - ScaledVideoWidth := rW; - ScaledVideoHeight := rH * ScreenAspect/fAspect; - end - else - begin - ScaledVideoHeight := rH; - ScaledVideoWidth := rW * fAspect/ScreenAspect; - end; - end; - - acoLetterBox: begin - if (ScreenAspect <= fAspect) then - begin - ScaledVideoWidth := rW; - ScaledVideoHeight := rH * ScreenAspect/fAspect; - end - else - begin - ScaledVideoHeight := rH; - ScaledVideoWidth := rW * fAspect/ScreenAspect; - end; + acoCrop: begin + if (ScreenAspect >= fAspect) then + begin + ScaledVideoWidth := RenderW; + ScaledVideoHeight := RenderH * ScreenAspect/fAspect; end else - raise Exception.Create('Unhandled aspect correction!'); + begin + ScaledVideoHeight := RenderH; + ScaledVideoWidth := RenderW * fAspect/ScreenAspect; + end; end; - - SRect.Left := (rW - ScaledVideoWidth) / 2 + Win.Left; - SRect.Right := SRect.Left + ScaledVideoWidth; - SRect.Upper := (rH - ScaledVideoHeight) / 2 + Win.Upper; - SRect.Lower := SRect.Upper + ScaledVideoHeight; + acoLetterBox: begin + ScaledVideoWidth := RenderW; + ScaledVideoHeight := RenderH * ScreenAspect/fAspect; + end + else + raise Exception.Create('Unhandled aspect correction!'); end; -begin - if (Window.TargetAspect = fAspectCorrection) then - GetCoords(ScreenRect, Window, fAspectCorrection) - else - begin - GetCoords(RectS, Window, fAspectCorrection); - GetCoords(RectT, Window, Window.TargetAspect); - ScreenRect.Left := RectS.Left + (RectT.Left-RectS.Left)*Window.ZoomFactor; - ScreenRect.Right := RectS.Right + (RectT.Right-RectS.Right)*Window.ZoomFactor; - ScreenRect.Upper := RectS.Upper + (RectT.Upper-RectS.Upper)*Window.ZoomFactor; - ScreenRect.Lower := RectS.Lower + (RectT.Lower-RectS.Lower)*Window.ZoomFactor; - end; + // center video + ScreenRect.Left := (RenderW - ScaledVideoWidth) / 2; + ScreenRect.Right := ScreenRect.Left + ScaledVideoWidth; + ScreenRect.Upper := (RenderH - ScaledVideoHeight) / 2; + ScreenRect.Lower := ScreenRect.Upper + ScaledVideoHeight; // texture contains right/lower (power-of-2) padding. // Determine the texture coords of the video frame. @@ -985,31 +937,15 @@ end; procedure TVideo_FFmpeg.DrawGL(Screen: integer); var - Window: TRectCoords; - -begin - Window.Left := 0; - Window.Right := ScreenW; - Window.Upper := 0; - Window.Lower := ScreenH; - Window.Windowed := false; - Window.Reflection := false; - Window.TargetAspect := fAspectCorrection; - DrawGL(Screen, Window, 1); -end; - -procedure TVideo_FFmpeg.DrawGL(Screen: integer; Window: TRectCoords; Blend: real); -var ScreenRect: TRectCoords; TexRect: TRectCoords; - begin // have a nice black background to draw on // (even if there were errors opening the vid) // TODO: Philipp: IMO TVideoPlayback should not clear the screen at // all, because clearing is already done by the background class // at this moment. - if (Screen = 1) and not Window.Windowed then + if (Screen = 1) then begin // It is important that we just clear once before we start // drawing the first screen otherwise the first screen @@ -1028,25 +964,14 @@ begin {$ENDIF} // get texture and screen positions - GetVideoRect(ScreenRect, TexRect, Window); + GetVideoRect(ScreenRect, TexRect); - if Window.Windowed then - begin - glScissor(round((Window.Left)*(ScreenW/Screens)/RenderW+(ScreenW/Screens)*(Screen-1)), - round((RenderH-Window.Lower)*ScreenH/RenderH), - round((Window.Right-Window.Left)*(ScreenW/Screens)/RenderW), - round((Window.Lower-Window.Upper)*ScreenH/RenderH)); - glEnable(GL_SCISSOR_TEST); - - // we could use blending for brightness control, but do we need this? - // the window-mode needs blending! - glEnable(GL_BLEND); - end else - glDisable(GL_BLEND); + // we could use blending for brightness control, but do we need this? + glDisable(GL_BLEND); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, fFrameTex); - glColor4f(1, 1, 1, Blend); + glColor3f(1, 1, 1); glBegin(GL_QUADS); // upper-left coord glTexCoord2f(TexRect.Left, TexRect.Upper); @@ -1061,49 +986,7 @@ begin glTexCoord2f(TexRect.Right, TexRect.Upper); glVertex2f(ScreenRect.Right, ScreenRect.Upper); glEnd; - glDisable(GL_SCISSOR_TEST); - - //Draw Reflection - if Window.Reflection then - begin - glScissor(round((Window.Left)*(ScreenW/Screens)/RenderW+(ScreenW/Screens)*(Screen-1)), - round((RenderH-Window.Lower-Window.ReflectionSpacing-(Window.Lower-Window.Upper)*0.5)*ScreenH/RenderH), - round((Window.Right-Window.Left)*(ScreenW/Screens)/RenderW), - round((Window.Lower-Window.Upper)*ScreenH/RenderH*0.5)); - glEnable(GL_SCISSOR_TEST); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - //Draw - glBegin(GL_QUADS);//Top Left - glColor4f(1, 1, 1, Blend-0.3); - glTexCoord2f(TexRect.Left, TexRect.Lower); - glVertex2f(ScreenRect.Left, Window.Lower + Window.ReflectionSpacing); - - //Bottom Left - glColor4f(1, 1, 1, 0); - glTexCoord2f(TexRect.Left, (TexRect.Lower-TexRect.Upper)*0.5); - glVertex2f(ScreenRect.Left, - Window.Lower + (ScreenRect.Lower-ScreenRect.Upper)*0.5 + Window.ReflectionSpacing); - - //Bottom Right - glColor4f(1, 1, 1, 0); - glTexCoord2f(TexRect.Right, (TexRect.Lower-TexRect.Upper)*0.5); - glVertex2f(ScreenRect.Right, - Window.Lower + (ScreenRect.Lower-ScreenRect.Upper)*0.5 + Window.ReflectionSpacing); - - //Top Right - glColor4f(1, 1, 1, Blend-0.3); - glTexCoord2f(TexRect.Right, TexRect.Lower); - glVertex2f(ScreenRect.Right, Window.Lower + Window.ReflectionSpacing); - glEnd; - - glDisable(GL_SCISSOR_TEST); - end; - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); {$IFDEF VideoBenchmark} Log.BenchmarkEnd(15); |