From a82aa01db1d538417a440a4201c602a74c09b88e Mon Sep 17 00:00:00 2001 From: divverent Date: Tue, 16 Jun 2009 18:41:24 +0000 Subject: [PATCH] cl_capturevideo_framestep example: when set to 4, and cl_capturevideo_fps is 30 then DP will run at 120fps and capture at 30fps currently pointless, will be great once motion blur is done git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9021 d7cf8633-e32d-0410-b094-e92efae38249 --- cap_avi.c | 6 +++--- cap_ogg.c | 2 +- cl_screen.c | 19 +++++++++++++------ client.h | 2 ++ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/cap_avi.c b/cap_avi.c index 97388c38..623be4ea 100644 --- a/cap_avi.c +++ b/cap_avi.c @@ -520,7 +520,7 @@ void SCR_CaptureVideo_Avi_BeginVideo() // AVI main header SCR_CaptureVideo_RIFF_Push("LIST", "hdrl", format->canseek ? -1 : 8+56+12+(12+52+8+40+8+68)+(cls.capturevideo.soundrate?(12+12+52+8+18):0)+12+(8+4)); SCR_CaptureVideo_RIFF_Push("avih", NULL, 56); - SCR_CaptureVideo_RIFF_Write32((int)(1000000.0 / cls.capturevideo.framerate)); // microseconds per frame + SCR_CaptureVideo_RIFF_Write32((int)(1000000.0 / (cls.capturevideo.framerate / cls.capturevideo.framestep))); // microseconds per frame SCR_CaptureVideo_RIFF_Write32(0); // max bytes per second SCR_CaptureVideo_RIFF_Write32(0); // padding granularity SCR_CaptureVideo_RIFF_Write32(0x910); // flags (AVIF_HASINDEX | AVIF_ISINTERLEAVED | AVIF_TRUSTCKTYPE) @@ -548,7 +548,7 @@ void SCR_CaptureVideo_Avi_BeginVideo() SCR_CaptureVideo_RIFF_Write16(0); // language SCR_CaptureVideo_RIFF_Write32(0); // initial frames // find an ideal divisor for the framerate - FindFraction(cls.capturevideo.framerate, &n, &d, 1000); + FindFraction(cls.capturevideo.framerate / cls.capturevideo.framestep, &n, &d, 1000); SCR_CaptureVideo_RIFF_Write32(d); // samples/second divisor SCR_CaptureVideo_RIFF_Write32(n); // samples/second multiplied by divisor SCR_CaptureVideo_RIFF_Write32(0); // start @@ -597,7 +597,7 @@ void SCR_CaptureVideo_Avi_BeginVideo() SCR_CaptureVideo_RIFF_Push("vprp", NULL, 68); SCR_CaptureVideo_RIFF_Write32(0); // VideoFormatToken SCR_CaptureVideo_RIFF_Write32(0); // VideoStandard - SCR_CaptureVideo_RIFF_Write32((int)cls.capturevideo.framerate); // dwVerticalRefreshRate (bogus) + SCR_CaptureVideo_RIFF_Write32((int)(cls.capturevideo.framerate / cls.capturevideo.framestep)); // dwVerticalRefreshRate (bogus) SCR_CaptureVideo_RIFF_Write32(width); // dwHTotalInT SCR_CaptureVideo_RIFF_Write32(height); // dwVTotalInLines FindFraction(aspect, &n, &d, 1000); diff --git a/cap_ogg.c b/cap_ogg.c index 159457d9..89a09fbd 100644 --- a/cap_ogg.c +++ b/cap_ogg.c @@ -987,7 +987,7 @@ void SCR_CaptureVideo_Ogg_BeginVideo() } format->yuvi = -1; // -1: no frame valid yet, write into 0 - FindFraction(cls.capturevideo.framerate, &num, &denom, 1001); + FindFraction(cls.capturevideo.framerate / cls.capturevideo.framestep, &num, &denom, 1001); ti.fps_numerator = num; ti.fps_denominator = denom; diff --git a/cl_screen.c b/cl_screen.c index 26bd9fc9..81a018a9 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -41,6 +41,7 @@ cvar_t cl_capturevideo_fps = {CVAR_SAVE, "cl_capturevideo_fps", "30", "how many cvar_t cl_capturevideo_nameformat = {CVAR_SAVE, "cl_capturevideo_nameformat", "dpvideo", "prefix for saved videos (the date is encoded using strftime escapes)"}; cvar_t cl_capturevideo_number = {CVAR_SAVE, "cl_capturevideo_number", "1", "number to append to video filename, incremented each time a capture begins"}; cvar_t cl_capturevideo_ogg = {CVAR_SAVE, "cl_capturevideo_ogg", "1", "save captured video data as Ogg/Vorbis/Theora streams"}; +cvar_t cl_capturevideo_framestep = {CVAR_SAVE, "cl_capturevideo_framestep", "1", "when set to n >= 1, render n frames to capture one (useful for motion blur like effects)"}; cvar_t r_letterbox = {0, "r_letterbox", "0", "reduces vertical height of view to simulate a letterboxed movie effect (can be used by mods for cutscenes)"}; cvar_t r_stereo_separation = {0, "r_stereo_separation", "4", "separation distance of eyes in the world (negative values are only useful for cross-eyed viewing)"}; cvar_t r_stereo_sidebyside = {0, "r_stereo_sidebyside", "0", "side by side views for those who can't afford glasses but can afford eye strain (note: use a negative r_stereo_separation if you want cross-eyed viewing)"}; @@ -870,6 +871,7 @@ void CL_Screen_Init(void) Cvar_RegisterVariable (&cl_capturevideo_nameformat); Cvar_RegisterVariable (&cl_capturevideo_number); Cvar_RegisterVariable (&cl_capturevideo_ogg); + Cvar_RegisterVariable (&cl_capturevideo_framestep); Cvar_RegisterVariable (&r_letterbox); Cvar_RegisterVariable(&r_stereo_separation); Cvar_RegisterVariable(&r_stereo_sidebyside); @@ -978,7 +980,8 @@ void SCR_CaptureVideo_BeginVideo(void) cls.capturevideo.width = width; cls.capturevideo.height = height; cls.capturevideo.active = true; - cls.capturevideo.framerate = bound(1, cl_capturevideo_fps.value, 1001); + cls.capturevideo.framerate = bound(1, cl_capturevideo_fps.value, 1001) * bound(1, cl_capturevideo_framestep.integer, 64); + cls.capturevideo.framestep = cl_capturevideo_framestep.integer; cls.capturevideo.soundrate = S_GetSoundRate(); cls.capturevideo.soundchannels = S_GetSoundChannels(); cls.capturevideo.startrealtime = realtime; @@ -1141,11 +1144,14 @@ static void SCR_ScaleDownBGRA(unsigned char *in, int inw, int inh, unsigned char } } -void SCR_CaptureVideo_VideoFrame(int newframenum) +void SCR_CaptureVideo_VideoFrame(int newframestepframenum) { int x = 0, y = 0; int width = cls.capturevideo.width, height = cls.capturevideo.height; + if(newframestepframenum == cls.capturevideo.framestepframe) + return; + CHECKGLERROR //return SCR_ScreenShot(filename, cls.capturevideo.buffer, cls.capturevideo.buffer + vid.width * vid.height * 3, cls.capturevideo.buffer + vid.width * vid.height * 6, 0, 0, vid.width, vid.height, false, false, false, jpeg, true); // speed is critical here, so do saving as directly as possible @@ -1153,8 +1159,8 @@ void SCR_CaptureVideo_VideoFrame(int newframenum) qglReadPixels (x, y, vid.width, vid.height, GL_BGRA, GL_UNSIGNED_BYTE, cls.capturevideo.screenbuffer);CHECKGLERROR SCR_ScaleDownBGRA (cls.capturevideo.screenbuffer, vid.width, vid.height, cls.capturevideo.outbuffer, width, height); - cls.capturevideo.videoframes(newframenum - cls.capturevideo.frame); - cls.capturevideo.frame = newframenum; + cls.capturevideo.videoframes(newframestepframenum - cls.capturevideo.framestepframe); + cls.capturevideo.framestepframe = newframestepframenum; if(cl_capturevideo_printfps.integer) { @@ -1185,7 +1191,7 @@ void SCR_CaptureVideo(void) { if (!cls.capturevideo.active) SCR_CaptureVideo_BeginVideo(); - if (cls.capturevideo.framerate != cl_capturevideo_fps.value) + if (cls.capturevideo.framerate != cl_capturevideo_fps.value * cl_capturevideo_framestep.integer) { Con_Printf("You can not change the video framerate while recording a video.\n"); Cvar_SetValueQuick(&cl_capturevideo_fps, cls.capturevideo.framerate); @@ -1209,7 +1215,8 @@ void SCR_CaptureVideo(void) return; } // write frames - SCR_CaptureVideo_VideoFrame(newframenum); + SCR_CaptureVideo_VideoFrame(newframenum / cls.capturevideo.framestep); + cls.capturevideo.frame = newframenum; if (cls.capturevideo.error) { Cvar_SetValueQuick(&cl_capturevideo, 0); diff --git a/client.h b/client.h index dc93f806..af05f85c 100644 --- a/client.h +++ b/client.h @@ -466,6 +466,8 @@ typedef struct capturevideostate_s { double startrealtime; double framerate; + int framestep; + int framestepframe; qboolean active; qboolean realtime; qboolean error; -- 2.39.2