Mercurial > libavcodec.hg
comparison vmdav.c @ 1882:5456ab242388 libavcodec
minor VMD system update; still not perfect, but should not crash either
author | melanson |
---|---|
date | Sun, 14 Mar 2004 04:08:11 +0000 |
parents | a660ef952580 |
children | d7505fbe66cb |
comparison
equal
deleted
inserted
replaced
1881:39ad6cd5d4a6 | 1882:5456ab242388 |
---|---|
20 | 20 |
21 /** | 21 /** |
22 * @file vmdvideo.c | 22 * @file vmdvideo.c |
23 * Sierra VMD audio & video decoders | 23 * Sierra VMD audio & video decoders |
24 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru) | 24 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru) |
25 * for more information on the Sierra VMD format, visit: | |
26 * http://www.pcisys.net/~melanson/codecs/ | |
25 * | 27 * |
26 * The video decoder outputs PAL8 colorspace data. The decoder expects | 28 * The video decoder outputs PAL8 colorspace data. The decoder expects |
27 * a 0x330-byte VMD file header to be transmitted via extradata during | 29 * a 0x330-byte VMD file header to be transmitted via extradata during |
28 * codec initialization. Each encoded frame that is sent to this decoder | 30 * codec initialization. Each encoded frame that is sent to this decoder |
29 * is expected to be prepended with the appropriate 16-byte frame | 31 * is expected to be prepended with the appropriate 16-byte frame |
30 * information record from the VMD file. | 32 * information record from the VMD file. |
31 * | 33 * |
32 * The audio decoder, like the video decoder, expects each encoded data | 34 * The audio decoder, like the video decoder, expects each encoded data |
33 * chunk to be prepended with the approriate 16-byte frame information | 35 * chunk to be prepended with the appropriate 16-byte frame information |
34 * record from the VMD file. It does not require the 0x330-byte VMD file | 36 * record from the VMD file. It does not require the 0x330-byte VMD file |
35 * header, but it does need the audio setup parameters passed in through | 37 * header, but it does need the audio setup parameters passed in through |
36 * normal libavcodec API means. | 38 * normal libavcodec API means. |
37 */ | 39 */ |
38 | 40 |
48 #define printf(...) {} //(f)printf() usage is forbidden in libavcodec, use av_log | 50 #define printf(...) {} //(f)printf() usage is forbidden in libavcodec, use av_log |
49 #define fprintf(...) {} | 51 #define fprintf(...) {} |
50 | 52 |
51 #define VMD_HEADER_SIZE 0x330 | 53 #define VMD_HEADER_SIZE 0x330 |
52 #define PALETTE_COUNT 256 | 54 #define PALETTE_COUNT 256 |
53 | |
54 #define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0]) | |
55 #define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \ | |
56 (((uint8_t*)(x))[2] << 16) | \ | |
57 (((uint8_t*)(x))[1] << 8) | \ | |
58 ((uint8_t*)(x))[0]) | |
59 | 55 |
60 /* | 56 /* |
61 * Video Decoder | 57 * Video Decoder |
62 */ | 58 */ |
63 | 59 |
273 do { | 269 do { |
274 len = *pb++; | 270 len = *pb++; |
275 if (len & 0x80) { | 271 if (len & 0x80) { |
276 len = (len & 0x7F) + 1; | 272 len = (len & 0x7F) + 1; |
277 if (*pb++ == 0xFF) | 273 if (*pb++ == 0xFF) |
278 len = rle_unpack(pb, dp, len); | 274 len = rle_unpack(pb, &dp[ofs], len); |
279 else | 275 else |
280 memcpy(&dp[ofs], pb, len); | 276 memcpy(&dp[ofs], pb, len); |
281 pb += len; | 277 pb += len; |
282 ofs += len; | 278 ofs += len; |
283 } else { | 279 } else { |
347 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data; | 343 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data; |
348 | 344 |
349 s->buf = buf; | 345 s->buf = buf; |
350 s->size = buf_size; | 346 s->size = buf_size; |
351 | 347 |
348 if (buf_size < 16) | |
349 return buf_size; | |
350 | |
352 s->frame.reference = 1; | 351 s->frame.reference = 1; |
353 if (avctx->get_buffer(avctx, &s->frame)) { | 352 if (avctx->get_buffer(avctx, &s->frame)) { |
354 printf (" VMD Video: get_buffer() failed\n"); | 353 printf (" VMD Video: get_buffer() failed\n"); |
355 return -1; | 354 return -1; |
356 } | 355 } |
406 | 405 |
407 s->channels = avctx->channels; | 406 s->channels = avctx->channels; |
408 s->bits = avctx->bits_per_sample; | 407 s->bits = avctx->bits_per_sample; |
409 s->block_align = avctx->block_align; | 408 s->block_align = avctx->block_align; |
410 | 409 |
411 printf (" %d channels, %d bits/sample, block align = %d\n", | 410 printf (" %d channels, %d bits/sample, block align = %d, sample rate = %d\n", |
412 s->channels, s->bits, s->block_align); | 411 s->channels, s->bits, s->block_align, avctx->sample_rate); |
413 | 412 |
414 /* set up the steps8 and steps16 tables */ | 413 /* set up the steps8 and steps16 tables */ |
415 for (i = 0; i < 8; i++) { | 414 for (i = 0; i < 8; i++) { |
416 if (i < 4) | 415 if (i < 4) |
417 s->steps8[i] = i; | 416 s->steps8[i] = i; |
458 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, | 457 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, |
459 uint8_t *buf, int ratio) { | 458 uint8_t *buf, int ratio) { |
460 | 459 |
461 } | 460 } |
462 | 461 |
463 static void vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, | 462 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, |
464 uint8_t *buf, int silence) | 463 uint8_t *buf, int silence) |
465 { | 464 { |
465 int bytes_decoded = 0; | |
466 int i; | |
467 | |
468 if (silence) | |
469 printf (" silent block!\n"); | |
466 if (s->channels == 2) { | 470 if (s->channels == 2) { |
471 | |
472 /* stereo handling */ | |
467 if ((s->block_align & 0x01) == 0) { | 473 if ((s->block_align & 0x01) == 0) { |
468 if (silence) | 474 if (silence) |
469 memset(data, 0, s->block_align * 2); | 475 memset(data, 0, s->block_align * 2); |
470 else | 476 else |
471 vmdaudio_decode_audio(s, data, buf, 1); | 477 vmdaudio_decode_audio(s, data, buf, 1); |
472 } else { | 478 } else { |
473 if (silence) | 479 if (silence) |
474 memset(data, 0, s->block_align * 2); | 480 memset(data, 0, s->block_align * 2); |
475 // else | 481 else |
476 // vmdaudio_decode_audio(s, data, buf, 1); | 482 vmdaudio_decode_audio(s, data, buf, 1); |
477 } | 483 } |
478 } else { | 484 } else { |
479 } | 485 |
486 /* mono handling */ | |
487 if (silence) { | |
488 if (s->bits == 16) { | |
489 memset(data, 0, s->block_align * 2); | |
490 bytes_decoded = s->block_align * 2; | |
491 } else { | |
492 // memset(data, 0x00, s->block_align); | |
493 // bytes_decoded = s->block_align; | |
494 memset(data, 0x00, s->block_align * 2); | |
495 bytes_decoded = s->block_align * 2; | |
496 } | |
497 } else { | |
498 if (s->bits == 16) { | |
499 } else { | |
500 /* copy the data but convert it to signed */ | |
501 for (i = 0; i < s->block_align; i++) | |
502 data[i * 2 + 1] = buf[i] + 0x80; | |
503 bytes_decoded = s->block_align * 2; | |
504 } | |
505 } | |
506 } | |
507 | |
508 return bytes_decoded; | |
480 } | 509 } |
481 | 510 |
482 static int vmdaudio_decode_frame(AVCodecContext *avctx, | 511 static int vmdaudio_decode_frame(AVCodecContext *avctx, |
483 void *data, int *data_size, | 512 void *data, int *data_size, |
484 uint8_t *buf, int buf_size) | 513 uint8_t *buf, int buf_size) |
489 | 518 |
490 /* point to the start of the encoded data */ | 519 /* point to the start of the encoded data */ |
491 unsigned char *p = buf + 16; | 520 unsigned char *p = buf + 16; |
492 unsigned char *p_end = buf + buf_size; | 521 unsigned char *p_end = buf + buf_size; |
493 | 522 |
523 printf (" processing audio frame with %d bytes\n", buf_size); | |
524 if (buf_size < 16) | |
525 return buf_size; | |
526 | |
527 *data_size = 0; | |
494 if (buf[6] == 1) { | 528 if (buf[6] == 1) { |
495 /* the chunk contains audio */ | 529 /* the chunk contains audio */ |
496 vmdaudio_loadsound(s, output_samples, p, 0); | 530 *data_size = vmdaudio_loadsound(s, output_samples, p, 0); |
497 } else if (buf[6] == 2) { | 531 } else if (buf[6] == 2) { |
532 printf (" hey! audio case #2\n"); | |
498 /* the chunk contains audio and silence mixed together */ | 533 /* the chunk contains audio and silence mixed together */ |
499 sound_flags = LE_32(p); | 534 sound_flags = LE_32(p); |
500 p += 4; | 535 p += 4; |
501 | 536 |
502 /* do something with extrabufs here? */ | 537 /* do something with extrabufs here? */ |
503 | 538 |
504 while (p < p_end) { | 539 while (p < p_end) { |
505 if (sound_flags & 0x01) | 540 if (sound_flags & 0x01) |
541 /* silence */ | |
542 *data_size += vmdaudio_loadsound(s, output_samples, p, 1); | |
543 else { | |
506 /* audio */ | 544 /* audio */ |
507 vmdaudio_loadsound(s, output_samples, p, 1); | 545 *data_size += vmdaudio_loadsound(s, output_samples, p, 0); |
508 else | 546 p += s->block_align; |
509 /* silence */ | 547 } |
510 vmdaudio_loadsound(s, output_samples, p, 0); | |
511 p += s->block_align; | |
512 output_samples += (s->block_align * s->bits / 8); | 548 output_samples += (s->block_align * s->bits / 8); |
513 sound_flags >>= 1; | 549 sound_flags >>= 1; |
514 } | 550 } |
515 } else if (buf[6] == 3) { | 551 } else if (buf[6] == 3) { |
552 printf (" hey! audio case #3\n"); | |
516 /* silent chunk */ | 553 /* silent chunk */ |
517 vmdaudio_loadsound(s, output_samples, p, 1); | 554 *data_size = vmdaudio_loadsound(s, output_samples, p, 1); |
518 } | 555 } |
519 | 556 |
520 | 557 printf (" final sample count = %d, byte count = %d\n", (*data_size) / 2, |
521 // *datasize = ; | 558 *data_size); |
522 return buf_size; | 559 return buf_size; |
523 } | 560 } |
524 | 561 |
525 | 562 |
526 /* | 563 /* |