~medibuntu-maintainers/mplayer/medibuntu.precise

« back to all changes in this revision

Viewing changes to ffmpeg/libavformat/matroskadec.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2012-01-12 22:23:28 UTC
  • mfrom: (0.4.7 sid)
  • mto: This revision was merged to the branch mainline in revision 76.
  • Revision ID: package-import@ubuntu.com-20120112222328-8jqdyodym3p84ygu
Tags: 2:1.0~rc4.dfsg1+svn34540-1
* New upstream snapshot
* upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
/**
23
23
 * @file
24
24
 * Matroska file demuxer
25
 
 * by Ronald Bultje <rbultje@ronald.bitfreak.net>
26
 
 * with a little help from Moritz Bunkus <moritz@bunkus.org>
27
 
 * totally reworked by Aurelien Jacobs <aurel@gnuage.org>
28
 
 * Specs available on the Matroska project page: http://www.matroska.org/.
 
25
 * @author Ronald Bultje <rbultje@ronald.bitfreak.net>
 
26
 * @author with a little help from Moritz Bunkus <moritz@bunkus.org>
 
27
 * @author totally reworked by Aurelien Jacobs <aurel@gnuage.org>
 
28
 * @see specs available on the Matroska project page: http://www.matroska.org/
29
29
 */
30
30
 
31
31
#include <stdio.h>
38
38
#include "rm.h"
39
39
#include "matroska.h"
40
40
#include "libavcodec/mpeg4audio.h"
41
 
#include "libavutil/intfloat_readwrite.h"
 
41
#include "libavutil/intfloat.h"
42
42
#include "libavutil/intreadwrite.h"
43
43
#include "libavutil/avstring.h"
44
44
#include "libavutil/lzo.h"
244
244
    /* What to skip before effectively reading a packet. */
245
245
    int skip_to_keyframe;
246
246
    uint64_t skip_to_timecode;
 
247
 
 
248
    /* File has a CUES element, but we defer parsing until it is needed. */
 
249
    int cues_parsing_deferred;
247
250
} MatroskaDemuxContext;
248
251
 
249
252
typedef struct {
621
624
    if (size == 0) {
622
625
        *num = 0;
623
626
    } else if (size == 4) {
624
 
        *num= av_int2flt(avio_rb32(pb));
625
 
    } else if(size==8){
626
 
        *num= av_int2dbl(avio_rb64(pb));
 
627
        *num = av_int2float(avio_rb32(pb));
 
628
    } else if (size == 8){
 
629
        *num = av_int2double(avio_rb64(pb));
627
630
    } else
628
631
        return AVERROR_INVALIDDATA;
629
632
 
798
801
    uint32_t id = syntax->id;
799
802
    uint64_t length;
800
803
    int res;
 
804
    void *newelem;
801
805
 
802
806
    data = (char *)data + syntax->data_offset;
803
807
    if (syntax->list_elem_size) {
804
808
        EbmlList *list = data;
805
 
        list->elem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size);
 
809
        newelem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size);
 
810
        if (!newelem)
 
811
            return AVERROR(ENOMEM);
 
812
        list->elem = newelem;
806
813
        data = (char*)list->elem + list->nb_elem*syntax->list_elem_size;
807
814
        memset(data, 0, syntax->list_elem_size);
808
815
        list->nb_elem++;
900
907
     * Not fully fool-proof, but good enough. */
901
908
    for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) {
902
909
        int probelen = strlen(matroska_doctypes[i]);
 
910
        if (total < probelen)
 
911
            continue;
903
912
        for (n = 4+size; n <= 4+size+total-probelen; n++)
904
913
            if (!memcmp(p->buf+n, matroska_doctypes[i], probelen))
905
914
                return AVPROBE_SCORE_MAX;
930
939
    uint8_t* data = *buf;
931
940
    int isize = *buf_size;
932
941
    uint8_t* pkt_data = NULL;
 
942
    uint8_t* newpktdata;
933
943
    int pkt_size = isize;
934
944
    int result = 0;
935
945
    int olen;
959
969
        zstream.avail_in = isize;
960
970
        do {
961
971
            pkt_size *= 3;
962
 
            pkt_data = av_realloc(pkt_data, pkt_size);
 
972
            newpktdata = av_realloc(pkt_data, pkt_size);
 
973
            if (!newpktdata) {
 
974
                inflateEnd(&zstream);
 
975
                goto failed;
 
976
            }
 
977
            pkt_data = newpktdata;
963
978
            zstream.avail_out = pkt_size - zstream.total_out;
964
979
            zstream.next_out = pkt_data + zstream.total_out;
965
980
            result = inflate(&zstream, Z_NO_FLUSH);
980
995
        bzstream.avail_in = isize;
981
996
        do {
982
997
            pkt_size *= 3;
983
 
            pkt_data = av_realloc(pkt_data, pkt_size);
 
998
            newpktdata = av_realloc(pkt_data, pkt_size);
 
999
            if (!newpktdata) {
 
1000
                BZ2_bzDecompressEnd(&bzstream);
 
1001
                goto failed;
 
1002
            }
 
1003
            pkt_data = newpktdata;
984
1004
            bzstream.avail_out = pkt_size - bzstream.total_out_lo32;
985
1005
            bzstream.next_out = pkt_data + bzstream.total_out_lo32;
986
1006
            result = BZ2_bzDecompress(&bzstream);
1035
1055
    }
1036
1056
}
1037
1057
 
1038
 
static void matroska_merge_packets(AVPacket *out, AVPacket *in)
 
1058
static int matroska_merge_packets(AVPacket *out, AVPacket *in)
1039
1059
{
1040
 
    out->data = av_realloc(out->data, out->size+in->size);
 
1060
    void *newdata = av_realloc(out->data, out->size+in->size);
 
1061
    if (!newdata)
 
1062
        return AVERROR(ENOMEM);
 
1063
    out->data = newdata;
1041
1064
    memcpy(out->data+out->size, in->data, in->size);
1042
1065
    out->size += in->size;
1043
1066
    av_destruct_packet(in);
1044
1067
    av_free(in);
 
1068
    return 0;
1045
1069
}
1046
1070
 
1047
1071
static void matroska_convert_tag(AVFormatContext *s, EbmlList *list,
1110
1134
    }
1111
1135
}
1112
1136
 
1113
 
static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
 
1137
static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, int idx)
1114
1138
{
1115
1139
    EbmlList *seekhead_list = &matroska->seekhead;
1116
1140
    MatroskaSeekhead *seekhead = seekhead_list->elem;
1118
1142
    int64_t before_pos = avio_tell(matroska->ctx->pb);
1119
1143
    uint32_t saved_id = matroska->current_id;
1120
1144
    MatroskaLevel level;
1121
 
    int i;
1122
 
 
1123
 
    // we should not do any seeking in the streaming case
1124
 
    if (!matroska->ctx->pb->seekable ||
1125
 
        (matroska->ctx->flags & AVFMT_FLAG_IGNIDX))
1126
 
        return;
1127
 
 
1128
 
    for (i=0; i<seekhead_list->nb_elem; i++) {
1129
 
        int64_t offset = seekhead[i].pos + matroska->segment_start;
1130
 
 
1131
 
        if (seekhead[i].pos <= before_pos
1132
 
            || seekhead[i].id == MATROSKA_ID_SEEKHEAD
1133
 
            || seekhead[i].id == MATROSKA_ID_CLUSTER)
1134
 
            continue;
1135
 
 
1136
 
        /* seek */
1137
 
        if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) != offset)
1138
 
            continue;
1139
 
 
 
1145
    int64_t offset;
 
1146
    int ret = 0;
 
1147
 
 
1148
    if (idx >= seekhead_list->nb_elem
 
1149
            || seekhead[idx].id == MATROSKA_ID_SEEKHEAD
 
1150
            || seekhead[idx].id == MATROSKA_ID_CLUSTER)
 
1151
        return 0;
 
1152
 
 
1153
    /* seek */
 
1154
    offset = seekhead[idx].pos + matroska->segment_start;
 
1155
    if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) == offset) {
1140
1156
        /* We don't want to lose our seekhead level, so we add
1141
1157
         * a dummy. This is a crude hack. */
1142
1158
        if (matroska->num_levels == EBML_MAX_DEPTH) {
1143
1159
            av_log(matroska->ctx, AV_LOG_INFO,
1144
1160
                   "Max EBML element depth (%d) reached, "
1145
1161
                   "cannot parse further.\n", EBML_MAX_DEPTH);
1146
 
            break;
1147
 
        }
1148
 
 
1149
 
        level.start = 0;
1150
 
        level.length = (uint64_t)-1;
1151
 
        matroska->levels[matroska->num_levels] = level;
1152
 
        matroska->num_levels++;
1153
 
        matroska->current_id = 0;
1154
 
 
1155
 
        ebml_parse(matroska, matroska_segment, matroska);
1156
 
 
1157
 
        /* remove dummy level */
1158
 
        while (matroska->num_levels) {
1159
 
            uint64_t length = matroska->levels[--matroska->num_levels].length;
1160
 
            if (length == (uint64_t)-1)
1161
 
                break;
 
1162
            ret = AVERROR_INVALIDDATA;
 
1163
        } else {
 
1164
            level.start = 0;
 
1165
            level.length = (uint64_t)-1;
 
1166
            matroska->levels[matroska->num_levels] = level;
 
1167
            matroska->num_levels++;
 
1168
            matroska->current_id = 0;
 
1169
 
 
1170
            ret = ebml_parse(matroska, matroska_segment, matroska);
 
1171
 
 
1172
            /* remove dummy level */
 
1173
            while (matroska->num_levels) {
 
1174
                uint64_t length = matroska->levels[--matroska->num_levels].length;
 
1175
                if (length == (uint64_t)-1)
 
1176
                    break;
 
1177
            }
1162
1178
        }
1163
1179
    }
1164
 
 
1165
1180
    /* seek back */
1166
1181
    avio_seek(matroska->ctx->pb, before_pos, SEEK_SET);
1167
1182
    matroska->level_up = level_up;
1168
1183
    matroska->current_id = saved_id;
 
1184
 
 
1185
    return ret;
 
1186
}
 
1187
 
 
1188
static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
 
1189
{
 
1190
    EbmlList *seekhead_list = &matroska->seekhead;
 
1191
    int64_t before_pos = avio_tell(matroska->ctx->pb);
 
1192
    int i;
 
1193
 
 
1194
    // we should not do any seeking in the streaming case
 
1195
    if (!matroska->ctx->pb->seekable ||
 
1196
        (matroska->ctx->flags & AVFMT_FLAG_IGNIDX))
 
1197
        return;
 
1198
 
 
1199
    for (i = 0; i < seekhead_list->nb_elem; i++) {
 
1200
        MatroskaSeekhead *seekhead = seekhead_list->elem;
 
1201
        if (seekhead[i].pos <= before_pos)
 
1202
            continue;
 
1203
 
 
1204
        // defer cues parsing until we actually need cue data.
 
1205
        if (seekhead[i].id == MATROSKA_ID_CUES) {
 
1206
            matroska->cues_parsing_deferred = 1;
 
1207
            continue;
 
1208
        }
 
1209
 
 
1210
        if (matroska_parse_seekhead_entry(matroska, i) < 0)
 
1211
            break;
 
1212
    }
 
1213
}
 
1214
 
 
1215
static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
 
1216
    EbmlList *seekhead_list = &matroska->seekhead;
 
1217
    MatroskaSeekhead *seekhead = seekhead_list->elem;
 
1218
    EbmlList *index_list;
 
1219
    MatroskaIndex *index;
 
1220
    int index_scale = 1;
 
1221
    int i, j;
 
1222
 
 
1223
    for (i = 0; i < seekhead_list->nb_elem; i++)
 
1224
        if (seekhead[i].id == MATROSKA_ID_CUES)
 
1225
            break;
 
1226
    assert(i <= seekhead_list->nb_elem);
 
1227
 
 
1228
    matroska_parse_seekhead_entry(matroska, i);
 
1229
 
 
1230
    index_list = &matroska->index;
 
1231
    index = index_list->elem;
 
1232
    if (index_list->nb_elem
 
1233
        && index[0].time > 1E14/matroska->time_scale) {
 
1234
        av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n");
 
1235
        index_scale = matroska->time_scale;
 
1236
    }
 
1237
    for (i = 0; i < index_list->nb_elem; i++) {
 
1238
        EbmlList *pos_list = &index[i].pos;
 
1239
        MatroskaIndexPos *pos = pos_list->elem;
 
1240
        for (j = 0; j < pos_list->nb_elem; j++) {
 
1241
            MatroskaTrack *track = matroska_find_track_by_num(matroska, pos[j].track);
 
1242
            if (track && track->stream)
 
1243
                av_add_index_entry(track->stream,
 
1244
                                   pos[j].pos + matroska->segment_start,
 
1245
                                   index[i].time/index_scale, 0, 0,
 
1246
                                   AVINDEX_KEYFRAME);
 
1247
        }
 
1248
    }
1169
1249
}
1170
1250
 
1171
1251
static int matroska_aac_profile(char *codec_id)
1183
1263
{
1184
1264
    int sri;
1185
1265
 
1186
 
    for (sri=0; sri<FF_ARRAY_ELEMS(ff_mpeg4audio_sample_rates); sri++)
1187
 
        if (ff_mpeg4audio_sample_rates[sri] == samplerate)
 
1266
    for (sri=0; sri<FF_ARRAY_ELEMS(avpriv_mpeg4audio_sample_rates); sri++)
 
1267
        if (avpriv_mpeg4audio_sample_rates[sri] == samplerate)
1188
1268
            break;
1189
1269
    return sri;
1190
1270
}
1197
1277
    EbmlList *chapters_list = &matroska->chapters;
1198
1278
    MatroskaChapter *chapters;
1199
1279
    MatroskaTrack *tracks;
1200
 
    EbmlList *index_list;
1201
 
    MatroskaIndex *index;
1202
 
    int index_scale = 1;
1203
1280
    uint64_t max_start = 0;
1204
1281
    Ebml ebml = { 0 };
1205
1282
    AVStream *st;
1274
1351
        }
1275
1352
        if (encodings_list->nb_elem > 1) {
1276
1353
            av_log(matroska->ctx, AV_LOG_ERROR,
1277
 
                   "Multiple combined encodings no supported");
 
1354
                   "Multiple combined encodings not supported");
1278
1355
        } else if (encodings_list->nb_elem == 1) {
1279
1356
            if (encodings[0].type ||
1280
1357
                (encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP &&
1319
1396
            }
1320
1397
        }
1321
1398
 
1322
 
        st = track->stream = av_new_stream(s, 0);
 
1399
        st = track->stream = avformat_new_stream(s, NULL);
1323
1400
        if (st == NULL)
1324
1401
            return AVERROR(ENOMEM);
1325
1402
 
1429
1506
 
1430
1507
        if (track->time_scale < 0.01)
1431
1508
            track->time_scale = 1.0;
1432
 
        av_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
 
1509
        avpriv_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
1433
1510
 
1434
1511
        st->codec->codec_id = codec_id;
1435
1512
        st->start_time = 0;
1442
1519
        if (track->flag_forced)
1443
1520
            st->disposition |= AV_DISPOSITION_FORCED;
1444
1521
 
1445
 
        if (track->default_duration)
1446
 
            av_reduce(&st->codec->time_base.num, &st->codec->time_base.den,
1447
 
                      track->default_duration, 1000000000, 30000);
1448
 
 
1449
1522
        if (!st->codec->extradata) {
1450
1523
            if(extradata){
1451
1524
                st->codec->extradata = extradata;
1493
1566
              attachements[j].bin.data && attachements[j].bin.size > 0)) {
1494
1567
            av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");
1495
1568
        } else {
1496
 
            AVStream *st = av_new_stream(s, 0);
 
1569
            AVStream *st = avformat_new_stream(s, NULL);
1497
1570
            if (st == NULL)
1498
1571
                break;
1499
1572
            av_dict_set(&st->metadata, "filename",attachements[j].filename, 0);
 
1573
            av_dict_set(&st->metadata, "mimetype", attachements[j].mime, 0);
1500
1574
            st->codec->codec_id = CODEC_ID_NONE;
1501
1575
            st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
1502
1576
            st->codec->extradata  = av_malloc(attachements[j].bin.size);
1521
1595
        if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid
1522
1596
            && (max_start==0 || chapters[i].start > max_start)) {
1523
1597
            chapters[i].chapter =
1524
 
            ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
 
1598
            avpriv_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
1525
1599
                           chapters[i].start, chapters[i].end,
1526
1600
                           chapters[i].title);
1527
1601
            av_dict_set(&chapters[i].chapter->metadata,
1529
1603
            max_start = chapters[i].start;
1530
1604
        }
1531
1605
 
1532
 
    index_list = &matroska->index;
1533
 
    index = index_list->elem;
1534
 
    if (index_list->nb_elem
1535
 
        && index[0].time > 100000000000000/matroska->time_scale) {
1536
 
        av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n");
1537
 
        index_scale = matroska->time_scale;
1538
 
    }
1539
 
    for (i=0; i<index_list->nb_elem; i++) {
1540
 
        EbmlList *pos_list = &index[i].pos;
1541
 
        MatroskaIndexPos *pos = pos_list->elem;
1542
 
        for (j=0; j<pos_list->nb_elem; j++) {
1543
 
            MatroskaTrack *track = matroska_find_track_by_num(matroska,
1544
 
                                                              pos[j].track);
1545
 
            if (track && track->stream)
1546
 
                av_add_index_entry(track->stream,
1547
 
                                   pos[j].pos + matroska->segment_start,
1548
 
                                   index[i].time/index_scale, 0, 0,
1549
 
                                   AVINDEX_KEYFRAME);
1550
 
        }
1551
 
    }
1552
 
 
1553
1606
    matroska_convert_tags(s);
1554
1607
 
1555
1608
    return 0;
1566
1619
        memcpy(pkt, matroska->packets[0], sizeof(AVPacket));
1567
1620
        av_free(matroska->packets[0]);
1568
1621
        if (matroska->num_packets > 1) {
 
1622
            void *newpackets;
1569
1623
            memmove(&matroska->packets[0], &matroska->packets[1],
1570
1624
                    (matroska->num_packets - 1) * sizeof(AVPacket *));
1571
 
            matroska->packets =
1572
 
                av_realloc(matroska->packets, (matroska->num_packets - 1) *
1573
 
                           sizeof(AVPacket *));
 
1625
            newpackets = av_realloc(matroska->packets,
 
1626
                            (matroska->num_packets - 1) * sizeof(AVPacket *));
 
1627
            if (newpackets)
 
1628
                matroska->packets = newpackets;
1574
1629
        } else {
1575
1630
            av_freep(&matroska->packets);
1576
1631
        }
1620
1675
    size -= n;
1621
1676
 
1622
1677
    track = matroska_find_track_by_num(matroska, num);
1623
 
    if (size <= 3 || !track || !track->stream) {
 
1678
    if (!track || !track->stream) {
1624
1679
        av_log(matroska->ctx, AV_LOG_INFO,
1625
1680
               "Invalid stream %"PRIu64" or size %u\n", num, size);
1626
 
        return res;
1627
 
    }
 
1681
        return AVERROR_INVALIDDATA;
 
1682
    } else if (size <= 3)
 
1683
        return 0;
1628
1684
    st = track->stream;
1629
1685
    if (st->discard >= AVDISCARD_ALL)
1630
1686
        return res;
1724
1780
                        lace_size[n] = lace_size[n - 1] + snum;
1725
1781
                        total += lace_size[n];
1726
1782
                    }
1727
 
                    lace_size[n] = size - total;
 
1783
                    lace_size[laces - 1] = size - total;
1728
1784
                    break;
1729
1785
                }
1730
1786
            }
1860
1916
    res = ebml_parse(matroska, matroska_clusters, &cluster);
1861
1917
    blocks_list = &cluster.blocks;
1862
1918
    blocks = blocks_list->elem;
1863
 
    for (i=0; i<blocks_list->nb_elem; i++)
 
1919
    for (i=0; i<blocks_list->nb_elem && !res; i++)
1864
1920
        if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
1865
1921
            int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
1866
1922
            if (!blocks[i].non_simple)
1879
1935
static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
1880
1936
{
1881
1937
    MatroskaDemuxContext *matroska = s->priv_data;
 
1938
    int ret = 0;
1882
1939
 
1883
 
    while (matroska_deliver_packet(matroska, pkt)) {
 
1940
    while (!ret && matroska_deliver_packet(matroska, pkt)) {
1884
1941
        if (matroska->done)
1885
1942
            return AVERROR_EOF;
1886
 
        matroska_parse_cluster(matroska);
 
1943
        ret = matroska_parse_cluster(matroska);
1887
1944
    }
1888
1945
 
1889
 
    return 0;
 
1946
    return ret;
1890
1947
}
1891
1948
 
1892
1949
static int matroska_read_seek(AVFormatContext *s, int stream_index,
1897
1954
    AVStream *st = s->streams[stream_index];
1898
1955
    int i, index, index_sub, index_min;
1899
1956
 
 
1957
    /* Parse the CUES now since we need the index data to seek. */
 
1958
    if (matroska->cues_parsing_deferred) {
 
1959
        matroska_parse_cues(matroska);
 
1960
        matroska->cues_parsing_deferred = 0;
 
1961
    }
 
1962
 
1900
1963
    if (!st->nb_index_entries)
1901
1964
        return 0;
1902
1965
    timestamp = FFMAX(timestamp, st->index_entries[0].timestamp);
1903
1966
 
1904
1967
    if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
1905
1968
        avio_seek(s->pb, st->index_entries[st->nb_index_entries-1].pos, SEEK_SET);
 
1969
        matroska->current_id = 0;
1906
1970
        while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
1907
1971
            matroska_clear_queue(matroska);
1908
1972
            if (matroska_parse_cluster(matroska) < 0)
1931
1995
    }
1932
1996
 
1933
1997
    avio_seek(s->pb, st->index_entries[index_min].pos, SEEK_SET);
 
1998
    matroska->current_id = 0;
1934
1999
    matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY);
1935
2000
    matroska->skip_to_timecode = st->index_entries[index].timestamp;
1936
2001
    matroska->done = 0;
1937
 
    av_update_cur_dts(s, st, st->index_entries[index].timestamp);
 
2002
    ff_update_cur_dts(s, st, st->index_entries[index].timestamp);
1938
2003
    return 0;
1939
2004
}
1940
2005
 
1955
2020
}
1956
2021
 
1957
2022
AVInputFormat ff_matroska_demuxer = {
1958
 
    "matroska,webm",
1959
 
    NULL_IF_CONFIG_SMALL("Matroska/WebM file format"),
1960
 
    sizeof(MatroskaDemuxContext),
1961
 
    matroska_probe,
1962
 
    matroska_read_header,
1963
 
    matroska_read_packet,
1964
 
    matroska_read_close,
1965
 
    matroska_read_seek,
 
2023
    .name           = "matroska,webm",
 
2024
    .long_name      = NULL_IF_CONFIG_SMALL("Matroska/WebM file format"),
 
2025
    .priv_data_size = sizeof(MatroskaDemuxContext),
 
2026
    .read_probe     = matroska_probe,
 
2027
    .read_header    = matroska_read_header,
 
2028
    .read_packet    = matroska_read_packet,
 
2029
    .read_close     = matroska_read_close,
 
2030
    .read_seek      = matroska_read_seek,
1966
2031
};