lirc anc lircc are MPlayer-only, so add LDFLAGS for MPlayer link only.
[mplayer/glamo.git] / libmpdemux / demux_mf.c
blobdc990c0b8f29f632b29e7fcf2d3a837fec72c58d
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 // force extension/type to have a fourcc
63 static const struct {
64 const char *type;
65 uint32_t format;
66 } type2format[] = {
67 { "bmp", mmioFOURCC('b', 'm', 'p', ' ') },
68 { "jpeg", mmioFOURCC('I', 'J', 'P', 'G') },
69 { "jpg", mmioFOURCC('I', 'J', 'P', 'G') },
70 { "jls", mmioFOURCC('I', 'J', 'P', 'G') },
71 { "thm", mmioFOURCC('I', 'J', 'P', 'G') },
72 { "db", mmioFOURCC('I', 'J', 'P', 'G') },
73 { "pcx", mmioFOURCC('p', 'c', 'x', ' ') },
74 { "png", mmioFOURCC('M', 'P', 'N', 'G') },
75 { "ptx", mmioFOURCC('p', 't', 'x', ' ') },
76 { "tga", mmioFOURCC('M', 'T', 'G', 'A') },
77 { "tif", mmioFOURCC('t', 'i', 'f', 'f') },
78 { "sgi", mmioFOURCC('S', 'G', 'I', '1') },
79 { "sun", mmioFOURCC('s', 'u', 'n', ' ') },
80 { "ras", mmioFOURCC('s', 'u', 'n', ' ') },
81 { "ra", mmioFOURCC('s', 'u', 'n', ' ') },
82 { "im1", mmioFOURCC('s', 'u', 'n', ' ') },
83 { "im8", mmioFOURCC('s', 'u', 'n', ' ') },
84 { "im24", mmioFOURCC('s', 'u', 'n', ' ') },
85 { "sunras", mmioFOURCC('s', 'u', 'n', ' ') },
86 { NULL, 0 }
89 static demuxer_t* demux_open_mf(demuxer_t* demuxer){
90 sh_video_t *sh_video = NULL;
91 mf_t *mf = NULL;
92 int i;
94 if(!demuxer->stream->url) return NULL;
95 if(strncmp(demuxer->stream->url, "mf://", 5)) return NULL;
98 mf=open_mf(demuxer->stream->url + 5);
99 if(!mf) return NULL;
101 if(!mf_type){
102 char* p=strrchr(mf->names[0],'.');
103 if(!p){
104 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! (try -mf type=xxx)\n" );
105 free( mf ); return NULL;
107 mf_type=strdup(p+1);
108 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! trying 'type=%s'...\n", mf_type);
111 mf->curr_frame=0;
113 demuxer->movi_start = 0;
114 demuxer->movi_end = mf->nr_of_files - 1;
116 // create a new video stream header
117 sh_video = new_sh_video(demuxer, 0);
118 // make sure the demuxer knows about the new video stream header
119 // (even though new_sh_video() ought to take care of it)
120 demuxer->video->sh = sh_video;
122 // make sure that the video demuxer stream header knows about its
123 // parent video demuxer stream (this is getting wacky), or else
124 // video_read_properties() will choke
125 sh_video->ds = demuxer->video;
127 for (i = 0; type2format[i].type; i++)
128 if (strcasecmp(mf_type, type2format[i].type) == 0)
129 break;
130 if (!type2format[i].type) {
131 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] unknown input file type.\n" );
132 free(mf);
133 return NULL;
135 sh_video->format = type2format[i].format;
137 sh_video->disp_w = mf_w;
138 sh_video->disp_h = mf_h;
139 sh_video->fps = mf_fps;
140 sh_video->frametime = 1 / sh_video->fps;
142 // emulate BITMAPINFOHEADER:
143 sh_video->bih=malloc(sizeof(BITMAPINFOHEADER));
144 memset(sh_video->bih,0,sizeof(BITMAPINFOHEADER));
145 sh_video->bih->biSize=40;
146 sh_video->bih->biWidth = mf_w;
147 sh_video->bih->biHeight = mf_h;
148 sh_video->bih->biPlanes=1;
149 sh_video->bih->biBitCount=24;
150 sh_video->bih->biCompression=sh_video->format;
151 sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3;
153 /* disable seeking */
154 // demuxer->seekable = 0;
156 demuxer->priv=(void*)mf;
158 return demuxer;
161 static void demux_close_mf(demuxer_t* demuxer) {
162 mf_t *mf = demuxer->priv;
164 if(!mf)
165 return;
166 free(mf);
169 static int demux_control_mf(demuxer_t *demuxer, int cmd, void *arg) {
170 mf_t *mf = (mf_t *)demuxer->priv;
171 sh_video_t *sh_video = demuxer->video->sh;
173 switch(cmd) {
174 case DEMUXER_CTRL_GET_TIME_LENGTH:
175 *((double *)arg) = (double)mf->nr_of_files / sh_video->fps;
176 return DEMUXER_CTRL_OK;
178 case DEMUXER_CTRL_GET_PERCENT_POS:
179 if (mf->nr_of_files <= 1)
180 return DEMUXER_CTRL_DONTKNOW;
181 *((int *)arg) = 100 * mf->curr_frame / (mf->nr_of_files - 1);
182 return DEMUXER_CTRL_OK;
184 default:
185 return DEMUXER_CTRL_NOTIMPL;
189 const demuxer_desc_t demuxer_desc_mf = {
190 "mf demuxer",
191 "mf",
192 "MF",
193 "?",
194 "multiframe?, pictures demuxer",
195 DEMUXER_TYPE_MF,
196 0, // no autodetect
197 NULL,
198 demux_mf_fill_buffer,
199 demux_open_mf,
200 demux_close_mf,
201 demux_seek_mf,
202 demux_control_mf