Mercurial > mplayer.hg
annotate libmpdemux/demux_vqf.c @ 36815:4c44fdd14655
Fix issue with Win32 GUI default preferences.
Don't (mis)use option variables to set defaults (and then don't use
them when actually setting the defaults in the preferences dialog).
Set them directly (and correctly) instead, and use proper symbolic
constants.
author | ib |
---|---|
date | Sun, 23 Feb 2014 19:33:46 +0000 |
parents | 92dd1764392a |
children |
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" |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
33674
diff
changeset
|
28 #include "mp_msg.h" |
14276 | 29 #include "demuxer.h" |
30 #include "stheader.h" | |
17012 | 31 #include "libmpcodecs/vqf.h" |
14276 | 32 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
33 static int demux_probe_vqf(demuxer_t* demuxer) |
14276 | 34 { |
35 char buf[KEYWORD_BYTES]; | |
36 stream_t *s; | |
37 s = demuxer->stream; | |
15818 | 38 if(stream_read(s,buf,KEYWORD_BYTES)!=KEYWORD_BYTES) |
39 return 0; | |
16175 | 40 if(memcmp(buf,"TWIN",KEYWORD_BYTES)==0) return DEMUXER_TYPE_VQF; /*version: 97012000*/ |
14276 | 41 return 0; |
42 } | |
43 | |
16175 | 44 static demuxer_t* demux_open_vqf(demuxer_t* demuxer) { |
14276 | 45 sh_audio_t* sh_audio; |
46 WAVEFORMATEX* w; | |
47 stream_t *s; | |
48 headerInfo *hi; | |
49 | |
50 s = demuxer->stream; | |
51 | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
29263
diff
changeset
|
52 sh_audio = new_sh_audio(demuxer,0, NULL); |
32111 | 53 sh_audio->wf = w = calloc(1, sizeof(*sh_audio->wf)+sizeof(headerInfo)); |
14276 | 54 hi = (headerInfo *)&w[1]; |
55 w->wFormatTag = 0x1; | |
56 sh_audio->format = mmioFOURCC('T','W','I','N'); /* TWinVQ */ | |
57 w->nChannels = sh_audio->channels = 2; | |
58 w->nSamplesPerSec = sh_audio->samplerate = 44100; | |
59 w->nAvgBytesPerSec = w->nSamplesPerSec*sh_audio->channels*2; | |
60 w->nBlockAlign = 0; | |
61 sh_audio->samplesize = 2; | |
62 w->wBitsPerSample = 8*sh_audio->samplesize; | |
63 w->cbSize = 0; | |
64 strcpy(hi->ID,"TWIN"); | |
65 stream_read(s,hi->ID+KEYWORD_BYTES,VERSION_BYTES); /* fourcc+version_id */ | |
66 while(1) | |
67 { | |
68 char chunk_id[4]; | |
69 unsigned chunk_size; | |
70 hi->size=chunk_size=stream_read_dword(s); /* include itself */ | |
71 stream_read(s,chunk_id,4); | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
72 if (chunk_size < 8) return NULL; |
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
73 chunk_size -= 8; |
28105 | 74 if(AV_RL32(chunk_id)==mmioFOURCC('C','O','M','M')) |
14276 | 75 { |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
76 char buf[BUFSIZ]; |
14276 | 77 unsigned i,subchunk_size; |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
78 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
|
79 if(stream_read(s,buf,chunk_size)!=chunk_size) return NULL; |
14276 | 80 i=0; |
28105 | 81 subchunk_size = AV_RB32(buf); |
82 hi->channelMode = AV_RB32(buf + 4); | |
14276 | 83 w->nChannels=sh_audio->channels=hi->channelMode+1; /*0-mono;1-stereo*/ |
28105 | 84 hi->bitRate = AV_RB32(buf + 8); |
14276 | 85 sh_audio->i_bps=hi->bitRate*1000/8; /* bitrate kbit/s */ |
86 w->nAvgBytesPerSec = sh_audio->i_bps; | |
28105 | 87 hi->samplingRate = AV_RB32(buf + 12); |
14276 | 88 switch(hi->samplingRate){ |
89 case 44: | |
90 w->nSamplesPerSec=44100; | |
91 break; | |
92 case 22: | |
93 w->nSamplesPerSec=22050; | |
94 break; | |
95 case 11: | |
96 w->nSamplesPerSec=11025; | |
97 break; | |
98 default: | |
99 w->nSamplesPerSec=hi->samplingRate*1000; | |
100 break; | |
101 } | |
102 sh_audio->samplerate=w->nSamplesPerSec; | |
28105 | 103 hi->securityLevel = AV_RB32(buf + 16); |
14276 | 104 w->nBlockAlign = 0; |
105 sh_audio->samplesize = 4; | |
106 w->wBitsPerSample = 8*sh_audio->samplesize; | |
107 w->cbSize = 0; | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
108 if (subchunk_size > chunk_size - 4) continue; |
14276 | 109 i+=subchunk_size+4; |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
110 while(i + 8 < chunk_size) |
14276 | 111 { |
112 unsigned slen,sid; | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
113 char sdata[BUFSIZ]; |
28105 | 114 sid = AV_RL32(buf + i); i+=4; |
115 slen = AV_RB32(buf + i); i+=4; | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
116 if (slen > sizeof(sdata) - 1 || slen > chunk_size - i) break; |
14276 | 117 if(sid==mmioFOURCC('D','S','I','Z')) |
118 { | |
28105 | 119 hi->Dsiz=AV_RB32(buf + i); |
14276 | 120 continue; /* describes the same info as size of DATA chunk */ |
121 } | |
122 memcpy(sdata,&buf[i],slen); sdata[slen]=0; i+=slen; | |
123 if(sid==mmioFOURCC('N','A','M','E')) | |
124 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
125 memcpy(hi->Name,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 126 demux_info_add(demuxer,"Title",sdata); |
127 } | |
128 else | |
129 if(sid==mmioFOURCC('A','U','T','H')) | |
130 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
131 memcpy(hi->Auth,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 132 demux_info_add(demuxer,"Author",sdata); |
133 } | |
134 else | |
135 if(sid==mmioFOURCC('C','O','M','T')) | |
136 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
137 memcpy(hi->Comt,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 138 demux_info_add(demuxer,"Comment",sdata); |
139 } | |
140 else | |
141 if(sid==mmioFOURCC('(','c',')',' ')) | |
142 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
143 memcpy(hi->Cpyr,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 144 demux_info_add(demuxer,"Copyright",sdata); |
145 } | |
146 else | |
147 if(sid==mmioFOURCC('F','I','L','E')) | |
148 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
149 memcpy(hi->File,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 150 } |
151 else | |
152 if(sid==mmioFOURCC('A','L','B','M')) demux_info_add(demuxer,"Album",sdata); | |
153 else | |
154 if(sid==mmioFOURCC('Y','E','A','R')) demux_info_add(demuxer,"Date",sdata); | |
155 else | |
156 if(sid==mmioFOURCC('T','R','A','C')) demux_info_add(demuxer,"Track",sdata); | |
157 else | |
158 if(sid==mmioFOURCC('E','N','C','D')) demux_info_add(demuxer,"Encoder",sdata); | |
159 else | |
160 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); | |
33674 | 161 /* rest not recognized due to untranslatable Japanese expressions */ |
14276 | 162 } |
163 } | |
164 else | |
28105 | 165 if(AV_RL32(chunk_id)==mmioFOURCC('D','A','T','A')) |
14276 | 166 { |
167 demuxer->movi_start=stream_tell(s); | |
28115
1a9b1b7e285f
Add extra checks to avoid crashes with broken vqf files.
reimar
parents:
28105
diff
changeset
|
168 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
|
169 mp_msg(MSGT_DEMUX, MSGL_V, "Found data at %"PRIX64" size %"PRIu64"\n",demuxer->movi_start,demuxer->movi_end); |
14276 | 170 /* Done! play it */ |
171 break; | |
172 } | |
173 else | |
174 { | |
28104 | 175 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
|
176 stream_skip(s,chunk_size); /*unknown chunk type */ |
14276 | 177 } |
178 } | |
179 | |
26299
4d56038ec730
Fix lots and lots of other demuxers broken by r26301
reimar
parents:
25883
diff
changeset
|
180 demuxer->audio->id = 0; |
14276 | 181 demuxer->audio->sh = sh_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", | |
33674 | 232 "ported from MPlayerXP", |
16175 | 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 }; |