[FFmpeg-devel,10/14] avformat/matroskadec: move the elements semantic in a separate file

Message ID 20200322085933.7532-10-robUx4@ycbcr.xyz
State New
Headers
Series [FFmpeg-devel,01/14] avformat/matroska: add missing Buttons track type |

Checks

Context Check Description
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Steve Lhomme March 22, 2020, 8:59 a.m. UTC
From: Steve Lhomme <robux4@ycbcr.xyz>

So the file can be generated from the Matroska Schema.

The EbmlSyntax structures are not shared between files.
matroska_segments and matroska_cluster_enter also have their size predefined.

No functional changes.
---
 libavformat/Makefile      |   2 +-
 libavformat/matroskadec.c | 668 +-------------------------------------
 libavformat/matroskasem.c | 384 ++++++++++++++++++++++
 libavformat/matroskasem.h | 362 +++++++++++++++++++++
 4 files changed, 748 insertions(+), 668 deletions(-)
 create mode 100644 libavformat/matroskasem.c
 create mode 100644 libavformat/matroskasem.h
  

Comments

Andreas Rheinhardt March 25, 2020, 2:09 a.m. UTC | #1
Steve Lhomme:
> From: Steve Lhomme <robux4@ycbcr.xyz>
> 
> So the file can be generated from the Matroska Schema.
> 
> The EbmlSyntax structures are not shared between files.
> matroska_segments and matroska_cluster_enter also have their size predefined.
> 
> No functional changes.
> ---
>  libavformat/Makefile      |   2 +-
>  libavformat/matroskadec.c | 668 +-------------------------------------
>  libavformat/matroskasem.c | 384 ++++++++++++++++++++++
>  libavformat/matroskasem.h | 362 +++++++++++++++++++++
>  4 files changed, 748 insertions(+), 668 deletions(-)
>  create mode 100644 libavformat/matroskasem.c
>  create mode 100644 libavformat/matroskasem.h

[...]

> diff --git a/libavformat/matroskasem.h b/libavformat/matroskasem.h
> new file mode 100644
> index 0000000000..8171982abf
> --- /dev/null
> +++ b/libavformat/matroskasem.h
> @@ -0,0 +1,362 @@
> +/*
> + * Matroska file semantic definition
> + * Copyright (c) 2003-2020 The FFmpeg project
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/**
> + * @file
> + * Matroska file demuxer
> + * @author Ronald Bultje <rbultje@ronald.bitfreak.net>
> + * @author with a little help from Moritz Bunkus <moritz@bunkus.org>
> + * @author totally reworked by Aurelien Jacobs <aurel@gnuage.org>
> + * @see specs available on the Matroska project page: http://www.matroska.org/
> + */
> +
> +#ifndef AVFORMAT_MATROSKASEM_H
> +#define AVFORMAT_MATROSKASEM_H
> +
> +#include <inttypes.h>
> +
> +#include "matroska.h"
> +#include "avformat.h"
> +#include "libavutil/frame.h"

Is it possible that you just included this for AVBufferRef (which is
defined in libavutil/buffer.h)?

- Andreas
  
Steve Lhomme March 28, 2020, 2:20 p.m. UTC | #2
On 2020-03-25 3:09, Andreas Rheinhardt wrote:
> Steve Lhomme:
>> From: Steve Lhomme <robux4@ycbcr.xyz>
>>
>> So the file can be generated from the Matroska Schema.
>>
>> The EbmlSyntax structures are not shared between files.
>> matroska_segments and matroska_cluster_enter also have their size predefined.
>>
>> No functional changes.
>> ---
>>   libavformat/Makefile      |   2 +-
>>   libavformat/matroskadec.c | 668 +-------------------------------------
>>   libavformat/matroskasem.c | 384 ++++++++++++++++++++++
>>   libavformat/matroskasem.h | 362 +++++++++++++++++++++
>>   4 files changed, 748 insertions(+), 668 deletions(-)
>>   create mode 100644 libavformat/matroskasem.c
>>   create mode 100644 libavformat/matroskasem.h
> 
> [...]
> 
>> diff --git a/libavformat/matroskasem.h b/libavformat/matroskasem.h
>> new file mode 100644
>> index 0000000000..8171982abf
>> --- /dev/null
>> +++ b/libavformat/matroskasem.h
>> @@ -0,0 +1,362 @@
>> +/*
>> + * Matroska file semantic definition
>> + * Copyright (c) 2003-2020 The FFmpeg project
>> + *
>> + * This file is part of FFmpeg.
>> + *
>> + * FFmpeg is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2.1 of the License, or (at your option) any later version.
>> + *
>> + * FFmpeg is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with FFmpeg; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + */
>> +
>> +/**
>> + * @file
>> + * Matroska file demuxer
>> + * @author Ronald Bultje <rbultje@ronald.bitfreak.net>
>> + * @author with a little help from Moritz Bunkus <moritz@bunkus.org>
>> + * @author totally reworked by Aurelien Jacobs <aurel@gnuage.org>
>> + * @see specs available on the Matroska project page: http://www.matroska.org/
>> + */
>> +
>> +#ifndef AVFORMAT_MATROSKASEM_H
>> +#define AVFORMAT_MATROSKASEM_H
>> +
>> +#include <inttypes.h>
>> +
>> +#include "matroska.h"
>> +#include "avformat.h"
>> +#include "libavutil/frame.h"
> 
> Is it possible that you just included this for AVBufferRef (which is
> defined in libavutil/buffer.h)?

Sure, I'll give it a try.
  
Andreas Rheinhardt April 8, 2020, 5:04 p.m. UTC | #3
Steve Lhomme:
> From: Steve Lhomme <robux4@ycbcr.xyz>
> 
> So the file can be generated from the Matroska Schema.
> 
> The EbmlSyntax structures are not shared between files.
> matroska_segments and matroska_cluster_enter also have their size predefined.
> 
> No functional changes.
> ---
>  libavformat/Makefile      |   2 +-
>  libavformat/matroskadec.c | 668 +-------------------------------------
>  libavformat/matroskasem.c | 384 ++++++++++++++++++++++
>  libavformat/matroskasem.h | 362 +++++++++++++++++++++
>  4 files changed, 748 insertions(+), 668 deletions(-)
>  create mode 100644 libavformat/matroskasem.c
>  create mode 100644 libavformat/matroskasem.h
> 

[...]

> diff --git a/libavformat/matroskasem.h b/libavformat/matroskasem.h
> new file mode 100644
> index 0000000000..8171982abf
> --- /dev/null
> +++ b/libavformat/matroskasem.h
> @@ -0,0 +1,362 @@
> +/*
> + * Matroska file semantic definition
> + * Copyright (c) 2003-2020 The FFmpeg project
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/**
> + * @file
> + * Matroska file demuxer
> + * @author Ronald Bultje <rbultje@ronald.bitfreak.net>
> + * @author with a little help from Moritz Bunkus <moritz@bunkus.org>
> + * @author totally reworked by Aurelien Jacobs <aurel@gnuage.org>
> + * @see specs available on the Matroska project page: http://www.matroska.org/
> + */
> +
> +#ifndef AVFORMAT_MATROSKASEM_H
> +#define AVFORMAT_MATROSKASEM_H
> +
> +#include <inttypes.h>
> +

[...]

> +// The following forward declarations need their size because
> +// a tentative definition with internal linkage must not be an
> +// incomplete type (6.7.2 in C90, 6.9.2 in C99).
> +// Removing the sizes breaks MSVC.
> +EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19],
> +                  matroska_track[27], matroska_track_encoding[6], matroska_track_encodings[2],
> +                  matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2],
> +                  matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2],
> +                  matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2],
> +                  matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8];

1. This here has confused me a lot. But first a quote from 6.9.2.2 of C99:

"A declaration of an identifier for an object that has file scope
without an initializer, and without a storage-class specifier or with
the storage-class specifier static, constitutes a tentative definition.
If a translation unit contains one or more tentative definitions for an
identifier, and the translation unit contains no external definition for
that identifier, then the behavior is exactly as if the translation unit
contains a file scope declaration of that identifier, with the composite
type as of the end of the translation unit, with an initializer equal to 0."

This applies to the above as you have not declared these EbmlSyntax
arrays as extern. So according to the standard there will be one
instance of each of these arrays in every translation unit that includes
matroskasem.h. And given that these have external linkage this means
that these objects have two definitions. So it should not work.

And yet it did (to my confusion), but it won't work any more with GCC
10. Here's why:
"A common mistake in C is omitting extern when declaring a global
variable in a header file. If the header is included by several files it
results in multiple definitions of the same variable. In previous GCC
versions this error is ignored. GCC 10 defaults to -fno-common, which
means a linker error will now be reported. To fix this, use extern in
header files when declaring global variables, and ensure each global is
defined in exactly one C file." ([1])


Besides that, there is more wrong with your approach here:
2. "If the declaration of an identifier for an object is a tentative
definition and has internal linkage, the declared type shall not be an
incomplete type." (6.9.2.3 from C99; that's what the warning that you
just copied refers to) This means that one can (and should) remove the
sizes from all the arrays declared with external linkage.
3. You did not abide by our naming conventions [2]. You'd have to use an
ff_ prefix for all those arrays with external linkage.
4. It is not necessary to export everything; syntax structures not
directly referenced by matroskadec.c should be internal to matroskasem.c.

> +
> +EbmlSyntax matroska_segments[1];
> +EbmlSyntax matroska_cluster_enter[1];

5. These sizes are wrong as they do not account for the sentinel.

> +
> +#endif /* AVFORMAT_MATROSKASEM_H */
> 

- Andreas

[1]: https://gcc.gnu.org/gcc-10/porting_to.html
[2]: https://ffmpeg.org/developer.html#Naming-conventions
  

Patch

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 8fd0d43721..09cd0d49ce 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -294,7 +294,7 @@  OBJS-$(CONFIG_LVF_DEMUXER)               += lvfdec.o
 OBJS-$(CONFIG_LXF_DEMUXER)               += lxfdec.o
 OBJS-$(CONFIG_M4V_DEMUXER)               += m4vdec.o rawdec.o
 OBJS-$(CONFIG_M4V_MUXER)                 += rawenc.o
-OBJS-$(CONFIG_MATROSKA_DEMUXER)          += matroskadec.o matroska.o  \
+OBJS-$(CONFIG_MATROSKA_DEMUXER)          += matroskadec.o matroskasem.o matroska.o \
                                             rmsipr.o flac_picture.o \
                                             oggparsevorbis.o vorbiscomment.o \
                                             flac_picture.o replaygain.o
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index b021a4cce0..8aa2cbda61 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -54,6 +54,7 @@ 
 #include "internal.h"
 #include "isom.h"
 #include "matroska.h"
+#include "matroskasem.h"
 #include "oggdec.h"
 /* For ff_codec_get_id(). */
 #include "riff.h"
@@ -80,673 +81,6 @@ 
                                          * to this many bytes of unknown data for the
                                          * SKIP_THRESHOLD check. */
 
-typedef enum {
-    EBML_NONE,
-    EBML_UINT,
-    EBML_SINT,
-    EBML_FLOAT,
-    EBML_STR,
-    EBML_UTF8,
-    EBML_BIN,
-    EBML_NEST,
-    EBML_LEVEL1,
-    EBML_STOP,
-    EBML_TYPE_COUNT
-} EbmlType;
-
-typedef const struct EbmlSyntax {
-    uint32_t id;
-    EbmlType type;
-    size_t list_elem_size;
-    size_t data_offset;
-    union {
-        int64_t     i;
-        uint64_t    u;
-        double      f;
-        const char *s;
-        const struct EbmlSyntax *n;
-    } def;
-} EbmlSyntax;
-
-typedef struct EbmlList {
-    int nb_elem;
-    unsigned int alloc_elem_size;
-    void *elem;
-} EbmlList;
-
-typedef struct EbmlBin {
-    int      size;
-    AVBufferRef *buf;
-    uint8_t *data;
-    int64_t  pos;
-} EbmlBin;
-
-typedef struct Ebml {
-    uint64_t version;
-    uint64_t max_size;
-    uint64_t id_length;
-    char    *doctype;
-    uint64_t doctype_version;
-} Ebml;
-
-typedef struct MatroskaTrackCompression {
-    uint64_t algo;
-    EbmlBin  settings;
-} MatroskaTrackCompression;
-
-typedef struct MatroskaTrackEncryption {
-    uint64_t algo;
-    EbmlBin  key_id;
-} MatroskaTrackEncryption;
-
-typedef struct MatroskaTrackEncoding {
-    uint64_t scope;
-    uint64_t type;
-    MatroskaTrackCompression compression;
-    MatroskaTrackEncryption encryption;
-} MatroskaTrackEncoding;
-
-typedef struct MatroskaMasteringMeta {
-    double r_x;
-    double r_y;
-    double g_x;
-    double g_y;
-    double b_x;
-    double b_y;
-    double white_x;
-    double white_y;
-    double max_luminance;
-    double min_luminance;
-} MatroskaMasteringMeta;
-
-typedef struct MatroskaTrackVideoColor {
-    uint64_t matrix_coefficients;
-    uint64_t bits_per_channel;
-    uint64_t chroma_sub_horz;
-    uint64_t chroma_sub_vert;
-    uint64_t cb_sub_horz;
-    uint64_t cb_sub_vert;
-    uint64_t chroma_siting_horz;
-    uint64_t chroma_siting_vert;
-    uint64_t range;
-    uint64_t transfer_characteristics;
-    uint64_t primaries;
-    uint64_t max_cll;
-    uint64_t max_fall;
-    MatroskaMasteringMeta mastering_meta;
-} MatroskaTrackVideoColor;
-
-typedef struct MatroskaTrackVideoProjection {
-    uint64_t type;
-    EbmlBin private;
-    double yaw;
-    double pitch;
-    double roll;
-} MatroskaTrackVideoProjection;
-
-typedef struct MatroskaTrackVideo {
-    double   frame_rate;
-    uint64_t display_width;
-    uint64_t display_height;
-    uint64_t pixel_width;
-    uint64_t pixel_height;
-    EbmlBin  color_space;
-    uint64_t display_unit;
-    uint64_t interlaced;
-    uint64_t field_order;
-    uint64_t stereo_mode;
-    uint64_t alpha_mode;
-    EbmlList color;
-    MatroskaTrackVideoProjection projection;
-} MatroskaTrackVideo;
-
-typedef struct MatroskaTrackAudio {
-    double   samplerate;
-    double   out_samplerate;
-    uint64_t bitdepth;
-    uint64_t channels;
-
-    /* real audio header (extracted from extradata) */
-    int      coded_framesize;
-    int      sub_packet_h;
-    int      frame_size;
-    int      sub_packet_size;
-    int      sub_packet_cnt;
-    int      pkt_cnt;
-    uint64_t buf_timecode;
-    uint8_t *buf;
-} MatroskaTrackAudio;
-
-typedef struct MatroskaTrackPlane {
-    uint64_t uid;
-    uint64_t type;
-} MatroskaTrackPlane;
-
-typedef struct MatroskaTrackOperation {
-    EbmlList combine_planes;
-} MatroskaTrackOperation;
-
-typedef struct MatroskaTrack {
-    uint64_t num;
-    uint64_t uid;
-    uint64_t type;
-    char    *name;
-    char    *codec_id;
-    EbmlBin  codec_priv;
-    char    *language;
-    double time_scale;
-    uint64_t default_duration;
-    uint64_t flag_default;
-    uint64_t flag_forced;
-    uint64_t seek_preroll;
-    MatroskaTrackVideo video;
-    MatroskaTrackAudio audio;
-    MatroskaTrackOperation operation;
-    EbmlList encodings;
-    uint64_t codec_delay;
-    uint64_t codec_delay_in_track_tb;
-
-    AVStream *stream;
-    int64_t end_timecode;
-    int ms_compat;
-    uint64_t max_block_additional_id;
-
-    uint32_t palette[AVPALETTE_COUNT];
-    int has_palette;
-} MatroskaTrack;
-
-typedef struct MatroskaAttachment {
-    uint64_t uid;
-    char *filename;
-    char *mime;
-    EbmlBin bin;
-
-    AVStream *stream;
-} MatroskaAttachment;
-
-typedef struct MatroskaChapter {
-    uint64_t start;
-    uint64_t end;
-    uint64_t uid;
-    char    *title;
-
-    AVChapter *chapter;
-} MatroskaChapter;
-
-typedef struct MatroskaIndexPos {
-    uint64_t track;
-    uint64_t pos;
-} MatroskaIndexPos;
-
-typedef struct MatroskaIndex {
-    uint64_t time;
-    EbmlList pos;
-} MatroskaIndex;
-
-typedef struct MatroskaTag {
-    char *name;
-    char *string;
-    char *lang;
-    uint64_t def;
-    EbmlList sub;
-} MatroskaTag;
-
-typedef struct MatroskaTagTarget {
-    char    *type;
-    uint64_t typevalue;
-    uint64_t trackuid;
-    uint64_t chapteruid;
-    uint64_t attachuid;
-} MatroskaTagTarget;
-
-typedef struct MatroskaTags {
-    MatroskaTagTarget target;
-    EbmlList tag;
-} MatroskaTags;
-
-typedef struct MatroskaSeekhead {
-    uint64_t id;
-    uint64_t pos;
-} MatroskaSeekhead;
-
-typedef struct MatroskaLevel {
-    uint64_t start;
-    uint64_t length;
-} MatroskaLevel;
-
-typedef struct MatroskaBlock {
-    uint64_t duration;
-    int64_t  reference;
-    uint64_t non_simple;
-    EbmlBin  bin;
-    uint64_t additional_id;
-    EbmlBin  additional;
-    int64_t  discard_padding;
-} MatroskaBlock;
-
-typedef struct MatroskaCluster {
-    MatroskaBlock block;
-    uint64_t timecode;
-    int64_t pos;
-} MatroskaCluster;
-
-typedef struct MatroskaLevel1Element {
-    int64_t  pos;
-    uint32_t id;
-    int parsed;
-} MatroskaLevel1Element;
-
-typedef struct MatroskaDemuxContext {
-    const AVClass *class;
-    AVFormatContext *ctx;
-
-    /* EBML stuff */
-    MatroskaLevel levels[EBML_MAX_DEPTH];
-    int      num_levels;
-    uint32_t current_id;
-    int64_t  resync_pos;
-    int      unknown_count;
-
-    uint64_t time_scale;
-    double   duration;
-    char    *title;
-    char    *muxingapp;
-    EbmlBin  date_utc;
-    EbmlList tracks;
-    EbmlList attachments;
-    EbmlList chapters;
-    EbmlList index;
-    EbmlList tags;
-    EbmlList seekhead;
-
-    /* byte position of the segment inside the stream */
-    int64_t segment_start;
-
-    /* the packet queue */
-    AVPacketList *queue;
-    AVPacketList *queue_end;
-
-    int done;
-
-    /* What to skip before effectively reading a packet. */
-    int skip_to_keyframe;
-    uint64_t skip_to_timecode;
-
-    /* File has a CUES element, but we defer parsing until it is needed. */
-    int cues_parsing_deferred;
-
-    /* Level1 elements and whether they were read yet */
-    MatroskaLevel1Element level1_elems[64];
-    int num_level1_elems;
-
-    MatroskaCluster current_cluster;
-
-    /* WebM DASH Manifest live flag */
-    int is_live;
-
-    /* Bandwidth value for WebM DASH Manifest */
-    int bandwidth;
-} MatroskaDemuxContext;
-
-#define CHILD_OF(parent) { .def = { .n = parent } }
-
-// The following forward declarations need their size because
-// a tentative definition with internal linkage must not be an
-// incomplete type (6.7.2 in C90, 6.9.2 in C99).
-// Removing the sizes breaks MSVC.
-static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19],
-                  matroska_track[27], matroska_track_encoding[6], matroska_track_encodings[2],
-                  matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2],
-                  matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2],
-                  matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2],
-                  matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8];
-
-static EbmlSyntax ebml_header[] = {
-    { EBML_ID_EBMLREADVERSION,    EBML_UINT, 0, offsetof(Ebml, version),         { .u = EBML_VERSION } },
-    { EBML_ID_EBMLMAXSIZELENGTH,  EBML_UINT, 0, offsetof(Ebml, max_size),        { .u = 8 } },
-    { EBML_ID_EBMLMAXIDLENGTH,    EBML_UINT, 0, offsetof(Ebml, id_length),       { .u = 4 } },
-    { EBML_ID_DOCTYPE,            EBML_STR,  0, offsetof(Ebml, doctype),         { .s = "(none)" } },
-    { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml, doctype_version), { .u = 1 } },
-    { EBML_ID_EBMLVERSION,        EBML_NONE },
-    { EBML_ID_DOCTYPEVERSION,     EBML_NONE },
-    CHILD_OF(ebml_syntax)
-};
-
-static EbmlSyntax ebml_syntax[] = {
-    { EBML_ID_HEADER,      EBML_NEST, 0, 0, { .n = ebml_header } },
-    { MATROSKA_ID_SEGMENT, EBML_STOP },
-    { 0 }
-};
-
-static EbmlSyntax matroska_info[] = {
-    { MATROSKA_ID_TIMECODESCALE, EBML_UINT,  0, offsetof(MatroskaDemuxContext, time_scale), { .u = 1000000 } },
-    { MATROSKA_ID_DURATION,      EBML_FLOAT, 0, offsetof(MatroskaDemuxContext, duration) },
-    { MATROSKA_ID_TITLE,         EBML_UTF8,  0, offsetof(MatroskaDemuxContext, title) },
-    { MATROSKA_ID_WRITINGAPP,    EBML_NONE },
-    { MATROSKA_ID_MUXINGAPP,     EBML_UTF8, 0, offsetof(MatroskaDemuxContext, muxingapp) },
-    { MATROSKA_ID_DATEUTC,       EBML_BIN,  0, offsetof(MatroskaDemuxContext, date_utc) },
-    { MATROSKA_ID_SEGMENTUID,    EBML_NONE },
-    CHILD_OF(matroska_segment)
-};
-
-static EbmlSyntax matroska_mastering_meta[] = {
-    { MATROSKA_ID_VIDEOCOLOR_RX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, r_x), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_RY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, r_y), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_GX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, g_x), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_GY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, g_y), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_BX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, b_x), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_BY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, b_y), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_WHITEX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, white_x), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_WHITEY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, white_y), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, min_luminance), { .f=-1 } },
-    { MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, max_luminance), { .f=-1 } },
-    CHILD_OF(matroska_track_video_color)
-};
-
-static EbmlSyntax matroska_track_video_color[] = {
-    { MATROSKA_ID_VIDEOCOLORMATRIXCOEFF,      EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, matrix_coefficients), { .u = AVCOL_SPC_UNSPECIFIED } },
-    { MATROSKA_ID_VIDEOCOLORBITSPERCHANNEL,   EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, bits_per_channel) },
-    { MATROSKA_ID_VIDEOCOLORCHROMASUBHORZ,    EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_horz) },
-    { MATROSKA_ID_VIDEOCOLORCHROMASUBVERT,    EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_vert) },
-    { MATROSKA_ID_VIDEOCOLORCBSUBHORZ,        EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, cb_sub_horz) },
-    { MATROSKA_ID_VIDEOCOLORCBSUBVERT,        EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, cb_sub_vert) },
-    { MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_horz), { .u = MATROSKA_COLOUR_CHROMASITINGHORZ_UNDETERMINED } },
-    { MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_vert), { .u = MATROSKA_COLOUR_CHROMASITINGVERT_UNDETERMINED } },
-    { MATROSKA_ID_VIDEOCOLORRANGE,            EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, range), { .u = AVCOL_RANGE_UNSPECIFIED } },
-    { MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, transfer_characteristics), { .u = AVCOL_TRC_UNSPECIFIED } },
-    { MATROSKA_ID_VIDEOCOLORPRIMARIES,        EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, primaries), { .u = AVCOL_PRI_UNSPECIFIED } },
-    { MATROSKA_ID_VIDEOCOLORMAXCLL,           EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_cll) },
-    { MATROSKA_ID_VIDEOCOLORMAXFALL,          EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_fall) },
-    { MATROSKA_ID_VIDEOCOLORMASTERINGMETA,    EBML_NEST, 0, offsetof(MatroskaTrackVideoColor, mastering_meta), { .n = matroska_mastering_meta } },
-    CHILD_OF(matroska_track_video)
-};
-
-static EbmlSyntax matroska_track_video_projection[] = {
-    { MATROSKA_ID_VIDEOPROJECTIONTYPE,        EBML_UINT,  0, offsetof(MatroskaTrackVideoProjection, type), { .u = MATROSKA_VIDEO_PROJECTION_TYPE_RECTANGULAR } },
-    { MATROSKA_ID_VIDEOPROJECTIONPRIVATE,     EBML_BIN,   0, offsetof(MatroskaTrackVideoProjection, private) },
-    { MATROSKA_ID_VIDEOPROJECTIONPOSEYAW,     EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, yaw), { .f=0.0 } },
-    { MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH,   EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, pitch), { .f=0.0 } },
-    { MATROSKA_ID_VIDEOPROJECTIONPOSEROLL,    EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, roll), { .f=0.0 } },
-    CHILD_OF(matroska_track_video)
-};
-
-static EbmlSyntax matroska_track_video[] = {
-    { MATROSKA_ID_VIDEOFRAMERATE,      EBML_FLOAT, 0, offsetof(MatroskaTrackVideo, frame_rate) },
-    { MATROSKA_ID_VIDEODISPLAYWIDTH,   EBML_UINT,  0, offsetof(MatroskaTrackVideo, display_width), { .u=-1 } },
-    { MATROSKA_ID_VIDEODISPLAYHEIGHT,  EBML_UINT,  0, offsetof(MatroskaTrackVideo, display_height), { .u=-1 } },
-    { MATROSKA_ID_VIDEOPIXELWIDTH,     EBML_UINT,  0, offsetof(MatroskaTrackVideo, pixel_width) },
-    { MATROSKA_ID_VIDEOPIXELHEIGHT,    EBML_UINT,  0, offsetof(MatroskaTrackVideo, pixel_height) },
-    { MATROSKA_ID_VIDEOCOLORSPACE,     EBML_BIN,   0, offsetof(MatroskaTrackVideo, color_space) },
-    { MATROSKA_ID_VIDEOALPHAMODE,      EBML_UINT,  0, offsetof(MatroskaTrackVideo, alpha_mode) },
-    { MATROSKA_ID_VIDEOCOLOR,          EBML_NEST,  sizeof(MatroskaTrackVideoColor), offsetof(MatroskaTrackVideo, color), { .n = matroska_track_video_color } },
-    { MATROSKA_ID_VIDEOPROJECTION,     EBML_NEST,  0, offsetof(MatroskaTrackVideo, projection), { .n = matroska_track_video_projection } },
-    { MATROSKA_ID_VIDEOPIXELCROPB,     EBML_NONE },
-    { MATROSKA_ID_VIDEOPIXELCROPT,     EBML_NONE },
-    { MATROSKA_ID_VIDEOPIXELCROPL,     EBML_NONE },
-    { MATROSKA_ID_VIDEOPIXELCROPR,     EBML_NONE },
-    { MATROSKA_ID_VIDEODISPLAYUNIT,    EBML_UINT,  0, offsetof(MatroskaTrackVideo, display_unit), { .u= MATROSKA_VIDEO_DISPLAYUNIT_PIXELS } },
-    { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_UINT,  0, offsetof(MatroskaTrackVideo, interlaced),  { .u = MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED } },
-    { MATROSKA_ID_VIDEOFIELDORDER,     EBML_UINT,  0, offsetof(MatroskaTrackVideo, field_order), { .u = MATROSKA_VIDEO_FIELDORDER_UNDETERMINED } },
-    { MATROSKA_ID_VIDEOSTEREOMODE,     EBML_UINT,  0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } },
-    { MATROSKA_ID_VIDEOASPECTRATIO,    EBML_NONE },
-    CHILD_OF(matroska_track)
-};
-
-static EbmlSyntax matroska_track_audio[] = {
-    { MATROSKA_ID_AUDIOSAMPLINGFREQ,    EBML_FLOAT, 0, offsetof(MatroskaTrackAudio, samplerate), { .f = 8000.0 } },
-    { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, EBML_FLOAT, 0, offsetof(MatroskaTrackAudio, out_samplerate) },
-    { MATROSKA_ID_AUDIOBITDEPTH,        EBML_UINT,  0, offsetof(MatroskaTrackAudio, bitdepth) },
-    { MATROSKA_ID_AUDIOCHANNELS,        EBML_UINT,  0, offsetof(MatroskaTrackAudio, channels),   { .u = 1 } },
-    CHILD_OF(matroska_track)
-};
-
-static EbmlSyntax matroska_track_encoding_compression[] = {
-    { MATROSKA_ID_ENCODINGCOMPALGO,     EBML_UINT, 0, offsetof(MatroskaTrackCompression, algo) },
-    { MATROSKA_ID_ENCODINGCOMPSETTINGS, EBML_BIN,  0, offsetof(MatroskaTrackCompression, settings) },
-    CHILD_OF(matroska_track_encoding)
-};
-
-static EbmlSyntax matroska_track_encoding_encryption[] = {
-    { MATROSKA_ID_ENCODINGENCALGO,        EBML_UINT, 0, offsetof(MatroskaTrackEncryption,algo) },
-    { MATROSKA_ID_ENCODINGENCKEYID,       EBML_BIN, 0, offsetof(MatroskaTrackEncryption,key_id) },
-    { MATROSKA_ID_ENCODINGENCAESSETTINGS, EBML_NONE },
-    { MATROSKA_ID_ENCODINGSIGALGO,        EBML_NONE },
-    { MATROSKA_ID_ENCODINGSIGHASHALGO,    EBML_NONE },
-    { MATROSKA_ID_ENCODINGSIGKEYID,       EBML_NONE },
-    { MATROSKA_ID_ENCODINGSIGNATURE,      EBML_NONE },
-    CHILD_OF(matroska_track_encoding)
-};
-static EbmlSyntax matroska_track_encoding[] = {
-    { MATROSKA_ID_ENCODINGSCOPE,       EBML_UINT, 0, offsetof(MatroskaTrackEncoding, scope),       { .u = 1 } },
-    { MATROSKA_ID_ENCODINGTYPE,        EBML_UINT, 0, offsetof(MatroskaTrackEncoding, type) },
-    { MATROSKA_ID_ENCODINGCOMPRESSION, EBML_NEST, 0, offsetof(MatroskaTrackEncoding, compression), { .n = matroska_track_encoding_compression } },
-    { MATROSKA_ID_ENCODINGENCRYPTION,  EBML_NEST, 0, offsetof(MatroskaTrackEncoding, encryption),  { .n = matroska_track_encoding_encryption } },
-    { MATROSKA_ID_ENCODINGORDER,       EBML_NONE },
-    CHILD_OF(matroska_track_encodings)
-};
-
-static EbmlSyntax matroska_track_encodings[] = {
-    { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack, encodings), { .n = matroska_track_encoding } },
-    CHILD_OF(matroska_track)
-};
-
-static EbmlSyntax matroska_track_plane[] = {
-    { MATROSKA_ID_TRACKPLANEUID,  EBML_UINT, 0, offsetof(MatroskaTrackPlane,uid) },
-    { MATROSKA_ID_TRACKPLANETYPE, EBML_UINT, 0, offsetof(MatroskaTrackPlane,type) },
-    CHILD_OF(matroska_track_combine_planes)
-};
-
-static EbmlSyntax matroska_track_combine_planes[] = {
-    { MATROSKA_ID_TRACKPLANE, EBML_NEST, sizeof(MatroskaTrackPlane), offsetof(MatroskaTrackOperation,combine_planes), {.n = matroska_track_plane} },
-    CHILD_OF(matroska_track_operation)
-};
-
-static EbmlSyntax matroska_track_operation[] = {
-    { MATROSKA_ID_TRACKCOMBINEPLANES, EBML_NEST, 0, 0, {.n = matroska_track_combine_planes} },
-    CHILD_OF(matroska_track)
-};
-
-static EbmlSyntax matroska_track[] = {
-    { MATROSKA_ID_TRACKNUMBER,           EBML_UINT,  0, offsetof(MatroskaTrack, num) },
-    { MATROSKA_ID_TRACKNAME,             EBML_UTF8,  0, offsetof(MatroskaTrack, name) },
-    { MATROSKA_ID_TRACKUID,              EBML_UINT,  0, offsetof(MatroskaTrack, uid) },
-    { MATROSKA_ID_TRACKTYPE,             EBML_UINT,  0, offsetof(MatroskaTrack, type) },
-    { MATROSKA_ID_CODECID,               EBML_STR,   0, offsetof(MatroskaTrack, codec_id) },
-    { MATROSKA_ID_CODECPRIVATE,          EBML_BIN,   0, offsetof(MatroskaTrack, codec_priv) },
-    { MATROSKA_ID_CODECDELAY,            EBML_UINT,  0, offsetof(MatroskaTrack, codec_delay) },
-    { MATROSKA_ID_TRACKLANGUAGE,         EBML_STR,   0, offsetof(MatroskaTrack, language),     { .s = "eng" } },
-    { MATROSKA_ID_TRACKDEFAULTDURATION,  EBML_UINT,  0, offsetof(MatroskaTrack, default_duration) },
-    { MATROSKA_ID_TRACKTIMECODESCALE,    EBML_FLOAT, 0, offsetof(MatroskaTrack, time_scale),   { .f = 1.0 } },
-    { MATROSKA_ID_TRACKFLAGDEFAULT,      EBML_UINT,  0, offsetof(MatroskaTrack, flag_default), { .u = 1 } },
-    { MATROSKA_ID_TRACKFLAGFORCED,       EBML_UINT,  0, offsetof(MatroskaTrack, flag_forced) },
-    { MATROSKA_ID_TRACKVIDEO,            EBML_NEST,  0, offsetof(MatroskaTrack, video),        { .n = matroska_track_video } },
-    { MATROSKA_ID_TRACKAUDIO,            EBML_NEST,  0, offsetof(MatroskaTrack, audio),        { .n = matroska_track_audio } },
-    { MATROSKA_ID_TRACKOPERATION,        EBML_NEST,  0, offsetof(MatroskaTrack, operation),    { .n = matroska_track_operation } },
-    { MATROSKA_ID_TRACKCONTENTENCODINGS, EBML_NEST,  0, 0,                                     { .n = matroska_track_encodings } },
-    { MATROSKA_ID_TRACKMAXBLKADDID,      EBML_UINT,  0, offsetof(MatroskaTrack, max_block_additional_id) },
-    { MATROSKA_ID_SEEKPREROLL,           EBML_UINT,  0, offsetof(MatroskaTrack, seek_preroll) },
-    { MATROSKA_ID_TRACKFLAGENABLED,      EBML_NONE },
-    { MATROSKA_ID_TRACKFLAGLACING,       EBML_NONE },
-    { MATROSKA_ID_CODECNAME,             EBML_NONE },
-    { MATROSKA_ID_CODECDECODEALL,        EBML_NONE },
-    { MATROSKA_ID_CODECINFOURL,          EBML_NONE },
-    { MATROSKA_ID_CODECDOWNLOADURL,      EBML_NONE },
-    { MATROSKA_ID_TRACKMINCACHE,         EBML_NONE },
-    { MATROSKA_ID_TRACKMAXCACHE,         EBML_NONE },
-    CHILD_OF(matroska_tracks)
-};
-
-static EbmlSyntax matroska_tracks[] = {
-    { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext, tracks), { .n = matroska_track } },
-    CHILD_OF(matroska_segment)
-};
-
-static EbmlSyntax matroska_attachment[] = {
-    { MATROSKA_ID_FILEUID,      EBML_UINT, 0, offsetof(MatroskaAttachment, uid) },
-    { MATROSKA_ID_FILENAME,     EBML_UTF8, 0, offsetof(MatroskaAttachment, filename) },
-    { MATROSKA_ID_FILEMIMETYPE, EBML_STR,  0, offsetof(MatroskaAttachment, mime) },
-    { MATROSKA_ID_FILEDATA,     EBML_BIN,  0, offsetof(MatroskaAttachment, bin) },
-    { MATROSKA_ID_FILEDESC,     EBML_NONE },
-    CHILD_OF(matroska_attachments)
-};
-
-static EbmlSyntax matroska_attachments[] = {
-    { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, sizeof(MatroskaAttachment), offsetof(MatroskaDemuxContext, attachments), { .n = matroska_attachment } },
-    CHILD_OF(matroska_segment)
-};
-
-static EbmlSyntax matroska_chapter_display[] = {
-    { MATROSKA_ID_CHAPSTRING,  EBML_UTF8, 0, offsetof(MatroskaChapter, title) },
-    { MATROSKA_ID_CHAPLANG,    EBML_NONE },
-    { MATROSKA_ID_CHAPCOUNTRY, EBML_NONE },
-    CHILD_OF(matroska_chapter_entry)
-};
-
-static EbmlSyntax matroska_chapter_entry[] = {
-    { MATROSKA_ID_CHAPTERTIMESTART,   EBML_UINT, 0, offsetof(MatroskaChapter, start), { .u = AV_NOPTS_VALUE } },
-    { MATROSKA_ID_CHAPTERTIMEEND,     EBML_UINT, 0, offsetof(MatroskaChapter, end),   { .u = AV_NOPTS_VALUE } },
-    { MATROSKA_ID_CHAPTERUID,         EBML_UINT, 0, offsetof(MatroskaChapter, uid) },
-    { MATROSKA_ID_CHAPTERDISPLAY,     EBML_NEST, 0,                        0,         { .n = matroska_chapter_display } },
-    { MATROSKA_ID_CHAPTERFLAGHIDDEN,  EBML_NONE },
-    { MATROSKA_ID_CHAPTERFLAGENABLED, EBML_NONE },
-    { MATROSKA_ID_CHAPTERPHYSEQUIV,   EBML_NONE },
-    { MATROSKA_ID_CHAPTERATOM,        EBML_NONE },
-    CHILD_OF(matroska_chapter)
-};
-
-static EbmlSyntax matroska_chapter[] = {
-    { MATROSKA_ID_CHAPTERATOM,        EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext, chapters), { .n = matroska_chapter_entry } },
-    { MATROSKA_ID_EDITIONUID,         EBML_NONE },
-    { MATROSKA_ID_EDITIONFLAGHIDDEN,  EBML_NONE },
-    { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE },
-    { MATROSKA_ID_EDITIONFLAGORDERED, EBML_NONE },
-    CHILD_OF(matroska_chapters)
-};
-
-static EbmlSyntax matroska_chapters[] = {
-    { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, { .n = matroska_chapter } },
-    CHILD_OF(matroska_segment)
-};
-
-static EbmlSyntax matroska_index_pos[] = {
-    { MATROSKA_ID_CUETRACK,           EBML_UINT, 0, offsetof(MatroskaIndexPos, track) },
-    { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, offsetof(MatroskaIndexPos, pos) },
-    { MATROSKA_ID_CUERELATIVEPOSITION,EBML_NONE },
-    { MATROSKA_ID_CUEDURATION,        EBML_NONE },
-    { MATROSKA_ID_CUEBLOCKNUMBER,     EBML_NONE },
-    CHILD_OF(matroska_index_entry)
-};
-
-static EbmlSyntax matroska_index_entry[] = {
-    { MATROSKA_ID_CUETIME,          EBML_UINT, 0,                        offsetof(MatroskaIndex, time) },
-    { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex, pos), { .n = matroska_index_pos } },
-    CHILD_OF(matroska_index)
-};
-
-static EbmlSyntax matroska_index[] = {
-    { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext, index), { .n = matroska_index_entry } },
-    CHILD_OF(matroska_segment)
-};
-
-static EbmlSyntax matroska_simpletag[] = {
-    { MATROSKA_ID_TAGNAME,        EBML_UTF8, 0,                   offsetof(MatroskaTag, name) },
-    { MATROSKA_ID_TAGSTRING,      EBML_UTF8, 0,                   offsetof(MatroskaTag, string) },
-    { MATROSKA_ID_TAGLANG,        EBML_STR,  0,                   offsetof(MatroskaTag, lang), { .s = "und" } },
-    { MATROSKA_ID_TAGDEFAULT,     EBML_UINT, 0,                   offsetof(MatroskaTag, def), { .u = 1 } },
-    { MATROSKA_ID_TAGDEFAULT_BUG, EBML_UINT, 0,                   offsetof(MatroskaTag, def), { .u = 1 } },
-    { MATROSKA_ID_SIMPLETAG,      EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag, sub),  { .n = matroska_simpletag } },
-    CHILD_OF(matroska_tag)
-};
-
-static EbmlSyntax matroska_tagtargets[] = {
-    { MATROSKA_ID_TAGTARGETS_TYPE,       EBML_STR,  0, offsetof(MatroskaTagTarget, type) },
-    { MATROSKA_ID_TAGTARGETS_TYPEVALUE,  EBML_UINT, 0, offsetof(MatroskaTagTarget, typevalue), { .u = 50 } },
-    { MATROSKA_ID_TAGTARGETS_TRACKUID,   EBML_UINT, 0, offsetof(MatroskaTagTarget, trackuid) },
-    { MATROSKA_ID_TAGTARGETS_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaTagTarget, chapteruid) },
-    { MATROSKA_ID_TAGTARGETS_ATTACHUID,  EBML_UINT, 0, offsetof(MatroskaTagTarget, attachuid) },
-    CHILD_OF(matroska_tag)
-};
-
-static EbmlSyntax matroska_tag[] = {
-    { MATROSKA_ID_SIMPLETAG,  EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTags, tag),    { .n = matroska_simpletag } },
-    { MATROSKA_ID_TAGTARGETS, EBML_NEST, 0,                   offsetof(MatroskaTags, target), { .n = matroska_tagtargets } },
-    CHILD_OF(matroska_tags)
-};
-
-static EbmlSyntax matroska_tags[] = {
-    { MATROSKA_ID_TAG, EBML_NEST, sizeof(MatroskaTags), offsetof(MatroskaDemuxContext, tags), { .n = matroska_tag } },
-    CHILD_OF(matroska_segment)
-};
-
-static EbmlSyntax matroska_seekhead_entry[] = {
-    { MATROSKA_ID_SEEKID,       EBML_UINT, 0, offsetof(MatroskaSeekhead, id) },
-    { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead, pos), { .u = -1 } },
-    CHILD_OF(matroska_seekhead)
-};
-
-static EbmlSyntax matroska_seekhead[] = {
-    { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext, seekhead), { .n = matroska_seekhead_entry } },
-    CHILD_OF(matroska_segment)
-};
-
-static EbmlSyntax matroska_segment[] = {
-    { MATROSKA_ID_CLUSTER,     EBML_STOP },
-    { MATROSKA_ID_INFO,        EBML_LEVEL1, 0, 0, { .n = matroska_info } },
-    { MATROSKA_ID_TRACKS,      EBML_LEVEL1, 0, 0, { .n = matroska_tracks } },
-    { MATROSKA_ID_ATTACHMENTS, EBML_LEVEL1, 0, 0, { .n = matroska_attachments } },
-    { MATROSKA_ID_CHAPTERS,    EBML_LEVEL1, 0, 0, { .n = matroska_chapters } },
-    { MATROSKA_ID_CUES,        EBML_LEVEL1, 0, 0, { .n = matroska_index } },
-    { MATROSKA_ID_TAGS,        EBML_LEVEL1, 0, 0, { .n = matroska_tags } },
-    { MATROSKA_ID_SEEKHEAD,    EBML_LEVEL1, 0, 0, { .n = matroska_seekhead } },
-    { 0 }   /* We don't want to go back to level 0, so don't add the parent. */
-};
-
-static EbmlSyntax matroska_segments[] = {
-    { MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, { .n = matroska_segment } },
-    { 0 }
-};
-
-static EbmlSyntax matroska_blockmore[] = {
-    { MATROSKA_ID_BLOCKADDID,      EBML_UINT, 0, offsetof(MatroskaBlock,additional_id), { .u = 1 } },
-    { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN,  0, offsetof(MatroskaBlock,additional) },
-    CHILD_OF(matroska_blockadditions)
-};
-
-static EbmlSyntax matroska_blockadditions[] = {
-    { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, {.n = matroska_blockmore} },
-    CHILD_OF(matroska_blockgroup)
-};
-
-static EbmlSyntax matroska_blockgroup[] = {
-    { MATROSKA_ID_BLOCK,          EBML_BIN,  0, offsetof(MatroskaBlock, bin) },
-    { MATROSKA_ID_BLOCKADDITIONS, EBML_NEST, 0, 0, { .n = matroska_blockadditions} },
-    { MATROSKA_ID_BLOCKDURATION,  EBML_UINT, 0, offsetof(MatroskaBlock, duration) },
-    { MATROSKA_ID_DISCARDPADDING, EBML_SINT, 0, offsetof(MatroskaBlock, discard_padding) },
-    { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference), { .i = INT64_MIN } },
-    { MATROSKA_ID_CODECSTATE,     EBML_NONE },
-    {                          1, EBML_UINT, 0, offsetof(MatroskaBlock, non_simple), { .u = 1 } },
-    CHILD_OF(matroska_cluster_parsing)
-};
-
-// The following array contains SimpleBlock and BlockGroup twice
-// in order to reuse the other values for matroska_cluster_enter.
-static EbmlSyntax matroska_cluster_parsing[] = {
-    { MATROSKA_ID_SIMPLEBLOCK,     EBML_BIN,  0, offsetof(MatroskaBlock, bin) },
-    { MATROSKA_ID_BLOCKGROUP,      EBML_NEST, 0, 0, { .n = matroska_blockgroup } },
-    { MATROSKA_ID_CLUSTERTIMECODE, EBML_UINT, 0, offsetof(MatroskaCluster, timecode) },
-    { MATROSKA_ID_SIMPLEBLOCK,     EBML_STOP },
-    { MATROSKA_ID_BLOCKGROUP,      EBML_STOP },
-    { MATROSKA_ID_CLUSTERPOSITION, EBML_NONE },
-    { MATROSKA_ID_CLUSTERPREVSIZE, EBML_NONE },
-    CHILD_OF(matroska_segment)
-};
-
-static EbmlSyntax matroska_cluster_enter[] = {
-    { MATROSKA_ID_CLUSTER,     EBML_NEST, 0, 0, { .n = &matroska_cluster_parsing[2] } },
-    { 0 }
-};
-#undef CHILD_OF
-
 static const char *const matroska_doctypes[] = { "matroska", "webm" };
 
 static int matroska_read_close(AVFormatContext *s);
diff --git a/libavformat/matroskasem.c b/libavformat/matroskasem.c
new file mode 100644
index 0000000000..ce9331e044
--- /dev/null
+++ b/libavformat/matroskasem.c
@@ -0,0 +1,384 @@ 
+/*
+ * Matroska file semantic definition
+ * Copyright (c) 2003-2020 The FFmpeg Project
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Matroska file semantic element definitions
+ * @author Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * @author with a little help from Moritz Bunkus <moritz@bunkus.org>
+ * @author totally reworked by Aurelien Jacobs <aurel@gnuage.org>
+ * @author Split from decoder by Steve Lhomme <slhomme@matroska.org>
+ * @see specs available on the Matroska project page: http://www.matroska.org/
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "matroskasem.h"
+
+#define CHILD_OF(parent) { .def = { .n = parent } }
+
+static EbmlSyntax ebml_header[] = {
+    { EBML_ID_EBMLREADVERSION,    EBML_UINT, 0, offsetof(Ebml, version),         { .u = EBML_VERSION } },
+    { EBML_ID_EBMLMAXSIZELENGTH,  EBML_UINT, 0, offsetof(Ebml, max_size),        { .u = 8 } },
+    { EBML_ID_EBMLMAXIDLENGTH,    EBML_UINT, 0, offsetof(Ebml, id_length),       { .u = 4 } },
+    { EBML_ID_DOCTYPE,            EBML_STR,  0, offsetof(Ebml, doctype),         { .s = "(none)" } },
+    { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml, doctype_version), { .u = 1 } },
+    { EBML_ID_EBMLVERSION,        EBML_NONE },
+    { EBML_ID_DOCTYPEVERSION,     EBML_NONE },
+    CHILD_OF(ebml_syntax)
+};
+
+EbmlSyntax ebml_syntax[] = {
+    { EBML_ID_HEADER,      EBML_NEST, 0, 0, { .n = ebml_header } },
+    { MATROSKA_ID_SEGMENT, EBML_STOP },
+    { 0 }
+};
+
+static EbmlSyntax matroska_info[] = {
+    { MATROSKA_ID_TIMECODESCALE, EBML_UINT,  0, offsetof(MatroskaDemuxContext, time_scale), { .u = 1000000 } },
+    { MATROSKA_ID_DURATION,      EBML_FLOAT, 0, offsetof(MatroskaDemuxContext, duration) },
+    { MATROSKA_ID_TITLE,         EBML_UTF8,  0, offsetof(MatroskaDemuxContext, title) },
+    { MATROSKA_ID_WRITINGAPP,    EBML_NONE },
+    { MATROSKA_ID_MUXINGAPP,     EBML_UTF8, 0, offsetof(MatroskaDemuxContext, muxingapp) },
+    { MATROSKA_ID_DATEUTC,       EBML_BIN,  0, offsetof(MatroskaDemuxContext, date_utc) },
+    { MATROSKA_ID_SEGMENTUID,    EBML_NONE },
+    CHILD_OF(matroska_segment)
+};
+
+static EbmlSyntax matroska_mastering_meta[] = {
+    { MATROSKA_ID_VIDEOCOLOR_RX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, r_x), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_RY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, r_y), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_GX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, g_x), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_GY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, g_y), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_BX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, b_x), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_BY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, b_y), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_WHITEX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, white_x), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_WHITEY, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, white_y), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, min_luminance), { .f=-1 } },
+    { MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX, EBML_FLOAT, 0, offsetof(MatroskaMasteringMeta, max_luminance), { .f=-1 } },
+    CHILD_OF(matroska_track_video_color)
+};
+
+EbmlSyntax matroska_track_video_color[] = {
+    { MATROSKA_ID_VIDEOCOLORMATRIXCOEFF,      EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, matrix_coefficients), { .u = AVCOL_SPC_UNSPECIFIED } },
+    { MATROSKA_ID_VIDEOCOLORBITSPERCHANNEL,   EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, bits_per_channel) },
+    { MATROSKA_ID_VIDEOCOLORCHROMASUBHORZ,    EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_horz) },
+    { MATROSKA_ID_VIDEOCOLORCHROMASUBVERT,    EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_sub_vert) },
+    { MATROSKA_ID_VIDEOCOLORCBSUBHORZ,        EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, cb_sub_horz) },
+    { MATROSKA_ID_VIDEOCOLORCBSUBVERT,        EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, cb_sub_vert) },
+    { MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_horz), { .u = MATROSKA_COLOUR_CHROMASITINGHORZ_UNDETERMINED } },
+    { MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, chroma_siting_vert), { .u = MATROSKA_COLOUR_CHROMASITINGVERT_UNDETERMINED } },
+    { MATROSKA_ID_VIDEOCOLORRANGE,            EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, range), { .u = AVCOL_RANGE_UNSPECIFIED } },
+    { MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS, EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, transfer_characteristics), { .u = AVCOL_TRC_UNSPECIFIED } },
+    { MATROSKA_ID_VIDEOCOLORPRIMARIES,        EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, primaries), { .u = AVCOL_PRI_UNSPECIFIED } },
+    { MATROSKA_ID_VIDEOCOLORMAXCLL,           EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_cll) },
+    { MATROSKA_ID_VIDEOCOLORMAXFALL,          EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_fall) },
+    { MATROSKA_ID_VIDEOCOLORMASTERINGMETA,    EBML_NEST, 0, offsetof(MatroskaTrackVideoColor, mastering_meta), { .n = matroska_mastering_meta } },
+    CHILD_OF(matroska_track_video)
+};
+
+static EbmlSyntax matroska_track_video_projection[] = {
+    { MATROSKA_ID_VIDEOPROJECTIONTYPE,        EBML_UINT,  0, offsetof(MatroskaTrackVideoProjection, type), { .u = MATROSKA_VIDEO_PROJECTION_TYPE_RECTANGULAR } },
+    { MATROSKA_ID_VIDEOPROJECTIONPRIVATE,     EBML_BIN,   0, offsetof(MatroskaTrackVideoProjection, private) },
+    { MATROSKA_ID_VIDEOPROJECTIONPOSEYAW,     EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, yaw), { .f=0.0 } },
+    { MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH,   EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, pitch), { .f=0.0 } },
+    { MATROSKA_ID_VIDEOPROJECTIONPOSEROLL,    EBML_FLOAT, 0, offsetof(MatroskaTrackVideoProjection, roll), { .f=0.0 } },
+    CHILD_OF(matroska_track_video)
+};
+
+EbmlSyntax matroska_track_video[] = {
+    { MATROSKA_ID_VIDEOFRAMERATE,      EBML_FLOAT, 0, offsetof(MatroskaTrackVideo, frame_rate) },
+    { MATROSKA_ID_VIDEODISPLAYWIDTH,   EBML_UINT,  0, offsetof(MatroskaTrackVideo, display_width), { .u=-1 } },
+    { MATROSKA_ID_VIDEODISPLAYHEIGHT,  EBML_UINT,  0, offsetof(MatroskaTrackVideo, display_height), { .u=-1 } },
+    { MATROSKA_ID_VIDEOPIXELWIDTH,     EBML_UINT,  0, offsetof(MatroskaTrackVideo, pixel_width) },
+    { MATROSKA_ID_VIDEOPIXELHEIGHT,    EBML_UINT,  0, offsetof(MatroskaTrackVideo, pixel_height) },
+    { MATROSKA_ID_VIDEOCOLORSPACE,     EBML_BIN,   0, offsetof(MatroskaTrackVideo, color_space) },
+    { MATROSKA_ID_VIDEOALPHAMODE,      EBML_UINT,  0, offsetof(MatroskaTrackVideo, alpha_mode) },
+    { MATROSKA_ID_VIDEOCOLOR,          EBML_NEST,  sizeof(MatroskaTrackVideoColor), offsetof(MatroskaTrackVideo, color), { .n = matroska_track_video_color } },
+    { MATROSKA_ID_VIDEOPROJECTION,     EBML_NEST,  0, offsetof(MatroskaTrackVideo, projection), { .n = matroska_track_video_projection } },
+    { MATROSKA_ID_VIDEOPIXELCROPB,     EBML_NONE },
+    { MATROSKA_ID_VIDEOPIXELCROPT,     EBML_NONE },
+    { MATROSKA_ID_VIDEOPIXELCROPL,     EBML_NONE },
+    { MATROSKA_ID_VIDEOPIXELCROPR,     EBML_NONE },
+    { MATROSKA_ID_VIDEODISPLAYUNIT,    EBML_UINT,  0, offsetof(MatroskaTrackVideo, display_unit), { .u= MATROSKA_VIDEO_DISPLAYUNIT_PIXELS } },
+    { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_UINT,  0, offsetof(MatroskaTrackVideo, interlaced),  { .u = MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED } },
+    { MATROSKA_ID_VIDEOFIELDORDER,     EBML_UINT,  0, offsetof(MatroskaTrackVideo, field_order), { .u = MATROSKA_VIDEO_FIELDORDER_UNDETERMINED } },
+    { MATROSKA_ID_VIDEOSTEREOMODE,     EBML_UINT,  0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } },
+    { MATROSKA_ID_VIDEOASPECTRATIO,    EBML_NONE },
+    CHILD_OF(matroska_track)
+};
+
+static EbmlSyntax matroska_track_audio[] = {
+    { MATROSKA_ID_AUDIOSAMPLINGFREQ,    EBML_FLOAT, 0, offsetof(MatroskaTrackAudio, samplerate), { .f = 8000.0 } },
+    { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, EBML_FLOAT, 0, offsetof(MatroskaTrackAudio, out_samplerate) },
+    { MATROSKA_ID_AUDIOBITDEPTH,        EBML_UINT,  0, offsetof(MatroskaTrackAudio, bitdepth) },
+    { MATROSKA_ID_AUDIOCHANNELS,        EBML_UINT,  0, offsetof(MatroskaTrackAudio, channels),   { .u = 1 } },
+    CHILD_OF(matroska_track)
+};
+
+static EbmlSyntax matroska_track_encoding_compression[] = {
+    { MATROSKA_ID_ENCODINGCOMPALGO,     EBML_UINT, 0, offsetof(MatroskaTrackCompression, algo) },
+    { MATROSKA_ID_ENCODINGCOMPSETTINGS, EBML_BIN,  0, offsetof(MatroskaTrackCompression, settings) },
+    CHILD_OF(matroska_track_encoding)
+};
+
+static EbmlSyntax matroska_track_encoding_encryption[] = {
+    { MATROSKA_ID_ENCODINGENCALGO,        EBML_UINT, 0, offsetof(MatroskaTrackEncryption,algo) },
+    { MATROSKA_ID_ENCODINGENCKEYID,       EBML_BIN, 0, offsetof(MatroskaTrackEncryption,key_id) },
+    { MATROSKA_ID_ENCODINGENCAESSETTINGS, EBML_NONE },
+    { MATROSKA_ID_ENCODINGSIGALGO,        EBML_NONE },
+    { MATROSKA_ID_ENCODINGSIGHASHALGO,    EBML_NONE },
+    { MATROSKA_ID_ENCODINGSIGKEYID,       EBML_NONE },
+    { MATROSKA_ID_ENCODINGSIGNATURE,      EBML_NONE },
+    CHILD_OF(matroska_track_encoding)
+};
+
+EbmlSyntax matroska_track_encoding[] = {
+    { MATROSKA_ID_ENCODINGSCOPE,       EBML_UINT, 0, offsetof(MatroskaTrackEncoding, scope),       { .u = 1 } },
+    { MATROSKA_ID_ENCODINGTYPE,        EBML_UINT, 0, offsetof(MatroskaTrackEncoding, type) },
+    { MATROSKA_ID_ENCODINGCOMPRESSION, EBML_NEST, 0, offsetof(MatroskaTrackEncoding, compression), { .n = matroska_track_encoding_compression } },
+    { MATROSKA_ID_ENCODINGENCRYPTION,  EBML_NEST, 0, offsetof(MatroskaTrackEncoding, encryption),  { .n = matroska_track_encoding_encryption } },
+    { MATROSKA_ID_ENCODINGORDER,       EBML_NONE },
+    CHILD_OF(matroska_track_encodings)
+};
+
+EbmlSyntax matroska_track_encodings[] = {
+    { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack, encodings), { .n = matroska_track_encoding } },
+    CHILD_OF(matroska_track)
+};
+
+EbmlSyntax matroska_track_plane[] = {
+    { MATROSKA_ID_TRACKPLANEUID,  EBML_UINT, 0, offsetof(MatroskaTrackPlane,uid) },
+    { MATROSKA_ID_TRACKPLANETYPE, EBML_UINT, 0, offsetof(MatroskaTrackPlane,type) },
+    CHILD_OF(matroska_track_combine_planes)
+};
+
+EbmlSyntax matroska_track_combine_planes[] = {
+    { MATROSKA_ID_TRACKPLANE, EBML_NEST, sizeof(MatroskaTrackPlane), offsetof(MatroskaTrackOperation,combine_planes), {.n = matroska_track_plane} },
+    CHILD_OF(matroska_track_operation)
+};
+
+EbmlSyntax matroska_track_operation[] = {
+    { MATROSKA_ID_TRACKCOMBINEPLANES, EBML_NEST, 0, 0, {.n = matroska_track_combine_planes} },
+    CHILD_OF(matroska_track)
+};
+
+EbmlSyntax matroska_track[] = {
+    { MATROSKA_ID_TRACKNUMBER,           EBML_UINT,  0, offsetof(MatroskaTrack, num) },
+    { MATROSKA_ID_TRACKNAME,             EBML_UTF8,  0, offsetof(MatroskaTrack, name) },
+    { MATROSKA_ID_TRACKUID,              EBML_UINT,  0, offsetof(MatroskaTrack, uid) },
+    { MATROSKA_ID_TRACKTYPE,             EBML_UINT,  0, offsetof(MatroskaTrack, type) },
+    { MATROSKA_ID_CODECID,               EBML_STR,   0, offsetof(MatroskaTrack, codec_id) },
+    { MATROSKA_ID_CODECPRIVATE,          EBML_BIN,   0, offsetof(MatroskaTrack, codec_priv) },
+    { MATROSKA_ID_CODECDELAY,            EBML_UINT,  0, offsetof(MatroskaTrack, codec_delay) },
+    { MATROSKA_ID_TRACKLANGUAGE,         EBML_STR,   0, offsetof(MatroskaTrack, language),     { .s = "eng" } },
+    { MATROSKA_ID_TRACKDEFAULTDURATION,  EBML_UINT,  0, offsetof(MatroskaTrack, default_duration) },
+    { MATROSKA_ID_TRACKTIMECODESCALE,    EBML_FLOAT, 0, offsetof(MatroskaTrack, time_scale),   { .f = 1.0 } },
+    { MATROSKA_ID_TRACKFLAGDEFAULT,      EBML_UINT,  0, offsetof(MatroskaTrack, flag_default), { .u = 1 } },
+    { MATROSKA_ID_TRACKFLAGFORCED,       EBML_UINT,  0, offsetof(MatroskaTrack, flag_forced) },
+    { MATROSKA_ID_TRACKVIDEO,            EBML_NEST,  0, offsetof(MatroskaTrack, video),        { .n = matroska_track_video } },
+    { MATROSKA_ID_TRACKAUDIO,            EBML_NEST,  0, offsetof(MatroskaTrack, audio),        { .n = matroska_track_audio } },
+    { MATROSKA_ID_TRACKOPERATION,        EBML_NEST,  0, offsetof(MatroskaTrack, operation),    { .n = matroska_track_operation } },
+    { MATROSKA_ID_TRACKCONTENTENCODINGS, EBML_NEST,  0, 0,                                     { .n = matroska_track_encodings } },
+    { MATROSKA_ID_TRACKMAXBLKADDID,      EBML_UINT,  0, offsetof(MatroskaTrack, max_block_additional_id) },
+    { MATROSKA_ID_SEEKPREROLL,           EBML_UINT,  0, offsetof(MatroskaTrack, seek_preroll) },
+    { MATROSKA_ID_TRACKFLAGENABLED,      EBML_NONE },
+    { MATROSKA_ID_TRACKFLAGLACING,       EBML_NONE },
+    { MATROSKA_ID_CODECNAME,             EBML_NONE },
+    { MATROSKA_ID_CODECDECODEALL,        EBML_NONE },
+    { MATROSKA_ID_CODECINFOURL,          EBML_NONE },
+    { MATROSKA_ID_CODECDOWNLOADURL,      EBML_NONE },
+    { MATROSKA_ID_TRACKMINCACHE,         EBML_NONE },
+    { MATROSKA_ID_TRACKMAXCACHE,         EBML_NONE },
+    CHILD_OF(matroska_tracks)
+};
+
+EbmlSyntax matroska_tracks[] = {
+    { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext, tracks), { .n = matroska_track } },
+    CHILD_OF(matroska_segment)
+};
+
+static EbmlSyntax matroska_attachment[] = {
+    { MATROSKA_ID_FILEUID,      EBML_UINT, 0, offsetof(MatroskaAttachment, uid) },
+    { MATROSKA_ID_FILENAME,     EBML_UTF8, 0, offsetof(MatroskaAttachment, filename) },
+    { MATROSKA_ID_FILEMIMETYPE, EBML_STR,  0, offsetof(MatroskaAttachment, mime) },
+    { MATROSKA_ID_FILEDATA,     EBML_BIN,  0, offsetof(MatroskaAttachment, bin) },
+    { MATROSKA_ID_FILEDESC,     EBML_NONE },
+    CHILD_OF(matroska_attachments)
+};
+
+EbmlSyntax matroska_attachments[] = {
+    { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, sizeof(MatroskaAttachment), offsetof(MatroskaDemuxContext, attachments), { .n = matroska_attachment } },
+    CHILD_OF(matroska_segment)
+};
+
+static EbmlSyntax matroska_chapter_display[] = {
+    { MATROSKA_ID_CHAPSTRING,  EBML_UTF8, 0, offsetof(MatroskaChapter, title) },
+    { MATROSKA_ID_CHAPLANG,    EBML_NONE },
+    { MATROSKA_ID_CHAPCOUNTRY, EBML_NONE },
+    CHILD_OF(matroska_chapter_entry)
+};
+
+EbmlSyntax matroska_chapter_entry[] = {
+    { MATROSKA_ID_CHAPTERTIMESTART,   EBML_UINT, 0, offsetof(MatroskaChapter, start), { .u = AV_NOPTS_VALUE } },
+    { MATROSKA_ID_CHAPTERTIMEEND,     EBML_UINT, 0, offsetof(MatroskaChapter, end),   { .u = AV_NOPTS_VALUE } },
+    { MATROSKA_ID_CHAPTERUID,         EBML_UINT, 0, offsetof(MatroskaChapter, uid) },
+    { MATROSKA_ID_CHAPTERDISPLAY,     EBML_NEST, 0,                        0,         { .n = matroska_chapter_display } },
+    { MATROSKA_ID_CHAPTERFLAGHIDDEN,  EBML_NONE },
+    { MATROSKA_ID_CHAPTERFLAGENABLED, EBML_NONE },
+    { MATROSKA_ID_CHAPTERPHYSEQUIV,   EBML_NONE },
+    { MATROSKA_ID_CHAPTERATOM,        EBML_NONE },
+    CHILD_OF(matroska_chapter)
+};
+
+EbmlSyntax matroska_chapter[] = {
+    { MATROSKA_ID_CHAPTERATOM,        EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext, chapters), { .n = matroska_chapter_entry } },
+    { MATROSKA_ID_EDITIONUID,         EBML_NONE },
+    { MATROSKA_ID_EDITIONFLAGHIDDEN,  EBML_NONE },
+    { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE },
+    { MATROSKA_ID_EDITIONFLAGORDERED, EBML_NONE },
+    CHILD_OF(matroska_chapters)
+};
+
+EbmlSyntax matroska_chapters[] = {
+    { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, { .n = matroska_chapter } },
+    CHILD_OF(matroska_segment)
+};
+
+static EbmlSyntax matroska_index_pos[] = {
+    { MATROSKA_ID_CUETRACK,           EBML_UINT, 0, offsetof(MatroskaIndexPos, track) },
+    { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, offsetof(MatroskaIndexPos, pos) },
+    { MATROSKA_ID_CUERELATIVEPOSITION,EBML_NONE },
+    { MATROSKA_ID_CUEDURATION,        EBML_NONE },
+    { MATROSKA_ID_CUEBLOCKNUMBER,     EBML_NONE },
+    CHILD_OF(matroska_index_entry)
+};
+
+EbmlSyntax matroska_index_entry[] = {
+    { MATROSKA_ID_CUETIME,          EBML_UINT, 0,                        offsetof(MatroskaIndex, time) },
+    { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex, pos), { .n = matroska_index_pos } },
+    CHILD_OF(matroska_index)
+};
+
+EbmlSyntax matroska_index[] = {
+    { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext, index), { .n = matroska_index_entry } },
+    CHILD_OF(matroska_segment)
+};
+
+static EbmlSyntax matroska_simpletag[] = {
+    { MATROSKA_ID_TAGNAME,        EBML_UTF8, 0,                   offsetof(MatroskaTag, name) },
+    { MATROSKA_ID_TAGSTRING,      EBML_UTF8, 0,                   offsetof(MatroskaTag, string) },
+    { MATROSKA_ID_TAGLANG,        EBML_STR,  0,                   offsetof(MatroskaTag, lang), { .s = "und" } },
+    { MATROSKA_ID_TAGDEFAULT,     EBML_UINT, 0,                   offsetof(MatroskaTag, def), { .u = 1 } },
+    { MATROSKA_ID_TAGDEFAULT_BUG, EBML_UINT, 0,                   offsetof(MatroskaTag, def), { .u = 1 } },
+    { MATROSKA_ID_SIMPLETAG,      EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag, sub),  { .n = matroska_simpletag } },
+    CHILD_OF(matroska_tag)
+};
+
+static EbmlSyntax matroska_tagtargets[] = {
+    { MATROSKA_ID_TAGTARGETS_TYPE,       EBML_STR,  0, offsetof(MatroskaTagTarget, type) },
+    { MATROSKA_ID_TAGTARGETS_TYPEVALUE,  EBML_UINT, 0, offsetof(MatroskaTagTarget, typevalue), { .u = 50 } },
+    { MATROSKA_ID_TAGTARGETS_TRACKUID,   EBML_UINT, 0, offsetof(MatroskaTagTarget, trackuid) },
+    { MATROSKA_ID_TAGTARGETS_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaTagTarget, chapteruid) },
+    { MATROSKA_ID_TAGTARGETS_ATTACHUID,  EBML_UINT, 0, offsetof(MatroskaTagTarget, attachuid) },
+    CHILD_OF(matroska_tag)
+};
+
+EbmlSyntax matroska_tag[] = {
+    { MATROSKA_ID_SIMPLETAG,  EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTags, tag),    { .n = matroska_simpletag } },
+    { MATROSKA_ID_TAGTARGETS, EBML_NEST, 0,                   offsetof(MatroskaTags, target), { .n = matroska_tagtargets } },
+    CHILD_OF(matroska_tags)
+};
+
+EbmlSyntax matroska_tags[] = {
+    { MATROSKA_ID_TAG, EBML_NEST, sizeof(MatroskaTags), offsetof(MatroskaDemuxContext, tags), { .n = matroska_tag } },
+    CHILD_OF(matroska_segment)
+};
+
+static EbmlSyntax matroska_seekhead_entry[] = {
+    { MATROSKA_ID_SEEKID,       EBML_UINT, 0, offsetof(MatroskaSeekhead, id) },
+    { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead, pos), { .u = -1 } },
+    CHILD_OF(matroska_seekhead)
+};
+
+EbmlSyntax matroska_seekhead[] = {
+    { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext, seekhead), { .n = matroska_seekhead_entry } },
+    CHILD_OF(matroska_segment)
+};
+
+EbmlSyntax matroska_segment[] = {
+    { MATROSKA_ID_CLUSTER,     EBML_STOP },
+    { MATROSKA_ID_INFO,        EBML_LEVEL1, 0, 0, { .n = matroska_info } },
+    { MATROSKA_ID_TRACKS,      EBML_LEVEL1, 0, 0, { .n = matroska_tracks } },
+    { MATROSKA_ID_ATTACHMENTS, EBML_LEVEL1, 0, 0, { .n = matroska_attachments } },
+    { MATROSKA_ID_CHAPTERS,    EBML_LEVEL1, 0, 0, { .n = matroska_chapters } },
+    { MATROSKA_ID_CUES,        EBML_LEVEL1, 0, 0, { .n = matroska_index } },
+    { MATROSKA_ID_TAGS,        EBML_LEVEL1, 0, 0, { .n = matroska_tags } },
+    { MATROSKA_ID_SEEKHEAD,    EBML_LEVEL1, 0, 0, { .n = matroska_seekhead } },
+    { 0 }   /* We don't want to go back to level 0, so don't add the parent. */
+};
+
+EbmlSyntax matroska_segments[] = {
+    { MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, { .n = matroska_segment } },
+    { 0 }
+};
+
+static EbmlSyntax matroska_blockmore[] = {
+    { MATROSKA_ID_BLOCKADDID,      EBML_UINT, 0, offsetof(MatroskaBlock,additional_id), { .u = 1 } },
+    { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN,  0, offsetof(MatroskaBlock,additional) },
+    CHILD_OF(matroska_blockadditions)
+};
+
+EbmlSyntax matroska_blockadditions[] = {
+    { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, {.n = matroska_blockmore} },
+    CHILD_OF(matroska_blockgroup)
+};
+
+EbmlSyntax matroska_blockgroup[] = {
+    { MATROSKA_ID_BLOCK,          EBML_BIN,  0, offsetof(MatroskaBlock, bin) },
+    { MATROSKA_ID_BLOCKADDITIONS, EBML_NEST, 0, 0, { .n = matroska_blockadditions} },
+    { MATROSKA_ID_BLOCKDURATION,  EBML_UINT, 0, offsetof(MatroskaBlock, duration) },
+    { MATROSKA_ID_DISCARDPADDING, EBML_SINT, 0, offsetof(MatroskaBlock, discard_padding) },
+    { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock, reference), { .i = INT64_MIN } },
+    { MATROSKA_ID_CODECSTATE,     EBML_NONE },
+    {                          1, EBML_UINT, 0, offsetof(MatroskaBlock, non_simple), { .u = 1 } },
+    CHILD_OF(matroska_cluster_parsing)
+};
+
+// The following array contains SimpleBlock and BlockGroup twice
+// in order to reuse the other values for matroska_cluster_enter.
+EbmlSyntax matroska_cluster_parsing[] = {
+    { MATROSKA_ID_SIMPLEBLOCK,     EBML_BIN,  0, offsetof(MatroskaBlock, bin) },
+    { MATROSKA_ID_BLOCKGROUP,      EBML_NEST, 0, 0, { .n = matroska_blockgroup } },
+    { MATROSKA_ID_CLUSTERTIMECODE, EBML_UINT, 0, offsetof(MatroskaCluster, timecode) },
+    { MATROSKA_ID_SIMPLEBLOCK,     EBML_STOP },
+    { MATROSKA_ID_BLOCKGROUP,      EBML_STOP },
+    { MATROSKA_ID_CLUSTERPOSITION, EBML_NONE },
+    { MATROSKA_ID_CLUSTERPREVSIZE, EBML_NONE },
+    CHILD_OF(matroska_segment)
+};
+
+EbmlSyntax matroska_cluster_enter[] = {
+    { MATROSKA_ID_CLUSTER,     EBML_NEST, 0, 0, { .n = &matroska_cluster_parsing[2] } },
+    { 0 }
+};
diff --git a/libavformat/matroskasem.h b/libavformat/matroskasem.h
new file mode 100644
index 0000000000..8171982abf
--- /dev/null
+++ b/libavformat/matroskasem.h
@@ -0,0 +1,362 @@ 
+/*
+ * Matroska file semantic definition
+ * Copyright (c) 2003-2020 The FFmpeg project
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Matroska file demuxer
+ * @author Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * @author with a little help from Moritz Bunkus <moritz@bunkus.org>
+ * @author totally reworked by Aurelien Jacobs <aurel@gnuage.org>
+ * @see specs available on the Matroska project page: http://www.matroska.org/
+ */
+
+#ifndef AVFORMAT_MATROSKASEM_H
+#define AVFORMAT_MATROSKASEM_H
+
+#include <inttypes.h>
+
+#include "matroska.h"
+#include "avformat.h"
+#include "libavutil/frame.h"
+
+typedef enum {
+    EBML_NONE,
+    EBML_UINT,
+    EBML_SINT,
+    EBML_FLOAT,
+    EBML_STR,
+    EBML_UTF8,
+    EBML_BIN,
+    EBML_NEST,
+    EBML_LEVEL1,
+    EBML_STOP,
+    EBML_TYPE_COUNT
+} EbmlType;
+
+typedef const struct EbmlSyntax {
+    uint32_t id;
+    EbmlType type;
+    size_t list_elem_size;
+    size_t data_offset;
+    union {
+        int64_t     i;
+        uint64_t    u;
+        double      f;
+        const char *s;
+        const struct EbmlSyntax *n;
+    } def;
+} EbmlSyntax;
+
+typedef struct EbmlList {
+    int nb_elem;
+    unsigned int alloc_elem_size;
+    void *elem;
+} EbmlList;
+
+typedef struct EbmlBin {
+    int      size;
+    AVBufferRef *buf;
+    uint8_t *data;
+    int64_t  pos;
+} EbmlBin;
+
+typedef struct Ebml {
+    uint64_t version;
+    uint64_t max_size;
+    uint64_t id_length;
+    char    *doctype;
+    uint64_t doctype_version;
+} Ebml;
+
+typedef struct MatroskaTrackCompression {
+    uint64_t algo;
+    EbmlBin  settings;
+} MatroskaTrackCompression;
+
+typedef struct MatroskaTrackEncryption {
+    uint64_t algo;
+    EbmlBin  key_id;
+} MatroskaTrackEncryption;
+
+typedef struct MatroskaTrackEncoding {
+    uint64_t scope;
+    uint64_t type;
+    MatroskaTrackCompression compression;
+    MatroskaTrackEncryption encryption;
+} MatroskaTrackEncoding;
+
+typedef struct MatroskaMasteringMeta {
+    double r_x;
+    double r_y;
+    double g_x;
+    double g_y;
+    double b_x;
+    double b_y;
+    double white_x;
+    double white_y;
+    double max_luminance;
+    double min_luminance;
+} MatroskaMasteringMeta;
+
+typedef struct MatroskaTrackVideoColor {
+    uint64_t matrix_coefficients;
+    uint64_t bits_per_channel;
+    uint64_t chroma_sub_horz;
+    uint64_t chroma_sub_vert;
+    uint64_t cb_sub_horz;
+    uint64_t cb_sub_vert;
+    uint64_t chroma_siting_horz;
+    uint64_t chroma_siting_vert;
+    uint64_t range;
+    uint64_t transfer_characteristics;
+    uint64_t primaries;
+    uint64_t max_cll;
+    uint64_t max_fall;
+    MatroskaMasteringMeta mastering_meta;
+} MatroskaTrackVideoColor;
+
+typedef struct MatroskaTrackVideoProjection {
+    uint64_t type;
+    EbmlBin private;
+    double yaw;
+    double pitch;
+    double roll;
+} MatroskaTrackVideoProjection;
+
+typedef struct MatroskaTrackVideo {
+    double   frame_rate;
+    uint64_t display_width;
+    uint64_t display_height;
+    uint64_t pixel_width;
+    uint64_t pixel_height;
+    EbmlBin  color_space;
+    uint64_t display_unit;
+    uint64_t interlaced;
+    uint64_t field_order;
+    uint64_t stereo_mode;
+    uint64_t alpha_mode;
+    EbmlList color;
+    MatroskaTrackVideoProjection projection;
+} MatroskaTrackVideo;
+
+typedef struct MatroskaTrackAudio {
+    double   samplerate;
+    double   out_samplerate;
+    uint64_t bitdepth;
+    uint64_t channels;
+
+    /* real audio header (extracted from extradata) */
+    int      coded_framesize;
+    int      sub_packet_h;
+    int      frame_size;
+    int      sub_packet_size;
+    int      sub_packet_cnt;
+    int      pkt_cnt;
+    uint64_t buf_timecode;
+    uint8_t *buf;
+} MatroskaTrackAudio;
+
+typedef struct MatroskaTrackPlane {
+    uint64_t uid;
+    uint64_t type;
+} MatroskaTrackPlane;
+
+typedef struct MatroskaTrackOperation {
+    EbmlList combine_planes;
+} MatroskaTrackOperation;
+
+typedef struct MatroskaTrack {
+    uint64_t num;
+    uint64_t uid;
+    uint64_t type;
+    char    *name;
+    char    *codec_id;
+    EbmlBin  codec_priv;
+    char    *language;
+    double time_scale;
+    uint64_t default_duration;
+    uint64_t flag_default;
+    uint64_t flag_forced;
+    uint64_t seek_preroll;
+    MatroskaTrackVideo video;
+    MatroskaTrackAudio audio;
+    MatroskaTrackOperation operation;
+    EbmlList encodings;
+    uint64_t codec_delay;
+    uint64_t codec_delay_in_track_tb;
+
+    AVStream *stream;
+    int64_t end_timecode;
+    int ms_compat;
+    uint64_t max_block_additional_id;
+
+    uint32_t palette[AVPALETTE_COUNT];
+    int has_palette;
+} MatroskaTrack;
+
+typedef struct MatroskaAttachment {
+    uint64_t uid;
+    char *filename;
+    char *mime;
+    EbmlBin bin;
+
+    AVStream *stream;
+} MatroskaAttachment;
+
+typedef struct MatroskaChapter {
+    uint64_t start;
+    uint64_t end;
+    uint64_t uid;
+    char    *title;
+
+    AVChapter *chapter;
+} MatroskaChapter;
+
+typedef struct MatroskaIndexPos {
+    uint64_t track;
+    uint64_t pos;
+} MatroskaIndexPos;
+
+typedef struct MatroskaIndex {
+    uint64_t time;
+    EbmlList pos;
+} MatroskaIndex;
+
+typedef struct MatroskaTag {
+    char *name;
+    char *string;
+    char *lang;
+    uint64_t def;
+    EbmlList sub;
+} MatroskaTag;
+
+typedef struct MatroskaTagTarget {
+    char    *type;
+    uint64_t typevalue;
+    uint64_t trackuid;
+    uint64_t chapteruid;
+    uint64_t attachuid;
+} MatroskaTagTarget;
+
+typedef struct MatroskaTags {
+    MatroskaTagTarget target;
+    EbmlList tag;
+} MatroskaTags;
+
+typedef struct MatroskaSeekhead {
+    uint64_t id;
+    uint64_t pos;
+} MatroskaSeekhead;
+
+typedef struct MatroskaLevel {
+    uint64_t start;
+    uint64_t length;
+} MatroskaLevel;
+
+typedef struct MatroskaBlock {
+    uint64_t duration;
+    int64_t  reference;
+    uint64_t non_simple;
+    EbmlBin  bin;
+    uint64_t additional_id;
+    EbmlBin  additional;
+    int64_t  discard_padding;
+} MatroskaBlock;
+
+typedef struct MatroskaCluster {
+    MatroskaBlock block;
+    uint64_t timecode;
+    int64_t pos;
+} MatroskaCluster;
+
+typedef struct MatroskaLevel1Element {
+    int64_t  pos;
+    uint32_t id;
+    int parsed;
+} MatroskaLevel1Element;
+
+typedef struct MatroskaDemuxContext {
+    const AVClass *class;
+    AVFormatContext *ctx;
+
+    /* EBML stuff */
+    MatroskaLevel levels[EBML_MAX_DEPTH];
+    int      num_levels;
+    uint32_t current_id;
+    int64_t  resync_pos;
+    int      unknown_count;
+
+    uint64_t time_scale;
+    double   duration;
+    char    *title;
+    char    *muxingapp;
+    EbmlBin  date_utc;
+    EbmlList tracks;
+    EbmlList attachments;
+    EbmlList chapters;
+    EbmlList index;
+    EbmlList tags;
+    EbmlList seekhead;
+
+    /* byte position of the segment inside the stream */
+    int64_t segment_start;
+
+    /* the packet queue */
+    AVPacketList *queue;
+    AVPacketList *queue_end;
+
+    int done;
+
+    /* What to skip before effectively reading a packet. */
+    int skip_to_keyframe;
+    uint64_t skip_to_timecode;
+
+    /* File has a CUES element, but we defer parsing until it is needed. */
+    int cues_parsing_deferred;
+
+    /* Level1 elements and whether they were read yet */
+    MatroskaLevel1Element level1_elems[64];
+    int num_level1_elems;
+
+    MatroskaCluster current_cluster;
+
+    /* WebM DASH Manifest live flag */
+    int is_live;
+
+    /* Bandwidth value for WebM DASH Manifest */
+    int bandwidth;
+} MatroskaDemuxContext;
+
+// The following forward declarations need their size because
+// a tentative definition with internal linkage must not be an
+// incomplete type (6.7.2 in C90, 6.9.2 in C99).
+// Removing the sizes breaks MSVC.
+EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19],
+                  matroska_track[27], matroska_track_encoding[6], matroska_track_encodings[2],
+                  matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2],
+                  matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2],
+                  matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2],
+                  matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8];
+
+EbmlSyntax matroska_segments[1];
+EbmlSyntax matroska_cluster_enter[1];
+
+#endif /* AVFORMAT_MATROSKASEM_H */