[FFmpeg-devel,RFC] avformat/mxfdec: provide some mxf DigitalVideoAndImageCompressionParameters as metadata

Submitted by Marton Balint on March 9, 2018, 9:34 p.m.

Details

Message ID 20180309213452.24489-1-cus@passwd.hu
State New
Headers show

Commit Message

Marton Balint March 9, 2018, 9:34 p.m.
Would this be useful for anybody?

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavformat/mxf.c                               |  5 ++
 libavformat/mxf.h                               |  7 +++
 libavformat/mxfdec.c                            | 36 +++++++++++
 libavformat/mxfsymbols.c                        | 83 +++++++++++++++++++++++++
 tests/ref/fate/concat-demuxer-extended-lavf-mxf |  2 +-
 tests/ref/fate/concat-demuxer-simple1-lavf-mxf  |  2 +-
 tools/gen-mxfsymbols.c.xslt                     | 58 +++++++++++++++++
 7 files changed, 191 insertions(+), 2 deletions(-)
 create mode 100644 libavformat/mxfsymbols.c
 create mode 100644 tools/gen-mxfsymbols.c.xslt

Comments

Tomas Härdin March 13, 2018, 3:33 p.m.
fre 2018-03-09 klockan 22:34 +0100 skrev Marton Balint:
> Would this be useful for anybody?

I've never even run into this before, so I can't really say. Maybe?

/Tomas

Patch hide | download patch | download mbox

diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index a909401f08..1e2a4b5a9a 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -22,6 +22,11 @@ 
 #include "libavutil/common.h"
 #include "mxf.h"
 
+/* Generated symbol table for metadata array */
+#include "mxfsymbols.c"
+
+const int ff_mxf_nb_element_symbols = FF_ARRAY_ELEMS(ff_mxf_element_symbols);
+
 /**
  * SMPTE RP224 http://www.smpte-ra.org/mdd/index.html
  */
diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index ffcc429a8b..3d4d0ef731 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -75,10 +75,17 @@  typedef struct {
     int samples_per_frame[6];
 } MXFSamplesPerFrame;
 
+typedef struct MXFElementSymbol {
+    UID uid;
+    const char *name;
+} MXFElementSymbol;
+
 extern const MXFCodecUL ff_mxf_data_definition_uls[];
 extern const MXFCodecUL ff_mxf_codec_uls[];
 extern const MXFCodecUL ff_mxf_pixel_format_uls[];
 extern const MXFCodecUL ff_mxf_codec_tag_uls[];
+extern const MXFElementSymbol ff_mxf_element_symbols[];
+extern const int ff_mxf_nb_element_symbols;
 
 int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt);
 const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base);
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 7a42555562..aee984770d 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -195,6 +195,7 @@  typedef struct MXFDescriptor {
     uint8_t *extradata;
     int extradata_size;
     enum AVPixelFormat pix_fmt;
+    AVDictionary *dict;
 } MXFDescriptor;
 
 typedef struct MXFIndexTableSegment {
@@ -325,6 +326,7 @@  static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
     switch ((*ctx)->type) {
     case Descriptor:
         av_freep(&((MXFDescriptor *)*ctx)->extradata);
+        av_dict_free(&((MXFDescriptor *)*ctx)->dict);
         break;
     case MultipleDescriptor:
         av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs);
@@ -1025,6 +1027,8 @@  static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int
     return 0;
 }
 
+static int mxf_uid_to_str(UID uid, char **str);
+
 static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor)
 {
     int code, value, ofs = 0;
@@ -1144,6 +1148,36 @@  static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
                 rsiz == FF_PROFILE_JPEG2000_DCINEMA_4K)
                 descriptor->pix_fmt = AV_PIX_FMT_XYZ12;
         }
+        {
+            int i;
+            for (i = 0; i < ff_mxf_nb_element_symbols; i++) {
+                if (IS_KLV_KEY(uid, ff_mxf_element_symbols[i].uid)) {
+                    uint64_t val = 0;
+                    char *s;
+                    switch (size) {
+                    case 1:
+                        val = avio_r8(pb);
+                        break;
+                    case 2:
+                        val = avio_rb16(pb);
+                        break;
+                    case 4:
+                        val = avio_rb32(pb);
+                        break;
+                    case 8:
+                        val = avio_rb64(pb);
+                        break;
+                    default:
+                        continue;
+                    }
+                    s = av_asprintf("%"PRIu64, val);
+                    if (!s)
+                        return AVERROR(ENOMEM);
+                    av_dict_set(&descriptor->dict, ff_mxf_element_symbols[i].name, s, AV_DICT_DONT_STRDUP_VAL);
+                    break;
+                }
+            }
+        }
         break;
     }
     return 0;
@@ -2202,6 +2236,8 @@  static int mxf_parse_structural_metadata(MXFContext *mxf)
         if (material_track->name && material_track->name[0])
             av_dict_set(&st->metadata, "track_name", material_track->name, 0);
 
+        av_dict_copy(&st->metadata, descriptor->dict, 0);
+
         mxf_parse_physical_source_package(mxf, source_track, st);
 
         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
diff --git a/libavformat/mxfsymbols.c b/libavformat/mxfsymbols.c
new file mode 100644
index 0000000000..18f5d514eb
--- /dev/null
+++ b/libavformat/mxfsymbols.c
@@ -0,0 +1,83 @@ 
+/*
+ * This file contains the element and symbol name list of various
+ * DigitalVideoAndImageCompressionParameters and is generated with
+ * tools/gen-mxfsymbols.c.xslt from
+ * https://registry.smpte-ra.org/view/published/Elements.xml
+ *
+ * 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
+ */
+const MXFElementSymbol ff_mxf_element_symbols[] = {
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x02,0x00,0x00}, "SingleSequence"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x03,0x00,0x00}, "ConstantBPictureCount"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x05,0x00,0x00}, "LowDelay"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x06,0x00,0x00}, "ClosedGOP"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x07,0x00,0x00}, "IdenticalGOP"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x08,0x00,0x00}, "MaxGOP"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x09,0x00,0x00}, "MaxBPictureCount"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0a,0x00,0x00}, "ProfileAndLevel"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0b,0x00,0x00}, "BitRate"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x02,0x00,0x00}, "MPEG4VisualSingleSequence"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x03,0x00,0x00}, "MPEG4VisualConstantBVOPs"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x05,0x00,0x00}, "MPEG4VisualLowDelay"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x06,0x00,0x00}, "MPEG4VisualClosedGOV"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x07,0x00,0x00}, "MPEG4VisualIdenticalGOV"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x08,0x00,0x00}, "MPEG4VisualMaxGOV"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x09,0x00,0x00}, "MPEG4VisualBVOPCount"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x0a,0x00,0x00}, "MPEG4VisualProfileAndLevel"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x02,0x02,0x0b,0x00,0x00}, "MPEG4VisualBitRate"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x01,0x00,0x00,0x00}, "Rsiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x02,0x00,0x00,0x00}, "Xsiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x03,0x00,0x00,0x00}, "Ysiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x04,0x00,0x00,0x00}, "XOsiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x05,0x00,0x00,0x00}, "YOsiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x06,0x00,0x00,0x00}, "XTsiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x07,0x00,0x00,0x00}, "YTsiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x08,0x00,0x00,0x00}, "XTOsiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x09,0x00,0x00,0x00}, "YTOsiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x0a,0x00,0x00,0x00}, "Csiz"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0c,0x04,0x01,0x06,0x04,0x02,0x00,0x00,0x00}, "VC1SingleSequence"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0c,0x04,0x01,0x06,0x04,0x04,0x00,0x00,0x00}, "VC1IdenticalGOP"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0c,0x04,0x01,0x06,0x04,0x05,0x00,0x00,0x00}, "VC1MaxGOP"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0c,0x04,0x01,0x06,0x04,0x06,0x00,0x00,0x00}, "VC1BPictureCount"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0c,0x04,0x01,0x06,0x04,0x07,0x00,0x00,0x00}, "VC1AverageBitRate"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0c,0x04,0x01,0x06,0x04,0x08,0x00,0x00,0x00}, "VC1MaximumBitRate"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0c,0x04,0x01,0x06,0x04,0x09,0x00,0x00,0x00}, "VC1Profile"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0c,0x04,0x01,0x06,0x04,0x0a,0x00,0x00,0x00}, "VC1Level"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x05,0x05,0x00,0x00,0x00}, "TIFFOrientation"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x05,0x06,0x00,0x00,0x00}, "TIFFSamplesPerPixel"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x04,0x01,0x06,0x05,0x07,0x00,0x00,0x00}, "TIFFLightSourceKind"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x03,0x00,0x00}, "AVCConstantBPictureFlag"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x06,0x00,0x00}, "AVCClosedGOPIndicator"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x07,0x00,0x00}, "AVCIdenticalGOPIndicator"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x08,0x00,0x00}, "AVCMaximumGOPSize"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x09,0x00,0x00}, "AVCMaximumBPictureCount"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x0a,0x00,0x00}, "AVCProfile"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x0b,0x00,0x00}, "AVCMaximumBitRate"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x0c,0x00,0x00}, "AVCProfileConstraint"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x0d,0x00,0x00}, "AVCLevel"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x0e,0x00,0x00}, "AVCDecodingDelay"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x0f,0x00,0x00}, "AVCMaximumRefFrames"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x10,0x00,0x00}, "AVCSequenceParameterSetFlag"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x11,0x00,0x00}, "AVCPictureParameterSetFlag"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x06,0x01,0x14,0x00,0x00}, "AVCAverageBitRate"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x07,0x01,0x00,0x00,0x00}, "VC2MajorVersion"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x07,0x02,0x00,0x00,0x00}, "VC2MinorVersion"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x07,0x03,0x00,0x00,0x00}, "VC2Profile"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x07,0x04,0x00,0x00,0x00}, "VC2Level"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x07,0x06,0x00,0x00,0x00}, "VC2SequenceHeadersIdentical"},
+    {{0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x07,0x07,0x00,0x00,0x00}, "VC2EditUnitsAreCompleteSequences"},
+};
diff --git a/tests/ref/fate/concat-demuxer-extended-lavf-mxf b/tests/ref/fate/concat-demuxer-extended-lavf-mxf
index c47f14faa1..20cc704ea1 100644
--- a/tests/ref/fate/concat-demuxer-extended-lavf-mxf
+++ b/tests/ref/fate/concat-demuxer-extended-lavf-mxf
@@ -1 +1 @@ 
-7e53f4c5cb0c9afda2771c9f0c697d9c *tests/data/fate/concat-demuxer-extended-lavf-mxf.ffprobe
+873211962cac57261708ec4f861c8c5c *tests/data/fate/concat-demuxer-extended-lavf-mxf.ffprobe
diff --git a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf
index 1174a1e183..fd88494033 100644
--- a/tests/ref/fate/concat-demuxer-simple1-lavf-mxf
+++ b/tests/ref/fate/concat-demuxer-simple1-lavf-mxf
@@ -120,5 +120,5 @@  audio|1|65280|1.360000|65280|1.360000|1920|0.040000|N/A|N/A|3840|206848|K_|1
 Strings Metadata
 video|0|37|1.480000|34|1.360000|1|0.040000|N/A|N/A|24786|211456|K_|1
 Strings Metadata
-0|mpeg2video|4|video|1/25|[0][0][0][0]|0x0000|352|288|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|N/A|1|N/A|25/1|25/1|1/25|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|51|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001
+0|mpeg2video|4|video|1/25|[0][0][0][0]|0x0000|352|288|0|0|1|1:1|11:9|yuv420p|8|tv|unknown|unknown|unknown|left|progressive|N/A|1|N/A|25/1|25/1|1/25|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|N/A|51|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001|200000|72
 1|pcm_s16le|unknown|audio|1/48000|[0][0][0][0]|0x0000|s16|48000|1|unknown|16|N/A|0/0|0/0|1/48000|0|0.000000|N/A|N/A|768000|N/A|N/A|N/A|N/A|50|0|0|0|0|0|0|0|0|0|0|0|0|0x060A2B340101010501010D001300000000000000000000000000000000000001
diff --git a/tools/gen-mxfsymbols.c.xslt b/tools/gen-mxfsymbols.c.xslt
new file mode 100644
index 0000000000..b5c3e9c0aa
--- /dev/null
+++ b/tools/gen-mxfsymbols.c.xslt
@@ -0,0 +1,58 @@ 
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:mxf="http://www.smpte-ra.org/schemas/335/2012" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="text" />
+
+<xsl:template match="/">/*
+ * This file contains the element and symbol name list of various
+ * DigitalVideoAndImageCompressionParameters and is generated with
+ * tools/gen-mxfsymbols.c.xslt from
+ * https://registry.smpte-ra.org/view/published/Elements.xml
+ *
+ * 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
+ */
+const MXFElementSymbol ff_mxf_element_symbols[] = {
+<xsl:for-each select="mxf:ElementsRegister/mxf:Entries/mxf:Entry[mxf:Kind='LEAF' and
+       starts-with(mxf:UL, 'urn:smpte:ul:060e2b34.010101') and substring(mxf:UL, 32, 6) = '040106' and (
+       mxf:Type='urn:smpte:ul:060e2b34.01040101.01040100.00000000' or
+       mxf:Type='urn:smpte:ul:060e2b34.01040101.01010100.00000000' or
+       mxf:Type='urn:smpte:ul:060e2b34.01040101.01010200.00000000' or
+       mxf:Type='urn:smpte:ul:060e2b34.01040101.01010300.00000000' or
+       mxf:Type='urn:smpte:ul:060e2b34.01040101.01010400.00000000' or
+       false)]"><!--
+-->    {<xsl:apply-templates select="mxf:UL"/>, "<xsl:value-of select="mxf:Symbol" disable-output-escaping="yes"/>"},
+</xsl:for-each>};
+</xsl:template>
+
+<xsl:template match="mxf:UL">{<!--
+    -->0x<xsl:value-of select="substring(node(), 14, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 16, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 18, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 20, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 23, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 25, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 27, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 29, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 32, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 34, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 36, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 38, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 41, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 43, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 45, 2)" />,<!--
+    -->0x<xsl:value-of select="substring(node(), 47, 2)" /><!--
+-->}</xsl:template>
+</xsl:stylesheet>