Add some details about verification to the manual.
authorCarl Hetherington <cth@carlh.net>
Tue, 5 Oct 2021 23:16:28 +0000 (01:16 +0200)
committerCarl Hetherington <cth@carlh.net>
Tue, 5 Oct 2021 23:16:35 +0000 (01:16 +0200)
doc/manual/.gitignore
doc/manual/Makefile
doc/manual/dcpomatic.xml
doc/manual/verifier.py [new file with mode: 0644]

index 3fa250264d7e50217f3dd3e7415ac8838a4d37fc..bc9331596f7d37e8cf35b58bab3d307f3edb98c2 100644 (file)
@@ -1 +1,4 @@
 screenshots/*.pdf
+verify_bv21_errors.xml
+verify_errors.xml
+verify_warnings.xml
index d57dd26307f8f2a657eae9d383abc7d707b622c1..d08dffe51ceb2e9ff07bbf23f81764902fe3cdd4 100644 (file)
@@ -1,6 +1,7 @@
 # DCP-o-matic manual makefile
 
 INKSCAPE = ~/Applications/inkscape
+LIBDCP = ~/src/libdcp
 
 
 all:   html pdf
@@ -104,11 +105,24 @@ SHORTCUTS :=      ../../src/tools/dcpomatic.cc
 shortcuts.xml: $(SHORTCUTS) shortcuts.py
        python3 shortcuts.py $(SHORTCUTS) > $@
 
+LIBDCP_DEPS = $(LIBDCP)/src/verify_j2k.cc $(LIBDCP)/src/dcp.cc $(LIBDCP)/src/verify.cc
+
+verify_errors.xml:     verifier.py $(LIBDCP_DEPS)
+       python3 verifier.py $(LIBDCP) ERROR > $@
+
+verify_bv21_errors.xml:        verifier.py $(LIBDCP_DEPS)
+       python3 verifier.py $(LIBDCP) BV21_ERROR > $@
+
+verify_warnings.xml:   verifier.py $(LIBDCP_DEPS)
+       python3 verifier.py $(LIBDCP) WARNING > $@
+
+
 #
 # HTML
 #
 
-html:  $(XML) config.xml shortcuts.xml dcpomatic-html.xsl extensions-html.ent dcpomatic.css dcpomatic_create.xml dcpomatic_cli.xml dcpomatic_kdm_cli.xml \
+html:  $(XML) config.xml shortcuts.xml verify_errors.xml verify_bv21_errors.xml verify_warnings.xml \
+       dcpomatic-html.xsl extensions-html.ent dcpomatic.css dcpomatic_create.xml dcpomatic_cli.xml dcpomatic_kdm_cli.xml \
        $(subst .pdf,.png,$(addprefix html/screenshots/,$(SCREENSHOTS))) \
        $(subst .svg,.png,$(addprefix diagrams/,$(DIAGRAMS))) \
 
@@ -128,7 +142,8 @@ html:       $(XML) config.xml shortcuts.xml dcpomatic-html.xsl extensions-html.ent dcp
 # PDF
 #
 
-pdf:   $(XML) config.xml dcpomatic-pdf.xsl extensions-pdf.ent dcpomatic_create.xml dcpomatic_cli.xml dcpomatic_kdm_cli.xml \
+pdf:   $(XML) config.xml shortcuts.xml verify_errors.xml verify_bv21_errors.xml verify_warnings.xml \
+       dcpomatic-pdf.xsl extensions-pdf.ent dcpomatic_create.xml dcpomatic_cli.xml dcpomatic_kdm_cli.xml \
        $(addprefix screenshots/,$(SCREENSHOTS)) \
        $(subst .svg,.pdf,$(addprefix diagrams/,$(DIAGRAMS)))
 
index 797a49fe5812acc820f54ee31c26f753c9e4c9c9..87d3287ae890c0c7c623ac517faa454d6e3017b8 100644 (file)
@@ -3741,7 +3741,7 @@ The full details of OV and VF files are discussed in <xref linkend="sec-overlay"
 </chapter>
 
 <chapter xml:id="ch-player" xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
-  <title>Playing and verifying DCPs</title>
+  <title>Playing DCPs</title>
 
   <para>DCP-o-matic includes a DCP player, and although it requires a
   very high-speed CPU to play DCPs in full resolution, it can also
@@ -3767,12 +3767,43 @@ The full details of OV and VF files are discussed in <xref linkend="sec-overlay"
   resolution.
   </para>
 
+</chapter>
+
+
+<chapter xml:id="ch-verifier" xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+  <title>Verifying DCPs</title>
+
   <para>
-    The player also offers a simple DCP validator.  To check a DCP,
+    The player also offers a DCP validator.  To check a DCP,
     open it and then select <guilabel>Verify DCP</guilabel> from the
-    <guilabel>Tools</guilabel> menu.  This will run some basic checks to see if the DCP meets the required standards.
+    <guilabel>Tools</guilabel> menu.  This will run various checks on the DCP.
+  </para>
+
+  <para>
+    The validator will report three kinds of problems:
   </para>
 
+  <itemizedlist>
+  <listitem>Errors &mdash; serious problems with the DCP that are likely to cause problems on playback.</listitem>
+  <listitem>Bv2.1 errors &mdash; errors described by the <ulink url="https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=9161348">SMPTE Bv2.1 standard</ulink>.</listitem>
+  <listitem>Warnings &mdash; small problems that may not matter.</listitem>
+  </itemizedlist>
+
+  <section>
+  <title>Errors</title>
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="verify_errors.xml"/>
+  </section>
+
+  <section>
+  <title>Bv2.1 errors</title>
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="verify_bv21_errors.xml"/>
+  </section>
+
+  <section>
+  <title>Warnings</title>
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="verify_warnings.xml"/>
+  </section>
+
 </chapter>
 
 
diff --git a/doc/manual/verifier.py b/doc/manual/verifier.py
new file mode 100644 (file)
index 0000000..877a118
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/python3
+
+from pathlib import Path
+import re
+import sys
+import subprocess
+
+if len(sys.argv) < 3:
+    print(f"Syntax: {sys.argv[0]} <path-to-libdcp-source-tree> <ERROR|BV21_ERROR|WARNING>")
+    sys.exit(1)
+
+libdcp = Path(sys.argv[1])
+type = sys.argv[2]
+header = libdcp / "src" / "verify.h"
+
+types = ("BV21_ERROR", "ERROR", "WARNING")
+
+def find_type(name):
+    """
+    Search source code to find where a given code is used and hence find out whether
+    it represents an error, Bv2.1 "error" or warning.
+    """
+    previous = ''
+    for source in ["verify_j2k.cc", "dcp.cc", "verify.cc"]:
+        path = libdcp / "src" / source
+        with open(path) as s:
+            for line in s:
+                if line.find(name) != -1:
+                    line_with_previous = previous + line
+                    for t in types:
+                        if line_with_previous.find(t) != -1:
+                            return t
+                    assert False
+                previous = line
+
+
+print('<itemizedlist>')
+
+active = False
+with open(header) as h:
+    for line in h:
+        strip = line.strip()
+        if strip == "enum class Code {":
+            active = True
+        elif strip == "};":
+            active = False
+        elif active:
+            if strip.startswith('/**'):
+                text = strip.replace('/**', '').replace('*/', '').strip()
+            elif not strip.startswith('/*') and not strip.startswith('*') and strip.endswith(','):
+                this_type = find_type(strip[:-1])
+                if this_type == type:
+                    text = re.sub(r"\[.*?\]", lambda m: f'(Bv2.1 {m[0][7:-1]})', text)
+                    text = text.replace('<', '&lt;')
+                    text = text.replace('>', '&gt;')
+                    text = re.sub(r"_(.*?)_", r"<code>\1</code>", text)
+                    print(f'<listitem>{text}.</listitem>')
+
+print('</itemizedlist>')