# HG changeset patch # User melanson # Date 1006646292 0 # Node ID 637e540831b9527871020afe01068fc55bfc2913 # Parent d930dbae8473e09c0d97961d1fdad43b5bf0039b mostly complete support for loading and decoding FLI/FLC animations diff -r d930dbae8473 -r 637e540831b9 libmpdemux/Makefile --- a/libmpdemux/Makefile Sat Nov 24 23:28:22 2001 +0000 +++ b/libmpdemux/Makefile Sat Nov 24 23:58:12 2001 +0000 @@ -3,7 +3,7 @@ include ../config.mak -SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c frequencies.c +SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c frequencies.c demux_fli.c ifeq ($(STREAMING),yes) SRCS += asf_streaming.c url.c http.c network.c endif diff -r d930dbae8473 -r 637e540831b9 libmpdemux/demux_fli.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/demux_fli.c Sat Nov 24 23:58:12 2001 +0000 @@ -0,0 +1,114 @@ +/* + FLI file parser for the MPlayer program + by Mike Melanson +*/ + +#include +#include +#include + +#include "config.h" +#include "mp_msg.h" +#include "help_mp.h" + +#include "stream.h" +#include "demuxer.h" +#include "stheader.h" + +typedef struct _fli_frames_t { + int num_frames; + int current_frame; + off_t *filepos; + unsigned int *frame_size; +} fli_frames_t; + +// return value: +// 0 = EOF or no stream found +// 1 = successfully read a packet +int demux_fli_fill_buffer(demuxer_t *demuxer){ + fli_frames_t *frames = (fli_frames_t *)demuxer->priv; + + // see if the end has been reached + if (frames->current_frame == frames->num_frames) + return 0; + + // fetch the frame from the file + // first, position the file properly since ds_read_packet() doesn't + // seem to do it, even though it takes a file offset as a parameter + stream_seek(demuxer->stream, frames->filepos[frames->current_frame]); + ds_read_packet(demuxer->video, + demuxer->stream, + frames->frame_size[frames->current_frame], + 0, /* not sure what pts is for */ + frames->filepos[frames->current_frame], + 0 /* what flags? */ + ); + + // get the next frame ready + frames->current_frame++; + + return 1; +} + +demuxer_t* demux_open_fli(demuxer_t* demuxer){ + sh_video_t *sh_video = NULL; + fli_frames_t *frames = (fli_frames_t *)malloc(sizeof(fli_frames_t)); + int frame_number; + + // go back to the beginning + stream_reset(demuxer->stream); + stream_seek(demuxer->stream, 0); + demuxer->movi_start = 128; + demuxer->movi_end = stream_read_dword_le(demuxer->stream); + + // skip the magic number + stream_skip(demuxer->stream, 2); + + // fetch the number of frames + frames->num_frames = stream_read_word_le(demuxer->stream); + frames->current_frame = 0; + + // allocate enough entries for the indices + frames->filepos = (off_t *)malloc(frames->num_frames * sizeof(off_t)); + frames->frame_size = (int *)malloc(frames->num_frames * sizeof(int)); + + // create a new video stream header + sh_video = new_sh_video(demuxer, 0); + + // make sure the demuxer knows about the new video stream header + // (even though new_sh_video() ought to take care of it) + demuxer->video->sh = sh_video; + + // make sure that the video demuxer stream header knows about its + // parent video demuxer stream (this is getting wacky), or else + // video_read_properties() will choke + sh_video->ds = demuxer->video; + + // custom fourcc for internal MPlayer use + sh_video->format = mmioFOURCC('F', 'L', 'I', 'C'); + + sh_video->disp_w = stream_read_word_le(demuxer->stream); + sh_video->disp_h = stream_read_word_le(demuxer->stream); + + // skip the video depth and flags + stream_skip(demuxer->stream, 4); + + // get the speed + sh_video->fps = 1000 / stream_read_word_le(demuxer->stream); + sh_video->frametime = 1/sh_video->fps; + + // build the frame index + stream_seek(demuxer->stream, demuxer->movi_start); + frame_number = 0; + while ((!stream_eof(demuxer->stream)) && (frame_number < frames->num_frames)) + { + frames->filepos[frame_number] = stream_tell(demuxer->stream); + frames->frame_size[frame_number] = stream_read_dword_le(demuxer->stream); + stream_skip(demuxer->stream, frames->frame_size[frame_number] - 4); + frame_number++; + } + + demuxer->priv = frames; + + return demuxer; +} diff -r d930dbae8473 -r 637e540831b9 libmpdemux/demuxer.c --- a/libmpdemux/demuxer.c Sat Nov 24 23:28:22 2001 +0000 +++ b/libmpdemux/demuxer.c Sat Nov 24 23:58:12 2001 +0000 @@ -149,6 +149,7 @@ // return value: // 0 = EOF or no stream found or invalid type // 1 = successfully read a packet +int demux_fli_fill_buffer(demuxer_t *demux); int demux_mpg_es_fill_buffer(demuxer_t *demux); int demux_mpg_fill_buffer(demuxer_t *demux); int demux_avi_fill_buffer(demuxer_t *demux); @@ -170,6 +171,7 @@ // Note: parameter 'ds' can be NULL! // printf("demux->type=%d\n",demux->type); switch(demux->type){ + case DEMUXER_TYPE_FLI: return demux_fli_fill_buffer(demux); case DEMUXER_TYPE_MPEG_ES: return demux_mpg_es_fill_buffer(demux); case DEMUXER_TYPE_MPEG_PS: return demux_mpg_fill_buffer(demux); case DEMUXER_TYPE_AVI: return demux_avi_fill_buffer(demux); @@ -354,6 +356,7 @@ demuxer_t* demux_open_avi(demuxer_t* demuxer); int mov_check_file(demuxer_t* demuxer); int mov_read_header(demuxer_t* demuxer); +int demux_open_fli(demuxer_t* demuxer); extern int vivo_check_file(demuxer_t *demuxer); extern void demux_open_vivo(demuxer_t *demuxer); @@ -381,6 +384,20 @@ file_format=DEMUXER_TYPE_TV; } #endif +//=============== Try to open as FLI file: ================= +if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_FLI){ + demuxer=new_demuxer(stream,DEMUXER_TYPE_FLI,audio_id,video_id,dvdsub_id); + { + int size=stream_read_dword_le(demuxer->stream); + int id=stream_read_word_le(demuxer->stream); + // chech for the FLI file magic number + if((id==0xAF11) || (id==0xAF12)){ + mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedFLIfile); + file_format=DEMUXER_TYPE_FLI; + } + } +} + //=============== Try to open as AVI file: ================= if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AVI){ demuxer=new_demuxer(stream,DEMUXER_TYPE_AVI,audio_id,video_id,dvdsub_id); @@ -481,6 +498,10 @@ demuxer->file_format=file_format; switch(file_format){ + case DEMUXER_TYPE_FLI: { + if (!demux_open_fli(demuxer)) return NULL; + break; + } case DEMUXER_TYPE_MOV: { if(!mov_read_header(demuxer)) return NULL; // sh_video=d_video->sh;if(sh_video) sh_video->ds=d_video; diff -r d930dbae8473 -r 637e540831b9 libmpdemux/demuxer.h --- a/libmpdemux/demuxer.h Sat Nov 24 23:28:22 2001 +0000 +++ b/libmpdemux/demuxer.h Sat Nov 24 23:58:12 2001 +0000 @@ -12,6 +12,7 @@ #define DEMUXER_TYPE_MOV 7 #define DEMUXER_TYPE_VIVO 8 #define DEMUXER_TYPE_TV 9 +#define DEMUXER_TYPE_FLI 10 #define DEMUXER_TIME_NONE 0 #define DEMUXER_TIME_PTS 1