| 589 | | /*********************************************************** |
|---|
| 590 | | * A filter predicate, used between the min seek granule |
|---|
| 591 | | * and the start time (ie. the bit between the prior keyframe |
|---|
| 592 | | * and the chop time) to filter packets which should be |
|---|
| 593 | | * included in the output. |
|---|
| 594 | | * \returns 0 Do not include \a op |
|---|
| 595 | | * \returns 1 Do include \a op |
|---|
| 596 | | */ |
|---|
| 597 | | static int |
|---|
| 598 | | filter (AnxOggData * aod, AnxOggTrack * aot, long serialno, ogg_packet * op) { |
|---|
| 599 | | |
|---|
| 600 | | AnxSourceTrack * track = &(aot->source_track); |
|---|
| 601 | | double timestamp; |
|---|
| 602 | | |
|---|
| 603 | | #ifdef DEBUG |
|---|
| 604 | | fprintf(aod->df, "state %s got_keygranule %d gp %llx keygranule %llx\n", |
|---|
| 605 | | aod->state == STATE_FILTER ? "FILTER" : "NOFILTER", |
|---|
| 606 | | aot->filter_got_keygranule, op->granulepos, aot->keygranule); |
|---|
| 607 | | #endif |
|---|
| 608 | | |
|---|
| 609 | | /* TRUE if we're not in state FILTER */ |
|---|
| 610 | | if (aod->state != STATE_FILTER) return 1; |
|---|
| 611 | | |
|---|
| 612 | | /* TRUE if we haven't done the seek yet */ |
|---|
| 613 | | if (aod->need_seek == NEED_SEEK_PENDING) return 1; |
|---|
| 614 | | |
|---|
| 615 | | timestamp = gp_to_time (aod->oggz, serialno, op->granulepos); |
|---|
| 616 | | |
|---|
| 617 | | #ifdef DEBUG |
|---|
| 618 | | fprintf(aod->df, "timestamp %f start_time %f\n", timestamp, |
|---|
| 619 | | aod->anx_source->start_time); |
|---|
| 620 | | #endif |
|---|
| 621 | | |
|---|
| 622 | | /* TRUE if we're beyond the start time */ |
|---|
| 623 | | if (timestamp-TOLERANCE >= aod->anx_source->start_time) { |
|---|
| 624 | | aod->state = STATE_DATA; |
|---|
| 625 | | return 1; |
|---|
| 626 | | } |
|---|
| 627 | | |
|---|
| 628 | | /* from here, we know we're filtering */ |
|---|
| 629 | | |
|---|
| 630 | | /* FALSE if we're not using granule_seek at all */ |
|---|
| 631 | | if (!aod->use_granule_seek) return 0; |
|---|
| 632 | | |
|---|
| 633 | | /* FALSE if this track doesn't use granuleshift */ |
|---|
| 634 | | if (track->granuleshift == 0) return 0; |
|---|
| 635 | | |
|---|
| 636 | | /* TRUE if we're beyond the keygranule for this track */ |
|---|
| 637 | | if (aot->filter_got_keygranule) return 1; |
|---|
| 638 | | |
|---|
| 639 | | if (op->granulepos >= aot->keygranule) { |
|---|
| 640 | | aot->filter_got_keygranule = 1; |
|---|
| 641 | | return 1; |
|---|
| 642 | | } |
|---|
| 643 | | |
|---|
| 644 | | /* TRUE if we're after the keygranule time */ |
|---|
| 645 | | #if 0 |
|---|
| 646 | | if (op->granulepos != -1 && timestamp+TOLERANCE >= aot->keygranule_time) { |
|---|
| 647 | | aot->filter_got_keygranule = 1; |
|---|
| 648 | | return 1; |
|---|
| 649 | | } |
|---|
| 650 | | |
|---|
| 651 | | /* XXX: TRUE if a theora from a keyframe, even if no granulepos */ |
|---|
| 652 | | if (!strcmp (track->content_type, THEORA_CONTENT_TYPE) && |
|---|
| 653 | | op->bytes > 0 && !(op->packet[0] & 0xC0)) { |
|---|
| 654 | | #ifdef DEBUG |
|---|
| 655 | | fprintf (aod->df, |
|---|
| 656 | | "anxogg::FILTER got Theora keyframe\n"); |
|---|
| 657 | | #endif |
|---|
| 658 | | |
|---|
| 659 | | aot->filter_got_keygranule = 1; |
|---|
| 660 | | return 1; |
|---|
| 661 | | } |
|---|
| 662 | | |
|---|
| 663 | | #endif |
|---|
| 664 | | |
|---|
| 665 | | /* FALSE otherwise */ |
|---|
| 666 | | return 0; |
|---|
| 667 | | |
|---|
| 668 | | #if 0 |
|---|
| 669 | | /* FALSE if this track uses keygranules, and we're before its time */ |
|---|
| 670 | | if (granulepos != -1 && timestamp+TOLERANCE < aot->keygranule_time) return 0; |
|---|
| 671 | | |
|---|
| 672 | | /* TRUE otherwise */ |
|---|
| 673 | | return 1; |
|---|
| 674 | | #endif |
|---|
| 675 | | } |
|---|
| 676 | | |
|---|
| 677 | | static int |
|---|
| 678 | | read_packet_data (OGGZ * oggz, ogg_packet * op, long serialno, |
|---|
| 679 | | void * user_data) |
|---|
| 680 | | { |
|---|
| 681 | | AnxOggData * aod = (AnxOggData *)user_data; |
|---|
| 682 | | AnxOggTrack * aot = NULL; |
|---|
| 683 | | AnxOggPacket * aop; |
|---|
| 684 | | AnxSource * m = aod->anx_source; |
|---|
| 685 | | AnxSourceTrack * track = NULL; |
|---|
| 686 | | anx_int64_t gp = oggz_tell_granulepos(oggz); |
|---|
| 687 | | |
|---|
| 688 | | op->granulepos = gp; |
|---|
| 689 | | |
|---|
| 690 | | #ifdef DEBUG |
|---|
| 691 | | fprintf (aod->df, "anxogg::read_packet_data IN: %010ld, granulepos %llx\n", |
|---|
| 692 | | serialno, gp); |
|---|
| 693 | | #endif |
|---|
| 694 | | |
|---|
| 695 | | if (!(aod->cmml_serialno != -1 && serialno == aod->cmml_serialno)) { |
|---|
| 696 | | aot = (AnxOggTrack *) oggz_table_lookup (aod->logicals, serialno); |
|---|
| 697 | | if (aot == NULL) { |
|---|
| 698 | | #ifdef DEBUG |
|---|
| 699 | | fprintf (aod->df, |
|---|
| 700 | | "anxogg::read_packet_data: %010ld not found\n", serialno); |
|---|
| 701 | | #endif |
|---|
| 702 | | return OGGZ_STOP_OK; |
|---|
| 703 | | } |
|---|
| 704 | | } |
|---|
| 705 | | |
|---|
| 706 | | if (op->b_o_s) { |
|---|
| 707 | | if (!strncmp ((char *)&op->packet[0], "AnxData", 7)) { |
|---|
| 708 | | /* Mark this track as anxv2, and don't copy the AnxData packet |
|---|
| 709 | | * into the bitstream */ |
|---|
| 710 | | if (aot) aot->anxv2_ignore_packet = 1; |
|---|
| 711 | | } |
|---|
| 712 | | } else { |
|---|
| 713 | | if (aod->cmml_serialno != -1 && serialno == aod->cmml_serialno) { |
|---|
| 714 | | double at_time; |
|---|
| 715 | | |
|---|
| 716 | | #ifdef DEBUG |
|---|
| 717 | | fprintf (aod->df, "aod->cmml_serialno %010ld, op->granulepos %lld\n", |
|---|
| 718 | | aod->cmml_serialno, gp); |
|---|
| 719 | | #endif |
|---|
| 720 | | |
|---|
| 721 | | if (gp == -1) { |
|---|
| 722 | | return OGGZ_STOP_ERR; |
|---|
| 723 | | } |
|---|
| 724 | | at_time = gp_to_time (aod->oggz, serialno, gp); |
|---|
| 725 | | |
|---|
| 726 | | #ifdef DEBUG |
|---|
| 727 | | { |
|---|
| 728 | | char * header = (char *)op->packet; |
|---|
| 729 | | fprintf (aod->df, |
|---|
| 730 | | "anxogg::read_packet_data: got CMML <%c%c%c%c> at %f\n", |
|---|
| 731 | | header[1], header[2], header[3], header[4], at_time); |
|---|
| 732 | | } |
|---|
| 733 | | #endif |
|---|
| 734 | | |
|---|
| 735 | | /* If this content doesn't use cmml_granuleshift, and this clip is |
|---|
| 736 | | * before the start_time, drop it */ |
|---|
| 737 | | if |
|---|
| 738 | | ( |
|---|
| 739 | | aod->cmml_granuleshift == 0 && op->bytes > 6 |
|---|
| 740 | | && |
|---|
| 741 | | !strncmp ((char *)op->packet, "<clip", 5) |
|---|
| 742 | | && |
|---|
| 743 | | at_time < aod->anx_source->start_time-TOLERANCE |
|---|
| 744 | | ) |
|---|
| 745 | | { |
|---|
| 746 | | #ifdef DEBUG |
|---|
| 747 | | fprintf (aod->df, |
|---|
| 748 | | "anxogg::read_packet_data: CMML clip too early, dropping\n"); |
|---|
| 749 | | #endif |
|---|
| 750 | | return OGGZ_STOP_OK; |
|---|
| 751 | | } |
|---|
| 752 | | |
|---|
| 753 | | if (aod->import_cmml) { |
|---|
| 754 | | aod->import_cmml ((char *)op->packet, op->bytes, at_time, |
|---|
| 755 | | aod->import_user_data); |
|---|
| 756 | | } |
|---|
| 757 | | return OGGZ_CONTINUE; |
|---|
| 758 | | } else { |
|---|
| 759 | | if (aot->anxv2_ignore_packet) { |
|---|
| 760 | | aot->anxv2_ignore_packet = 0; |
|---|
| 761 | | op->b_o_s = 1; |
|---|
| 762 | | } else { |
|---|
| 763 | | aod->got_non_bos = 1; |
|---|
| 764 | | } |
|---|
| 765 | | } |
|---|
| 766 | | } |
|---|
| 767 | | |
|---|
| 768 | | track = &(aot->source_track); |
|---|
| 769 | | |
|---|
| 770 | | if (!track) { |
|---|
| 771 | | #ifdef DEBUG |
|---|
| 772 | | fprintf (aod->df, "anxogg::read_packet: track NULL\n"); |
|---|
| 773 | | #endif |
|---|
| 774 | | return OGGZ_STOP_OK; |
|---|
| 775 | | } |
|---|
| 776 | | |
|---|
| 777 | | if (aod->nr_headers_remaining == 0 && !aod->got_end && |
|---|
| 778 | | (m->end_time != -1.0) && (gp != -1)) { |
|---|
| 779 | | ogg_int64_t granule = gp_to_granule (oggz, serialno, gp); |
|---|
| 780 | | if (granule >= track->end_granule) { |
|---|
| 781 | | #ifdef DEBUG |
|---|
| 782 | | fprintf (aod->df, "anxogg::read_packet_data: got_end\n"); |
|---|
| 783 | | #endif |
|---|
| 784 | | aod->got_end = 1; |
|---|
| 785 | | } |
|---|
| 786 | | } |
|---|
| 787 | | |
|---|
| 788 | | #ifdef DEBUG |
|---|
| 789 | | fprintf (aod->df, "anxogg::read_packet: Filter? (%s)\n", |
|---|
| 790 | | aod->state == STATE_FILTER ? "USE_FN" : "NO_FN"); |
|---|
| 791 | | #endif |
|---|
| 792 | | |
|---|
| 793 | | if (!aod->ignore_media && !aod->got_end && !aot->anxv2_ignore_packet && |
|---|
| 794 | | (aod->state != STATE_FILTER || |
|---|
| 795 | | filter (aod, aot, serialno, op))) { |
|---|
| 796 | | #ifdef DEBUG |
|---|
| 797 | | fprintf (aod->df, "anxogg::read_packet_data: no, copy out\n"); |
|---|
| 798 | | #endif |
|---|
| 799 | | aop = anx_malloc (sizeof (AnxOggPacket)); |
|---|
| 800 | | aop->length = op->bytes; |
|---|
| 801 | | aop->data = anx_malloc (op->bytes); |
|---|
| 802 | | aop->granulepos = op->granulepos; |
|---|
| 803 | | aop->current_time = ((double)oggz_tell_units (oggz)) / SUBSECONDS; |
|---|
| 804 | | aop->source_track = track; |
|---|
| 805 | | aop->eos = op->e_o_s; |
|---|
| 806 | | |
|---|
| 807 | | #if 0 |
|---|
| 808 | | if (aod->nr_headers_remaining == 0 && aop->granulepos != -1) { |
|---|
| 809 | | aop->granulepos -= track->start_granule; |
|---|
| 810 | | } |
|---|
| 811 | | #endif |
|---|
| 812 | | |
|---|
| 813 | | memcpy (aop->data, op->packet, op->bytes); |
|---|
| 814 | | |
|---|
| 815 | | aod->media_packets = anx_list_append (aod->media_packets, aop); |
|---|
| 816 | | |
|---|
| 817 | | if (aot->nr_headers_remaining > 0) { |
|---|
| 818 | | aod->nr_headers_remaining--; |
|---|
| 819 | | aot->nr_headers_remaining--; |
|---|
| 820 | | |
|---|
| 821 | | #ifdef DEBUG |
|---|
| 822 | | fprintf (aod->df, |
|---|
| 823 | | "anxogg::read_packet_data: nr_headers_remaining = %d, start_time = %f\n", |
|---|
| 824 | | aod->nr_headers_remaining, m->start_time); |
|---|
| 825 | | #endif |
|---|
| 826 | | } |
|---|
| 827 | | |
|---|
| 828 | | if |
|---|
| 829 | | ( |
|---|
| 830 | | aod->need_seek == NEED_SEEK_PENDING |
|---|
| 831 | | && |
|---|
| 832 | | aod->nr_headers_remaining == 0 |
|---|
| 833 | | && |
|---|
| 834 | | m->start_time != 0.0 |
|---|
| 835 | | ) |
|---|
| 836 | | { |
|---|
| 837 | | if (oggz_seek_units (oggz, 0, SEEK_CUR) >= 0) { |
|---|
| 838 | | #ifdef DEBUG |
|---|
| 839 | | fprintf (aod->df, "anxogg::read_packet_data NEED seek\n"); |
|---|
| 840 | | #endif |
|---|
| 841 | | aod->need_seek = NEED_SEEK; |
|---|
| 842 | | return OGGZ_CONTINUE; |
|---|
| 843 | | } |
|---|
| 844 | | } |
|---|
| 845 | | } |
|---|
| 846 | | |
|---|
| 847 | | return OGGZ_STOP_OK; |
|---|
| 848 | | } |
|---|
| 849 | | |
|---|
| | 801 | /*********************************************************** |
|---|
| | 802 | * Read: Pass data packets to the writer |
|---|
| | 803 | */ |
|---|
| | 804 | |
|---|
| | 805 | static double |
|---|
| | 806 | anxogg_seek_update (AnxSource * source) |
|---|
| | 807 | { |
|---|
| | 808 | AnxOggData * aod = (AnxOggData *)source->custom_data; |
|---|
| | 809 | double seek_offset; |
|---|
| | 810 | ogg_int64_t units, units_at; |
|---|
| | 811 | double offset; |
|---|
| | 812 | |
|---|
| | 813 | if (aod->use_granule_seek) { |
|---|
| | 814 | seek_offset = aod->min_granule_seek; |
|---|
| | 815 | #ifdef DEBUG |
|---|
| | 816 | fprintf(aod->df, "anxogg_seek_update: using min_granule_seek %f\n", |
|---|
| | 817 | seek_offset); |
|---|
| | 818 | #endif |
|---|
| | 819 | } else { |
|---|
| | 820 | seek_offset = source->start_time; |
|---|
| | 821 | #ifdef DEBUG |
|---|
| | 822 | fprintf(aod->df, "anxogg_seek_update: using start time %f\n", seek_offset); |
|---|
| | 823 | #endif |
|---|
| | 824 | } |
|---|
| | 825 | seek_offset -= 1.0; |
|---|
| | 826 | if (seek_offset < 0.0) seek_offset = 0.0; |
|---|
| | 827 | |
|---|
| | 828 | units = (ogg_int64_t)(SUBSECONDS * seek_offset); |
|---|
| | 829 | units_at = oggz_seek_units (aod->oggz, units, SEEK_SET); |
|---|
| | 830 | |
|---|
| | 831 | if (units_at == -1) { |
|---|
| | 832 | #ifdef DEBUG |
|---|
| | 833 | fprintf (aod->df, "anxogg_seek_update: oggz_seek_units FAIL\n"); |
|---|
| | 834 | #endif |
|---|
| | 835 | return -1.0; |
|---|
| | 836 | } |
|---|
| | 837 | |
|---|
| | 838 | offset = ((double)units_at) / SUBSECONDS; |
|---|
| | 839 | |
|---|
| | 840 | aod->need_seek = NEED_SEEK_DONE; |
|---|
| | 841 | |
|---|
| | 842 | #ifdef DEBUG |
|---|
| | 843 | fprintf (aod->df, |
|---|
| | 844 | "anxogg: seek_update to %lld (wanted %lld (%f))\n", units_at, |
|---|
| | 845 | units, seek_offset); |
|---|
| | 846 | #endif |
|---|
| | 847 | |
|---|
| | 848 | if (source->end_time != -1.0 && offset >= source->end_time) { |
|---|
| | 849 | #ifdef DEBUG |
|---|
| | 850 | fprintf (aod->df, |
|---|
| | 851 | "anxoggg: seek update > end_time %f\n", source->end_time); |
|---|
| | 852 | #endif |
|---|
| | 853 | aod->got_end = 1; |
|---|
| | 854 | } |
|---|
| | 855 | |
|---|
| | 856 | return offset; |
|---|
| | 857 | } |
|---|
| | 858 | |
|---|
| | 859 | static long |
|---|
| | 860 | anxogg_read_update (AnxSource * media) |
|---|
| | 861 | { |
|---|
| | 862 | AnxOggData * aod = (AnxOggData *)media->custom_data; |
|---|
| | 863 | |
|---|
| | 864 | do_read: |
|---|
| | 865 | |
|---|
| | 866 | while ((aod->media_packets == NULL) && (oggz_read (aod->oggz, 1024)) != 0); |
|---|
| | 867 | |
|---|
| | 868 | if (aod->need_seek == NEED_SEEK && aod->nr_headers_remaining == 0) { |
|---|
| | 869 | anxogg_seek_update (media); |
|---|
| | 870 | goto do_read; |
|---|
| | 871 | } |
|---|
| | 872 | |
|---|
| | 873 | return 0; |
|---|
| | 874 | } |
|---|
| | 875 | |
|---|
| | 876 | /*********************************************************** |
|---|
| | 877 | * A filter predicate, used between the min seek granule |
|---|
| | 878 | * and the start time (ie. the bit between the prior keyframe |
|---|
| | 879 | * and the chop time) to filter packets which should be |
|---|
| | 880 | * included in the output. |
|---|
| | 881 | * \returns 0 Do not include \a op |
|---|
| | 882 | * \returns 1 Do include \a op |
|---|
| | 883 | */ |
|---|
| | 884 | static int |
|---|
| | 885 | filter (AnxOggData * aod, AnxOggTrack * aot, long serialno, ogg_packet * op) { |
|---|
| | 886 | |
|---|
| | 887 | AnxSourceTrack * track = &(aot->source_track); |
|---|
| | 888 | double timestamp; |
|---|
| | 889 | |
|---|
| | 890 | #ifdef DEBUG |
|---|
| | 891 | fprintf(aod->df, "state %s got_keygranule %d gp %llx keygranule %llx\n", |
|---|
| | 892 | aod->state == STATE_FILTER ? "FILTER" : "NOFILTER", |
|---|
| | 893 | aot->filter_got_keygranule, op->granulepos, aot->keygranule); |
|---|
| | 894 | #endif |
|---|
| | 895 | |
|---|
| | 896 | /* TRUE if we're not in state FILTER */ |
|---|
| | 897 | if (aod->state != STATE_FILTER) return 1; |
|---|
| | 898 | |
|---|
| | 899 | /* TRUE if we haven't done the seek yet */ |
|---|
| | 900 | if (aod->need_seek == NEED_SEEK_PENDING) return 1; |
|---|
| | 901 | |
|---|
| | 902 | timestamp = gp_to_time (aod->oggz, serialno, op->granulepos); |
|---|
| | 903 | |
|---|
| | 904 | #ifdef DEBUG |
|---|
| | 905 | fprintf(aod->df, "timestamp %f start_time %f\n", timestamp, |
|---|
| | 906 | aod->anx_source->start_time); |
|---|
| | 907 | #endif |
|---|
| | 908 | |
|---|
| | 909 | /* TRUE if we're beyond the start time */ |
|---|
| | 910 | if (timestamp-TOLERANCE >= aod->anx_source->start_time) { |
|---|
| | 911 | aod->state = STATE_DATA; |
|---|
| | 912 | return 1; |
|---|
| | 913 | } |
|---|
| | 914 | |
|---|
| | 915 | /* from here, we know we're filtering */ |
|---|
| | 916 | |
|---|
| | 917 | /* FALSE if we're not using granule_seek at all */ |
|---|
| | 918 | if (!aod->use_granule_seek) return 0; |
|---|
| | 919 | |
|---|
| | 920 | /* FALSE if this track doesn't use granuleshift */ |
|---|
| | 921 | if (track->granuleshift == 0) return 0; |
|---|
| | 922 | |
|---|
| | 923 | /* TRUE if we're beyond the keygranule for this track */ |
|---|
| | 924 | if (aot->filter_got_keygranule) return 1; |
|---|
| | 925 | |
|---|
| | 926 | if (op->granulepos >= aot->keygranule) { |
|---|
| | 927 | aot->filter_got_keygranule = 1; |
|---|
| | 928 | return 1; |
|---|
| | 929 | } |
|---|
| | 930 | |
|---|
| | 931 | /* TRUE if we're after the keygranule time */ |
|---|
| | 932 | #if 0 |
|---|
| | 933 | if (op->granulepos != -1 && timestamp+TOLERANCE >= aot->keygranule_time) { |
|---|
| | 934 | aot->filter_got_keygranule = 1; |
|---|
| | 935 | return 1; |
|---|
| | 936 | } |
|---|
| | 937 | |
|---|
| | 938 | /* XXX: TRUE if a theora from a keyframe, even if no granulepos */ |
|---|
| | 939 | if (!strcmp (track->content_type, THEORA_CONTENT_TYPE) && |
|---|
| | 940 | op->bytes > 0 && !(op->packet[0] & 0xC0)) { |
|---|
| | 941 | #ifdef DEBUG |
|---|
| | 942 | fprintf (aod->df, |
|---|
| | 943 | "anxogg::FILTER got Theora keyframe\n"); |
|---|
| | 944 | #endif |
|---|
| | 945 | |
|---|
| | 946 | aot->filter_got_keygranule = 1; |
|---|
| | 947 | return 1; |
|---|
| | 948 | } |
|---|
| | 949 | |
|---|
| | 950 | #endif |
|---|
| | 951 | |
|---|
| | 952 | /* FALSE otherwise */ |
|---|
| | 953 | return 0; |
|---|
| | 954 | |
|---|
| | 955 | #if 0 |
|---|
| | 956 | /* FALSE if this track uses keygranules, and we're before its time */ |
|---|
| | 957 | if (granulepos != -1 && timestamp+TOLERANCE < aot->keygranule_time) return 0; |
|---|
| | 958 | |
|---|
| | 959 | /* TRUE otherwise */ |
|---|
| | 960 | return 1; |
|---|
| | 961 | #endif |
|---|
| | 962 | } |
|---|
| | 963 | |
|---|
| | 964 | static int |
|---|
| | 965 | read_packet_data (OGGZ * oggz, ogg_packet * op, long serialno, |
|---|
| | 966 | void * user_data) |
|---|
| | 967 | { |
|---|
| | 968 | AnxOggData * aod = (AnxOggData *)user_data; |
|---|
| | 969 | AnxOggTrack * aot = NULL; |
|---|
| | 970 | AnxOggPacket * aop; |
|---|
| | 971 | AnxSource * m = aod->anx_source; |
|---|
| | 972 | AnxSourceTrack * track = NULL; |
|---|
| | 973 | anx_int64_t gp = oggz_tell_granulepos(oggz); |
|---|
| | 974 | |
|---|
| | 975 | op->granulepos = gp; |
|---|
| | 976 | |
|---|
| | 977 | #ifdef DEBUG |
|---|
| | 978 | fprintf (aod->df, "anxogg::read_packet_data IN: %010ld, granulepos %llx\n", |
|---|
| | 979 | serialno, gp); |
|---|
| | 980 | #endif |
|---|
| | 981 | |
|---|
| | 982 | if (!(aod->cmml_serialno != -1 && serialno == aod->cmml_serialno)) { |
|---|
| | 983 | aot = (AnxOggTrack *) oggz_table_lookup (aod->logicals, serialno); |
|---|
| | 984 | if (aot == NULL) { |
|---|
| | 985 | #ifdef DEBUG |
|---|
| | 986 | fprintf (aod->df, |
|---|
| | 987 | "anxogg::read_packet_data: %010ld not found\n", serialno); |
|---|
| | 988 | #endif |
|---|
| | 989 | return OGGZ_STOP_OK; |
|---|
| | 990 | } |
|---|
| | 991 | } |
|---|
| | 992 | |
|---|
| | 993 | if (op->b_o_s) { |
|---|
| | 994 | if (!strncmp ((char *)&op->packet[0], "AnxData", 7)) { |
|---|
| | 995 | /* Mark this track as anxv2, and don't copy the AnxData packet |
|---|
| | 996 | * into the bitstream */ |
|---|
| | 997 | if (aot) aot->anxv2_ignore_packet = 1; |
|---|
| | 998 | } |
|---|
| | 999 | } else { |
|---|
| | 1000 | if (aod->cmml_serialno != -1 && serialno == aod->cmml_serialno) { |
|---|
| | 1001 | double at_time; |
|---|
| | 1002 | |
|---|
| | 1003 | #ifdef DEBUG |
|---|
| | 1004 | fprintf (aod->df, "aod->cmml_serialno %010ld, op->granulepos %lld\n", |
|---|
| | 1005 | aod->cmml_serialno, gp); |
|---|
| | 1006 | #endif |
|---|
| | 1007 | |
|---|
| | 1008 | if (gp == -1) { |
|---|
| | 1009 | return OGGZ_STOP_ERR; |
|---|
| | 1010 | } |
|---|
| | 1011 | at_time = gp_to_time (aod->oggz, serialno, gp); |
|---|
| | 1012 | |
|---|
| | 1013 | #ifdef DEBUG |
|---|
| | 1014 | { |
|---|
| | 1015 | char * header = (char *)op->packet; |
|---|
| | 1016 | fprintf (aod->df, |
|---|
| | 1017 | "anxogg::read_packet_data: got CMML <%c%c%c%c> at %f\n", |
|---|
| | 1018 | header[1], header[2], header[3], header[4], at_time); |
|---|
| | 1019 | } |
|---|
| | 1020 | #endif |
|---|
| | 1021 | |
|---|
| | 1022 | /* If this content doesn't use cmml_granuleshift, and this clip is |
|---|
| | 1023 | * before the start_time, drop it */ |
|---|
| | 1024 | if |
|---|
| | 1025 | ( |
|---|
| | 1026 | aod->cmml_granuleshift == 0 && op->bytes > 6 |
|---|
| | 1027 | && |
|---|
| | 1028 | !strncmp ((char *)op->packet, "<clip", 5) |
|---|
| | 1029 | && |
|---|
| | 1030 | at_time < aod->anx_source->start_time-TOLERANCE |
|---|
| | 1031 | ) |
|---|
| | 1032 | { |
|---|
| | 1033 | #ifdef DEBUG |
|---|
| | 1034 | fprintf (aod->df, |
|---|
| | 1035 | "anxogg::read_packet_data: CMML clip too early, dropping\n"); |
|---|
| | 1036 | #endif |
|---|
| | 1037 | return OGGZ_STOP_OK; |
|---|
| | 1038 | } |
|---|
| | 1039 | |
|---|
| | 1040 | if (aod->import_cmml) { |
|---|
| | 1041 | aod->import_cmml ((char *)op->packet, op->bytes, at_time, |
|---|
| | 1042 | aod->import_user_data); |
|---|
| | 1043 | } |
|---|
| | 1044 | return OGGZ_CONTINUE; |
|---|
| | 1045 | } else { |
|---|
| | 1046 | if (aot->anxv2_ignore_packet) { |
|---|
| | 1047 | aot->anxv2_ignore_packet = 0; |
|---|
| | 1048 | op->b_o_s = 1; |
|---|
| | 1049 | } else { |
|---|
| | 1050 | aod->got_non_bos = 1; |
|---|
| | 1051 | } |
|---|
| | 1052 | } |
|---|
| | 1053 | } |
|---|
| | 1054 | |
|---|
| | 1055 | track = &(aot->source_track); |
|---|
| | 1056 | |
|---|
| | 1057 | if (!track) { |
|---|
| | 1058 | #ifdef DEBUG |
|---|
| | 1059 | fprintf (aod->df, "anxogg::read_packet: track NULL\n"); |
|---|
| | 1060 | #endif |
|---|
| | 1061 | return OGGZ_STOP_OK; |
|---|
| | 1062 | } |
|---|
| | 1063 | |
|---|
| | 1064 | if (aod->nr_headers_remaining == 0 && !aod->got_end && |
|---|
| | 1065 | (m->end_time != -1.0) && (gp != -1)) { |
|---|
| | 1066 | ogg_int64_t granule = gp_to_granule (oggz, serialno, gp); |
|---|
| | 1067 | if (granule >= track->end_granule) { |
|---|
| | 1068 | #ifdef DEBUG |
|---|
| | 1069 | fprintf (aod->df, "anxogg::read_packet_data: got_end\n"); |
|---|
| | 1070 | #endif |
|---|
| | 1071 | aod->got_end = 1; |
|---|
| | 1072 | } |
|---|
| | 1073 | } |
|---|
| | 1074 | |
|---|
| | 1075 | #ifdef DEBUG |
|---|
| | 1076 | fprintf (aod->df, "anxogg::read_packet: Filter? (%s)\n", |
|---|
| | 1077 | aod->state == STATE_FILTER ? "USE_FN" : "NO_FN"); |
|---|
| | 1078 | #endif |
|---|
| | 1079 | |
|---|
| | 1080 | if (!aod->ignore_media && !aod->got_end && !aot->anxv2_ignore_packet && |
|---|
| | 1081 | (aod->state != STATE_FILTER || |
|---|
| | 1082 | filter (aod, aot, serialno, op))) { |
|---|
| | 1083 | #ifdef DEBUG |
|---|
| | 1084 | fprintf (aod->df, "anxogg::read_packet_data: no, copy out\n"); |
|---|
| | 1085 | #endif |
|---|
| | 1086 | aop = anx_malloc (sizeof (AnxOggPacket)); |
|---|
| | 1087 | aop->length = op->bytes; |
|---|
| | 1088 | aop->data = anx_malloc (op->bytes); |
|---|
| | 1089 | aop->granulepos = op->granulepos; |
|---|
| | 1090 | aop->current_time = ((double)oggz_tell_units (oggz)) / SUBSECONDS; |
|---|
| | 1091 | aop->source_track = track; |
|---|
| | 1092 | aop->eos = op->e_o_s; |
|---|
| | 1093 | |
|---|
| | 1094 | #if 0 |
|---|
| | 1095 | if (aod->nr_headers_remaining == 0 && aop->granulepos != -1) { |
|---|
| | 1096 | aop->granulepos -= track->start_granule; |
|---|
| | 1097 | } |
|---|
| | 1098 | #endif |
|---|
| | 1099 | |
|---|
| | 1100 | memcpy (aop->data, op->packet, op->bytes); |
|---|
| | 1101 | |
|---|
| | 1102 | aod->media_packets = anx_list_append (aod->media_packets, aop); |
|---|
| | 1103 | |
|---|
| | 1104 | if (aot->nr_headers_remaining > 0) { |
|---|
| | 1105 | aod->nr_headers_remaining--; |
|---|
| | 1106 | aot->nr_headers_remaining--; |
|---|
| | 1107 | |
|---|
| | 1108 | #ifdef DEBUG |
|---|
| | 1109 | fprintf (aod->df, |
|---|
| | 1110 | "anxogg::read_packet_data: nr_headers_remaining = %d, start_time = %f\n", |
|---|
| | 1111 | aod->nr_headers_remaining, m->start_time); |
|---|
| | 1112 | #endif |
|---|
| | 1113 | } |
|---|
| | 1114 | |
|---|
| | 1115 | if |
|---|
| | 1116 | ( |
|---|
| | 1117 | aod->need_seek == NEED_SEEK_PENDING |
|---|
| | 1118 | && |
|---|
| | 1119 | aod->nr_headers_remaining == 0 |
|---|
| | 1120 | && |
|---|
| | 1121 | m->start_time != 0.0 |
|---|
| | 1122 | ) |
|---|
| | 1123 | { |
|---|
| | 1124 | if (oggz_seek_units (oggz, 0, SEEK_CUR) >= 0) { |
|---|
| | 1125 | #ifdef DEBUG |
|---|
| | 1126 | fprintf (aod->df, "anxogg::read_packet_data NEED seek\n"); |
|---|
| | 1127 | #endif |
|---|
| | 1128 | aod->need_seek = NEED_SEEK; |
|---|
| | 1129 | return OGGZ_CONTINUE; |
|---|
| | 1130 | } |
|---|
| | 1131 | } |
|---|
| | 1132 | } |
|---|
| | 1133 | |
|---|
| | 1134 | return OGGZ_STOP_OK; |
|---|
| | 1135 | } |
|---|
| | 1136 | |
|---|
| | 1137 | static AnxOggPacket * |
|---|
| | 1138 | anxogg_packet_free (AnxOggPacket * aop) |
|---|
| | 1139 | { |
|---|
| | 1140 | anx_free (aop->data); |
|---|
| | 1141 | anx_free (aop); |
|---|
| | 1142 | return NULL; |
|---|
| | 1143 | } |
|---|
| | 1144 | |
|---|
| | 1145 | static long |
|---|
| | 1146 | anxogg_read (AnxSource * media, char * buf, long n, long bound) |
|---|
| | 1147 | { |
|---|
| | 1148 | AnxOggData * aod = (AnxOggData *)media->custom_data; |
|---|
| | 1149 | AnxOggPacket * aop; |
|---|
| | 1150 | AnxList * head; |
|---|
| | 1151 | long bytes_to_read; |
|---|
| | 1152 | |
|---|
| | 1153 | if (aod->ignore_media) return -1; |
|---|
| | 1154 | |
|---|
| | 1155 | anxogg_read_update (media); |
|---|
| | 1156 | |
|---|
| | 1157 | head = aod->media_packets; |
|---|
| | 1158 | if (head == NULL) { |
|---|
| | 1159 | media->eos = 1; |
|---|
| | 1160 | return 0; |
|---|
| | 1161 | } |
|---|
| | 1162 | |
|---|
| | 1163 | aop = (AnxOggPacket *)head->data; |
|---|
| | 1164 | bytes_to_read = MIN (n, aop->length - aod->current_offset); |
|---|
| | 1165 | |
|---|
| | 1166 | memcpy (buf, &aop->data[aod->current_offset], bytes_to_read); |
|---|
| | 1167 | |
|---|
| | 1168 | aod->current_offset += bytes_to_read; |
|---|
| | 1169 | |
|---|
| | 1170 | if (aod->headers_unread > 0) aod->headers_unread--; |
|---|
| | 1171 | if (aod->headers_unread == 0) media->written_secondaries = 1; |
|---|
| | 1172 | |
|---|
| | 1173 | media->current_track = aop->source_track; |
|---|
| | 1174 | |
|---|
| | 1175 | #ifdef DEBUG_VERBOSE |
|---|
| | 1176 | fprintf (aod->df, "anxogg: reading from stream %s\n", |
|---|
| | 1177 | media->current_track->content_type); |
|---|
| | 1178 | #endif |
|---|
| | 1179 | |
|---|
| | 1180 | media->current_track->current_granule = aop->granulepos; |
|---|
| | 1181 | media->current_track->eos = aop->eos; |
|---|
| | 1182 | |
|---|
| | 1183 | /* If that's finished this media packet, advance to the next one */ |
|---|
| | 1184 | if (aod->current_offset >= aop->length) { |
|---|
| | 1185 | aod->media_packets = |
|---|
| | 1186 | anx_list_remove (aod->media_packets, head); |
|---|
| | 1187 | |
|---|
| | 1188 | aop = anxogg_packet_free (aop); |
|---|
| | 1189 | anx_free (head); |
|---|
| | 1190 | |
|---|
| | 1191 | aod->current_offset = 0; |
|---|
| | 1192 | |
|---|
| | 1193 | anxogg_read_update (media); |
|---|
| | 1194 | |
|---|
| | 1195 | if (aod->media_packets != NULL) |
|---|
| | 1196 | aop = (AnxOggPacket *)aod->media_packets->data; |
|---|
| | 1197 | } |
|---|
| | 1198 | |
|---|
| | 1199 | /* Set current time to the current time of the next packet that would |
|---|
| | 1200 | * be served */ |
|---|
| | 1201 | if (aop && aop->current_time != -1) |
|---|
| | 1202 | media->current_time = aop->current_time; |
|---|
| | 1203 | |
|---|
| | 1204 | return bytes_to_read; |
|---|
| | 1205 | } |
|---|
| | 1206 | |
|---|
| | 1207 | static long |
|---|
| | 1208 | anxogg_sizeof_next_read (AnxSource * media, long bound) |
|---|
| | 1209 | { |
|---|
| | 1210 | AnxOggData * aod = (AnxOggData *)media->custom_data; |
|---|
| | 1211 | AnxOggPacket * aop; |
|---|
| | 1212 | long bytes_to_read; |
|---|
| | 1213 | |
|---|
| | 1214 | if (aod->ignore_media) return -1; |
|---|
| | 1215 | |
|---|
| | 1216 | while ((aod->media_packets == NULL) && (oggz_read (aod->oggz, 1024)) != 0); |
|---|
| | 1217 | |
|---|
| | 1218 | if (aod->media_packets == NULL) { |
|---|
| | 1219 | media->eos = 1; |
|---|
| | 1220 | return 0; |
|---|
| | 1221 | } |
|---|
| | 1222 | |
|---|
| | 1223 | aop = (AnxOggPacket *)aod->media_packets->data; |
|---|
| | 1224 | bytes_to_read = aop->length - aod->current_offset; |
|---|
| | 1225 | |
|---|
| | 1226 | return bytes_to_read; |
|---|
| | 1227 | } |
|---|
| | 1228 | |
|---|
| | 1229 | /*********************************************************** |
|---|
| | 1230 | * Open |
|---|
| | 1231 | */ |
|---|
| | 1232 | |
|---|
| 1224 | | static long |
|---|
| 1225 | | anxogg_read_update (AnxSource * media) |
|---|
| 1226 | | { |
|---|
| 1227 | | AnxOggData * aod = (AnxOggData *)media->custom_data; |
|---|
| 1228 | | |
|---|
| 1229 | | do_read: |
|---|
| 1230 | | |
|---|
| 1231 | | while ((aod->media_packets == NULL) && (oggz_read (aod->oggz, 1024)) != 0); |
|---|
| 1232 | | |
|---|
| 1233 | | if (aod->need_seek == NEED_SEEK && aod->nr_headers_remaining == 0) { |
|---|
| 1234 | | anxogg_seek_update (media); |
|---|
| 1235 | | goto do_read; |
|---|
| 1236 | | } |
|---|
| 1237 | | |
|---|
| 1238 | | return 0; |
|---|
| 1239 | | } |
|---|
| 1240 | | |
|---|
| 1241 | | static AnxOggPacket * |
|---|
| 1242 | | anxogg_packet_free (AnxOggPacket * aop) |
|---|
| 1243 | | { |
|---|
| 1244 | | anx_free (aop->data); |
|---|
| 1245 | | anx_free (aop); |
|---|
| 1246 | | return NULL; |
|---|
| 1247 | | } |
|---|
| 1248 | | |
|---|
| 1249 | | static long |
|---|
| 1250 | | anxogg_read (AnxSource * media, char * buf, long n, long bound) |
|---|
| 1251 | | { |
|---|
| 1252 | | AnxOggData * aod = (AnxOggData *)media->custom_data; |
|---|
| 1253 | | AnxOggPacket * aop; |
|---|
| 1254 | | AnxList * head; |
|---|
| 1255 | | long bytes_to_read; |
|---|
| 1256 | | |
|---|
| 1257 | | if (aod->ignore_media) return -1; |
|---|
| 1258 | | |
|---|
| 1259 | | anxogg_read_update (media); |
|---|
| 1260 | | |
|---|
| 1261 | | head = aod->media_packets; |
|---|
| 1262 | | if (head == NULL) { |
|---|
| 1263 | | media->eos = 1; |
|---|
| 1264 | | return 0; |
|---|
| 1265 | | } |
|---|
| 1266 | | |
|---|
| 1267 | | aop = (AnxOggPacket *)head->data; |
|---|
| 1268 | | bytes_to_read = MIN (n, aop->length - aod->current_offset); |
|---|
| 1269 | | |
|---|
| 1270 | | memcpy (buf, &aop->data[aod->current_offset], bytes_to_read); |
|---|
| 1271 | | |
|---|
| 1272 | | aod->current_offset += bytes_to_read; |
|---|
| 1273 | | |
|---|
| 1274 | | if (aod->headers_unread > 0) aod->headers_unread--; |
|---|
| 1275 | | if (aod->headers_unread == 0) media->written_secondaries = 1; |
|---|
| 1276 | | |
|---|
| 1277 | | media->current_track = aop->source_track; |
|---|
| 1278 | | |
|---|
| 1279 | | #ifdef DEBUG_VERBOSE |
|---|
| 1280 | | fprintf (aod->df, "anxogg: reading from stream %s\n", |
|---|
| 1281 | | media->current_track->content_type); |
|---|
| 1282 | | #endif |
|---|
| 1283 | | |
|---|
| 1284 | | media->current_track->current_granule = aop->granulepos; |
|---|
| 1285 | | media->current_track->eos = aop->eos; |
|---|
| 1286 | | |
|---|
| 1287 | | /* If that's finished this media packet, advance to the next one */ |
|---|
| 1288 | | if (aod->current_offset >= aop->length) { |
|---|
| 1289 | | aod->media_packets = |
|---|
| 1290 | | anx_list_remove (aod->media_packets, head); |
|---|
| 1291 | | |
|---|
| 1292 | | aop = anxogg_packet_free (aop); |
|---|
| 1293 | | anx_free (head); |
|---|
| 1294 | | |
|---|
| 1295 | | aod->current_offset = 0; |
|---|
| 1296 | | |
|---|
| 1297 | | anxogg_read_update (media); |
|---|
| 1298 | | |
|---|
| 1299 | | if (aod->media_packets != NULL) |
|---|
| 1300 | | aop = (AnxOggPacket *)aod->media_packets->data; |
|---|
| 1301 | | } |
|---|
| 1302 | | |
|---|
| 1303 | | /* Set current time to the current time of the next packet that would |
|---|
| 1304 | | * be served */ |
|---|
| 1305 | | if (aop && aop->current_time != -1) |
|---|
| 1306 | | media->current_time = aop->current_time; |
|---|
| 1307 | | |
|---|
| 1308 | | return bytes_to_read; |
|---|
| 1309 | | } |
|---|
| 1310 | | |
|---|
| 1311 | | static long |
|---|
| 1312 | | anxogg_sizeof_next_read (AnxSource * media, long bound) |
|---|
| 1313 | | { |
|---|
| 1314 | | AnxOggData * aod = (AnxOggData *)media->custom_data; |
|---|
| 1315 | | AnxOggPacket * aop; |
|---|
| 1316 | | long bytes_to_read; |
|---|
| 1317 | | |
|---|
| 1318 | | if (aod->ignore_media) return -1; |
|---|
| 1319 | | |
|---|
| 1320 | | while ((aod->media_packets == NULL) && (oggz_read (aod->oggz, 1024)) != 0); |
|---|
| 1321 | | |
|---|
| 1322 | | if (aod->media_packets == NULL) { |
|---|
| 1323 | | media->eos = 1; |
|---|
| 1324 | | return 0; |
|---|
| 1325 | | } |
|---|
| 1326 | | |
|---|
| 1327 | | aop = (AnxOggPacket *)aod->media_packets->data; |
|---|
| 1328 | | bytes_to_read = aop->length - aod->current_offset; |
|---|
| 1329 | | |
|---|
| 1330 | | return bytes_to_read; |
|---|
| 1331 | | } |
|---|
| 1332 | | |
|---|
| | 1341 | /*********************************************************** |
|---|
| | 1342 | * Close |
|---|
| | 1343 | */ |
|---|