whitespace cosmetics:
[mplayer/glamo.git] / libmpdemux / demux_mf.c
blobf7c241feed4dcb839a821abc5e853e0dd605ab2f
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <unistd.h>
9 #include "config.h"
10 #include "mp_msg.h"
11 #include "help_mp.h"
13 #include "stream/stream.h"
14 #include "demuxer.h"
15 #include "stheader.h"
16 #include "mf.h"
18 static void demux_seek_mf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
19 mf_t * mf = (mf_t *)demuxer->priv;
20 sh_video_t * sh_video = demuxer->video->sh;
21 int newpos = (flags & SEEK_ABSOLUTE)?0:mf->curr_frame - 1;
23 if ( flags & SEEK_FACTOR ) newpos+=rel_seek_secs*(mf->nr_of_files - 1);
24 else newpos+=rel_seek_secs * sh_video->fps;
25 if ( newpos < 0 ) newpos=0;
26 if( newpos >= mf->nr_of_files) newpos=mf->nr_of_files - 1;
27 mf->curr_frame=newpos;
30 // return value:
31 // 0 = EOF or no stream found
32 // 1 = successfully read a packet
33 static int demux_mf_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){
34 mf_t * mf;
35 struct stat fs;
36 FILE * f;
38 mf=(mf_t*)demuxer->priv;
39 if ( mf->curr_frame >= mf->nr_of_files ) return 0;
41 stat( mf->names[mf->curr_frame],&fs );
42 // printf( "[demux_mf] frame: %d (%s,%d)\n",mf->curr_frame,mf->names[mf->curr_frame],fs.st_size );
44 if ( !( f=fopen( mf->names[mf->curr_frame],"rb" ) ) ) return 0;
46 sh_video_t * sh_video = demuxer->video->sh;
47 demux_packet_t * dp = new_demux_packet( fs.st_size );
48 if ( !fread( dp->buffer,fs.st_size,1,f ) ) return 0;
49 dp->pts=mf->curr_frame / sh_video->fps;
50 dp->pos=mf->curr_frame;
51 dp->flags=0;
52 // append packet to DS stream:
53 ds_add_packet( demuxer->video,dp );
55 fclose( f );
57 mf->curr_frame++;
58 return 1;
61 static const struct {
62 const char *type;
63 uint32_t format;
64 } type2format[] = {
65 { "bmp", mmioFOURCC('b', 'm', 'p', ' ') },
66 { "jpeg", mmioFOURCC('I', 'J', 'P', 'G') },
67 { "jpg", mmioFOURCC('I', 'J', 'P', 'G') },
68 { "pcx", mmioFOURCC('p', 'c', 'x', ' ') },
69 { "png", mmioFOURCC('M', 'P', 'N', 'G') },
70 { "ptx", mmioFOURCC('p', 't', 'x', ' ') },
71 { "tga", mmioFOURCC('M', 'T', 'G', 'A') },
72 { "tif", mmioFOURCC('t', 'i', 'f', 'f') },
73 { "sgi", mmioFOURCC('S', 'G', 'I', '1') },
74 { "sun", mmioFOURCC('s', 'u', 'n', ' ') },
75 { "ras", mmioFOURCC('s', 'u', 'n', ' ') },
76 { "ra", mmioFOURCC('s', 'u', 'n', ' ') },
77 { "im1", mmioFOURCC('s', 'u', 'n', ' ') },
78 { "im8", mmioFOURCC('s', 'u', 'n', ' ') },
79 { "im24", mmioFOURCC('s', 'u', 'n', ' ') },
80 { "sunras", mmioFOURCC('s', 'u', 'n', ' ') },
81 { NULL, 0 }
84 static demuxer_t* demux_open_mf(demuxer_t* demuxer){
85 sh_video_t *sh_video = NULL;
86 mf_t *mf = NULL;
87 int i;
89 if(!demuxer->stream->url) return NULL;
90 if(strncmp(demuxer->stream->url, "mf://", 5)) return NULL;
93 mf=open_mf(demuxer->stream->url + 5);
94 if(!mf) return NULL;
96 if(!mf_type){
97 char* p=strrchr(mf->names[0],'.');
98 if(!p){
99 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! (try -mf type=xxx)\n" );
100 free( mf ); return NULL;
102 mf_type=strdup(p+1);
103 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! trying 'type=%s'...\n", mf_type);
106 mf->curr_frame=0;
108 demuxer->movi_start = 0;
109 demuxer->movi_end = mf->nr_of_files - 1;
111 // create a new video stream header
112 sh_video = new_sh_video(demuxer, 0);
113 // make sure the demuxer knows about the new video stream header
114 // (even though new_sh_video() ought to take care of it)
115 demuxer->video->sh = sh_video;
117 // make sure that the video demuxer stream header knows about its
118 // parent video demuxer stream (this is getting wacky), or else
119 // video_read_properties() will choke
120 sh_video->ds = demuxer->video;
122 for (i = 0; type2format[i].type; i++)
123 if (strcasecmp(mf_type, type2format[i].type) == 0)
124 break;
125 if (!type2format[i].type) {
126 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] unknown input file type.\n" );
127 free(mf);
128 return NULL;
130 sh_video->format = type2format[i].format;
132 sh_video->disp_w = mf_w;
133 sh_video->disp_h = mf_h;
134 sh_video->fps = mf_fps;
135 sh_video->frametime = 1 / sh_video->fps;
137 // emulate BITMAPINFOHEADER:
138 sh_video->bih=malloc(sizeof(BITMAPINFOHEADER));
139 memset(sh_video->bih,0,sizeof(BITMAPINFOHEADER));
140 sh_video->bih->biSize=40;
141 sh_video->bih->biWidth = mf_w;
142 sh_video->bih->biHeight = mf_h;
143 sh_video->bih->biPlanes=1;
144 sh_video->bih->biBitCount=24;
145 sh_video->bih->biCompression=sh_video->format;
146 sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3;
148 /* disable seeking */
149 // demuxer->seekable = 0;
151 demuxer->priv=(void*)mf;
153 return demuxer;
156 static void demux_close_mf(demuxer_t* demuxer) {
157 mf_t *mf = demuxer->priv;
159 if(!mf)
160 return;
161 free(mf);
164 static int demux_control_mf(demuxer_t *demuxer, int cmd, void *arg) {
165 mf_t *mf = (mf_t *)demuxer->priv;
166 sh_video_t *sh_video = demuxer->video->sh;
168 switch(cmd) {
169 case DEMUXER_CTRL_GET_TIME_LENGTH:
170 *((double *)arg) = (double)mf->nr_of_files / sh_video->fps;
171 return DEMUXER_CTRL_OK;
173 case DEMUXER_CTRL_GET_PERCENT_POS:
174 if (mf->nr_of_files <= 1)
175 return DEMUXER_CTRL_DONTKNOW;
176 *((int *)arg) = 100 * mf->curr_frame / (mf->nr_of_files - 1);
177 return DEMUXER_CTRL_OK;
179 default:
180 return DEMUXER_CTRL_NOTIMPL;
184 const demuxer_desc_t demuxer_desc_mf = {
185 "mf demuxer",
186 "mf",
187 "MF",
188 "?",
189 "multiframe?, pictures demuxer",
190 DEMUXER_TYPE_MF,
191 0, // no autodetect
192 NULL,
193 demux_mf_fill_buffer,
194 demux_open_mf,
195 demux_close_mf,
196 demux_seek_mf,
197 demux_control_mf