Mercurial > mplayer.hg
annotate libmpdemux/demux_vqf.c @ 33259:04dc3e55cd90
Increase the maximum value of the DVB timeout to 240 seconds.
Some devices may need more time for the initial tune (e.g. firmware loading).
Let the user specify higher timeout value if there is need to.
The default remains 30 seconds.
author | iive |
---|---|
date | Sun, 01 May 2011 18:07:59 +0000 |
parents | 7c8d240d37a6 |
children | 4fc2a8d8a042 |
rev | line source |
---|---|
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
1 /* |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
2 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
3 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
7 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
8 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
12 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
13 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
17 */ |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28115
diff
changeset
|
18 |
14276 | 19 #include "config.h" |
20 | |
21 #include <stdlib.h> | |
22 #include <stdio.h> | |
21372 | 23 #include "libavutil/common.h" |
28105 | 24 #include "libavutil/intreadwrite.h" |
21507
fa99b3d31d13
Hack around libavutil/bswap.h compilation problems due to always_inline undefined.
reimar
parents:
21372
diff
changeset
|
25 #include "mpbswap.h" |
14276 | 26 |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
21531
diff
changeset
|
27 #include "stream/stream.h" |
14276 | 28 #include "demuxer.h" |
29 #include "stheader.h" | |
17012 | 30 #include "libmpcodecs/vqf.h" |
14276 | 31 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
32 static int demux_probe_vqf(demuxer_t* demuxer) |
14276 | 33 { |
34 char buf[KEYWORD_BYTES]; | |
35 stream_t *s; | |
36 s = demuxer->stream; | |
15818 | 37 if(stream_read(s,buf,KEYWORD_BYTES)!=KEYWORD_BYTES) |
38 return 0; | |
16175 | 39 if(memcmp(buf,"TWIN",KEYWORD_BYTES)==0) return DEMUXER_TYPE_VQF; /*version: 97012000*/ |
14276 | 40 return 0; |
41 } | |
42 | |
16175 | 43 static demuxer_t* demux_open_vqf(demuxer_t* demuxer) { |
14276 | 44 sh_audio_t* sh_audio; |
45 WAVEFORMATEX* w; | |
46 stream_t *s; | |
47 headerInfo *hi; | |
48 | |
49 s = demuxer->stream; | |
50 | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
29263
diff
changeset
|
51 sh_audio = new_sh_audio(demuxer,0, NULL); |
32111 | 52 sh_audio->wf = w = calloc(1, sizeof(*sh_audio->wf)+sizeof(headerInfo)); |
14276 | 53 hi = (headerInfo *)&w[1]; |
54 w->wFormatTag = 0x1; | |
55 sh_audio->format = mmioFOURCC('T','W','I','N'); /* TWinVQ */ | |
56 w->nChannels = sh_audio->channels = 2; | |
57 w->nSamplesPerSec = sh_audio->samplerate = 44100; | |
58 w->nAvgBytesPerSec = w->nSamplesPerSec*sh_audio->channels*2; | |
59 w->nBlockAlign = 0; | |
60 sh_audio->samplesize = 2; | |
61 w->wBitsPerSample = 8*sh_audio->samplesize; | |
62 w->cbSize = 0; | |
63 strcpy(hi->ID,"TWIN"); | |
64 stream_read(s,hi->ID+KEYWORD_BYTES,VERSION_BYTES); /* fourcc+version_id */ | |
65 while(1) | |
66 { | |
67 char chunk_id[4]; | |
68 unsigned chunk_size; | |
69 hi->size=chunk_size=stream_read_dword(s); /* include itself */ | |
70 stream_read(s,chunk_id,4); | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
71 if (chunk_size < 8) return NULL; |
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
72 chunk_size -= 8; |
28105 | 73 if(AV_RL32(chunk_id)==mmioFOURCC('C','O','M','M')) |
14276 | 74 { |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
75 char buf[BUFSIZ]; |
14276 | 76 unsigned i,subchunk_size; |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
77 if (chunk_size > sizeof(buf) || chunk_size < 20) return NULL; |
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
78 if(stream_read(s,buf,chunk_size)!=chunk_size) return NULL; |
14276 | 79 i=0; |
28105 | 80 subchunk_size = AV_RB32(buf); |
81 hi->channelMode = AV_RB32(buf + 4); | |
14276 | 82 w->nChannels=sh_audio->channels=hi->channelMode+1; /*0-mono;1-stereo*/ |
28105 | 83 hi->bitRate = AV_RB32(buf + 8); |
14276 | 84 sh_audio->i_bps=hi->bitRate*1000/8; /* bitrate kbit/s */ |
85 w->nAvgBytesPerSec = sh_audio->i_bps; | |
28105 | 86 hi->samplingRate = AV_RB32(buf + 12); |
14276 | 87 switch(hi->samplingRate){ |
88 case 44: | |
89 w->nSamplesPerSec=44100; | |
90 break; | |
91 case 22: | |
92 w->nSamplesPerSec=22050; | |
93 break; | |
94 case 11: | |
95 w->nSamplesPerSec=11025; | |
96 break; | |
97 default: | |
98 w->nSamplesPerSec=hi->samplingRate*1000; | |
99 break; | |
100 } | |
101 sh_audio->samplerate=w->nSamplesPerSec; | |
28105 | 102 hi->securityLevel = AV_RB32(buf + 16); |
14276 | 103 w->nBlockAlign = 0; |
104 sh_audio->samplesize = 4; | |
105 w->wBitsPerSample = 8*sh_audio->samplesize; | |
106 w->cbSize = 0; | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
107 if (subchunk_size > chunk_size - 4) continue; |
14276 | 108 i+=subchunk_size+4; |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
109 while(i + 8 < chunk_size) |
14276 | 110 { |
111 unsigned slen,sid; | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
112 char sdata[BUFSIZ]; |
28105 | 113 sid = AV_RL32(buf + i); i+=4; |
114 slen = AV_RB32(buf + i); i+=4; | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
115 if (slen > sizeof(sdata) - 1 || slen > chunk_size - i) break; |
14276 | 116 if(sid==mmioFOURCC('D','S','I','Z')) |
117 { | |
28105 | 118 hi->Dsiz=AV_RB32(buf + i); |
14276 | 119 continue; /* describes the same info as size of DATA chunk */ |
120 } | |
121 memcpy(sdata,&buf[i],slen); sdata[slen]=0; i+=slen; | |
122 if(sid==mmioFOURCC('N','A','M','E')) | |
123 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
124 memcpy(hi->Name,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 125 demux_info_add(demuxer,"Title",sdata); |
126 } | |
127 else | |
128 if(sid==mmioFOURCC('A','U','T','H')) | |
129 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
130 memcpy(hi->Auth,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 131 demux_info_add(demuxer,"Author",sdata); |
132 } | |
133 else | |
134 if(sid==mmioFOURCC('C','O','M','T')) | |
135 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
136 memcpy(hi->Comt,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 137 demux_info_add(demuxer,"Comment",sdata); |
138 } | |
139 else | |
140 if(sid==mmioFOURCC('(','c',')',' ')) | |
141 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
142 memcpy(hi->Cpyr,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 143 demux_info_add(demuxer,"Copyright",sdata); |
144 } | |
145 else | |
146 if(sid==mmioFOURCC('F','I','L','E')) | |
147 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
148 memcpy(hi->File,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 149 } |
150 else | |
151 if(sid==mmioFOURCC('A','L','B','M')) demux_info_add(demuxer,"Album",sdata); | |
152 else | |
153 if(sid==mmioFOURCC('Y','E','A','R')) demux_info_add(demuxer,"Date",sdata); | |
154 else | |
155 if(sid==mmioFOURCC('T','R','A','C')) demux_info_add(demuxer,"Track",sdata); | |
156 else | |
157 if(sid==mmioFOURCC('E','N','C','D')) demux_info_add(demuxer,"Encoder",sdata); | |
158 else | |
159 mp_msg(MSGT_DEMUX, MSGL_V, "Unhandled subchunk '%c%c%c%c'='%s'\n",((char *)&sid)[0],((char *)&sid)[1],((char *)&sid)[2],((char *)&sid)[3],sdata); | |
160 /* other stuff is unrecognized due untranslatable japan's idiomatics */ | |
161 } | |
162 } | |
163 else | |
28105 | 164 if(AV_RL32(chunk_id)==mmioFOURCC('D','A','T','A')) |
14276 | 165 { |
166 demuxer->movi_start=stream_tell(s); | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
167 demuxer->movi_end=demuxer->movi_start+chunk_size; |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16175
diff
changeset
|
168 mp_msg(MSGT_DEMUX, MSGL_V, "Found data at %"PRIX64" size %"PRIu64"\n",demuxer->movi_start,demuxer->movi_end); |
14276 | 169 /* Done! play it */ |
170 break; | |
171 } | |
172 else | |
173 { | |
28104 | 174 mp_msg(MSGT_DEMUX, MSGL_V, "Unhandled chunk '%c%c%c%c' %u bytes\n",chunk_id[0],chunk_id[1],chunk_id[2],chunk_id[3],chunk_size); |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
175 stream_skip(s,chunk_size); /*unknown chunk type */ |
14276 | 176 } |
177 } | |
178 | |
26299
4d56038ec730
Fix lots and lots of other demuxers broken by r26301
reimar
parents:
25883
diff
changeset
|
179 demuxer->audio->id = 0; |
14276 | 180 demuxer->audio->sh = sh_audio; |
181 sh_audio->ds = demuxer->audio; | |
182 stream_seek(s,demuxer->movi_start); | |
183 demuxer->seekable=0; | |
184 return demuxer; | |
185 } | |
186 | |
16175 | 187 static int demux_vqf_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) { |
14276 | 188 sh_audio_t* sh_audio = demuxer->audio->sh; |
189 int l = sh_audio->wf->nAvgBytesPerSec; | |
190 off_t spos = stream_tell(demuxer->stream); | |
191 demux_packet_t* dp; | |
192 | |
193 if(stream_eof(demuxer->stream)) | |
194 return 0; | |
195 | |
196 dp = new_demux_packet(l); | |
197 ds->pts = spos / (float)(sh_audio->wf->nAvgBytesPerSec); | |
198 ds->pos = spos; | |
199 | |
200 l=stream_read(demuxer->stream,dp->buffer,l); | |
201 resize_demux_packet(dp,l); | |
202 ds_add_packet(ds,dp); | |
203 | |
204 return 1; | |
205 } | |
206 | |
17636 | 207 static void demux_seek_vqf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ |
14276 | 208 #if 0 |
209 stream_t* s = demuxer->stream; | |
210 sh_audio_t* sh_audio = demuxer->audio->sh; | |
211 off_t base,pos; | |
212 | |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
213 base = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : stream_tell(s); |
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
214 if(flags & SEEK_FACTOR) |
14276 | 215 pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs); |
216 else | |
217 pos = base + (rel_seek_secs*sh_audio->i_bps); | |
218 | |
219 pos -= (pos % (sh_audio->channels * sh_audio->samplesize) ); | |
220 stream_seek(s,pos); | |
221 #endif | |
222 } | |
223 | |
16175 | 224 static void demux_close_vqf(demuxer_t* demuxer) {} |
225 | |
226 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
22605
diff
changeset
|
227 const demuxer_desc_t demuxer_desc_vqf = { |
16175 | 228 "TwinVQ demuxer", |
229 "vqf", | |
230 "VQF", | |
231 "Nick Kurshev", | |
232 "ported frm MPlayerXP", | |
233 DEMUXER_TYPE_VQF, | |
234 1, // safe autodetect | |
235 demux_probe_vqf, | |
236 demux_vqf_fill_buffer, | |
237 demux_open_vqf, | |
238 demux_close_vqf, | |
239 demux_seek_vqf, | |
240 NULL | |
241 }; |