DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
cl_video_jamdecode.c File Reference

Go to the source code of this file.

Data Structures

struct  jamdecodestream_t
 

Functions

void jam_close (void *stream)
 
static void jam_decodeframe (unsigned char *inbuf, unsigned char *outbuf, unsigned char *prevbuf, int outsize, int frametype)
 
double jam_getaspectratio (void *stream)
 
double jam_getframerate (void *stream)
 
unsigned int jam_getheight (void *stream)
 
unsigned int jam_getwidth (void *stream)
 
voidjam_open (clvideo_t *video, char *filename, const char **errorstring)
 
int jam_video (void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow)
 

Function Documentation

◆ jam_close()

void jam_close ( void * stream)

Definition at line 167 of file cl_video_jamdecode.c.

168{
170 if (s == NULL)
171 return;
172 if (s->frame_compressed)
175 if (s->frame)
176 Z_Free(s->frame);
177 s->frame = NULL;
178 if (s->frame_prev)
179 Z_Free(s->frame_prev);
180 s->frame_prev = NULL;
181 if (s->sndchan != -1)
182 S_StopChannel(s->sndchan, true, true);
183 s->sndchan = -1;
184 if (s->file)
185 FS_Close(s->file);
186 s->file = NULL;
187#ifdef JAM_USELIBAVCODECSCALE
188 if (s->frame_output_buffer)
189 Z_Free(s->frame_output_buffer);
190 s->frame_output_buffer = NULL;
191 if (s->frame_output)
192 AvUtil_Free(s->frame_output);
193 s->frame_output = NULL;
194 if (s->frame_output_scale)
195 AvUtil_Free(s->frame_output_scale);
196 s->frame_output_scale = NULL;
197#endif
198 Z_Free(s);
199}
int FS_Close(qfile_t *file)
Definition fs.c:2970
#define NULL
Definition qtypes.h:12
void S_StopChannel(unsigned int channel_ind, qbool lockmutex, qbool freesfx)
Definition snd_main.c:1648
unsigned char * frame_compressed
unsigned char * frame
unsigned char * frame_prev
#define Z_Free(data)
Definition zone.h:164

References jamdecodestream_t::file, jamdecodestream_t::frame, jamdecodestream_t::frame_compressed, jamdecodestream_t::frame_prev, FS_Close(), NULL, S_StopChannel(), jamdecodestream_t::sndchan, and Z_Free.

Referenced by jam_open().

◆ jam_decodeframe()

static void jam_decodeframe ( unsigned char * inbuf,
unsigned char * outbuf,
unsigned char * prevbuf,
int outsize,
int frametype )
static

Definition at line 230 of file cl_video_jamdecode.c.

231{
232 unsigned char *srcptr, *destptr, *prevptr;
233 int bytesleft;
234 unsigned int mark;
235 unsigned short int bits;
236 int rep;
237 int backoffs;
238 unsigned char *back;
239 int i;
240
241 srcptr = inbuf;
242 destptr = outbuf;
243 prevptr = prevbuf;
244 bytesleft = outsize;
245
246 if (frametype == 2)
247 {
248 memcpy(outbuf, inbuf, outsize);
249 return;
250 }
251 while(bytesleft > 0)
252 {
253 memcpy(&mark, srcptr, 4);
254 srcptr += 4;
255 for(i=0; i<32 && bytesleft > 0; i++,mark=mark>>1)
256 {
257 if(mark & 1)
258 {
259 *destptr = *srcptr;
260 destptr ++;
261 prevptr ++;
262 srcptr ++;
263 bytesleft --;
264 }
265 else
266 {
267 bits = srcptr[0] + 256*srcptr[1];
268 rep = (bits >> 11) + 3;
269 if(frametype == 1)
270 {
271 backoffs = 0x821 - (bits & 0x7ff);
272 back = destptr - backoffs;
273 }
274 else
275 {
276 backoffs = 0x400 - (bits & 0x7ff);
277 back = prevptr - backoffs;
278 }
279 srcptr += 2;
280 memcpy(destptr, back, rep);
281 destptr += rep;
282 prevptr += rep;
283 bytesleft -= rep;
284 }
285 }
286 }
287}
int i

References i.

Referenced by jam_video().

◆ jam_getaspectratio()

double jam_getaspectratio ( void * stream)

Definition at line 223 of file cl_video_jamdecode.c.

224{
226 return s->info_aspectratio;
227}

References jamdecodestream_t::info_aspectratio.

Referenced by jam_open().

◆ jam_getframerate()

double jam_getframerate ( void * stream)

Definition at line 216 of file cl_video_jamdecode.c.

217{
219 return s->info_framerate;
220}

References jamdecodestream_t::info_framerate.

Referenced by jam_open().

◆ jam_getheight()

unsigned int jam_getheight ( void * stream)

Definition at line 209 of file cl_video_jamdecode.c.

210{
212 return s->info_imageheight;
213}
unsigned int info_imageheight

References jamdecodestream_t::info_imageheight.

Referenced by jam_open().

◆ jam_getwidth()

unsigned int jam_getwidth ( void * stream)

Definition at line 202 of file cl_video_jamdecode.c.

203{
205 return s->info_imagewidth;
206}
unsigned int info_imagewidth

References jamdecodestream_t::info_imagewidth.

Referenced by jam_open().

◆ jam_open()

void * jam_open ( clvideo_t * video,
char * filename,
const char ** errorstring )

Definition at line 47 of file cl_video_jamdecode.c.

48{
49 char jamHead[16];
51 char *wavename;
52
53 // allocate stream structure
55 memset(s, 0, sizeof(jamdecodestream_t));
56 if (s == NULL)
57 {
58 *errorstring = "unable to allocate memory for stream info structure";
59 return NULL;
60 }
61 s->sndchan = -1;
62
63 // open file
64 s->file = FS_OpenVirtualFile(filename, true);
65 if (!s->file)
66 {
67 *errorstring = "unable to open videofile";
68 jam_close(s);
69 return NULL;
70 }
71
72 // read header
73 if (!FS_Read(s->file, jamHead, 16))
74 {
75 *errorstring = "JamDecoder: unexpected EOF reading header";
76 jam_close(s);
77 return NULL;
78 }
79 if (memcmp(jamHead, "JAM", 4))
80 {
81 *errorstring = "JamDecoder: not a JAM file";
82 jam_close(s);
83 return NULL;
84 }
85
86 s->info_imagewidth = LittleLong(*(jamHead + 4));
87 s->info_imageheight = LittleLong(*(jamHead + 8));
88 s->info_frames = LittleLong(*(jamHead + 12)) - 1;
89 s->info_framerate = 15;
90 s->info_aspectratio = (double)s->info_imagewidth / (double)s->info_imageheight;
91 s->colorscale = 0.90;
92 s->colorsub = 4;
94
95 // allocate frame input/output
96 if (s->framesize < 0)
97 {
98 *errorstring = "JamDecoder: bad framesize";
99 jam_close(s);
100 return NULL;
101 }
102 s->frame = (unsigned char *)Z_Malloc(s->framesize * 2);
103 s->frame_prev = (unsigned char *)Z_Malloc(s->framesize * 2);
104 s->frame_compressed = (unsigned char *)Z_Malloc(s->framesize);
105 if (s->frame_compressed == NULL || s->frame == NULL || s->frame_prev == NULL)
106 {
107 *errorstring = "JamDecoder: unable to allocate memory for video decoder";
108 jam_close(s);
109 return NULL;
110 }
111
112 // scale support provided by libavcodec
113#ifdef JAM_USELIBAVCODECSCALE
114 s->framewidth = s->info_imagewidth;
115 s->frameheight = s->info_imageheight;
116
117 // min size
118 if (cl_video_libavcodec_minwidth.integer > 0)
119 s->info_imagewidth = max(s->info_imagewidth, (unsigned int)cl_video_libavcodec_minwidth.integer);
120 if (cl_video_libavcodec_minheight.integer > 0)
121 s->info_imageheight = max(s->info_imageheight, (unsigned int)cl_video_libavcodec_minheight.integer);
122
123 // allocate output
124 s->frame_output_buffer = (unsigned char *)Z_Malloc(s->framesize * 4);
125 s->frame_output = AvCodec_AllocFrame();
126 s->frame_output_scale = AvCodec_AllocFrame();
127 if (!s->frame_output_buffer || !s->frame_output || !s->frame_output_scale)
128 {
129 *errorstring = "JamDecoder: failed to allocate LibAvcodec frame";
130 jam_close(s);
131 Z_Free(s);
132 return NULL;
133 }
134#endif
135
136 // everything is ok
137 // set the module functions
138 s->framenum = 0;
139 video->close = jam_close;
140 video->getwidth = jam_getwidth;
141 video->getheight = jam_getheight;
143 video->decodeframe = jam_video;
145
146 // set sound
147 size_t namelen;
148 namelen = strlen(filename) + 10;
149 wavename = (char *)Z_Malloc(namelen);
150 if (wavename)
151 {
152 sfx_t* sfx;
153 FS_StripExtension(filename, wavename, namelen);
154 dp_strlcat(wavename, ".wav", namelen);
155 sfx = S_PrecacheSound(wavename, false, false);
156 if (sfx != NULL)
157 s->sndchan = S_StartSound (-1, 0, sfx, vec3_origin, 1.0f, 0);
158 else
159 s->sndchan = -1;
160 Z_Free(wavename);
161 }
162
163 return s;
164}
double jam_getframerate(void *stream)
unsigned int jam_getheight(void *stream)
void jam_close(void *stream)
double jam_getaspectratio(void *stream)
unsigned int jam_getwidth(void *stream)
int jam_video(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow)
#define dp_strlcat(dst, src, dsize)
Definition common.h:304
#define LittleLong(l)
Definition common.h:92
fs_offset_t FS_Read(qfile_t *file, void *buffer, size_t buffersize)
Definition fs.c:3066
qfile_t * FS_OpenVirtualFile(const char *filepath, qbool quiet)
Definition fs.c:2928
void FS_StripExtension(const char *in, char *out, size_t size_out)
Definition fs.c:3611
vec3_t vec3_origin
Definition mathlib.c:26
#define max(A, B)
Definition mathlib.h:38
float strlen(string s)
int S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
S_StartSound returns the channel index, or -1 if an error occurred.
Definition snd_main.c:1643
sfx_t * S_PrecacheSound(const char *name, qbool complain, qbool levelsound)
Definition snd_main.c:1048
void(* close)(void *stream)
Definition cl_video.h:62
double(* getframerate)(void *stream)
Definition cl_video.h:65
unsigned int(* getheight)(void *stream)
Definition cl_video.h:64
int(* decodeframe)(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow)
Definition cl_video.h:67
double(* getaspectratio)(void *stream)
Definition cl_video.h:66
unsigned int(* getwidth)(void *stream)
Definition cl_video.h:63
#define Z_Malloc(size)
Definition zone.h:161

References clvideo_t::close, jamdecodestream_t::colorscale, jamdecodestream_t::colorsub, clvideo_t::decodeframe, dp_strlcat, jamdecodestream_t::file, jamdecodestream_t::frame, jamdecodestream_t::frame_compressed, jamdecodestream_t::frame_prev, jamdecodestream_t::framenum, jamdecodestream_t::framesize, FS_OpenVirtualFile(), FS_Read(), FS_StripExtension(), clvideo_t::getaspectratio, clvideo_t::getframerate, clvideo_t::getheight, clvideo_t::getwidth, jamdecodestream_t::info_aspectratio, jamdecodestream_t::info_framerate, jamdecodestream_t::info_frames, jamdecodestream_t::info_imageheight, jamdecodestream_t::info_imagewidth, jam_close(), jam_getaspectratio(), jam_getframerate(), jam_getheight(), jam_getwidth(), jam_video(), LittleLong, max, NULL, S_PrecacheSound(), S_StartSound(), jamdecodestream_t::sndchan, strlen(), vec3_origin, Z_Free, and Z_Malloc.

Referenced by OpenStream().

◆ jam_video()

int jam_video ( void * stream,
void * imagedata,
unsigned int Rmask,
unsigned int Gmask,
unsigned int Bmask,
unsigned int bytesperpixel,
int imagebytesperrow )

Definition at line 290 of file cl_video_jamdecode.c.

291{
292 unsigned char frameHead[16], *b;
293 unsigned int compsize, outsize, i;
295
296 // EOF
297 if (s->framenum >= s->info_frames)
298 return 1;
299 s->framenum++;
300
301readframe:
302 // read frame header
303 if (!FS_Read(s->file, &frameHead, 16))
304 {
305 Con_Printf("JamDecoder: unexpected EOF on frame %i\n", s->framenum);
306 return 1;
307 }
308 compsize = LittleLong(*(frameHead + 8)) - 16;
309 outsize = LittleLong(*(frameHead + 12));
310 if (compsize > s->framesize || outsize > s->framesize)
311 {
312 Con_Printf("JamDecoder: got bogus header on frame %i\n", s->framenum);
313 return 1;
314 }
315
316 // read frame contents
317 if (!FS_Read(s->file, s->frame_compressed, compsize))
318 {
319 Con_Printf("JamDecoder: unexpected EOF on frame %i\n", s->framenum);
320 return 1;
321 }
322
323 // palette goes interleaved with special flag
324 if (frameHead[0] == 2)
325 {
326 if (compsize == 768)
327 {
328 memcpy(s->frame_palette, s->frame_compressed, 768);
329 for(i = 0; i < 768; i++)
330 s->frame_palette[i] = (unsigned char)(bound(0, (s->frame_palette[i] * s->colorscale) - s->colorsub, 255));
331 goto readframe;
332 }
333 }
334 else
335 {
336 // decode frame
337 // shift buffers to provide current and previous one, decode
338 b = s->frame_prev;
339 s->frame_prev = s->frame;
340 s->frame = b;
341 jam_decodeframe(s->frame_compressed, s->frame, s->frame_prev, outsize, frameHead[4]);
342#ifdef JAM_USELIBAVCODECSCALE
343 // make BGRA imagepixels from 8bit palettized frame
344 b = (unsigned char *)s->frame_output_buffer;
345 for(i = 0; i < s->framesize; i++)
346 {
347 *b++ = s->frame_palette[s->frame[i]*3 + 2];
348 *b++ = s->frame_palette[s->frame[i]*3 + 1];
349 *b++ = s->frame_palette[s->frame[i]*3];
350 *b++ = 255;
351 }
352 // scale
353 AvCodec_FillPicture((AVPicture *)s->frame_output, (uint8_t *)s->frame_output_buffer, PIX_FMT_BGRA, s->framewidth, s->frameheight);
354 AvCodec_FillPicture((AVPicture *)s->frame_output_scale, (uint8_t *)imagedata, PIX_FMT_BGRA, s->info_imagewidth, s->info_imageheight);
355 SwsContext *scale_context = SwScale_GetCachedContext(NULL, s->framewidth, s->frameheight, PIX_FMT_BGRA, s->info_imagewidth, s->info_imageheight, PIX_FMT_BGRA, libavcodec_scalers[max(0, min(LIBAVCODEC_SCALERS, cl_video_libavcodec_scaler.integer))], NULL, NULL, NULL);
356 if (!scale_context)
357 {
358 Con_Printf("JamDecoder: LibAvcodec: error creating scale context frame %i\n", s->framenum);
359 return 1;
360 }
361 if (!SwScale_Scale(scale_context, s->frame_output->data, s->frame_output->linesize, 0, s->frameheight, s->frame_output_scale->data, s->frame_output_scale->linesize))
362 Con_Printf("JamDecoder: LibAvcodec : error scaling frame\n", s->framenum);
363 SwScale_FreeContext(scale_context);
364#else
365 // make BGRA imagepixels from 8bit palettized frame
366 b = (unsigned char *)imagedata;
367 for(i = 0; i < s->framesize; i++)
368 {
369 // bgra
370 *b++ = s->frame_palette[s->frame[i]*3 + 2];
371 *b++ = s->frame_palette[s->frame[i]*3 + 1];
372 *b++ = s->frame_palette[s->frame[i]*3];
373 *b++ = 255;
374 }
375#endif
376 }
377 return 0;
378}
static void jam_decodeframe(unsigned char *inbuf, unsigned char *outbuf, unsigned char *prevbuf, int outsize, int frametype)
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define min(A, B)
Definition mathlib.h:37
#define bound(min, num, max)
Definition mathlib.h:34
dp_FragColor b
unsigned char frame_palette[768]

References b, bound, jamdecodestream_t::colorscale, jamdecodestream_t::colorsub, Con_Printf(), jamdecodestream_t::file, jamdecodestream_t::frame, jamdecodestream_t::frame_compressed, jamdecodestream_t::frame_palette, jamdecodestream_t::frame_prev, jamdecodestream_t::framenum, jamdecodestream_t::framesize, FS_Read(), i, jamdecodestream_t::info_frames, jamdecodestream_t::info_imageheight, jamdecodestream_t::info_imagewidth, jam_decodeframe(), LittleLong, max, min, and NULL.

Referenced by jam_open().