Mercurial > mplayer.hg
annotate libmpdemux/demux_mf.c @ 28992:947ef23ba798
Test if create_vdp_decoder() might succeed by calling it from config()
with a small value for max_reference_frames.
This does not make automatic recovery by using software decoder possible,
but lets MPlayer fail more graciously on - actually existing - buggy
hardware that does not support certain H264 widths when using
hardware accelerated decoding (784, 864, 944, 1024, 1808, 1888 pixels on
NVIDIA G98) and if the user tries to hardware-decode more samples at
the same time than supported.
Might break playback of H264 Intra-Only samples on hardware with very
little video memory.
author | cehoyos |
---|---|
date | Sat, 21 Mar 2009 20:11:05 +0000 |
parents | e2552a27678c |
children | d643e4643313 |
rev | line source |
---|---|
4550 | 1 |
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> | |
8 | |
9 #include "config.h" | |
10 #include "mp_msg.h" | |
11 #include "help_mp.h" | |
12 | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
22083
diff
changeset
|
13 #include "stream/stream.h" |
4550 | 14 #include "demuxer.h" |
15 #include "stheader.h" | |
16 #include "mf.h" | |
17 | |
17636 | 18 static void demux_seek_mf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ |
7407 | 19 mf_t * mf = (mf_t *)demuxer->priv; |
4565 | 20 sh_video_t * sh_video = demuxer->video->sh; |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
21 int newpos = (flags & SEEK_ABSOLUTE)?0:mf->curr_frame - 1; |
4565 | 22 |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
23 if ( flags & SEEK_FACTOR ) newpos+=rel_seek_secs*(mf->nr_of_files - 1); |
4565 | 24 else newpos+=rel_seek_secs * sh_video->fps; |
25 if ( newpos < 0 ) newpos=0; | |
19180 | 26 if( newpos >= mf->nr_of_files) newpos=mf->nr_of_files - 1; |
4565 | 27 mf->curr_frame=newpos; |
4550 | 28 } |
29 | |
30 // return value: | |
31 // 0 = EOF or no stream found | |
32 // 1 = successfully read a packet | |
16175 | 33 static int demux_mf_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){ |
4550 | 34 mf_t * mf; |
35 struct stat fs; | |
36 FILE * f; | |
37 | |
7407 | 38 mf=(mf_t*)demuxer->priv; |
39 if ( mf->curr_frame >= mf->nr_of_files ) return 0; | |
4550 | 40 |
7407 | 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 ); | |
4550 | 43 |
9992 | 44 if ( !( f=fopen( mf->names[mf->curr_frame],"rb" ) ) ) return 0; |
4550 | 45 { |
46 sh_video_t * sh_video = demuxer->video->sh; | |
47 demux_packet_t * dp = new_demux_packet( fs.st_size ); | |
4565 | 48 if ( !fread( dp->buffer,fs.st_size,1,f ) ) return 0; |
7407 | 49 dp->pts=mf->curr_frame / sh_video->fps; |
50 dp->pos=mf->curr_frame; | |
4550 | 51 dp->flags=0; |
52 // append packet to DS stream: | |
53 ds_add_packet( demuxer->video,dp ); | |
54 } | |
55 fclose( f ); | |
56 | |
7407 | 57 mf->curr_frame++; |
4550 | 58 return 1; |
59 } | |
60 | |
28990
e2552a27678c
map jls (jpeg-ls), thm and db (thumbnails) files to jpg
compn
parents:
26711
diff
changeset
|
61 // force extension/type to have a fourcc |
e2552a27678c
map jls (jpeg-ls), thm and db (thumbnails) files to jpg
compn
parents:
26711
diff
changeset
|
62 |
25033
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
63 static const struct { |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
64 const char *type; |
25062
25ee4d06a2df
100l, fix uint32_t* instead of uint32_t typo in demux_mf type->fourcc table
reimar
parents:
25034
diff
changeset
|
65 uint32_t format; |
25033
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
66 } type2format[] = { |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
67 { "bmp", mmioFOURCC('b', 'm', 'p', ' ') }, |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
68 { "jpeg", mmioFOURCC('I', 'J', 'P', 'G') }, |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
69 { "jpg", mmioFOURCC('I', 'J', 'P', 'G') }, |
28990
e2552a27678c
map jls (jpeg-ls), thm and db (thumbnails) files to jpg
compn
parents:
26711
diff
changeset
|
70 { "jls", mmioFOURCC('I', 'J', 'P', 'G') }, |
e2552a27678c
map jls (jpeg-ls), thm and db (thumbnails) files to jpg
compn
parents:
26711
diff
changeset
|
71 { "thm", mmioFOURCC('I', 'J', 'P', 'G') }, |
e2552a27678c
map jls (jpeg-ls), thm and db (thumbnails) files to jpg
compn
parents:
26711
diff
changeset
|
72 { "db", mmioFOURCC('I', 'J', 'P', 'G') }, |
25961 | 73 { "pcx", mmioFOURCC('p', 'c', 'x', ' ') }, |
25033
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
74 { "png", mmioFOURCC('M', 'P', 'N', 'G') }, |
26711 | 75 { "ptx", mmioFOURCC('p', 't', 'x', ' ') }, |
25033
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
76 { "tga", mmioFOURCC('M', 'T', 'G', 'A') }, |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
77 { "tif", mmioFOURCC('t', 'i', 'f', 'f') }, |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
78 { "sgi", mmioFOURCC('S', 'G', 'I', '1') }, |
26070 | 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', ' ') }, | |
25033
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
86 { NULL, 0 } |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
87 }; |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
88 |
16175 | 89 static demuxer_t* demux_open_mf(demuxer_t* demuxer){ |
4550 | 90 sh_video_t *sh_video = NULL; |
91 mf_t *mf = NULL; | |
25033
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
92 int i; |
7407 | 93 |
94 if(!demuxer->stream->url) return NULL; | |
22083
59982606e602
mf demuxer only works with mf:// urls, so check for that.
reimar
parents:
19794
diff
changeset
|
95 if(strncmp(demuxer->stream->url, "mf://", 5)) return NULL; |
9148
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
96 |
17624
7b30bef00830
allow autodetection of pictures type when using mf://@file.list syntax
iive
parents:
17569
diff
changeset
|
97 |
7b30bef00830
allow autodetection of pictures type when using mf://@file.list syntax
iive
parents:
17569
diff
changeset
|
98 mf=open_mf(demuxer->stream->url + 5); |
7b30bef00830
allow autodetection of pictures type when using mf://@file.list syntax
iive
parents:
17569
diff
changeset
|
99 if(!mf) return NULL; |
7b30bef00830
allow autodetection of pictures type when using mf://@file.list syntax
iive
parents:
17569
diff
changeset
|
100 |
9148
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
101 if(!mf_type){ |
17624
7b30bef00830
allow autodetection of pictures type when using mf://@file.list syntax
iive
parents:
17569
diff
changeset
|
102 char* p=strrchr(mf->names[0],'.'); |
9148
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
103 if(!p){ |
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
104 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! (try -mf type=xxx)\n" ); |
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
105 free( mf ); return NULL; |
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
106 } |
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
107 mf_type=strdup(p+1); |
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
108 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] file type was not set! trying 'type=%s'...\n", mf_type); |
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
109 } |
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
110 |
7407 | 111 mf->curr_frame=0; |
4550 | 112 |
113 demuxer->movi_start = 0; | |
114 demuxer->movi_end = mf->nr_of_files - 1; | |
115 | |
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; | |
121 | |
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; | |
9148
946b14a9e743
type autodetection (from filemask/filelist extension)
arpi
parents:
7407
diff
changeset
|
126 |
25033
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
127 for (i = 0; type2format[i].type; i++) |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
128 if (strcasecmp(mf_type, type2format[i].type) == 0) |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
129 break; |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
130 if (!type2format[i].type) { |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
131 mp_msg(MSGT_DEMUX, MSGL_INFO, "[demux_mf] unknown input file type.\n" ); |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
132 free(mf); |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
133 return NULL; |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
134 } |
3dceb6c96307
Replace if-else constructs for type -> fourcc mapping by a table in demux_mf
reimar
parents:
25020
diff
changeset
|
135 sh_video->format = type2format[i].format; |
4550 | 136 |
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; | |
141 | |
4556 | 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; | |
152 | |
4550 | 153 /* disable seeking */ |
4565 | 154 // demuxer->seekable = 0; |
4550 | 155 |
7407 | 156 demuxer->priv=(void*)mf; |
4550 | 157 |
158 return demuxer; | |
159 } | |
5810 | 160 |
16175 | 161 static void demux_close_mf(demuxer_t* demuxer) { |
7407 | 162 mf_t *mf = demuxer->priv; |
5810 | 163 |
7407 | 164 if(!mf) |
5810 | 165 return; |
7407 | 166 free(mf); |
5810 | 167 } |
16175 | 168 |
19220
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
169 static int demux_control_mf(demuxer_t *demuxer, int cmd, void *arg) { |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
170 mf_t *mf = (mf_t *)demuxer->priv; |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
171 sh_video_t *sh_video = demuxer->video->sh; |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
172 |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
173 switch(cmd) { |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
174 case DEMUXER_CTRL_GET_TIME_LENGTH: |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
175 *((double *)arg) = (double)mf->nr_of_files / sh_video->fps; |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
176 return DEMUXER_CTRL_OK; |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
177 |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
178 case DEMUXER_CTRL_GET_PERCENT_POS: |
19794
0951c3e8864b
Avoid division by zero DEMUXER_CTRL_GET_PERCENT_POS with only one frame by just
reimar
parents:
19220
diff
changeset
|
179 if (mf->nr_of_files <= 1) |
0951c3e8864b
Avoid division by zero DEMUXER_CTRL_GET_PERCENT_POS with only one frame by just
reimar
parents:
19220
diff
changeset
|
180 return DEMUXER_CTRL_DONTKNOW; |
19220
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
181 *((int *)arg) = 100 * mf->curr_frame / (mf->nr_of_files - 1); |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
182 return DEMUXER_CTRL_OK; |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
183 |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
184 default: |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
185 return DEMUXER_CTRL_NOTIMPL; |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
186 } |
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
187 } |
16175 | 188 |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25062
diff
changeset
|
189 const demuxer_desc_t demuxer_desc_mf = { |
16175 | 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, | |
19220
fbd2391fcbb8
Implement DEMUXER_CTRL_GET_TIME_LENGTH and DEMUXER_CTRL_GET_PERCENT_POS,
reimar
parents:
19180
diff
changeset
|
202 demux_control_mf |
16175 | 203 }; |