3 * copyright (c) 2001 Mike Melanson
5 * This file is part of MPlayer.
7 * MPlayer is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * MPlayer is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "stream/stream.h"
38 unsigned int *frame_size
;
41 static void demux_seek_fli(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
){
42 fli_frames_t
*frames
= (fli_frames_t
*)demuxer
->priv
;
43 sh_video_t
*sh_video
= demuxer
->video
->sh
;
44 int newpos
=(flags
&SEEK_ABSOLUTE
)?0:frames
->current_frame
;
45 if(flags
&SEEK_FACTOR
){
47 newpos
+=rel_seek_secs
*frames
->num_frames
;
50 newpos
+=rel_seek_secs
*sh_video
->fps
;
52 if(newpos
<0) newpos
=0; else
53 if(newpos
>frames
->num_frames
) newpos
=frames
->num_frames
;
54 frames
->current_frame
=newpos
;
58 // 0 = EOF or no stream found
59 // 1 = successfully read a packet
60 static int demux_fli_fill_buffer(demuxer_t
*demuxer
, demux_stream_t
*ds
){
61 fli_frames_t
*frames
= (fli_frames_t
*)demuxer
->priv
;
62 sh_video_t
*sh_video
= demuxer
->video
->sh
;
64 // see if the end has been reached
65 if (frames
->current_frame
>= frames
->num_frames
)
68 // fetch the frame from the file
69 // first, position the file properly since ds_read_packet() doesn't
70 // seem to do it, even though it takes a file offset as a parameter
71 stream_seek(demuxer
->stream
, frames
->filepos
[frames
->current_frame
]);
72 ds_read_packet(demuxer
->video
,
74 frames
->frame_size
[frames
->current_frame
],
75 frames
->current_frame
/sh_video
->fps
,
76 frames
->filepos
[frames
->current_frame
],
77 0 /* what flags? -> demuxer.h (alex) */
80 // get the next frame ready
81 frames
->current_frame
++;
86 static demuxer_t
* demux_open_fli(demuxer_t
* demuxer
){
87 sh_video_t
*sh_video
= NULL
;
88 fli_frames_t
*frames
= malloc(sizeof(fli_frames_t
));
91 unsigned int frame_size
;
93 unsigned char * header
;
95 // go back to the beginning
96 stream_reset(demuxer
->stream
);
97 stream_seek(demuxer
->stream
, 0);
99 header
= calloc(1, sizeof(BITMAPINFOHEADER
) + 128);
100 stream_read(demuxer
->stream
, header
+ sizeof(BITMAPINFOHEADER
), 128);
101 stream_seek(demuxer
->stream
, 0);
103 demuxer
->movi_start
= 128;
104 demuxer
->movi_end
= stream_read_dword_le(demuxer
->stream
);
106 magic_number
= stream_read_word_le(demuxer
->stream
);
108 if ((magic_number
!= 0xAF11) && (magic_number
!= 0xAF12))
110 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Bad/unknown magic number (%04x)\n",
117 // fetch the number of frames
118 frames
->num_frames
= stream_read_word_le(demuxer
->stream
);
119 frames
->current_frame
= 0;
121 // allocate enough entries for the indices
122 // audit: num_frames is 16bit so it is safe against overflow
123 frames
->filepos
= malloc(frames
->num_frames
* sizeof(off_t
));
124 frames
->frame_size
= malloc(frames
->num_frames
* sizeof(int));
126 // create a new video stream header
127 sh_video
= new_sh_video(demuxer
, 0);
129 // make sure the demuxer knows about the new video stream header
130 // (even though new_sh_video() ought to take care of it)
131 demuxer
->video
->sh
= sh_video
;
133 // make sure that the video demuxer stream header knows about its
134 // parent video demuxer stream (this is getting wacky), or else
135 // video_read_properties() will choke
136 sh_video
->ds
= demuxer
->video
;
138 // custom fourcc for internal MPlayer use
139 sh_video
->format
= mmioFOURCC('F', 'L', 'I', 'C');
141 sh_video
->disp_w
= stream_read_word_le(demuxer
->stream
);
142 sh_video
->disp_h
= stream_read_word_le(demuxer
->stream
);
144 // pass extradata to codec
145 sh_video
->bih
= (BITMAPINFOHEADER
*)header
;
146 sh_video
->bih
->biSize
= sizeof(BITMAPINFOHEADER
) + 128;
147 sh_video
->bih
->biWidth
= sh_video
->disp_w
;
148 sh_video
->bih
->biHeight
= sh_video
->disp_h
;
150 // skip the video depth and flags
151 stream_skip(demuxer
->stream
, 4);
154 speed
= stream_read_word_le(demuxer
->stream
);
157 if (magic_number
== 0xAF11)
159 sh_video
->fps
= 1000 / speed
;
160 sh_video
->frametime
= 1/sh_video
->fps
;
162 // build the frame index
163 stream_seek(demuxer
->stream
, demuxer
->movi_start
);
165 while ((!stream_eof(demuxer
->stream
)) && (frame_number
< frames
->num_frames
))
167 frames
->filepos
[frame_number
] = stream_tell(demuxer
->stream
);
168 frame_size
= stream_read_dword_le(demuxer
->stream
);
169 magic_number
= stream_read_word_le(demuxer
->stream
);
170 stream_skip(demuxer
->stream
, frame_size
- 6);
172 // if this chunk has the right magic number, index it
173 if ((magic_number
== 0xF1FA) || (magic_number
== 0xF5FA))
175 frames
->frame_size
[frame_number
] = frame_size
;
180 // save the actual number of frames indexed
181 frames
->num_frames
= frame_number
;
183 demuxer
->priv
= frames
;
188 static void demux_close_fli(demuxer_t
* demuxer
) {
189 fli_frames_t
*frames
= demuxer
->priv
;
195 free(frames
->filepos
);
196 if(frames
->frame_size
)
197 free(frames
->frame_size
);
204 static int fli_check_file(demuxer_t
* demuxer
)
208 stream_seek(demuxer
->stream
, 4);
209 id
=stream_read_word_le(demuxer
->stream
);
210 // check for the FLI file magic number
211 if((id
==0xAF11) || (id
==0xAF12))
212 return DEMUXER_TYPE_FLI
;
218 const demuxer_desc_t demuxer_desc_fli
= {
219 "Autodesk FLIC demuxer",
223 "Supports also some extensions",
225 0, // unsafe autodetect (short signature)
227 demux_fli_fill_buffer
,