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;