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 /*