Mercurial > mplayer.hg
comparison libmpdemux/demux_real.c @ 3788:d554b5b33d76
improved audio codec detection
author | alex |
---|---|
date | Thu, 27 Dec 2001 10:15:13 +0000 |
parents | 026ccd3dc489 |
children | 15745f11e717 |
comparison
equal
deleted
inserted
replaced
3787:55603340d1b2 | 3788:d554b5b33d76 |
---|---|
2 Real parser & demuxer | 2 Real parser & demuxer |
3 | 3 |
4 (C) Alex Beregszaszi <alex@naxine.org> | 4 (C) Alex Beregszaszi <alex@naxine.org> |
5 | 5 |
6 Based on FFmpeg's libav/rm.c. | 6 Based on FFmpeg's libav/rm.c. |
7 */ | |
8 | |
9 /* | |
10 Some codecs for Real (from Mike Melanson): | |
11 | |
12 RV10: As has been mentioned, H.263-based; not an unreasonable guess | |
13 RV20: RealVideo 2.0, nothing known | |
14 RV30: RealVideo 3.0,nothing known, but I don't believe I've ever seen any | |
15 media encoded with it | |
16 DNET: apparently one of their original audio codecs, to be used with music | |
17 SIPR: SiprNet, based on ACELP, and is great for compressing voice | |
18 COKR(?): Cooker, the fabled G2 audio codec | |
7 */ | 19 */ |
8 | 20 |
9 #include <stdio.h> | 21 #include <stdio.h> |
10 #include <stdlib.h> | 22 #include <stdlib.h> |
11 #include <unistd.h> | 23 #include <unistd.h> |
202 stream_skip(demuxer->stream, 4); /* data offset */ | 214 stream_skip(demuxer->stream, 4); /* data offset */ |
203 stream_skip(demuxer->stream, 2); /* nb streams */ | 215 stream_skip(demuxer->stream, 2); /* nb streams */ |
204 stream_skip(demuxer->stream, 2); /* flags */ | 216 stream_skip(demuxer->stream, 2); /* flags */ |
205 break; | 217 break; |
206 case MKTAG('C', 'O', 'N', 'T'): | 218 case MKTAG('C', 'O', 'N', 'T'): |
219 { | |
220 char *buf; | |
221 int len; | |
222 | |
207 printf("Broadcasting informations (title, author, copyright, comment)\n"); | 223 printf("Broadcasting informations (title, author, copyright, comment)\n"); |
208 skip_str(0, demuxer); /* title */ | 224 |
209 skip_str(0, demuxer); /* author */ | 225 len = stream_read_word(demuxer->stream); |
210 skip_str(0, demuxer); /* copyright */ | 226 if (len > 0) |
211 skip_str(0, demuxer); /* comment */ | 227 { |
228 buf = malloc(len+1); | |
229 stream_read(demuxer->stream, buf, len); | |
230 demux_info_add(demuxer, "name", buf); | |
231 free(buf); | |
232 } | |
233 | |
234 len = stream_read_word(demuxer->stream); | |
235 if (len > 0) | |
236 { | |
237 buf = malloc(len+1); | |
238 stream_read(demuxer->stream, buf, len); | |
239 demux_info_add(demuxer, "author", buf); | |
240 free(buf); | |
241 } | |
242 | |
243 len = stream_read_word(demuxer->stream); | |
244 if (len > 0) | |
245 { | |
246 buf = malloc(len+1); | |
247 stream_read(demuxer->stream, buf, len); | |
248 demux_info_add(demuxer, "copyright", buf); | |
249 free(buf); | |
250 } | |
251 | |
252 len = stream_read_word(demuxer->stream); | |
253 if (len > 0) | |
254 { | |
255 buf = malloc(len+1); | |
256 stream_read(demuxer->stream, buf, len); | |
257 demux_info_add(demuxer, "comment", buf); | |
258 free(buf); | |
259 } | |
260 | |
261 // skip_str(0, demuxer); /* title */ | |
262 // skip_str(0, demuxer); /* author */ | |
263 // skip_str(0, demuxer); /* copyright */ | |
264 // skip_str(0, demuxer); /* comment */ | |
212 break; | 265 break; |
266 } | |
213 case MKTAG('M', 'D', 'P', 'R'): | 267 case MKTAG('M', 'D', 'P', 'R'): |
214 { | 268 { |
215 /* new stream */ | 269 /* new stream */ |
216 int stream_id; | 270 int stream_id; |
217 int bitrate; | 271 int bitrate; |
240 if (v == MKTAG(0xfd, 'a', 'r', '.')) /* audio header */ | 294 if (v == MKTAG(0xfd, 'a', 'r', '.')) /* audio header */ |
241 { | 295 { |
242 sh_audio_t *sh = new_sh_audio(demuxer, stream_id); | 296 sh_audio_t *sh = new_sh_audio(demuxer, stream_id); |
243 | 297 |
244 printf("Found audio stream!\n"); | 298 printf("Found audio stream!\n"); |
245 stream_skip(demuxer->stream, 4); /* version */ | 299 // printf("pos: %x\n", stream_tell(demuxer->stream)); |
246 stream_skip(demuxer->stream, 4); /* .ra4 */ | 300 stream_skip(demuxer->stream, 2); /* version (4 or 5) */ |
247 stream_skip(demuxer->stream, 4); | |
248 stream_skip(demuxer->stream, 2); | 301 stream_skip(demuxer->stream, 2); |
302 stream_skip(demuxer->stream, 4); /* .ra4 or .ra5 */ | |
303 stream_skip(demuxer->stream, 4); | |
304 stream_skip(demuxer->stream, 2); /* version (4 or 5) */ | |
249 stream_skip(demuxer->stream, 4); /* header size */ | 305 stream_skip(demuxer->stream, 4); /* header size */ |
250 stream_skip(demuxer->stream, 2); /* add codec info */ | 306 stream_skip(demuxer->stream, 2); /* add codec info */ |
251 stream_skip(demuxer->stream, 4); /* coded frame size */ | 307 stream_skip(demuxer->stream, 4); /* coded frame size */ |
252 stream_skip(demuxer->stream, 4); | 308 stream_skip(demuxer->stream, 4); |
253 stream_skip(demuxer->stream, 4); | 309 stream_skip(demuxer->stream, 4); |
261 sh->channels = stream_read_word(demuxer->stream); | 317 sh->channels = stream_read_word(demuxer->stream); |
262 | 318 |
263 { | 319 { |
264 char buf[128]; | 320 char buf[128]; |
265 | 321 |
322 skip_str(1, demuxer); | |
323 // get_str(1, demuxer, buf, sizeof(buf)); | |
266 get_str(1, demuxer, buf, sizeof(buf)); | 324 get_str(1, demuxer, buf, sizeof(buf)); |
267 get_str(1, demuxer, buf, sizeof(buf)); | |
268 | 325 |
269 v = 0; /* not supported audio codec */ | 326 v = 0; /* not supported audio codec */ |
270 if (!strcmp(buf, "dnet")) | 327 if (strstr(buf, "dnet")) |
271 { | 328 { |
272 printf("Found AC3 audio\n"); | 329 printf("Found AC3 audio\n"); |
273 sh->format = 0x2000; /* ac3 */ | 330 sh->format = 0x2000; /* ac3 */ |
274 v = 1; | 331 v = 1; |
332 } | |
333 if (strstr(buf, "sipr")) | |
334 { | |
335 printf("Found SiproLab's ACELP\n"); | |
336 sh->format = 0x130; | |
337 v = 1; | |
338 } | |
339 if (strstr(buf, "cook")) | |
340 { | |
341 printf("Found Real's GeneralCooker (unsupported)\n"); | |
342 v = 0; | |
275 } | 343 } |
276 } | 344 } |
277 // skip_str(1, demuxer); /* desc */ | 345 // skip_str(1, demuxer); /* desc */ |
278 // skip_str(1, demuxer); /* desc */ | 346 // skip_str(1, demuxer); /* desc */ |
279 | 347 |
281 /* available codecs: DNET -> ac3 */ | 349 /* available codecs: DNET -> ac3 */ |
282 // sh->format = 0x2000; /* ac3 */ | 350 // sh->format = 0x2000; /* ac3 */ |
283 | 351 |
284 if (v) | 352 if (v) |
285 { | 353 { |
286 printf("Audio codec: 0x%x\n", sh->format); | 354 |
355 /* Emulate WAVEFORMATEX struct: */ | |
356 sh->wf = malloc(sizeof(WAVEFORMATEX)); | |
357 memset(sh->wf, 0, sizeof(WAVEFORMATEX)); | |
358 sh->wf->wFormatTag = sh->format; | |
359 sh->wf->nChannels = sh->channels; | |
360 sh->wf->wBitsPerSample = 16; | |
361 sh->wf->nSamplesPerSec = sh->samplerate; | |
362 sh->wf->nAvgBytesPerSec = bitrate; | |
363 sh->wf->nBlockAlign = 19; /* 19 for acelp, pff */ | |
364 sh->wf->cbSize = 0; | |
365 | |
287 /* insert as stream */ | 366 /* insert as stream */ |
288 demuxer->audio->sh = sh; | 367 demuxer->audio->sh = sh; |
289 sh->ds = demuxer->audio; | 368 sh->ds = demuxer->audio; |
290 demuxer->audio->id = stream_id; | 369 demuxer->audio->id = stream_id; |
291 | 370 |
343 case 0x10003001: | 422 case 0x10003001: |
344 /* sub id: 3 */ | 423 /* sub id: 3 */ |
345 /* codec id: rv10 */ | 424 /* codec id: rv10 */ |
346 break; | 425 break; |
347 case 0x20001000: | 426 case 0x20001000: |
427 case 0x20100001: | |
348 /* codec id: rv20 */ | 428 /* codec id: rv20 */ |
349 break; | 429 break; |
350 default: | 430 default: |
351 /* codec id: none */ | 431 /* codec id: none */ |
432 printf("unknown id: %x\n", v); | |
352 } | 433 } |
353 | 434 |
354 /* insert as stream */ | 435 /* insert as stream */ |
355 demuxer->video->sh = sh; | 436 demuxer->video->sh = sh; |
356 sh->ds = demuxer->video; | 437 sh->ds = demuxer->video; |