From 70b3c52211617e1d585a1bbe805c5fd47176bfd1 Mon Sep 17 00:00:00 2001 From: vortex Date: Sat, 4 Dec 2010 14:24:55 +0000 Subject: [PATCH] maked cl_video to have module playback, so several video formats can be implemented. Quite nasty yet, as streaming audio is not supported and all videos have extension .dpv (as set by playvideo command). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10648 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_video.c | 49 +++++++++++++++++++++++++++++++---------------- cl_video.h | 8 +++++++- dpvsimpledecode.c | 14 ++++++++------ dpvsimpledecode.h | 5 ++++- 4 files changed, 52 insertions(+), 24 deletions(-) diff --git a/cl_video.c b/cl_video.c index 634e69a3..624d7847 100644 --- a/cl_video.c +++ b/cl_video.c @@ -4,6 +4,12 @@ #include "cl_video.h" #include "dpvsimpledecode.h" +// VorteX: JAM video module used by Blood Omnicide +//#define USEJAM +#ifdef USEJAM + #include "jamdecode.c" +#endif + // cvars cvar_t cl_video_subtitles = {CVAR_SAVE, "cl_video_subtitles", "0", "show subtitles for videos (if they are presented)"}; cvar_t cl_video_subtitles_lines = {CVAR_SAVE, "cl_video_subtitles_lines", "4", "how many lines to occupy for subtitles"}; @@ -38,29 +44,35 @@ static clvideo_t *FindUnusedVid( void ) static qboolean OpenStream( clvideo_t * video ) { const char *errorstring; - video->stream = dpvsimpledecode_open( video->filename, &errorstring); + video->stream = dpvsimpledecode_open( video, video->filename, &errorstring); if (!video->stream ) { +#ifdef USEJAM + video->stream = jam_open( video, video->filename, &errorstring); + if (video->stream) + return true; +#endif Con_Printf("unable to open \"%s\", error: %s\n", video->filename, errorstring); return false; } return true; } -static void VideoUpdateCallback(rtexture_t *rt, void *data) { +static void VideoUpdateCallback(rtexture_t *rt, void *data) +{ clvideo_t *video = (clvideo_t *) data; R_UpdateTexture( video->cpif.tex, (unsigned char *)video->imagedata, 0, 0, video->cpif.width, video->cpif.height ); } static void LinkVideoTexture( clvideo_t *video ) { - video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name, - video->cpif.width, video->cpif.height, NULL, TEXTYPE_BGRA, TEXF_PERSISTENT | TEXF_CLAMP, -1, NULL ); + video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name, video->cpif.width, video->cpif.height, NULL, TEXTYPE_BGRA, TEXF_PERSISTENT | TEXF_CLAMP, -1, NULL ); R_MakeTextureDynamic( video->cpif.tex, VideoUpdateCallback, video ); CL_LinkDynTexture( video->cpif.name, video->cpif.tex ); } -static void UnlinkVideoTexture( clvideo_t *video ) { +static void UnlinkVideoTexture( clvideo_t *video ) +{ CL_UnlinkDynTexture( video->cpif.name ); // free the texture R_FreeTexture( video->cpif.tex ); @@ -71,13 +83,13 @@ static void UnlinkVideoTexture( clvideo_t *video ) { static void SuspendVideo( clvideo_t * video ) { - if( video->suspended ) + if (video->suspended) return; video->suspended = true; - UnlinkVideoTexture( video ); + UnlinkVideoTexture(video); // if we are in firstframe mode, also close the stream - if( video->state == CLVIDEO_FIRSTFRAME ) - dpvsimpledecode_close( video->stream ); + if (video->state == CLVIDEO_FIRSTFRAME) + video->close(video->stream); } static qboolean WakeVideo( clvideo_t * video ) @@ -201,12 +213,12 @@ static clvideo_t* OpenVideo( clvideo_t *video, const char *filename, const char video->state = CLVIDEO_FIRSTFRAME; video->framenum = -1; - video->framerate = dpvsimpledecode_getframerate( video->stream ); + video->framerate = video->getframerate( video->stream ); video->lasttime = realtime; video->subtitles = 0; - video->cpif.width = dpvsimpledecode_getwidth( video->stream ); - video->cpif.height = dpvsimpledecode_getheight( video->stream ); + video->cpif.width = video->getwidth( video->stream ); + video->cpif.height = video->getheight( video->stream ); video->imagedata = Mem_Alloc( cls.permanentmempool, video->cpif.width * video->cpif.height * cl_videobytesperpixel ); LinkVideoTexture( video ); @@ -291,7 +303,7 @@ void CL_RestartVideo(clvideo_t *video) video->framenum = -1; // reopen stream - dpvsimpledecode_close(video->stream); + video->close(video->stream); if (!OpenStream(video)) video->state = CLVIDEO_UNUSED; } @@ -306,7 +318,7 @@ void CL_CloseVideo(clvideo_t * video) // close stream if (!video->suspended || video->state != CLVIDEO_FIRSTFRAME) - dpvsimpledecode_close(video->stream); + video->close(video->stream); // unlink texture if (!video->suspended) UnlinkVideoTexture(video); @@ -354,7 +366,7 @@ void CL_Video_Frame(void) { do { video->framenum++; - if (dpvsimpledecode_video(video->stream, video->imagedata, cl_videormask, cl_videogmask, cl_videobmask, cl_videobytesperpixel, cl_videobytesperpixel * video->cpif.width)) + if (video->decodeframe(video->stream, video->imagedata, cl_videormask, cl_videogmask, cl_videobmask, cl_videobytesperpixel, cl_videobytesperpixel * video->cpif.width)) { // finished? CL_RestartVideo(video); @@ -597,6 +609,7 @@ void CL_VideoStop(void) static void CL_PlayVideo_f(void) { char name[MAX_QPATH], subtitlesfile[MAX_QPATH]; + const char *extension; Host_StartVideo(); @@ -606,7 +619,11 @@ static void CL_PlayVideo_f(void) return; } - dpsnprintf(name, sizeof(name), "video/%s.dpv", Cmd_Argv(1)); + extension = FS_FileExtension(Cmd_Argv(1)); + if (extension[0]) + dpsnprintf(name, sizeof(name), "video/%s", Cmd_Argv(1)); + else + dpsnprintf(name, sizeof(name), "video/%s.dpv", Cmd_Argv(1)); if ( Cmd_Argc() > 2) CL_VideoStart(name, Cmd_Argv(2)); else diff --git a/cl_video.h b/cl_video.h index 589a11b8..4277124e 100644 --- a/cl_video.h +++ b/cl_video.h @@ -54,8 +54,14 @@ typedef struct clvideo_s float subtitle_start[CLVIDEO_MAX_SUBTITLES]; float subtitle_end[CLVIDEO_MAX_SUBTITLES]; - // if a video is suspended, it is automatically paused (else we'd still have to process the frames) + // this functions gets filled by video format module + void (*close) (void *stream); + unsigned int (*getwidth) (void *stream); + unsigned int (*getheight) (void *stream); + double (*getframerate) (void *stream); + int (*decodeframe) (void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow); + // if a video is suspended, it is automatically paused (else we'd still have to process the frames) // used to determine whether the video's resources should be freed or not double lasttime; // when lasttime - realtime > THRESHOLD, all but the stream is freed diff --git a/dpvsimpledecode.c b/dpvsimpledecode.c index 8ad43bea..6ace51c0 100644 --- a/dpvsimpledecode.c +++ b/dpvsimpledecode.c @@ -1,4 +1,3 @@ - #include "quakedef.h" #include "dpvsimpledecode.h" @@ -333,7 +332,7 @@ static int dpvsimpledecode_setpixelformat(dpvsimpledecodestream_t *s, unsigned i // opening and closing streams // opens a stream -void *dpvsimpledecode_open(char *filename, const char **errorstring) +void *dpvsimpledecode_open(clvideo_t *video, char *filename, const char **errorstring) { dpvsimpledecodestream_t *s; char t[8], *wavename; @@ -385,7 +384,14 @@ void *dpvsimpledecode_open(char *filename, const char **errorstring) Z_Free(wavename); } // all is well... + // set the module functions s->videoframenum = -10000; + video->close = dpvsimpledecode_close; + video->getwidth = dpvsimpledecode_getwidth; + video->getheight = dpvsimpledecode_getheight; + video->getframerate = dpvsimpledecode_getframerate; + video->decodeframe = dpvsimpledecode_video; + return s; } else if (errorstring != NULL) @@ -506,10 +512,6 @@ double dpvsimpledecode_getframerate(void *stream) return s->info_framerate; } - - - - static int dpvsimpledecode_convertpixels(dpvsimpledecodestream_t *s, void *imagedata, int imagebytesperrow) { unsigned int a, x, y, width, height; diff --git a/dpvsimpledecode.h b/dpvsimpledecode.h index 075f3652..621b001c 100644 --- a/dpvsimpledecode.h +++ b/dpvsimpledecode.h @@ -2,6 +2,8 @@ #ifndef DPVSIMPLEDECODE_H #define DPVSIMPLEDECODE_H +#include "cl_video.h" + #define DPVSIMPLEDECODEERROR_NONE 0 #define DPVSIMPLEDECODEERROR_EOF 1 #define DPVSIMPLEDECODEERROR_READERROR 2 @@ -16,7 +18,8 @@ // opening and closing streams // opens a stream -void *dpvsimpledecode_open(char *filename, const char **errorstring); +void *dpvsimpledecode_open(clvideo_t *video, char *filename, const char **errorstring); + // closes a stream void dpvsimpledecode_close(void *stream); -- 2.39.2