Decoder interface additions and changes
in preparation for the upcoming CDP architecture -- support for registering external decoders; DukVid file IO changed from resX to uio git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1280 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -20,28 +20,33 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "libs/sndlib.h"
|
|
||||||
#include "libs/sound/sound.h"
|
|
||||||
#include "dukvid.h"
|
#include "dukvid.h"
|
||||||
#include "endian_uqm.h"
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "libs/uio.h"
|
||||||
|
#include "endian_uqm.h"
|
||||||
|
|
||||||
#define THIS_PTR TFB_VideoDecoder* This
|
#define THIS_PTR TFB_VideoDecoder* This
|
||||||
|
|
||||||
uint32 dukv_GetStructSize (void);
|
static const char* dukv_GetName (void);
|
||||||
int dukv_GetError (THIS_PTR);
|
static bool dukv_InitModule (int flags);
|
||||||
bool dukv_Init (THIS_PTR, TFB_PixelFormat* fmt);
|
static void dukv_TermModule (void);
|
||||||
void dukv_Term (THIS_PTR);
|
static uint32 dukv_GetStructSize (void);
|
||||||
bool dukv_Open (THIS_PTR, uio_DirHandle *dir, const char *filename);
|
static int dukv_GetError (THIS_PTR);
|
||||||
void dukv_Close (THIS_PTR);
|
static bool dukv_Init (THIS_PTR, TFB_PixelFormat* fmt);
|
||||||
int dukv_DecodeNext (THIS_PTR);
|
static void dukv_Term (THIS_PTR);
|
||||||
uint32 dukv_SeekFrame (THIS_PTR, uint32 frame);
|
static bool dukv_Open (THIS_PTR, uio_DirHandle *dir, const char *filename);
|
||||||
float dukv_SeekTime (THIS_PTR, float time);
|
static void dukv_Close (THIS_PTR);
|
||||||
uint32 dukv_GetFrame (THIS_PTR);
|
static int dukv_DecodeNext (THIS_PTR);
|
||||||
float dukv_GetTime (THIS_PTR);
|
static uint32 dukv_SeekFrame (THIS_PTR, uint32 frame);
|
||||||
|
static float dukv_SeekTime (THIS_PTR, float time);
|
||||||
|
static uint32 dukv_GetFrame (THIS_PTR);
|
||||||
|
static float dukv_GetTime (THIS_PTR);
|
||||||
|
|
||||||
TFB_VideoDecoderFuncs dukv_DecoderVtbl =
|
TFB_VideoDecoderFuncs dukv_DecoderVtbl =
|
||||||
{
|
{
|
||||||
|
dukv_GetName,
|
||||||
|
dukv_InitModule,
|
||||||
|
dukv_TermModule,
|
||||||
dukv_GetStructSize,
|
dukv_GetStructSize,
|
||||||
dukv_GetError,
|
dukv_GetError,
|
||||||
dukv_Init,
|
dukv_Init,
|
||||||
@@ -107,7 +112,7 @@ typedef struct tfb_duckvideodecoder
|
|||||||
#define DUCK_MAX_FRAME_SIZE 0x8000U
|
#define DUCK_MAX_FRAME_SIZE 0x8000U
|
||||||
#define DUCK_END_OF_SEQUENCE 1
|
#define DUCK_END_OF_SEQUENCE 1
|
||||||
|
|
||||||
void
|
static void
|
||||||
dukv_DecodeFrame (uint8* src_p, uint32* dst_p, uint32 wb, uint32 hb,
|
dukv_DecodeFrame (uint8* src_p, uint32* dst_p, uint32 wb, uint32 hb,
|
||||||
TFB_DuckVideoDeltas* deltas)
|
TFB_DuckVideoDeltas* deltas)
|
||||||
{
|
{
|
||||||
@@ -205,7 +210,7 @@ dukv_DecodeFrame (uint8* src_p, uint32* dst_p, uint32 wb, uint32 hb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
dukv_DecodeFrameV3 (uint8* src_p, uint32* dst_p, uint32 wb, uint32 hb,
|
dukv_DecodeFrameV3 (uint8* src_p, uint32* dst_p, uint32 wb, uint32 hb,
|
||||||
TFB_DuckVideoDeltas* deltas)
|
TFB_DuckVideoDeltas* deltas)
|
||||||
{
|
{
|
||||||
@@ -270,7 +275,7 @@ dukv_DecodeFrameV3 (uint8* src_p, uint32* dst_p, uint32 wb, uint32 hb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
dukv_OpenStream (TFB_DuckVideoDecoder* dukv)
|
dukv_OpenStream (TFB_DuckVideoDecoder* dukv)
|
||||||
{
|
{
|
||||||
char filename[280];
|
char filename[280];
|
||||||
@@ -278,10 +283,10 @@ dukv_OpenStream (TFB_DuckVideoDecoder* dukv)
|
|||||||
strcat (strcpy (filename, dukv->basename), ".duk");
|
strcat (strcpy (filename, dukv->basename), ".duk");
|
||||||
|
|
||||||
return (dukv->stream =
|
return (dukv->stream =
|
||||||
res_OpenResFile (dukv->basedir, filename, "rb")) != NULL;
|
uio_fopen (dukv->basedir, filename, "rb")) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
dukv_ReadFrames (TFB_DuckVideoDecoder* dukv)
|
dukv_ReadFrames (TFB_DuckVideoDecoder* dukv)
|
||||||
{
|
{
|
||||||
char filename[280];
|
char filename[280];
|
||||||
@@ -290,20 +295,23 @@ dukv_ReadFrames (TFB_DuckVideoDecoder* dukv)
|
|||||||
|
|
||||||
strcat (strcpy (filename, dukv->basename), ".frm");
|
strcat (strcpy (filename, dukv->basename), ".frm");
|
||||||
|
|
||||||
if (!(fp = res_OpenResFile (dukv->basedir, filename, "rb")))
|
if (!(fp = uio_fopen (dukv->basedir, filename, "rb")))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
dukv->cframes = LengthResFile (fp) / sizeof (uint32);
|
// get number of frames
|
||||||
|
uio_fseek (fp, 0, SEEK_END);
|
||||||
|
dukv->cframes = uio_ftell (fp) / sizeof (uint32);
|
||||||
|
uio_fseek (fp, 0, SEEK_SET);
|
||||||
dukv->frames = (uint32*) HMalloc (dukv->cframes * sizeof (uint32));
|
dukv->frames = (uint32*) HMalloc (dukv->cframes * sizeof (uint32));
|
||||||
|
|
||||||
if ((uint32)ReadResFile (dukv->frames, sizeof (uint32), dukv->cframes,
|
if (uio_fread (dukv->frames, sizeof (uint32), dukv->cframes,
|
||||||
fp) != dukv->cframes)
|
fp) != dukv->cframes)
|
||||||
{
|
{
|
||||||
HFree (dukv->frames);
|
HFree (dukv->frames);
|
||||||
dukv->frames = 0;
|
dukv->frames = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
res_CloseResFile (fp);
|
uio_fclose (fp);
|
||||||
|
|
||||||
for (i = 0; i < dukv->cframes; ++i)
|
for (i = 0; i < dukv->cframes; ++i)
|
||||||
dukv->frames[i] = UQM_SwapBE32 (dukv->frames[i]);
|
dukv->frames[i] = UQM_SwapBE32 (dukv->frames[i]);
|
||||||
@@ -311,7 +319,7 @@ dukv_ReadFrames (TFB_DuckVideoDecoder* dukv)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
dukv_ReadVectors (TFB_DuckVideoDecoder* dukv, uint8* vectors)
|
dukv_ReadVectors (TFB_DuckVideoDecoder* dukv, uint8* vectors)
|
||||||
{
|
{
|
||||||
uio_Stream *fp;
|
uio_Stream *fp;
|
||||||
@@ -320,16 +328,16 @@ dukv_ReadVectors (TFB_DuckVideoDecoder* dukv, uint8* vectors)
|
|||||||
|
|
||||||
strcat (strcpy (filename, dukv->basename), ".tbl");
|
strcat (strcpy (filename, dukv->basename), ".tbl");
|
||||||
|
|
||||||
if (!(fp = res_OpenResFile (dukv->basedir, filename, "rb")))
|
if (!(fp = uio_fopen (dukv->basedir, filename, "rb")))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ret = ReadResFile (vectors, NUM_VEC_ITEMS * NUM_VECTORS, 1, fp);
|
ret = uio_fread (vectors, NUM_VEC_ITEMS, NUM_VECTORS, fp);
|
||||||
res_CloseResFile (fp);
|
uio_fclose (fp);
|
||||||
|
|
||||||
return ret;
|
return ret == NUM_VECTORS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
dukv_ReadHeader (TFB_DuckVideoDecoder* dukv, sint32* pl, sint32* pc)
|
dukv_ReadHeader (TFB_DuckVideoDecoder* dukv, sint32* pl, sint32* pc)
|
||||||
{
|
{
|
||||||
uio_Stream *fp;
|
uio_Stream *fp;
|
||||||
@@ -340,11 +348,11 @@ dukv_ReadHeader (TFB_DuckVideoDecoder* dukv, sint32* pl, sint32* pc)
|
|||||||
|
|
||||||
strcat (strcpy (filename, dukv->basename), ".hdr");
|
strcat (strcpy (filename, dukv->basename), ".hdr");
|
||||||
|
|
||||||
if (!(fp = res_OpenResFile (dukv->basedir, filename, "rb")))
|
if (!(fp = uio_fopen (dukv->basedir, filename, "rb")))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ret = ReadResFile (&hdr, sizeof (hdr), 1, fp);
|
ret = uio_fread (&hdr, sizeof (hdr), 1, fp);
|
||||||
res_CloseResFile (fp);
|
uio_fclose (fp);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -364,7 +372,7 @@ dukv_ReadHeader (TFB_DuckVideoDecoder* dukv, sint32* pl, sint32* pc)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sint32
|
static sint32
|
||||||
dukv_make_delta (sint32* protos, bool is_chroma, int i1, int i2)
|
dukv_make_delta (sint32* protos, bool is_chroma, int i1, int i2)
|
||||||
{
|
{
|
||||||
sint32 d1, d2;
|
sint32 d1, d2;
|
||||||
@@ -383,7 +391,7 @@ dukv_make_delta (sint32* protos, bool is_chroma, int i1, int i2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sint32
|
static sint32
|
||||||
dukv_make_corr (sint32* protos, bool is_chroma, int i1, int i2)
|
dukv_make_corr (sint32* protos, bool is_chroma, int i1, int i2)
|
||||||
{
|
{
|
||||||
sint32 d1, d2;
|
sint32 d1, d2;
|
||||||
@@ -400,7 +408,7 @@ dukv_make_corr (sint32* protos, bool is_chroma, int i1, int i2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
dukv_DecodeVector (uint8* vec, sint32* p, bool is_chroma, sint32* deltas)
|
dukv_DecodeVector (uint8* vec, sint32* p, bool is_chroma, sint32* deltas)
|
||||||
{
|
{
|
||||||
int citems = vec[0];
|
int citems = vec[0];
|
||||||
@@ -419,7 +427,7 @@ dukv_DecodeVector (uint8* vec, sint32* p, bool is_chroma, sint32* deltas)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
dukv_InitDeltas (TFB_DuckVideoDecoder* dukv, uint8* vectors,
|
dukv_InitDeltas (TFB_DuckVideoDecoder* dukv, uint8* vectors,
|
||||||
sint32* pl, sint32* pc)
|
sint32* pl, sint32* pc)
|
||||||
{
|
{
|
||||||
@@ -433,7 +441,7 @@ dukv_InitDeltas (TFB_DuckVideoDecoder* dukv, uint8* vectors,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__inline__ uint32
|
static __inline__ uint32
|
||||||
dukv_PixelConv (uint16 pix, const TFB_PixelFormat* fmt)
|
dukv_PixelConv (uint16 pix, const TFB_PixelFormat* fmt)
|
||||||
{
|
{
|
||||||
uint32 r, g, b;
|
uint32 r, g, b;
|
||||||
@@ -448,7 +456,7 @@ dukv_PixelConv (uint16 pix, const TFB_PixelFormat* fmt)
|
|||||||
((b >> fmt->Bloss) << fmt->Bshift);
|
((b >> fmt->Bloss) << fmt->Bshift);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
dukv_RenderFrame (THIS_PTR)
|
dukv_RenderFrame (THIS_PTR)
|
||||||
{
|
{
|
||||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
@@ -524,19 +532,40 @@ dukv_RenderFrame (THIS_PTR)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
static const char*
|
||||||
|
dukv_GetName (void)
|
||||||
|
{
|
||||||
|
return "DukVid";
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
dukv_InitModule (int flags)
|
||||||
|
{
|
||||||
|
// no flags are defined for now
|
||||||
|
return true;
|
||||||
|
|
||||||
|
(void)flags; // dodge compiler warning
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dukv_TermModule (void)
|
||||||
|
{
|
||||||
|
// do an extensive search on the word 'nothing'
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32
|
||||||
dukv_GetStructSize (void)
|
dukv_GetStructSize (void)
|
||||||
{
|
{
|
||||||
return sizeof (TFB_DuckVideoDecoder);
|
return sizeof (TFB_DuckVideoDecoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
dukv_GetError (THIS_PTR)
|
dukv_GetError (THIS_PTR)
|
||||||
{
|
{
|
||||||
return This->error;
|
return This->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
dukv_Init (THIS_PTR, TFB_PixelFormat* fmt)
|
dukv_Init (THIS_PTR, TFB_PixelFormat* fmt)
|
||||||
{
|
{
|
||||||
This->format = fmt;
|
This->format = fmt;
|
||||||
@@ -544,7 +573,7 @@ dukv_Init (THIS_PTR, TFB_PixelFormat* fmt)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
dukv_Term (THIS_PTR)
|
dukv_Term (THIS_PTR)
|
||||||
{
|
{
|
||||||
//TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
//TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
@@ -552,7 +581,7 @@ dukv_Term (THIS_PTR)
|
|||||||
dukv_Close (This);
|
dukv_Close (This);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
dukv_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
|
dukv_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
|
||||||
{
|
{
|
||||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
@@ -595,7 +624,7 @@ dukv_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
dukv_Close (THIS_PTR)
|
dukv_Close (THIS_PTR)
|
||||||
{
|
{
|
||||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
@@ -612,7 +641,7 @@ dukv_Close (THIS_PTR)
|
|||||||
}
|
}
|
||||||
if (dukv->stream)
|
if (dukv->stream)
|
||||||
{
|
{
|
||||||
res_CloseResFile (dukv->stream);
|
uio_fclose (dukv->stream);
|
||||||
dukv->stream = NULL;
|
dukv->stream = NULL;
|
||||||
}
|
}
|
||||||
if (dukv->inbuf)
|
if (dukv->inbuf)
|
||||||
@@ -627,7 +656,7 @@ dukv_Close (THIS_PTR)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
dukv_DecodeNext (THIS_PTR)
|
dukv_DecodeNext (THIS_PTR)
|
||||||
{
|
{
|
||||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
@@ -639,8 +668,8 @@ dukv_DecodeNext (THIS_PTR)
|
|||||||
if (!dukv->stream || dukv->iframe >= dukv->cframes)
|
if (!dukv->stream || dukv->iframe >= dukv->cframes)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SeekResFile (dukv->stream, dukv->frames[dukv->iframe], SEEK_SET);
|
uio_fseek (dukv->stream, dukv->frames[dukv->iframe], SEEK_SET);
|
||||||
if (ReadResFile (&fh, sizeof (fh), 1, dukv->stream) != 1)
|
if (uio_fread (&fh, sizeof (fh), 1, dukv->stream) != 1)
|
||||||
{
|
{
|
||||||
dukv->last_error = dukve_EOF;
|
dukv->last_error = dukve_EOF;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -654,8 +683,8 @@ dukv_DecodeNext (THIS_PTR)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SeekResFile (dukv->stream, vofs, SEEK_CUR);
|
uio_fseek (dukv->stream, vofs, SEEK_CUR);
|
||||||
if ((uint32)ReadResFile (dukv->inbuf, 1, vsize, dukv->stream) != vsize)
|
if (uio_fread (dukv->inbuf, 1, vsize, dukv->stream) != vsize)
|
||||||
{
|
{
|
||||||
dukv->last_error = dukve_EOF;
|
dukv->last_error = dukve_EOF;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -676,7 +705,7 @@ dukv_DecodeNext (THIS_PTR)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
static uint32
|
||||||
dukv_SeekFrame (THIS_PTR, uint32 frame)
|
dukv_SeekFrame (THIS_PTR, uint32 frame)
|
||||||
{
|
{
|
||||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
@@ -687,7 +716,7 @@ dukv_SeekFrame (THIS_PTR, uint32 frame)
|
|||||||
return dukv->iframe = frame;
|
return dukv->iframe = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
static float
|
||||||
dukv_SeekTime (THIS_PTR, float time)
|
dukv_SeekTime (THIS_PTR, float time)
|
||||||
{
|
{
|
||||||
//TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
//TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
@@ -696,7 +725,7 @@ dukv_SeekTime (THIS_PTR, float time)
|
|||||||
return (float) dukv_SeekFrame (This, frame) / DUCK_GENERAL_FPS;
|
return (float) dukv_SeekFrame (This, frame) / DUCK_GENERAL_FPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
static uint32
|
||||||
dukv_GetFrame (THIS_PTR)
|
dukv_GetFrame (THIS_PTR)
|
||||||
{
|
{
|
||||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
@@ -704,7 +733,7 @@ dukv_GetFrame (THIS_PTR)
|
|||||||
return dukv->iframe;
|
return dukv->iframe;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
static float
|
||||||
dukv_GetTime (THIS_PTR)
|
dukv_GetTime (THIS_PTR)
|
||||||
{
|
{
|
||||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
//Copyright Paul Reiche, Fred Ford. 1992-2002
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -18,32 +18,47 @@
|
|||||||
#include "videodec.h"
|
#include "videodec.h"
|
||||||
#include "dukvid.h"
|
#include "dukvid.h"
|
||||||
|
|
||||||
|
#define MAX_REG_DECODERS 31
|
||||||
|
|
||||||
static bool vd_inited = 0;
|
static bool vd_inited = 0;
|
||||||
static TFB_PixelFormat vd_vidfmt;
|
static TFB_PixelFormat vd_vidfmt;
|
||||||
|
static int vd_flags = 0;
|
||||||
|
|
||||||
static struct vd_DecoderInfo
|
struct TFB_RegVideoDecoder
|
||||||
{
|
{
|
||||||
|
bool builtin;
|
||||||
|
bool used; // ever used indicator
|
||||||
const char* ext;
|
const char* ext;
|
||||||
const char* name;
|
const TFB_VideoDecoderFuncs* funcs;
|
||||||
TFB_VideoDecoderFuncs* funcs;
|
};
|
||||||
}
|
static TFB_RegVideoDecoder vd_decoders[MAX_REG_DECODERS + 1] =
|
||||||
vd_decoders[] =
|
|
||||||
{
|
{
|
||||||
{"duk", "DukVid", &dukv_DecoderVtbl},
|
{true, true, "duk", &dukv_DecoderVtbl},
|
||||||
{NULL, NULL, NULL} // null term
|
{false, false, NULL, NULL}, // null term
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vd_computeMasks (uint32 mask, DWORD* shift, DWORD* loss);
|
static void vd_computeMasks (uint32 mask, DWORD* shift, DWORD* loss);
|
||||||
|
|
||||||
|
const char*
|
||||||
|
VideoDecoder_GetName (TFB_VideoDecoder *decoder)
|
||||||
|
{
|
||||||
|
if (!decoder || !decoder->funcs)
|
||||||
|
return "(Null)";
|
||||||
|
return decoder->funcs->GetName ();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VideoDecoder_Init (int flags, int depth, uint32 Rmask, uint32 Gmask,
|
VideoDecoder_Init (int flags, int depth, uint32 Rmask, uint32 Gmask,
|
||||||
uint32 Bmask, uint32 Amask)
|
uint32 Bmask, uint32 Amask)
|
||||||
{
|
{
|
||||||
|
TFB_RegVideoDecoder* info;
|
||||||
|
|
||||||
vd_inited = 0;
|
vd_inited = 0;
|
||||||
|
|
||||||
if (depth < 15 || depth > 32)
|
if (depth < 15 || depth > 32)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "VideoDecoder_Init: Unsupported video depth %d\n", depth);
|
fprintf (stderr, "VideoDecoder_Init: "
|
||||||
|
"Unsupported video depth %d\n", depth);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,24 +82,142 @@ VideoDecoder_Init (int flags, int depth, uint32 Rmask, uint32 Gmask,
|
|||||||
vd_computeMasks (Amask, &vd_vidfmt.Ashift, &vd_vidfmt.Aloss);
|
vd_computeMasks (Amask, &vd_vidfmt.Ashift, &vd_vidfmt.Aloss);
|
||||||
// END: adapted from SDL
|
// END: adapted from SDL
|
||||||
|
|
||||||
vd_inited = 1;
|
// init built-in decoders
|
||||||
(void)flags; // dodge compiler warning
|
for (info = vd_decoders; info->ext; info++)
|
||||||
|
{
|
||||||
|
if (!info->funcs->InitModule (flags))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "VideoDecoder_Init(): "
|
||||||
|
"%s video decoder init failed\n",
|
||||||
|
info->funcs->GetName ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
vd_flags = flags;
|
||||||
|
vd_inited = 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VideoDecoder_Uninit (void)
|
VideoDecoder_Uninit (void)
|
||||||
{
|
{
|
||||||
|
TFB_RegVideoDecoder* info;
|
||||||
|
|
||||||
|
// uninit all decoders
|
||||||
|
// and unregister loaded decoders
|
||||||
|
for (info = vd_decoders; info->used; info++)
|
||||||
|
{
|
||||||
|
if (info->ext) // check if present
|
||||||
|
info->funcs->TermModule ();
|
||||||
|
|
||||||
|
if (!info->builtin)
|
||||||
|
{
|
||||||
|
info->used = false;
|
||||||
|
info->ext = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
vd_inited = 0;
|
vd_inited = 0;
|
||||||
// go for a strall in a park
|
}
|
||||||
|
|
||||||
|
TFB_RegVideoDecoder*
|
||||||
|
VideoDecoder_Register (const char* fileext, TFB_VideoDecoderFuncs* decvtbl)
|
||||||
|
{
|
||||||
|
TFB_RegVideoDecoder* info;
|
||||||
|
TFB_RegVideoDecoder* newslot = NULL;
|
||||||
|
|
||||||
|
if (!decvtbl)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "VideoDecoder_Register(): Null decoder table\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!fileext)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "VideoDecoder_Register(): Bad file type for %s\n",
|
||||||
|
decvtbl->GetName ());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if extension already registered
|
||||||
|
for (info = vd_decoders; info->used &&
|
||||||
|
(!info->ext || strcmp (info->ext, fileext) != 0);
|
||||||
|
++info)
|
||||||
|
{
|
||||||
|
// and pick up an empty slot (where available)
|
||||||
|
if (!newslot && !info->ext)
|
||||||
|
newslot = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info >= vd_decoders + MAX_REG_DECODERS)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "VideoDecoder_Register(): Decoders limit reached\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (info->ext)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "VideoDecoder_Register(): "
|
||||||
|
"'%s' decoder already registered (%s denied)\n",
|
||||||
|
fileext, decvtbl->GetName ());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decvtbl->InitModule (vd_flags))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "VideoDecoder_Register(): %s decoder init failed\n",
|
||||||
|
decvtbl->GetName ());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newslot)
|
||||||
|
{
|
||||||
|
newslot = info;
|
||||||
|
newslot->used = true;
|
||||||
|
// make next one a term
|
||||||
|
info[1].builtin = false;
|
||||||
|
info[1].used = false;
|
||||||
|
info[1].ext = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
newslot->ext = fileext;
|
||||||
|
newslot->funcs = decvtbl;
|
||||||
|
|
||||||
|
return newslot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
VideoDecoder_Unregister (TFB_RegVideoDecoder* regdec)
|
||||||
|
{
|
||||||
|
if (regdec < vd_decoders || regdec >= vd_decoders + MAX_REG_DECODERS ||
|
||||||
|
!regdec->ext || !regdec->funcs)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "VideoDecoder_Unregister(): "
|
||||||
|
"Invalid or expired decoder passed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
regdec->funcs->TermModule ();
|
||||||
|
regdec->ext = NULL;
|
||||||
|
regdec->funcs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TFB_VideoDecoderFuncs*
|
||||||
|
VideoDecoder_Lookup (const char* fileext)
|
||||||
|
{
|
||||||
|
TFB_RegVideoDecoder* info;
|
||||||
|
|
||||||
|
for (info = vd_decoders; info->used &&
|
||||||
|
(!info->ext || strcmp (info->ext, fileext) != 0);
|
||||||
|
++info)
|
||||||
|
;
|
||||||
|
return info->ext ? info->funcs : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TFB_VideoDecoder*
|
TFB_VideoDecoder*
|
||||||
VideoDecoder_Load (uio_DirHandle *dir, const char *filename)
|
VideoDecoder_Load (uio_DirHandle *dir, const char *filename)
|
||||||
{
|
{
|
||||||
const char* pext;
|
const char* pext;
|
||||||
struct vd_DecoderInfo* dinfo;
|
TFB_RegVideoDecoder* info;
|
||||||
TFB_VideoDecoder* decoder;
|
TFB_VideoDecoder* decoder;
|
||||||
|
|
||||||
|
|
||||||
@@ -99,27 +232,28 @@ VideoDecoder_Load (uio_DirHandle *dir, const char *filename)
|
|||||||
}
|
}
|
||||||
++pext;
|
++pext;
|
||||||
|
|
||||||
for (dinfo = vd_decoders;
|
for (info = vd_decoders; info->used &&
|
||||||
dinfo->ext && strcmp(dinfo->ext, pext) != 0;
|
(!info->ext || strcmp (info->ext, pext) != 0);
|
||||||
++dinfo)
|
++info)
|
||||||
;
|
;
|
||||||
if (!dinfo->ext)
|
if (!info->ext)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "VideoDecoder_Load: Unsupported file type\n");
|
fprintf (stderr, "VideoDecoder_Load: Unsupported file type\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder = (TFB_VideoDecoder*) HCalloc (dinfo->funcs->GetStructSize ());
|
decoder = (TFB_VideoDecoder*) HCalloc (info->funcs->GetStructSize ());
|
||||||
decoder->funcs = dinfo->funcs;
|
decoder->funcs = info->funcs;
|
||||||
if (!decoder->funcs->Init (decoder, &vd_vidfmt))
|
if (!decoder->funcs->Init (decoder, &vd_vidfmt))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "VideoDecoder_Load: Cannot init '%s' decoder, code %d\n",
|
fprintf (stderr, "VideoDecoder_Load: "
|
||||||
dinfo->name, decoder->funcs->GetError (decoder));
|
"Cannot init '%s' decoder, code %d\n",
|
||||||
|
decoder->funcs->GetName (),
|
||||||
|
decoder->funcs->GetError (decoder));
|
||||||
HFree (decoder);
|
HFree (decoder);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->decoder_info = dinfo->name;
|
|
||||||
decoder->dir = dir;
|
decoder->dir = dir;
|
||||||
decoder->filename = (char *) HMalloc (strlen (filename) + 1);
|
decoder->filename = (char *) HMalloc (strlen (filename) + 1);
|
||||||
strcpy (decoder->filename, filename);
|
strcpy (decoder->filename, filename);
|
||||||
@@ -127,8 +261,10 @@ VideoDecoder_Load (uio_DirHandle *dir, const char *filename)
|
|||||||
|
|
||||||
if (!decoder->funcs->Open (decoder, dir, filename))
|
if (!decoder->funcs->Open (decoder, dir, filename))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "VideoDecoder_Load: '%s' decoder did not load %s, code %d\n",
|
fprintf (stderr, "VideoDecoder_Load: "
|
||||||
dinfo->name, filename, decoder->funcs->GetError (decoder));
|
"'%s' decoder did not load %s, code %d\n",
|
||||||
|
decoder->funcs->GetName (), filename,
|
||||||
|
decoder->funcs->GetError (decoder));
|
||||||
|
|
||||||
VideoDecoder_Free (decoder);
|
VideoDecoder_Free (decoder);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ typedef struct tfb_videodecoder TFB_VideoDecoder;
|
|||||||
|
|
||||||
typedef struct tfb_videodecoderfunc
|
typedef struct tfb_videodecoderfunc
|
||||||
{
|
{
|
||||||
|
const char* (* GetName) (void);
|
||||||
|
bool (* InitModule) (int flags);
|
||||||
|
void (* TermModule) ();
|
||||||
uint32 (* GetStructSize) (void);
|
uint32 (* GetStructSize) (void);
|
||||||
int (* GetError) (THIS_PTR);
|
int (* GetError) (THIS_PTR);
|
||||||
bool (* Init) (THIS_PTR, TFB_PixelFormat* fmt);
|
bool (* Init) (THIS_PTR, TFB_PixelFormat* fmt);
|
||||||
@@ -81,7 +84,6 @@ struct tfb_videodecoder
|
|||||||
sint32 error;
|
sint32 error;
|
||||||
float pos; // position in seconds
|
float pos; // position in seconds
|
||||||
uint32 cur_frame;
|
uint32 cur_frame;
|
||||||
const char *decoder_info;
|
|
||||||
|
|
||||||
// semi-private
|
// semi-private
|
||||||
uio_DirHandle *dir;
|
uio_DirHandle *dir;
|
||||||
@@ -97,6 +99,13 @@ enum
|
|||||||
VIDEODECODER_EOF,
|
VIDEODECODER_EOF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct TFB_RegVideoDecoder TFB_RegVideoDecoder;
|
||||||
|
|
||||||
|
TFB_RegVideoDecoder* VideoDecoder_Register (const char* fileext,
|
||||||
|
TFB_VideoDecoderFuncs* decvtbl);
|
||||||
|
void VideoDecoder_Unregister (TFB_RegVideoDecoder* regdec);
|
||||||
|
const TFB_VideoDecoderFuncs* VideoDecoder_Lookup (const char* fileext);
|
||||||
|
|
||||||
bool VideoDecoder_Init (int flags, int depth, uint32 Rmask, uint32 Gmask,
|
bool VideoDecoder_Init (int flags, int depth, uint32 Rmask, uint32 Gmask,
|
||||||
uint32 Bmask, uint32 Amask);
|
uint32 Bmask, uint32 Amask);
|
||||||
void VideoDecoder_Uninit (void);
|
void VideoDecoder_Uninit (void);
|
||||||
@@ -107,6 +116,7 @@ float VideoDecoder_Seek (TFB_VideoDecoder *decoder, float time_pos);
|
|||||||
uint32 VideoDecoder_SeekFrame (TFB_VideoDecoder *decoder, uint32 frame_pos);
|
uint32 VideoDecoder_SeekFrame (TFB_VideoDecoder *decoder, uint32 frame_pos);
|
||||||
void VideoDecoder_Rewind (TFB_VideoDecoder *decoder);
|
void VideoDecoder_Rewind (TFB_VideoDecoder *decoder);
|
||||||
void VideoDecoder_Free (TFB_VideoDecoder *decoder);
|
void VideoDecoder_Free (TFB_VideoDecoder *decoder);
|
||||||
|
const char* VideoDecoder_GetName (TFB_VideoDecoder *decoder);
|
||||||
|
|
||||||
|
|
||||||
#endif // _VIDEODEC_H
|
#endif // _VIDEODEC_H
|
||||||
|
|||||||
Reference in New Issue
Block a user