Revision d88d806b libavformat/matroskadec.c

View differences:

libavformat/matroskadec.c
1643 1643
    if (ebml_peek_id(matroska, NULL) != MATROSKA_ID_CLUSTER)
1644 1644
        return -1;
1645 1645

  
1646
    {
1647
        tracks = matroska->tracks.elem;
1648
        for (i=0; i < matroska->tracks.nb_elem; i++) {
1649
            MatroskaTrack *track = &tracks[i];
1650
            enum CodecID codec_id = CODEC_ID_NONE;
1651
            uint8_t *extradata = NULL;
1652
            int extradata_size = 0;
1653
            int extradata_offset = 0;
1654

  
1655
            /* Apply some sanity checks. */
1656
            if (track->codec_id == NULL)
1657
                continue;
1658

  
1659
            for(j=0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++){
1660
                if(!strncmp(ff_mkv_codec_tags[j].str, track->codec_id,
1661
                            strlen(ff_mkv_codec_tags[j].str))){
1662
                    codec_id= ff_mkv_codec_tags[j].id;
1663
                    break;
1664
                }
1646
    tracks = matroska->tracks.elem;
1647
    for (i=0; i < matroska->tracks.nb_elem; i++) {
1648
        MatroskaTrack *track = &tracks[i];
1649
        enum CodecID codec_id = CODEC_ID_NONE;
1650
        uint8_t *extradata = NULL;
1651
        int extradata_size = 0;
1652
        int extradata_offset = 0;
1653

  
1654
        /* Apply some sanity checks. */
1655
        if (track->codec_id == NULL)
1656
            continue;
1657

  
1658
        for(j=0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++){
1659
            if(!strncmp(ff_mkv_codec_tags[j].str, track->codec_id,
1660
                        strlen(ff_mkv_codec_tags[j].str))){
1661
                codec_id= ff_mkv_codec_tags[j].id;
1662
                break;
1665 1663
            }
1664
        }
1666 1665

  
1667
            st = track->stream = av_new_stream(s, matroska->num_streams++);
1668
            if (st == NULL)
1669
                return AVERROR(ENOMEM);
1666
        st = track->stream = av_new_stream(s, matroska->num_streams++);
1667
        if (st == NULL)
1668
            return AVERROR(ENOMEM);
1669

  
1670
        /* Set the FourCC from the CodecID. */
1671
        /* This is the MS compatibility mode which stores a
1672
         * BITMAPINFOHEADER in the CodecPrivate. */
1673
        if (!strcmp(track->codec_id,
1674
                    MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC) &&
1675
            (track->codec_priv.size >= 40) &&
1676
            (track->codec_priv.data != NULL)) {
1677
            /* Offset of biCompression. Stored in LE. */
1678
            track->video.fourcc = AV_RL32(track->codec_priv.data + 16);
1679
            codec_id = codec_get_id(codec_bmp_tags, track->video.fourcc);
1670 1680

  
1671
            /* Set the FourCC from the CodecID. */
1672
            /* This is the MS compatibility mode which stores a
1673
             * BITMAPINFOHEADER in the CodecPrivate. */
1674
            if (!strcmp(track->codec_id,
1675
                        MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC) &&
1676
                (track->codec_priv.size >= 40) &&
1677
                (track->codec_priv.data != NULL)) {
1678
                /* Offset of biCompression. Stored in LE. */
1679
                track->video.fourcc = AV_RL32(track->codec_priv.data + 16);
1680
                codec_id = codec_get_id(codec_bmp_tags, track->video.fourcc);
1681
        }
1681 1682

  
1682
            }
1683
        /* This is the MS compatibility mode which stores a
1684
         * WAVEFORMATEX in the CodecPrivate. */
1685
        else if (!strcmp(track->codec_id,
1686
                         MATROSKA_CODEC_ID_AUDIO_ACM) &&
1687
                 (track->codec_priv.size >= 18) &&
1688
                 (track->codec_priv.data != NULL)) {
1689
            /* Offset of wFormatTag. Stored in LE. */
1690
            uint16_t tag = AV_RL16(track->codec_priv.data);
1691
            codec_id = codec_get_id(codec_wav_tags, tag);
1683 1692

  
1684
            /* This is the MS compatibility mode which stores a
1685
             * WAVEFORMATEX in the CodecPrivate. */
1686
            else if (!strcmp(track->codec_id,
1687
                             MATROSKA_CODEC_ID_AUDIO_ACM) &&
1688
                (track->codec_priv.size >= 18) &&
1689
                (track->codec_priv.data != NULL)) {
1690
                /* Offset of wFormatTag. Stored in LE. */
1691
                uint16_t tag = AV_RL16(track->codec_priv.data);
1692
                codec_id = codec_get_id(codec_wav_tags, tag);
1693
        }
1693 1694

  
1694
            }
1695
        else if (!strcmp(track->codec_id, "V_QUICKTIME") &&
1696
                 (track->codec_priv.size >= 86) &&
1697
                 (track->codec_priv.data != NULL)) {
1698
            track->video.fourcc = AV_RL32(track->codec_priv.data);
1699
            codec_id=codec_get_id(codec_movvideo_tags, track->video.fourcc);
1700
        }
1695 1701

  
1696
            if (!strcmp(track->codec_id, "V_QUICKTIME") &&
1697
                (track->codec_priv.size >= 86) &&
1698
                (track->codec_priv.data != NULL)) {
1699
                track->video.fourcc = AV_RL32(track->codec_priv.data);
1700
                codec_id=codec_get_id(codec_movvideo_tags, track->video.fourcc);
1702
        else if (codec_id == CODEC_ID_AAC && !track->codec_priv.size) {
1703
            int profile = matroska_aac_profile(track->codec_id);
1704
            int sri = matroska_aac_sri(track->audio.samplerate);
1705
            extradata = av_malloc(5);
1706
            if (extradata == NULL)
1707
                return AVERROR(ENOMEM);
1708
            extradata[0] = (profile << 3) | ((sri&0x0E) >> 1);
1709
            extradata[1] = ((sri&0x01) << 7) | (track->audio.channels<<3);
1710
            if (strstr(track->codec_id, "SBR")) {
1711
                sri = matroska_aac_sri(track->audio.out_samplerate);
1712
                extradata[2] = 0x56;
1713
                extradata[3] = 0xE5;
1714
                extradata[4] = 0x80 | (sri<<3);
1715
                extradata_size = 5;
1716
            } else {
1717
                extradata_size = 2;
1701 1718
            }
1719
        }
1702 1720

  
1703
            else if (codec_id == CODEC_ID_AAC && !track->codec_priv.size) {
1704
                int profile = matroska_aac_profile(track->codec_id);
1705
                int sri = matroska_aac_sri(track->audio.samplerate);
1706
                extradata = av_malloc(5);
1707
                if (extradata == NULL)
1708
                    return AVERROR(ENOMEM);
1709
                extradata[0] = (profile << 3) | ((sri&0x0E) >> 1);
1710
                extradata[1] = ((sri&0x01) << 7) | (track->audio.channels<<3);
1711
                if (strstr(track->codec_id, "SBR")) {
1712
                    sri = matroska_aac_sri(track->audio.out_samplerate);
1713
                    extradata[2] = 0x56;
1714
                    extradata[3] = 0xE5;
1715
                    extradata[4] = 0x80 | (sri<<3);
1716
                    extradata_size = 5;
1717
                } else {
1718
                    extradata_size = 2;
1719
                }
1720
            }
1721
        else if (codec_id == CODEC_ID_TTA) {
1722
            ByteIOContext b;
1723
            extradata_size = 30;
1724
            extradata = av_mallocz(extradata_size);
1725
            if (extradata == NULL)
1726
                return AVERROR(ENOMEM);
1727
            init_put_byte(&b, extradata, extradata_size, 1,
1728
                          NULL, NULL, NULL, NULL);
1729
            put_buffer(&b, "TTA1", 4);
1730
            put_le16(&b, 1);
1731
            put_le16(&b, track->audio.channels);
1732
            put_le16(&b, track->audio.bitdepth);
1733
            put_le32(&b, track->audio.out_samplerate);
1734
            put_le32(&b, matroska->ctx->duration * track->audio.out_samplerate);
1735
        }
1721 1736

  
1722
            else if (codec_id == CODEC_ID_TTA) {
1723
                ByteIOContext b;
1724
                extradata_size = 30;
1725
                extradata = av_mallocz(extradata_size);
1726
                if (extradata == NULL)
1727
                    return AVERROR(ENOMEM);
1728
                init_put_byte(&b, extradata, extradata_size, 1,
1729
                              NULL, NULL, NULL, NULL);
1730
                put_buffer(&b, "TTA1", 4);
1731
                put_le16(&b, 1);
1732
                put_le16(&b, track->audio.channels);
1733
                put_le16(&b, track->audio.bitdepth);
1734
                put_le32(&b, track->audio.out_samplerate);
1735
                put_le32(&b, matroska->ctx->duration * track->audio.out_samplerate);
1736
            }
1737
        else if (codec_id == CODEC_ID_RV10 || codec_id == CODEC_ID_RV20 ||
1738
                 codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) {
1739
            extradata_offset = 26;
1740
            track->codec_priv.size -= extradata_offset;
1741
        }
1742

  
1743
        else if (codec_id == CODEC_ID_RA_144) {
1744
            track->audio.out_samplerate = 8000;
1745
            track->audio.channels = 1;
1746
        }
1737 1747

  
1738
            else if (codec_id == CODEC_ID_RV10 || codec_id == CODEC_ID_RV20 ||
1739
                     codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) {
1740
                extradata_offset = 26;
1748
        else if (codec_id == CODEC_ID_RA_288 ||
1749
                 codec_id == CODEC_ID_COOK ||
1750
                 codec_id == CODEC_ID_ATRAC3) {
1751
            ByteIOContext b;
1752

  
1753
            init_put_byte(&b, track->codec_priv.data,track->codec_priv.size,
1754
                          0, NULL, NULL, NULL, NULL);
1755
            url_fskip(&b, 24);
1756
            track->audio.coded_framesize = get_be32(&b);
1757
            url_fskip(&b, 12);
1758
            track->audio.sub_packet_h    = get_be16(&b);
1759
            track->audio.frame_size      = get_be16(&b);
1760
            track->audio.sub_packet_size = get_be16(&b);
1761
            track->audio.buf = av_malloc(track->audio.frame_size * track->audio.sub_packet_h);
1762
            if (codec_id == CODEC_ID_RA_288) {
1763
                st->codec->block_align = track->audio.coded_framesize;
1764
                track->codec_priv.size = 0;
1765
            } else {
1766
                st->codec->block_align = track->audio.sub_packet_size;
1767
                extradata_offset = 78;
1741 1768
                track->codec_priv.size -= extradata_offset;
1742 1769
            }
1770
        }
1743 1771

  
1744
            else if (codec_id == CODEC_ID_RA_144) {
1745
                track->audio.out_samplerate = 8000;
1746
                track->audio.channels = 1;
1747
            }
1772
        if (codec_id == CODEC_ID_NONE) {
1773
            av_log(matroska->ctx, AV_LOG_INFO,
1774
                   "Unknown/unsupported CodecID %s.\n",
1775
                   track->codec_id);
1776
        }
1748 1777

  
1749
            else if (codec_id == CODEC_ID_RA_288 ||
1750
                     codec_id == CODEC_ID_COOK ||
1751
                     codec_id == CODEC_ID_ATRAC3) {
1752
                ByteIOContext b;
1753

  
1754
                init_put_byte(&b, track->codec_priv.data,track->codec_priv.size,
1755
                              0, NULL, NULL, NULL, NULL);
1756
                url_fskip(&b, 24);
1757
                track->audio.coded_framesize = get_be32(&b);
1758
                url_fskip(&b, 12);
1759
                track->audio.sub_packet_h    = get_be16(&b);
1760
                track->audio.frame_size      = get_be16(&b);
1761
                track->audio.sub_packet_size = get_be16(&b);
1762
                track->audio.buf = av_malloc(track->audio.frame_size * track->audio.sub_packet_h);
1763
                if (codec_id == CODEC_ID_RA_288) {
1764
                    st->codec->block_align = track->audio.coded_framesize;
1765
                    track->codec_priv.size = 0;
1766
                } else {
1767
                    st->codec->block_align = track->audio.sub_packet_size;
1768
                    extradata_offset = 78;
1769
                    track->codec_priv.size -= extradata_offset;
1770
                }
1771
            }
1778
        av_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
1772 1779

  
1773
            if (codec_id == CODEC_ID_NONE) {
1774
                av_log(matroska->ctx, AV_LOG_INFO,
1775
                       "Unknown/unsupported CodecID %s.\n",
1776
                       track->codec_id);
1777
            }
1780
        st->codec->codec_id = codec_id;
1781
        st->start_time = 0;
1782
        if (strcmp(track->language, "und"))
1783
            av_strlcpy(st->language, track->language, 4);
1778 1784

  
1779
            av_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
1780

  
1781
            st->codec->codec_id = codec_id;
1782
            st->start_time = 0;
1783
            if (strcmp(track->language, "und"))
1784
                av_strlcpy(st->language, track->language, 4);
1785

  
1786
            if (track->flag_default)
1787
                st->disposition |= AV_DISPOSITION_DEFAULT;
1788

  
1789
            if (track->default_duration)
1790
                av_reduce(&st->codec->time_base.num, &st->codec->time_base.den,
1791
                          track->default_duration, 1000000000, 30000);
1792

  
1793
            if(extradata){
1794
                st->codec->extradata = extradata;
1795
                st->codec->extradata_size = extradata_size;
1796
            } else if(track->codec_priv.data && track->codec_priv.size > 0){
1797
                st->codec->extradata = av_malloc(track->codec_priv.size);
1798
                if(st->codec->extradata == NULL)
1799
                    return AVERROR(ENOMEM);
1800
                st->codec->extradata_size = track->codec_priv.size;
1801
                memcpy(st->codec->extradata,
1802
                       track->codec_priv.data + extradata_offset,
1803
                       track->codec_priv.size);
1804
            }
1785
        if (track->flag_default)
1786
            st->disposition |= AV_DISPOSITION_DEFAULT;
1805 1787

  
1806
            if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
1807
                st->codec->codec_type = CODEC_TYPE_VIDEO;
1808
                st->codec->codec_tag  = track->video.fourcc;
1809
                st->codec->width  = track->video.pixel_width;
1810
                st->codec->height = track->video.pixel_height;
1811
                av_reduce(&st->codec->sample_aspect_ratio.num,
1812
                          &st->codec->sample_aspect_ratio.den,
1813
                          st->codec->height * track->video.display_width,
1814
                          st->codec-> width * track->video.display_height,
1815
                          255);
1816
                st->need_parsing = AVSTREAM_PARSE_HEADERS;
1817
            } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
1818
                st->codec->codec_type = CODEC_TYPE_AUDIO;
1819
                st->codec->sample_rate = track->audio.out_samplerate;
1820
                st->codec->channels = track->audio.channels;
1821
            } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
1822
                st->codec->codec_type = CODEC_TYPE_SUBTITLE;
1823
            }
1788
        if (track->default_duration)
1789
            av_reduce(&st->codec->time_base.num, &st->codec->time_base.den,
1790
                      track->default_duration, 1000000000, 30000);
1824 1791

  
1825
            /* What do we do with private data? E.g. for Vorbis. */
1792
        if(extradata){
1793
            st->codec->extradata = extradata;
1794
            st->codec->extradata_size = extradata_size;
1795
        } else if(track->codec_priv.data && track->codec_priv.size > 0){
1796
            st->codec->extradata = av_malloc(track->codec_priv.size);
1797
            if(st->codec->extradata == NULL)
1798
                return AVERROR(ENOMEM);
1799
            st->codec->extradata_size = track->codec_priv.size;
1800
            memcpy(st->codec->extradata,
1801
                   track->codec_priv.data + extradata_offset,
1802
                   track->codec_priv.size);
1826 1803
        }
1827
        res = 0;
1804

  
1805
        if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
1806
            st->codec->codec_type = CODEC_TYPE_VIDEO;
1807
            st->codec->codec_tag  = track->video.fourcc;
1808
            st->codec->width  = track->video.pixel_width;
1809
            st->codec->height = track->video.pixel_height;
1810
            av_reduce(&st->codec->sample_aspect_ratio.num,
1811
                      &st->codec->sample_aspect_ratio.den,
1812
                      st->codec->height * track->video.display_width,
1813
                      st->codec-> width * track->video.display_height,
1814
                      255);
1815
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
1816
        } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
1817
            st->codec->codec_type = CODEC_TYPE_AUDIO;
1818
            st->codec->sample_rate = track->audio.out_samplerate;
1819
            st->codec->channels = track->audio.channels;
1820
        } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
1821
            st->codec->codec_type = CODEC_TYPE_SUBTITLE;
1822
        }
1823

  
1824
        /* What do we do with private data? E.g. for Vorbis. */
1828 1825
    }
1826
    res = 0;
1829 1827

  
1830 1828
    index_list = &matroska->index;
1831 1829
    index = index_list->elem;

Also available in: Unified diff