Mercurial > mplayer.hg
annotate libmpdemux/demux_fli.c @ 16185:973b82bf1187
do not crash when /dev/video0 is not present
author | faust3 |
---|---|
date | Sat, 06 Aug 2005 18:19:58 +0000 |
parents | 6b86089c2edd |
children | 67c30d47ffd4 |
rev | line source |
---|---|
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
1 /* |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
2 FLI file parser for the MPlayer program |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
3 by Mike Melanson |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
4 */ |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
5 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
6 #include <stdio.h> |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
7 #include <stdlib.h> |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
8 #include <unistd.h> |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
9 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
10 #include "config.h" |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
11 #include "mp_msg.h" |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
12 #include "help_mp.h" |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
13 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
14 #include "stream.h" |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
15 #include "demuxer.h" |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
16 #include "stheader.h" |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
17 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
18 typedef struct _fli_frames_t { |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
19 int num_frames; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
20 int current_frame; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
21 off_t *filepos; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
22 unsigned int *frame_size; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
23 } fli_frames_t; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
24 |
16175 | 25 static void demux_seek_fli(demuxer_t *demuxer,float rel_seek_secs,int flags){ |
3544 | 26 fli_frames_t *frames = (fli_frames_t *)demuxer->priv; |
27 sh_video_t *sh_video = demuxer->video->sh; | |
28 int newpos=(flags&1)?0:frames->current_frame; | |
29 if(flags&2){ | |
30 // float 0..1 | |
31 newpos+=rel_seek_secs*frames->num_frames; | |
32 } else { | |
33 // secs | |
34 newpos+=rel_seek_secs*sh_video->fps; | |
35 } | |
36 if(newpos<0) newpos=0; else | |
37 if(newpos>frames->num_frames) newpos=frames->num_frames; | |
38 frames->current_frame=newpos; | |
39 } | |
40 | |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
41 // return value: |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
42 // 0 = EOF or no stream found |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
43 // 1 = successfully read a packet |
16175 | 44 static int demux_fli_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){ |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
45 fli_frames_t *frames = (fli_frames_t *)demuxer->priv; |
3221 | 46 sh_video_t *sh_video = demuxer->video->sh; |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
47 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
48 // see if the end has been reached |
3544 | 49 if (frames->current_frame >= frames->num_frames) |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
50 return 0; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
51 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
52 // fetch the frame from the file |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
53 // first, position the file properly since ds_read_packet() doesn't |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
54 // seem to do it, even though it takes a file offset as a parameter |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
55 stream_seek(demuxer->stream, frames->filepos[frames->current_frame]); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
56 ds_read_packet(demuxer->video, |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
57 demuxer->stream, |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
58 frames->frame_size[frames->current_frame], |
3221 | 59 frames->current_frame/sh_video->fps, |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
60 frames->filepos[frames->current_frame], |
3221 | 61 0 /* what flags? -> demuxer.h (alex) */ |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
62 ); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
63 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
64 // get the next frame ready |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
65 frames->current_frame++; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
66 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
67 return 1; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
68 } |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
69 |
16175 | 70 static demuxer_t* demux_open_fli(demuxer_t* demuxer){ |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
71 sh_video_t *sh_video = NULL; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
72 fli_frames_t *frames = (fli_frames_t *)malloc(sizeof(fli_frames_t)); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
73 int frame_number; |
3104 | 74 int speed; |
3105
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
75 unsigned int frame_size; |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
76 int magic_number; |
11846
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
77 unsigned char * header; |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
78 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
79 // go back to the beginning |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
80 stream_reset(demuxer->stream); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
81 stream_seek(demuxer->stream, 0); |
11846
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
82 |
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
83 header = malloc(sizeof(BITMAPINFOHEADER) + 128); |
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
84 stream_read(demuxer->stream, header + sizeof(BITMAPINFOHEADER), 128); |
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
85 stream_seek(demuxer->stream, 0); |
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
86 |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
87 demuxer->movi_start = 128; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
88 demuxer->movi_end = stream_read_dword_le(demuxer->stream); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
89 |
3229 | 90 magic_number = stream_read_word_le(demuxer->stream); |
91 | |
92 if ((magic_number != 0xAF11) && (magic_number != 0xAF12)) | |
93 { | |
94 mp_msg(MSGT_DEMUX, MSGL_ERR, "Bad/unknown magic number (%04x)\n", | |
95 magic_number); | |
96 return(NULL); | |
97 } | |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
98 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
99 // fetch the number of frames |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
100 frames->num_frames = stream_read_word_le(demuxer->stream); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
101 frames->current_frame = 0; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
102 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
103 // allocate enough entries for the indices |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
104 frames->filepos = (off_t *)malloc(frames->num_frames * sizeof(off_t)); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
105 frames->frame_size = (int *)malloc(frames->num_frames * sizeof(int)); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
106 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
107 // create a new video stream header |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
108 sh_video = new_sh_video(demuxer, 0); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
109 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
110 // make sure the demuxer knows about the new video stream header |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
111 // (even though new_sh_video() ought to take care of it) |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
112 demuxer->video->sh = sh_video; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
113 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
114 // make sure that the video demuxer stream header knows about its |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
115 // parent video demuxer stream (this is getting wacky), or else |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
116 // video_read_properties() will choke |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
117 sh_video->ds = demuxer->video; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
118 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
119 // custom fourcc for internal MPlayer use |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
120 sh_video->format = mmioFOURCC('F', 'L', 'I', 'C'); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
121 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
122 sh_video->disp_w = stream_read_word_le(demuxer->stream); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
123 sh_video->disp_h = stream_read_word_le(demuxer->stream); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
124 |
11846
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
125 // pass extradata to codec |
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
126 sh_video->bih = (BITMAPINFOHEADER*)header; |
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
127 sh_video->bih->biSize = sizeof(BITMAPINFOHEADER) + 128; |
e3c3d01e9b86
Pass header to codec in extradata (needed by ffmpeg fli decoder)
rtognimp
parents:
5810
diff
changeset
|
128 |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
129 // skip the video depth and flags |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
130 stream_skip(demuxer->stream, 4); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
131 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
132 // get the speed |
3104 | 133 speed = stream_read_word_le(demuxer->stream); |
134 if (speed == 0) | |
135 speed = 1; | |
3229 | 136 if (magic_number == 0xAF11) |
137 speed *= 1000/70; | |
3104 | 138 sh_video->fps = 1000 / speed; |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
139 sh_video->frametime = 1/sh_video->fps; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
140 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
141 // build the frame index |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
142 stream_seek(demuxer->stream, demuxer->movi_start); |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
143 frame_number = 0; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
144 while ((!stream_eof(demuxer->stream)) && (frame_number < frames->num_frames)) |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
145 { |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
146 frames->filepos[frame_number] = stream_tell(demuxer->stream); |
3105
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
147 frame_size = stream_read_dword_le(demuxer->stream); |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
148 magic_number = stream_read_word_le(demuxer->stream); |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
149 stream_skip(demuxer->stream, frame_size - 6); |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
150 |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
151 // if this chunk has the right magic number, index it |
4800
e47b32c0eca8
discovered what appears to be another valid FLI frame magic number
melanson
parents:
3544
diff
changeset
|
152 if ((magic_number == 0xF1FA) || (magic_number == 0xF5FA)) |
3105
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
153 { |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
154 frames->frame_size[frame_number] = frame_size; |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
155 frame_number++; |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
156 } |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
157 } |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
158 |
3105
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
159 // save the actual number of frames indexed |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
160 frames->num_frames = frame_number; |
f951f3be126c
fixed FLI demuxer so that it skips over app-specific frames
melanson
parents:
3104
diff
changeset
|
161 |
3101
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
162 demuxer->priv = frames; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
163 |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
164 return demuxer; |
637e540831b9
mostly complete support for loading and decoding FLI/FLC animations
melanson
parents:
diff
changeset
|
165 } |
5810 | 166 |
16175 | 167 static void demux_close_fli(demuxer_t* demuxer) { |
5810 | 168 fli_frames_t *frames = demuxer->priv; |
169 | |
170 if(!frames) | |
171 return; | |
172 | |
173 if(frames->filepos) | |
174 free(frames->filepos); | |
175 if(frames->frame_size) | |
176 free(frames->frame_size); | |
177 | |
178 free(frames); | |
179 | |
180 } | |
16175 | 181 |
182 | |
183 static int fli_check_file(demuxer_t* demuxer) | |
184 { | |
185 int id; | |
186 | |
187 stream_seek(demuxer->stream, 4); | |
188 id=stream_read_word_le(demuxer->stream); | |
189 // check for the FLI file magic number | |
190 if((id==0xAF11) || (id==0xAF12)) | |
191 return DEMUXER_TYPE_FLI; | |
192 | |
193 return 0; | |
194 } | |
195 | |
196 | |
197 demuxer_desc_t demuxer_desc_fli = { | |
198 "Autodesk FLIC demuxer", | |
199 "fli", | |
200 "FLI", | |
201 "Mike Melanson", | |
202 "Supports also some extensions", | |
203 DEMUXER_TYPE_FLI, | |
204 0, // unsafe autodetect (short signature) | |
205 fli_check_file, | |
206 demux_fli_fill_buffer, | |
207 demux_open_fli, | |
208 demux_close_fli, | |
209 demux_seek_fli, | |
210 NULL | |
211 }; |