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.
29 #include "stream/stream.h"
37 unsigned int *frame_size
;
40 static void demux_seek_fli(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
){
41 fli_frames_t
*frames
= (fli_frames_t
*)demuxer
->priv
;
42 sh_video_t
*sh_video
= demuxer
->video
->sh
;
43 int newpos
=(flags
&SEEK_ABSOLUTE
)?0:frames
->current_frame
;
44 if(flags
&SEEK_FACTOR
){
46 newpos
+=rel_seek_secs
*frames
->num_frames
;
49 newpos
+=rel_seek_secs
*sh_video
->fps
;
51 if(newpos
<0) newpos
=0; else
52 if(newpos
>frames
->num_frames
) newpos
=frames
->num_frames
;
53 frames
->current_frame
=newpos
;
57 // 0 = EOF or no stream found
58 // 1 = successfully read a packet
59 static int demux_fli_fill_buffer(demuxer_t
*demuxer
, demux_stream_t
*ds
){
60 fli_frames_t
*frames
= (fli_frames_t
*)demuxer
->priv
;
61 sh_video_t
*sh_video
= demuxer
->video
->sh
;
63 // see if the end has been reached
64 if (frames
->current_frame
>= frames
->num_frames
)
67 // fetch the frame from the file
68 // first, position the file properly since ds_read_packet() doesn't
69 // seem to do it, even though it takes a file offset as a parameter
70 stream_seek(demuxer
->stream
, frames
->filepos
[frames
->current_frame
]);
71 ds_read_packet(demuxer
->video
,
73 frames
->frame_size
[frames
->current_frame
],
74 frames
->current_frame
/sh_video
->fps
,
75 frames
->filepos
[frames
->current_frame
],
76 0 /* what flags? -> demuxer.h (alex) */
79 // get the next frame ready
80 frames
->current_frame
++;
85 static demuxer_t
* demux_open_fli(demuxer_t
* demuxer
){
86 sh_video_t
*sh_video
= NULL
;
87 fli_frames_t
*frames
= malloc(sizeof(fli_frames_t
));
90 unsigned int frame_size
;
92 unsigned char * header
;
94 // go back to the beginning
95 stream_reset(demuxer
->stream
);
96 stream_seek(demuxer
->stream
, 0);
98 header
= calloc(1, sizeof(BITMAPINFOHEADER
) + 128);
99 stream_read(demuxer
->stream
, header
+ sizeof(BITMAPINFOHEADER
), 128);
100 stream_seek(demuxer
->stream
, 0);
102 demuxer
->movi_start
= 128;
103 demuxer
->movi_end
= stream_read_dword_le(demuxer
->stream
);
105 magic_number
= stream_read_word_le(demuxer
->stream
);
107 if ((magic_number
!= 0xAF11) && (magic_number
!= 0xAF12))
109 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Bad/unknown magic number (%04x)\n",
116 // fetch the number of frames
117 frames
->num_frames
= stream_read_word_le(demuxer
->stream
);
118 frames
->current_frame
= 0;
120 // allocate enough entries for the indices
121 // audit: num_frames is 16bit so it is safe against overflow
122 frames
->filepos
= malloc(frames
->num_frames
* sizeof(off_t
));
123 frames
->frame_size
= malloc(frames
->num_frames
* sizeof(int));
125 // create a new video stream header
126 sh_video
= new_sh_video(demuxer
, 0);
128 // make sure the demuxer knows about the new video stream header
129 // (even though new_sh_video() ought to take care of it)
130 demuxer
->video
->sh
= sh_video
;
132 // make sure that the video demuxer stream header knows about its
133 // parent video demuxer stream (this is getting wacky), or else
134 // video_read_properties() will choke
135 sh_video
->ds
= demuxer
->video
;
137 // custom fourcc for internal MPlayer use
138 sh_video
->format
= mmioFOURCC('F', 'L', 'I', 'C');
140 sh_video
->disp_w
= stream_read_word_le(demuxer
->stream
);
141 sh_video
->disp_h
= stream_read_word_le(demuxer
->stream
);
143 // pass extradata to codec
144 sh_video
->bih
= (BITMAPINFOHEADER
*)header
;
145 sh_video
->bih
->biSize
= sizeof(BITMAPINFOHEADER
) + 128;
146 sh_video
->bih
->biWidth
= sh_video
->disp_w
;
147 sh_video
->bih
->biHeight
= sh_video
->disp_h
;
149 // skip the video depth and flags
150 stream_skip(demuxer
->stream
, 4);
153 speed
= stream_read_word_le(demuxer
->stream
);
156 if (magic_number
== 0xAF11)
158 sh_video
->fps
= 1000 / speed
;
159 sh_video
->frametime
= 1/sh_video
->fps
;
161 // build the frame index
162 stream_seek(demuxer
->stream
, demuxer
->movi_start
);
164 while ((!stream_eof(demuxer
->stream
)) && (frame_number
< frames
->num_frames
))
166 frames
->filepos
[frame_number
] = stream_tell(demuxer
->stream
);
167 frame_size
= stream_read_dword_le(demuxer
->stream
);
168 magic_number
= stream_read_word_le(demuxer
->stream
);
169 stream_skip(demuxer
->stream
, frame_size
- 6);
171 // if this chunk has the right magic number, index it
172 if ((magic_number
== 0xF1FA) || (magic_number
== 0xF5FA))
174 frames
->frame_size
[frame_number
] = frame_size
;
179 // save the actual number of frames indexed
180 frames
->num_frames
= frame_number
;
182 demuxer
->priv
= frames
;
187 static void demux_close_fli(demuxer_t
* demuxer
) {
188 fli_frames_t
*frames
= demuxer
->priv
;
194 free(frames
->filepos
);
195 if(frames
->frame_size
)
196 free(frames
->frame_size
);
203 static int fli_check_file(demuxer_t
* demuxer
)
207 stream_seek(demuxer
->stream
, 4);
208 id
=stream_read_word_le(demuxer
->stream
);
209 // check for the FLI file magic number
210 if((id
==0xAF11) || (id
==0xAF12))
211 return DEMUXER_TYPE_FLI
;
217 const demuxer_desc_t demuxer_desc_fli
= {
218 "Autodesk FLIC demuxer",
222 "Supports also some extensions",
224 0, // unsafe autodetect (short signature)
226 demux_fli_fill_buffer
,