maked cl_video to have module playback, so several video formats can be implemented...
authorvortex <vortex@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 4 Dec 2010 14:24:55 +0000 (14:24 +0000)
committervortex <vortex@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 4 Dec 2010 14:24:55 +0000 (14:24 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10648 d7cf8633-e32d-0410-b094-e92efae38249

cl_video.c
cl_video.h
dpvsimpledecode.c
dpvsimpledecode.h

index 634e69a..624d784 100644 (file)
@@ -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
index 589a11b..4277124 100644 (file)
@@ -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
index 8ad43be..6ace51c 100644 (file)
@@ -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;
index 075f365..621b001 100644 (file)
@@ -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);