]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
FIX LINEFEEDS :(
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 1 Apr 2012 09:36:32 +0000 (09:36 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 1 Apr 2012 09:36:32 +0000 (09:36 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11776 d7cf8633-e32d-0410-b094-e92efae38249

cl_video_libavw.c

index dc2905fe45f2ac348e58ffad5967f02c61e2439a..206b9c6998ad9c8a4de8faa7940db9f5f74765ee 100644 (file)
-/*\r
-       Libavcodec integration for Darkplaces by Timofeyev Pavel\r
-\r
-       This program is free software; you can redistribute it and/or\r
-       modify it under the terms of the GNU General Public License\r
-       as published by the Free Software Foundation; either version 2\r
-       of the License, or (at your option) any later version.\r
-\r
-       This program is distributed in the hope that it will be useful,\r
-       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
-\r
-       See the GNU General Public License for more details.\r
-\r
-       You should have received a copy of the GNU General Public License\r
-       along with this program; if not, write to:\r
-\r
-               Free Software Foundation, Inc.\r
-               59 Temple Place - Suite 330\r
-               Boston, MA  02111-1307, USA\r
-\r
-*/\r
-\r
-// LordHavoc: for some reason this is being #include'd rather than treated as its own file...\r
-// LordHavoc: adapted to not require stdint.h as this is not available on MSVC++, using unsigned char instead of uint8_t and fs_offset_t instead of int64_t.\r
-\r
-// scaler type\r
-#define LIBAVW_SCALER_BILINEAR  0\r
-#define LIBAVW_SCALER_BICUBIC   1\r
-#define LIBAVW_SCALER_X         2\r
-#define LIBAVW_SCALER_POINT     3\r
-#define LIBAVW_SCALER_AREA      4\r
-#define LIBAVW_SCALER_BICUBLIN  5\r
-#define LIBAVW_SCALER_GAUSS     6\r
-#define LIBAVW_SCALER_SINC      7\r
-#define LIBAVW_SCALER_LANCZOS   8\r
-#define LIBAVW_SCALER_SPLINE    9\r
-// output format\r
-#define LIBAVW_PIXEL_FORMAT_BGR   0\r
-#define LIBAVW_PIXEL_FORMAT_BGRA  1\r
-// print levels\r
-#define LIBAVW_PRINT_WARNING 1\r
-#define LIBAVW_PRINT_ERROR   2\r
-#define LIBAVW_PRINT_FATAL   3\r
-#define LIBAVW_PRINT_PANIC   4\r
-// exported callback functions:\r
-typedef void    avwCallbackPrint(int, const char *);\r
-typedef int     avwCallbackIoRead(void *, unsigned char *, int);\r
-typedef fs_offset_t avwCallbackIoSeek(void *, fs_offset_t, int);\r
-typedef fs_offset_t avwCallbackIoSeekSize(void *);\r
-// exported functions:\r
-int         (*qLibAvW_Init)(avwCallbackPrint *printfunction); // init library, returns error code\r
-const char *(*qLibAvW_ErrorString)(int errorcode); // get string for error code\r
-const char *(*qLibAvW_AvcVersion)(void); // get a string containing libavcodec version wrapper was built for\r
-float       (*qLibAvW_Version)(void); // get wrapper version\r
-int         (*qLibAvW_CreateStream)(void **stream); // create stream, returns error code\r
-void        (*qLibAvW_RemoveStream)(void *stream); // flush and remove stream\r
-int         (*qLibAvW_StreamGetVideoWidth)(void *stream); // get video parameters of stream\r
-int         (*qLibAvW_StreamGetVideoHeight)(void *stream);\r
-double      (*qLibAvW_StreamGetFramerate)(void *stream);\r
-int         (*qLibAvW_StreamGetError)(void *stream); // get last function errorcode from stream\r
-// simple API to play video\r
-int (*qLibAvW_PlayVideo)(void *stream, void *file, avwCallbackIoRead *IoRead, avwCallbackIoSeek *IoSeek, avwCallbackIoSeekSize *IoSeekSize);\r
-int (*qLibAvW_PlaySeekNextFrame)(void *stream);\r
-int (*qLibAvW_PlayGetFrameImage)(void *stream, int pixel_format, void *imagedata, int imagewidth, int imageheight, int scaler);\r
-\r
-static dllfunction_t libavwfuncs[] =\r
-{\r
-       {"LibAvW_Init",                (void **) &qLibAvW_Init },\r
-       {"LibAvW_ErrorString",         (void **) &qLibAvW_ErrorString },\r
-       {"LibAvW_AvcVersion",          (void **) &qLibAvW_AvcVersion },\r
-       {"LibAvW_Version",             (void **) &qLibAvW_Version },\r
-       {"LibAvW_CreateStream",        (void **) &qLibAvW_CreateStream },\r
-       {"LibAvW_RemoveStream",        (void **) &qLibAvW_RemoveStream },\r
-       {"LibAvW_StreamGetVideoWidth", (void **) &qLibAvW_StreamGetVideoWidth },\r
-       {"LibAvW_StreamGetVideoHeight",(void **) &qLibAvW_StreamGetVideoHeight },\r
-       {"LibAvW_StreamGetFramerate",  (void **) &qLibAvW_StreamGetFramerate },\r
-       {"LibAvW_StreamGetError",      (void **) &qLibAvW_StreamGetError },\r
-       {"LibAvW_PlayVideo",           (void **) &qLibAvW_PlayVideo },\r
-       {"LibAvW_PlaySeekNextFrame",   (void **) &qLibAvW_PlaySeekNextFrame },\r
-       {"LibAvW_PlayGetFrameImage",   (void **) &qLibAvW_PlayGetFrameImage },\r
-       {NULL, NULL}\r
-};\r
-\r
-const char* dllnames_libavw[] =\r
-{\r
-#if defined(WIN32)\r
-               "libavw.dll",\r
-#elif defined(MACOSX)\r
-               "libavw.dylib",\r
-#else\r
-               "libavw.so.1",\r
-               "libavw.so",\r
-#endif\r
-               NULL\r
-};\r
-\r
-static dllhandle_t libavw_dll = NULL;\r
-\r
-// DP videostream\r
-typedef struct libavwstream_s\r
-{\r
-       qfile_t     *file;\r
-       double       info_framerate;\r
-       unsigned int info_imagewidth;\r
-       unsigned int info_imageheight;\r
-       double       info_aspectratio;\r
-       void        *stream;\r
-\r
-       // channel the sound file is being played on\r
-       sfx_t *sfx;\r
-       int    sndchan;\r
-       int    sndstarted;\r
-}\r
-libavwstream_t;\r
-\r
-cvar_t cl_video_libavw_minwidth  = {CVAR_SAVE, "cl_video_libavw_minwidth", "0", "if videos width is lesser than minimal, thay will be upscaled"};\r
-cvar_t cl_video_libavw_minheight = {CVAR_SAVE, "cl_video_libavw_minheight", "0", "if videos height is lesser than minimal, thay will be upscaled"};\r
-cvar_t cl_video_libavw_scaler    = {CVAR_SAVE, "cl_video_libavw_scaler", "1", "selects a scaler for libavcode played videos. Scalers are: 0 - bilinear, 1 - bicubic, 2 - x, 3 - point, 4 - area, 5 - bicublin, 6 - gauss, 7 - sinc, 8 - lanczos, 9 - spline."};\r
-\r
-// video extensions\r
-const char* libavw_extensions[] =\r
-{\r
-       "ogv",\r
-       "avi",\r
-       "mpg",\r
-       "mp4",\r
-       "mkv",\r
-       "webm",\r
-       "bik",\r
-       "roq",\r
-       "flv",\r
-       "wmv",\r
-       "mpeg",\r
-       "mjpeg",\r
-       "mpeg4",\r
-       NULL\r
-};\r
-\r
-/*\r
-=================================================================\r
-\r
-  Video decoding\r
-  a features that is not supported yet and likely to be done\r
-  - streaming audio from videofiles\r
-  - streaming subtitles\r
-\r
-=================================================================\r
-*/\r
-\r
-unsigned int libavw_getwidth(void *stream);\r
-unsigned int libavw_getheight(void *stream);\r
-double libavw_getframerate(void *stream);\r
-double libavw_getaspectratio(void *stream);\r
-void libavw_close(void *stream);\r
-\r
-static int libavw_decodeframe(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow)\r
-{\r
-       int pixel_format = LIBAVW_PIXEL_FORMAT_BGR;\r
-       int errorcode;\r
-\r
-       libavwstream_t *s = (libavwstream_t *)stream;\r
-\r
-       // start sound\r
-       if (!s->sndstarted)\r
-       {\r
-               if (s->sfx != NULL)\r
-                       s->sndchan = S_StartSound(-1, 0, s->sfx, vec3_origin, 1.0f, 0);\r
-               s->sndstarted = 1;\r
-       }\r
-\r
-       // read frame\r
-       if (!qLibAvW_PlaySeekNextFrame(s->stream))\r
-       {\r
-               // got error or file end\r
-               errorcode = qLibAvW_StreamGetError(s->stream);\r
-               if (errorcode)\r
-                       Con_Printf("LibAvW: %s\n", qLibAvW_ErrorString(errorcode));\r
-               return 1;\r
-       }\r
-\r
-       // decode into bgr texture\r
-       if (bytesperpixel == 4)\r
-               pixel_format = LIBAVW_PIXEL_FORMAT_BGRA;\r
-       else if (bytesperpixel == 3)\r
-               pixel_format = LIBAVW_PIXEL_FORMAT_BGR;\r
-       else\r
-       {\r
-               Con_Printf("LibAvW: cannot determine pixel format for bpp %i\n", bytesperpixel);\r
-               return 1;\r
-       }\r
-       if (!qLibAvW_PlayGetFrameImage(s->stream, pixel_format, imagedata, s->info_imagewidth, s->info_imageheight, min(9, max(0, cl_video_libavw_scaler.integer))))\r
-               Con_Printf("LibAvW: %s\n", qLibAvW_ErrorString(qLibAvW_StreamGetError(s->stream)));\r
-       return 0;\r
-}\r
-\r
-// get stream info\r
-unsigned int libavw_getwidth(void *stream)\r
-{\r
-       return ((libavwstream_t *)stream)->info_imagewidth;\r
-}\r
-\r
-unsigned int libavw_getheight(void *stream)\r
-{\r
-       return ((libavwstream_t *)stream)->info_imageheight;\r
-}\r
-\r
-double libavw_getframerate(void *stream)\r
-{\r
-       return ((libavwstream_t *)stream)->info_framerate;\r
-}\r
-\r
-double libavw_getaspectratio(void *stream)\r
-{\r
-       return ((libavwstream_t *)stream)->info_aspectratio;\r
-}\r
-\r
-// close stream\r
-void libavw_close(void *stream)\r
-{\r
-       libavwstream_t *s = (libavwstream_t *)stream;\r
-\r
-       if (s->stream)\r
-               qLibAvW_RemoveStream(s->stream);\r
-       s->stream = NULL;\r
-       if (s->file)\r
-               FS_Close(s->file);\r
-       s->file = NULL;\r
-       if (s->sndchan >= 0)\r
-               S_StopChannel(s->sndchan, true, true);\r
-       s->sndchan = -1;\r
-}\r
-\r
-// IO wrapper\r
-static int LibAvW_FS_Read(void *opaque, unsigned char *buf, int buf_size)\r
-{\r
-       return FS_Read((qfile_t *)opaque, buf, buf_size);\r
-}\r
-static fs_offset_t LibAvW_FS_Seek(void *opaque, fs_offset_t pos, int whence)\r
-{\r
-       return (fs_offset_t)FS_Seek((qfile_t *)opaque, pos, whence);\r
-}\r
-static fs_offset_t LibAvW_FS_SeekSize(void *opaque)\r
-{\r
-       return (fs_offset_t)FS_FileSize((qfile_t *)opaque);\r
-}\r
-\r
-// open as DP video stream\r
-static void *LibAvW_OpenVideo(clvideo_t *video, char *filename, const char **errorstring)\r
-{\r
-       libavwstream_t *s;\r
-       char filebase[MAX_OSPATH], check[MAX_OSPATH];\r
-       unsigned int i;\r
-       int errorcode;\r
-       char *wavename;\r
-       size_t len;\r
-\r
-       if (!libavw_dll)\r
-               return NULL;\r
-\r
-       // allocate stream\r
-       s = (libavwstream_t *)Z_Malloc(sizeof(libavwstream_t));\r
-       s->sndchan = -1;\r
-       memset(s, 0, sizeof(libavwstream_t));\r
-       if (s == NULL)\r
-       {\r
-               *errorstring = "unable to allocate memory for stream info structure";\r
-               return NULL;\r
-       }\r
-\r
-       // open file\r
-       s->file = FS_OpenVirtualFile(filename, true);\r
-       if (!s->file)\r
-       {\r
-               FS_StripExtension(filename, filebase, sizeof(filebase));\r
-               // we tried .dpv, try another extensions\r
-               for (i = 0; libavw_extensions[i] != NULL; i++)\r
-               {\r
-                       dpsnprintf(check, sizeof(check), "%s.%s", filebase, libavw_extensions[i]);\r
-                       s->file = FS_OpenVirtualFile(check, true);\r
-                       if (s->file)\r
-                               break;\r
-               }\r
-               if (!s->file)\r
-               {\r
-                       *errorstring = "unable to open videofile";\r
-                       libavw_close(s);\r
-                       Z_Free(s);\r
-                        return NULL;\r
-               }\r
-       }\r
-\r
-       // allocate libavw stream\r
-       if ((errorcode = qLibAvW_CreateStream(&s->stream)))\r
-       {\r
-               *errorstring = qLibAvW_ErrorString(errorcode);\r
-               libavw_close(s);\r
-               Z_Free(s);\r
-        return NULL;\r
-       }\r
-\r
-       // open video for playing\r
-       if (!qLibAvW_PlayVideo(s->stream, s->file, &LibAvW_FS_Read, &LibAvW_FS_Seek, &LibAvW_FS_SeekSize))\r
-       {\r
-               *errorstring = qLibAvW_ErrorString(qLibAvW_StreamGetError(s->stream));\r
-               libavw_close(s);\r
-               Z_Free(s);\r
-        return NULL;\r
-       }\r
-\r
-       // all right, start codec\r
-       s->info_imagewidth = qLibAvW_StreamGetVideoWidth(s->stream);\r
-       s->info_imageheight = qLibAvW_StreamGetVideoHeight(s->stream);\r
-       s->info_framerate = qLibAvW_StreamGetFramerate(s->stream);\r
-       s->info_aspectratio = (double)s->info_imagewidth / (double)s->info_imageheight;\r
-       video->close = libavw_close;\r
-       video->getwidth = libavw_getwidth;\r
-       video->getheight = libavw_getheight;\r
-       video->getframerate = libavw_getframerate;\r
-       video->decodeframe = libavw_decodeframe;\r
-       video->getaspectratio = libavw_getaspectratio;\r
-\r
-       // apply min-width, min-height, keep aspect rate\r
-       if (cl_video_libavw_minwidth.integer > 0)\r
-               s->info_imagewidth = max(s->info_imagewidth, (unsigned int)cl_video_libavw_minwidth.integer);\r
-       if (cl_video_libavw_minheight.integer > 0)\r
-               s->info_imageheight = max(s->info_imageheight, (unsigned int)cl_video_libavw_minheight.integer);\r
-       \r
-       // provide sound in separate .wav\r
-       len = strlen(filename) + 10;\r
-       wavename = (char *)Z_Malloc(len);\r
-       if (wavename)\r
-       {\r
-               FS_StripExtension(filename, wavename, len-1);\r
-               strlcat(wavename, ".wav", len);\r
-               s->sfx = S_PrecacheSound(wavename, false, false);\r
-               s->sndchan = -1;\r
-               Z_Free(wavename);\r
-       }\r
-       return s;\r
-}\r
-\r
-static void libavw_message(int level, const char *message)\r
-{\r
-       if (level == LIBAVW_PRINT_WARNING)\r
-               Con_Printf("LibAvcodec warning: %s\n", message);\r
-       else if (level == LIBAVW_PRINT_ERROR)\r
-               Con_Printf("LibAvcodec error: %s\n", message);\r
-       else if (level == LIBAVW_PRINT_FATAL)\r
-               Con_Printf("LibAvcodec fatal error: %s\n", message);\r
-       else\r
-               Con_Printf("LibAvcodec panic: %s\n", message);\r
-}\r
-\r
-static qboolean LibAvW_OpenLibrary(void)\r
-{\r
-       int errorcode;\r
-\r
-       // COMMANDLINEOPTION: Video: -nolibavw disables libavcodec wrapper support\r
-       if (COM_CheckParm("-nolibavw"))\r
-               return false;\r
-\r
-       // load DLL's\r
-       Sys_LoadLibrary(dllnames_libavw, &libavw_dll, libavwfuncs);\r
-       if (!libavw_dll)\r
-               return false;\r
-\r
-       // initialize libav wrapper\r
-       if ((errorcode = qLibAvW_Init(&libavw_message)))\r
-       {\r
-               Con_Printf("LibAvW failed to initialize: %s\n", qLibAvW_ErrorString(errorcode));\r
-               Sys_UnloadLibrary(&libavw_dll);\r
-       }\r
-\r
-       Cvar_RegisterVariable(&cl_video_libavw_minwidth);\r
-       Cvar_RegisterVariable(&cl_video_libavw_minheight);\r
-       Cvar_RegisterVariable(&cl_video_libavw_scaler);\r
-\r
-       return true;\r
-}\r
-\r
-static void LibAvW_CloseLibrary(void)\r
-{\r
-       Sys_UnloadLibrary(&libavw_dll);\r
-}\r
-\r
+/*
+       Libavcodec integration for Darkplaces by Timofeyev Pavel
+
+       This program is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 2
+       of the License, or (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+       See the GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to:
+
+               Free Software Foundation, Inc.
+               59 Temple Place - Suite 330
+               Boston, MA  02111-1307, USA
+
+*/
+
+// LordHavoc: for some reason this is being #include'd rather than treated as its own file...
+// LordHavoc: adapted to not require stdint.h as this is not available on MSVC++, using unsigned char instead of uint8_t and fs_offset_t instead of int64_t.
+
+// scaler type
+#define LIBAVW_SCALER_BILINEAR  0
+#define LIBAVW_SCALER_BICUBIC   1
+#define LIBAVW_SCALER_X         2
+#define LIBAVW_SCALER_POINT     3
+#define LIBAVW_SCALER_AREA      4
+#define LIBAVW_SCALER_BICUBLIN  5
+#define LIBAVW_SCALER_GAUSS     6
+#define LIBAVW_SCALER_SINC      7
+#define LIBAVW_SCALER_LANCZOS   8
+#define LIBAVW_SCALER_SPLINE    9
+// output format
+#define LIBAVW_PIXEL_FORMAT_BGR   0
+#define LIBAVW_PIXEL_FORMAT_BGRA  1
+// print levels
+#define LIBAVW_PRINT_WARNING 1
+#define LIBAVW_PRINT_ERROR   2
+#define LIBAVW_PRINT_FATAL   3
+#define LIBAVW_PRINT_PANIC   4
+// exported callback functions:
+typedef void    avwCallbackPrint(int, const char *);
+typedef int     avwCallbackIoRead(void *, unsigned char *, int);
+typedef fs_offset_t avwCallbackIoSeek(void *, fs_offset_t, int);
+typedef fs_offset_t avwCallbackIoSeekSize(void *);
+// exported functions:
+int         (*qLibAvW_Init)(avwCallbackPrint *printfunction); // init library, returns error code
+const char *(*qLibAvW_ErrorString)(int errorcode); // get string for error code
+const char *(*qLibAvW_AvcVersion)(void); // get a string containing libavcodec version wrapper was built for
+float       (*qLibAvW_Version)(void); // get wrapper version
+int         (*qLibAvW_CreateStream)(void **stream); // create stream, returns error code
+void        (*qLibAvW_RemoveStream)(void *stream); // flush and remove stream
+int         (*qLibAvW_StreamGetVideoWidth)(void *stream); // get video parameters of stream
+int         (*qLibAvW_StreamGetVideoHeight)(void *stream);
+double      (*qLibAvW_StreamGetFramerate)(void *stream);
+int         (*qLibAvW_StreamGetError)(void *stream); // get last function errorcode from stream
+// simple API to play video
+int (*qLibAvW_PlayVideo)(void *stream, void *file, avwCallbackIoRead *IoRead, avwCallbackIoSeek *IoSeek, avwCallbackIoSeekSize *IoSeekSize);
+int (*qLibAvW_PlaySeekNextFrame)(void *stream);
+int (*qLibAvW_PlayGetFrameImage)(void *stream, int pixel_format, void *imagedata, int imagewidth, int imageheight, int scaler);
+
+static dllfunction_t libavwfuncs[] =
+{
+       {"LibAvW_Init",                (void **) &qLibAvW_Init },
+       {"LibAvW_ErrorString",         (void **) &qLibAvW_ErrorString },
+       {"LibAvW_AvcVersion",          (void **) &qLibAvW_AvcVersion },
+       {"LibAvW_Version",             (void **) &qLibAvW_Version },
+       {"LibAvW_CreateStream",        (void **) &qLibAvW_CreateStream },
+       {"LibAvW_RemoveStream",        (void **) &qLibAvW_RemoveStream },
+       {"LibAvW_StreamGetVideoWidth", (void **) &qLibAvW_StreamGetVideoWidth },
+       {"LibAvW_StreamGetVideoHeight",(void **) &qLibAvW_StreamGetVideoHeight },
+       {"LibAvW_StreamGetFramerate",  (void **) &qLibAvW_StreamGetFramerate },
+       {"LibAvW_StreamGetError",      (void **) &qLibAvW_StreamGetError },
+       {"LibAvW_PlayVideo",           (void **) &qLibAvW_PlayVideo },
+       {"LibAvW_PlaySeekNextFrame",   (void **) &qLibAvW_PlaySeekNextFrame },
+       {"LibAvW_PlayGetFrameImage",   (void **) &qLibAvW_PlayGetFrameImage },
+       {NULL, NULL}
+};
+
+const char* dllnames_libavw[] =
+{
+#if defined(WIN32)
+               "libavw.dll",
+#elif defined(MACOSX)
+               "libavw.dylib",
+#else
+               "libavw.so.1",
+               "libavw.so",
+#endif
+               NULL
+};
+
+static dllhandle_t libavw_dll = NULL;
+
+// DP videostream
+typedef struct libavwstream_s
+{
+       qfile_t     *file;
+       double       info_framerate;
+       unsigned int info_imagewidth;
+       unsigned int info_imageheight;
+       double       info_aspectratio;
+       void        *stream;
+
+       // channel the sound file is being played on
+       sfx_t *sfx;
+       int    sndchan;
+       int    sndstarted;
+}
+libavwstream_t;
+
+cvar_t cl_video_libavw_minwidth  = {CVAR_SAVE, "cl_video_libavw_minwidth", "0", "if videos width is lesser than minimal, thay will be upscaled"};
+cvar_t cl_video_libavw_minheight = {CVAR_SAVE, "cl_video_libavw_minheight", "0", "if videos height is lesser than minimal, thay will be upscaled"};
+cvar_t cl_video_libavw_scaler    = {CVAR_SAVE, "cl_video_libavw_scaler", "1", "selects a scaler for libavcode played videos. Scalers are: 0 - bilinear, 1 - bicubic, 2 - x, 3 - point, 4 - area, 5 - bicublin, 6 - gauss, 7 - sinc, 8 - lanczos, 9 - spline."};
+
+// video extensions
+const char* libavw_extensions[] =
+{
+       "ogv",
+       "avi",
+       "mpg",
+       "mp4",
+       "mkv",
+       "webm",
+       "bik",
+       "roq",
+       "flv",
+       "wmv",
+       "mpeg",
+       "mjpeg",
+       "mpeg4",
+       NULL
+};
+
+/*
+=================================================================
+
+  Video decoding
+  a features that is not supported yet and likely to be done
+  - streaming audio from videofiles
+  - streaming subtitles
+
+=================================================================
+*/
+
+unsigned int libavw_getwidth(void *stream);
+unsigned int libavw_getheight(void *stream);
+double libavw_getframerate(void *stream);
+double libavw_getaspectratio(void *stream);
+void libavw_close(void *stream);
+
+static int libavw_decodeframe(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow)
+{
+       int pixel_format = LIBAVW_PIXEL_FORMAT_BGR;
+       int errorcode;
+
+       libavwstream_t *s = (libavwstream_t *)stream;
+
+       // start sound
+       if (!s->sndstarted)
+       {
+               if (s->sfx != NULL)
+                       s->sndchan = S_StartSound(-1, 0, s->sfx, vec3_origin, 1.0f, 0);
+               s->sndstarted = 1;
+       }
+
+       // read frame
+       if (!qLibAvW_PlaySeekNextFrame(s->stream))
+       {
+               // got error or file end
+               errorcode = qLibAvW_StreamGetError(s->stream);
+               if (errorcode)
+                       Con_Printf("LibAvW: %s\n", qLibAvW_ErrorString(errorcode));
+               return 1;
+       }
+
+       // decode into bgr texture
+       if (bytesperpixel == 4)
+               pixel_format = LIBAVW_PIXEL_FORMAT_BGRA;
+       else if (bytesperpixel == 3)
+               pixel_format = LIBAVW_PIXEL_FORMAT_BGR;
+       else
+       {
+               Con_Printf("LibAvW: cannot determine pixel format for bpp %i\n", bytesperpixel);
+               return 1;
+       }
+       if (!qLibAvW_PlayGetFrameImage(s->stream, pixel_format, imagedata, s->info_imagewidth, s->info_imageheight, min(9, max(0, cl_video_libavw_scaler.integer))))
+               Con_Printf("LibAvW: %s\n", qLibAvW_ErrorString(qLibAvW_StreamGetError(s->stream)));
+       return 0;
+}
+
+// get stream info
+unsigned int libavw_getwidth(void *stream)
+{
+       return ((libavwstream_t *)stream)->info_imagewidth;
+}
+
+unsigned int libavw_getheight(void *stream)
+{
+       return ((libavwstream_t *)stream)->info_imageheight;
+}
+
+double libavw_getframerate(void *stream)
+{
+       return ((libavwstream_t *)stream)->info_framerate;
+}
+
+double libavw_getaspectratio(void *stream)
+{
+       return ((libavwstream_t *)stream)->info_aspectratio;
+}
+
+// close stream
+void libavw_close(void *stream)
+{
+       libavwstream_t *s = (libavwstream_t *)stream;
+
+       if (s->stream)
+               qLibAvW_RemoveStream(s->stream);
+       s->stream = NULL;
+       if (s->file)
+               FS_Close(s->file);
+       s->file = NULL;
+       if (s->sndchan >= 0)
+               S_StopChannel(s->sndchan, true, true);
+       s->sndchan = -1;
+}
+
+// IO wrapper
+static int LibAvW_FS_Read(void *opaque, unsigned char *buf, int buf_size)
+{
+       return FS_Read((qfile_t *)opaque, buf, buf_size);
+}
+static fs_offset_t LibAvW_FS_Seek(void *opaque, fs_offset_t pos, int whence)
+{
+       return (fs_offset_t)FS_Seek((qfile_t *)opaque, pos, whence);
+}
+static fs_offset_t LibAvW_FS_SeekSize(void *opaque)
+{
+       return (fs_offset_t)FS_FileSize((qfile_t *)opaque);
+}
+
+// open as DP video stream
+static void *LibAvW_OpenVideo(clvideo_t *video, char *filename, const char **errorstring)
+{
+       libavwstream_t *s;
+       char filebase[MAX_OSPATH], check[MAX_OSPATH];
+       unsigned int i;
+       int errorcode;
+       char *wavename;
+       size_t len;
+
+       if (!libavw_dll)
+               return NULL;
+
+       // allocate stream
+       s = (libavwstream_t *)Z_Malloc(sizeof(libavwstream_t));
+       s->sndchan = -1;
+       memset(s, 0, sizeof(libavwstream_t));
+       if (s == NULL)
+       {
+               *errorstring = "unable to allocate memory for stream info structure";
+               return NULL;
+       }
+
+       // open file
+       s->file = FS_OpenVirtualFile(filename, true);
+       if (!s->file)
+       {
+               FS_StripExtension(filename, filebase, sizeof(filebase));
+               // we tried .dpv, try another extensions
+               for (i = 0; libavw_extensions[i] != NULL; i++)
+               {
+                       dpsnprintf(check, sizeof(check), "%s.%s", filebase, libavw_extensions[i]);
+                       s->file = FS_OpenVirtualFile(check, true);
+                       if (s->file)
+                               break;
+               }
+               if (!s->file)
+               {
+                       *errorstring = "unable to open videofile";
+                       libavw_close(s);
+                       Z_Free(s);
+                        return NULL;
+               }
+       }
+
+       // allocate libavw stream
+       if ((errorcode = qLibAvW_CreateStream(&s->stream)))
+       {
+               *errorstring = qLibAvW_ErrorString(errorcode);
+               libavw_close(s);
+               Z_Free(s);
+        return NULL;
+       }
+
+       // open video for playing
+       if (!qLibAvW_PlayVideo(s->stream, s->file, &LibAvW_FS_Read, &LibAvW_FS_Seek, &LibAvW_FS_SeekSize))
+       {
+               *errorstring = qLibAvW_ErrorString(qLibAvW_StreamGetError(s->stream));
+               libavw_close(s);
+               Z_Free(s);
+        return NULL;
+       }
+
+       // all right, start codec
+       s->info_imagewidth = qLibAvW_StreamGetVideoWidth(s->stream);
+       s->info_imageheight = qLibAvW_StreamGetVideoHeight(s->stream);
+       s->info_framerate = qLibAvW_StreamGetFramerate(s->stream);
+       s->info_aspectratio = (double)s->info_imagewidth / (double)s->info_imageheight;
+       video->close = libavw_close;
+       video->getwidth = libavw_getwidth;
+       video->getheight = libavw_getheight;
+       video->getframerate = libavw_getframerate;
+       video->decodeframe = libavw_decodeframe;
+       video->getaspectratio = libavw_getaspectratio;
+
+       // apply min-width, min-height, keep aspect rate
+       if (cl_video_libavw_minwidth.integer > 0)
+               s->info_imagewidth = max(s->info_imagewidth, (unsigned int)cl_video_libavw_minwidth.integer);
+       if (cl_video_libavw_minheight.integer > 0)
+               s->info_imageheight = max(s->info_imageheight, (unsigned int)cl_video_libavw_minheight.integer);
+       
+       // provide sound in separate .wav
+       len = strlen(filename) + 10;
+       wavename = (char *)Z_Malloc(len);
+       if (wavename)
+       {
+               FS_StripExtension(filename, wavename, len-1);
+               strlcat(wavename, ".wav", len);
+               s->sfx = S_PrecacheSound(wavename, false, false);
+               s->sndchan = -1;
+               Z_Free(wavename);
+       }
+       return s;
+}
+
+static void libavw_message(int level, const char *message)
+{
+       if (level == LIBAVW_PRINT_WARNING)
+               Con_Printf("LibAvcodec warning: %s\n", message);
+       else if (level == LIBAVW_PRINT_ERROR)
+               Con_Printf("LibAvcodec error: %s\n", message);
+       else if (level == LIBAVW_PRINT_FATAL)
+               Con_Printf("LibAvcodec fatal error: %s\n", message);
+       else
+               Con_Printf("LibAvcodec panic: %s\n", message);
+}
+
+static qboolean LibAvW_OpenLibrary(void)
+{
+       int errorcode;
+
+       // COMMANDLINEOPTION: Video: -nolibavw disables libavcodec wrapper support
+       if (COM_CheckParm("-nolibavw"))
+               return false;
+
+       // load DLL's
+       Sys_LoadLibrary(dllnames_libavw, &libavw_dll, libavwfuncs);
+       if (!libavw_dll)
+               return false;
+
+       // initialize libav wrapper
+       if ((errorcode = qLibAvW_Init(&libavw_message)))
+       {
+               Con_Printf("LibAvW failed to initialize: %s\n", qLibAvW_ErrorString(errorcode));
+               Sys_UnloadLibrary(&libavw_dll);
+       }
+
+       Cvar_RegisterVariable(&cl_video_libavw_minwidth);
+       Cvar_RegisterVariable(&cl_video_libavw_minheight);
+       Cvar_RegisterVariable(&cl_video_libavw_scaler);
+
+       return true;
+}
+
+static void LibAvW_CloseLibrary(void)
+{
+       Sys_UnloadLibrary(&libavw_dll);
+}
+