2 FLI file parser for the MPlayer program
18 typedef struct _fli_frames_t
{
22 unsigned int *frame_size
;
25 static void demux_seek_fli(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
){
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
;
31 newpos
+=rel_seek_secs
*frames
->num_frames
;
34 newpos
+=rel_seek_secs
*sh_video
->fps
;
36 if(newpos
<0) newpos
=0; else
37 if(newpos
>frames
->num_frames
) newpos
=frames
->num_frames
;
38 frames
->current_frame
=newpos
;
42 // 0 = EOF or no stream found
43 // 1 = successfully read a packet
44 static int demux_fli_fill_buffer(demuxer_t
*demuxer
, demux_stream_t
*ds
){
45 fli_frames_t
*frames
= (fli_frames_t
*)demuxer
->priv
;
46 sh_video_t
*sh_video
= demuxer
->video
->sh
;
48 // see if the end has been reached
49 if (frames
->current_frame
>= frames
->num_frames
)
52 // fetch the frame from the file
53 // first, position the file properly since ds_read_packet() doesn't
54 // seem to do it, even though it takes a file offset as a parameter
55 stream_seek(demuxer
->stream
, frames
->filepos
[frames
->current_frame
]);
56 ds_read_packet(demuxer
->video
,
58 frames
->frame_size
[frames
->current_frame
],
59 frames
->current_frame
/sh_video
->fps
,
60 frames
->filepos
[frames
->current_frame
],
61 0 /* what flags? -> demuxer.h (alex) */
64 // get the next frame ready
65 frames
->current_frame
++;
70 static demuxer_t
* demux_open_fli(demuxer_t
* demuxer
){
71 sh_video_t
*sh_video
= NULL
;
72 fli_frames_t
*frames
= (fli_frames_t
*)malloc(sizeof(fli_frames_t
));
75 unsigned int frame_size
;
77 unsigned char * header
;
79 // go back to the beginning
80 stream_reset(demuxer
->stream
);
81 stream_seek(demuxer
->stream
, 0);
83 header
= malloc(sizeof(BITMAPINFOHEADER
) + 128);
84 stream_read(demuxer
->stream
, header
+ sizeof(BITMAPINFOHEADER
), 128);
85 stream_seek(demuxer
->stream
, 0);
87 demuxer
->movi_start
= 128;
88 demuxer
->movi_end
= stream_read_dword_le(demuxer
->stream
);
90 magic_number
= stream_read_word_le(demuxer
->stream
);
92 if ((magic_number
!= 0xAF11) && (magic_number
!= 0xAF12))
94 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Bad/unknown magic number (%04x)\n",
101 // fetch the number of frames
102 frames
->num_frames
= stream_read_word_le(demuxer
->stream
);
103 frames
->current_frame
= 0;
105 // allocate enough entries for the indices
106 frames
->filepos
= (off_t
*)malloc(frames
->num_frames
* sizeof(off_t
));
107 frames
->frame_size
= (int *)malloc(frames
->num_frames
* sizeof(int));
109 // create a new video stream header
110 sh_video
= new_sh_video(demuxer
, 0);
112 // make sure the demuxer knows about the new video stream header
113 // (even though new_sh_video() ought to take care of it)
114 demuxer
->video
->sh
= sh_video
;
116 // make sure that the video demuxer stream header knows about its
117 // parent video demuxer stream (this is getting wacky), or else
118 // video_read_properties() will choke
119 sh_video
->ds
= demuxer
->video
;
121 // custom fourcc for internal MPlayer use
122 sh_video
->format
= mmioFOURCC('F', 'L', 'I', 'C');
124 sh_video
->disp_w
= stream_read_word_le(demuxer
->stream
);
125 sh_video
->disp_h
= stream_read_word_le(demuxer
->stream
);
127 // pass extradata to codec
128 sh_video
->bih
= (BITMAPINFOHEADER
*)header
;
129 sh_video
->bih
->biSize
= sizeof(BITMAPINFOHEADER
) + 128;
131 // skip the video depth and flags
132 stream_skip(demuxer
->stream
, 4);
135 speed
= stream_read_word_le(demuxer
->stream
);
138 if (magic_number
== 0xAF11)
140 sh_video
->fps
= 1000 / speed
;
141 sh_video
->frametime
= 1/sh_video
->fps
;
143 // build the frame index
144 stream_seek(demuxer
->stream
, demuxer
->movi_start
);
146 while ((!stream_eof(demuxer
->stream
)) && (frame_number
< frames
->num_frames
))
148 frames
->filepos
[frame_number
] = stream_tell(demuxer
->stream
);
149 frame_size
= stream_read_dword_le(demuxer
->stream
);
150 magic_number
= stream_read_word_le(demuxer
->stream
);
151 stream_skip(demuxer
->stream
, frame_size
- 6);
153 // if this chunk has the right magic number, index it
154 if ((magic_number
== 0xF1FA) || (magic_number
== 0xF5FA))
156 frames
->frame_size
[frame_number
] = frame_size
;
161 // save the actual number of frames indexed
162 frames
->num_frames
= frame_number
;
164 demuxer
->priv
= frames
;
169 static void demux_close_fli(demuxer_t
* demuxer
) {
170 fli_frames_t
*frames
= demuxer
->priv
;
176 free(frames
->filepos
);
177 if(frames
->frame_size
)
178 free(frames
->frame_size
);
185 static int fli_check_file(demuxer_t
* demuxer
)
189 stream_seek(demuxer
->stream
, 4);
190 id
=stream_read_word_le(demuxer
->stream
);
191 // check for the FLI file magic number
192 if((id
==0xAF11) || (id
==0xAF12))
193 return DEMUXER_TYPE_FLI
;
199 demuxer_desc_t demuxer_desc_fli
= {
200 "Autodesk FLIC demuxer",
204 "Supports also some extensions",
206 0, // unsafe autodetect (short signature)
208 demux_fli_fill_buffer
,