Add missing #include, fixes the warning:
[mplayer/greg.git] / libmpdemux / demux_mf.c
blob38e90484bfffe1c261443ef4e5e704b8a5c220dd
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 & 1)?0:mf->curr_frame - 1;
23 if ( flags & 2 ) 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 { "png", mmioFOURCC('M', 'P', 'N', 'G') },
69 { "tga", mmioFOURCC('M', 'T', 'G', 'A') },
70 { "tif", mmioFOURCC('t', 'i', 'f', 'f') },
71 { "sgi", mmioFOURCC('S', 'G', 'I', '1') },
72 { NULL, 0 }
75 static demuxer_t* demux_open_mf(demuxer_t* demuxer){
76 sh_video_t *sh_video = NULL;
77 mf_t *mf = NULL;
78 int i;
80 if(!demuxer->stream->url) return NULL;
81 if(strncmp(demuxer->stream->url, "mf://", 5)) return NULL;
84 mf=open_mf(demuxer->stream->url + 5);
85 if(!mf) return NULL;
87 if(!mf_type){
88 char* p=strrchr(mf->names[0],'.');
89 if(!p){
90 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! (try -mf type=xxx)\n" );
91 free( mf ); return NULL;
93 mf_type=strdup(p+1);
94 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! trying 'type=%s'...\n", mf_type);
97 mf->curr_frame=0;
99 demuxer->movi_start = 0;
100 demuxer->movi_end = mf->nr_of_files - 1;
102 // create a new video stream header
103 sh_video = new_sh_video(demuxer, 0);
104 // make sure the demuxer knows about the new video stream header
105 // (even though new_sh_video() ought to take care of it)
106 demuxer->video->sh = sh_video;
108 // make sure that the video demuxer stream header knows about its
109 // parent video demuxer stream (this is getting wacky), or else
110 // video_read_properties() will choke
111 sh_video->ds = demuxer->video;
113 for (i = 0; type2format[i].type; i++)
114 if (strcasecmp(mf_type, type2format[i].type) == 0)
115 break;
116 if (!type2format[i].type) {
117 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] unknown input file type.\n" );
118 free(mf);
119 return NULL;
121 sh_video->format = type2format[i].format;
123 sh_video->disp_w = mf_w;
124 sh_video->disp_h = mf_h;
125 sh_video->fps = mf_fps;
126 sh_video->frametime = 1 / sh_video->fps;
128 // emulate BITMAPINFOHEADER:
129 sh_video->bih=malloc(sizeof(BITMAPINFOHEADER));
130 memset(sh_video->bih,0,sizeof(BITMAPINFOHEADER));
131 sh_video->bih->biSize=40;
132 sh_video->bih->biWidth = mf_w;
133 sh_video->bih->biHeight = mf_h;
134 sh_video->bih->biPlanes=1;
135 sh_video->bih->biBitCount=24;
136 sh_video->bih->biCompression=sh_video->format;
137 sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3;
139 /* disable seeking */
140 // demuxer->seekable = 0;
142 demuxer->priv=(void*)mf;
144 return demuxer;
147 static void demux_close_mf(demuxer_t* demuxer) {
148 mf_t *mf = demuxer->priv;
150 if(!mf)
151 return;
152 free(mf);
155 static int demux_control_mf(demuxer_t *demuxer, int cmd, void *arg) {
156 mf_t *mf = (mf_t *)demuxer->priv;
157 sh_video_t *sh_video = demuxer->video->sh;
159 switch(cmd) {
160 case DEMUXER_CTRL_GET_TIME_LENGTH:
161 *((double *)arg) = (double)mf->nr_of_files / sh_video->fps;
162 return DEMUXER_CTRL_OK;
164 case DEMUXER_CTRL_GET_PERCENT_POS:
165 if (mf->nr_of_files <= 1)
166 return DEMUXER_CTRL_DONTKNOW;
167 *((int *)arg) = 100 * mf->curr_frame / (mf->nr_of_files - 1);
168 return DEMUXER_CTRL_OK;
170 default:
171 return DEMUXER_CTRL_NOTIMPL;
175 demuxer_desc_t demuxer_desc_mf = {
176 "mf demuxer",
177 "mf",
178 "MF",
179 "?",
180 "multiframe?, pictures demuxer",
181 DEMUXER_TYPE_MF,
182 0, // no autodetect
183 NULL,
184 demux_mf_fill_buffer,
185 demux_open_mf,
186 demux_close_mf,
187 demux_seek_mf,
188 demux_control_mf