Mercurial > mplayer.hg
annotate libmpdemux/demux_vqf.c @ 24674:f6cf2c01315d
Format 0x01 cannot be used with "AMV IMA ADPCM", because it belongs to normal PCM.
Make lavf demuxer set codec tag to AMVA in this case.
No need to use -ac +ffadpcmimaamva anymore.
author | voroshil |
---|---|
date | Wed, 03 Oct 2007 15:27:02 +0000 |
parents | 4d81dbdf46b9 |
children | d4fe6e23283e |
rev | line source |
---|---|
14276 | 1 #include "config.h" |
2 | |
3 #include <stdlib.h> | |
4 #include <stdio.h> | |
21372 | 5 #include "libavutil/common.h" |
21507
fa99b3d31d13
Hack around libavutil/bswap.h compilation problems due to always_inline undefined.
reimar
parents:
21372
diff
changeset
|
6 #include "mpbswap.h" |
14276 | 7 |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
21531
diff
changeset
|
8 #include "stream/stream.h" |
14276 | 9 #include "demuxer.h" |
10 #include "stheader.h" | |
17012 | 11 #include "libmpcodecs/vqf.h" |
14276 | 12 |
16175 | 13 static int demux_probe_vqf(demuxer_t* demuxer) |
14276 | 14 { |
15 char buf[KEYWORD_BYTES]; | |
16 stream_t *s; | |
17 s = demuxer->stream; | |
15818 | 18 if(stream_read(s,buf,KEYWORD_BYTES)!=KEYWORD_BYTES) |
19 return 0; | |
16175 | 20 if(memcmp(buf,"TWIN",KEYWORD_BYTES)==0) return DEMUXER_TYPE_VQF; /*version: 97012000*/ |
14276 | 21 return 0; |
22 } | |
23 | |
16175 | 24 static demuxer_t* demux_open_vqf(demuxer_t* demuxer) { |
14276 | 25 sh_audio_t* sh_audio; |
26 WAVEFORMATEX* w; | |
27 stream_t *s; | |
28 headerInfo *hi; | |
29 | |
30 s = demuxer->stream; | |
31 | |
32 sh_audio = new_sh_audio(demuxer,0); | |
19062
83c3afeab35d
drops casts from void * on malloc/calloc from libmpdemux code
reynaldo
parents:
17636
diff
changeset
|
33 sh_audio->wf = w = malloc(sizeof(WAVEFORMATEX)+sizeof(headerInfo)); |
14276 | 34 hi = (headerInfo *)&w[1]; |
35 memset(hi,0,sizeof(headerInfo)); | |
36 w->wFormatTag = 0x1; | |
37 sh_audio->format = mmioFOURCC('T','W','I','N'); /* TWinVQ */ | |
38 w->nChannels = sh_audio->channels = 2; | |
39 w->nSamplesPerSec = sh_audio->samplerate = 44100; | |
40 w->nAvgBytesPerSec = w->nSamplesPerSec*sh_audio->channels*2; | |
41 w->nBlockAlign = 0; | |
42 sh_audio->samplesize = 2; | |
43 w->wBitsPerSample = 8*sh_audio->samplesize; | |
44 w->cbSize = 0; | |
45 strcpy(hi->ID,"TWIN"); | |
46 stream_read(s,hi->ID+KEYWORD_BYTES,VERSION_BYTES); /* fourcc+version_id */ | |
47 while(1) | |
48 { | |
49 char chunk_id[4]; | |
50 unsigned chunk_size; | |
51 hi->size=chunk_size=stream_read_dword(s); /* include itself */ | |
52 stream_read(s,chunk_id,4); | |
53 if(*((uint32_t *)&chunk_id[0])==mmioFOURCC('C','O','M','M')) | |
54 { | |
55 char buf[chunk_size-8]; | |
56 unsigned i,subchunk_size; | |
57 if(stream_read(s,buf,chunk_size-8)!=chunk_size-8) return NULL; | |
58 i=0; | |
59 subchunk_size=be2me_32(*((uint32_t *)&buf[0])); | |
60 hi->channelMode=be2me_32(*((uint32_t *)&buf[4])); | |
61 w->nChannels=sh_audio->channels=hi->channelMode+1; /*0-mono;1-stereo*/ | |
62 hi->bitRate=be2me_32(*((uint32_t *)&buf[8])); | |
63 sh_audio->i_bps=hi->bitRate*1000/8; /* bitrate kbit/s */ | |
64 w->nAvgBytesPerSec = sh_audio->i_bps; | |
65 hi->samplingRate=be2me_32(*((uint32_t *)&buf[12])); | |
66 switch(hi->samplingRate){ | |
67 case 44: | |
68 w->nSamplesPerSec=44100; | |
69 break; | |
70 case 22: | |
71 w->nSamplesPerSec=22050; | |
72 break; | |
73 case 11: | |
74 w->nSamplesPerSec=11025; | |
75 break; | |
76 default: | |
77 w->nSamplesPerSec=hi->samplingRate*1000; | |
78 break; | |
79 } | |
80 sh_audio->samplerate=w->nSamplesPerSec; | |
81 hi->securityLevel=be2me_32(*((uint32_t *)&buf[16])); | |
82 w->nBlockAlign = 0; | |
83 sh_audio->samplesize = 4; | |
84 w->wBitsPerSample = 8*sh_audio->samplesize; | |
85 w->cbSize = 0; | |
86 i+=subchunk_size+4; | |
87 while(i<chunk_size-8) | |
88 { | |
89 unsigned slen,sid; | |
90 char sdata[chunk_size]; | |
91 sid=*((uint32_t *)&buf[i]); i+=4; | |
92 slen=be2me_32(*((uint32_t *)&buf[i])); i+=4; | |
93 if(sid==mmioFOURCC('D','S','I','Z')) | |
94 { | |
95 hi->Dsiz=be2me_32(*((uint32_t *)&buf[i])); | |
96 continue; /* describes the same info as size of DATA chunk */ | |
97 } | |
98 memcpy(sdata,&buf[i],slen); sdata[slen]=0; i+=slen; | |
99 if(sid==mmioFOURCC('N','A','M','E')) | |
100 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
101 memcpy(hi->Name,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 102 demux_info_add(demuxer,"Title",sdata); |
103 } | |
104 else | |
105 if(sid==mmioFOURCC('A','U','T','H')) | |
106 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
107 memcpy(hi->Auth,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 108 demux_info_add(demuxer,"Author",sdata); |
109 } | |
110 else | |
111 if(sid==mmioFOURCC('C','O','M','T')) | |
112 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
113 memcpy(hi->Comt,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 114 demux_info_add(demuxer,"Comment",sdata); |
115 } | |
116 else | |
117 if(sid==mmioFOURCC('(','c',')',' ')) | |
118 { | |
21531
a90aa203186c
Get rid of min/max macros from aviheader.h, they do not belong here.
reimar
parents:
21507
diff
changeset
|
119 memcpy(hi->Cpyr,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 120 demux_info_add(demuxer,"Copyright",sdata); |
121 } | |
122 else | |
123 if(sid==mmioFOURCC('F','I','L','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->File,sdata,FFMIN(BUFSIZ,slen)); |
14276 | 126 } |
127 else | |
128 if(sid==mmioFOURCC('A','L','B','M')) demux_info_add(demuxer,"Album",sdata); | |
129 else | |
130 if(sid==mmioFOURCC('Y','E','A','R')) demux_info_add(demuxer,"Date",sdata); | |
131 else | |
132 if(sid==mmioFOURCC('T','R','A','C')) demux_info_add(demuxer,"Track",sdata); | |
133 else | |
134 if(sid==mmioFOURCC('E','N','C','D')) demux_info_add(demuxer,"Encoder",sdata); | |
135 else | |
136 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); | |
137 /* other stuff is unrecognized due untranslatable japan's idiomatics */ | |
138 } | |
139 } | |
140 else | |
141 if(*((uint32_t *)&chunk_id[0])==mmioFOURCC('D','A','T','A')) | |
142 { | |
143 demuxer->movi_start=stream_tell(s); | |
144 demuxer->movi_end=demuxer->movi_start+chunk_size-8; | |
16750
0a31740dd5e6
Use PRI?64 defines as format strings for 64 bit variables.
reimar
parents:
16175
diff
changeset
|
145 mp_msg(MSGT_DEMUX, MSGL_V, "Found data at %"PRIX64" size %"PRIu64"\n",demuxer->movi_start,demuxer->movi_end); |
14276 | 146 /* Done! play it */ |
147 break; | |
148 } | |
149 else | |
150 { | |
151 mp_msg(MSGT_DEMUX, MSGL_V, "Unhandled chunk '%c%c%c%c' %u bytes\n",((char *)&chunk_id)[0],((char *)&chunk_id)[1],((char *)&chunk_id)[2],((char *)&chunk_id)[3],chunk_size); | |
152 stream_skip(s,chunk_size-8); /*unknown chunk type */ | |
153 } | |
154 } | |
155 | |
156 demuxer->audio->sh = sh_audio; | |
157 sh_audio->ds = demuxer->audio; | |
158 stream_seek(s,demuxer->movi_start); | |
159 demuxer->seekable=0; | |
160 return demuxer; | |
161 } | |
162 | |
16175 | 163 static int demux_vqf_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) { |
14276 | 164 sh_audio_t* sh_audio = demuxer->audio->sh; |
165 int l = sh_audio->wf->nAvgBytesPerSec; | |
166 off_t spos = stream_tell(demuxer->stream); | |
167 demux_packet_t* dp; | |
168 | |
169 if(stream_eof(demuxer->stream)) | |
170 return 0; | |
171 | |
172 dp = new_demux_packet(l); | |
173 ds->pts = spos / (float)(sh_audio->wf->nAvgBytesPerSec); | |
174 ds->pos = spos; | |
175 | |
176 l=stream_read(demuxer->stream,dp->buffer,l); | |
177 resize_demux_packet(dp,l); | |
178 ds_add_packet(ds,dp); | |
179 | |
180 return 1; | |
181 } | |
182 | |
17636 | 183 static void demux_seek_vqf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ |
14276 | 184 #if 0 |
185 stream_t* s = demuxer->stream; | |
186 sh_audio_t* sh_audio = demuxer->audio->sh; | |
187 off_t base,pos; | |
188 | |
189 base = (flags & 1) ? demuxer->movi_start : stream_tell(s); | |
190 if(flags & 2) | |
191 pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs); | |
192 else | |
193 pos = base + (rel_seek_secs*sh_audio->i_bps); | |
194 | |
195 pos -= (pos % (sh_audio->channels * sh_audio->samplesize) ); | |
196 stream_seek(s,pos); | |
197 #endif | |
198 } | |
199 | |
16175 | 200 static void demux_close_vqf(demuxer_t* demuxer) {} |
201 | |
202 | |
203 demuxer_desc_t demuxer_desc_vqf = { | |
204 "TwinVQ demuxer", | |
205 "vqf", | |
206 "VQF", | |
207 "Nick Kurshev", | |
208 "ported frm MPlayerXP", | |
209 DEMUXER_TYPE_VQF, | |
210 1, // safe autodetect | |
211 demux_probe_vqf, | |
212 demux_vqf_fill_buffer, | |
213 demux_open_vqf, | |
214 demux_close_vqf, | |
215 demux_seek_vqf, | |
216 NULL | |
217 }; |