Mercurial > mplayer.hg
comparison libmpdemux/demux_fli.c @ 3101:637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
author | melanson |
---|---|
date | Sat, 24 Nov 2001 23:58:12 +0000 |
parents | |
children | 829637d529e9 |
comparison
equal
deleted
inserted
replaced
3100:d930dbae8473 | 3101:637e540831b9 |
---|---|
1 /* | |
2 FLI file parser for the MPlayer program | |
3 by Mike Melanson | |
4 */ | |
5 | |
6 #include <stdio.h> | |
7 #include <stdlib.h> | |
8 #include <unistd.h> | |
9 | |
10 #include "config.h" | |
11 #include "mp_msg.h" | |
12 #include "help_mp.h" | |
13 | |
14 #include "stream.h" | |
15 #include "demuxer.h" | |
16 #include "stheader.h" | |
17 | |
18 typedef struct _fli_frames_t { | |
19 int num_frames; | |
20 int current_frame; | |
21 off_t *filepos; | |
22 unsigned int *frame_size; | |
23 } fli_frames_t; | |
24 | |
25 // return value: | |
26 // 0 = EOF or no stream found | |
27 // 1 = successfully read a packet | |
28 int demux_fli_fill_buffer(demuxer_t *demuxer){ | |
29 fli_frames_t *frames = (fli_frames_t *)demuxer->priv; | |
30 | |
31 // see if the end has been reached | |
32 if (frames->current_frame == frames->num_frames) | |
33 return 0; | |
34 | |
35 // fetch the frame from the file | |
36 // first, position the file properly since ds_read_packet() doesn't | |
37 // seem to do it, even though it takes a file offset as a parameter | |
38 stream_seek(demuxer->stream, frames->filepos[frames->current_frame]); | |
39 ds_read_packet(demuxer->video, | |
40 demuxer->stream, | |
41 frames->frame_size[frames->current_frame], | |
42 0, /* not sure what pts is for */ | |
43 frames->filepos[frames->current_frame], | |
44 0 /* what flags? */ | |
45 ); | |
46 | |
47 // get the next frame ready | |
48 frames->current_frame++; | |
49 | |
50 return 1; | |
51 } | |
52 | |
53 demuxer_t* demux_open_fli(demuxer_t* demuxer){ | |
54 sh_video_t *sh_video = NULL; | |
55 fli_frames_t *frames = (fli_frames_t *)malloc(sizeof(fli_frames_t)); | |
56 int frame_number; | |
57 | |
58 // go back to the beginning | |
59 stream_reset(demuxer->stream); | |
60 stream_seek(demuxer->stream, 0); | |
61 demuxer->movi_start = 128; | |
62 demuxer->movi_end = stream_read_dword_le(demuxer->stream); | |
63 | |
64 // skip the magic number | |
65 stream_skip(demuxer->stream, 2); | |
66 | |
67 // fetch the number of frames | |
68 frames->num_frames = stream_read_word_le(demuxer->stream); | |
69 frames->current_frame = 0; | |
70 | |
71 // allocate enough entries for the indices | |
72 frames->filepos = (off_t *)malloc(frames->num_frames * sizeof(off_t)); | |
73 frames->frame_size = (int *)malloc(frames->num_frames * sizeof(int)); | |
74 | |
75 // create a new video stream header | |
76 sh_video = new_sh_video(demuxer, 0); | |
77 | |
78 // make sure the demuxer knows about the new video stream header | |
79 // (even though new_sh_video() ought to take care of it) | |
80 demuxer->video->sh = sh_video; | |
81 | |
82 // make sure that the video demuxer stream header knows about its | |
83 // parent video demuxer stream (this is getting wacky), or else | |
84 // video_read_properties() will choke | |
85 sh_video->ds = demuxer->video; | |
86 | |
87 // custom fourcc for internal MPlayer use | |
88 sh_video->format = mmioFOURCC('F', 'L', 'I', 'C'); | |
89 | |
90 sh_video->disp_w = stream_read_word_le(demuxer->stream); | |
91 sh_video->disp_h = stream_read_word_le(demuxer->stream); | |
92 | |
93 // skip the video depth and flags | |
94 stream_skip(demuxer->stream, 4); | |
95 | |
96 // get the speed | |
97 sh_video->fps = 1000 / stream_read_word_le(demuxer->stream); | |
98 sh_video->frametime = 1/sh_video->fps; | |
99 | |
100 // build the frame index | |
101 stream_seek(demuxer->stream, demuxer->movi_start); | |
102 frame_number = 0; | |
103 while ((!stream_eof(demuxer->stream)) && (frame_number < frames->num_frames)) | |
104 { | |
105 frames->filepos[frame_number] = stream_tell(demuxer->stream); | |
106 frames->frame_size[frame_number] = stream_read_dword_le(demuxer->stream); | |
107 stream_skip(demuxer->stream, frames->frame_size[frame_number] - 4); | |
108 frame_number++; | |
109 } | |
110 | |
111 demuxer->priv = frames; | |
112 | |
113 return demuxer; | |
114 } |