Video decoder refactoring;
Removed an unnecessary level of indirection; decoder-specific data is kept together with general decoder data. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1261 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,7 +1,22 @@
|
||||
/*
|
||||
* 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 the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* DUCK video player
|
||||
*
|
||||
* Status: as raw as it gets
|
||||
*
|
||||
* Status: fully functional
|
||||
*/
|
||||
|
||||
#include "video.h"
|
||||
@@ -11,21 +26,23 @@
|
||||
#include "endian_uqm.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define _THIS TFB_VideoDecoder* This
|
||||
#define THIS_PTR TFB_VideoDecoder* This
|
||||
|
||||
int dukv_GetError (_THIS);
|
||||
bool dukv_Init (_THIS, TFB_PixelFormat* fmt);
|
||||
void dukv_Term (_THIS);
|
||||
bool dukv_Open (_THIS, uio_DirHandle *dir, const char *filename);
|
||||
void dukv_Close (_THIS);
|
||||
int dukv_DecodeNext (_THIS);
|
||||
uint32 dukv_SeekFrame (_THIS, uint32 frame);
|
||||
float dukv_SeekTime (_THIS, float time);
|
||||
uint32 dukv_GetFrame (_THIS);
|
||||
float dukv_GetTime (_THIS);
|
||||
uint32 dukv_GetStructSize (void);
|
||||
int dukv_GetError (THIS_PTR);
|
||||
bool dukv_Init (THIS_PTR, TFB_PixelFormat* fmt);
|
||||
void dukv_Term (THIS_PTR);
|
||||
bool dukv_Open (THIS_PTR, uio_DirHandle *dir, const char *filename);
|
||||
void dukv_Close (THIS_PTR);
|
||||
int dukv_DecodeNext (THIS_PTR);
|
||||
uint32 dukv_SeekFrame (THIS_PTR, uint32 frame);
|
||||
float dukv_SeekTime (THIS_PTR, float time);
|
||||
uint32 dukv_GetFrame (THIS_PTR);
|
||||
float dukv_GetTime (THIS_PTR);
|
||||
|
||||
TFB_VideoDecoderFuncs dukv_DecoderVtbl =
|
||||
{
|
||||
dukv_GetStructSize,
|
||||
dukv_GetError,
|
||||
dukv_Init,
|
||||
dukv_Term,
|
||||
@@ -59,8 +76,13 @@ typedef struct tfb_duckvideodeltas
|
||||
|
||||
} TFB_DuckVideoDeltas;
|
||||
|
||||
typedef struct tfb_duckvideo
|
||||
// specific video decoder struct derived from TFB_VideoDecoder
|
||||
// the only sane way in C one can :)
|
||||
typedef struct tfb_duckvideodecoder
|
||||
{
|
||||
// always the first member
|
||||
TFB_VideoDecoder decoder;
|
||||
|
||||
sint32 last_error;
|
||||
uio_DirHandle* basedir;
|
||||
char* basename;
|
||||
@@ -71,8 +93,7 @@ typedef struct tfb_duckvideo
|
||||
uint32 cframes;
|
||||
uint32 iframe;
|
||||
uint32 version;
|
||||
uint32 wb, hb; // width + height in blocks
|
||||
uint32 w, h;
|
||||
uint32 wb, hb; // width, height in blocks
|
||||
|
||||
// generated
|
||||
TFB_DuckVideoDeltas d;
|
||||
@@ -80,7 +101,7 @@ typedef struct tfb_duckvideo
|
||||
uint8* inbuf;
|
||||
uint32* decbuf;
|
||||
|
||||
} TFB_DuckVideo;
|
||||
} TFB_DuckVideoDecoder;
|
||||
|
||||
#define DUCK_GENERAL_FPS 14.622f
|
||||
#define DUCK_MAX_FRAME_SIZE 0x8000U
|
||||
@@ -250,7 +271,7 @@ dukv_DecodeFrameV3 (uint8* src_p, uint32* dst_p, uint32 wb, uint32 hb,
|
||||
}
|
||||
|
||||
bool
|
||||
dukv_OpenStream (TFB_DuckVideo* dukv)
|
||||
dukv_OpenStream (TFB_DuckVideoDecoder* dukv)
|
||||
{
|
||||
char filename[280];
|
||||
|
||||
@@ -261,7 +282,7 @@ dukv_OpenStream (TFB_DuckVideo* dukv)
|
||||
}
|
||||
|
||||
bool
|
||||
dukv_ReadFrames (TFB_DuckVideo* dukv)
|
||||
dukv_ReadFrames (TFB_DuckVideoDecoder* dukv)
|
||||
{
|
||||
char filename[280];
|
||||
uint32 i;
|
||||
@@ -275,8 +296,8 @@ dukv_ReadFrames (TFB_DuckVideo* dukv)
|
||||
dukv->cframes = LengthResFile (fp) / sizeof (uint32);
|
||||
dukv->frames = (uint32*) HMalloc (dukv->cframes * sizeof (uint32));
|
||||
|
||||
if ((uint32)ReadResFile (dukv->frames, sizeof (uint32), dukv->cframes, fp)
|
||||
!= dukv->cframes)
|
||||
if ((uint32)ReadResFile (dukv->frames, sizeof (uint32), dukv->cframes,
|
||||
fp) != dukv->cframes)
|
||||
{
|
||||
HFree (dukv->frames);
|
||||
dukv->frames = 0;
|
||||
@@ -291,7 +312,7 @@ dukv_ReadFrames (TFB_DuckVideo* dukv)
|
||||
}
|
||||
|
||||
bool
|
||||
dukv_ReadVectors (TFB_DuckVideo* dukv, uint8* vectors)
|
||||
dukv_ReadVectors (TFB_DuckVideoDecoder* dukv, uint8* vectors)
|
||||
{
|
||||
uio_Stream *fp;
|
||||
char filename[280];
|
||||
@@ -309,7 +330,7 @@ dukv_ReadVectors (TFB_DuckVideo* dukv, uint8* vectors)
|
||||
}
|
||||
|
||||
bool
|
||||
dukv_ReadHeader (TFB_DuckVideo* dukv, sint32* pl, sint32* pc)
|
||||
dukv_ReadHeader (TFB_DuckVideoDecoder* dukv, sint32* pl, sint32* pc)
|
||||
{
|
||||
uio_Stream *fp;
|
||||
char filename[280];
|
||||
@@ -337,8 +358,8 @@ dukv_ReadHeader (TFB_DuckVideo* dukv, sint32* pl, sint32* pc)
|
||||
pc[i] = (sint16) UQM_SwapBE16 (hdr.chromas[i]);
|
||||
}
|
||||
|
||||
dukv->w = dukv->wb * 4;
|
||||
dukv->h = dukv->hb * 4;
|
||||
dukv->decoder.w = dukv->wb * 4;
|
||||
dukv->decoder.h = dukv->hb * 4;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -399,7 +420,8 @@ dukv_DecodeVector (uint8* vec, sint32* p, bool is_chroma, sint32* deltas)
|
||||
}
|
||||
|
||||
void
|
||||
dukv_InitDeltas (TFB_DuckVideo* dukv, uint8* vectors, sint32* pl, sint32* pc)
|
||||
dukv_InitDeltas (TFB_DuckVideoDecoder* dukv, uint8* vectors,
|
||||
sint32* pl, sint32* pc)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -427,14 +449,14 @@ dukv_PixelConv (uint16 pix, const TFB_PixelFormat* fmt)
|
||||
}
|
||||
|
||||
void
|
||||
dukv_RenderFrame (_THIS)
|
||||
dukv_RenderFrame (THIS_PTR)
|
||||
{
|
||||
TFB_DuckVideo* dukv = This->dec_data;
|
||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
const TFB_PixelFormat* fmt = This->format;
|
||||
uint32 h, x, y;
|
||||
uint32* dec = dukv->decbuf;
|
||||
|
||||
h = dukv->h / 2;
|
||||
h = dukv->decoder.h / 2;
|
||||
|
||||
// separate bpp versions for speed
|
||||
switch (fmt->BytesPerPixel)
|
||||
@@ -448,7 +470,7 @@ dukv_RenderFrame (_THIS)
|
||||
dst0 = (uint16*) This->callbacks.GetCanvasLine (This, y * 2);
|
||||
dst1 = (uint16*) This->callbacks.GetCanvasLine (This, y * 2 + 1);
|
||||
|
||||
for (x = 0; x < dukv->w; ++x, ++dec, ++dst0, ++dst1)
|
||||
for (x = 0; x < dukv->decoder.w; ++x, ++dec, ++dst0, ++dst1)
|
||||
{
|
||||
uint32 pair = *dec;
|
||||
*dst0 = dukv_PixelConv ((uint16)(pair >> 16), fmt);
|
||||
@@ -466,7 +488,8 @@ dukv_RenderFrame (_THIS)
|
||||
dst0 = (uint8*) This->callbacks.GetCanvasLine (This, y * 2);
|
||||
dst1 = (uint8*) This->callbacks.GetCanvasLine (This, y * 2 + 1);
|
||||
|
||||
for (x = 0; x < dukv->w; ++x, ++dec, dst0 += 3, dst1 += 3)
|
||||
for (x = 0; x < dukv->decoder.w;
|
||||
++x, ++dec, dst0 += 3, dst1 += 3)
|
||||
{
|
||||
uint32 pair = *dec;
|
||||
*(uint32*)dst0 =
|
||||
@@ -486,7 +509,7 @@ dukv_RenderFrame (_THIS)
|
||||
dst0 = (uint32*) This->callbacks.GetCanvasLine (This, y * 2);
|
||||
dst1 = (uint32*) This->callbacks.GetCanvasLine (This, y * 2 + 1);
|
||||
|
||||
for (x = 0; x < dukv->w; ++x, ++dec, ++dst0, ++dst1)
|
||||
for (x = 0; x < dukv->decoder.w; ++x, ++dec, ++dst0, ++dst1)
|
||||
{
|
||||
uint32 pair = *dec;
|
||||
*dst0 = dukv_PixelConv ((uint16)(pair >> 16), fmt);
|
||||
@@ -501,34 +524,38 @@ dukv_RenderFrame (_THIS)
|
||||
|
||||
}
|
||||
|
||||
uint32
|
||||
dukv_GetStructSize (void)
|
||||
{
|
||||
return sizeof (TFB_DuckVideoDecoder);
|
||||
}
|
||||
|
||||
int dukv_GetError (_THIS)
|
||||
int
|
||||
dukv_GetError (THIS_PTR)
|
||||
{
|
||||
return This->error;
|
||||
}
|
||||
|
||||
bool
|
||||
dukv_Init (_THIS, TFB_PixelFormat* fmt)
|
||||
dukv_Init (THIS_PTR, TFB_PixelFormat* fmt)
|
||||
{
|
||||
This->format = fmt;
|
||||
This->audio_synced = 1;
|
||||
This->dec_data = HCalloc (sizeof (TFB_DuckVideo));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
dukv_Term (_THIS)
|
||||
dukv_Term (THIS_PTR)
|
||||
{
|
||||
//TFB_DuckVideo* dukv = This->dec_data;
|
||||
//TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
|
||||
dukv_Close (This);
|
||||
HFree (This->dec_data);
|
||||
}
|
||||
|
||||
bool
|
||||
dukv_Open (_THIS, uio_DirHandle *dir, const char *filename)
|
||||
dukv_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
|
||||
{
|
||||
TFB_DuckVideo* dukv = This->dec_data;
|
||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
char* pext;
|
||||
sint32 lumas[8], chromas[8];
|
||||
uint8* vectors;
|
||||
@@ -556,23 +583,22 @@ dukv_Open (_THIS, uio_DirHandle *dir, const char *filename)
|
||||
dukv_InitDeltas (dukv, vectors, lumas, chromas);
|
||||
HFree (vectors);
|
||||
|
||||
This->w = dukv->w;
|
||||
This->h = dukv->h;
|
||||
This->length = (float) dukv->cframes / DUCK_GENERAL_FPS;
|
||||
This->frame_count = dukv->cframes;
|
||||
This->max_frame_wait =
|
||||
(uint32) (1000.0f / DUCK_GENERAL_FPS * 1.1);
|
||||
|
||||
dukv->inbuf = HMalloc (DUCK_MAX_FRAME_SIZE);
|
||||
dukv->decbuf = HMalloc (dukv->w * dukv->h * sizeof (uint16));
|
||||
dukv->decbuf = HMalloc (
|
||||
dukv->decoder.w * dukv->decoder.h * sizeof (uint16));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
dukv_Close (_THIS)
|
||||
dukv_Close (THIS_PTR)
|
||||
{
|
||||
TFB_DuckVideo* dukv = This->dec_data;
|
||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
|
||||
if (dukv->basename)
|
||||
{
|
||||
@@ -602,9 +628,9 @@ dukv_Close (_THIS)
|
||||
}
|
||||
|
||||
int
|
||||
dukv_DecodeNext (_THIS)
|
||||
dukv_DecodeNext (THIS_PTR)
|
||||
{
|
||||
TFB_DuckVideo* dukv = This->dec_data;
|
||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
uint32 fh[2];
|
||||
uint32 vofs;
|
||||
uint32 vsize;
|
||||
@@ -651,9 +677,9 @@ dukv_DecodeNext (_THIS)
|
||||
}
|
||||
|
||||
uint32
|
||||
dukv_SeekFrame (_THIS, uint32 frame)
|
||||
dukv_SeekFrame (THIS_PTR, uint32 frame)
|
||||
{
|
||||
TFB_DuckVideo* dukv = This->dec_data;
|
||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
|
||||
if (frame > dukv->cframes)
|
||||
frame = dukv->cframes; // EOS
|
||||
@@ -662,26 +688,26 @@ dukv_SeekFrame (_THIS, uint32 frame)
|
||||
}
|
||||
|
||||
float
|
||||
dukv_SeekTime (_THIS, float time)
|
||||
dukv_SeekTime (THIS_PTR, float time)
|
||||
{
|
||||
//TFB_DuckVideo* dukv = This->dec_data;
|
||||
//TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
uint32 frame = (uint32) (time * DUCK_GENERAL_FPS);
|
||||
|
||||
return (float) dukv_SeekFrame (This, frame) / DUCK_GENERAL_FPS;
|
||||
}
|
||||
|
||||
uint32
|
||||
dukv_GetFrame (_THIS)
|
||||
dukv_GetFrame (THIS_PTR)
|
||||
{
|
||||
TFB_DuckVideo* dukv = This->dec_data;
|
||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
|
||||
return dukv->iframe;
|
||||
}
|
||||
|
||||
float
|
||||
dukv_GetTime (_THIS)
|
||||
dukv_GetTime (THIS_PTR)
|
||||
{
|
||||
TFB_DuckVideo* dukv = This->dec_data;
|
||||
TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This;
|
||||
|
||||
return (float) dukv->iframe / DUCK_GENERAL_FPS;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ VideoDecoder_Load (uio_DirHandle *dir, const char *filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
decoder = (TFB_VideoDecoder*) HCalloc (sizeof (*decoder));
|
||||
decoder = (TFB_VideoDecoder*) HCalloc (dinfo->funcs->GetStructSize ());
|
||||
decoder->funcs = dinfo->funcs;
|
||||
if (!decoder->funcs->Init (decoder, &vd_vidfmt))
|
||||
{
|
||||
|
||||
@@ -24,20 +24,21 @@
|
||||
// forward-declare
|
||||
typedef struct tfb_videodecoder TFB_VideoDecoder;
|
||||
|
||||
#define _THIS TFB_VideoDecoder*
|
||||
#define THIS_PTR TFB_VideoDecoder*
|
||||
|
||||
typedef struct tfb_videodecoderfunc
|
||||
{
|
||||
int (* GetError) (_THIS);
|
||||
bool (* Init) (_THIS, TFB_PixelFormat* fmt);
|
||||
void (* Term) (_THIS);
|
||||
bool (* Open) (_THIS, uio_DirHandle *dir, const char *filename);
|
||||
void (* Close) (_THIS);
|
||||
int (* DecodeNext) (_THIS);
|
||||
uint32 (* SeekFrame) (_THIS, uint32 frame);
|
||||
float (* SeekTime) (_THIS, float time);
|
||||
uint32 (* GetFrame) (_THIS);
|
||||
float (* GetTime) (_THIS);
|
||||
uint32 (* GetStructSize) (void);
|
||||
int (* GetError) (THIS_PTR);
|
||||
bool (* Init) (THIS_PTR, TFB_PixelFormat* fmt);
|
||||
void (* Term) (THIS_PTR);
|
||||
bool (* Open) (THIS_PTR, uio_DirHandle *dir, const char *filename);
|
||||
void (* Close) (THIS_PTR);
|
||||
int (* DecodeNext) (THIS_PTR);
|
||||
uint32 (* SeekFrame) (THIS_PTR, uint32 frame);
|
||||
float (* SeekTime) (THIS_PTR, float time);
|
||||
uint32 (* GetFrame) (THIS_PTR);
|
||||
float (* GetTime) (THIS_PTR);
|
||||
|
||||
} TFB_VideoDecoderFuncs;
|
||||
|
||||
@@ -46,17 +47,17 @@ typedef struct tfb_videodecoderfunc
|
||||
typedef struct tfb_videocallbacks
|
||||
{
|
||||
// any decoder calls this
|
||||
void* (* GetCanvasLine) (_THIS, uint32 line);
|
||||
void* (* GetCanvasLine) (THIS_PTR, uint32 line);
|
||||
// non-audio-driven decoders call this to figure out
|
||||
// when the next frame should be drawn
|
||||
uint32 (* GetTicks) (_THIS);
|
||||
uint32 (* GetTicks) (THIS_PTR);
|
||||
// non-audio-driven decoders call this to inform
|
||||
// the player when the next frame should be drawn
|
||||
bool (* SetTimer) (_THIS, uint32 msecs);
|
||||
bool (* SetTimer) (THIS_PTR, uint32 msecs);
|
||||
|
||||
} TFB_VideoCallbacks;
|
||||
|
||||
#undef _THIS
|
||||
#undef THIS_PTR
|
||||
|
||||
struct tfb_videodecoder
|
||||
{
|
||||
@@ -72,8 +73,6 @@ struct tfb_videodecoder
|
||||
bool audio_synced;
|
||||
// decoder callbacks
|
||||
TFB_VideoCallbacks callbacks;
|
||||
// decoder-defined data - don't mess with
|
||||
void *dec_data;
|
||||
|
||||
// other - public
|
||||
bool looping;
|
||||
|
||||
Reference in New Issue
Block a user