[FFmpeg-devel,22/37] avformat/matroskadec: Link to parents in syntax tables

Submitted by Andreas Rheinhardt on May 16, 2019, 10:30 p.m.

Details

Message ID 20190516223018.30827-23-andreas.rheinhardt@gmail.com
State Accepted
Commit c1abd95ad0964ff7295fa38af564f2dea1a3b314
Headers show

Commit Message

Andreas Rheinhardt May 16, 2019, 10:30 p.m.
By linking to the syntax of the parent (i.e. the containing master
element) one can check whether an element is actually part of a higher
level in the EBML hierarchy. Knowing this is important for
unknown-length levels, because they end when an element that doesn't
belong to this, but to a higher hierarchy level is encountered.

Sometimes there are different syntaxes dealing with the same elements.
In this case it is important to use a parent that contains all the
elements at the parent level; whether this is the syntax actually used
to enter the child's level is irrelevant. This affects the list of level
1 elements (which has been used as parent for matroska_cluster, too) and
it affects recursive elements (currently only the SimpleTag), where the
non-recursive parent has to be choosen.

This is in preparation for a patch that redoes level handling.

Finally, the segment id has been added to ebml_syntax. This will enable
handling of unknown-length EBML headers.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavformat/matroskadec.c | 89 ++++++++++++++++++++++-----------------
 1 file changed, 50 insertions(+), 39 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 949169d708..31c70c84d4 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -378,6 +378,15 @@  typedef struct MatroskaDemuxContext {
     int bandwidth;
 } MatroskaDemuxContext;
 
+#define CHILD_OF(parent) { .def = { .n = parent } }
+
+static const EbmlSyntax ebml_syntax[], matroska_segment[], matroska_track_video_color[], matroska_track_video[],
+                        matroska_track[], matroska_track_encoding[], matroska_track_encodings[],
+                        matroska_track_combine_planes[], matroska_track_operation[], matroska_tracks[],
+                        matroska_attachments[], matroska_chapter_entry[], matroska_chapter[], matroska_chapters[],
+                        matroska_index_entry[], matroska_index[], matroska_tag[], matroska_tags[], matroska_seekhead[],
+                        matroska_blockadditions[], matroska_blockgroup[], matroska_cluster_parsing[];
+
 static const 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 } },
@@ -386,11 +395,12 @@  static const EbmlSyntax ebml_header[] = {
     { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml, doctype_version), { .u = 1 } },
     { EBML_ID_EBMLVERSION,        EBML_NONE },
     { EBML_ID_DOCTYPEVERSION,     EBML_NONE },
-    { 0 }
+    CHILD_OF(ebml_syntax)
 };
 
 static const EbmlSyntax ebml_syntax[] = {
-    { EBML_ID_HEADER, EBML_NEST, 0, 0, { .n = ebml_header } },
+    { EBML_ID_HEADER,      EBML_NEST, 0, 0, { .n = ebml_header } },
+    { MATROSKA_ID_SEGMENT, EBML_STOP },
     { 0 }
 };
 
@@ -402,7 +412,7 @@  static const EbmlSyntax matroska_info[] = {
     { MATROSKA_ID_MUXINGAPP,     EBML_UTF8, 0, offsetof(MatroskaDemuxContext, muxingapp) },
     { MATROSKA_ID_DATEUTC,       EBML_BIN,  0, offsetof(MatroskaDemuxContext, date_utc) },
     { MATROSKA_ID_SEGMENTUID,    EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_segment)
 };
 
 static const EbmlSyntax matroska_mastering_meta[] = {
@@ -416,7 +426,7 @@  static const EbmlSyntax matroska_mastering_meta[] = {
     { 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 } },
-    { 0 }
+    CHILD_OF(matroska_track_video_color)
 };
 
 static const EbmlSyntax matroska_track_video_color[] = {
@@ -434,7 +444,7 @@  static const EbmlSyntax matroska_track_video_color[] = {
     { MATROSKA_ID_VIDEOCOLORMAXCLL,           EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_cll), { .u=0 } },
     { MATROSKA_ID_VIDEOCOLORMAXFALL,          EBML_UINT, 0, offsetof(MatroskaTrackVideoColor, max_fall), { .u=0 } },
     { MATROSKA_ID_VIDEOCOLORMASTERINGMETA,    EBML_NEST, 0, offsetof(MatroskaTrackVideoColor, mastering_meta), { .n = matroska_mastering_meta } },
-    { 0 }
+    CHILD_OF(matroska_track_video)
 };
 
 static const EbmlSyntax matroska_track_video_projection[] = {
@@ -443,7 +453,7 @@  static const EbmlSyntax matroska_track_video_projection[] = {
     { 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 } },
-    { 0 }
+    CHILD_OF(matroska_track_video)
 };
 
 static const EbmlSyntax matroska_track_video[] = {
@@ -465,7 +475,7 @@  static const EbmlSyntax matroska_track_video[] = {
     { 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 },
-    { 0 }
+    CHILD_OF(matroska_track)
 };
 
 static const EbmlSyntax matroska_track_audio[] = {
@@ -473,13 +483,13 @@  static const EbmlSyntax matroska_track_audio[] = {
     { 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 } },
-    { 0 }
+    CHILD_OF(matroska_track)
 };
 
 static const EbmlSyntax matroska_track_encoding_compression[] = {
     { MATROSKA_ID_ENCODINGCOMPALGO,     EBML_UINT, 0, offsetof(MatroskaTrackCompression, algo), { .u = 0 } },
     { MATROSKA_ID_ENCODINGCOMPSETTINGS, EBML_BIN,  0, offsetof(MatroskaTrackCompression, settings) },
-    { 0 }
+    CHILD_OF(matroska_track_encoding)
 };
 
 static const EbmlSyntax matroska_track_encoding_encryption[] = {
@@ -490,7 +500,7 @@  static const EbmlSyntax matroska_track_encoding_encryption[] = {
     { MATROSKA_ID_ENCODINGSIGHASHALGO,    EBML_NONE },
     { MATROSKA_ID_ENCODINGSIGKEYID,       EBML_NONE },
     { MATROSKA_ID_ENCODINGSIGNATURE,      EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_track_encoding)
 };
 static const EbmlSyntax matroska_track_encoding[] = {
     { MATROSKA_ID_ENCODINGSCOPE,       EBML_UINT, 0, offsetof(MatroskaTrackEncoding, scope),       { .u = 1 } },
@@ -498,28 +508,28 @@  static const EbmlSyntax matroska_track_encoding[] = {
     { 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 },
-    { 0 }
+    CHILD_OF(matroska_track_encodings)
 };
 
 static const EbmlSyntax matroska_track_encodings[] = {
     { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack, encodings), { .n = matroska_track_encoding } },
-    { 0 }
+    CHILD_OF(matroska_track)
 };
 
 static const EbmlSyntax matroska_track_plane[] = {
     { MATROSKA_ID_TRACKPLANEUID,  EBML_UINT, 0, offsetof(MatroskaTrackPlane,uid) },
     { MATROSKA_ID_TRACKPLANETYPE, EBML_UINT, 0, offsetof(MatroskaTrackPlane,type) },
-    { 0 }
+    CHILD_OF(matroska_track_combine_planes)
 };
 
 static const EbmlSyntax matroska_track_combine_planes[] = {
     { MATROSKA_ID_TRACKPLANE, EBML_NEST, sizeof(MatroskaTrackPlane), offsetof(MatroskaTrackOperation,combine_planes), {.n = matroska_track_plane} },
-    { 0 }
+    CHILD_OF(matroska_track_operation)
 };
 
 static const EbmlSyntax matroska_track_operation[] = {
     { MATROSKA_ID_TRACKCOMBINEPLANES, EBML_NEST, 0, 0, {.n = matroska_track_combine_planes} },
-    { 0 }
+    CHILD_OF(matroska_track)
 };
 
 static const EbmlSyntax matroska_track[] = {
@@ -549,12 +559,12 @@  static const EbmlSyntax matroska_track[] = {
     { MATROSKA_ID_CODECDOWNLOADURL,      EBML_NONE },
     { MATROSKA_ID_TRACKMINCACHE,         EBML_NONE },
     { MATROSKA_ID_TRACKMAXCACHE,         EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_tracks)
 };
 
 static const EbmlSyntax matroska_tracks[] = {
     { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext, tracks), { .n = matroska_track } },
-    { 0 }
+    CHILD_OF(matroska_segment)
 };
 
 static const EbmlSyntax matroska_attachment[] = {
@@ -563,19 +573,19 @@  static const EbmlSyntax matroska_attachment[] = {
     { MATROSKA_ID_FILEMIMETYPE, EBML_STR,  0, offsetof(MatroskaAttachment, mime) },
     { MATROSKA_ID_FILEDATA,     EBML_BIN,  0, offsetof(MatroskaAttachment, bin) },
     { MATROSKA_ID_FILEDESC,     EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_attachments)
 };
 
 static const EbmlSyntax matroska_attachments[] = {
     { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, sizeof(MatroskaAttachment), offsetof(MatroskaDemuxContext, attachments), { .n = matroska_attachment } },
-    { 0 }
+    CHILD_OF(matroska_segment)
 };
 
 static const EbmlSyntax matroska_chapter_display[] = {
     { MATROSKA_ID_CHAPSTRING,  EBML_UTF8, 0, offsetof(MatroskaChapter, title) },
     { MATROSKA_ID_CHAPLANG,    EBML_NONE },
     { MATROSKA_ID_CHAPCOUNTRY, EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_chapter_entry)
 };
 
 static const EbmlSyntax matroska_chapter_entry[] = {
@@ -587,7 +597,7 @@  static const EbmlSyntax matroska_chapter_entry[] = {
     { MATROSKA_ID_CHAPTERFLAGENABLED, EBML_NONE },
     { MATROSKA_ID_CHAPTERPHYSEQUIV,   EBML_NONE },
     { MATROSKA_ID_CHAPTERATOM,        EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_chapter)
 };
 
 static const EbmlSyntax matroska_chapter[] = {
@@ -596,12 +606,12 @@  static const EbmlSyntax matroska_chapter[] = {
     { MATROSKA_ID_EDITIONFLAGHIDDEN,  EBML_NONE },
     { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE },
     { MATROSKA_ID_EDITIONFLAGORDERED, EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_chapters)
 };
 
 static const EbmlSyntax matroska_chapters[] = {
     { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, { .n = matroska_chapter } },
-    { 0 }
+    CHILD_OF(matroska_segment)
 };
 
 static const EbmlSyntax matroska_index_pos[] = {
@@ -610,18 +620,18 @@  static const EbmlSyntax matroska_index_pos[] = {
     { MATROSKA_ID_CUERELATIVEPOSITION,EBML_NONE },
     { MATROSKA_ID_CUEDURATION,        EBML_NONE },
     { MATROSKA_ID_CUEBLOCKNUMBER,     EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_index_entry)
 };
 
 static const 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 } },
-    { 0 }
+    CHILD_OF(matroska_index)
 };
 
 static const EbmlSyntax matroska_index[] = {
     { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext, index), { .n = matroska_index_entry } },
-    { 0 }
+    CHILD_OF(matroska_segment)
 };
 
 static const EbmlSyntax matroska_simpletag[] = {
@@ -631,7 +641,7 @@  static const EbmlSyntax matroska_simpletag[] = {
     { MATROSKA_ID_TAGDEFAULT,     EBML_UINT, 0,                   offsetof(MatroskaTag, def) },
     { MATROSKA_ID_TAGDEFAULT_BUG, EBML_UINT, 0,                   offsetof(MatroskaTag, def) },
     { MATROSKA_ID_SIMPLETAG,      EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag, sub),  { .n = matroska_simpletag } },
-    { 0 }
+    CHILD_OF(matroska_tag)
 };
 
 static const EbmlSyntax matroska_tagtargets[] = {
@@ -640,29 +650,29 @@  static const EbmlSyntax matroska_tagtargets[] = {
     { 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) },
-    { 0 }
+    CHILD_OF(matroska_tag)
 };
 
 static const 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 } },
-    { 0 }
+    CHILD_OF(matroska_tags)
 };
 
 static const EbmlSyntax matroska_tags[] = {
     { MATROSKA_ID_TAG, EBML_NEST, sizeof(MatroskaTags), offsetof(MatroskaDemuxContext, tags), { .n = matroska_tag } },
-    { 0 }
+    CHILD_OF(matroska_segment)
 };
 
 static const EbmlSyntax matroska_seekhead_entry[] = {
     { MATROSKA_ID_SEEKID,       EBML_UINT, 0, offsetof(MatroskaSeekhead, id) },
     { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead, pos), { .u = -1 } },
-    { 0 }
+    CHILD_OF(matroska_seekhead)
 };
 
 static const EbmlSyntax matroska_seekhead[] = {
     { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext, seekhead), { .n = matroska_seekhead_entry } },
-    { 0 }
+    CHILD_OF(matroska_segment)
 };
 
 static const EbmlSyntax matroska_segment[] = {
@@ -674,7 +684,7 @@  static const EbmlSyntax matroska_segment[] = {
     { MATROSKA_ID_TAGS,        EBML_LEVEL1, 0, 0, { .n = matroska_tags } },
     { MATROSKA_ID_SEEKHEAD,    EBML_LEVEL1, 0, 0, { .n = matroska_seekhead } },
     { MATROSKA_ID_CLUSTER,     EBML_STOP },
-    { 0 }
+    { 0 }   /* We don't want to go back to level 0, so don't add the parent. */
 };
 
 static const EbmlSyntax matroska_segments[] = {
@@ -685,12 +695,12 @@  static const EbmlSyntax matroska_segments[] = {
 static const EbmlSyntax matroska_blockmore[] = {
     { MATROSKA_ID_BLOCKADDID,      EBML_UINT, 0, offsetof(MatroskaBlock,additional_id) },
     { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN,  0, offsetof(MatroskaBlock,additional) },
-    { 0 }
+    CHILD_OF(matroska_blockadditions)
 };
 
 static const EbmlSyntax matroska_blockadditions[] = {
     { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, {.n = matroska_blockmore} },
-    { 0 }
+    CHILD_OF(matroska_blockgroup)
 };
 
 static const EbmlSyntax matroska_blockgroup[] = {
@@ -701,7 +711,7 @@  static const EbmlSyntax matroska_blockgroup[] = {
     { 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 } },
-    { 0 }
+    CHILD_OF(matroska_cluster_parsing)
 };
 
 static const EbmlSyntax matroska_cluster_parsing[] = {
@@ -715,7 +725,7 @@  static const EbmlSyntax matroska_cluster_parsing[] = {
     { MATROSKA_ID_TAGS,            EBML_NONE },
     { MATROSKA_ID_SEEKHEAD,        EBML_NONE },
     { MATROSKA_ID_CLUSTER,         EBML_STOP },
-    { 0 }
+    { 0 } /* We don't want to go back to level 0, so don't add the parent. */
 };
 
 static const EbmlSyntax matroska_cluster[] = {
@@ -724,7 +734,7 @@  static const EbmlSyntax matroska_cluster[] = {
     { MATROSKA_ID_SIMPLEBLOCK,     EBML_STOP },
     { MATROSKA_ID_CLUSTERPOSITION, EBML_NONE },
     { MATROSKA_ID_CLUSTERPREVSIZE, EBML_NONE },
-    { 0 }
+    CHILD_OF(matroska_segment)
 };
 
 static const EbmlSyntax matroska_clusters[] = {
@@ -733,8 +743,9 @@  static const EbmlSyntax matroska_clusters[] = {
     { MATROSKA_ID_CUES,     EBML_NONE },
     { MATROSKA_ID_TAGS,     EBML_NONE },
     { MATROSKA_ID_SEEKHEAD, EBML_NONE },
-    { 0 }
+    { 0 } /* We don't want to go back to level 0, so don't add the parent. */
 };
+#undef CHILD_OF
 
 static const char *const matroska_doctypes[] = { "matroska", "webm" };