Mercurial > libavformat.hg
comparison rm.c @ 194:37e7cd3d544d libavformat
support for older real audio files (<= version 3)
author | bellard |
---|---|
date | Mon, 11 Aug 2003 16:16:49 +0000 |
parents | 6c9d6422a2f6 |
children | 3d92f793fd67 |
comparison
equal
deleted
inserted
replaced
193:5079b6e20e91 | 194:37e7cd3d544d |
---|---|
37 typedef struct { | 37 typedef struct { |
38 StreamInfo streams[2]; | 38 StreamInfo streams[2]; |
39 StreamInfo *audio_stream, *video_stream; | 39 StreamInfo *audio_stream, *video_stream; |
40 int data_pos; /* position of the data after the header */ | 40 int data_pos; /* position of the data after the header */ |
41 int nb_packets; | 41 int nb_packets; |
42 int old_format; | |
42 } RMContext; | 43 } RMContext; |
43 | 44 |
44 static void put_str(ByteIOContext *s, const char *tag) | 45 static void put_str(ByteIOContext *s, const char *tag) |
45 { | 46 { |
46 put_be16(s,strlen(tag)); | 47 put_be16(s,strlen(tag)); |
463 *q++ = get_byte(pb); | 464 *q++ = get_byte(pb); |
464 } | 465 } |
465 *q = '\0'; | 466 *q = '\0'; |
466 } | 467 } |
467 | 468 |
469 static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st, | |
470 int read_all) | |
471 { | |
472 ByteIOContext *pb = &s->pb; | |
473 char buf[128]; | |
474 uint32_t version; | |
475 int i; | |
476 | |
477 /* ra type header */ | |
478 version = get_be32(pb); /* version */ | |
479 if (((version >> 16) & 0xff) == 3) { | |
480 /* very old version */ | |
481 for(i = 0; i < 14; i++) | |
482 get_byte(pb); | |
483 get_str8(pb, s->title, sizeof(s->title)); | |
484 get_str8(pb, s->author, sizeof(s->author)); | |
485 get_str8(pb, s->copyright, sizeof(s->copyright)); | |
486 get_str8(pb, s->comment, sizeof(s->comment)); | |
487 get_byte(pb); | |
488 get_str8(pb, buf, sizeof(buf)); | |
489 st->codec.sample_rate = 8000; | |
490 st->codec.channels = 1; | |
491 st->codec.codec_type = CODEC_TYPE_AUDIO; | |
492 st->codec.codec_id = CODEC_ID_RA_144; | |
493 } else { | |
494 /* old version (4) */ | |
495 get_be32(pb); /* .ra4 */ | |
496 get_be32(pb); | |
497 get_be16(pb); | |
498 get_be32(pb); /* header size */ | |
499 get_be16(pb); /* add codec info */ | |
500 get_be32(pb); /* coded frame size */ | |
501 get_be32(pb); /* ??? */ | |
502 get_be32(pb); /* ??? */ | |
503 get_be32(pb); /* ??? */ | |
504 get_be16(pb); /* 1 */ | |
505 get_be16(pb); /* coded frame size */ | |
506 get_be32(pb); | |
507 st->codec.sample_rate = get_be16(pb); | |
508 get_be32(pb); | |
509 st->codec.channels = get_be16(pb); | |
510 get_str8(pb, buf, sizeof(buf)); /* desc */ | |
511 get_str8(pb, buf, sizeof(buf)); /* desc */ | |
512 st->codec.codec_type = CODEC_TYPE_AUDIO; | |
513 if (!strcmp(buf, "dnet")) { | |
514 st->codec.codec_id = CODEC_ID_AC3; | |
515 } else { | |
516 st->codec.codec_id = CODEC_ID_NONE; | |
517 pstrcpy(st->codec.codec_name, sizeof(st->codec.codec_name), | |
518 buf); | |
519 } | |
520 if (read_all) { | |
521 get_byte(pb); | |
522 get_byte(pb); | |
523 get_byte(pb); | |
524 | |
525 get_str8(pb, s->title, sizeof(s->title)); | |
526 get_str8(pb, s->author, sizeof(s->author)); | |
527 get_str8(pb, s->copyright, sizeof(s->copyright)); | |
528 get_str8(pb, s->comment, sizeof(s->comment)); | |
529 } | |
530 } | |
531 } | |
532 | |
533 static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap) | |
534 { | |
535 RMContext *rm = s->priv_data; | |
536 AVStream *st; | |
537 | |
538 rm->old_format = 1; | |
539 st = av_new_stream(s, 0); | |
540 if (!st) | |
541 goto fail; | |
542 rm_read_audio_stream_info(s, st, 1); | |
543 return 0; | |
544 fail: | |
545 return -1; | |
546 } | |
547 | |
468 static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) | 548 static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) |
469 { | 549 { |
470 RMContext *rm = s->priv_data; | 550 RMContext *rm = s->priv_data; |
471 AVStream *st; | 551 AVStream *st; |
472 ByteIOContext *pb = &s->pb; | 552 ByteIOContext *pb = &s->pb; |
475 int64_t codec_pos; | 555 int64_t codec_pos; |
476 unsigned int h263_hack_version, start_time, duration; | 556 unsigned int h263_hack_version, start_time, duration; |
477 char buf[128]; | 557 char buf[128]; |
478 int flags = 0; | 558 int flags = 0; |
479 | 559 |
480 if (get_le32(pb) != MKTAG('.', 'R', 'M', 'F')) | 560 tag = get_le32(pb); |
561 if (tag == MKTAG('.', 'r', 'a', 0xfd)) { | |
562 /* very old .ra format */ | |
563 return rm_read_header_old(s, ap); | |
564 } else if (tag != MKTAG('.', 'R', 'M', 'F')) { | |
481 return -EIO; | 565 return -EIO; |
566 } | |
482 | 567 |
483 get_be32(pb); /* header size */ | 568 get_be32(pb); /* header size */ |
484 get_be16(pb); | 569 get_be16(pb); |
485 get_be32(pb); | 570 get_be32(pb); |
486 get_be32(pb); /* number of headers */ | 571 get_be32(pb); /* number of headers */ |
543 codec_pos = url_ftell(pb); | 628 codec_pos = url_ftell(pb); |
544 | 629 |
545 v = get_be32(pb); | 630 v = get_be32(pb); |
546 if (v == MKTAG(0xfd, 'a', 'r', '.')) { | 631 if (v == MKTAG(0xfd, 'a', 'r', '.')) { |
547 /* ra type header */ | 632 /* ra type header */ |
548 get_be32(pb); /* version */ | 633 rm_read_audio_stream_info(s, st, 0); |
549 get_be32(pb); /* .ra4 */ | |
550 get_be32(pb); | |
551 get_be16(pb); | |
552 get_be32(pb); /* header size */ | |
553 get_be16(pb); /* add codec info */ | |
554 get_be32(pb); /* coded frame size */ | |
555 get_be32(pb); /* ??? */ | |
556 get_be32(pb); /* ??? */ | |
557 get_be32(pb); /* ??? */ | |
558 get_be16(pb); /* 1 */ | |
559 get_be16(pb); /* coded frame size */ | |
560 get_be32(pb); | |
561 st->codec.sample_rate = get_be16(pb); | |
562 get_be32(pb); | |
563 st->codec.channels = get_be16(pb); | |
564 get_str8(pb, buf, sizeof(buf)); /* desc */ | |
565 get_str8(pb, buf, sizeof(buf)); /* desc */ | |
566 st->codec.codec_type = CODEC_TYPE_AUDIO; | |
567 if (!strcmp(buf, "dnet")) { | |
568 st->codec.codec_id = CODEC_ID_AC3; | |
569 } else { | |
570 st->codec.codec_id = CODEC_ID_NONE; | |
571 pstrcpy(st->codec.codec_name, sizeof(st->codec.codec_name), | |
572 buf); | |
573 } | |
574 } else { | 634 } else { |
575 if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) { | 635 if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) { |
576 fail1: | 636 fail1: |
577 fprintf(stderr, "Unsupported video codec\n"); | 637 fprintf(stderr, "Unsupported video codec\n"); |
578 goto fail; | 638 goto fail; |
643 (*len)-=2; | 703 (*len)-=2; |
644 return (n << 16) | n1; | 704 return (n << 16) | n1; |
645 } | 705 } |
646 } | 706 } |
647 | 707 |
708 /* multiple of 20 bytes for ra144 (ugly) */ | |
709 #define RAW_PACKET_SIZE 1000 | |
710 | |
648 static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) | 711 static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) |
649 { | 712 { |
650 RMContext *rm = s->priv_data; | 713 RMContext *rm = s->priv_data; |
651 ByteIOContext *pb = &s->pb; | 714 ByteIOContext *pb = &s->pb; |
652 AVStream *st; | 715 AVStream *st; |
653 int len, num, timestamp, i, tmp, j; | 716 int len, num, timestamp, i, tmp, j; |
654 uint8_t *ptr; | 717 uint8_t *ptr; |
655 int flags; | 718 int flags; |
656 | 719 |
657 redo: | 720 if (rm->old_format) { |
658 if (rm->nb_packets == 0) | 721 /* just read raw bytes */ |
659 return -EIO; | 722 len = RAW_PACKET_SIZE; |
660 get_be16(pb); | 723 av_new_packet(pkt, len); |
661 len = get_be16(pb); | 724 pkt->stream_index = 0; |
662 if (len < 12) | 725 len = get_buffer(pb, pkt->data, len); |
663 return -EIO; | 726 if (len <= 0) { |
664 num = get_be16(pb); | 727 av_free_packet(pkt); |
665 timestamp = get_be32(pb); | 728 return -EIO; |
666 get_byte(pb); /* reserved */ | 729 } |
667 flags = get_byte(pb); /* flags */ | 730 pkt->size = len; |
668 rm->nb_packets--; | 731 st = s->streams[0]; |
669 len -= 12; | 732 } else { |
670 | 733 redo: |
671 st = NULL; | 734 if (rm->nb_packets == 0) |
672 for(i=0;i<s->nb_streams;i++) { | 735 return -EIO; |
673 st = s->streams[i]; | 736 get_be16(pb); |
674 if (num == st->id) | 737 len = get_be16(pb); |
675 break; | 738 if (len < 12) |
676 } | 739 return -EIO; |
677 if (i == s->nb_streams) { | 740 num = get_be16(pb); |
678 /* skip packet if unknown number */ | 741 timestamp = get_be32(pb); |
679 url_fskip(pb, len); | 742 get_byte(pb); /* reserved */ |
680 goto redo; | 743 flags = get_byte(pb); /* flags */ |
681 } | 744 rm->nb_packets--; |
682 | 745 len -= 12; |
683 if (st->codec.codec_type == CODEC_TYPE_VIDEO) { | 746 |
684 int full_frame, h, pic_num; | 747 st = NULL; |
685 | 748 for(i=0;i<s->nb_streams;i++) { |
686 h= get_byte(pb); | 749 st = s->streams[i]; |
687 if ((h & 0xc0) == 0xc0) { | 750 if (num == st->id) |
688 int len2, pos; | 751 break; |
689 full_frame = 1; | 752 } |
690 len2= get_num(pb, &len); | 753 if (i == s->nb_streams) { |
691 pos = get_num(pb, &len); | 754 /* skip packet if unknown number */ |
692 //printf("pos:%d\n",len); | 755 url_fskip(pb, len); |
693 len -= 2; | 756 goto redo; |
694 } else { | 757 } |
695 int seq, frame_size, pos; | 758 |
696 full_frame = 0; | 759 if (st->codec.codec_type == CODEC_TYPE_VIDEO) { |
697 seq = get_byte(pb); | 760 int full_frame, h, pic_num; |
698 frame_size = get_num(pb, &len); | 761 |
699 pos = get_num(pb, &len); | 762 h= get_byte(pb); |
700 //printf("seq:%d, size:%d, pos:%d\n",seq,frame_size,pos); | 763 if ((h & 0xc0) == 0xc0) { |
701 len -= 3; | 764 int len2, pos; |
702 } | 765 full_frame = 1; |
703 /* picture number */ | 766 len2= get_num(pb, &len); |
704 pic_num= get_byte(pb); | 767 pos = get_num(pb, &len); |
705 | 768 //printf("pos:%d\n",len); |
706 //XXX/FIXME/HACK, demuxer should be fixed to send complete frames ... | 769 len -= 2; |
707 if(st->codec.slice_offset==NULL) | 770 } else { |
708 st->codec.slice_offset= (int*)av_malloc(sizeof(int)); | 771 int seq, frame_size, pos; |
709 st->codec.slice_count= full_frame; | 772 full_frame = 0; |
710 st->codec.slice_offset[0]= 0; | 773 seq = get_byte(pb); |
711 } | 774 frame_size = get_num(pb, &len); |
712 | 775 pos = get_num(pb, &len); |
713 av_new_packet(pkt, len); | 776 //printf("seq:%d, size:%d, pos:%d\n",seq,frame_size,pos); |
714 pkt->stream_index = i; | 777 len -= 3; |
715 get_buffer(pb, pkt->data, len); | 778 } |
779 /* picture number */ | |
780 pic_num= get_byte(pb); | |
781 | |
782 //XXX/FIXME/HACK, demuxer should be fixed to send complete frames ... | |
783 if(st->codec.slice_offset==NULL) | |
784 st->codec.slice_offset= (int*)av_malloc(sizeof(int)); | |
785 st->codec.slice_count= full_frame; | |
786 st->codec.slice_offset[0]= 0; | |
787 } | |
788 | |
789 av_new_packet(pkt, len); | |
790 pkt->stream_index = i; | |
791 get_buffer(pb, pkt->data, len); | |
792 } | |
716 | 793 |
717 /* for AC3, needs to swap bytes */ | 794 /* for AC3, needs to swap bytes */ |
718 if (st->codec.codec_id == CODEC_ID_AC3) { | 795 if (st->codec.codec_id == CODEC_ID_AC3) { |
719 ptr = pkt->data; | 796 ptr = pkt->data; |
720 for(j=0;j<len;j+=2) { | 797 for(j=0;j<len;j+=2) { |
735 static int rm_probe(AVProbeData *p) | 812 static int rm_probe(AVProbeData *p) |
736 { | 813 { |
737 /* check file header */ | 814 /* check file header */ |
738 if (p->buf_size <= 32) | 815 if (p->buf_size <= 32) |
739 return 0; | 816 return 0; |
740 if (p->buf[0] == '.' && p->buf[1] == 'R' && | 817 if ((p->buf[0] == '.' && p->buf[1] == 'R' && |
741 p->buf[2] == 'M' && p->buf[3] == 'F' && | 818 p->buf[2] == 'M' && p->buf[3] == 'F' && |
742 p->buf[4] == 0 && p->buf[5] == 0) | 819 p->buf[4] == 0 && p->buf[5] == 0) || |
820 (p->buf[0] == '.' && p->buf[1] == 'r' && | |
821 p->buf[2] == 'a' && p->buf[3] == 0xfd)) | |
743 return AVPROBE_SCORE_MAX; | 822 return AVPROBE_SCORE_MAX; |
744 else | 823 else |
745 return 0; | 824 return 0; |
746 } | 825 } |
747 | 826 |