From 27799def63021daab4b4bc9d09597a2d0bb76e11 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 1 May 2021 18:59:16 +0200 Subject: [PATCH] - rewrote movie player so that the decoder backends only perform the decoding but do not draw the frames themselves. This caused twq problems: 1. It made it impossible to let the client apply effects to the video. 2. The client had no control when rendering stopped. Now the backends only provide a texture handle that the client must draw. One immediate benefit is that Blood's fixed viewport scaling is now available to all video formats. --- source/core/movie/movieplayer.cpp | 46 +++++++++++++++++++----------- wadsrc/static/zscript/screenjob.zs | 24 ++++++++++++++-- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/source/core/movie/movieplayer.cpp b/source/core/movie/movieplayer.cpp index dbf20e5ff..f5dfbe0b0 100644 --- a/source/core/movie/movieplayer.cpp +++ b/source/core/movie/movieplayer.cpp @@ -67,6 +67,7 @@ public: virtual bool Frame(uint64_t clock) = 0; virtual void Stop() {} virtual ~MoviePlayer() = default; + virtual FTextureID GetTexture() = 0; }; //--------------------------------------------------------------------------- @@ -119,17 +120,12 @@ public: if (currentclock < nextframetime - 1) { - twod->ClearScreen(); - DrawTexture(twod, animtex.GetFrame(), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Masked, false, TAG_DONE); return true; } animtex.SetFrame(ANIM_GetPalette(&anim), ANIM_DrawFrame(&anim, curframe)); frametime = currentclock; - twod->ClearScreen(); - DrawTexture(twod, animtex.GetFrame(), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Masked, false, TAG_DONE); - int delay = 20; if (frameTicks) { @@ -168,6 +164,11 @@ public: buffer.Reset(); animtex.Clean(); } + + FTextureID GetTexture() override + { + return animtex.GetFrameID(); + } }; //--------------------------------------------------------------------------- @@ -199,8 +200,6 @@ public: { if (failed) return false; bool playon = decoder.RunFrame(clock); - twod->ClearScreen(); - DrawTexture(twod, decoder.animTex().GetFrame(), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, TAG_DONE); return playon; } @@ -208,6 +207,11 @@ public: { decoder.Close(); } + + FTextureID GetTexture() override + { + return decoder.animTex().GetFrameID(); + } }; //--------------------------------------------------------------------------- @@ -466,7 +470,6 @@ public: lastsoundframe = soundframe; } } - DrawTexture(twod, animtex.GetFrame(), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit, TAG_DONE); return !stop; } @@ -482,6 +485,11 @@ public: vpx_codec_destroy(&codec); animtex.Clean(); } + + FTextureID GetTexture() override + { + return animtex.GetFrameID(); + } }; //--------------------------------------------------------------------------- @@ -567,7 +575,6 @@ public: nFrameNs = 1'000'000'000 / nFrameRate; nFrames = Smacker_GetNumFrames(hSMK); Smacker_GetPalette(hSMK, palette); - fullscreenScale = (!(flags & FIXEDVIEWPORT) || (nWidth <= 320 && nHeight <= 200) || nWidth >= 640 || nHeight >= 480); numAudioTracks = Smacker_GetNumAudioTracks(hSMK); if (numAudioTracks) @@ -629,14 +636,7 @@ public: } } - if (fullscreenScale) - { - DrawTexture(twod, animtex.GetFrame(), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, TAG_DONE); - } - else - { - DrawTexture(twod, animtex.GetFrame(), 320, 240, DTA_VirtualWidth, 640, DTA_VirtualHeight, 480, DTA_CenterOffset, true, TAG_DONE); - } + if (frame > nFrame) { nFrame++; @@ -670,6 +670,12 @@ public: Smacker_Close(hSMK); animtex.Clean(); } + + FTextureID GetTexture() override + { + return animtex.GetFrameID(); + } + }; //--------------------------------------------------------------------------- @@ -812,3 +818,9 @@ DEFINE_ACTION_FUNCTION(_MoviePlayer, Destroy) delete self; return 0; } + +DEFINE_ACTION_FUNCTION(_MoviePlayer, GetTexture) +{ + PARAM_SELF_STRUCT_PROLOGUE(MoviePlayer); + ACTION_RETURN_INT(self->GetTexture().GetIndex()); +} diff --git a/wadsrc/static/zscript/screenjob.zs b/wadsrc/static/zscript/screenjob.zs index 8182323f4..53c6d8a94 100644 --- a/wadsrc/static/zscript/screenjob.zs +++ b/wadsrc/static/zscript/screenjob.zs @@ -230,6 +230,7 @@ struct MoviePlayer native native void Start(); native bool Frame(double clock); native void Destroy(); + native TextureID GetTexture(); } //--------------------------------------------------------------------------- @@ -242,10 +243,12 @@ class MoviePlayerJob : SkippableScreenJob { MoviePlayer player; bool started; + int flag; - ScreenJob Init(MoviePlayer mp) + ScreenJob Init(MoviePlayer mp, int flags) { Super.Init(); + flag = flags; player = mp; return self; } @@ -253,7 +256,7 @@ class MoviePlayerJob : SkippableScreenJob static ScreenJob CreateWithSoundInfo(String filename, Array soundinfo, int flags, int frametime, int firstframetime = -1, int lastframetime = -1) { let movie = MoviePlayer.Create(filename, soundinfo, flags, frametime, firstframetime, lastframetime); - if (movie) return new("MoviePlayerJob").Init(movie); + if (movie) return new("MoviePlayerJob").Init(movie, flags); return null; } static ScreenJob Create(String filename, int flags, int frametime = -1) @@ -268,6 +271,22 @@ class MoviePlayerJob : SkippableScreenJob empty.Push(int(soundname)); return CreateWithSoundInfo(filename, empty, flags, frametime); } + + virtual void DrawFrame() + { + let tex = player.GetTexture(); + let size = TexMan.GetScaledSize(tex); + + if (!(flag & MoviePlayer.FIXEDVIEWPORT) || (size.x <= 320 && size.y <= 200) || size.x >= 640 || size.y >= 480) + { + Screen.DrawTexture(tex, false, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_Masked, false); + } + else + { + Screen.DrawTexture(tex, false, 320, 240, DTA_VirtualWidth, 640, DTA_VirtualHeight, 480, DTA_CenterOffset, true, DTA_Masked, false); + } + + } override void Draw(double smoothratio) { @@ -286,6 +305,7 @@ class MoviePlayerJob : SkippableScreenJob { jobstate = finished; } + DrawFrame(); } override void OnDestroy()