diff options
121 files changed, 24939 insertions, 4985 deletions
diff --git a/asdcplib/COPYING b/asdcplib/COPYING index c7899786..3c09d56f 100644 --- a/asdcplib/COPYING +++ b/asdcplib/COPYING @@ -1,5 +1,5 @@ -AS-DCP Lib is Copyright (c) 2003-2009, John Hurst +AS-DCP Lib is Copyright (c) 2003-2012, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -24,3 +24,32 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +IMF Essence Component (AS-02) implementation: +(AS_02.h AS_02_internal.h AS_02_JP2K.cpp AS_02_MXF.cpp AS_02_PCM.cpp + as-02-unwrap.cpp as-02-wrap.cpp h__02_Reader.cpp h__02_Writer.cpp) +Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/asdcplib/Makefile.in b/asdcplib/Makefile.in index 897c13e2..435b67fb 100644 --- a/asdcplib/Makefile.in +++ b/asdcplib/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -41,6 +40,51 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -60,10 +104,16 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(top_srcdir)/configure COPYING \ - build-aux/config.guess build-aux/config.sub build-aux/depcomp \ - build-aux/install-sh build-aux/ltmain.sh build-aux/missing +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) COPYING README \ + build-aux/compile build-aux/config.guess build-aux/config.sub \ + build-aux/depcomp build-aux/install-sh build-aux/missing \ + build-aux/ltmain.sh $(top_srcdir)/build-aux/compile \ + $(top_srcdir)/build-aux/config.guess \ + $(top_srcdir)/build-aux/config.sub \ + $(top_srcdir)/build-aux/install-sh \ + $(top_srcdir)/build-aux/ltmain.sh \ + $(top_srcdir)/build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_expat.m4 \ $(top_srcdir)/m4/ax_lib_openssl.m4 \ @@ -79,22 +129,61 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - distdir dist dist-all distcheck +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) @@ -105,6 +194,7 @@ am__remove_distdir = \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi +am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ @@ -132,12 +222,14 @@ am__relativize = \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best +DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -324,22 +416,25 @@ distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -354,57 +449,12 @@ $(RECURSIVE_TARGETS): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -420,12 +470,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -437,15 +482,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -454,9 +495,31 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) @@ -492,13 +555,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -527,40 +587,42 @@ distdir: $(DISTFILES) || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__remove_distdir) + $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__remove_distdir) - -dist-lzma: distdir - tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma - $(am__remove_distdir) + $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) + $(am__post_remove_distdir) dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) + $(am__post_remove_distdir) -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -571,8 +633,6 @@ distcheck: dist GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lzma*) \ - lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ @@ -584,18 +644,19 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -618,7 +679,7 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__remove_distdir) + $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' @@ -753,14 +814,13 @@ ps-am: uninstall-am: -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-generic \ - clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ - dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \ - dist-zip distcheck distclean distclean-generic \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ distclean-libtool distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ @@ -770,7 +830,7 @@ uninstall-am: install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-recursive uninstall uninstall-am + ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/asdcplib/README b/asdcplib/README index 8a630647..5f2ece91 100755 --- a/asdcplib/README +++ b/asdcplib/README @@ -1,15 +1,26 @@ -$Id: README,v 1.75 2012/03/07 19:29:06 mikey Exp $ +$Id: README,v 1.97 2015/11/10 19:40:55 jhurst Exp $ The asdcplib library is a set of objects that offer simplified access to files conforming to the sound and picture track file formats developed by the SMPTE Working -Group DC28.20. +Group DC28.20 (now TC 21DC). -This work was originally funded by Digital Cinema -Initiatives, LLC (DCI). Subsequent efforts have been funded -by Deluxe Laboratories, Doremi Labs, CineCert LLC, Avica -Technology and others. +Recently, support has also been added for SMPTE draft ST +2067-5 "IMF Essence Component", AKA "AS-02". This code was +donated by Fraunhofer IIS. It carries additional copyright +information which should be listed whenever you link the +AS-02 elements of the library. Please look at the top of +the AS-02 files to see this copyright information. + +AS-02 support is carried in separate object modules, so +unless you #include <AS_02.h> and link libas-02.so you are +still using plain old asdcp. + +This work was originally funded by Digital Cinema Initiatives, +LLC (DCI). Subsequent efforts have been funded by Deluxe +Laboratories, Doremi Labs, CineCert LLC, Avica Technology +and others. **The asdcplib project was originally housed on SourceForge. The project has moved to http://www.cinecert.com/asdcplib/ @@ -32,11 +43,11 @@ supporting this project. Design Notes This library is intended (but of course not limited) for -use by developers of commercial D-Cinema products. It is -designed to be easily integrated into a wide variety of -development environments. Commercial users are strongly -urged to use static linking (at least where you use this -library) to prevent malicious in-field replacement of +use by developers of commercial D-Cinema products (and now +IMF!). It is designed to be easily integrated into a wide +variety of development environments. Commercial users are +strongly urged to use static linking (at least where you use +this library) to prevent malicious in-field replacement of critical system modules. This recommendation should be considered wherever Open Source or Free software is being used in conjunction with critical security parameters, such @@ -50,12 +61,15 @@ crypto functions can be replaced by linking to alternative implementations of the ASDCP:: objects which provide those services. -AS_DCP.h contains the entire API. You do not need to read -any of the other files, except maybe asdcp-test.cpp which -contains detailed usage examples of each of the API's -services. The KM_* files may be of interest for general -development support, but may be ignored if all you want -is simple AS-DCP support. +AS_DCP.h contains the entire AS-DCP API. You do not need to +read any of the other files, except maybe asdcp-test.cpp which +contains detailed usage examples of each of the API's services. +The KM_* files may be of interest for general development +support, but may be ignored if all you want is simple AS-DCP +support. + +Likewise, draft 2067-5 "IMF Essence Component" (AS-02) support +is entirely contained in AS-02.h Build Instructions @@ -67,9 +81,8 @@ MinGW installed. For those Windows users who would prefer to build this natively, an "nmake" build file and instructions can be found in the win32 subdirectory. -OpenSSL is also required, and the most recent version of v0.9.8 -is recommended. See http://www.openssl.org/ for more information -and download instructions. +OpenSSL is also required, any recent version should be fine. See +http://www.openssl.org/ for more information and download instructions. Optional support for writing Timed Text Track Files is supported by either Xerces-C or Expat. See http://xerces.apache.org/xerces-c/ or @@ -77,7 +90,8 @@ http://expat.sourceforge.net/ for source and build instructions. To configure and build, type './configure' followed by 'make'. There are several test targets on the POSIX side, but you need to assemble -a set of test files to use them. +a set of test files to use them. AS-02 support can be enabled with + --enable-as-02. I have tested this build on win32, Linux, OpenBSD, and Darwin platforms. Others may work as well. @@ -97,6 +111,10 @@ asdcp-info - Displays information about AS-DCP (MXF) track files. asdcp-util - Calculates digests and generates random numbers and UUIDs. +as-02-wrap - Writes AS-02 Essence Component files. + +as-02-unwrap - Extracts essence from AS-02 Essence Component files. + kmfilegen - Writes and verifies large files using a platform- independent format. Use it to test issues related to large files. @@ -111,17 +129,272 @@ blackwave - Write a WAVE file full of zeros, Used to make filler j2c-test - Displays information about JP2K codestreams. +Experimental feature: Prototype for High Dynamic Range is a wrapper +for the IMF application that allows JPEG-2000 codestreams to be paired +with opaque blobs of metadata. AS-02 support must be enabled to +build this feature, so --enable-as-02 must be enabled if +--enable-phdr is to be used. The following executable programs will be +built: + +phdr-wrap - Writes AS-02 PHDR Essence Component files. + +phdr-unwrap - Extracts essence from AS-02 PHDR Essence Component files. + Documentation -The API documentation is mostly in AS_DCP.h. Read that file for -a detailed description of the library's capabilities. Read -asdcp-test.cpp for library usage examples. The command-line -utilities all respond to -h. +The API documentation is mostly in AS_DCP.h. and AS_02.h Read those +files for a detailed description of the library's capabilities. Read +asdcp-*.cpp and as-02-*.cpp files for library usage examples. The +command-line utilities all respond to -h. Change History +2015-11-10 - bug fixes, IMF text, pink noise + o I moved personal dev environment from older gcc to newer clang. Many + small changes were made to satisfy the new compiler: + - Altered many printf format codes to use the correct format for the + given integer type. + - Parenthesized some expressions to clarify previously ambiguous + expectation about precedence. + - Created macro KM_MACOSX for use in OS-specific code selection. + - Removed last uses of the old C-language abs(), now using Kumu::xabs(). + - Removed last uses of the old C-language atoi(), not using strtol(). + o Added platform-independent call Kumu::GetExecutablePath() (to be tested + on win32). + o Added new capabilities to Result_t. + o Added imlementation of SMPTE ST 2092-1 pink noise generator. + o Added pinkwave CLI utility. + o Added font support to the IMF timed-text wrapper. + o Fixed a bug that was causing Array properties to be written without + the (count, length) header (from PAL). + o General review of Batch/Array distinction throughout the project. + o Cleaned up definitions of optional properties in all MXF metadata packs. + o Fixed Win32 build (from Crowe). + o Fixed a bug that caused incorrect failure when parsing JPEG 2000 + codestreams having fewer than five decomposition levels. (from Korneder). + o Fixed missing UUID generation in some instances of the MCALinkID property. + o Added -w option to asdcp-wrap to support use of WTF label with MCA. + o Altered asdcp-wrap to recognize "-C <UL>" when MCA is being used. + o Fixed broken -A <w>/<h> option in as-02-wrap and phdr-wrap. + o asdcp-wrap and as-02-wrap now allow split channel groups in MCA labels. + + +2015-02-23 - bug fixes + o Fixed a new bug introduced by the fix to large numbers of subtitle ancillary + resources. + o Added support for generic Aux Data (ST 429-14) to asdcp-wrap. + + +2015-02-19 - PHDR feature, bug fixes + o Modified PCMParser and PCMParserList to return partial frame buffers at the + end of a WAV input file. This was needed to allow wrapping all samples into + an AS-02 audio file (which is clip-wrapped) in the case where the input file + has an odd number of samples with respect to the frame buffer size being + used. If there is more than one input file the length of the last buffer + will be determined by PCMParserList to be the shortest of the input files. + Prior to this change, partial samples in an input WAV file have been + abandoned (i.e., not written out to the MXF file). As a result, AS-DCP + applications will have to decide whether to abandon the partial last frame + (usually detected by testing frame_buffer.Size() != frame_buffer.Capacity()) + or write it to the MXF file. Programs written to the old API will write the + partial frame (i.e., new behavior.) This should not be harmful since the + remainder of the buffer is zeroed and the output file will contain one + additional edit unit compared to the previous version. + o asdcp-wrap has been modified to test for the partial buffer and by default + will complain and abandon the buffer (i.e., same behavior but with a warning + message.) A new command line switch (-g) alters this behavior and writes + the buffer to the MXF file (it still warns the user that this condition is + present.) + o as-02-wrap now wraps all samples from the input file to the MXF file. There + is no padding, the clip is exactly the set of samples from the input. + o as-02 unwrap is temporarily restricted to creating wav files that are + aligned with the frame buffer size. This means that the output file will + be longer than the original WAV input in the case where the input file has + an odd number of samples with respect to the frame buffer size being used. + The pad samples are zero (silence). + o Modified CalcFramesFromDurationInSamples() to increment the count by one for + the case where the input file has an odd number of samples with respect to + the frame buffer size being used (previously it truncated the odd samples.) + o Fixed ST 429-5 / ST 2067-5 wrapping to increase header space when ancillary + resources are present (fixes a bug that cause the header to overflow the + allotted space when large numbers of PNG files were present.) + o Refactored GetXMLDocType() to use the XML parser. + o Added ParseFirstFromString() method to Kumu::XMLElement + o Removed Kumu::StringIsXML from the API. + o Added ASDCP::MXF::RGBALayout type + o Added J2CLayout property to JPEG2000PictureSubDescriptor + o Changed km_token_split() to retain empty elements in the output list + o Added PHDR wrapping for AS-02. + o Added J2CLayout property to the JPEG2000PictureSubDescriptor. This + support is preliminary: the Raw data type is being used instead of + RGBALayout type, which will be in the next release. + + +2014-10-2 - Bug fixes and enhancements, 2.2.6 + o Fixed erroneous 377-4 MCA identifier in AS_DCP_PCM dump routine + o Fixed erroneous byte 13 in + WaveAudioDescriptor_ReferenceAudioAlignmentLevel label + o Added missing implementation of -W option to as-02.unwrap + o Fixed erroneous use of d-cinema ChannelAssignment label in as-02-wrap + + +2014-10-01 - Bug fixes and enhancements, 2.2.5 + o Finished AS-02 text wrap/unwrap + o Fixed fractional seconds parsing for Timestamp objects + o Updated KLVPacket to use 64-bit length; allows huge packets + in AS-02 PCM files + o cleaned up use of atoi() in the library + + +2014-07-09 - Additional IMF/AS-02 support, bug fixes and enhancements, 2.1.4 + o Added IMF App 2 edit rates in AS_02 namespace: EditRate_29_97, + EditRate_59_94. + o Revised AEC CBC context objects to copy the key rather than + keep the reference passed in to it. + o Addressed a bug that would allow unimpeded iteration of component + values in a JP2K::PictureDescriptor object. + o Addressed a bug that was incorrectly recording the sequence Duration + in MXF Track objects. + o Added ASDCP::AtmosSyncChannelMixer::AppendSilenceChannels() + o Added a QCD decoder to the j2c parser. + o Altered ASDCP::KLVPacket::HasUL() to use version-blind matching. + o Fixed an uninitialized variable in MemIOReader::ReadString() that + caused unbounded reads. + o Fixed broken ByteString::ArchiveLength() method + o Fixed broken version numbers on SoundfieldGroupLinkID and + GroupOfSoundfieldGroupsLinkID UL values. + o Added DBOXMotionCodePrimaryStream and DBOXMotionCodeSecondaryStream UL + values to the internal dictionary. + o Added optional prefix handling to MCA label generator. + o Re-factored MCA label generator to include additional + metadata (Thanks to Mike Radford). + o Added new options to as-02-wrap. + + +2014-01-06 – Additional IMF/AS-02 support, bug fixes 2.1.1 + o Fixed missing-index-partion bugs for AS-02 files. + o Moved LocalFilenameResolver into the AS_DCP public API so that it + can be used by other modules including AS-02. + o Did further refactoring of AS-02 Writer classes to separate CBR + and VBR indexing implementations. + o Fixed wave wrapping UL in clip-wrapped AS-02 files. Renamed some + UL constants to reflect "clip" or "frame" wrapping. + o Re-factored JP2K_PDesc_to_MD() and MD_to_JP2K_PDesc() to work + with GenericPictureEssenceDescriptor objects. + o Fixed a bug that was suppressing PictureComponentSizing, + CodingStyleDefault and QuantizationDefault when writing the + essence descriptor in a JP2K file (AS-DCP and AS-02). + o Fixed the version byte on the following UL values: + StereoscopicPictureSubDescriptor + GenericPictureEssenceDescriptor_ColorPrimaries + GenericPictureEssenceDescriptor_ActiveHeight + GenericPictureEssenceDescriptor_ActiveWidth + GenericPictureEssenceDescriptor_ActiveXOffset + GenericPictureEssenceDescriptor_ActiveYOffset + o Added some essence descriptor options to as-02-wrap. + o Changed bit rate display in asdcp-info from mebi-bits/s to + mega-bits/s. + o Added "SMPTE" / "Interop" format type display to asdcp-info. + o Improved integration of ST 377-4 MCA concepts with ST 429-2 static + labels. + o Modified asdcp-wrap to assume -L when wrapping timed-text (since + there is no MXF text wrapping for Interop.) + o Added new EssenceType_t values for IMF/AS-02 track files. + o Added detection for AS-02 track files to ASDCP::EssenceType() + o Changed lots of "const char*" to "const std::string&" in the + APIs defined by KM_fileio.h and AS_DCP.h. + o Fixed VBR Delta Segment entries to correctly flag progressive + material. + o Fixed PCM unwrapping bugs in as-02-unwrap. + o Fixed missing return statement in ArchivableString::ArchiveLength + (thanks to both Kristof Provost and Franck Chopin) + o Fixed broken sample alignment in RF64Writer (thanks to Wolfgang + Woehl and Dolby) + o Fixed win32 build (thanks to Dolby) + o fixed a bug that caused blackwave to only produce 96kHz WAV files. + (thanks to Stephane W) + + +2013-07-02 – IMF/AS-02 support, bug fixes 2.0.0 + o Massive refactoring of internals to allow easier implementation + of AS-02. Some API changes were made as well (note that + OPAtomHeader is now OP1aHeader and RIP is no longer part of the + OP1aHeader.) If you are using this project as a library (and + especially if you are keeping patches against it) PLEASE TAKE + TIME TO EVALUATE THIS RELEASE THOUROUGHLY BEFORE ADDING IT TO + YOUR RELEASE PATH. + o Final integration of Fraunhoffer IIS code contribution. AS-02 + files are now fully supported with some TODOs and two major + exceptions: LEAD indexes are not supported by the MXF writers + and interlace images are not yet supported. + o Added support for MCA labels (ST 428-12) to asdcp-wrap. Note + that this project is still in the early stages of interop testing + so errors are likely present and don't expect any server to + make use of this feature. + + +2013-07-01 - Bug fixes, enhancements 1.12.50 + o Fixed missing return statement in ArchivableString::ArchiveLength + (thanks to both Kristof Provost and Franck Chopin) + o Fixed broken sample alignment in RF64Writer (thanks to Dolby) + o Fixed win32 build (thanks to Dolby) + + +2013-04-12 - Dolby Atmos support and more audio labels 1.11.49 + o Significant code contribution from Dolby Laboratories to add + support for generic data track files as proposed in ST 21DC + and also Dolby Atmos track file support as a specialization. + o Added Dolby-contributed code to support generating the external + sync signal for d-cinema as proposed in ST 21DC. + o Added Dolby-contributed code to support RF64 WAVE files. + o Fixed UL error in ST 429-5 DM encoding (contributed by Dolby). + o Added ULs for ST 428-12 and Amd. 429-2 2013. Please check! + + +2013-02-20 - bug fixes, enhancements 1.10.48 + o Refactored internals of the AS-DCP file readers. While no + changes in behavior are intended, users are cautioned to test + thouroughly before use in production. + o Fixed a bug in ReadAncillaryResource that was causing bogus HMAC + failures when reading resources from a file. + o Fixed premature-release bug in the Expat version of the XML parser. + Thanks to Carsten Feldheim (IIS) for the tip. + o Fixed -W option in asdcp-unwrap. Thanks to RGB. + o Added P-HFR support to asdcp-wrap (see URL for details: + http://isdcf.com/papers/ISDCF-HighFrameRate-DCP.pdf). + o Added support for SMPTE ST 428-21 "Archival Frame Rates". + o Added -P option to asdcp-wrap (inserts arbitrary UL into the + PictureEssenceCoding property when wrapping JP2K files.) + o Added support for 96 kHz files to blackwave. + o Added new path and string manglers to Kumu. + o Updated MCA ULs (I warned you...). Again please take some + time to proof this work against ST 477-4 including the latest + drafts of the registries. + Changed the version byte (8 0f 16) to 0x0e: + MCALabelSubDescriptor + AudioChannelLabelSubDescriptor + SoundfieldGroupLabelSubDescriptor + GroupOfSoundfieldGroupsLabelSubDescriptor + GroupOfSoundfieldGroupsLinkID + Changed bytes 8 and and 13 of SoundfieldGroupLinkID + Added items to the UL dictionary: + MCAPartitionKind + MCAPartitionNumber + MCATitle + MCATitleVersion + MCATitleSubVersion + MCAEpisode + MCAAudioContentKind + MCAAudioElementKind + + +2012-08-07 - bug fix, 1.10.46 + o Added missing zero-initializers to time values when parsing a + timestamp string (in the case where the optional [Thh:mm.[:ss]] + syntax is not present in an encoded string). + 2012-03-06 - bug fixes, enhancements 1.9.45 o Removed ASDCP::Timestamp, all items that were of that class are now of class Kumu::Timestamp @@ -240,7 +513,8 @@ Change History o ST 429-5 files have corrected ULs for DCTimedTextDescriptor and GenericStream DataElement. Files made with previous versions of the library are incompatible with this and future versions. - o Fixed File Package TrackNumber values. Thanks to Sankar. + o Fixed File Package TrackNumber values. Th +anks to Sankar. o Added edit rate constants to AS_DCP.h (25, 30, 50, 60). o Changed AudioDescriptor "SampleRate" element name to "EditRate" to make it consistent with the other types. diff --git a/asdcplib/aclocal.m4 b/asdcplib/aclocal.m4 index de62d1de..e5c71bd9 100644 --- a/asdcplib/aclocal.m4 +++ b/asdcplib/aclocal.m4 @@ -1,8 +1,7 @@ -# generated automatically by aclocal 1.11.3 -*- Autoconf -*- +# generated automatically by aclocal 1.14.1 -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -# Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -12,33 +11,31 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, -[m4_warning([this file was generated for autoconf 2.68. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically `autoreconf'.])]) +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' +[am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.3], [], +m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -54,24 +51,22 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.3])dnl +[AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -90,7 +85,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you +# harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -116,22 +111,19 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 9 - # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl @@ -150,16 +142,14 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, -# 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 12 -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing @@ -169,7 +159,7 @@ fi])]) # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was @@ -182,12 +172,13 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], @@ -195,8 +186,8 @@ AC_CACHE_CHECK([dependency style of $depcc], # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -236,16 +227,16 @@ AC_CACHE_CHECK([dependency style of $depcc], : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -254,8 +245,8 @@ AC_CACHE_CHECK([dependency style of $depcc], test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -263,7 +254,7 @@ AC_CACHE_CHECK([dependency style of $depcc], fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -311,7 +302,7 @@ AM_CONDITIONAL([am__fastdep$1], [ # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl @@ -321,9 +312,13 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' @@ -338,20 +333,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -#serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -364,7 +357,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -376,21 +369,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` @@ -408,7 +399,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will +# is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], @@ -418,18 +409,21 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 16 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -442,7 +436,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -471,31 +465,40 @@ AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl @@ -506,34 +509,78 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -555,15 +602,12 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, -# Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -577,16 +621,14 @@ if test x"${install_sh}" != xset; then install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST(install_sh)]) +AC_SUBST([install_sh])]) -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -602,14 +644,12 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 - # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. @@ -627,7 +667,7 @@ am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -654,15 +694,12 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -670,11 +707,10 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -687,54 +723,22 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) + AC_MSG_WARN(['missing' script is too old or missing]) fi ]) -# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, -# Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 1 - -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -744,7 +748,7 @@ AC_DEFUN([_AM_MANGLE_OPTION], # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ @@ -758,24 +762,82 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Check to make sure that the build environment is sane. -*- Autoconf -*- +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -786,32 +848,40 @@ case `pwd` in esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$[2]" = conftest.file ) then @@ -821,46 +891,118 @@ else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT(yes)]) +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor `install' (even GNU) is that you can't +# One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize +# always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 3 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -874,18 +1016,16 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -895,76 +1035,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. + +# We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + AM_RUN_LOG([cat conftest.dir/file]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi + done rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar <conftest.tar]) - grep GrepMe conftest.dir/file >/dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR diff --git a/asdcplib/build-aux/compile b/asdcplib/build-aux/compile new file mode 100755 index 00000000..531136b0 --- /dev/null +++ b/asdcplib/build-aux/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Written by Tom Tromey <tromey@cygnus.com>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/asdcplib/build-aux/config.guess b/asdcplib/build-aux/config.guess index 49ba16f1..9afd6762 100755 --- a/asdcplib/build-aux/config.guess +++ b/asdcplib/build-aux/config.guess @@ -1,14 +1,12 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-01-01' +timestamp='2013-11-29' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -17,26 +15,22 @@ timestamp='2012-01-01' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see <http://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to <config-patches@gnu.org> and include a ChangeLog -# entry. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). # -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. +# Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + me=`echo "$0" | sed -e 's,.*/,,'` @@ -56,9 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -140,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include <features.h> + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in @@ -202,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} @@ -304,7 +321,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) + arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -803,6 +820,9 @@ EOF i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; @@ -854,15 +874,22 @@ EOF exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -874,59 +901,54 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build @@ -945,54 +967,63 @@ EOF #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1196,6 +1227,9 @@ EOF BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1222,19 +1256,31 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) @@ -1251,7 +1297,7 @@ EOF NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; - NSE-?:NONSTOP_KERNEL:*:*) + NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) @@ -1320,11 +1366,11 @@ EOF i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - eval $set_cc_for_build cat >$dummy.c <<EOF #ifdef _SEQUENT_ diff --git a/asdcplib/build-aux/config.sub b/asdcplib/build-aux/config.sub index d6b6b3c7..61cb4bc2 100755 --- a/asdcplib/build-aux/config.sub +++ b/asdcplib/build-aux/config.sub @@ -1,38 +1,31 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-01-01' +timestamp='2013-10-01' -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # -# This program 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 General Public License for more details. +# This program 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 +# General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see <http://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted GNU ChangeLog entry. +# Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -75,9 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -125,13 +116,17 @@ esac maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] @@ -154,7 +149,7 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze) + -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; @@ -223,6 +218,12 @@ case $os in -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; -lynx*) os=-lynxos ;; @@ -247,13 +248,16 @@ case $basic_machine in # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | be32 | be64 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ | bfin \ - | c4x | clipper \ + | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ @@ -261,10 +265,11 @@ case $basic_machine in | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -282,16 +287,17 @@ case $basic_machine in | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ - | nios | nios2 \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ - | or32 \ + | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ @@ -319,7 +325,7 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | picochip) + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -332,7 +338,10 @@ case $basic_machine in strongarm | thumb | xscale) basic_machine=arm-unknown ;; - + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; xscaleeb) basic_machine=armeb-unknown ;; @@ -355,15 +364,16 @@ case $basic_machine in # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ @@ -372,11 +382,13 @@ case $basic_machine in | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ @@ -394,12 +406,13 @@ case $basic_machine in | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ @@ -775,11 +788,15 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; - microblaze) + microblaze*) basic_machine=microblaze-xilinx ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; mingw32) - basic_machine=i386-pc + basic_machine=i686-pc os=-mingw32 ;; mingw32ce) @@ -815,7 +832,7 @@ case $basic_machine in basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) - basic_machine=i386-pc + basic_machine=i686-pc os=-msys ;; mvs) @@ -1006,7 +1023,11 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; - rdos) + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) basic_machine=i386-pc os=-rdos ;; @@ -1333,21 +1354,21 @@ case $os in -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-uclibc* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ @@ -1479,9 +1500,6 @@ case $os in -aros*) os=-aros ;; - -kaos*) - os=-kaos - ;; -zvmoe) os=-zvmoe ;; @@ -1530,6 +1548,12 @@ case $basic_machine in c4x-* | tic4x-*) os=-coff ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; tic54x-*) os=-coff ;; @@ -1570,6 +1594,9 @@ case $basic_machine in mips*-*) os=-elf ;; + or1k-*) + os=-elf + ;; or32-*) os=-coff ;; diff --git a/asdcplib/build-aux/depcomp b/asdcplib/build-aux/depcomp index bd0ac089..4ebd5b3a 100755 --- a/asdcplib/build-aux/depcomp +++ b/asdcplib/build-aux/depcomp @@ -1,10 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2011-12-04.11; # UTC +scriptversion=2013-05-30.07; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, -# 2011 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,9 +27,9 @@ scriptversion=2011-12-04.11; # UTC case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] @@ -40,8 +39,8 @@ as side-effects. Environment variables: depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. @@ -57,6 +56,66 @@ EOF ;; esac +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 @@ -69,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" +# Avoid interferences from the environment. +gccflag= dashmflag= + # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case @@ -80,26 +142,32 @@ if test "$depmode" = hp; then fi if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc fi case "$depmode" in @@ -122,8 +190,7 @@ gcc3) done "$@" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -131,13 +198,17 @@ gcc3) ;; gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then @@ -145,33 +216,31 @@ gcc) fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. + # The second -e expression handles DOS-style file names with drive + # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. +## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory +## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -189,8 +258,7 @@ sgi) "$@" -MDupdate "$tmpdepfile" fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -198,43 +266,41 @@ sgi) if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the + # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" ;; +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the + # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u @@ -247,9 +313,7 @@ aix) "$@" -M fi stat=$? - - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi @@ -258,44 +322,100 @@ aix) do test -f "$tmpdepfile" && break done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : + # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -307,8 +427,8 @@ icc) sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -319,9 +439,8 @@ hp2) # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d @@ -332,8 +451,7 @@ hp2) "$@" +Maked fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi @@ -343,77 +461,61 @@ hp2) test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" else - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; msvc7) if test "$libtool" = yes; then @@ -424,8 +526,7 @@ msvc7) "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" - if test "$stat" = 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -443,14 +544,15 @@ msvc7) p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g -s/\(.*\)/ \1 \\/p +s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { - s/.*/ / + s/.*/'"$tab"'/ G p }' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; @@ -478,7 +580,7 @@ dashmstdout) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -498,18 +600,18 @@ dashmstdout) done test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' + # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -562,11 +664,12 @@ makedepend) # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; @@ -583,7 +686,7 @@ cpp) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -602,10 +705,10 @@ cpp) esac done - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" @@ -637,23 +740,23 @@ msvisualcpp) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; + set fnord "$@" + shift + shift + ;; *) - set fnord "$@" "$arg" - shift - shift - ;; + set fnord "$@" "$arg" + shift + shift + ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; diff --git a/asdcplib/build-aux/install-sh b/asdcplib/build-aux/install-sh index a9244eb0..377bb868 100755 --- a/asdcplib/build-aux/install-sh +++ b/asdcplib/build-aux/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-01-19.21; # UTC +scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ scriptversion=2011-01-19.21; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,7 +156,7 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac @@ -190,7 +190,7 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac @@ -202,7 +202,7 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi @@ -240,7 +240,7 @@ fi for src do - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac @@ -354,7 +354,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. + # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in diff --git a/asdcplib/build-aux/ltmain.sh b/asdcplib/build-aux/ltmain.sh index 63ae69dc..9ae038c2 100644 --- a/asdcplib/build-aux/ltmain.sh +++ b/asdcplib/build-aux/ltmain.sh @@ -5851,9 +5851,10 @@ func_mode_link () # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -stdlib=* select c++ std lib with clang -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + -O*|-flto*|-fwhopr*|-fuse-linker-plugin|-stdlib=*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" diff --git a/asdcplib/build-aux/missing b/asdcplib/build-aux/missing index 86a8fc31..db98974f 100755 --- a/asdcplib/build-aux/missing +++ b/asdcplib/build-aux/missing @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2012-01-06.13; # UTC +scriptversion=2013-10-28.13; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,68 +25,40 @@ scriptversion=2012-01-06.13; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi +case $1 in -msg="missing on your system" + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to <bug-automake@gnu.org>." exit $? @@ -99,228 +70,141 @@ Send bug reports to <bug-automake@gnu.org>." ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" ;; -esac - -exit 0 + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/asdcplib/build-aux/test-driver b/asdcplib/build-aux/test-driver new file mode 100755 index 00000000..d3060566 --- /dev/null +++ b/asdcplib/build-aux/test-driver @@ -0,0 +1,139 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2013-07-13.22; # UTC + +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <<END +Usage: + test-driver --test-name=NAME --log-file=PATH --trs-file=PATH + [--expect-failure={yes|no}] [--color-tests={yes|no}] + [--enable-hard-errors={yes|no}] [--] + TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] +The '--test-name', '--log-file' and '--trs-file' options are mandatory. +END +} + +test_name= # Used for reporting. +log_file= # Where to save the output of the test script. +trs_file= # Where to save the metadata of the test run. +expect_failure=no +color_tests=no +enable_hard_errors=yes +while test $# -gt 0; do + case $1 in + --help) print_usage; exit $?;; + --version) echo "test-driver $scriptversion"; exit $?;; + --test-name) test_name=$2; shift;; + --log-file) log_file=$2; shift;; + --trs-file) trs_file=$2; shift;; + --color-tests) color_tests=$2; shift;; + --expect-failure) expect_failure=$2; shift;; + --enable-hard-errors) enable_hard_errors=$2; shift;; + --) shift; break;; + -*) usage_error "invalid option: '$1'";; + *) break;; + esac + shift +done + +missing_opts= +test x"$test_name" = x && missing_opts="$missing_opts --test-name" +test x"$log_file" = x && missing_opts="$missing_opts --log-file" +test x"$trs_file" = x && missing_opts="$missing_opts --trs-file" +if test x"$missing_opts" != x; then + usage_error "the following mandatory options are missing:$missing_opts" +fi + +if test $# -eq 0; then + usage_error "missing argument" +fi + +if test $color_tests = yes; then + # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. + red='[0;31m' # Red. + grn='[0;32m' # Green. + lgn='[1;32m' # Light green. + blu='[1;34m' # Blue. + mgn='[0;35m' # Magenta. + std='[m' # No color. +else + red= grn= lgn= blu= mgn= std= +fi + +do_exit='rm -f $log_file $trs_file; (exit $st); exit $st' +trap "st=129; $do_exit" 1 +trap "st=130; $do_exit" 2 +trap "st=141; $do_exit" 13 +trap "st=143; $do_exit" 15 + +# Test script is run here. +"$@" >$log_file 2>&1 +estatus=$? +if test $enable_hard_errors = no && test $estatus -eq 99; then + estatus=1 +fi + +case $estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/asdcplib/configure b/asdcplib/configure index 041db0fe..57bd859e 100755 --- a/asdcplib/configure +++ b/asdcplib/configure @@ -1,13 +1,11 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for asdcplib 1.9.45. +# Generated by GNU Autoconf 2.69 for asdcplib 2.5.11. # # Report bugs to <asdcplib@cinecert.com>. # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -136,6 +134,31 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -169,7 +192,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -222,21 +246,25 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -339,6 +367,14 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -460,6 +496,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -494,16 +534,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -515,28 +555,8 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -570,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='asdcplib' PACKAGE_TARNAME='asdcplib' -PACKAGE_VERSION='1.9.45' -PACKAGE_STRING='asdcplib 1.9.45' +PACKAGE_VERSION='2.5.11' +PACKAGE_STRING='asdcplib 2.5.11' PACKAGE_BUGREPORT='asdcplib@cinecert.com' PACKAGE_URL='' @@ -616,6 +636,10 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +USE_PHDR_FALSE +USE_PHDR_TRUE +USE_AS_02_FALSE +USE_AS_02_TRUE ENABLE_RANDOM_UUID_FALSE ENABLE_RANDOM_UUID_TRUE DEV_HEADERS_FALSE @@ -702,6 +726,10 @@ build_os build_vendor build_cpu build +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V am__untar am__tar AMTAR @@ -766,6 +794,7 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking +enable_silent_rules enable_dependency_tracking enable_shared enable_static @@ -786,6 +815,8 @@ with_python enable_freedist enable_dev_headers enable_random_case_UUID +enable_as_02 +enable_phdr ' ac_precious_vars='build_alias host_alias @@ -1256,8 +1287,6 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1343,7 +1372,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures asdcplib 1.9.45 to adapt to many kinds of systems. +\`configure' configures asdcplib 2.5.11 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1413,7 +1442,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of asdcplib 1.9.45:";; + short | recursive ) echo "Configuration of asdcplib 2.5.11:";; esac cat <<\_ACEOF @@ -1421,8 +1450,12 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] @@ -1431,7 +1464,9 @@ Optional Features: --disable-largefile omit support for large files --enable-freedist ensure source distribution is of BSD-licensed code --enable-dev-headers install development headers - --enable-random-case-UUID allow randomly cased UUID headers when the environment variable KM_USE_RANDOM_UUID is set + --enable-random-case-UUID encode randomly-cased UUID values when the environment variable KM_USE_RANDOM_UUID is set + --enable-as-02 enable support for SMPTE ST 2067-5 MXF files, A.K.A. AS-02 + --enable-phdr enable support for Prototype for High Dyamic Range in AS-02 Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1533,10 +1568,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -asdcplib configure 1.9.45 -generated by GNU Autoconf 2.68 +asdcplib configure 2.5.11 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1650,7 +1685,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -1910,7 +1945,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -1932,8 +1967,8 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by asdcplib $as_me 1.9.45, which was -generated by GNU Autoconf 2.68. Invocation command line was +It was created by asdcplib $as_me 2.5.11, which was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2312,7 +2347,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. #AC_CONFIG_HEADER([src/config.h]) -am__api_version='1.11' +am__api_version='1.14' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2351,7 +2386,7 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -2409,9 +2444,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -2422,32 +2454,40 @@ case `pwd` in esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi - + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$2" = conftest.file ) then @@ -2459,6 +2499,16 @@ Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -2481,12 +2531,12 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then @@ -2498,10 +2548,10 @@ if test x"${install_sh}" != xset; then esac fi -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. +# will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -2520,7 +2570,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2560,7 +2610,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2611,7 +2661,7 @@ do test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ @@ -2640,12 +2690,6 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -2664,7 +2708,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2728,6 +2772,45 @@ else fi rmdir .tst 2>/dev/null +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -2750,7 +2833,7 @@ fi # Define the identity of the package. PACKAGE='asdcplib' - VERSION='1.9.45' + VERSION='2.5.11' cat >>confdefs.h <<_ACEOF @@ -2778,12 +2861,22 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' @@ -2791,6 +2884,50 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + + # Checks for programs. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || @@ -2897,7 +3034,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2937,7 +3074,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2990,7 +3127,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3031,7 +3168,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -3089,7 +3226,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3133,7 +3270,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3579,8 +3716,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdarg.h> #include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -3664,6 +3800,65 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" @@ -3683,7 +3878,7 @@ am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -3739,8 +3934,8 @@ else # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -3775,16 +3970,16 @@ else : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -3793,8 +3988,8 @@ else test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -3802,7 +3997,7 @@ else fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -3884,7 +4079,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3928,7 +4123,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4124,8 +4319,8 @@ else # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -4160,16 +4355,16 @@ else : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -4178,8 +4373,8 @@ else test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -4187,7 +4382,7 @@ else fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -4357,7 +4552,7 @@ do for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue + as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in @@ -4433,7 +4628,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -4499,7 +4694,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -4566,7 +4761,7 @@ do for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue + as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in @@ -4822,7 +5017,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4866,7 +5061,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5290,7 +5485,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5330,7 +5525,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5636,7 +5831,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5676,7 +5871,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5780,7 +5975,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5824,7 +6019,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5949,7 +6144,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5989,7 +6184,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6048,7 +6243,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6088,7 +6283,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6737,7 +6932,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6777,7 +6972,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6857,7 +7052,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6897,7 +7092,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6949,7 +7144,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6989,7 +7184,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7041,7 +7236,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7081,7 +7276,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7133,7 +7328,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7173,7 +7368,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7225,7 +7420,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7265,7 +7460,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -14969,7 +15164,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -15009,7 +15204,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -15241,6 +15436,8 @@ _ACEOF esac rm -rf conftest* fi + + fi if test "$ac_cv_sys_largefile_CC" != no; then @@ -16155,7 +16352,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -16492,7 +16689,9 @@ fi # Check whether --enable-freedist was given. if test "${enable_freedist+set}" = set; then : enableval=$enable_freedist; case "${enableval}" in - yes) freedist=true ;; + yes) freedist=true + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: BSD licensed ASDCPlib creation ENABLED." >&5 +$as_echo "$as_me: WARNING: BSD licensed ASDCPlib creation ENABLED." >&2;} ;; no) freedist=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-freedist" "$LINENO" 5 ;; esac @@ -16546,6 +16745,44 @@ else ENABLE_RANDOM_UUID_FALSE= fi +# Check whether --enable-as-02 was given. +if test "${enable_as_02+set}" = set; then : + enableval=$enable_as_02; case "${enableval}" in + yes) as_02_use=true ;; + no) as_02_use=false ;; + *) as_fn_error $? "bad value ${enableval} for --enable-as-02" "$LINENO" 5 ;; + esac +else + as_02_use=false +fi + + if test x$as_02_use = xtrue; then + USE_AS_02_TRUE= + USE_AS_02_FALSE='#' +else + USE_AS_02_TRUE='#' + USE_AS_02_FALSE= +fi + +# Check whether --enable-phdr was given. +if test "${enable_phdr+set}" = set; then : + enableval=$enable_phdr; case "${enableval}" in + yes) phdr_use=true ;; + no) phdr_use=false ;; + *) as_fn_error $? "bad value ${enableval} for --enable-phdr" "$LINENO" 5 ;; + esac +else + phdr_use=false +fi + + if test x$phdr_use = xtrue; then + USE_PHDR_TRUE= + USE_PHDR_FALSE='#' +else + USE_PHDR_TRUE='#' + USE_PHDR_FALSE= +fi + # Checks for libraries. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 @@ -16760,6 +16997,14 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -16820,6 +17065,14 @@ if test -z "${ENABLE_RANDOM_UUID_TRUE}" && test -z "${ENABLE_RANDOM_UUID_FALSE}" as_fn_error $? "conditional \"ENABLE_RANDOM_UUID\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_AS_02_TRUE}" && test -z "${USE_AS_02_FALSE}"; then + as_fn_error $? "conditional \"USE_AS_02\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_PHDR_TRUE}" && test -z "${USE_PHDR_FALSE}"; then + as_fn_error $? "conditional \"USE_PHDR\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -17118,16 +17371,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -17187,28 +17440,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -17229,8 +17470,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by asdcplib $as_me 1.9.45, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by asdcplib $as_me 2.5.11, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -17286,11 +17527,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -asdcplib config.status 1.9.45 -configured by $0, generated by GNU Autoconf 2.68, +asdcplib config.status 2.5.11 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -17370,7 +17611,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -18215,7 +18456,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -18228,7 +18469,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -18262,21 +18503,19 @@ $as_echo X"$mf" | continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || diff --git a/asdcplib/configure.ac b/asdcplib/configure.ac index bc3b84e8..16afc10f 100644 --- a/asdcplib/configure.ac +++ b/asdcplib/configure.ac @@ -1,6 +1,6 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -# Copyright (c) 2007-2012 John Hurst. All rights reserved. +# Copyright (c) 2007-2015 John Hurst. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -37,13 +37,15 @@ AC_PREREQ([2.59]) # For example, if asdcplib version 1.0.0 were modified to accomodate changes # in file format, and if no changes were made to AS_DCP.h, the new version would be # 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1. -AC_INIT([asdcplib], [1.9.45], [asdcplib@cinecert.com]) +AC_INIT([asdcplib], [2.5.11], [asdcplib@cinecert.com]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_SRCDIR([src/KM_error.h]) #AC_CONFIG_HEADER([src/config.h]) AM_INIT_AUTOMAKE([1.9 foreign]) +AC_CONFIG_MACRO_DIR([m4]) + # Checks for programs. AC_CANONICAL_BUILD AC_CANONICAL_HOST @@ -73,7 +75,8 @@ AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) AC_ARG_ENABLE([freedist], [ --enable-freedist ensure source distribution is of BSD-licensed code], [case "${enableval}" in - yes) freedist=true ;; + yes) freedist=true + AC_MSG_WARN([BSD licensed ASDCPlib creation ENABLED.]) ;; no) freedist=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-freedist]) ;; esac],[freedist=false]) @@ -87,13 +90,29 @@ AC_ARG_ENABLE([dev-headers], esac],[dev_headers=false]) AM_CONDITIONAL([DEV_HEADERS], [test x$dev_headers = xtrue]) AC_ARG_ENABLE([random-case-UUID], - [ --enable-random-case-UUID allow randomly cased UUID headers when the environment variable KM_USE_RANDOM_UUID is set], + [ --enable-random-case-UUID encode randomly-cased UUID values when the environment variable KM_USE_RANDOM_UUID is set], [case "${enableval}" in yes) random_case_UUID=true ;; no) random_case_UUID=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-random-case-UUID]) ;; esac],[random_case_UUID=false]) AM_CONDITIONAL([ENABLE_RANDOM_UUID], [test x$random_case_UUID = xtrue]) +AC_ARG_ENABLE([as-02], + [ --enable-as-02 enable support for SMPTE ST 2067-5 MXF files, A.K.A. AS-02], + [case "${enableval}" in + yes) as_02_use=true ;; + no) as_02_use=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-as-02]) ;; + esac],[as_02_use=false]) + AM_CONDITIONAL([USE_AS_02], [test x$as_02_use = xtrue]) +AC_ARG_ENABLE([phdr], + [ --enable-phdr enable support for Prototype for High Dyamic Range in AS-02], + [case "${enableval}" in + yes) phdr_use=true ;; + no) phdr_use=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-phdr]) ;; + esac],[phdr_use=false]) + AM_CONDITIONAL([USE_PHDR], [test x$phdr_use = xtrue]) # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_create]) diff --git a/asdcplib/src/AS_02.h b/asdcplib/src/AS_02.h new file mode 100644 index 00000000..129949ac --- /dev/null +++ b/asdcplib/src/AS_02.h @@ -0,0 +1,498 @@ +/* +Copyright (c) 2011-2014, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_02.h + \version $Id: AS_02.h,v 1.19 2015/03/21 05:26:06 jhurst Exp $ + \brief AS-02 library, public interface + +This module implements MXF AS-02 is a set of file access objects that +offer simplified access to files conforming to the standards published +by the SMPTE Media and Packaging Technology Committee 35PM. The file +format, labeled IMF Essence Component (AKA "AS-02" for historical +reasons), is described in the following document: + + o SMPTE 2067-5:2013 IMF Essence Component + +The following use cases are supported by the module: + + o Write essence to a plaintext or ciphertext AS-02 file: + JPEG 2000 codestreams + PCM audio streams + + o Read essence from a plaintext or ciphertext AS-02 file: + JPEG 2000 codestreams + PCM audio streams + + o Read header metadata from an AS-02 file + +NOTE: ciphertext support for clip-wrapped PCM is not yet complete. +*/ + +#ifndef _AS_02_H_ +#define _AS_02_H_ + +#include "Metadata.h" + + +namespace AS_02 +{ + using Kumu::Result_t; + + KM_DECLARE_RESULT(AS02_FORMAT, -116, "The file format is not proper OP-1a/AS-02."); + + namespace MXF { + // + // reads distributed index tables and provides a uniform lookup with + // translated StreamOffest values (that is, StreamOffest is adjusted + // to the actual file position + class AS02IndexReader : public ASDCP::MXF::Partition + { + Kumu::ByteString m_IndexSegmentData; + ui32_t m_Duration; + ui32_t m_BytesPerEditUnit; + + Result_t InitFromBuffer(const byte_t* p, ui32_t l, const ui64_t& body_offset, const ui64_t& essence_container_offset); + + ASDCP_NO_COPY_CONSTRUCT(AS02IndexReader); + AS02IndexReader(); + + public: + const ASDCP::Dictionary*& m_Dict; + ASDCP::IPrimerLookup *m_Lookup; + + AS02IndexReader(const ASDCP::Dictionary*&); + virtual ~AS02IndexReader(); + + Result_t InitFromFile(const Kumu::FileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence); + ui32_t GetDuration() const; + void Dump(FILE* = 0); + Result_t GetMDObjectByID(const Kumu::UUID&, ASDCP::MXF::InterchangeObject** = 0); + Result_t GetMDObjectByType(const byte_t*, ASDCP::MXF::InterchangeObject** = 0); + Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList); + Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const; + }; + + + // Returns size in bytes of a single sample of data described by ADesc + inline ui32_t CalcSampleSize(const ASDCP::MXF::WaveAudioDescriptor& d) + { + return (d.QuantizationBits / 8) * d.ChannelCount; + } + + // Returns number of samples per frame of data described by ADesc + inline ui32_t CalcSamplesPerFrame(const ASDCP::MXF::WaveAudioDescriptor& d, const ASDCP::Rational& edit_rate) + { + double tmpd = d.AudioSamplingRate.Quotient() / edit_rate.Quotient(); + return (ui32_t)ceil(tmpd); + } + + // Returns the size in bytes of a frame of data described by ADesc + inline ui32_t CalcFrameBufferSize(const ASDCP::MXF::WaveAudioDescriptor& d, const ASDCP::Rational& edit_rate) + { + return CalcSampleSize(d) * CalcSamplesPerFrame(d, edit_rate); + } + + // Returns number of frames for data described by ADesc, given a duration in samples and an edit rate + inline ui32_t CalcFramesFromDurationInSamples(const ui32_t duration_samples, const ASDCP::MXF::WaveAudioDescriptor& d, + const ASDCP::Rational& edit_rate) + { + ui32_t spf = CalcSamplesPerFrame(d, edit_rate); + ui32_t frames = duration_samples / spf; + + if ( duration_samples % spf != 0 ) + { + ++frames; + } + + return frames; + } + + } // namespace MXF + + + // IMF App 2 edit rates not already exposed in namespace ASDCP + const ASDCP::Rational EditRate_29_97 = ASDCP::Rational(30000, 1001); + const ASDCP::Rational EditRate_59_94 = ASDCP::Rational(60000, 1001); + + //--------------------------------------------------------------------------------- + // Accessors in the MXFReader and MXFWriter classes below return these types to + // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h + + // See ST 2067-5 Sec. x.y.z + enum IndexStrategy_t + { + IS_LEAD, + IS_FOLLOW, + IS_FILE_SPECIFIC, + IS_MAX + }; + + namespace JP2K + { + // + class MXFWriter + { + class h__Writer; + ASDCP::mem_ptr<h__Writer> m_Writer; + ASDCP_NO_COPY_CONSTRUCT(MXFWriter); + + public: + MXFWriter(); + virtual ~MXFWriter(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual ASDCP::MXF::OP1aHeader& OP1aHeader(); + virtual ASDCP::MXF::RIP& RIP(); + + // Open the file for writing. The file must not exist. Returns error if + // the operation cannot be completed or if nonsensical data is discovered + // in the essence descriptor. + Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const ASDCP::Rational& edit_rate, const ui32_t& header_size = 16384, + const IndexStrategy_t& strategy = IS_FOLLOW, const ui32_t& partition_space = 10); + + // Writes a frame of essence to the MXF file. If the optional AESEncContext + // argument is present, the essence is encrypted prior to writing. + // Fails if the file is not open, is finalized, or an operating system + // error occurs. + Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0); + + // Closes the MXF file, writing the index and revised header. + Result_t Finalize(); + }; + + // + class MXFReader + { + class h__Reader; + ASDCP::mem_ptr<h__Reader> m_Reader; + ASDCP_NO_COPY_CONSTRUCT(MXFReader); + + public: + MXFReader(); + virtual ~MXFReader(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual ASDCP::MXF::OP1aHeader& OP1aHeader(); + virtual AS_02::MXF::AS02IndexReader& AS02IndexReader(); + virtual ASDCP::MXF::RIP& RIP(); + + // Open the file for reading. The file must exist. Returns error if the + // operation cannot be completed. + Result_t OpenRead(const std::string& filename) const; + + // Returns RESULT_INIT if the file is not open. + Result_t Close() const; + + // Fill a WriterInfo struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillWriterInfo(ASDCP::WriterInfo&) const; + + // Reads a frame of essence from the MXF file. If the optional AESEncContext + // argument is present, the essence is decrypted after reading. If the MXF + // file is encrypted and the AESDecContext argument is NULL, the frame buffer + // will contain the ciphertext frame data. If the HMACContext argument is + // not NULL, the HMAC will be calculated (if the file supports it). + // Returns RESULT_INIT if the file is not open, failure if the frame number is + // out of range, or if optional decrypt or HAMC operations fail. + Result_t ReadFrame(ui32_t frame_number, ASDCP::JP2K::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const; + + // Print debugging information to stream + void DumpHeaderMetadata(FILE* = 0) const; + void DumpIndex(FILE* = 0) const; + }; + + } //namespace JP2K + + + //--------------------------------------------------------------------------------- + // + namespace PCM + { + // see AS_DCP.h for related data types + + // An AS-02 PCM file is clip-wrapped, but the interface defined below mimics that used + // for frame-wrapped essence elsewhere in this library. The concept of frame rate + // therefore is only relevant to these classes and is not reflected in or affected by + // the contents of the MXF file. The frame rate that is set on the writer is only + // for compatibility with the existing parsers, samples are packed contiguously into + // the same clip-wrapped packet. Similarly, the edit rate must be set when initializing + // the reader to signal the number of samples to be read by each call to ReadFrame(); + + // + class MXFWriter + { + class h__Writer; + ASDCP::mem_ptr<h__Writer> m_Writer; + ASDCP_NO_COPY_CONSTRUCT(MXFWriter); + + public: + MXFWriter(); + virtual ~MXFWriter(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual ASDCP::MXF::OP1aHeader& OP1aHeader(); + virtual ASDCP::MXF::RIP& RIP(); + + // Open the file for writing. The file must not exist. Returns error if + // the operation cannot be completed or if nonsensical data is discovered + // in the essence descriptor. + Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const ASDCP::Rational& edit_rate, ui32_t HeaderSize = 16384); + + // Writes a frame of essence to the MXF file. If the optional AESEncContext + // argument is present, the essence is encrypted prior to writing. + // Fails if the file is not open, is finalized, or an operating system + // error occurs. + Result_t WriteFrame(const ASDCP::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0); + + // Closes the MXF file, writing the index and revised header. + Result_t Finalize(); + }; + + // + class MXFReader + { + class h__Reader; + ASDCP::mem_ptr<h__Reader> m_Reader; + ASDCP_NO_COPY_CONSTRUCT(MXFReader); + + public: + MXFReader(); + virtual ~MXFReader(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual ASDCP::MXF::OP1aHeader& OP1aHeader(); + virtual AS_02::MXF::AS02IndexReader& AS02IndexReader(); + virtual ASDCP::MXF::RIP& RIP(); + + // Open the file for reading. The file must exist. Returns error if the + // operation cannot be completed. + Result_t OpenRead(const std::string& filename, const ASDCP::Rational& EditRate); + + // Returns RESULT_INIT if the file is not open. + Result_t Close() const; + + // Fill a WriterInfo struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillWriterInfo(ASDCP::WriterInfo&) const; + + // Reads a frame of essence from the MXF file. If the optional AESEncContext + // argument is present, the essence is decrypted after reading. If the MXF + // file is encrypted and the AESDecContext argument is NULL, the frame buffer + // will contain the ciphertext frame data. If the HMACContext argument is + // not NULL, the HMAC will be calculated (if the file supports it). + // Returns RESULT_INIT if the file is not open, failure if the frame number is + // out of range, or if optional decrypt or HAMC operations fail. + Result_t ReadFrame(ui32_t frame_number, ASDCP::PCM::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const; + + // Print debugging information to stream + void DumpHeaderMetadata(FILE* = 0) const; + void DumpIndex(FILE* = 0) const; + }; + } // namespace PCM + + //--------------------------------------------------------------------------------- + // + namespace TimedText + { + using ASDCP::TimedText::TimedTextDescriptor; + using ASDCP::TimedText::TimedTextResourceDescriptor; + using ASDCP::TimedText::ResourceList_t; + + // + class Type5UUIDFilenameResolver : public ASDCP::TimedText::IResourceResolver + { + typedef std::map<Kumu::UUID, std::string> ResourceMap; + + ResourceMap m_ResourceMap; + std::string m_Dirname; + KM_NO_COPY_CONSTRUCT(Type5UUIDFilenameResolver); + + public: + Type5UUIDFilenameResolver(); + virtual ~Type5UUIDFilenameResolver(); + Result_t OpenRead(const std::string& dirname); + Result_t ResolveRID(const byte_t* uuid, ASDCP::TimedText::FrameBuffer& FrameBuf) const; + }; + + // + class ST2052_TextParser + { + class h__TextParser; + ASDCP::mem_ptr<h__TextParser> m_Parser; + ASDCP_NO_COPY_CONSTRUCT(ST2052_TextParser); + + public: + ST2052_TextParser(); + virtual ~ST2052_TextParser(); + + // Opens an XML file for reading, parses data to provide a complete + // set of stream metadata for the MXFWriter below. + Result_t OpenRead(const std::string& filename) const; + + // Parse an XML string + Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const; + + // Fill a TimedTextDescriptor struct with the values from the file's contents. + // Returns RESULT_INIT if the file is not open. + Result_t FillTimedTextDescriptor(ASDCP::TimedText::TimedTextDescriptor&) const; + + // Reads the complete Timed Text Resource into the given string. + Result_t ReadTimedTextResource(std::string&) const; + + // Reads the Ancillary Resource having the given ID. Fails if the buffer + // is too small or the resource does not exist. The optional Resolver + // argument can be provided which will be used to retrieve the resource + // having a particulat UUID. If a Resolver is not supplied, the default + // internal resolver will return the contents of the file having the UUID + // as the filename. The filename must exist in the same directory as the + // XML file opened with OpenRead(). + Result_t ReadAncillaryResource(const Kumu::UUID&, ASDCP::TimedText::FrameBuffer&, + const ASDCP::TimedText::IResourceResolver* Resolver = 0) const; + }; + + // + class MXFWriter + { + class h__Writer; + ASDCP::mem_ptr<h__Writer> m_Writer; + ASDCP_NO_COPY_CONSTRUCT(MXFWriter); + + public: + MXFWriter(); + virtual ~MXFWriter(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual ASDCP::MXF::OP1aHeader& OP1aHeader(); + virtual ASDCP::MXF::RIP& RIP(); + + // Open the file for writing. The file must not exist. Returns error if + // the operation cannot be completed or if nonsensical data is discovered + // in the essence descriptor. + Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&, + const ASDCP::TimedText::TimedTextDescriptor&, ui32_t HeaderSize = 16384); + + // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8 + // encoded. If the optional AESEncContext argument is present, the essence + // is encrypted prior to writing. Fails if the file is not open, is finalized, + // or an operating system error occurs. + // This method may only be called once, and it must be called before any + // call to WriteAncillaryResource(). RESULT_STATE will be returned if these + // conditions are not met. + Result_t WriteTimedTextResource(const std::string& XMLDoc, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0); + + // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext + // argument is present, the essence is encrypted prior to writing. + // Fails if the file is not open, is finalized, or an operating system + // error occurs. RESULT_STATE will be returned if the method is called before + // WriteTimedTextResource() + Result_t WriteAncillaryResource(const ASDCP::TimedText::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0); + + // Closes the MXF file, writing the index and revised header. + Result_t Finalize(); + }; + + // + class MXFReader + { + class h__Reader; + ASDCP::mem_ptr<h__Reader> m_Reader; + ASDCP_NO_COPY_CONSTRUCT(MXFReader); + + public: + MXFReader(); + virtual ~MXFReader(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual ASDCP::MXF::OP1aHeader& OP1aHeader(); + virtual AS_02::MXF::AS02IndexReader& AS02IndexReader(); + virtual ASDCP::MXF::RIP& RIP(); + + // Open the file for reading. The file must exist. Returns error if the + // operation cannot be completed. + Result_t OpenRead(const std::string& filename) const; + + // Returns RESULT_INIT if the file is not open. + Result_t Close() const; + + // Fill a TimedTextDescriptor struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillTimedTextDescriptor(ASDCP::TimedText::TimedTextDescriptor&) const; + + // Fill a WriterInfo struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillWriterInfo(ASDCP::WriterInfo&) const; + + // Reads the complete Timed Text Resource into the given string. Fails if the resource + // is encrypted and AESDecContext is NULL (use the following method to retrieve the + // raw ciphertet block). + Result_t ReadTimedTextResource(std::string&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const; + + // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext + // argument is present, the resource is decrypted after reading. If the MXF + // file is encrypted and the AESDecContext argument is NULL, the frame buffer + // will contain the ciphertext frame data. If the HMACContext argument is + // not NULL, the HMAC will be calculated (if the file supports it). + // Returns RESULT_INIT if the file is not open, failure if the frame number is + // out of range, or if optional decrypt or HAMC operations fail. + Result_t ReadTimedTextResource(ASDCP::TimedText::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const; + + // Reads the timed-text resource having the given UUID from the MXF file. If the + // optional AESEncContext argument is present, the resource is decrypted after + // reading. If the MXF file is encrypted and the AESDecContext argument is NULL, + // the frame buffer will contain the ciphertext frame data. If the HMACContext + // argument is not NULL, the HMAC will be calculated (if the file supports it). + // Returns RESULT_INIT if the file is not open, failure if the frame number is + // out of range, or if optional decrypt or HAMC operations fail. + Result_t ReadAncillaryResource(const Kumu::UUID&, ASDCP::TimedText::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const; + + // Print debugging information to stream + void DumpHeaderMetadata(FILE* = 0) const; + void DumpIndex(FILE* = 0) const; + }; + } // namespace TimedText + + +} // namespace AS_02 + +#endif // _AS_02_H_ + +// +// end AS_02.h +// diff --git a/asdcplib/src/AS_02_JP2K.cpp b/asdcplib/src/AS_02_JP2K.cpp new file mode 100644 index 00000000..dc1c7cee --- /dev/null +++ b/asdcplib/src/AS_02_JP2K.cpp @@ -0,0 +1,497 @@ +/* +Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_02_JP2K.cpp + \version $Id: AS_02_JP2K.cpp,v 1.14 2014/09/21 13:27:43 jhurst Exp $ + \brief AS-02 library, JPEG 2000 essence reader and writer implementation +*/ + +#include "AS_02_internal.h" + +#include <iostream> +#include <iomanip> + +using namespace ASDCP; +using namespace ASDCP::JP2K; +using Kumu::GenRandomValue; + +//------------------------------------------------------------------------------------------ + +static std::string JP2K_PACKAGE_LABEL = "File Package: SMPTE ST 422 / ST 2067-5 frame wrapping of JPEG 2000 codestreams"; +static std::string PICT_DEF_LABEL = "Image Track"; + +//------------------------------------------------------------------------------------------ +// +// hidden, internal implementation of JPEG 2000 reader + + +class AS_02::JP2K::MXFReader::h__Reader : public AS_02::h__AS02Reader +{ + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + +public: + h__Reader(const Dictionary& d) : + AS_02::h__AS02Reader(d) {} + + virtual ~h__Reader() {} + + Result_t OpenRead(const std::string&); + Result_t ReadFrame(ui32_t, ASDCP::JP2K::FrameBuffer&, AESDecContext*, HMACContext*); +}; + +// +Result_t +AS_02::JP2K::MXFReader::h__Reader::OpenRead(const std::string& filename) +{ + Result_t result = OpenMXFRead(filename.c_str()); + + if( KM_SUCCESS(result) ) + { + InterchangeObject* tmp_iobj = 0; + + m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CDCIEssenceDescriptor), &tmp_iobj); + + if ( tmp_iobj == 0 ) + { + m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor), &tmp_iobj); + } + + if ( tmp_iobj == 0 ) + { + DefaultLogSink().Error("RGBAEssenceDescriptor nor CDCIEssenceDescriptor found.\n"); + } + + m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor), &tmp_iobj); + + if ( tmp_iobj == 0 ) + { + DefaultLogSink().Error("JPEG2000PictureSubDescriptor not found.\n"); + } + + std::list<InterchangeObject*> ObjectList; + m_HeaderPart.GetMDObjectsByType(OBJ_TYPE_ARGS(Track), ObjectList); + + if ( ObjectList.empty() ) + { + DefaultLogSink().Error("MXF Metadata contains no Track Sets.\n"); + return RESULT_AS02_FORMAT; + } + } + + return result; +} + +// +// +Result_t +AS_02::JP2K::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf, + ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) +{ + if ( ! m_File.IsOpen() ) + return RESULT_INIT; + + assert(m_Dict); + return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_JPEG2000Essence), Ctx, HMAC); +} + +//------------------------------------------------------------------------------------------ +// + +AS_02::JP2K::MXFReader::MXFReader() +{ + m_Reader = new h__Reader(DefaultCompositeDict()); +} + + +AS_02::JP2K::MXFReader::~MXFReader() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +AS_02::JP2K::MXFReader::OP1aHeader() +{ + if ( m_Reader.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Reader->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +AS_02::MXF::AS02IndexReader& +AS_02::JP2K::MXFReader::AS02IndexReader() +{ + if ( m_Reader.empty() ) + { + assert(g_AS02IndexReader); + return *g_AS02IndexReader; + } + + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +AS_02::JP2K::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; +} + +// Open the file for reading. The file must exist. Returns error if the +// operation cannot be completed. +Result_t +AS_02::JP2K::MXFReader::OpenRead(const std::string& filename) const +{ + return m_Reader->OpenRead(filename); +} + +// +Result_t +AS_02::JP2K::MXFReader::Close() const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + m_Reader->Close(); + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +Result_t +AS_02::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::JP2K::FrameBuffer& FrameBuf, + ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +Result_t +AS_02::JP2K::MXFReader::FillWriterInfo(WriterInfo& Info) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + Info = m_Reader->m_Info; + return RESULT_OK; + } + + return RESULT_INIT; +} + + +//------------------------------------------------------------------------------------------ + +// +class AS_02::JP2K::MXFWriter::h__Writer : public AS_02::h__AS02WriterFrame +{ + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); + + JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor; + +public: + byte_t m_EssenceUL[SMPTE_UL_LENGTH]; + + h__Writer(const Dictionary& d) : h__AS02WriterFrame(d), m_EssenceSubDescriptor(0) { + memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); + } + + virtual ~h__Writer(){} + + Result_t OpenWrite(const std::string&, ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const AS_02::IndexStrategy_t& IndexStrategy, + const ui32_t& PartitionSpace, const ui32_t& HeaderSize); + Result_t SetSourceStream(const std::string& label, const ASDCP::Rational& edit_rate); + Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, ASDCP::AESEncContext*, ASDCP::HMACContext*); + Result_t Finalize(); +}; + + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +Result_t +AS_02::JP2K::MXFWriter::h__Writer::OpenWrite(const std::string& filename, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const AS_02::IndexStrategy_t& IndexStrategy, + const ui32_t& PartitionSpace_sec, const ui32_t& HeaderSize) +{ + if ( ! m_State.Test_BEGIN() ) + { + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + } + + if ( m_IndexStrategy != AS_02::IS_FOLLOW ) + { + DefaultLogSink().Error("Only strategy IS_FOLLOW is supported at this time.\n"); + return Kumu::RESULT_NOTIMPL; + } + + Result_t result = m_File.OpenWrite(filename.c_str()); + + if ( KM_SUCCESS(result) ) + { + m_IndexStrategy = IndexStrategy; + m_PartitionSpace = PartitionSpace_sec; // later converted to edit units by SetSourceStream() + m_HeaderSize = HeaderSize; + + if ( essence_descriptor->GetUL() != UL(m_Dict->ul(MDD_RGBAEssenceDescriptor)) + && essence_descriptor->GetUL() != UL(m_Dict->ul(MDD_CDCIEssenceDescriptor)) ) + { + DefaultLogSink().Error("Essence descriptor is not a RGBAEssenceDescriptor or CDCIEssenceDescriptor.\n"); + essence_descriptor->Dump(); + return RESULT_AS02_FORMAT; + } + + m_EssenceDescriptor = essence_descriptor; + + ASDCP::MXF::InterchangeObject_list_t::iterator i; + for ( i = essence_sub_descriptor_list.begin(); i != essence_sub_descriptor_list.end(); ++i ) + { + if ( (*i)->GetUL() != UL(m_Dict->ul(MDD_JPEG2000PictureSubDescriptor)) ) + { + DefaultLogSink().Error("Essence sub-descriptor is not a JPEG2000PictureSubDescriptor.\n"); + (*i)->Dump(); + } + + m_EssenceSubDescriptorList.push_back(*i); + GenRandomValue((*i)->InstanceUID); + m_EssenceDescriptor->SubDescriptors.push_back((*i)->InstanceUID); + *i = 0; // parent will only free the ones we don't keep + } + + result = m_State.Goto_INIT(); + } + + return result; +} + +// Automatically sets the MXF file's metadata from the first jpeg codestream stream. +Result_t +AS_02::JP2K::MXFWriter::h__Writer::SetSourceStream(const std::string& label, const ASDCP::Rational& edit_rate) +{ + assert(m_Dict); + if ( ! m_State.Test_INIT() ) + { + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + } + + memcpy(m_EssenceUL, m_Dict->ul(MDD_JPEG2000Essence), SMPTE_UL_LENGTH); + m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container + Result_t result = m_State.Goto_READY(); + + if ( KM_SUCCESS(result) ) + { + result = WriteAS02Header(label, UL(m_Dict->ul(MDD_JPEG_2000WrappingFrame)), + PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)), + edit_rate, derive_timecode_rate_from_edit_rate(edit_rate)); + + if ( KM_SUCCESS(result) ) + { + this->m_IndexWriter.SetPrimerLookup(&this->m_HeaderPart.m_Primer); + } + } + + return result; +} + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +// +Result_t +AS_02::JP2K::MXFWriter::h__Writer::WriteFrame(const ASDCP::JP2K::FrameBuffer& FrameBuf, + AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( FrameBuf.Size() == 0 ) + { + DefaultLogSink().Error("The frame buffer size is zero.\n"); + return RESULT_PARAM; + } + + Result_t result = RESULT_OK; + + if ( m_State.Test_READY() ) + { + result = m_State.Goto_RUNNING(); // first time through + } + + if ( KM_SUCCESS(result) ) + { + result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC); + m_FramesWritten++; + } + + return result; +} + +// Closes the MXF file, writing the index and other closing information. +// +Result_t +AS_02::JP2K::MXFWriter::h__Writer::Finalize() +{ + if ( ! m_State.Test_RUNNING() ) + { + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + } + + Result_t result = m_State.Goto_FINAL(); + + if ( KM_SUCCESS(result) ) + { + result = WriteAS02Footer(); + } + + return result; +} + + +//------------------------------------------------------------------------------------------ + + + +AS_02::JP2K::MXFWriter::MXFWriter() +{ +} + +AS_02::JP2K::MXFWriter::~MXFWriter() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +AS_02::JP2K::MXFWriter::OP1aHeader() +{ + if ( m_Writer.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Writer->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +AS_02::JP2K::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +Result_t +AS_02::JP2K::MXFWriter::OpenWrite(const std::string& filename, const ASDCP::WriterInfo& Info, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const ASDCP::Rational& edit_rate, const ui32_t& header_size, + const IndexStrategy_t& strategy, const ui32_t& partition_space) +{ + if ( essence_descriptor == 0 ) + { + DefaultLogSink().Error("Essence descriptor object required.\n"); + return RESULT_PARAM; + } + + m_Writer = new AS_02::JP2K::MXFWriter::h__Writer(DefaultSMPTEDict()); + m_Writer->m_Info = Info; + + Result_t result = m_Writer->OpenWrite(filename, essence_descriptor, essence_sub_descriptor_list, + strategy, partition_space, header_size); + + if ( KM_SUCCESS(result) ) + result = m_Writer->SetSourceStream(JP2K_PACKAGE_LABEL, edit_rate); + + if ( KM_FAILURE(result) ) + m_Writer.release(); + + return result; +} + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +Result_t +AS_02::JP2K::MXFWriter::WriteFrame(const ASDCP::JP2K::FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC); +} + +// Closes the MXF file, writing the index and other closing information. +Result_t +AS_02::JP2K::MXFWriter::Finalize() +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->Finalize(); +} + + +// +// end AS_02_JP2K.cpp +// diff --git a/asdcplib/src/AS_02_PCM.cpp b/asdcplib/src/AS_02_PCM.cpp new file mode 100644 index 00000000..ec609008 --- /dev/null +++ b/asdcplib/src/AS_02_PCM.cpp @@ -0,0 +1,600 @@ +/* +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*! \file AS_02_PCM.cpp + \version $Id: AS_02_PCM.cpp,v 1.16 2015/10/07 16:41:23 jhurst Exp $ + \brief AS-02 library, PCM essence reader and writer implementation +*/ + +#include "AS_02_internal.h" + +#include <map> +#include <iostream> +#include <iomanip> + +//------------------------------------------------------------------------------------------ + +static std::string PCM_PACKAGE_LABEL = "File Package: SMPTE 382M clip wrapping of wave audio"; +static std::string SOUND_DEF_LABEL = "Sound Track"; + + +//------------------------------------------------------------------------------------------ + + +class AS_02::PCM::MXFReader::h__Reader : public AS_02::h__AS02Reader +{ + ui64_t m_ClipEssenceBegin, m_ClipSize; + ui32_t m_ClipDurationFrames, m_BytesPerFrame; + + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + h__Reader(); + +public: + h__Reader(const Dictionary& d) : AS_02::h__AS02Reader(d), m_ClipEssenceBegin(0), m_ClipSize(0), + m_ClipDurationFrames(0) {} + virtual ~h__Reader() {} + + ASDCP::Result_t OpenRead(const std::string&, const ASDCP::Rational& edit_rate); + ASDCP::Result_t ReadFrame(ui32_t, ASDCP::PCM::FrameBuffer&, ASDCP::AESDecContext*, ASDCP::HMACContext*); +}; + +// TODO: This will ignore any body partitions past the first +// +// +ASDCP::Result_t +AS_02::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename, const ASDCP::Rational& edit_rate) +{ + ASDCP::MXF::WaveAudioDescriptor* wave_descriptor = 0; + IndexTableSegment::IndexEntry tmp_entry; + Result_t result = OpenMXFRead(filename.c_str()); + + if( KM_SUCCESS(result) ) + { + InterchangeObject* tmp_obj = 0; + + if ( KM_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &tmp_obj)) ) + { + wave_descriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(tmp_obj); + } + } + + if ( wave_descriptor == 0 ) + { + DefaultLogSink().Error("WaveAudioDescriptor object not found.\n"); + result = RESULT_AS02_FORMAT; + } + + if ( KM_SUCCESS(result) ) + result = m_IndexAccess.Lookup(0, tmp_entry); + + if ( KM_SUCCESS(result) ) + result = m_File.Seek(tmp_entry.StreamOffset); + + if ( KM_SUCCESS(result) ) + { + assert(wave_descriptor); + KLReader reader; + result = reader.ReadKLFromFile(m_File); + + if ( KM_SUCCESS(result) ) + { + if ( ! UL(reader.Key()).MatchIgnoreStream(m_Dict->ul(MDD_WAVEssenceClip)) ) + { + const MDDEntry *entry = m_Dict->FindUL(reader.Key()); + + if ( entry == 0 ) + { + char buf[64]; + DefaultLogSink().Error("Essence wrapper key is not WAVEssenceClip: %s\n", UL(reader.Key()).EncodeString(buf, 64)); + } + else + { + DefaultLogSink().Error("Essence wrapper key is not WAVEssenceClip: %s\n", entry->name); + } + + return RESULT_AS02_FORMAT; + } + + if ( wave_descriptor->BlockAlign == 0 ) + { + DefaultLogSink().Error("EssenceDescriptor has corrupt BlockAlign value, unable to continue.\n"); + return RESULT_AS02_FORMAT; + } + + if ( reader.Length() % wave_descriptor->BlockAlign != 0 ) + { + DefaultLogSink().Error("Clip length is not an even multiple of BlockAlign, unable to continue.\n"); + return RESULT_AS02_FORMAT; + } + + m_ClipEssenceBegin = m_File.Tell(); + m_ClipSize = reader.Length(); + m_BytesPerFrame = AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, edit_rate); + m_ClipDurationFrames = m_ClipSize / m_BytesPerFrame; + + if ( m_ClipSize % m_BytesPerFrame > 0 ) + { + ++m_ClipDurationFrames; // there is a partial frame at the end + } + } + } + + return result; +} + +// +ASDCP::Result_t +AS_02::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBuffer& FrameBuf, + ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) +{ + if ( ! m_File.IsOpen() ) + { + return RESULT_INIT; + } + + if ( ! ( FrameNum < m_ClipDurationFrames ) ) + { + return RESULT_RANGE; + } + + assert(m_ClipEssenceBegin); + ui64_t offset = FrameNum * m_BytesPerFrame; + ui64_t position = m_ClipEssenceBegin + offset; + Result_t result = RESULT_OK; + + if ( m_File.Tell() != position ) + { + result = m_File.Seek(position); + } + + if ( KM_SUCCESS(result) ) + { + ui64_t remainder = m_ClipSize - offset; + ui32_t read_size = ( remainder < m_BytesPerFrame ) ? remainder : m_BytesPerFrame; + result = m_File.Read(FrameBuf.Data(), read_size); + + if ( KM_SUCCESS(result) ) + { + FrameBuf.Size(read_size); + + if ( read_size < FrameBuf.Capacity() ) + { + memset(FrameBuf.Data() + FrameBuf.Size(), 0, FrameBuf.Capacity() - FrameBuf.Size()); + } + } + } + + return result; +} + + +//------------------------------------------------------------------------------------------ +// + + +AS_02::PCM::MXFReader::MXFReader() +{ + m_Reader = new h__Reader(DefaultCompositeDict()); +} + +AS_02::PCM::MXFReader::~MXFReader() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +AS_02::PCM::MXFReader::OP1aHeader() +{ + if ( m_Reader.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Reader->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +AS_02::MXF::AS02IndexReader& +AS_02::PCM::MXFReader::AS02IndexReader() +{ + if ( m_Reader.empty() ) + { + assert(g_AS02IndexReader); + return *g_AS02IndexReader; + } + + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +AS_02::PCM::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; +} + +// Open the file for reading. The file must exist. Returns error if the +// operation cannot be completed. +ASDCP::Result_t +AS_02::PCM::MXFReader::OpenRead(const std::string& filename, const ASDCP::Rational& edit_rate) +{ + return m_Reader->OpenRead(filename, edit_rate); +} + +// +Result_t +AS_02::PCM::MXFReader::Close() const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + m_Reader->Close(); + return RESULT_OK; + } + + return RESULT_INIT; +} + +// Reads a frame of essence from the MXF file. If the optional AESEncContext +// argument is present, the essence is decrypted after reading. If the MXF +// file is encrypted and the AESDecContext argument is NULL, the frame buffer +// will contain the ciphertext frame data. +ASDCP::Result_t +AS_02::PCM::MXFReader::ReadFrame(ui32_t FrameNum, ASDCP::PCM::FrameBuffer& FrameBuf, + ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +AS_02::PCM::MXFReader::FillWriterInfo(WriterInfo& Info) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + Info = m_Reader->m_Info; + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +void +AS_02::PCM::MXFReader::DumpHeaderMetadata(FILE* stream) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + m_Reader->m_HeaderPart.Dump(stream); +} + + +// +void +AS_02::PCM::MXFReader::DumpIndex(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_IndexAccess.Dump(stream); +} + + +//------------------------------------------------------------------------------------------ + +// +class AS_02::PCM::MXFWriter::h__Writer : public AS_02::h__AS02WriterClip +{ + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); + +public: + ASDCP::MXF::WaveAudioDescriptor *m_WaveAudioDescriptor; + byte_t m_EssenceUL[SMPTE_UL_LENGTH]; + ui32_t m_BytesPerSample; + + h__Writer(const Dictionary& d) : AS_02::h__AS02WriterClip(d), m_WaveAudioDescriptor(0), m_BytesPerSample(0) + { + memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); + } + + virtual ~h__Writer(){} + + Result_t OpenWrite(const std::string&, ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, const ui32_t& header_size); + Result_t SetSourceStream(const ASDCP::Rational&); + Result_t WriteFrame(const FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0); + Result_t Finalize(); +}; + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +ASDCP::Result_t +AS_02::PCM::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, const ui32_t& header_size) +{ + assert(essence_descriptor); + + m_WaveAudioDescriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(essence_descriptor); + + if ( m_WaveAudioDescriptor == 0 ) + { + DefaultLogSink().Error("Essence descriptor is not a WaveAudioDescriptor.\n"); + essence_descriptor->Dump(); + return RESULT_AS02_FORMAT; + } + + if ( ! m_State.Test_BEGIN() ) + { + return RESULT_STATE; + } + + Result_t result = m_File.OpenWrite(filename.c_str()); + + if ( KM_SUCCESS(result) ) + { + m_HeaderSize = header_size; + m_EssenceDescriptor = essence_descriptor; + m_WaveAudioDescriptor->SampleRate = m_WaveAudioDescriptor->AudioSamplingRate; + + ASDCP::MXF::InterchangeObject_list_t::iterator i; + for ( i = essence_sub_descriptor_list.begin(); i != essence_sub_descriptor_list.end(); ++i ) + { + if ( (*i)->GetUL() != UL(m_Dict->ul(MDD_AudioChannelLabelSubDescriptor)) + && (*i)->GetUL() != UL(m_Dict->ul(MDD_SoundfieldGroupLabelSubDescriptor)) + && (*i)->GetUL() != UL(m_Dict->ul(MDD_GroupOfSoundfieldGroupsLabelSubDescriptor)) ) + { + DefaultLogSink().Error("Essence sub-descriptor is not an MCALabelSubDescriptor.\n"); + (*i)->Dump(); + } + + m_EssenceSubDescriptorList.push_back(*i); + GenRandomValue((*i)->InstanceUID); + m_EssenceDescriptor->SubDescriptors.push_back((*i)->InstanceUID); + *i = 0; // parent will only free the ones we don't keep + } + + result = m_State.Goto_INIT(); + } + + return result; +} + + +// Automatically sets the MXF file's metadata from the WAV parser info. +ASDCP::Result_t +AS_02::PCM::MXFWriter::h__Writer::SetSourceStream(const ASDCP::Rational& edit_rate) +{ + if ( ! m_State.Test_INIT() ) + { + return RESULT_STATE; + } + + memcpy(m_EssenceUL, m_Dict->ul(MDD_WAVEssenceClip), SMPTE_UL_LENGTH); + m_EssenceUL[15] = 1; // set the stream identifier + Result_t result = m_State.Goto_READY(); + + if ( KM_SUCCESS(result) ) + { + assert(m_WaveAudioDescriptor); + m_BytesPerSample = AS_02::MXF::CalcSampleSize(*m_WaveAudioDescriptor); + result = WriteAS02Header(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrappingClip)), + SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)), + m_EssenceDescriptor->SampleRate, derive_timecode_rate_from_edit_rate(edit_rate)); + + if ( KM_SUCCESS(result) ) + { + this->m_IndexWriter.SetEditRate(m_WaveAudioDescriptor->AudioSamplingRate, + AS_02::MXF::CalcSampleSize(*m_WaveAudioDescriptor)); + } + } + + return result; +} + + +// +// +ASDCP::Result_t +AS_02::PCM::MXFWriter::h__Writer::WriteFrame(const FrameBuffer& frame_buf, AESEncContext* Ctx, + HMACContext* HMAC) +{ + if ( frame_buf.Size() == 0 ) + { + DefaultLogSink().Error("The frame buffer size is zero.\n"); + return RESULT_PARAM; + } + + Result_t result = RESULT_OK; + + if ( m_State.Test_READY() ) + { + result = m_State.Goto_RUNNING(); // first time through + } + + if ( KM_SUCCESS(result) && ! HasOpenClip() ) + { + result = StartClip(m_EssenceUL, Ctx, HMAC); + } + + if ( KM_SUCCESS(result) ) + { + result = WriteClipBlock(frame_buf); + } + + if ( KM_SUCCESS(result) ) + { + m_FramesWritten += frame_buf.Size() / m_BytesPerSample; + } + + return result; +} + +// Closes the MXF file, writing the index and other closing information. +// +ASDCP::Result_t +AS_02::PCM::MXFWriter::h__Writer::Finalize() +{ + if ( ! m_State.Test_RUNNING() ) + return RESULT_STATE; + + m_State.Goto_FINAL(); + + Result_t result = FinalizeClip(AS_02::MXF::CalcSampleSize(*m_WaveAudioDescriptor)); + + if ( KM_SUCCESS(result) ) + { + m_WaveAudioDescriptor->ContainerDuration = m_IndexWriter.m_Duration = m_FramesWritten; + WriteAS02Footer(); + } + + return result; +} + + +//------------------------------------------------------------------------------------------ +// + + + +AS_02::PCM::MXFWriter::MXFWriter() +{ +} + +AS_02::PCM::MXFWriter::~MXFWriter() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +AS_02::PCM::MXFWriter::OP1aHeader() +{ + if ( m_Writer.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Writer->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +AS_02::PCM::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +ASDCP::Result_t +AS_02::PCM::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const ASDCP::Rational& edit_rate, ui32_t header_size) +{ + if ( essence_descriptor == 0 ) + { + DefaultLogSink().Error("Essence descriptor object required.\n"); + return RESULT_PARAM; + } + + if ( Info.EncryptedEssence ) + { + DefaultLogSink().Error("Encryption not supported for ST 382 clip-wrap.\n"); + return Kumu::RESULT_NOTIMPL; + } + + m_Writer = new h__Writer(DefaultSMPTEDict()); + m_Writer->m_Info = Info; + + Result_t result = m_Writer->OpenWrite(filename, essence_descriptor, essence_sub_descriptor_list, header_size); + + if ( KM_SUCCESS(result) ) + result = m_Writer->SetSourceStream(edit_rate); + + if ( ASDCP_FAILURE(result) ) + m_Writer.release(); + + return result; +} + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +ASDCP::Result_t +AS_02::PCM::MXFWriter::WriteFrame(const FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC); +} + +// Closes the MXF file, writing the index and other closing information. +ASDCP::Result_t +AS_02::PCM::MXFWriter::Finalize() +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->Finalize(); +} + + + +// +// end AS_02_PCM.cpp +// + diff --git a/asdcplib/src/AS_02_PHDR.cpp b/asdcplib/src/AS_02_PHDR.cpp new file mode 100644 index 00000000..4dbbb21c --- /dev/null +++ b/asdcplib/src/AS_02_PHDR.cpp @@ -0,0 +1,776 @@ +/* +Copyright (c) 2011-2015, John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_02_PHDR.cpp + \version $Id: AS_02_PHDR.cpp,v 1.7 2015/10/09 23:41:11 jhurst Exp $ + \brief AS-02 library, JPEG 2000 P-HDR essence reader and writer implementation +*/ + +#include "AS_02_internal.h" +#include "AS_02_PHDR.h" + +#include <iostream> +#include <iomanip> + +using namespace ASDCP; +using namespace ASDCP::JP2K; +using Kumu::GenRandomValue; + +//------------------------------------------------------------------------------------------ + +static std::string JP2K_PACKAGE_LABEL = "File Package: PROTOTYPE SMPTE ST 422 / ST 2067-5 frame wrapping of JPEG 2000 codestreams with HDR metadata"; +static std::string PICT_DEF_LABEL = "PHDR Image Track"; +static std::string MD_DEF_LABEL = "PHDR Metadata Track"; + + + +//------------------------------------------------------------------------------------------ + +// +void +AS_02::PHDR::FrameBuffer::Dump(FILE* stream, ui32_t dump_bytes) const +{ + if ( stream == 0 ) + stream = stderr; + + fprintf(stream, "Frame %d, %d bytes (metadata: %zd bytes)\n", FrameNumber(), Size(), OpaqueMetadata.size()); + + if ( dump_bytes > 0 ) + { + Kumu::hexdump(RoData(), Kumu::xmin(dump_bytes, Size()), stream); + } +} + + +//------------------------------------------------------------------------------------------ +// +// hidden, internal implementation of JPEG 2000 reader + + +class AS_02::PHDR::MXFReader::h__Reader : public AS_02::h__AS02Reader +{ + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + +public: + h__Reader(const Dictionary& d) : + AS_02::h__AS02Reader(d) {} + + virtual ~h__Reader() {} + + Result_t OpenRead(const std::string& filename, std::string& PHDR_master_metadata); + Result_t ReadFrame(ui32_t, AS_02::PHDR::FrameBuffer&, AESDecContext*, HMACContext*); +}; + +// +Result_t +AS_02::PHDR::MXFReader::h__Reader::OpenRead(const std::string& filename, std::string& PHDR_master_metadata) +{ + Result_t result = OpenMXFRead(filename.c_str()); + ui32_t SimplePayloadSID = 0; + + if( KM_SUCCESS(result) ) + { + InterchangeObject* tmp_iobj = 0; + + m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CDCIEssenceDescriptor), &tmp_iobj); + + if ( tmp_iobj == 0 ) + { + m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor), &tmp_iobj); + } + + if ( tmp_iobj == 0 ) + { + DefaultLogSink().Error("RGBAEssenceDescriptor nor CDCIEssenceDescriptor found.\n"); + return RESULT_AS02_FORMAT; + } + + m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor), &tmp_iobj); + + if ( tmp_iobj == 0 ) + { + DefaultLogSink().Error("JPEG2000PictureSubDescriptor not found.\n"); + return RESULT_AS02_FORMAT; + } + + m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(PHDRMetadataTrackSubDescriptor), &tmp_iobj); + + if ( tmp_iobj == 0 ) + { + DefaultLogSink().Error("PHDRMetadataTrackSubDescriptor not found.\n"); + return RESULT_AS02_FORMAT; + } + else + { + PHDRMetadataTrackSubDescriptor *tmp_desc = dynamic_cast<PHDRMetadataTrackSubDescriptor*>(tmp_iobj); + assert(tmp_desc); + SimplePayloadSID = tmp_desc->SimplePayloadSID; + } + + std::list<InterchangeObject*> ObjectList; + m_HeaderPart.GetMDObjectsByType(OBJ_TYPE_ARGS(Track), ObjectList); + + if ( ObjectList.empty() ) + { + DefaultLogSink().Error("MXF Metadata contains no Track Sets.\n"); + return RESULT_AS02_FORMAT; + } + } + + // if PHDRSimplePayload exists, go get it + if ( KM_SUCCESS(result) && SimplePayloadSID ) + { + RIP::const_pair_iterator pi; + RIP::PartitionPair TmpPair; + + // Look up the partition start in the RIP using the SID. + for ( pi = m_RIP.PairArray.begin(); pi != m_RIP.PairArray.end(); ++pi ) + { + if ( (*pi).BodySID == SimplePayloadSID ) + { + TmpPair = *pi; + break; + } + } + + if ( TmpPair.ByteOffset == 0 ) + { + DefaultLogSink().Error("Body SID not found in RIP set: %d\n", SimplePayloadSID); + return RESULT_AS02_FORMAT; + } + + // seek to the start of the partition + if ( (Kumu::fpos_t)TmpPair.ByteOffset != m_LastPosition ) + { + m_LastPosition = TmpPair.ByteOffset; + result = m_File.Seek(TmpPair.ByteOffset); + } + + // read the partition header + ASDCP::MXF::Partition GSPart(m_Dict); + result = GSPart.InitFromFile(m_File); + + if ( KM_SUCCESS(result) ) + { + // read the generic stream packet + if ( KM_SUCCESS(result) ) + { + ASDCP::FrameBuffer tmp_buf; + tmp_buf.Capacity(Kumu::Megabyte); + + result = Read_EKLV_Packet(m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, + 0, 0, tmp_buf, m_Dict->ul(MDD_GenericStream_DataElement), 0, 0); + + if ( KM_SUCCESS(result) ) + { + PHDR_master_metadata.assign((const char*)tmp_buf.RoData(), tmp_buf.Size()); + } + } + } + } + + return result; +} + +// +// +Result_t +AS_02::PHDR::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, AS_02::PHDR::FrameBuffer& FrameBuf, + ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) +{ + if ( ! m_File.IsOpen() ) + return RESULT_INIT; + + assert(m_Dict); + Result_t result = ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_JPEG2000Essence), Ctx, HMAC); + + if ( KM_SUCCESS(result) ) + { + ASDCP::FrameBuffer tmp_metadata_buffer; + tmp_metadata_buffer.Capacity(8192); + + result = Read_EKLV_Packet(m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, + FrameNum, FrameNum + 1, tmp_metadata_buffer, m_Dict->ul(MDD_PHDRImageMetadataItem), Ctx, HMAC); + + if ( KM_SUCCESS(result) ) + { + FrameBuf.OpaqueMetadata.assign((const char*)tmp_metadata_buffer.RoData(), tmp_metadata_buffer.Size()); + } + else + { + DefaultLogSink().Error("Metadata packet not found at frame %d.\n", FrameNum); + result = RESULT_OK; + } + } + + return result; +} + +//------------------------------------------------------------------------------------------ +// + +AS_02::PHDR::MXFReader::MXFReader() +{ + m_Reader = new h__Reader(DefaultCompositeDict()); +} + + +AS_02::PHDR::MXFReader::~MXFReader() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +AS_02::PHDR::MXFReader::OP1aHeader() +{ + if ( m_Reader.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Reader->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +AS_02::MXF::AS02IndexReader& +AS_02::PHDR::MXFReader::AS02IndexReader() +{ + if ( m_Reader.empty() ) + { + assert(g_AS02IndexReader); + return *g_AS02IndexReader; + } + + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +AS_02::PHDR::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; +} + +// Open the file for reading. The file must exist. Returns error if the +// operation cannot be completed. +Result_t +AS_02::PHDR::MXFReader::OpenRead(const std::string& filename, std::string& PHDR_master_metadata) const +{ + return m_Reader->OpenRead(filename, PHDR_master_metadata); +} + +// +Result_t +AS_02::PHDR::MXFReader::Close() const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + m_Reader->Close(); + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +Result_t +AS_02::PHDR::MXFReader::ReadFrame(ui32_t FrameNum, AS_02::PHDR::FrameBuffer& FrameBuf, + ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +Result_t +AS_02::PHDR::MXFReader::FillWriterInfo(WriterInfo& Info) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + Info = m_Reader->m_Info; + return RESULT_OK; + } + + return RESULT_INIT; +} + + +//------------------------------------------------------------------------------------------ + +// +class AS_02::PHDR::MXFWriter::h__Writer : public AS_02::h__AS02WriterFrame +{ + PHDRMetadataTrackSubDescriptor *m_MetadataTrackSubDescriptor; + + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); + + JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor; + + Result_t WritePHDRHeader(const std::string& PackageLabel, const ASDCP::UL& WrappingUL, + const std::string& TrackName, const ASDCP::UL& EssenceUL, + const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate, + const ui32_t& TCFrameRate); + +public: + byte_t m_EssenceUL[SMPTE_UL_LENGTH]; + byte_t m_MetadataUL[SMPTE_UL_LENGTH]; + + h__Writer(const Dictionary& d) : h__AS02WriterFrame(d), m_EssenceSubDescriptor(0), m_MetadataTrackSubDescriptor(0) { + memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); + memset(m_MetadataUL, 0, SMPTE_UL_LENGTH); + } + + virtual ~h__Writer(){} + + Result_t OpenWrite(const std::string&, ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const AS_02::IndexStrategy_t& IndexStrategy, + const ui32_t& PartitionSpace, const ui32_t& HeaderSize); + Result_t SetSourceStream(const std::string& label, const ASDCP::Rational& edit_rate); + Result_t WriteFrame(const AS_02::PHDR::FrameBuffer&, ASDCP::AESEncContext*, ASDCP::HMACContext*); + Result_t Finalize(const std::string& PHDR_master_metadata); +}; + + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +Result_t +AS_02::PHDR::MXFWriter::h__Writer::OpenWrite(const std::string& filename, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const AS_02::IndexStrategy_t& IndexStrategy, + const ui32_t& PartitionSpace_sec, const ui32_t& HeaderSize) +{ + if ( ! m_State.Test_BEGIN() ) + { + return RESULT_STATE; + } + + if ( m_IndexStrategy != AS_02::IS_FOLLOW ) + { + DefaultLogSink().Error("Only strategy IS_FOLLOW is supported at this time.\n"); + return Kumu::RESULT_NOTIMPL; + } + + Result_t result = m_File.OpenWrite(filename); + + if ( KM_SUCCESS(result) ) + { + m_IndexStrategy = IndexStrategy; + m_PartitionSpace = PartitionSpace_sec; // later converted to edit units by WritePHDRHeader() + m_HeaderSize = HeaderSize; + + if ( essence_descriptor->GetUL() != UL(m_Dict->ul(MDD_RGBAEssenceDescriptor)) + && essence_descriptor->GetUL() != UL(m_Dict->ul(MDD_CDCIEssenceDescriptor)) ) + { + DefaultLogSink().Error("Essence descriptor is not a RGBAEssenceDescriptor or CDCIEssenceDescriptor.\n"); + essence_descriptor->Dump(); + return RESULT_AS02_FORMAT; + } + + m_EssenceDescriptor = essence_descriptor; + + ASDCP::MXF::InterchangeObject_list_t::iterator i; + for ( i = essence_sub_descriptor_list.begin(); i != essence_sub_descriptor_list.end(); ++i ) + { + if ( (*i)->GetUL() != UL(m_Dict->ul(MDD_JPEG2000PictureSubDescriptor)) ) + { + DefaultLogSink().Error("Essence sub-descriptor is not a JPEG2000PictureSubDescriptor.\n"); + (*i)->Dump(); + } + + m_EssenceSubDescriptorList.push_back(*i); + GenRandomValue((*i)->InstanceUID); + m_EssenceDescriptor->SubDescriptors.push_back((*i)->InstanceUID); + *i = 0; // parent will only free the ones we don't keep + } + + result = m_State.Goto_INIT(); + } + + return result; +} + +// all the above for a single source clip +Result_t +AS_02::PHDR::MXFWriter::h__Writer::WritePHDRHeader(const std::string& PackageLabel, const ASDCP::UL& WrappingUL, + const std::string& TrackName, const ASDCP::UL& EssenceUL, + const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate, + const ui32_t& TCFrameRate) +{ + if ( EditRate.Numerator == 0 || EditRate.Denominator == 0 ) + { + DefaultLogSink().Error("Non-zero edit-rate reqired.\n"); + return RESULT_PARAM; + } + + InitHeader(); + + AddSourceClip(EditRate, EditRate/*TODO: for a moment*/, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel); + + // add metadata track + TrackSet<SourceClip> metdata_track = + CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage, + MD_DEF_LABEL, EditRate, + UL(m_Dict->ul(MDD_PHDRImageMetadataItem)), + 3 /* track id */, m_Dict); + + metdata_track.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(metdata_track.Sequence->Duration.get())); + // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from. + metdata_track.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((UL(m_MetadataUL).Value() + 12))); + + metdata_track.Clip = new SourceClip(m_Dict); + m_HeaderPart.AddChildObject(metdata_track.Clip); + metdata_track.Sequence->StructuralComponents.push_back(metdata_track.Clip->InstanceUID); + metdata_track.Clip->DataDefinition = UL(m_Dict->ul(MDD_PHDRImageMetadataWrappingFrame)); + + // for now we do not allow setting this value, so all files will be 'original' + metdata_track.Clip->SourceTrackID = 0; + metdata_track.Clip->SourcePackageID = NilUMID; + + metdata_track.Clip->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(metdata_track.Clip->Duration.get())); + + // add PHDR subdescriptor + m_MetadataTrackSubDescriptor = new PHDRMetadataTrackSubDescriptor(m_Dict); + m_EssenceSubDescriptorList.push_back(m_MetadataTrackSubDescriptor); + GenRandomValue(m_MetadataTrackSubDescriptor->InstanceUID); + m_EssenceDescriptor->SubDescriptors.push_back(m_MetadataTrackSubDescriptor->InstanceUID); + m_MetadataTrackSubDescriptor->DataDefinition = UL(m_Dict->ul(MDD_PHDRImageMetadataWrappingFrame)); + m_MetadataTrackSubDescriptor->SourceTrackID = 3; + m_MetadataTrackSubDescriptor->SimplePayloadSID = 0; + + AddEssenceDescriptor(WrappingUL); + + m_IndexWriter.SetPrimerLookup(&m_HeaderPart.m_Primer); + m_RIP.PairArray.push_back(RIP::PartitionPair(0, 0)); // Header partition RIP entry + m_IndexWriter.OperationalPattern = m_HeaderPart.OperationalPattern; + m_IndexWriter.EssenceContainers = m_HeaderPart.EssenceContainers; + + Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); + + if ( KM_SUCCESS(result) ) + { + m_PartitionSpace *= floor( EditRate.Quotient() + 0.5 ); // convert seconds to edit units + m_ECStart = m_File.Tell(); + m_IndexWriter.IndexSID = 129; + + UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); + Partition body_part(m_Dict); + body_part.BodySID = 1; + body_part.OperationalPattern = m_HeaderPart.OperationalPattern; + body_part.EssenceContainers = m_HeaderPart.EssenceContainers; + body_part.ThisPartition = m_ECStart; + result = body_part.WriteToFile(m_File, body_ul); + m_RIP.PairArray.push_back(RIP::PartitionPair(1, body_part.ThisPartition)); // Second RIP Entry + } + + return result; +} + +// Automatically sets the MXF file's metadata from the first jpeg codestream stream. +Result_t +AS_02::PHDR::MXFWriter::h__Writer::SetSourceStream(const std::string& label, const ASDCP::Rational& edit_rate) +{ + assert(m_Dict); + if ( ! m_State.Test_INIT() ) + { + return RESULT_STATE; + } + + memcpy(m_EssenceUL, m_Dict->ul(MDD_JPEG2000Essence), SMPTE_UL_LENGTH); + m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first track of the essence container + + memcpy(m_MetadataUL, m_Dict->ul(MDD_PHDRImageMetadataItem), SMPTE_UL_LENGTH); + m_MetadataUL[SMPTE_UL_LENGTH-1] = 3; // third track of the essence container + + Result_t result = m_State.Goto_READY(); + + if ( KM_SUCCESS(result) ) + { + result = WritePHDRHeader(label, UL(m_Dict->ul(MDD_JPEG_2000WrappingFrame)), + PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)), + edit_rate, derive_timecode_rate_from_edit_rate(edit_rate)); + + if ( KM_SUCCESS(result) ) + { + this->m_IndexWriter.SetPrimerLookup(&this->m_HeaderPart.m_Primer); + } + } + + return result; +} + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +// +Result_t +AS_02::PHDR::MXFWriter::h__Writer::WriteFrame(const AS_02::PHDR::FrameBuffer& FrameBuf, + AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( FrameBuf.Size() == 0 ) + { + DefaultLogSink().Error("The frame buffer size is zero.\n"); + return RESULT_PARAM; + } + + Result_t result = RESULT_OK; + + if ( m_State.Test_READY() ) + { + result = m_State.Goto_RUNNING(); // first time through + } + + if ( KM_SUCCESS(result) ) + { + ui64_t this_stream_offset = m_StreamOffset; // m_StreamOffset will be changed by the call to Write_EKLV_Packet + + result = Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten, + m_StreamOffset, FrameBuf, m_EssenceUL, Ctx, HMAC); + + if ( KM_SUCCESS(result) ) + { + ASDCP::FrameBuffer metadata_buffer_wrapper; + metadata_buffer_wrapper.SetData((byte_t*)(FrameBuf.OpaqueMetadata.c_str()), FrameBuf.OpaqueMetadata.size()); + metadata_buffer_wrapper.Size(FrameBuf.OpaqueMetadata.size()); + + + result = Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten, + m_StreamOffset, metadata_buffer_wrapper, m_MetadataUL, Ctx, HMAC); + } + + if ( KM_SUCCESS(result) ) + { + IndexTableSegment::IndexEntry Entry; + Entry.StreamOffset = this_stream_offset; + m_IndexWriter.PushIndexEntry(Entry); + } + + if ( m_FramesWritten > 1 && ( ( m_FramesWritten + 1 ) % m_PartitionSpace ) == 0 ) + { + m_IndexWriter.ThisPartition = m_File.Tell(); + m_IndexWriter.WriteToFile(m_File); + m_RIP.PairArray.push_back(RIP::PartitionPair(0, m_IndexWriter.ThisPartition)); + + UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); + Partition body_part(m_Dict); + body_part.BodySID = 1; + body_part.OperationalPattern = m_HeaderPart.OperationalPattern; + body_part.EssenceContainers = m_HeaderPart.EssenceContainers; + body_part.ThisPartition = m_File.Tell(); + + body_part.BodyOffset = m_StreamOffset; + result = body_part.WriteToFile(m_File, body_ul); + m_RIP.PairArray.push_back(RIP::PartitionPair(1, body_part.ThisPartition)); + } + } + + if ( KM_SUCCESS(result) ) + { + m_FramesWritten++; + } + + return result; +} + +// Closes the MXF file, writing the index and other closing information. +// +Result_t +AS_02::PHDR::MXFWriter::h__Writer::Finalize(const std::string& PHDR_master_metadata) +{ + if ( ! m_State.Test_RUNNING() ) + return RESULT_STATE; + + Result_t result = m_State.Goto_FINAL(); + + if ( KM_SUCCESS(result) ) + { + if ( m_IndexWriter.GetDuration() > 0 ) + { + m_IndexWriter.ThisPartition = this->m_File.Tell(); + m_IndexWriter.WriteToFile(this->m_File); + m_RIP.PairArray.push_back(RIP::PartitionPair(0, this->m_IndexWriter.ThisPartition)); + } + + if ( ! PHDR_master_metadata.empty() ) + { + // write PHDRSimplePayload + Kumu::fpos_t here = m_File.Tell(); + + // create generic stream partition header + static UL GenericStream_DataElement(m_Dict->ul(MDD_GenericStream_DataElement)); + ASDCP::MXF::Partition GSPart(m_Dict); + + GSPart.ThisPartition = here; + GSPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset; + GSPart.OperationalPattern = m_HeaderPart.OperationalPattern; + GSPart.BodySID = 2; + m_MetadataTrackSubDescriptor->SimplePayloadSID = 2; + + m_RIP.PairArray.push_back(RIP::PartitionPair(2, here)); + GSPart.EssenceContainers = m_HeaderPart.EssenceContainers; + + static UL gs_part_ul(m_Dict->ul(MDD_GenericStreamPartition)); + Result_t result = GSPart.WriteToFile(m_File, gs_part_ul); + + if ( KM_SUCCESS(result) ) + { + ASDCP::FrameBuffer tmp_buf; + tmp_buf.SetData((byte_t*)PHDR_master_metadata.c_str(), PHDR_master_metadata.size()); + tmp_buf.Size(PHDR_master_metadata.size()); + + result = Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten, + m_StreamOffset, tmp_buf, GenericStream_DataElement.Value(), 0, 0); + } + } + + result = WriteAS02Footer(); + } + + return result; +} + + +//------------------------------------------------------------------------------------------ + + + +AS_02::PHDR::MXFWriter::MXFWriter() +{ +} + +AS_02::PHDR::MXFWriter::~MXFWriter() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +AS_02::PHDR::MXFWriter::OP1aHeader() +{ + if ( m_Writer.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Writer->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +AS_02::PHDR::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +Result_t +AS_02::PHDR::MXFWriter::OpenWrite(const std::string& filename, const ASDCP::WriterInfo& Info, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const ASDCP::Rational& edit_rate, const ui32_t& header_size, + const IndexStrategy_t& strategy, const ui32_t& partition_space) +{ + if ( essence_descriptor == 0 ) + { + DefaultLogSink().Error("Essence descriptor object required.\n"); + return RESULT_PARAM; + } + + m_Writer = new AS_02::PHDR::MXFWriter::h__Writer(DefaultSMPTEDict()); + m_Writer->m_Info = Info; + + Result_t result = m_Writer->OpenWrite(filename, essence_descriptor, essence_sub_descriptor_list, + strategy, partition_space, header_size); + + if ( KM_SUCCESS(result) ) + result = m_Writer->SetSourceStream(JP2K_PACKAGE_LABEL, edit_rate); + + if ( KM_FAILURE(result) ) + m_Writer.release(); + + return result; +} + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +Result_t +AS_02::PHDR::MXFWriter::WriteFrame(const AS_02::PHDR::FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC); +} + +// Closes the MXF file, writing the index and other closing information. +Result_t +AS_02::PHDR::MXFWriter::Finalize(const std::string& PHDR_master_metadata) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->Finalize(PHDR_master_metadata); +} + + +// +// end AS_02_PHDR.cpp +// diff --git a/asdcplib/src/AS_02_PHDR.h b/asdcplib/src/AS_02_PHDR.h new file mode 100644 index 00000000..e9084042 --- /dev/null +++ b/asdcplib/src/AS_02_PHDR.h @@ -0,0 +1,191 @@ +/* +Copyright (c) 2011-2015, John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*! \file AS_02_PHDR.h + \version $Id: AS_02_PHDR.h,v 1.4 2015/01/22 21:05:58 jhurst Exp $ + \brief AS-02 library, JPEG 2000 P-HDR essence reader and writer implementation +*/ + + +#ifndef _AS_02_PHDR_H_ +#define _AS_02_PHDR_H_ + +#include "AS_02.h" + +namespace AS_02 +{ + + namespace PHDR + { + // + class FrameBuffer : public ASDCP::JP2K::FrameBuffer + { + public: + std::string OpaqueMetadata; + + FrameBuffer() {} + FrameBuffer(ui32_t size) { Capacity(size); } + virtual ~FrameBuffer() {} + + // Print debugging information to stream (stderr default) + void Dump(FILE* = 0, ui32_t dump_bytes = 0) const; + }; + + // An object which reads a sequence of files containing + // JPEG 2000 P-HDR pictures and metadata. + class SequenceParser + { + class h__SequenceParser; + Kumu::mem_ptr<h__SequenceParser> m_Parser; + ASDCP_NO_COPY_CONSTRUCT(SequenceParser); + + public: + SequenceParser(); + virtual ~SequenceParser(); + + // Opens a directory for reading. The directory is expected to contain one or + // more pairs of files, each containing the codestream for exactly one picture (.j2c) + // and the corresponding P-HDR metadata (.xml). The files must be named such that the + // frames are in temporal order when sorted alphabetically by filename. The parser + // will automatically parse enough data from the first file to provide a complete set + // of stream metadata for the MXFWriter below. The contents of the metadata files will + // not be analyzed (i.e., the raw bytes will be passed in without scrutiny.) If the + // "pedantic" parameter is given and is true, the J2C parser will check the JPEG 2000 + // metadata for each codestream and fail if a mismatch is detected. + Result_t OpenRead(const std::string& filename, bool pedantic = false) const; + + // Opens a file sequence for reading. The sequence is expected to contain one or + // more pairs of filenames, each naming a file containing the codestream (.j2c) and the + // corresponding P-HDR metadata (.xml) for exactly one picture. The parser will + // automatically parse enough data from the first file to provide a complete set of + // stream metadata for the MXFWriter below. If the "pedantic" parameter is given and + // is true, the parser will check the metadata for each codestream and fail if a + // mismatch is detected. + Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const; + + // Fill a PictureDescriptor struct with the values from the first file's codestream. + // Returns RESULT_INIT if the directory is not open. + Result_t FillPictureDescriptor(ASDCP::JP2K::PictureDescriptor&) const; + + // Rewind the directory to the beginning. + Result_t Reset() const; + + // Reads the next sequential frame in the directory and places it in the frame buffer. + // Fails if the buffer is too small or the direcdtory contains no more files. The frame + // buffer's PlaintextOffset parameter will be set to the first byte of the data segment. + // Set this value to zero if you want encrypted headers. + Result_t ReadFrame(AS_02::PHDR::FrameBuffer&) const; + }; + + // + class MXFWriter + { + class h__Writer; + ASDCP::mem_ptr<h__Writer> m_Writer; + ASDCP_NO_COPY_CONSTRUCT(MXFWriter); + + public: + MXFWriter(); + virtual ~MXFWriter(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual ASDCP::MXF::OP1aHeader& OP1aHeader(); + virtual ASDCP::MXF::RIP& RIP(); + + // Open the file for writing. The file must not exist. Returns error if + // the operation cannot be completed or if nonsensical data is discovered + // in the essence descriptor. + Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&, + ASDCP::MXF::FileDescriptor* essence_descriptor, + ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list, + const ASDCP::Rational& edit_rate, const ui32_t& header_size = 16384, + const IndexStrategy_t& strategy = IS_FOLLOW, const ui32_t& partition_space = 10); + + // Writes a frame of essence to the MXF file. If the optional AESEncContext + // argument is present, the essence is encrypted prior to writing. + // Fails if the file is not open, is finalized, or an operating system + // error occurs. + Result_t WriteFrame(const AS_02::PHDR::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0); + + // Closes the MXF file, writing the final index, the PHDR master metadata and the revised header. + Result_t Finalize(const std::string& PHDR_master_metadata); + }; + + // + class MXFReader + { + class h__Reader; + ASDCP::mem_ptr<h__Reader> m_Reader; + ASDCP_NO_COPY_CONSTRUCT(MXFReader); + + public: + MXFReader(); + virtual ~MXFReader(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual ASDCP::MXF::OP1aHeader& OP1aHeader(); + virtual AS_02::MXF::AS02IndexReader& AS02IndexReader(); + virtual ASDCP::MXF::RIP& RIP(); + + // Open the file for reading. The file must exist. Returns error if the + // operation cannot be completed. If master metadata is available it will + // be placed into the string object passed as the second argument. + Result_t OpenRead(const std::string& filename, std::string& PHDR_master_metadata) const; + + // Returns RESULT_INIT if the file is not open. + Result_t Close() const; + + // Fill a WriterInfo struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillWriterInfo(ASDCP::WriterInfo&) const; + + // Reads a frame of essence from the MXF file. If the optional AESEncContext + // argument is present, the essence is decrypted after reading. If the MXF + // file is encrypted and the AESDecContext argument is NULL, the frame buffer + // will contain the ciphertext frame data. If the HMACContext argument is + // not NULL, the HMAC will be calculated (if the file supports it). + // Returns RESULT_INIT if the file is not open, failure if the frame number is + // out of range, or if optional decrypt or HAMC operations fail. + Result_t ReadFrame(ui32_t frame_number, AS_02::PHDR::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const; + + // Print debugging information to stream + void DumpHeaderMetadata(FILE* = 0) const; + void DumpIndex(FILE* = 0) const; + }; + + } // end namespace PHDR + +} // end namespace AS_02 + +#endif // _AS_02_PHDR_H_ + +// +// end AS_02_PHDR.h +// diff --git a/asdcplib/src/AS_02_TimedText.cpp b/asdcplib/src/AS_02_TimedText.cpp new file mode 100644 index 00000000..01a978d1 --- /dev/null +++ b/asdcplib/src/AS_02_TimedText.cpp @@ -0,0 +1,745 @@ +/* +Copyright (c) 2008-2015, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_DCP_TimedText.cpp + \version $Id: AS_02_TimedText.cpp,v 1.5 2015/10/09 23:41:11 jhurst Exp $ + \brief AS-DCP library, PCM essence reader and writer implementation +*/ + + +#include "AS_02_internal.h" +#include "KM_xml.h" +#include <iostream> +#include <iomanip> + +using Kumu::GenRandomValue; + +static std::string TIMED_TEXT_PACKAGE_LABEL = "File Package: SMPTE ST 429-5 / ST 2067-5 clip wrapping of IMF Timed Text data"; +static std::string TIMED_TEXT_DEF_LABEL = "Timed Text Track"; + + +//------------------------------------------------------------------------------------------ + +const char* +MIME2str(TimedText::MIMEType_t m) +{ + if ( m == TimedText::MT_PNG ) + return "image/png"; + + else if ( m == TimedText::MT_OPENTYPE ) + return "application/x-font-opentype"; + + return "application/octet-stream"; +} + +//------------------------------------------------------------------------------------------ + +typedef std::map<Kumu::UUID, Kumu::UUID> ResourceMap_t; + +class AS_02::TimedText::MXFReader::h__Reader : public AS_02::h__AS02Reader +{ + ASDCP::MXF::TimedTextDescriptor* m_EssenceDescriptor; + ResourceMap_t m_ResourceMap; + + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + +public: + TimedTextDescriptor m_TDesc; + + h__Reader(const Dictionary& d) : AS_02::h__AS02Reader(d), m_EssenceDescriptor(0) { + memset(&m_TDesc.AssetID, 0, UUIDlen); + } + + virtual ~h__Reader() {} + + Result_t OpenRead(const std::string&); + Result_t MD_to_TimedText_TDesc(TimedTextDescriptor& TDesc); + Result_t ReadTimedTextResource(ASDCP::TimedText::FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC); + Result_t ReadAncillaryResource(const Kumu::UUID&, ASDCP::TimedText::FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC); +}; + +// +ASDCP::Result_t +AS_02::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedTextDescriptor& TDesc) +{ + assert(m_EssenceDescriptor); + memset(&m_TDesc.AssetID, 0, UUIDlen); + ASDCP::MXF::TimedTextDescriptor* TDescObj = (ASDCP::MXF::TimedTextDescriptor*)m_EssenceDescriptor; + + TDesc.EditRate = TDescObj->SampleRate; + assert(TDescObj->ContainerDuration <= 0xFFFFFFFFL); + TDesc.ContainerDuration = (ui32_t) TDescObj->ContainerDuration; + memcpy(TDesc.AssetID, TDescObj->ResourceID.Value(), UUIDlen); + TDesc.NamespaceName = TDescObj->NamespaceURI; + TDesc.EncodingName = TDescObj->UCSEncoding; + + Array<Kumu::UUID>::const_iterator sdi = TDescObj->SubDescriptors.begin(); + TimedTextResourceSubDescriptor* DescObject = 0; + Result_t result = RESULT_OK; + + for ( ; sdi != TDescObj->SubDescriptors.end() && KM_SUCCESS(result); sdi++ ) + { + InterchangeObject* tmp_iobj = 0; + result = m_HeaderPart.GetMDObjectByID(*sdi, &tmp_iobj); + DescObject = static_cast<TimedTextResourceSubDescriptor*>(tmp_iobj); + + if ( KM_SUCCESS(result) ) + { + TimedTextResourceDescriptor TmpResource; + memcpy(TmpResource.ResourceID, DescObject->AncillaryResourceID.Value(), UUIDlen); + + if ( DescObject->MIMEMediaType.find("application/x-font-opentype") != std::string::npos + || DescObject->MIMEMediaType.find("application/x-opentype") != std::string::npos + || DescObject->MIMEMediaType.find("font/opentype") != std::string::npos ) + { + TmpResource.Type = ASDCP::TimedText::MT_OPENTYPE; + } + else if ( DescObject->MIMEMediaType.find("image/png") != std::string::npos ) + { + TmpResource.Type = ASDCP::TimedText::MT_PNG; + } + else + { + TmpResource.Type = ASDCP::TimedText::MT_BIN; + } + + TDesc.ResourceList.push_back(TmpResource); + m_ResourceMap.insert(ResourceMap_t::value_type(DescObject->AncillaryResourceID, *sdi)); + } + else + { + DefaultLogSink().Error("Broken sub-descriptor link\n"); + return RESULT_FORMAT; + } + } + + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFReader::h__Reader::OpenRead(const std::string& filename) +{ + Result_t result = OpenMXFRead(filename.c_str()); + + if( ASDCP_SUCCESS(result) ) + { + if ( m_EssenceDescriptor == 0 ) + { + InterchangeObject* tmp_iobj = 0; + result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor), &tmp_iobj); + m_EssenceDescriptor = static_cast<ASDCP::MXF::TimedTextDescriptor*>(tmp_iobj); + } + + if( ASDCP_SUCCESS(result) ) + result = MD_to_TimedText_TDesc(m_TDesc); + } + + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFReader::h__Reader::ReadTimedTextResource(ASDCP::TimedText::FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) +{ + if ( ! m_File.IsOpen() ) + return RESULT_INIT; + + assert(m_Dict); + Result_t result = ReadEKLVFrame(0, FrameBuf, m_Dict->ul(MDD_TimedTextEssence), Ctx, HMAC); + + if( ASDCP_SUCCESS(result) ) + { + FrameBuf.AssetID(m_TDesc.AssetID); + FrameBuf.MIMEType("text/xml"); + } + + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const Kumu::UUID& uuid, + ASDCP::TimedText::FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) +{ + ResourceMap_t::const_iterator ri = m_ResourceMap.find(uuid); + if ( ri == m_ResourceMap.end() ) + { + char buf[64]; + DefaultLogSink().Error("No such resource: %s\n", uuid.EncodeHex(buf, 64)); + return RESULT_RANGE; + } + + TimedTextResourceSubDescriptor* DescObject = 0; + // get the subdescriptor + InterchangeObject* tmp_iobj = 0; + Result_t result = m_HeaderPart.GetMDObjectByID((*ri).second, &tmp_iobj); + DescObject = static_cast<TimedTextResourceSubDescriptor*>(tmp_iobj); + + if ( KM_SUCCESS(result) ) + { + RIP::const_pair_iterator pi; + RIP::PartitionPair TmpPair; + ui32_t sequence = 0; + + // Look up the partition start in the RIP using the SID. + // Count the sequence length in because this is the sequence + // value needed to complete the HMAC. + for ( pi = m_RIP.PairArray.begin(); pi != m_RIP.PairArray.end(); ++pi, ++sequence ) + { + if ( (*pi).BodySID == DescObject->EssenceStreamID ) + { + TmpPair = *pi; + break; + } + } + + if ( TmpPair.ByteOffset == 0 ) + { + DefaultLogSink().Error("Body SID not found in RIP set: %d\n", DescObject->EssenceStreamID); + return RESULT_FORMAT; + } + + if ( KM_SUCCESS(result) ) + { + FrameBuf.AssetID(uuid.Value()); + FrameBuf.MIMEType(DescObject->MIMEMediaType); + + // seek tp the start of the partition + if ( (Kumu::fpos_t)TmpPair.ByteOffset != m_LastPosition ) + { + m_LastPosition = TmpPair.ByteOffset; + result = m_File.Seek(TmpPair.ByteOffset); + } + + // read the partition header + ASDCP::MXF::Partition GSPart(m_Dict); + result = GSPart.InitFromFile(m_File); + + if( ASDCP_SUCCESS(result) ) + { + // check the SID + if ( DescObject->EssenceStreamID != GSPart.BodySID ) + { + char buf[64]; + DefaultLogSink().Error("Generic stream partition body differs: %s\n", uuid.EncodeHex(buf, 64)); + return RESULT_FORMAT; + } + + // read the essence packet + assert(m_Dict); + if( ASDCP_SUCCESS(result) ) + result = ReadEKLVPacket(0, sequence, FrameBuf, m_Dict->ul(MDD_GenericStream_DataElement), Ctx, HMAC); + } + } + } + + return result; +} + + +//------------------------------------------------------------------------------------------ + +AS_02::TimedText::MXFReader::MXFReader() +{ + m_Reader = new h__Reader(DefaultSMPTEDict()); +} + + +AS_02::TimedText::MXFReader::~MXFReader() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +AS_02::TimedText::MXFReader::OP1aHeader() +{ + if ( m_Reader.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Reader->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +AS_02::MXF::AS02IndexReader& +AS_02::TimedText::MXFReader::AS02IndexReader() +{ + if ( m_Reader.empty() ) + { + assert(g_AS02IndexReader); + return *g_AS02IndexReader; + } + + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +AS_02::TimedText::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; +} + +// Open the file for reading. The file must exist. Returns error if the +// operation cannot be completed. +ASDCP::Result_t +AS_02::TimedText::MXFReader::OpenRead(const std::string& filename) const +{ + return m_Reader->OpenRead(filename); +} + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +AS_02::TimedText::MXFReader::FillTimedTextDescriptor(TimedText::TimedTextDescriptor& TDesc) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + TDesc = m_Reader->m_TDesc; + return RESULT_OK; + } + + return RESULT_INIT; +} + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +AS_02::TimedText::MXFReader::FillWriterInfo(WriterInfo& Info) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + Info = m_Reader->m_Info; + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFReader::ReadTimedTextResource(std::string& s, AESDecContext* Ctx, HMACContext* HMAC) const +{ + ASDCP::TimedText::FrameBuffer FrameBuf(8*Kumu::Megabyte); + + Result_t result = ReadTimedTextResource(FrameBuf, Ctx, HMAC); + + if ( ASDCP_SUCCESS(result) ) + s.assign((char*)FrameBuf.Data(), FrameBuf.Size()); + + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFReader::ReadTimedTextResource(ASDCP::TimedText::FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadTimedTextResource(FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFReader::ReadAncillaryResource(const Kumu::UUID& uuid, ASDCP::TimedText::FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadAncillaryResource(uuid, FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + + +// +void +AS_02::TimedText::MXFReader::DumpHeaderMetadata(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_HeaderPart.Dump(stream); +} + + +// +void +AS_02::TimedText::MXFReader::DumpIndex(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_IndexAccess.Dump(stream); +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFReader::Close() const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + m_Reader->Close(); + return RESULT_OK; + } + + return RESULT_INIT; +} + + +//------------------------------------------------------------------------------------------ + + +// +class AS_02::TimedText::MXFWriter::h__Writer : public AS_02::h__AS02WriterClip +{ + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); + +public: + TimedTextDescriptor m_TDesc; + byte_t m_EssenceUL[SMPTE_UL_LENGTH]; + ui32_t m_EssenceStreamID; + + h__Writer(const Dictionary& d) : AS_02::h__AS02WriterClip(d), m_EssenceStreamID(10) + { + memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); + } + + virtual ~h__Writer() {} + + Result_t OpenWrite(const std::string&, ui32_t HeaderSize); + Result_t SetSourceStream(const ASDCP::TimedText::TimedTextDescriptor&); + Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0); + Result_t WriteAncillaryResource(const ASDCP::TimedText::FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); + Result_t Finalize(); + Result_t TimedText_TDesc_to_MD(ASDCP::TimedText::TimedTextDescriptor& TDesc); +}; + +// +ASDCP::Result_t +AS_02::TimedText::MXFWriter::h__Writer::TimedText_TDesc_to_MD(TimedText::TimedTextDescriptor& TDesc) +{ + assert(m_EssenceDescriptor); + ASDCP::MXF::TimedTextDescriptor* TDescObj = (ASDCP::MXF::TimedTextDescriptor*)m_EssenceDescriptor; + + TDescObj->SampleRate = TDesc.EditRate; + TDescObj->ContainerDuration = TDesc.ContainerDuration; + TDescObj->ResourceID.Set(TDesc.AssetID); + TDescObj->NamespaceURI = TDesc.NamespaceName; + TDescObj->UCSEncoding = TDesc.EncodingName; + + return RESULT_OK; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize) +{ + if ( ! m_State.Test_BEGIN() ) + { + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + } + + Result_t result = m_File.OpenWrite(filename.c_str()); + + if ( ASDCP_SUCCESS(result) ) + { + m_HeaderSize = HeaderSize; + m_EssenceDescriptor = new ASDCP::MXF::TimedTextDescriptor(m_Dict); + result = m_State.Goto_INIT(); + } + + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedTextDescriptor const& TDesc) +{ + if ( ! m_State.Test_INIT() ) + { + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + } + + assert(m_Dict); + m_TDesc = TDesc; + + Result_t result = TimedText_TDesc_to_MD(m_TDesc); + + if ( KM_SUCCESS(result) ) + { + ResourceList_t::const_iterator i; + for ( i = m_TDesc.ResourceList.begin() ; i != m_TDesc.ResourceList.end(); ++i ) + { + TimedTextResourceSubDescriptor* resourceSubdescriptor = new TimedTextResourceSubDescriptor(m_Dict); + GenRandomValue(resourceSubdescriptor->InstanceUID); + resourceSubdescriptor->AncillaryResourceID.Set((*i).ResourceID); + resourceSubdescriptor->MIMEMediaType = MIME2str((*i).Type); + resourceSubdescriptor->EssenceStreamID = m_EssenceStreamID++; + m_EssenceSubDescriptorList.push_back((FileDescriptor*)resourceSubdescriptor); + m_EssenceDescriptor->SubDescriptors.push_back(resourceSubdescriptor->InstanceUID); + + // 72 == sizeof K, L, instanceuid, uuid + sizeof int32 + tag/len * 4 + m_HeaderSize += ( resourceSubdescriptor->MIMEMediaType.ArchiveLength() * 2 /*ArchiveLength is broken*/ ) + 72; + } + } + + if ( KM_SUCCESS(result) ) + { + result = WriteAS02Header(TIMED_TEXT_PACKAGE_LABEL, UL(m_Dict->ul(MDD_TimedTextWrappingClip)), + "Data Track", UL(m_EssenceUL), UL(m_Dict->ul(MDD_TimedTextEssence)), + TDesc.EditRate, derive_timecode_rate_from_edit_rate(TDesc.EditRate)); + } + + if ( KM_SUCCESS(result) ) + { + this->m_IndexWriter.SetPrimerLookup(&this->m_HeaderPart.m_Primer); + } + + if ( KM_SUCCESS(result) ) + { + memcpy(m_EssenceUL, m_Dict->ul(MDD_TimedTextEssence), SMPTE_UL_LENGTH); + m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container + result = m_State.Goto_READY(); + } + + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFWriter::h__Writer::WriteTimedTextResource(const std::string& XMLDoc, + ASDCP::AESEncContext* Ctx, ASDCP::HMACContext* HMAC) +{ + Result_t result = m_State.Goto_RUNNING(); + + if ( KM_SUCCESS(result) ) + { + // TODO: make sure it's XML + + ui32_t str_size = XMLDoc.size(); + ASDCP::TimedText::FrameBuffer FrameBuf(str_size); + + memcpy(FrameBuf.Data(), XMLDoc.c_str(), str_size); + FrameBuf.Size(str_size); + + IndexTableSegment::IndexEntry Entry; + Entry.StreamOffset = m_StreamOffset; + + if ( KM_SUCCESS(result) ) + { + ui64_t this_stream_offset = m_StreamOffset; // m_StreamOffset will be changed by the call to Write_EKLV_Packet + + result = Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten, + m_StreamOffset, FrameBuf, m_EssenceUL, Ctx, HMAC); + } + } + + return result; +} + + +// +ASDCP::Result_t +AS_02::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::TimedText::FrameBuffer& FrameBuf, + ASDCP::AESEncContext* Ctx, ASDCP::HMACContext* HMAC) +{ + if ( ! m_State.Test_RUNNING() ) + { + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + } + + Kumu::fpos_t here = m_File.Tell(); + assert(m_Dict); + + // create generic stream partition header + static UL GenericStream_DataElement(m_Dict->ul(MDD_GenericStream_DataElement)); + ASDCP::MXF::Partition GSPart(m_Dict); + + GSPart.ThisPartition = here; + GSPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset; + GSPart.BodySID = m_EssenceStreamID; + GSPart.OperationalPattern = m_HeaderPart.OperationalPattern; + + m_RIP.PairArray.push_back(RIP::PartitionPair(m_EssenceStreamID++, here)); + GSPart.EssenceContainers.push_back(UL(m_Dict->ul(MDD_TimedTextEssence))); + UL TmpUL(m_Dict->ul(MDD_GenericStreamPartition)); + Result_t result = GSPart.WriteToFile(m_File, TmpUL); + + if ( KM_SUCCESS(result) ) + { + ui64_t this_stream_offset = m_StreamOffset; // m_StreamOffset will be changed by the call to Write_EKLV_Packet + + result = Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten, + m_StreamOffset, FrameBuf, GenericStream_DataElement.Value(), Ctx, HMAC); + } + + m_FramesWritten++; + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFWriter::h__Writer::Finalize() +{ + if ( ! m_State.Test_RUNNING() ) + { + DefaultLogSink().Error("Cannot finalize file, the primary essence resource has not been written.\n"); + return RESULT_STATE; + } + + m_IndexWriter.m_Duration = m_FramesWritten = m_TDesc.ContainerDuration; + + Result_t result = m_State.Goto_FINAL(); + + if ( KM_SUCCESS(result) ) + { + result = WriteAS02Footer(); + } + + return result; +} + + +//------------------------------------------------------------------------------------------ + +AS_02::TimedText::MXFWriter::MXFWriter() +{ +} + +AS_02::TimedText::MXFWriter::~MXFWriter() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +AS_02::TimedText::MXFWriter::OP1aHeader() +{ + if ( m_Writer.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Writer->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +AS_02::TimedText::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +ASDCP::Result_t +AS_02::TimedText::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, + const TimedTextDescriptor& TDesc, ui32_t HeaderSize) +{ + if ( Info.LabelSetType != LS_MXF_SMPTE ) + { + DefaultLogSink().Error("Timed Text support requires LS_MXF_SMPTE\n"); + return RESULT_FORMAT; + } + + m_Writer = new h__Writer(DefaultSMPTEDict()); + m_Writer->m_Info = Info; + + Result_t result = m_Writer->OpenWrite(filename, HeaderSize); + + if ( ASDCP_SUCCESS(result) ) + result = m_Writer->SetSourceStream(TDesc); + + if ( ASDCP_FAILURE(result) ) + m_Writer.release(); + + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFWriter::WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteTimedTextResource(XMLDoc, Ctx, HMAC); +} + +// +ASDCP::Result_t +AS_02::TimedText::MXFWriter::WriteAncillaryResource(const ASDCP::TimedText::FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteAncillaryResource(FrameBuf, Ctx, HMAC); +} + +// Closes the MXF file, writing the index and other closing information. +ASDCP::Result_t +AS_02::TimedText::MXFWriter::Finalize() +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->Finalize(); +} + + + +// +// end AS_02_timedText.cpp +// diff --git a/asdcplib/src/AS_02_internal.h b/asdcplib/src/AS_02_internal.h new file mode 100644 index 00000000..bcee7a7b --- /dev/null +++ b/asdcplib/src/AS_02_internal.h @@ -0,0 +1,330 @@ +/* +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_02_internal.h + \version $Id: AS_02_internal.h *** + \brief AS-02 library, non-public common elements +*/ + +#ifndef _AS_02_INTERNAL_H_ +#define _AS_02_INTERNAL_H_ + +#include "KM_log.h" +#include "AS_DCP_internal.h" +#include "AS_02.h" + +using Kumu::DefaultLogSink; + +#ifdef DEFAULT_02_MD_DECL +AS_02::MXF::AS02IndexReader *g_AS02IndexReader; +#else +extern AS_02::MXF::AS02IndexReader *g_AS02IndexReader; +#endif + + +namespace AS_02 +{ + + void default_md_object_init(); + + + // + class h__AS02Reader : public ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader> + { + ASDCP_NO_COPY_CONSTRUCT(h__AS02Reader); + h__AS02Reader(); + + public: + h__AS02Reader(const ASDCP::Dictionary&); + virtual ~h__AS02Reader(); + + Result_t OpenMXFRead(const char* filename); + + // USE FRAME WRAPPING... + Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC); + + // OR CLIP WRAPPING... + // clip wrapping is handled directly by the essence-specific classes + // Result_t ReadyClip(const ui32_t& FrameNum, const byte_t* EssenceUL, ASDCP::AESDecContext* Ctx, ASDCP::HMACContext* HMAC, ui64_t& position); + /// Result_t ReadClipBlock(ASDCP::FrameBuffer& FrameBuf, const ui32_t& read_size); + + // NOT BOTH! + }; + + + namespace MXF + { + // + class AS02IndexWriterVBR : public ASDCP::MXF::Partition + { + ASDCP::MXF::IndexTableSegment* m_CurrentSegment; + ASDCP::MXF::Rational m_EditRate; + + KM_NO_COPY_CONSTRUCT(AS02IndexWriterVBR); + AS02IndexWriterVBR(); + + public: + const ASDCP::Dictionary*& m_Dict; + ASDCP::IPrimerLookup* m_Lookup; + + AS02IndexWriterVBR(const ASDCP::Dictionary*&); + virtual ~AS02IndexWriterVBR(); + + // + void SetPrimerLookup(ASDCP::IPrimerLookup* lookup) { + assert(lookup); + m_Lookup = lookup; + } + + Result_t WriteToFile(Kumu::FileWriter& Writer); + void Dump(FILE* = 0); + + ui32_t GetDuration() const; + void PushIndexEntry(const ASDCP::MXF::IndexTableSegment::IndexEntry&); + }; + + + // + class AS02IndexWriterCBR : public ASDCP::MXF::Partition + { + ASDCP::MXF::IndexTableSegment* m_CurrentSegment; + ASDCP::MXF::Rational m_EditRate; + + KM_NO_COPY_CONSTRUCT(AS02IndexWriterCBR); + AS02IndexWriterCBR(); + + public: + const ASDCP::Dictionary*& m_Dict; + ASDCP::IPrimerLookup* m_Lookup; + ui32_t m_Duration; + ui32_t m_SampleSize; + + AS02IndexWriterCBR(const ASDCP::Dictionary*&); + virtual ~AS02IndexWriterCBR(); + + // + void SetPrimerLookup(ASDCP::IPrimerLookup* lookup) { + assert(lookup); + m_Lookup = lookup; + } + + Result_t WriteToFile(Kumu::FileWriter& Writer); + ui32_t GetDuration() const; + void SetEditRate(const ASDCP::Rational& edit_rate, const ui32_t& sample_size); + }; + } + + // + template <class IndexWriterType> + class h__AS02Writer : public ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader> + { + ASDCP_NO_COPY_CONSTRUCT(h__AS02Writer); + h__AS02Writer(); + + public: + ui32_t m_PartitionSpace; // edit units per partition + IndexWriterType m_IndexWriter; + ui64_t m_ECStart; // offset of the first essence element + + // + h__AS02Writer(const ASDCP::Dictionary& d) : + ASDCP::MXF::TrackFileWriter<ASDCP::MXF::OP1aHeader>(d), m_IndexWriter(m_Dict), m_ECStart(0) {} + + ~h__AS02Writer() {} + + + + // all the above for a single source clip + Result_t WriteAS02Header(const std::string& PackageLabel, const ASDCP::UL& WrappingUL, + const std::string& TrackName, const ASDCP::UL& EssenceUL, + const ASDCP::UL& DataDefinition, const ASDCP::Rational& EditRate, + const ui32_t& TCFrameRate) + { + if ( EditRate.Numerator == 0 || EditRate.Denominator == 0 ) + { + DefaultLogSink().Error("Non-zero edit-rate reqired.\n"); + return RESULT_PARAM; + } + + InitHeader(); + + AddSourceClip(EditRate, EditRate/*TODO: for a moment*/, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel); + AddEssenceDescriptor(WrappingUL); + + this->m_IndexWriter.SetPrimerLookup(&this->m_HeaderPart.m_Primer); + this->m_RIP.PairArray.push_back(RIP::PartitionPair(0, 0)); // Header partition RIP entry + this->m_IndexWriter.OperationalPattern = this->m_HeaderPart.OperationalPattern; + this->m_IndexWriter.EssenceContainers = this->m_HeaderPart.EssenceContainers; + + Result_t result = this->m_HeaderPart.WriteToFile(this->m_File, this->m_HeaderSize); + + if ( KM_SUCCESS(result) ) + { + this->m_PartitionSpace *= floor( EditRate.Quotient() + 0.5 ); // convert seconds to edit units + this->m_ECStart = this->m_File.Tell(); + this->m_IndexWriter.IndexSID = 129; + + UL body_ul(this->m_Dict->ul(MDD_ClosedCompleteBodyPartition)); + Partition body_part(this->m_Dict); + body_part.BodySID = 1; + body_part.OperationalPattern = this->m_HeaderPart.OperationalPattern; + body_part.EssenceContainers = this->m_HeaderPart.EssenceContainers; + body_part.ThisPartition = this->m_ECStart; + result = body_part.WriteToFile(this->m_File, body_ul); + this->m_RIP.PairArray.push_back(RIP::PartitionPair(1, body_part.ThisPartition)); // Second RIP Entry + } + + return result; + } + + // standard method of writing the header and footer of a completed AS-02 file + // + Result_t WriteAS02Footer() + { + if ( this->m_IndexWriter.GetDuration() > 0 ) + { + this->m_IndexWriter.ThisPartition = this->m_File.Tell(); + this->m_IndexWriter.WriteToFile(this->m_File); + this->m_RIP.PairArray.push_back(RIP::PartitionPair(0, this->m_IndexWriter.ThisPartition)); + } + + // update all Duration properties + ASDCP::MXF::Partition footer_part(this->m_Dict); + DurationElementList_t::iterator dli = this->m_DurationUpdateList.begin(); + + for (; dli != this->m_DurationUpdateList.end(); ++dli ) + { + **dli = this->m_FramesWritten; + } + + this->m_EssenceDescriptor->ContainerDuration = this->m_FramesWritten; + footer_part.PreviousPartition = this->m_RIP.PairArray.back().ByteOffset; + + Kumu::fpos_t here = this->m_File.Tell(); + this->m_RIP.PairArray.push_back(RIP::PartitionPair(0, here)); // Last RIP Entry + this->m_HeaderPart.FooterPartition = here; + + assert(this->m_Dict); + footer_part.OperationalPattern = this->m_HeaderPart.OperationalPattern; + footer_part.EssenceContainers = this->m_HeaderPart.EssenceContainers; + footer_part.FooterPartition = here; + footer_part.ThisPartition = here; + + UL footer_ul(this->m_Dict->ul(MDD_CompleteFooter)); + Result_t result = footer_part.WriteToFile(this->m_File, footer_ul); + + if ( KM_SUCCESS(result) ) + result = this->m_RIP.WriteToFile(this->m_File); + + if ( KM_SUCCESS(result) ) + result = this->m_File.Seek(0); + + if ( KM_SUCCESS(result) ) + result = m_HeaderPart.WriteToFile(this->m_File, this->m_HeaderSize); + + if ( KM_SUCCESS(result) ) + { + ASDCP::MXF::RIP::const_pair_iterator i = this->m_RIP.PairArray.begin(); + ui64_t header_byte_count = this->m_HeaderPart.HeaderByteCount; + ui64_t previous_partition = 0; + + for ( i = this->m_RIP.PairArray.begin(); KM_SUCCESS(result) && i != this->m_RIP.PairArray.end(); ++i ) + { + ASDCP::MXF::Partition plain_part(this->m_Dict); + result = this->m_File.Seek(i->ByteOffset); + + if ( KM_SUCCESS(result) ) + result = plain_part.InitFromFile(this->m_File); + + if ( KM_SUCCESS(result) + && ( plain_part.IndexSID > 0 || plain_part.BodySID > 0 ) ) + { + plain_part.PreviousPartition = previous_partition; + plain_part.FooterPartition = footer_part.ThisPartition; + previous_partition = plain_part.ThisPartition; + result = this->m_File.Seek(i->ByteOffset); + + if ( KM_SUCCESS(result) ) + { + UL tmp_ul = plain_part.GetUL(); + result = plain_part.WriteToFile(this->m_File, tmp_ul); + } + } + } + } + + this->m_File.Close(); + return result; + } + }; + + // + class h__AS02WriterFrame : public h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR> + { + ASDCP_NO_COPY_CONSTRUCT(h__AS02WriterFrame); + h__AS02WriterFrame(); + + public: + IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5 + + h__AS02WriterFrame(const Dictionary&); + virtual ~h__AS02WriterFrame(); + + Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, + AESEncContext* Ctx, HMACContext* HMAC); + }; + + // + class h__AS02WriterClip : public h__AS02Writer<AS_02::MXF::AS02IndexWriterCBR> + { + ASDCP_NO_COPY_CONSTRUCT(h__AS02WriterClip); + h__AS02WriterClip(); + + public: + ui64_t m_ECStart; // offset of the first essence element + ui64_t m_ClipStart; // state variable for clip-wrap-in-progress + // AS_02::MXF::AS02IndexWriterCBR m_IndexWriter; + IndexStrategy_t m_IndexStrategy; // per SMPTE ST 2067-5 + + h__AS02WriterClip(const Dictionary&); + virtual ~h__AS02WriterClip(); + + bool HasOpenClip() const; + Result_t StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC); + Result_t WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf); + Result_t FinalizeClip(ui32_t bytes_per_frame); + }; + +} // namespace AS_02 + +#endif // _AS_02_INTERNAL_H_ + +// +// end AS_02_internal.h +// diff --git a/asdcplib/src/AS_DCP.cpp b/asdcplib/src/AS_DCP.cpp index 0ae9a1f4..14e08104 100755 --- a/asdcplib/src/AS_DCP.cpp +++ b/asdcplib/src/AS_DCP.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2009, John Hurst +Copyright (c) 2004-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP.cpp - \version $Id: AS_DCP.cpp,v 1.6 2009/04/09 19:16:49 msheby Exp $ + \version $Id: AS_DCP.cpp,v 1.7 2014/09/21 13:27:43 jhurst Exp $ \brief AS-DCP library, misc classes and subroutines */ @@ -39,6 +39,46 @@ ASDCP::Version() } + +//------------------------------------------------------------------------------------------ +// + +// Encodes a rational number as a string having a single delimiter character between +// numerator and denominator. Retuns the buffer pointer to allow convenient in-line use. +const char* +ASDCP::EncodeRational(const Rational& rational, char* str_buf, ui32_t buf_len, char delimiter) +{ + assert(str_buf); + snprintf(str_buf, buf_len, "%u%c%u", rational.Numerator, delimiter, rational.Denominator); + return str_buf; +} + +// Decodes a rational number havng a single non-digit delimiter character between +// the numerator and denominator. Returns false if the string does not contain +// the expected syntax. +bool +ASDCP::DecodeRational(const char* str_rational, Rational& rational) +{ + assert(str_rational); + rational.Numerator = strtol(str_rational, 0, 10); + + const char* p = str_rational; + while ( *p && isdigit(*p) ) + { + ++p; + } + + if ( p[0] == 0 || p[1] == 0 ) + { + return false; + } + + ++p; + rational.Denominator = strtol(p, 0, 10); + return true; +} + + //------------------------------------------------------------------------------------------ // // frame buffer base class implementation diff --git a/asdcplib/src/AS_DCP.h b/asdcplib/src/AS_DCP.h index eb2ce6e6..9e9702fc 100755 --- a/asdcplib/src/AS_DCP.h +++ b/asdcplib/src/AS_DCP.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2012, John Hurst +Copyright (c) 2003-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,13 +25,13 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP.h - \version $Id: AS_DCP.h,v 1.43 2012/02/02 01:58:43 jhurst Exp $ + \version $Id: AS_DCP.h,v 1.52 2015/04/21 03:55:31 jhurst Exp $ \brief AS-DCP library, public interface The asdcplib library is a set of file access objects that offer simplified access to files conforming to the standards published by the SMPTE D-Cinema Technology Committee 21DC. The file format, labeled AS-DCP, -is described in series of separate documents which include but may not +is described in a series of documents which includes but may not be be limited to: o SMPTE ST 429-2:2011 DCP Operational Constraints @@ -40,8 +40,10 @@ be be limited to: o SMPTE ST 429-5:2009 Timed Text Track File o SMPTE ST 429-6:2006 MXF Track File Essence Encryption o SMPTE ST 429-10:2008 Stereoscopic Picture Track File + o SMPTE ST 429-14:2008 Aux Data Track File o SMPTE ST 330:2004 - UMID o SMPTE ST 336:2001 - KLV + o SMPTE ST 377:2004 - MXF (old version, required) o SMPTE ST 377-1:2011 - MXF o SMPTE ST 377-4:2012 - MXF Multichannel Audio Labeling Framework o SMPTE ST 390:2011 - MXF OP-Atom @@ -61,18 +63,14 @@ be be limited to: The following use cases are supported by the library: o Write essence to a plaintext or ciphertext AS-DCP file: - MPEG2 Video Elementary Stream - JPEG 2000 codestreams - JPEG 2000 stereoscopic codestream pairs - PCM audio streams - SMPTE 429-7 Timed Text XML with font and image resources - o Read essence from a plaintext or ciphertext AS-DCP file: MPEG2 Video Elementary Stream JPEG 2000 codestreams JPEG 2000 stereoscopic codestream pairs PCM audio streams SMPTE 429-7 Timed Text XML with font and image resources + Aux Data (frame-wrapped synchronous blob) + Proposed Dolby (TM) Atmos track file o Read header metadata from an AS-DCP file @@ -87,7 +85,7 @@ This project depends upon the following libraries: #define _AS_DCP_H_ #include <KM_error.h> -#include <KM_platform.h> +#include <KM_fileio.h> #include <stdio.h> #include <stdarg.h> #include <math.h> @@ -204,24 +202,38 @@ namespace ASDCP { // The file accessors in this library implement a bounded set of essence types. // This list will be expanded when support for new types is added to the library. enum EssenceType_t { - ESS_UNKNOWN, // the file is not a supported AS-DCP essence container - ESS_MPEG2_VES, // the file contains an MPEG video elementary stream - ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams - ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs - ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs - ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources - ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic) + ESS_UNKNOWN, // the file is not a supported AS-DCP of AS-02 essence container + + // + ESS_MPEG2_VES, // the file contains an MPEG-2 video elementary stream + + // d-cinema essence types + ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams + ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs + ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs + ESS_TIMED_TEXT, // the file contains an XML timed text document and one or more resources + ESS_JPEG_2000_S, // the file contains one or more JPEG 2000 codestream pairs (stereoscopic) + ESS_DCDATA_UNKNOWN, // the file contains one or more D-Cinema Data bytestreams + ESS_DCDATA_DOLBY_ATMOS, // the file contains one or more DolbyATMOS bytestreams + + // IMF essence types + ESS_AS02_JPEG_2000, // the file contains one or more JPEG 2000 codestreams + ESS_AS02_PCM_24b_48k, // the file contains one or more PCM audio pairs, clip wrapped + ESS_AS02_PCM_24b_96k, // the file contains one or more PCM audio pairs, clip wrapped + ESS_AS02_TIMED_TEXT, // the file contains a TTML document and zero or more resources + + ESS_MAX }; // Determine the type of essence contained in the given MXF file. RESULT_OK // is returned if the file is successfully opened and contains a valid MXF // stream. If there is an error, the result code will indicate the reason. - Result_t EssenceType(const char* filename, EssenceType_t& type); + Result_t EssenceType(const std::string& filename, EssenceType_t& type); // Determine the type of essence contained in the given raw file. RESULT_OK // is returned if the file is successfully opened and contains a known // stream type. If there is an error, the result code will indicate the reason. - Result_t RawEssenceType(const char* filename, EssenceType_t& type); + Result_t RawEssenceType(const std::string& filename, EssenceType_t& type); //--------------------------------------------------------------------------------- @@ -254,7 +266,7 @@ namespace ASDCP { if ( Numerator == rhs.Numerator && Denominator < rhs.Denominator ) return true; return false; } - + inline bool operator>(const Rational& rhs) { if ( Numerator > rhs.Numerator ) return true; if ( Numerator == rhs.Numerator && Denominator > rhs.Denominator ) return true; @@ -262,6 +274,16 @@ namespace ASDCP { } }; + // Encodes a rational number as a string having a single delimiter character between + // numerator and denominator. Retuns the buffer pointer to allow convenient in-line use. + const char* EncodeRational(const Rational&, char* str_buf, ui32_t buf_len, char delimiter = ' '); + + // Decodes a rational number havng a single non-digit delimiter character between + // the numerator and denominator. Returns false if the string does not contain + // the expected syntax. + bool DecodeRational(const char* str_rat, Rational&); + + // common edit rates, use these instead of hard coded constants const Rational EditRate_24 = Rational(24,1); const Rational EditRate_23_98 = Rational(24000,1001); // Not a DCI-compliant value! @@ -280,6 +302,15 @@ namespace ASDCP { const Rational EditRate_100 = Rational(100,1); const Rational EditRate_120 = Rational(120,1); + // Archival frame rates, see ST 428-21 + // These rates are new and not supported by all systems. Do not assume that + // a package made using one of these rates will work just anywhere! + const Rational EditRate_16 = Rational(16,1); + const Rational EditRate_18 = Rational(200,11); // 18.182 + const Rational EditRate_20 = Rational(20,1); + const Rational EditRate_22 = Rational(240,11); // 21.818 + + // Non-reference counting container for internal member objects. // Please do not use this class for any other purpose. template <class T> @@ -335,7 +366,8 @@ namespace ASDCP { { LS_MXF_UNKNOWN, LS_MXF_INTEROP, - LS_MXF_SMPTE + LS_MXF_SMPTE, + LS_MAX }; // @@ -357,7 +389,7 @@ namespace ASDCP { static byte_t default_ProductUUID_Data[UUIDlen] = { 0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01, 0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d }; - + memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen); memset(AssetUUID, 0, UUIDlen); memset(ContextID, 0, UUIDlen); @@ -399,7 +431,7 @@ namespace ASDCP { // Initializes Rijndael CBC encryption context. // Returns error if the key argument is NULL. Result_t InitKey(const byte_t* key); - + // Initializes 16 byte CBC Initialization Vector. This operation may be performed // any number of times for a given key. // Returns error if the i_vec argument is NULL. @@ -559,8 +591,9 @@ namespace ASDCP { namespace MXF { // #include<Metadata.h> to use these - class OPAtomHeader; + class OP1aHeader; class OPAtomIndexFooter; + class RIP; }; //--------------------------------------------------------------------------------- @@ -593,22 +626,22 @@ namespace ASDCP { // MPEG2VideoDescriptor object. struct VideoDescriptor { - Rational EditRate; // - ui32_t FrameRate; // - Rational SampleRate; // - ui8_t FrameLayout; // - ui32_t StoredWidth; // - ui32_t StoredHeight; // - Rational AspectRatio; // - ui32_t ComponentDepth; // - ui32_t HorizontalSubsampling; // - ui32_t VerticalSubsampling; // - ui8_t ColorSiting; // - ui8_t CodedContentType; // - bool LowDelay; // - ui32_t BitRate; // - ui8_t ProfileAndLevel; // - ui32_t ContainerDuration; // + Rational EditRate; // + ui32_t FrameRate; // + Rational SampleRate; // + ui8_t FrameLayout; // + ui32_t StoredWidth; // + ui32_t StoredHeight; // + Rational AspectRatio; // + ui32_t ComponentDepth; // + ui32_t HorizontalSubsampling; // + ui32_t VerticalSubsampling; // + ui8_t ColorSiting; // + ui8_t CodedContentType; // + bool LowDelay; // + ui32_t BitRate; // + ui8_t ProfileAndLevel; // + ui32_t ContainerDuration; // }; // Print VideoDescriptor to std::ostream @@ -638,7 +671,7 @@ namespace ASDCP { { Capacity(size); } - + virtual ~FrameBuffer() {} // Sets the MPEG frame type of the picture data in the frame buffer. @@ -689,7 +722,7 @@ namespace ASDCP { // Opens the stream for reading, parses enough data to provide a complete // set of stream metadata for the MXFWriter below. - Result_t OpenRead(const char* filename) const; + Result_t OpenRead(const std::string& filename) const; // Fill a VideoDescriptor struct with the values from the file's header. // Returns RESULT_INIT if the file is not open. @@ -720,13 +753,14 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed or if nonsensical data is discovered // in the essence descriptor. - Result_t OpenWrite(const char* filename, const WriterInfo&, + Result_t OpenWrite(const std::string& filename, const WriterInfo&, const VideoDescriptor&, ui32_t HeaderSize = 16384); // Writes a frame of essence to the MXF file. If the optional AESEncContext @@ -752,12 +786,13 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. - Result_t OpenRead(const char* filename) const; + Result_t OpenRead(const std::string& filename) const; // Returns RESULT_INIT if the file is not open. Result_t Close() const; @@ -779,6 +814,12 @@ namespace ASDCP { // out of range, or if optional decrypt or HAMC operations fail. Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const; + // Using the index table read from the footer partition, lookup the frame number + // and return the offset into the file at which to read that frame of essence. + // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is + // out of range. + Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const; + // Calculates the first frame in transport order of the GOP in which the requested // frame is located. Calls ReadFrame() to fetch the frame at the calculated position. // Returns RESULT_INIT if the file is not open. @@ -822,18 +863,20 @@ namespace ASDCP { CF_CFG_3, // 7.1 (SDDS) with optional HI/VI CF_CFG_4, // Wild Track Format CF_CFG_5, // 7.1 DS with optional HI/VI + CF_CFG_6, // ST 377-4 (MCA) labels (see also ASDCP::MXF::decode_mca_string) + CF_MAXIMUM }; struct AudioDescriptor { Rational EditRate; // rate of frame wrapping Rational AudioSamplingRate; // rate of audio sample - ui32_t Locked; // + ui32_t Locked; // ui32_t ChannelCount; // number of channels ui32_t QuantizationBits; // number of bits per single-channel sample ui32_t BlockAlign; // number of bytes ber sample, all channels - ui32_t AvgBps; // - ui32_t LinkedTrackID; // + ui32_t AvgBps; // + ui32_t LinkedTrackID; // ui32_t ContainerDuration; // number of frames ChannelFormat_t ChannelFormat; // audio channel arrangement }; @@ -869,7 +912,7 @@ namespace ASDCP { FrameBuffer() {} FrameBuffer(ui32_t size) { Capacity(size); } virtual ~FrameBuffer() {} - + // Print debugging information to stream (stderr default) void Dump(FILE* = 0, ui32_t dump_bytes = 0) const; }; @@ -891,7 +934,7 @@ namespace ASDCP { // Opens the stream for reading, parses enough data to provide a complete // set of stream metadata for the MXFWriter below. PictureRate controls // ther frame rate for the MXF frame wrapping option. - Result_t OpenRead(const char* filename, const Rational& PictureRate) const; + Result_t OpenRead(const std::string& filename, const Rational& PictureRate) const; // Fill an AudioDescriptor struct with the values from the file's header. // Returns RESULT_INIT if the file is not open. @@ -919,13 +962,14 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed or if nonsensical data is discovered // in the essence descriptor. - Result_t OpenWrite(const char* filename, const WriterInfo&, + Result_t OpenWrite(const std::string& filename, const WriterInfo&, const AudioDescriptor&, ui32_t HeaderSize = 16384); // Writes a frame of essence to the MXF file. If the optional AESEncContext @@ -951,12 +995,13 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. - Result_t OpenRead(const char* filename) const; + Result_t OpenRead(const std::string& filename) const; // Returns RESULT_INIT if the file is not open. Result_t Close() const; @@ -978,6 +1023,12 @@ namespace ASDCP { // out of range, or if optional decrypt or HAMC operations fail. Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const; + // Using the index table read from the footer partition, lookup the frame number + // and return the offset into the file at which to read that frame of essence. + // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is + // out of range. + Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const; + // Print debugging information to stream void DumpHeaderMetadata(FILE* = 0) const; void DumpIndex(FILE* = 0) const; @@ -1010,7 +1061,7 @@ namespace ASDCP { ui8_t NumberOfLayers[sizeof(ui16_t)]; ui8_t MultiCompTransform; } SGcod; - + struct { ui8_t DecompositionLevels; @@ -1065,7 +1116,7 @@ namespace ASDCP { FrameBuffer() {} FrameBuffer(ui32_t size) { Capacity(size); } virtual ~FrameBuffer() {} - + // Print debugging information to stream (stderr default) void Dump(FILE* = 0, ui32_t dump_bytes = 0) const; }; @@ -1089,9 +1140,7 @@ namespace ASDCP { // The frame buffer's PlaintextOffset parameter will be set to the first // byte of the data segment. Set this value to zero if you want // encrypted headers. - Result_t OpenReadFrame(const char* filename, FrameBuffer&) const; - - Result_t OpenReadFrame(const unsigned char * data, unsigned int size, FrameBuffer&) const; + Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const; // Fill a PictureDescriptor struct with the values from the file's codestream. // Returns RESULT_INIT if the file is not open. @@ -1119,16 +1168,16 @@ namespace ASDCP { // alphabetically by filename. The parser will automatically parse enough data // from the first file to provide a complete set of stream metadata for the // MXFWriter below. If the "pedantic" parameter is given and is true, the - // parser will check the metadata for each codestream and fail if a + // parser will check the metadata for each codestream and fail if a // mismatch is detected. - Result_t OpenRead(const char* filename, bool pedantic = false) const; + Result_t OpenRead(const std::string& filename, bool pedantic = false) const; // Opens a file sequence for reading. The sequence is expected to contain one or // more filenames, each naming a file containing the codestream for exactly one // picture. The parser will automatically parse enough data // from the first file to provide a complete set of stream metadata for the // MXFWriter below. If the "pedantic" parameter is given and is true, the - // parser will check the metadata for each codestream and fail if a + // parser will check the metadata for each codestream and fail if a // mismatch is detected. Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const; @@ -1162,29 +1211,24 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); - // Open the file for writing. The file must not exist unless overwrite is true. Returns error if + // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed or if nonsensical data is discovered // in the essence descriptor. - Result_t OpenWrite(const char* filename, const WriterInfo&, - const PictureDescriptor&, ui32_t HeaderSize, bool overwrite); + Result_t OpenWrite(const std::string& filename, const WriterInfo&, + const PictureDescriptor&, ui32_t HeaderSize = 16384); // Writes a frame of essence to the MXF file. If the optional AESEncContext // argument is present, the essence is encrypted prior to writing. - // A MD5 hash of the data that we write is written to hash if it is not 0 // Fails if the file is not open, is finalized, or an operating system // error occurs. - Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0, std::string* hash = 0); - - Result_t FakeWriteFrame(int size); + Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); // Closes the MXF file, writing the index and revised header. Result_t Finalize(); - - // Return the current file offset in the MXF file that we are writing - ui64_t Tell() const; }; // @@ -1200,12 +1244,13 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. - Result_t OpenRead(const char* filename) const; + Result_t OpenRead(const std::string& filename) const; // Returns RESULT_INIT if the file is not open. Result_t Close() const; @@ -1227,6 +1272,12 @@ namespace ASDCP { // out of range, or if optional decrypt or HAMC operations fail. Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const; + // Using the index table read from the footer partition, lookup the frame number + // and return the offset into the file at which to read that frame of essence. + // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is + // out of range. + Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const; + // Print debugging information to stream void DumpHeaderMetadata(FILE* = 0) const; void DumpIndex(FILE* = 0) const; @@ -1241,7 +1292,7 @@ namespace ASDCP { SP_LEFT, SP_RIGHT }; - + struct SFrameBuffer { JP2K::FrameBuffer Left; @@ -1265,14 +1316,15 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); - // Open the file for writing. The file must not exist unless overwrite is true. Returns error if + // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed or if nonsensical data is discovered // in the essence descriptor. - Result_t OpenWrite(const char* filename, const WriterInfo&, - const PictureDescriptor&, ui32_t HeaderSize, bool overwrite); + Result_t OpenWrite(const std::string& filename, const WriterInfo&, + const PictureDescriptor&, ui32_t HeaderSize = 16384); // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext // argument is present, the essence is encrypted prior to writing. @@ -1287,16 +1339,11 @@ namespace ASDCP { // RESULT_SPHASE will be returned if phase is reversed. The first frame // written must be left eye. Result_t WriteFrame(const FrameBuffer&, StereoscopicPhase_t phase, - AESEncContext* = 0, HMACContext* = 0, std::string* hash = 0); + AESEncContext* = 0, HMACContext* = 0); - Result_t FakeWriteFrame(int size, StereoscopicPhase_t phase); - // Closes the MXF file, writing the index and revised header. Returns // RESULT_SPHASE if WriteFrame was called an odd number of times. Result_t Finalize(); - - // Return the current file offset in the MXF file that we are writing - ui64_t Tell() const; }; // @@ -1312,12 +1359,13 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. - Result_t OpenRead(const char* filename) const; + Result_t OpenRead(const std::string& filename) const; // Returns RESULT_INIT if the file is not open. Result_t Close() const; @@ -1349,6 +1397,12 @@ namespace ASDCP { Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const; + // Using the index table read from the footer partition, lookup the frame number + // and return the offset into the file at which to read that frame of essence. + // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is + // out of range. + Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const; + // Print debugging information to stream void DumpHeaderMetadata(FILE* = 0) const; void DumpIndex(FILE* = 0) const; @@ -1364,7 +1418,7 @@ namespace ASDCP { struct TimedTextResourceDescriptor { byte_t ResourceID[UUIDlen]; - MIMEType_t Type; + MIMEType_t Type; TimedTextResourceDescriptor() : Type(MT_BIN) {} }; @@ -1373,7 +1427,7 @@ namespace ASDCP { struct TimedTextDescriptor { - Rational EditRate; // + Rational EditRate; // ui32_t ContainerDuration; byte_t AssetID[UUIDlen]; std::string NamespaceName; @@ -1401,7 +1455,7 @@ namespace ASDCP { FrameBuffer() { memset(m_AssetID, 0, UUIDlen); } FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); } virtual ~FrameBuffer() {} - + inline const byte_t* AssetID() const { return m_AssetID; } inline void AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); } inline const char* MIMEType() const { return m_MIMEType.c_str(); } @@ -1411,6 +1465,8 @@ namespace ASDCP { void Dump(FILE* = 0, ui32_t dump_bytes = 0) const; }; + // An abstract base for a lookup service that returns the resource data + // identified by the given ancillary resource id. // class IResourceResolver { @@ -1419,6 +1475,21 @@ namespace ASDCP { virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID }; + // Resolves resource references by testing the named directory for file names containing + // the respective UUID. + // + class LocalFilenameResolver : public ASDCP::TimedText::IResourceResolver + { + std::string m_Dirname; + ASDCP_NO_COPY_CONSTRUCT(LocalFilenameResolver); + + public: + LocalFilenameResolver(); + virtual ~LocalFilenameResolver(); + Result_t OpenRead(const std::string& dirname); + Result_t ResolveRID(const byte_t* uuid, FrameBuffer& FrameBuf) const; + }; + // class DCSubtitleParser { @@ -1432,12 +1503,12 @@ namespace ASDCP { // Opens an XML file for reading, parses data to provide a complete // set of stream metadata for the MXFWriter below. - Result_t OpenRead(const char* filename) const; + Result_t OpenRead(const std::string& filename) const; // Parses an XML document to provide a complete set of stream metadata // for the MXFWriter below. The optional filename argument is used to // initialize the default resource resolver (see ReadAncillaryResource). - Result_t OpenRead(const std::string& xml_doc, const char* filename = 0) const; + Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const; // Fill a TimedTextDescriptor struct with the values from the file's contents. // Returns RESULT_INIT if the file is not open. @@ -1470,13 +1541,14 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed or if nonsensical data is discovered // in the essence descriptor. - Result_t OpenWrite(const char* filename, const WriterInfo&, + Result_t OpenWrite(const std::string& filename, const WriterInfo&, const TimedTextDescriptor&, ui32_t HeaderSize = 16384); // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8 @@ -1512,12 +1584,13 @@ namespace ASDCP { // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! - virtual MXF::OPAtomHeader& OPAtomHeader(); + virtual MXF::OP1aHeader& OP1aHeader(); virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. - Result_t OpenRead(const char* filename) const; + Result_t OpenRead(const std::string& filename) const; // Returns RESULT_INIT if the file is not open. Result_t Close() const; @@ -1559,6 +1632,294 @@ namespace ASDCP { }; } // namespace TimedText + //--------------------------------------------------------------------------------- + // + namespace DCData + { + struct DCDataDescriptor + { + Rational EditRate; // Sample rate + ui32_t ContainerDuration; // number of frames + byte_t AssetID[UUIDlen]; // The UUID for the DCData track + byte_t DataEssenceCoding[UUIDlen]; // The coding for the data carried + }; + + // Print DCDataDescriptor to std::ostream + std::ostream& operator << (std::ostream& strm, const DCDataDescriptor& ddesc); + // Print debugging information to stream (stderr default) + void DCDataDescriptorDump(const DCDataDescriptor&, FILE* = 0); + + // + class FrameBuffer : public ASDCP::FrameBuffer + { + public: + FrameBuffer() {} + FrameBuffer(ui32_t size) { Capacity(size); } + virtual ~FrameBuffer() {} + + // Print debugging information to stream (stderr default) + void Dump(FILE* = 0, ui32_t dump_bytes = 0) const; + }; + + // An object which opens and reads a DC Data file. The file is expected + // to contain exactly one complete frame of DC data essence as an unwrapped (raw) + // byte stream. + class BytestreamParser + { + class h__BytestreamParser; + mem_ptr<h__BytestreamParser> m_Parser; + ASDCP_NO_COPY_CONSTRUCT(BytestreamParser); + + public: + BytestreamParser(); + virtual ~BytestreamParser(); + + // Opens a file for reading, parses enough data to provide a complete + // set of stream metadata for the MXFWriter below. + // The frame buffer's PlaintextOffset parameter will be set to the first + // byte of the data segment. Set this value to zero if you want + // encrypted headers. + Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const; + + // Fill a DCDataDescriptor struct with the values from the file's bytestream. + // Returns RESULT_INIT if the file is not open. + Result_t FillDCDataDescriptor(DCDataDescriptor&) const; + }; + + // An object which reads a sequence of files containing DC Data. + class SequenceParser + { + class h__SequenceParser; + mem_ptr<h__SequenceParser> m_Parser; + ASDCP_NO_COPY_CONSTRUCT(SequenceParser); + + public: + SequenceParser(); + virtual ~SequenceParser(); + + // Opens a directory for reading. The directory is expected to contain one or + // more files, each containing the bytestream for exactly one frame. The files + // must be named such that the frames are in temporal order when sorted + // alphabetically by filename. + Result_t OpenRead(const std::string& filename) const; + + // Opens a file sequence for reading. The sequence is expected to contain one or + // more filenames, each naming a file containing the bytestream for exactly one + // frame. + Result_t OpenRead(const std::list<std::string>& file_list) const; + + // Fill a DCDataDescriptor struct with default values. + // Returns RESULT_INIT if the directory is not open. + Result_t FillDCDataDescriptor(DCDataDescriptor&) const; + + // Rewind the directory to the beginning. + Result_t Reset() const; + + // Reads the next sequential frame in the directory and places it in the + // frame buffer. Fails if the buffer is too small or the direcdtory + // contains no more files. + // The frame buffer's PlaintextOffset parameter will be set to the first + // byte of the data segment. Set this value to zero if you want + // encrypted headers. + Result_t ReadFrame(FrameBuffer&) const; + }; + + // + class MXFWriter + { + class h__Writer; + mem_ptr<h__Writer> m_Writer; + ASDCP_NO_COPY_CONSTRUCT(MXFWriter); + + public: + MXFWriter(); + virtual ~MXFWriter(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual MXF::OP1aHeader& OP1aHeader(); + virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); + + // Open the file for writing. The file must not exist. Returns error if + // the operation cannot be completed or if nonsensical data is discovered + // in the essence descriptor. + Result_t OpenWrite(const std::string& filename, const WriterInfo&, + const DCDataDescriptor&, ui32_t HeaderSize = 16384); + + // Writes a frame of essence to the MXF file. If the optional AESEncContext + // argument is present, the essence is encrypted prior to writing. + // Fails if the file is not open, is finalized, or an operating system + // error occurs. + Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); + + // Closes the MXF file, writing the index and revised header. + Result_t Finalize(); + }; + + // + class MXFReader + { + class h__Reader; + mem_ptr<h__Reader> m_Reader; + ASDCP_NO_COPY_CONSTRUCT(MXFReader); + + public: + MXFReader(); + virtual ~MXFReader(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual MXF::OP1aHeader& OP1aHeader(); + virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); + + // Open the file for reading. The file must exist. Returns error if the + // operation cannot be completed. + Result_t OpenRead(const std::string& filename) const; + + // Returns RESULT_INIT if the file is not open. + Result_t Close() const; + + // Fill a DCDataDescriptor struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillDCDataDescriptor(DCDataDescriptor&) const; + + // Fill a WriterInfo struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillWriterInfo(WriterInfo&) const; + + // Reads a frame of essence from the MXF file. If the optional AESEncContext + // argument is present, the essence is decrypted after reading. If the MXF + // file is encrypted and the AESDecContext argument is NULL, the frame buffer + // will contain the ciphertext frame data. If the HMACContext argument is + // not NULL, the HMAC will be calculated (if the file supports it). + // Returns RESULT_INIT if the file is not open, failure if the frame number is + // out of range, or if optional decrypt or HAMC operations fail. + Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const; + + // Using the index table read from the footer partition, lookup the frame number + // and return the offset into the file at which to read that frame of essence. + // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is + // out of range. + Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const; + + // Print debugging information to stream + void DumpHeaderMetadata(FILE* = 0) const; + void DumpIndex(FILE* = 0) const; + }; + + } // namespace DCData + + //--------------------------------------------------------------------------------- + // + namespace ATMOS + { + struct AtmosDescriptor : public DCData::DCDataDescriptor + { + ui32_t FirstFrame; // Frame number of the frame to align with the FFOA of the picture track + ui16_t MaxChannelCount; // Max number of channels in bitstream + ui16_t MaxObjectCount; // Max number of objects in bitstream + byte_t AtmosID[UUIDlen]; // UUID of Atmos Project + ui8_t AtmosVersion; // ATMOS Coder Version used to create bitstream + }; + + // Print AtmosDescriptor to std::ostream + std::ostream& operator << (std::ostream& strm, const AtmosDescriptor& adesc); + // Print debugging information to stream (stderr default) + void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0); + // Determine if a file is a raw atmos file + bool IsDolbyAtmos(const std::string& filename); + + // + class MXFWriter + { + + class h__Writer; + mem_ptr<h__Writer> m_Writer; + ASDCP_NO_COPY_CONSTRUCT(MXFWriter); + + public: + MXFWriter(); + virtual ~MXFWriter(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual MXF::OP1aHeader& OP1aHeader(); + virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); + + // Open the file for writing. The file must not exist. Returns error if + // the operation cannot be completed or if nonsensical data is discovered + // in the essence descriptor. + Result_t OpenWrite(const std::string& filename, const WriterInfo&, + const AtmosDescriptor&, ui32_t HeaderSize = 16384); + + // Writes a frame of essence to the MXF file. If the optional AESEncContext + // argument is present, the essence is encrypted prior to writing. + // Fails if the file is not open, is finalized, or an operating system + // error occurs. + Result_t WriteFrame(const DCData::FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); + + // Closes the MXF file, writing the index and revised header. + Result_t Finalize(); + }; + + // + class MXFReader + { + class h__Reader; + mem_ptr<h__Reader> m_Reader; + ASDCP_NO_COPY_CONSTRUCT(MXFReader); + + public: + MXFReader(); + virtual ~MXFReader(); + + // Warning: direct manipulation of MXF structures can interfere + // with the normal operation of the wrapper. Caveat emptor! + virtual MXF::OP1aHeader& OP1aHeader(); + virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter(); + virtual MXF::RIP& RIP(); + + // Open the file for reading. The file must exist. Returns error if the + // operation cannot be completed. + Result_t OpenRead(const std::string& filename) const; + + // Returns RESULT_INIT if the file is not open. + Result_t Close() const; + + // Fill an AtmosDescriptor struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillAtmosDescriptor(AtmosDescriptor&) const; + + // Fill a WriterInfo struct with the values from the file's header. + // Returns RESULT_INIT if the file is not open. + Result_t FillWriterInfo(WriterInfo&) const; + + // Reads a frame of essence from the MXF file. If the optional AESEncContext + // argument is present, the essence is decrypted after reading. If the MXF + // file is encrypted and the AESDecContext argument is NULL, the frame buffer + // will contain the ciphertext frame data. If the HMACContext argument is + // not NULL, the HMAC will be calculated (if the file supports it). + // Returns RESULT_INIT if the file is not open, failure if the frame number is + // out of range, or if optional decrypt or HAMC operations fail. + Result_t ReadFrame(ui32_t frame_number, DCData::FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const; + + // Using the index table read from the footer partition, lookup the frame number + // and return the offset into the file at which to read that frame of essence. + // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is + // out of range. + Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const; + + // Print debugging information to stream + void DumpHeaderMetadata(FILE* = 0) const; + void DumpIndex(FILE* = 0) const; + }; + + } // namespace ATMOS + + } // namespace ASDCP diff --git a/asdcplib/src/AS_DCP_AES.cpp b/asdcplib/src/AS_DCP_AES.cpp index bb2a4006..8af7a7b4 100755 --- a/asdcplib/src/AS_DCP_AES.cpp +++ b/asdcplib/src/AS_DCP_AES.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP_AES.h - \version $Id: AS_DCP_AES.cpp,v 1.13 2009/10/15 17:31:27 jhurst Exp $ + \version $Id: AS_DCP_AES.cpp,v 1.14 2014/03/14 21:53:38 jhurst Exp $ \brief AS-DCP library, AES wrapper */ @@ -58,6 +58,7 @@ print_ssl_error() class ASDCP::AESEncContext::h__AESContext : public AES_KEY { public: + Kumu::SymmetricKey m_KeyBuf; byte_t m_IVec[CBC_BLOCK_SIZE]; }; @@ -76,8 +77,9 @@ ASDCP::AESEncContext::InitKey(const byte_t* key) return RESULT_INIT; m_Context = new h__AESContext; + m_Context->m_KeyBuf.Set(key); - if ( AES_set_encrypt_key(key, KEY_SIZE_BITS, m_Context) ) + if ( AES_set_encrypt_key(m_Context->m_KeyBuf.Value(), KEY_SIZE_BITS, m_Context) ) { print_ssl_error(); return RESULT_CRYPT_INIT; @@ -159,6 +161,7 @@ ASDCP::AESEncContext::EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t class ASDCP::AESDecContext::h__AESContext : public AES_KEY { public: + Kumu::SymmetricKey m_KeyBuf; byte_t m_IVec[CBC_BLOCK_SIZE]; }; @@ -177,8 +180,9 @@ ASDCP::AESDecContext::InitKey(const byte_t* key) return RESULT_INIT; m_Context = new h__AESContext; + m_Context->m_KeyBuf.Set(key); - if ( AES_set_decrypt_key(key, KEY_SIZE_BITS, m_Context) ) + if ( AES_set_decrypt_key(m_Context->m_KeyBuf.Value(), KEY_SIZE_BITS, m_Context) ) { print_ssl_error(); return RESULT_CRYPT_INIT; diff --git a/asdcplib/src/AS_DCP_ATMOS.cpp b/asdcplib/src/AS_DCP_ATMOS.cpp new file mode 100644 index 00000000..7e1b853f --- /dev/null +++ b/asdcplib/src/AS_DCP_ATMOS.cpp @@ -0,0 +1,491 @@ +/* +Copyright (c) 2004-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_DCP_ATMOS.cpp + \version $Id: AS_DCP_ATMOS.cpp,v 1.4 2014/01/02 23:29:22 jhurst Exp $ + \brief AS-DCP library, Dolby Atmos essence reader and writer implementation +*/ + + +#include <iostream> + +#include "AS_DCP.h" +#include "AS_DCP_DCData_internal.h" +#include "AS_DCP_internal.h" + +namespace ASDCP +{ +namespace ATMOS +{ + static std::string ATMOS_PACKAGE_LABEL = "File Package: SMPTE-GC frame wrapping of Dolby ATMOS data"; + static std::string ATMOS_DEF_LABEL = "Dolby ATMOS Data Track"; + static byte_t ATMOS_ESSENCE_CODING[SMPTE_UL_LENGTH] = { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, + 0x0e, 0x09, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00 }; +} // namespace ATMOS +} // namespace ASDCP + +// +std::ostream& +ASDCP::ATMOS::operator << (std::ostream& strm, const AtmosDescriptor& ADesc) +{ + char str_buf[40]; + strm << " EditRate: " << ADesc.EditRate.Numerator << "/" << ADesc.EditRate.Denominator << std::endl; + strm << " ContainerDuration: " << (unsigned) ADesc.ContainerDuration << std::endl; + strm << " DataEssenceCoding: " << UL(ADesc.DataEssenceCoding).EncodeString(str_buf, 40) << std::endl; + strm << " AtmosVersion: " << (unsigned) ADesc.AtmosVersion << std::endl; + strm << " MaxChannelCount: " << (unsigned) ADesc.MaxChannelCount << std::endl; + strm << " MaxObjectCount: " << (unsigned) ADesc.MaxObjectCount << std::endl; + strm << " AtmosID: " << UUID(ADesc.AtmosID).EncodeString(str_buf, 40) << std::endl; + strm << " FirstFrame: " << (unsigned) ADesc.FirstFrame << std::endl; + return strm; +} + +// +void +ASDCP::ATMOS::AtmosDescriptorDump(const AtmosDescriptor& ADesc, FILE* stream) +{ + char str_buf[40]; + char atmosID_buf[40]; + if ( stream == 0 ) + stream = stderr; + + fprintf(stream, "\ + EditRate: %d/%d\n\ + ContainerDuration: %u\n\ + DataEssenceCoding: %s\n\ + AtmosVersion: %u\n\ + MaxChannelCount: %u\n\ + MaxObjectCount: %u\n\ + AtmosID: %s\n\ + FirsFrame: %u\n", + ADesc.EditRate.Numerator, ADesc.EditRate.Denominator, + ADesc.ContainerDuration, + UL(ADesc.DataEssenceCoding).EncodeString(str_buf, 40), + ADesc.AtmosVersion, + ADesc.MaxChannelCount, + ADesc.MaxObjectCount, + UUID(ADesc.AtmosID).EncodeString(atmosID_buf, 40), + ADesc.FirstFrame); +} + +// +bool +ASDCP::ATMOS::IsDolbyAtmos(const std::string& filename) +{ + // TODO + // For now use an atmos extension + bool result = ( 0 == (std::string("atmos").compare(Kumu::PathGetExtension(filename))) ); + return result; +} + + +//------------------------------------------------------------------------------------------ + + +class ASDCP::ATMOS::MXFReader::h__Reader : public ASDCP::DCData::h__Reader +{ + MXF::DolbyAtmosSubDescriptor* m_EssenceSubDescriptor; + + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + h__Reader(); + + public: + AtmosDescriptor m_ADesc; + + h__Reader(const Dictionary& d) : DCData::h__Reader(d), m_EssenceSubDescriptor(NULL), + m_ADesc() {} + virtual ~h__Reader() {} + Result_t OpenRead(const std::string&); + Result_t MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& ADesc); +}; + +ASDCP::Result_t +ASDCP::ATMOS::MXFReader::h__Reader::MD_to_Atmos_ADesc(ATMOS::AtmosDescriptor& ADesc) +{ + ASDCP_TEST_NULL(m_EssenceSubDescriptor); + Result_t result = MD_to_DCData_DDesc(ADesc); + if( ASDCP_SUCCESS(result) ) + { + MXF::DolbyAtmosSubDescriptor* ADescObj = m_EssenceSubDescriptor; + ADesc.MaxChannelCount = ADescObj->MaxChannelCount; + ADesc.MaxObjectCount = ADescObj->MaxObjectCount; + ::memcpy(ADesc.AtmosID, ADescObj->AtmosID.Value(), UUIDlen); + ADesc.AtmosVersion = ADescObj->AtmosVersion; + ADesc.FirstFrame = ADescObj->FirstFrame; + } + return result; +} + +// +// +ASDCP::Result_t +ASDCP::ATMOS::MXFReader::h__Reader::OpenRead(const std::string& filename) +{ + Result_t result = DCData::h__Reader::OpenRead(filename); + + if( ASDCP_SUCCESS(result) ) + { + + if (NULL == m_EssenceSubDescriptor) + { + InterchangeObject* iObj = NULL; + result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor), &iObj); + m_EssenceSubDescriptor = static_cast<MXF::DolbyAtmosSubDescriptor*>(iObj); + + if ( iObj == 0 ) + { + DefaultLogSink().Error("DolbyAtmosSubDescriptor object not found.\n"); + return RESULT_FORMAT; + } + } + + if ( ASDCP_SUCCESS(result) ) + { + result = MD_to_Atmos_ADesc(m_ADesc); + } + } + + return result; +} + + +//------------------------------------------------------------------------------------------ + +ASDCP::ATMOS::MXFReader::MXFReader() +{ + m_Reader = new h__Reader(DefaultSMPTEDict()); +} + + +ASDCP::ATMOS::MXFReader::~MXFReader() +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + m_Reader->Close(); +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +ASDCP::ATMOS::MXFReader::OP1aHeader() +{ + if ( m_Reader.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Reader->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OPAtomIndexFooter& +ASDCP::ATMOS::MXFReader::OPAtomIndexFooter() +{ + if ( m_Reader.empty() ) + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } + + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::ATMOS::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; +} + +// Open the file for reading. The file must exist. Returns error if the +// operation cannot be completed. +ASDCP::Result_t +ASDCP::ATMOS::MXFReader::OpenRead(const std::string& filename) const +{ + return m_Reader->OpenRead(filename); +} + +// +ASDCP::Result_t +ASDCP::ATMOS::MXFReader::ReadFrame(ui32_t FrameNum, DCData::FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + +ASDCP::Result_t +ASDCP::ATMOS::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const +{ + return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +ASDCP::ATMOS::MXFReader::FillAtmosDescriptor(AtmosDescriptor& ADesc) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + ADesc = m_Reader->m_ADesc; + return RESULT_OK; + } + + return RESULT_INIT; +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +ASDCP::ATMOS::MXFReader::FillWriterInfo(WriterInfo& Info) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + Info = m_Reader->m_Info; + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +void +ASDCP::ATMOS::MXFReader::DumpHeaderMetadata(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_HeaderPart.Dump(stream); +} + +// +void +ASDCP::ATMOS::MXFReader::DumpIndex(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_IndexAccess.Dump(stream); +} + +// +ASDCP::Result_t +ASDCP::ATMOS::MXFReader::Close() const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + m_Reader->Close(); + return RESULT_OK; + } + + return RESULT_INIT; +} + + +//------------------------------------------------------------------------------------------ + +// +class ASDCP::ATMOS::MXFWriter::h__Writer : public DCData::h__Writer +{ + MXF::DolbyAtmosSubDescriptor* m_EssenceSubDescriptor; + + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); + + public: + AtmosDescriptor m_ADesc; + + h__Writer(const Dictionary& d) : DCData::h__Writer(d), + m_EssenceSubDescriptor(NULL), m_ADesc() {} + + virtual ~h__Writer(){} + + Result_t OpenWrite(const std::string&, ui32_t HeaderSize, const AtmosDescriptor& ADesc); + Result_t Atmos_ADesc_to_MD(const AtmosDescriptor& ADesc); +}; + +// +ASDCP::Result_t +ASDCP::ATMOS::MXFWriter::h__Writer::Atmos_ADesc_to_MD(const AtmosDescriptor& ADesc) +{ + ASDCP_TEST_NULL(m_EssenceDescriptor); + ASDCP_TEST_NULL(m_EssenceSubDescriptor); + MXF::DolbyAtmosSubDescriptor * ADescObj = m_EssenceSubDescriptor; + ADescObj->MaxChannelCount = ADesc.MaxChannelCount; + ADescObj->MaxObjectCount = ADesc.MaxObjectCount; + ADescObj->AtmosID.Set(ADesc.AtmosID); + ADescObj->AtmosVersion = ADesc.AtmosVersion; + ADescObj->FirstFrame = ADesc.FirstFrame; + return RESULT_OK; +} + +// +ASDCP::Result_t +ASDCP::ATMOS::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize, const AtmosDescriptor& ADesc) +{ + + m_EssenceSubDescriptor = new DolbyAtmosSubDescriptor(m_Dict); + DCData::SubDescriptorList_t subDescriptors; + subDescriptors.push_back(m_EssenceSubDescriptor); + Result_t result = DCData::h__Writer::OpenWrite(filename, HeaderSize, subDescriptors); + if ( ASDCP_FAILURE(result) ) + delete m_EssenceSubDescriptor; + + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc = ADesc; + memcpy(m_ADesc.DataEssenceCoding, ATMOS_ESSENCE_CODING, SMPTE_UL_LENGTH); + result = Atmos_ADesc_to_MD(m_ADesc); + } + + return result; +} + + + + +//------------------------------------------------------------------------------------------ + +ASDCP::ATMOS::MXFWriter::MXFWriter() +{ +} + +ASDCP::ATMOS::MXFWriter::~MXFWriter() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +ASDCP::ATMOS::MXFWriter::OP1aHeader() +{ + if ( m_Writer.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Writer->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OPAtomIndexFooter& +ASDCP::ATMOS::MXFWriter::OPAtomIndexFooter() +{ + if ( m_Writer.empty() ) + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } + + return m_Writer->m_FooterPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::ATMOS::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +ASDCP::Result_t +ASDCP::ATMOS::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, + const AtmosDescriptor& ADesc, ui32_t HeaderSize) +{ + if ( Info.LabelSetType != LS_MXF_SMPTE ) + { + DefaultLogSink().Error("Atmos support requires LS_MXF_SMPTE\n"); + return RESULT_FORMAT; + } + + m_Writer = new h__Writer(DefaultSMPTEDict()); + m_Writer->m_Info = Info; + + Result_t result = m_Writer->OpenWrite(filename, HeaderSize, ADesc); + + if ( ASDCP_SUCCESS(result) ) + result = m_Writer->SetSourceStream(ADesc, ATMOS_ESSENCE_CODING, ATMOS_PACKAGE_LABEL, + ATMOS_DEF_LABEL); + + if ( ASDCP_FAILURE(result) ) + m_Writer.release(); + + return result; +} + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +ASDCP::Result_t +ASDCP::ATMOS::MXFWriter::WriteFrame(const DCData::FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC); +} + +// Closes the MXF file, writing the index and other closing information. +ASDCP::Result_t +ASDCP::ATMOS::MXFWriter::Finalize() +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->Finalize(); +} + + +// +// end AS_DCP_ATMOS.cpp +// + + diff --git a/asdcplib/src/AS_DCP_DCData.cpp b/asdcplib/src/AS_DCP_DCData.cpp new file mode 100644 index 00000000..9c0950e6 --- /dev/null +++ b/asdcplib/src/AS_DCP_DCData.cpp @@ -0,0 +1,586 @@ +/* +Copyright (c) 2004-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_DCP_DCData.cpp + \version $Id: AS_DCP_DCData.cpp,v 1.5 2014/01/02 23:29:22 jhurst Exp $ + \brief AS-DCP library, Dcinema generic data essence reader and writer implementation +*/ + +#include <iostream> + +#include "AS_DCP.h" +#include "AS_DCP_DCData_internal.h" +#include "AS_DCP_internal.h" + +namespace ASDCP +{ +namespace DCData +{ + static std::string DC_DATA_PACKAGE_LABEL = "File Package: SMPTE-GC frame wrapping of D-Cinema Generic data"; + static std::string DC_DATA_DEF_LABEL = "D-Cinema Generic Data Track"; +} // namespace DCData +} // namespace ASDCP + +// +std::ostream& +ASDCP::DCData::operator << (std::ostream& strm, const DCDataDescriptor& DDesc) +{ + char str_buf[40]; + strm << " EditRate: " << DDesc.EditRate.Numerator << "/" << DDesc.EditRate.Denominator << std::endl; + strm << " ContainerDuration: " << (unsigned) DDesc.ContainerDuration << std::endl; + strm << " DataEssenceCoding: " << UL(DDesc.DataEssenceCoding).EncodeString(str_buf, 40) << std::endl; + return strm; +} + +// +void +ASDCP::DCData::DCDataDescriptorDump(const DCDataDescriptor& DDesc, FILE* stream) +{ + char str_buf[40]; + if ( stream == 0 ) + stream = stderr; + + fprintf(stream, "\ + EditRate: %d/%d\n\ + ContainerDuration: %u\n\ + DataEssenceCoding: %s\n", + DDesc.EditRate.Numerator, DDesc.EditRate.Denominator, + DDesc.ContainerDuration, + UL(DDesc.DataEssenceCoding).EncodeString(str_buf, 40)); +} + + +//------------------------------------------------------------------------------------------ + + +ASDCP::Result_t +ASDCP::DCData::h__Reader::MD_to_DCData_DDesc(DCData::DCDataDescriptor& DDesc) +{ + ASDCP_TEST_NULL(m_EssenceDescriptor); + MXF::DCDataDescriptor* DDescObj = m_EssenceDescriptor; + DDesc.EditRate = DDescObj->SampleRate; + assert(DDescObj->ContainerDuration <= 0xFFFFFFFFL); + DDesc.ContainerDuration = static_cast<ui32_t>(DDescObj->ContainerDuration); + memcpy(DDesc.DataEssenceCoding, DDescObj->DataEssenceCoding.Value(), SMPTE_UL_LENGTH); + return RESULT_OK; +} + +// +// +ASDCP::Result_t +ASDCP::DCData::h__Reader::OpenRead(const std::string& filename) +{ + Result_t result = OpenMXFRead(filename); + + if( ASDCP_SUCCESS(result) ) + { + if (NULL == m_EssenceDescriptor) + { + InterchangeObject* iObj = NULL; + result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor), &iObj); + m_EssenceDescriptor = static_cast<MXF::DCDataDescriptor*>(iObj); + + if ( m_EssenceDescriptor == 0 ) + { + DefaultLogSink().Error("DCDataDescriptor object not found.\n"); + return RESULT_FORMAT; + } + } + + if ( ASDCP_SUCCESS(result) ) + { + result = MD_to_DCData_DDesc(m_DDesc); + } + } + + // check for sample/frame rate sanity + if ( ASDCP_SUCCESS(result) + && m_DDesc.EditRate != EditRate_24 + && m_DDesc.EditRate != EditRate_25 + && m_DDesc.EditRate != EditRate_30 + && m_DDesc.EditRate != EditRate_48 + && m_DDesc.EditRate != EditRate_50 + && m_DDesc.EditRate != EditRate_60 + && m_DDesc.EditRate != EditRate_96 + && m_DDesc.EditRate != EditRate_100 + && m_DDesc.EditRate != EditRate_120 ) + { + DefaultLogSink().Error("DC Data file EditRate is not a supported value: %d/%d\n", // lu + m_DDesc.EditRate.Numerator, m_DDesc.EditRate.Denominator); + + return RESULT_FORMAT; + } + + return result; +} + +// +// +ASDCP::Result_t +ASDCP::DCData::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) +{ + if ( ! m_File.IsOpen() ) + return RESULT_INIT; + + assert(m_Dict); + return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_DCDataEssence), Ctx, HMAC); +} + + +// +//------------------------------------------------------------------------------------------ + +class ASDCP::DCData::MXFReader::h__Reader : public DCData::h__Reader +{ + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + h__Reader(); + + public: + h__Reader(const Dictionary& d) : DCData::h__Reader(d) {} + virtual ~h__Reader() {} +}; + + +//------------------------------------------------------------------------------------------ + + +// +void +ASDCP::DCData::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const +{ + if ( stream == 0 ) + stream = stderr; + + fprintf(stream, "Frame: %06u, %7u bytes\n", m_FrameNumber, m_Size); + + if ( dump_len > 0 ) + Kumu::hexdump(m_Data, dump_len, stream); +} + + +//------------------------------------------------------------------------------------------ + +ASDCP::DCData::MXFReader::MXFReader() +{ + m_Reader = new h__Reader(DefaultSMPTEDict()); +} + + +ASDCP::DCData::MXFReader::~MXFReader() +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + m_Reader->Close(); +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +ASDCP::DCData::MXFReader::OP1aHeader() +{ + if ( m_Reader.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Reader->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OPAtomIndexFooter& +ASDCP::DCData::MXFReader::OPAtomIndexFooter() +{ + if ( m_Reader.empty() ) + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } + + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::DCData::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; +} + +// Open the file for reading. The file must exist. Returns error if the +// operation cannot be completed. +ASDCP::Result_t +ASDCP::DCData::MXFReader::OpenRead(const std::string& filename) const +{ + return m_Reader->OpenRead(filename); +} + +// +ASDCP::Result_t +ASDCP::DCData::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, + AESDecContext* Ctx, HMACContext* HMAC) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + return m_Reader->ReadFrame(FrameNum, FrameBuf, Ctx, HMAC); + + return RESULT_INIT; +} + +ASDCP::Result_t +ASDCP::DCData::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const +{ + return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +ASDCP::DCData::MXFReader::FillDCDataDescriptor(DCDataDescriptor& DDesc) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + DDesc = m_Reader->m_DDesc; + return RESULT_OK; + } + + return RESULT_INIT; +} + + +// Fill the struct with the values from the file's header. +// Returns RESULT_INIT if the file is not open. +ASDCP::Result_t +ASDCP::DCData::MXFReader::FillWriterInfo(WriterInfo& Info) const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + Info = m_Reader->m_Info; + return RESULT_OK; + } + + return RESULT_INIT; +} + +// +void +ASDCP::DCData::MXFReader::DumpHeaderMetadata(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_HeaderPart.Dump(stream); +} + + +// +void +ASDCP::DCData::MXFReader::DumpIndex(FILE* stream) const +{ + if ( m_Reader->m_File.IsOpen() ) + m_Reader->m_IndexAccess.Dump(stream); +} + +// +ASDCP::Result_t +ASDCP::DCData::MXFReader::Close() const +{ + if ( m_Reader && m_Reader->m_File.IsOpen() ) + { + m_Reader->Close(); + return RESULT_OK; + } + + return RESULT_INIT; +} + + +//------------------------------------------------------------------------------------------ + + +// +ASDCP::Result_t +ASDCP::DCData::h__Writer::DCData_DDesc_to_MD(DCData::DCDataDescriptor& DDesc) +{ + ASDCP_TEST_NULL(m_EssenceDescriptor); + MXF::DCDataDescriptor* DDescObj = static_cast<MXF::DCDataDescriptor *>(m_EssenceDescriptor); + + DDescObj->SampleRate = DDesc.EditRate; + DDescObj->ContainerDuration = DDesc.ContainerDuration; + DDescObj->DataEssenceCoding.Set(DDesc.DataEssenceCoding); + + return RESULT_OK; +} + +// +ASDCP::Result_t +ASDCP::DCData::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize, + const SubDescriptorList_t& subDescriptors) +{ + if ( ! m_State.Test_BEGIN() ) + return RESULT_STATE; + + Result_t result = m_File.OpenWrite(filename); + + if ( ASDCP_SUCCESS(result) ) + { + m_HeaderSize = HeaderSize; + m_EssenceDescriptor = new MXF::DCDataDescriptor(m_Dict); + SubDescriptorList_t::const_iterator sDObj; + SubDescriptorList_t::const_iterator lastDescriptor = subDescriptors.end(); + for (sDObj = subDescriptors.begin(); sDObj != lastDescriptor; ++sDObj) + { + m_EssenceSubDescriptorList.push_back(*sDObj); + GenRandomValue((*sDObj)->InstanceUID); + m_EssenceDescriptor->SubDescriptors.push_back((*sDObj)->InstanceUID); + } + result = m_State.Goto_INIT(); + } + + return result; +} + +// +ASDCP::Result_t +ASDCP::DCData::h__Writer::SetSourceStream(DCDataDescriptor const& DDesc, + const byte_t * essenceCoding, + const std::string& packageLabel, + const std::string& defLabel) +{ + if ( ! m_State.Test_INIT() ) + return RESULT_STATE; + + if ( DDesc.EditRate != EditRate_24 + && DDesc.EditRate != EditRate_25 + && DDesc.EditRate != EditRate_30 + && DDesc.EditRate != EditRate_48 + && DDesc.EditRate != EditRate_50 + && DDesc.EditRate != EditRate_60 + && DDesc.EditRate != EditRate_96 + && DDesc.EditRate != EditRate_100 + && DDesc.EditRate != EditRate_120 ) + { + DefaultLogSink().Error("DCDataDescriptor.EditRate is not a supported value: %d/%d\n", + DDesc.EditRate.Numerator, DDesc.EditRate.Denominator); + return RESULT_RAW_FORMAT; + } + + assert(m_Dict); + m_DDesc = DDesc; + if (NULL != essenceCoding) + memcpy(m_DDesc.DataEssenceCoding, essenceCoding, SMPTE_UL_LENGTH); + Result_t result = DCData_DDesc_to_MD(m_DDesc); + + if ( ASDCP_SUCCESS(result) ) + { + memcpy(m_EssenceUL, m_Dict->ul(MDD_DCDataEssence), SMPTE_UL_LENGTH); + m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container + result = m_State.Goto_READY(); + } + + if ( ASDCP_SUCCESS(result) ) + { + ui32_t TCFrameRate = m_DDesc.EditRate.Numerator; + + result = WriteASDCPHeader(packageLabel, UL(m_Dict->ul(MDD_DCDataWrappingFrame)), + defLabel, UL(m_EssenceUL), UL(m_Dict->ul(MDD_DataDataDef)), + m_DDesc.EditRate, TCFrameRate); + } + + return result; +} + +// +ASDCP::Result_t +ASDCP::DCData::h__Writer::WriteFrame(const FrameBuffer& FrameBuf, + ASDCP::AESEncContext* Ctx, ASDCP::HMACContext* HMAC) +{ + Result_t result = RESULT_OK; + + if ( m_State.Test_READY() ) + result = m_State.Goto_RUNNING(); // first time through + + ui64_t StreamOffset = m_StreamOffset; + + if ( ASDCP_SUCCESS(result) ) + result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC); + + if ( ASDCP_SUCCESS(result) ) + { + IndexTableSegment::IndexEntry Entry; + Entry.StreamOffset = StreamOffset; + m_FooterPart.PushIndexEntry(Entry); + m_FramesWritten++; + } + return result; +} + +// Closes the MXF file, writing the index and other closing information. +// +ASDCP::Result_t +ASDCP::DCData::h__Writer::Finalize() +{ + if ( ! m_State.Test_RUNNING() ) + return RESULT_STATE; + + m_State.Goto_FINAL(); + + return WriteASDCPFooter(); +} + + +// +//------------------------------------------------------------------------------------------ + + +class ASDCP::DCData::MXFWriter::h__Writer : public DCData::h__Writer +{ + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); + + public: + h__Writer(const Dictionary& d) : DCData::h__Writer(d) {} + virtual ~h__Writer() {} +}; + + +//------------------------------------------------------------------------------------------ + +ASDCP::DCData::MXFWriter::MXFWriter() +{ +} + +ASDCP::DCData::MXFWriter::~MXFWriter() +{ +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OP1aHeader& +ASDCP::DCData::MXFWriter::OP1aHeader() +{ + if ( m_Writer.empty() ) + { + assert(g_OP1aHeader); + return *g_OP1aHeader; + } + + return m_Writer->m_HeaderPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::OPAtomIndexFooter& +ASDCP::DCData::MXFWriter::OPAtomIndexFooter() +{ + if ( m_Writer.empty() ) + { + assert(g_OPAtomIndexFooter); + return *g_OPAtomIndexFooter; + } + + return m_Writer->m_FooterPart; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::DCData::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + +// Open the file for writing. The file must not exist. Returns error if +// the operation cannot be completed. +ASDCP::Result_t +ASDCP::DCData::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, + const DCDataDescriptor& DDesc, ui32_t HeaderSize) +{ + if ( Info.LabelSetType != LS_MXF_SMPTE ) + { + DefaultLogSink().Error("DC Data support requires LS_MXF_SMPTE\n"); + return RESULT_FORMAT; + } + + m_Writer = new h__Writer(DefaultSMPTEDict()); + m_Writer->m_Info = Info; + + Result_t result = m_Writer->OpenWrite(filename, HeaderSize, SubDescriptorList_t()); + + if ( ASDCP_SUCCESS(result) ) + result = m_Writer->SetSourceStream(DDesc, NULL, DC_DATA_PACKAGE_LABEL, DC_DATA_DEF_LABEL); + + if ( ASDCP_FAILURE(result) ) + m_Writer.release(); + + return result; +} + +// Writes a frame of essence to the MXF file. If the optional AESEncContext +// argument is present, the essence is encrypted prior to writing. +// Fails if the file is not open, is finalized, or an operating system +// error occurs. +ASDCP::Result_t +ASDCP::DCData::MXFWriter::WriteFrame(const FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->WriteFrame(FrameBuf, Ctx, HMAC); +} + +// Closes the MXF file, writing the index and other closing information. +ASDCP::Result_t +ASDCP::DCData::MXFWriter::Finalize() +{ + if ( m_Writer.empty() ) + return RESULT_INIT; + + return m_Writer->Finalize(); +} + + +// +// end AS_DCP_DCData.cpp +// diff --git a/asdcplib/src/AS_DCP_DCData_internal.h b/asdcplib/src/AS_DCP_DCData_internal.h new file mode 100644 index 00000000..c529b14b --- /dev/null +++ b/asdcplib/src/AS_DCP_DCData_internal.h @@ -0,0 +1,94 @@ +/* +Copyright (c) 2004-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AS_DCP_DCData_internal.h + \version $Id: AS_DCP_DCData_internal.h,v 1.3 2014/01/02 23:29:22 jhurst Exp $ + \brief AS-DCP library, non-public common DCData reader and writer implementation +*/ + +#ifndef _AS_DCP_DCDATA_INTERNAL_H_ +#define _AS_DCP_DCDATA_INTERNAL_H_ + +#include <list> + +#include "AS_DCP_internal.h" + +namespace ASDCP +{ + +namespace MXF +{ + class InterchangeObject; +} + +namespace DCData +{ + typedef std::list<MXF::InterchangeObject*> SubDescriptorList_t; + + class h__Reader : public ASDCP::h__ASDCPReader + { + MXF::DCDataDescriptor* m_EssenceDescriptor; + ASDCP_NO_COPY_CONSTRUCT(h__Reader); + h__Reader(); + + public: + DCDataDescriptor m_DDesc; + + h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), + m_DDesc() {} + ~h__Reader() {} + Result_t OpenRead(const std::string&); + Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); + Result_t MD_to_DCData_DDesc(DCData::DCDataDescriptor& DDesc); + }; + + class h__Writer : public ASDCP::h__ASDCPWriter + { + ASDCP_NO_COPY_CONSTRUCT(h__Writer); + h__Writer(); + + public: + DCDataDescriptor m_DDesc; + byte_t m_EssenceUL[SMPTE_UL_LENGTH]; + + h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d) { + memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); + } + + ~h__Writer(){} + + Result_t OpenWrite(const std::string&, ui32_t HeaderSize, const SubDescriptorList_t& subDescriptors); + Result_t SetSourceStream(const DCDataDescriptor&, const byte_t*, const std::string&, const std::string&); + Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); + Result_t Finalize(); + Result_t DCData_DDesc_to_MD(DCData::DCDataDescriptor& DDesc); +}; + + +} // namespace DCData +} // namespace ASDCP + +#endif // _AS_DCP_DCDATA_INTERNAL_H_ diff --git a/asdcplib/src/AS_DCP_JP2K.cpp b/asdcplib/src/AS_DCP_JP2K.cpp index 05166d68..58781d61 100755 --- a/asdcplib/src/AS_DCP_JP2K.cpp +++ b/asdcplib/src/AS_DCP_JP2K.cpp @@ -1,7 +1,5 @@ -/* -*- c-basic-offset: 2; -*- */ - /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -27,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP_JP2k.cpp - \version $Id: AS_DCP_JP2K.cpp,v 1.54 2012/02/07 18:54:24 jhurst Exp $ + \version $Id: AS_DCP_JP2K.cpp,v 1.69 2015/10/07 16:41:23 jhurst Exp $ \brief AS-DCP library, JPEG 2000 essence reader and writer implementation */ @@ -35,7 +33,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <iostream> #include <iomanip> -using std::cout; using namespace ASDCP::JP2K; using Kumu::GenRandomValue; @@ -72,7 +69,7 @@ ASDCP::JP2K::operator << (std::ostream& strm, const PictureDescriptor& PDesc) strm << " bits h-sep v-sep" << std::endl; ui32_t i; - for ( i = 0; i < PDesc.Csize; i++ ) + for ( i = 0; i < PDesc.Csize && i < MaxComponents; ++i ) { strm << " " << std::setw(4) << PDesc.ImageComponents[i].Ssize + 1 /* See ISO 15444-1, Table A11, for the origin of '+1' */ << " " << std::setw(5) << PDesc.ImageComponents[i].XRsize @@ -93,13 +90,13 @@ ASDCP::JP2K::operator << (std::ostream& strm, const PictureDescriptor& PDesc) ui32_t precinct_set_size = 0; - for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ ) + for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; ++i ) precinct_set_size++; strm << " Precincts: " << (short) precinct_set_size << std::endl; strm << "precinct dimensions:" << std::endl; - for ( i = 0; i < precinct_set_size; i++ ) + for ( i = 0; i < precinct_set_size && i < MaxPrecincts; ++i ) strm << " " << i + 1 << ": " << s_exp_lookup[PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]&0x0f] << " x " << s_exp_lookup[(PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]>>4)&0x0f] << std::endl; @@ -157,7 +154,7 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream) fprintf(stream, " bits h-sep v-sep\n"); ui32_t i; - for ( i = 0; i < PDesc.Csize; i++ ) + for ( i = 0; i < PDesc.Csize && i < MaxComponents; i++ ) { fprintf(stream, " %4d %5d %5d\n", PDesc.ImageComponents[i].Ssize + 1, // See ISO 15444-1, Table A11, for the origin of '+1' @@ -166,34 +163,34 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream) ); } - fprintf(stream, " Scod: %hd\n", PDesc.CodingStyleDefault.Scod); - fprintf(stream, " ProgressionOrder: %hd\n", PDesc.CodingStyleDefault.SGcod.ProgressionOrder); + fprintf(stream, " Scod: %hhu\n", PDesc.CodingStyleDefault.Scod); + fprintf(stream, " ProgressionOrder: %hhu\n", PDesc.CodingStyleDefault.SGcod.ProgressionOrder); fprintf(stream, " NumberOfLayers: %hd\n", KM_i16_BE(Kumu::cp2i<ui16_t>(PDesc.CodingStyleDefault.SGcod.NumberOfLayers))); - fprintf(stream, " MultiCompTransform: %hd\n", PDesc.CodingStyleDefault.SGcod.MultiCompTransform); - fprintf(stream, "DecompositionLevels: %hd\n", PDesc.CodingStyleDefault.SPcod.DecompositionLevels); - fprintf(stream, " CodeblockWidth: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockWidth); - fprintf(stream, " CodeblockHeight: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockHeight); - fprintf(stream, " CodeblockStyle: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockStyle); - fprintf(stream, " Transformation: %hd\n", PDesc.CodingStyleDefault.SPcod.Transformation); + fprintf(stream, " MultiCompTransform: %hhu\n", PDesc.CodingStyleDefault.SGcod.MultiCompTransform); + fprintf(stream, "DecompositionLevels: %hhu\n", PDesc.CodingStyleDefault.SPcod.DecompositionLevels); + fprintf(stream, " CodeblockWidth: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockWidth); + fprintf(stream, " CodeblockHeight: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockHeight); + fprintf(stream, " CodeblockStyle: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockStyle); + fprintf(stream, " Transformation: %hhu\n", PDesc.CodingStyleDefault.SPcod.Transformation); ui32_t precinct_set_size = 0; - for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ ) + for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; ++i ) precinct_set_size++; - fprintf(stream, " Precincts: %hd\n", precinct_set_size); + fprintf(stream, " Precincts: %u\n", precinct_set_size); fprintf(stream, "precinct dimensions:\n"); - for ( i = 0; i < precinct_set_size; i++ ) + for ( i = 0; i < precinct_set_size && i < MaxPrecincts; i++ ) fprintf(stream, " %d: %d x %d\n", i + 1, s_exp_lookup[PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]&0x0f], s_exp_lookup[(PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]>>4)&0x0f] ); - fprintf(stream, " Sqcd: %hd\n", PDesc.QuantizationDefault.Sqcd); + fprintf(stream, " Sqcd: %hhu\n", PDesc.QuantizationDefault.Sqcd); char tmp_buf[MaxDefaults*2]; fprintf(stream, " SPqcd: %s\n", @@ -203,12 +200,128 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream) } +const int VideoLineMapSize = 16; // See SMPTE 377M D.2.1 +const int PixelLayoutSize = 8*2; // See SMPTE 377M D.2.3 +static const byte_t s_PixelLayoutXYZ[PixelLayoutSize] = { 0xd8, 0x0c, 0xd9, 0x0c, 0xda, 0x0c, 0x00 }; + +// +ASDCP::Result_t +ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc, + const ASDCP::Dictionary& dict, + ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor, + ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor) +{ + EssenceDescriptor.ContainerDuration = PDesc.ContainerDuration; + EssenceDescriptor.SampleRate = PDesc.EditRate; + EssenceDescriptor.FrameLayout = 0; + EssenceDescriptor.StoredWidth = PDesc.StoredWidth; + EssenceDescriptor.StoredHeight = PDesc.StoredHeight; + EssenceDescriptor.AspectRatio = PDesc.AspectRatio; + + EssenceSubDescriptor.Rsize = PDesc.Rsize; + EssenceSubDescriptor.Xsize = PDesc.Xsize; + EssenceSubDescriptor.Ysize = PDesc.Ysize; + EssenceSubDescriptor.XOsize = PDesc.XOsize; + EssenceSubDescriptor.YOsize = PDesc.YOsize; + EssenceSubDescriptor.XTsize = PDesc.XTsize; + EssenceSubDescriptor.YTsize = PDesc.YTsize; + EssenceSubDescriptor.XTOsize = PDesc.XTOsize; + EssenceSubDescriptor.YTOsize = PDesc.YTOsize; + EssenceSubDescriptor.Csize = PDesc.Csize; + + const ui32_t tmp_buffer_len = 1024; + byte_t tmp_buffer[tmp_buffer_len]; + + *(ui32_t*)tmp_buffer = KM_i32_BE(MaxComponents); // three components + *(ui32_t*)(tmp_buffer+4) = KM_i32_BE(sizeof(ASDCP::JP2K::ImageComponent_t)); + memcpy(tmp_buffer + 8, &PDesc.ImageComponents, sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents); + + const ui32_t pcomp_size = (sizeof(ui32_t) * 2) + (sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents); + memcpy(EssenceSubDescriptor.PictureComponentSizing.get().Data(), tmp_buffer, pcomp_size); + EssenceSubDescriptor.PictureComponentSizing.get().Length(pcomp_size); + EssenceSubDescriptor.PictureComponentSizing.set_has_value(); + + ui32_t precinct_set_size = 0; + for ( ui32_t i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; ++i ) + precinct_set_size++; + + ui32_t csd_size = sizeof(CodingStyleDefault_t) - MaxPrecincts + precinct_set_size; + memcpy(EssenceSubDescriptor.CodingStyleDefault.get().Data(), &PDesc.CodingStyleDefault, csd_size); + EssenceSubDescriptor.CodingStyleDefault.get().Length(csd_size); + EssenceSubDescriptor.CodingStyleDefault.set_has_value(); + + ui32_t qdflt_size = PDesc.QuantizationDefault.SPqcdLength + 1; + memcpy(EssenceSubDescriptor.QuantizationDefault.get().Data(), &PDesc.QuantizationDefault, qdflt_size); + EssenceSubDescriptor.QuantizationDefault.get().Length(qdflt_size); + EssenceSubDescriptor.QuantizationDefault.set_has_value(); + + return RESULT_OK; +} + + +// +ASDCP::Result_t +ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor, + const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor, + const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate, + ASDCP::JP2K::PictureDescriptor& PDesc) +{ + memset(&PDesc, 0, sizeof(PDesc)); + + PDesc.EditRate = EditRate; + PDesc.SampleRate = SampleRate; + assert(EssenceDescriptor.ContainerDuration.const_get() <= 0xFFFFFFFFL); + PDesc.ContainerDuration = static_cast<ui32_t>(EssenceDescriptor.ContainerDuration.const_get()); + PDesc.StoredWidth = EssenceDescriptor.StoredWidth; + PDesc.StoredHeight = EssenceDescriptor.StoredHeight; + PDesc.AspectRatio = EssenceDescriptor.AspectRatio; + + PDesc.Rsize = EssenceSubDescriptor.Rsize; + PDesc.Xsize = EssenceSubDescriptor.Xsize; + PDesc.Ysize = EssenceSubDescriptor.Ysize; + PDesc.XOsize = EssenceSubDescriptor.XOsize; + PDesc.YOsize = EssenceSubDescriptor.YOsize; + PDesc.XTsize = EssenceSubDescriptor.XTsize; + PDesc.YTsize = EssenceSubDescriptor.YTsize; + PDesc.XTOsize = EssenceSubDescriptor.XTOsize; + PDesc.YTOsize = EssenceSubDescriptor.YTOsize; + PDesc.Csize = EssenceSubDescriptor.Csize; + + // PictureComponentSizing + ui32_t tmp_size = EssenceSubDescriptor.PictureComponentSizing.const_get().Length(); + + if ( tmp_size == 17 ) // ( 2 * sizeof(ui32_t) ) + 3 components * 3 byte each + { + memcpy(&PDesc.ImageComponents, EssenceSubDescriptor.PictureComponentSizing.const_get().RoData() + 8, tmp_size - 8); + } + else + { + DefaultLogSink().Warn("Unexpected PictureComponentSizing size: %u, should be 17\n", tmp_size); + } + + // CodingStyleDefault + memset(&PDesc.CodingStyleDefault, 0, sizeof(CodingStyleDefault_t)); + memcpy(&PDesc.CodingStyleDefault, + EssenceSubDescriptor.CodingStyleDefault.const_get().RoData(), + EssenceSubDescriptor.CodingStyleDefault.const_get().Length()); + + // QuantizationDefault + memset(&PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t)); + memcpy(&PDesc.QuantizationDefault, + EssenceSubDescriptor.QuantizationDefault.const_get().RoData(), + EssenceSubDescriptor.QuantizationDefault.const_get().Length()); + + PDesc.QuantizationDefault.SPqcdLength = EssenceSubDescriptor.QuantizationDefault.const_get().Length() - 1; + return RESULT_OK; +} + + //------------------------------------------------------------------------------------------ // // hidden, internal implementation of JPEG 2000 reader -class lh__Reader : public ASDCP::h__Reader +class lh__Reader : public ASDCP::h__ASDCPReader { RGBAEssenceDescriptor* m_EssenceDescriptor; JPEG2000PictureSubDescriptor* m_EssenceSubDescriptor; @@ -222,71 +335,19 @@ public: PictureDescriptor m_PDesc; // codestream parameter list lh__Reader(const Dictionary& d) : - ASDCP::h__Reader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {} - Result_t OpenRead(const char*, EssenceType_t); - Result_t ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*); - Result_t MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDesc); -}; - -// -ASDCP::Result_t -lh__Reader::MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDesc) -{ - memset(&PDesc, 0, sizeof(PDesc)); - MXF::RGBAEssenceDescriptor* PDescObj = (MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor; - - PDesc.EditRate = m_EditRate; - PDesc.SampleRate = m_SampleRate; - assert(PDescObj->ContainerDuration <= 0xFFFFFFFFL); - PDesc.ContainerDuration = (ui32_t) PDescObj->ContainerDuration; - PDesc.StoredWidth = PDescObj->StoredWidth; - PDesc.StoredHeight = PDescObj->StoredHeight; - PDesc.AspectRatio = PDescObj->AspectRatio; - - if ( m_EssenceSubDescriptor != 0 ) - { - PDesc.Rsize = m_EssenceSubDescriptor->Rsize; - PDesc.Xsize = m_EssenceSubDescriptor->Xsize; - PDesc.Ysize = m_EssenceSubDescriptor->Ysize; - PDesc.XOsize = m_EssenceSubDescriptor->XOsize; - PDesc.YOsize = m_EssenceSubDescriptor->YOsize; - PDesc.XTsize = m_EssenceSubDescriptor->XTsize; - PDesc.YTsize = m_EssenceSubDescriptor->YTsize; - PDesc.XTOsize = m_EssenceSubDescriptor->XTOsize; - PDesc.YTOsize = m_EssenceSubDescriptor->YTOsize; - PDesc.Csize = m_EssenceSubDescriptor->Csize; - - // PictureComponentSizing - ui32_t tmp_size = m_EssenceSubDescriptor->PictureComponentSizing.Length(); - - if ( tmp_size == 17 ) // ( 2 * sizeof(ui32_t) ) + 3 components * 3 byte each - memcpy(&PDesc.ImageComponents, m_EssenceSubDescriptor->PictureComponentSizing.RoData() + 8, tmp_size - 8); - - else - DefaultLogSink().Error("Unexpected PictureComponentSizing size: %u, should be 17\n", tmp_size); - - // CodingStyleDefault - memset(&PDesc.CodingStyleDefault, 0, sizeof(CodingStyleDefault_t)); - memcpy(&PDesc.CodingStyleDefault, - m_EssenceSubDescriptor->CodingStyleDefault.RoData(), - m_EssenceSubDescriptor->CodingStyleDefault.Length()); + ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0), m_EssenceSubDescriptor(0), m_Format(ESS_UNKNOWN) {} - // QuantizationDefault - memset(&PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t)); - memcpy(&PDesc.QuantizationDefault, - m_EssenceSubDescriptor->QuantizationDefault.RoData(), - m_EssenceSubDescriptor->QuantizationDefault.Length()); + virtual ~lh__Reader() {} - PDesc.QuantizationDefault.SPqcdLength = m_EssenceSubDescriptor->QuantizationDefault.Length() - 1; - } + Result_t OpenRead(const std::string&, EssenceType_t); + Result_t ReadFrame(ui32_t, JP2K::FrameBuffer&, AESDecContext*, HMACContext*); +}; - return RESULT_OK; -} // // ASDCP::Result_t -lh__Reader::OpenRead(const char* filename, EssenceType_t type) +lh__Reader::OpenRead(const std::string& filename, EssenceType_t type) { Result_t result = OpenMXFRead(filename); @@ -296,9 +357,22 @@ lh__Reader::OpenRead(const char* filename, EssenceType_t type) m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor), &tmp_iobj); m_EssenceDescriptor = static_cast<RGBAEssenceDescriptor*>(tmp_iobj); + if ( m_EssenceDescriptor == 0 ) + { + DefaultLogSink().Error("RGBAEssenceDescriptor object not found.\n"); + return RESULT_FORMAT; + } + m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor), &tmp_iobj); m_EssenceSubDescriptor = static_cast<JPEG2000PictureSubDescriptor*>(tmp_iobj); + if ( m_EssenceSubDescriptor == 0 ) + { + m_EssenceDescriptor = 0; + DefaultLogSink().Error("JPEG2000PictureSubDescriptor object not found.\n"); + return RESULT_FORMAT; + } + std::list<InterchangeObject*> ObjectList; m_HeaderPart.GetMDObjectsByType(OBJ_TYPE_ARGS(Track), ObjectList); @@ -318,12 +392,12 @@ lh__Reader::OpenRead(const char* filename, EssenceType_t type) DefaultLogSink().Warn("EditRate and SampleRate do not match (%.03f, %.03f).\n", m_EditRate.Quotient(), m_SampleRate.Quotient()); - if ( (m_EditRate == EditRate_24 && m_SampleRate == EditRate_48) || - (m_EditRate == EditRate_25 && m_SampleRate == EditRate_50) || - (m_EditRate == EditRate_30 && m_SampleRate == EditRate_60) || - (m_EditRate == EditRate_48 && m_SampleRate == EditRate_96) || - (m_EditRate == EditRate_50 && m_SampleRate == EditRate_100) || - (m_EditRate == EditRate_60 && m_SampleRate == EditRate_120) ) + if ( ( m_EditRate == EditRate_24 && m_SampleRate == EditRate_48 ) + || ( m_EditRate == EditRate_25 && m_SampleRate == EditRate_50 ) + || ( m_EditRate == EditRate_30 && m_SampleRate == EditRate_60 ) + || ( m_EditRate == EditRate_48 && m_SampleRate == EditRate_96 ) + || ( m_EditRate == EditRate_50 && m_SampleRate == EditRate_100 ) + || ( m_EditRate == EditRate_60 && m_SampleRate == EditRate_120 ) ) { DefaultLogSink().Debug("File may contain JPEG Interop stereoscopic images.\n"); return RESULT_SFORMAT; @@ -395,15 +469,9 @@ lh__Reader::OpenRead(const char* filename, EssenceType_t type) return RESULT_STATE; } - result = MD_to_JP2K_PDesc(m_PDesc); + result = MD_to_JP2K_PDesc(*m_EssenceDescriptor, *m_EssenceSubDescriptor, m_EditRate, m_SampleRate, m_PDesc); } - if( ASDCP_SUCCESS(result) ) - result = InitMXFIndex(); - - if( ASDCP_SUCCESS(result) ) - result = InitInfo(); - return result; } @@ -462,18 +530,20 @@ ASDCP::JP2K::MXFReader::MXFReader() ASDCP::JP2K::MXFReader::~MXFReader() { + if ( m_Reader && m_Reader->m_File.IsOpen() ) + m_Reader->Close(); } // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::JP2K::MXFReader::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::JP2K::MXFReader::OP1aHeader() { if ( m_Reader.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Reader->m_HeaderPart; @@ -491,13 +561,28 @@ ASDCP::JP2K::MXFReader::OPAtomIndexFooter() return *g_OPAtomIndexFooter; } - return m_Reader->m_FooterPart; + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::JP2K::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; } // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. ASDCP::Result_t -ASDCP::JP2K::MXFReader::OpenRead(const char* filename) const +ASDCP::JP2K::MXFReader::OpenRead(const std::string& filename) const { return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000); } @@ -513,6 +598,12 @@ ASDCP::JP2K::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, return RESULT_INIT; } +ASDCP::Result_t +ASDCP::JP2K::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const +{ + return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); +} + // Fill the struct with the values from the file's header. // Returns RESULT_INIT if the file is not open. @@ -557,7 +648,7 @@ void ASDCP::JP2K::MXFReader::DumpIndex(FILE* stream) const { if ( m_Reader->m_File.IsOpen() ) - m_Reader->m_FooterPart.Dump(stream); + m_Reader->m_IndexAccess.Dump(stream); } // @@ -591,14 +682,13 @@ public: // look up frame index node IndexTableSegment::IndexEntry TmpEntry; - if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) ) + if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) ) { - DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); return RESULT_RANGE; } // get frame position - Kumu::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset; + Kumu::fpos_t FilePosition = m_HeaderPart.BodyOffset + TmpEntry.StreamOffset; Result_t result = RESULT_OK; if ( phase == SP_LEFT ) @@ -666,18 +756,20 @@ ASDCP::JP2K::MXFSReader::MXFSReader() ASDCP::JP2K::MXFSReader::~MXFSReader() { + if ( m_Reader && m_Reader->m_File.IsOpen() ) + m_Reader->Close(); } // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::JP2K::MXFSReader::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::JP2K::MXFSReader::OP1aHeader() { if ( m_Reader.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Reader->m_HeaderPart; @@ -695,13 +787,28 @@ ASDCP::JP2K::MXFSReader::OPAtomIndexFooter() return *g_OPAtomIndexFooter; } - return m_Reader->m_FooterPart; + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::JP2K::MXFSReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; } // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. ASDCP::Result_t -ASDCP::JP2K::MXFSReader::OpenRead(const char* filename) const +ASDCP::JP2K::MXFSReader::OpenRead(const std::string& filename) const { return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000_S); } @@ -734,6 +841,12 @@ ASDCP::JP2K::MXFSReader::ReadFrame(ui32_t FrameNum, StereoscopicPhase_t phase, F return RESULT_INIT; } +ASDCP::Result_t +ASDCP::JP2K::MXFSReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const +{ + return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); +} + // Fill the struct with the values from the file's header. // Returns RESULT_INIT if the file is not open. ASDCP::Result_t @@ -777,7 +890,7 @@ void ASDCP::JP2K::MXFSReader::DumpIndex(FILE* stream) const { if ( m_Reader->m_File.IsOpen() ) - m_Reader->m_FooterPart.Dump(stream); + m_Reader->m_IndexAccess.Dump(stream); } // @@ -798,7 +911,7 @@ ASDCP::JP2K::MXFSReader::Close() const // -class lh__Writer : public ASDCP::h__Writer +class lh__Writer : public ASDCP::h__ASDCPWriter { ASDCP_NO_COPY_CONSTRUCT(lh__Writer); lh__Writer(); @@ -809,116 +922,28 @@ public: PictureDescriptor m_PDesc; byte_t m_EssenceUL[SMPTE_UL_LENGTH]; - lh__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_EssenceSubDescriptor(0) { + lh__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_EssenceSubDescriptor(0) { memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); } - ~lh__Writer(){} + virtual ~lh__Writer(){} - Result_t OpenWrite(const char*, EssenceType_t type, ui32_t HeaderSize, bool); + Result_t OpenWrite(const std::string&, EssenceType_t type, ui32_t HeaderSize); Result_t SetSourceStream(const PictureDescriptor&, const std::string& label, ASDCP::Rational LocalEditRate = ASDCP::Rational(0,0)); - Result_t WriteFrame(const JP2K::FrameBuffer&, bool add_index, AESEncContext*, HMACContext*, std::string* hash = 0); - Result_t FakeWriteFrame(int size, bool add_index); + Result_t WriteFrame(const JP2K::FrameBuffer&, bool add_index, AESEncContext*, HMACContext*); Result_t Finalize(); - Result_t JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc); }; -const int VideoLineMapSize = 16; // See SMPTE 377M D.2.1 -const int PixelLayoutSize = 8*2; // See SMPTE 377M D.2.3 -static const byte_t s_PixelLayoutXYZ[PixelLayoutSize] = { 0xd8, 0x0c, 0xd9, 0x0c, 0xda, 0x0c, 0x00 }; - -// -ASDCP::Result_t -lh__Writer::JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDesc) -{ - assert(m_EssenceDescriptor); - assert(m_EssenceSubDescriptor); - MXF::RGBAEssenceDescriptor* PDescObj = (MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor; - - PDescObj->ContainerDuration = PDesc.ContainerDuration; - PDescObj->SampleRate = PDesc.EditRate; - PDescObj->FrameLayout = 0; - PDescObj->StoredWidth = PDesc.StoredWidth; - PDescObj->StoredHeight = PDesc.StoredHeight; - PDescObj->AspectRatio = PDesc.AspectRatio; - - // if ( m_Info.LabelSetType == LS_MXF_SMPTE ) - // { - // PictureEssenceCoding UL = - // Video Line Map ui32_t[VideoLineMapSize] = { 2, 4, 0, 0 } - // CaptureGamma UL = - // ComponentMaxRef ui32_t = 4095 - // ComponentMinRef ui32_t = 0 - // PixelLayout byte_t[PixelLayoutSize] = s_PixelLayoutXYZ - // } - - assert(m_Dict); - if ( PDesc.StoredWidth < 2049 ) - { - PDescObj->PictureEssenceCoding.Set(m_Dict->ul(MDD_JP2KEssenceCompression_2K)); - m_EssenceSubDescriptor->Rsize = 3; - } - else - { - PDescObj->PictureEssenceCoding.Set(m_Dict->ul(MDD_JP2KEssenceCompression_4K)); - m_EssenceSubDescriptor->Rsize = 4; - } - - m_EssenceSubDescriptor->Xsize = PDesc.Xsize; - m_EssenceSubDescriptor->Ysize = PDesc.Ysize; - m_EssenceSubDescriptor->XOsize = PDesc.XOsize; - m_EssenceSubDescriptor->YOsize = PDesc.YOsize; - m_EssenceSubDescriptor->XTsize = PDesc.XTsize; - m_EssenceSubDescriptor->YTsize = PDesc.YTsize; - m_EssenceSubDescriptor->XTOsize = PDesc.XTOsize; - m_EssenceSubDescriptor->YTOsize = PDesc.YTOsize; - m_EssenceSubDescriptor->Csize = PDesc.Csize; - - const ui32_t tmp_buffer_len = 1024; - byte_t tmp_buffer[tmp_buffer_len]; - - ui32_t* tmp_buffer_ui32 = (ui32_t*) tmp_buffer; - *tmp_buffer_ui32 = KM_i32_BE(MaxComponents); // three components - - *(ui32_t*)(tmp_buffer+4) = KM_i32_BE(sizeof(ASDCP::JP2K::ImageComponent_t)); - memcpy(tmp_buffer + 8, &PDesc.ImageComponents, sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents); - - const ui32_t pcomp_size = (sizeof(int) * 2) + (sizeof(ASDCP::JP2K::ImageComponent_t) * MaxComponents); - memcpy(m_EssenceSubDescriptor->PictureComponentSizing.Data(), tmp_buffer, pcomp_size); - m_EssenceSubDescriptor->PictureComponentSizing.Length(pcomp_size); - - ui32_t precinct_set_size = 0, i; - for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ ) - precinct_set_size++; - - ui32_t csd_size = sizeof(CodingStyleDefault_t) - MaxPrecincts + precinct_set_size; - memcpy(m_EssenceSubDescriptor->CodingStyleDefault.Data(), &PDesc.CodingStyleDefault, csd_size); - m_EssenceSubDescriptor->CodingStyleDefault.Length(csd_size); - - ui32_t qdflt_size = PDesc.QuantizationDefault.SPqcdLength + 1; - memcpy(m_EssenceSubDescriptor->QuantizationDefault.Data(), &PDesc.QuantizationDefault, qdflt_size); - m_EssenceSubDescriptor->QuantizationDefault.Length(qdflt_size); - - return RESULT_OK; -} - - -// Open the file for writing. The file must not exist unless overwrite is true. Returns error if +// Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -lh__Writer::OpenWrite(const char* filename, EssenceType_t type, ui32_t HeaderSize, bool overwrite) +lh__Writer::OpenWrite(const std::string& filename, EssenceType_t type, ui32_t HeaderSize) { if ( ! m_State.Test_BEGIN() ) return RESULT_STATE; - Result_t result = RESULT_OK; - if (overwrite) { - result = m_File.OpenModify(filename); - m_File.Seek(0); - } else { - result = m_File.OpenWrite(filename); - } + Result_t result = m_File.OpenWrite(filename); if ( ASDCP_SUCCESS(result) ) { @@ -960,10 +985,26 @@ lh__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l LocalEditRate = PDesc.EditRate; m_PDesc = PDesc; - Result_t result = JP2K_PDesc_to_MD(m_PDesc); + assert(m_Dict); + assert(m_EssenceDescriptor); + assert(m_EssenceSubDescriptor); + Result_t result = JP2K_PDesc_to_MD(m_PDesc, *m_Dict, + *static_cast<ASDCP::MXF::GenericPictureEssenceDescriptor*>(m_EssenceDescriptor), + *m_EssenceSubDescriptor); if ( ASDCP_SUCCESS(result) ) { + if ( PDesc.StoredWidth < 2049 ) + { + static_cast<ASDCP::MXF::RGBAEssenceDescriptor*>(m_EssenceDescriptor)->PictureEssenceCoding.Set(m_Dict->ul(MDD_JP2KEssenceCompression_2K)); + m_EssenceSubDescriptor->Rsize = 3; + } + else + { + static_cast<ASDCP::MXF::RGBAEssenceDescriptor*>(m_EssenceDescriptor)->PictureEssenceCoding.Set(m_Dict->ul(MDD_JP2KEssenceCompression_4K)); + m_EssenceSubDescriptor->Rsize = 4; + } + memcpy(m_EssenceUL, m_Dict->ul(MDD_JPEG2000Essence), SMPTE_UL_LENGTH); m_EssenceUL[SMPTE_UL_LENGTH-1] = 1; // first (and only) essence container result = m_State.Goto_READY(); @@ -971,11 +1012,9 @@ lh__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l if ( ASDCP_SUCCESS(result) ) { - ui32_t TCFrameRate = ( m_PDesc.EditRate == EditRate_23_98 ) ? 24 : m_PDesc.EditRate.Numerator; - - result = WriteMXFHeader(label, UL(m_Dict->ul(MDD_JPEG_2000Wrapping)), - PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)), - LocalEditRate, TCFrameRate); + result = WriteASDCPHeader(label, UL(m_Dict->ul(MDD_JPEG_2000WrappingFrame)), + PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)), + LocalEditRate, derive_timecode_rate_from_edit_rate(m_PDesc.EditRate)); } return result; @@ -988,7 +1027,7 @@ lh__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l // ASDCP::Result_t lh__Writer::WriteFrame(const JP2K::FrameBuffer& FrameBuf, bool add_index, - AESEncContext* Ctx, HMACContext* HMAC, std::string* hash) + AESEncContext* Ctx, HMACContext* HMAC) { Result_t result = RESULT_OK; @@ -998,31 +1037,7 @@ lh__Writer::WriteFrame(const JP2K::FrameBuffer& FrameBuf, bool add_index, ui64_t StreamOffset = m_StreamOffset; if ( ASDCP_SUCCESS(result) ) - result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC, hash); - - if ( ASDCP_SUCCESS(result) && add_index ) - { - IndexTableSegment::IndexEntry Entry; - Entry.StreamOffset = StreamOffset; - m_FooterPart.PushIndexEntry(Entry); - } - - m_FramesWritten++; - return result; -} - -Result_t -lh__Writer::FakeWriteFrame(int size, bool add_index) -{ - Result_t result = RESULT_OK; - - if ( m_State.Test_READY() ) - result = m_State.Goto_RUNNING(); - - ui64_t StreamOffset = m_StreamOffset; - - if ( ASDCP_SUCCESS(result) ) - result = FakeWriteEKLVPacket(size); + result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC); if ( ASDCP_SUCCESS(result) && add_index ) { @@ -1046,7 +1061,7 @@ lh__Writer::Finalize() m_State.Goto_FINAL(); - return WriteMXFFooter(); + return WriteASDCPFooter(); } @@ -1076,13 +1091,13 @@ ASDCP::JP2K::MXFWriter::~MXFWriter() // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::JP2K::MXFWriter::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::JP2K::MXFWriter::OP1aHeader() { if ( m_Writer.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Writer->m_HeaderPart; @@ -1103,11 +1118,26 @@ ASDCP::JP2K::MXFWriter::OPAtomIndexFooter() return m_Writer->m_FooterPart; } -// Open the file for writing. The file must not exist unless overwrite is true. Returns error if +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::JP2K::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + +// Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -ASDCP::JP2K::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info, - const PictureDescriptor& PDesc, ui32_t HeaderSize, bool overwrite) +ASDCP::JP2K::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, + const PictureDescriptor& PDesc, ui32_t HeaderSize) { if ( Info.LabelSetType == LS_MXF_SMPTE ) m_Writer = new h__Writer(DefaultSMPTEDict()); @@ -1116,7 +1146,7 @@ ASDCP::JP2K::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info, m_Writer->m_Info = Info; - Result_t result = m_Writer->OpenWrite(filename, ASDCP::ESS_JPEG_2000, HeaderSize, overwrite); + Result_t result = m_Writer->OpenWrite(filename, ASDCP::ESS_JPEG_2000, HeaderSize); if ( ASDCP_SUCCESS(result) ) result = m_Writer->SetSourceStream(PDesc, JP2K_PACKAGE_LABEL); @@ -1133,21 +1163,12 @@ ASDCP::JP2K::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info, // Fails if the file is not open, is finalized, or an operating system // error occurs. ASDCP::Result_t -ASDCP::JP2K::MXFWriter::WriteFrame(const FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC, std::string* hash) -{ - if ( m_Writer.empty() ) - return RESULT_INIT; - - return m_Writer->WriteFrame(FrameBuf, true, Ctx, HMAC, hash); -} - -ASDCP::Result_t -ASDCP::JP2K::MXFWriter::FakeWriteFrame(int size) +ASDCP::JP2K::MXFWriter::WriteFrame(const FrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC) { if ( m_Writer.empty() ) return RESULT_INIT; - return m_Writer->FakeWriteFrame(size, true); + return m_Writer->WriteFrame(FrameBuf, true, Ctx, HMAC); } // Closes the MXF file, writing the index and other closing information. @@ -1160,12 +1181,6 @@ ASDCP::JP2K::MXFWriter::Finalize() return m_Writer->Finalize(); } -ui64_t -ASDCP::JP2K::MXFWriter::Tell() const -{ - return m_Writer->m_File.Tell(); -} - //------------------------------------------------------------------------------------------ // @@ -1182,7 +1197,7 @@ public: // Result_t WriteFrame(const FrameBuffer& FrameBuf, StereoscopicPhase_t phase, - AESEncContext* Ctx, HMACContext* HMAC, std::string* hash) + AESEncContext* Ctx, HMACContext* HMAC) { if ( m_NextPhase != phase ) return RESULT_SPHASE; @@ -1190,28 +1205,11 @@ public: if ( phase == SP_LEFT ) { m_NextPhase = SP_RIGHT; - return lh__Writer::WriteFrame(FrameBuf, true, Ctx, HMAC, hash); + return lh__Writer::WriteFrame(FrameBuf, true, Ctx, HMAC); } m_NextPhase = SP_LEFT; - return lh__Writer::WriteFrame(FrameBuf, false, Ctx, HMAC, hash); - } - - Result_t FakeWriteFrame(int size, StereoscopicPhase_t phase) - { - if (m_NextPhase != phase) - { - return RESULT_SPHASE; - } - - if (phase == SP_LEFT) - { - m_NextPhase = SP_RIGHT; - return lh__Writer::FakeWriteFrame(size, true); - } - - m_NextPhase = SP_LEFT; - return lh__Writer::FakeWriteFrame(size, false); + return lh__Writer::WriteFrame(FrameBuf, false, Ctx, HMAC); } // @@ -1239,13 +1237,13 @@ ASDCP::JP2K::MXFSWriter::~MXFSWriter() // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::JP2K::MXFSWriter::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::JP2K::MXFSWriter::OP1aHeader() { if ( m_Writer.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Writer->m_HeaderPart; @@ -1266,11 +1264,26 @@ ASDCP::JP2K::MXFSWriter::OPAtomIndexFooter() return m_Writer->m_FooterPart; } +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::JP2K::MXFSWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -ASDCP::JP2K::MXFSWriter::OpenWrite(const char* filename, const WriterInfo& Info, - const PictureDescriptor& PDesc, ui32_t HeaderSize, bool overwrite) +ASDCP::JP2K::MXFSWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, + const PictureDescriptor& PDesc, ui32_t HeaderSize) { if ( Info.LabelSetType == LS_MXF_SMPTE ) m_Writer = new h__SWriter(DefaultSMPTEDict()); @@ -1293,7 +1306,7 @@ ASDCP::JP2K::MXFSWriter::OpenWrite(const char* filename, const WriterInfo& Info, m_Writer->m_Info = Info; - Result_t result = m_Writer->OpenWrite(filename, ASDCP::ESS_JPEG_2000_S, HeaderSize, overwrite); + Result_t result = m_Writer->OpenWrite(filename, ASDCP::ESS_JPEG_2000_S, HeaderSize); if ( ASDCP_SUCCESS(result) ) { @@ -1332,10 +1345,10 @@ ASDCP::JP2K::MXFSWriter::WriteFrame(const SFrameBuffer& FrameBuf, AESEncContext* if ( m_Writer.empty() ) return RESULT_INIT; - Result_t result = m_Writer->WriteFrame(FrameBuf.Left, SP_LEFT, Ctx, HMAC, 0); + Result_t result = m_Writer->WriteFrame(FrameBuf.Left, SP_LEFT, Ctx, HMAC); if ( ASDCP_SUCCESS(result) ) - result = m_Writer->WriteFrame(FrameBuf.Right, SP_RIGHT, Ctx, HMAC, 0); + result = m_Writer->WriteFrame(FrameBuf.Right, SP_RIGHT, Ctx, HMAC); return result; } @@ -1346,21 +1359,12 @@ ASDCP::JP2K::MXFSWriter::WriteFrame(const SFrameBuffer& FrameBuf, AESEncContext* // error occurs. ASDCP::Result_t ASDCP::JP2K::MXFSWriter::WriteFrame(const FrameBuffer& FrameBuf, StereoscopicPhase_t phase, - AESEncContext* Ctx, HMACContext* HMAC, std::string* hash) + AESEncContext* Ctx, HMACContext* HMAC) { if ( m_Writer.empty() ) return RESULT_INIT; - return m_Writer->WriteFrame(FrameBuf, phase, Ctx, HMAC, hash); -} - -ASDCP::Result_t -ASDCP::JP2K::MXFSWriter::FakeWriteFrame(int size, StereoscopicPhase_t phase) -{ - if ( m_Writer.empty() ) - return RESULT_INIT; - - return m_Writer->FakeWriteFrame(size, phase); + return m_Writer->WriteFrame(FrameBuf, phase, Ctx, HMAC); } // Closes the MXF file, writing the index and other closing information. @@ -1373,12 +1377,6 @@ ASDCP::JP2K::MXFSWriter::Finalize() return m_Writer->Finalize(); } -ui64_t -ASDCP::JP2K::MXFSWriter::Tell() const -{ - return m_Writer->m_File.Tell(); -} - // // end AS_DCP_JP2K.cpp // diff --git a/asdcplib/src/AS_DCP_MPEG2.cpp b/asdcplib/src/AS_DCP_MPEG2.cpp index bc64c1e7..92228887 100755 --- a/asdcplib/src/AS_DCP_MPEG2.cpp +++ b/asdcplib/src/AS_DCP_MPEG2.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP_MPEG2.cpp - \version $Id: AS_DCP_MPEG2.cpp,v 1.34 2012/02/07 18:54:24 jhurst Exp $ + \version $Id: AS_DCP_MPEG2.cpp,v 1.44 2015/10/07 16:41:23 jhurst Exp $ \brief AS-DCP library, MPEG2 essence reader and writer implementation */ @@ -62,7 +62,7 @@ MD_to_MPEG2_VDesc(MXF::MPEG2VideoDescriptor* VDescObj, MPEG2::VideoDescriptor& V VDesc.ColorSiting = VDescObj->ColorSiting; VDesc.CodedContentType = VDescObj->CodedContentType; - VDesc.LowDelay = VDescObj->LowDelay == 0 ? false : true; + VDesc.LowDelay = VDescObj->LowDelay.get() == 0 ? false : true; VDesc.BitRate = VDescObj->BitRate; VDesc.ProfileAndLevel = VDescObj->ProfileAndLevel; return RESULT_OK; @@ -160,7 +160,7 @@ ASDCP::MPEG2::VideoDescriptorDump(const VideoDescriptor& VDesc, FILE* stream) // // hidden, internal implementation of MPEG2 reader -class ASDCP::MPEG2::MXFReader::h__Reader : public ASDCP::h__Reader +class ASDCP::MPEG2::MXFReader::h__Reader : public ASDCP::h__ASDCPReader { ASDCP_NO_COPY_CONSTRUCT(h__Reader); h__Reader(); @@ -168,9 +168,9 @@ class ASDCP::MPEG2::MXFReader::h__Reader : public ASDCP::h__Reader public: VideoDescriptor m_VDesc; // video parameter list - h__Reader(const Dictionary& d) : ASDCP::h__Reader(d) {} - ~h__Reader() {} - Result_t OpenRead(const char*); + h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {} + virtual ~h__Reader() {} + Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); Result_t ReadFrameGOPStart(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); Result_t FindFrameGOPStart(ui32_t, ui32_t&); @@ -181,26 +181,26 @@ public: // // ASDCP::Result_t -ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const char* filename) +ASDCP::MPEG2::MXFReader::h__Reader::OpenRead(const std::string& filename) { Result_t result = OpenMXFRead(filename); if( ASDCP_SUCCESS(result) ) { - InterchangeObject* Object; + InterchangeObject* Object = 0; + if ( ASDCP_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor), &Object)) ) { - assert(Object); + if ( Object == 0 ) + { + DefaultLogSink().Error("MPEG2VideoDescriptor object not found.\n"); + return RESULT_FORMAT; + } + result = MD_to_MPEG2_VDesc((MXF::MPEG2VideoDescriptor*)Object, m_VDesc); } } - if( ASDCP_SUCCESS(result) ) - result = InitMXFIndex(); - - if( ASDCP_SUCCESS(result) ) - result = InitInfo(); - return result; } @@ -235,9 +235,8 @@ ASDCP::MPEG2::MXFReader::h__Reader::FindFrameGOPStart(ui32_t FrameNum, ui32_t& K // look up frame index node IndexTableSegment::IndexEntry TmpEntry; - if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) ) + if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) ) { - DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); return RESULT_RANGE; } @@ -256,9 +255,8 @@ ASDCP::MPEG2::MXFReader::h__Reader::FrameType(ui32_t FrameNum, FrameType_t& type // look up frame index node IndexTableSegment::IndexEntry TmpEntry; - if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) ) + if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) ) { - DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); return RESULT_RANGE; } @@ -283,7 +281,7 @@ ASDCP::MPEG2::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& Fram return result; IndexTableSegment::IndexEntry TmpEntry; - m_FooterPart.Lookup(FrameNum, TmpEntry); + m_IndexAccess.Lookup(FrameNum, TmpEntry); switch ( ( TmpEntry.Flags >> 4 ) & 0x03 ) { @@ -310,7 +308,7 @@ ASDCP::MPEG2::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const if ( stream == 0 ) stream = stderr; - fprintf(stream, "Frame: %06u, %c%-2hu, %7u bytes", + fprintf(stream, "Frame: %06u, %c%-2hhu, %7u bytes", m_FrameNumber, FrameTypeChar(m_FrameType), m_TemporalOffset, m_Size); if ( m_GOPStart ) @@ -333,18 +331,20 @@ ASDCP::MPEG2::MXFReader::MXFReader() ASDCP::MPEG2::MXFReader::~MXFReader() { + if ( m_Reader && m_Reader->m_File.IsOpen() ) + m_Reader->Close(); } // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::MPEG2::MXFReader::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::MPEG2::MXFReader::OP1aHeader() { if ( m_Reader.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Reader->m_HeaderPart; @@ -362,13 +362,28 @@ ASDCP::MPEG2::MXFReader::OPAtomIndexFooter() return *g_OPAtomIndexFooter; } - return m_Reader->m_FooterPart; + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::MPEG2::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; } // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. ASDCP::Result_t -ASDCP::MPEG2::MXFReader::OpenRead(const char* filename) const +ASDCP::MPEG2::MXFReader::OpenRead(const std::string& filename) const { return m_Reader->OpenRead(filename); } @@ -387,6 +402,13 @@ ASDCP::MPEG2::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, // ASDCP::Result_t +ASDCP::MPEG2::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const +{ + return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); +} + +// +ASDCP::Result_t ASDCP::MPEG2::MXFReader::ReadFrameGOPStart(ui32_t FrameNum, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const { @@ -451,7 +473,7 @@ void ASDCP::MPEG2::MXFReader::DumpIndex(FILE* stream) const { if ( m_Reader->m_File.IsOpen() ) - m_Reader->m_FooterPart.Dump(stream); + m_Reader->m_IndexAccess.Dump(stream); } // @@ -481,7 +503,7 @@ ASDCP::MPEG2::MXFReader::FrameType(ui32_t FrameNum, FrameType_t& type) const //------------------------------------------------------------------------------------------ // -class ASDCP::MPEG2::MXFWriter::h__Writer : public ASDCP::h__Writer +class ASDCP::MPEG2::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter { ASDCP_NO_COPY_CONSTRUCT(h__Writer); h__Writer(); @@ -491,13 +513,13 @@ public: ui32_t m_GOPOffset; byte_t m_EssenceUL[SMPTE_UL_LENGTH]; - h__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_GOPOffset(0) { + h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_GOPOffset(0) { memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); } - ~h__Writer(){} + virtual ~h__Writer(){} - Result_t OpenWrite(const char*, ui32_t HeaderSize); + Result_t OpenWrite(const std::string&, ui32_t HeaderSize); Result_t SetSourceStream(const VideoDescriptor&); Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); Result_t Finalize(); @@ -507,7 +529,7 @@ public: // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize) +ASDCP::MPEG2::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize) { if ( ! m_State.Test_BEGIN() ) return RESULT_STATE; @@ -544,11 +566,11 @@ ASDCP::MPEG2::MXFWriter::h__Writer::SetSourceStream(const VideoDescriptor& VDesc if ( ASDCP_SUCCESS(result) ) { - ui32_t TCFrameRate = ( m_VDesc.EditRate == EditRate_23_98 ) ? 24 : m_VDesc.EditRate.Numerator; + m_FooterPart.SetDeltaParams(IndexTableSegment::DeltaEntry(-1, 0, 0)); - result = WriteMXFHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrapping)), - PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)), - m_VDesc.EditRate, TCFrameRate); + result = WriteASDCPHeader(MPEG_PACKAGE_LABEL, UL(m_Dict->ul(MDD_MPEG2_VESWrappingFrame)), + PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)), + m_VDesc.EditRate, derive_timecode_rate_from_edit_rate(m_VDesc.EditRate)); } return result; @@ -585,8 +607,6 @@ ASDCP::MPEG2::MXFWriter::h__Writer::WriteFrame(const FrameBuffer& FrameBuf, AESE case FRAME_I: Flags = 0x00; break; case FRAME_P: Flags = 0x22; break; case FRAME_B: Flags = 0x33; break; - /* Keep gcc quiet */ - case FRAME_U: break; } if ( FrameBuf.GOPStart() ) @@ -627,7 +647,7 @@ ASDCP::MPEG2::MXFWriter::h__Writer::Finalize() m_State.Goto_FINAL(); - return WriteMXFFooter(); + return WriteASDCPFooter(); } @@ -646,13 +666,13 @@ ASDCP::MPEG2::MXFWriter::~MXFWriter() // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::MPEG2::MXFWriter::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::MPEG2::MXFWriter::OP1aHeader() { if ( m_Writer.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Writer->m_HeaderPart; @@ -673,10 +693,25 @@ ASDCP::MPEG2::MXFWriter::OPAtomIndexFooter() return m_Writer->m_FooterPart; } +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::MPEG2::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -ASDCP::MPEG2::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info, +ASDCP::MPEG2::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, const VideoDescriptor& VDesc, ui32_t HeaderSize) { if ( Info.LabelSetType == LS_MXF_SMPTE ) diff --git a/asdcplib/src/AS_DCP_MXF.cpp b/asdcplib/src/AS_DCP_MXF.cpp index da5232f8..4ff490ed 100755 --- a/asdcplib/src/AS_DCP_MXF.cpp +++ b/asdcplib/src/AS_DCP_MXF.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2009, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP_MXF.cpp - \version $Id: AS_DCP_MXF.cpp,v 1.31 2009/08/04 18:43:10 jhurst Exp $ + \version $Id: AS_DCP_MXF.cpp,v 1.39 2015/04/21 03:55:31 jhurst Exp $ \brief AS-DCP library, misc classes and subroutines */ @@ -161,14 +161,14 @@ ASDCP::MD_to_CryptoInfo(CryptographicContext* InfoObj, WriterInfo& Info, const D // // ASDCP::Result_t -ASDCP::EssenceType(const char* filename, EssenceType_t& type) +ASDCP::EssenceType(const std::string& filename, EssenceType_t& type) { const Dictionary* m_Dict = &DefaultCompositeDict(); - assert(m_Dict); + InterchangeObject* md_object = 0; - ASDCP_TEST_NULL_STR(filename); + assert(m_Dict); Kumu::FileReader Reader; - OPAtomHeader TestHeader(m_Dict); + OP1aHeader TestHeader(m_Dict); Result_t result = Reader.OpenRead(filename); @@ -178,33 +178,105 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type) if ( ASDCP_SUCCESS(result) ) { type = ESS_UNKNOWN; - if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor))) ) + + if ( TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_OPAtom)) + || TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_MXFInterop_OPAtom)) ) + { + if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) ) + { + if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(StereoscopicPictureSubDescriptor))) ) + { + type = ESS_JPEG_2000_S; + } + else + { + type = ESS_JPEG_2000; + } + } + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) ) + { + assert(md_object); + if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k ) + { + type = ESS_PCM_24b_96k; + } + else + { + type = ESS_PCM_24b_48k; + } + } + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) ) + { + type = ESS_MPEG2_VES; + } + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) ) + { + type = ESS_TIMED_TEXT; + } + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DCDataDescriptor))) ) + { + if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(DolbyAtmosSubDescriptor))) ) + { + type = ESS_DCDATA_DOLBY_ATMOS; + } + else + { + type = ESS_DCDATA_UNKNOWN; + } + } + } + else if ( TestHeader.OperationalPattern == UL(m_Dict->ul(MDD_OP1a)) ) { - if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(StereoscopicPictureSubDescriptor))) ) - type = ESS_JPEG_2000_S; - else - type = ESS_JPEG_2000; + if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor))) ) + { + type = ESS_AS02_JPEG_2000; + } + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &md_object)) ) + { + assert(md_object); + if ( static_cast<ASDCP::MXF::WaveAudioDescriptor*>(md_object)->AudioSamplingRate == SampleRate_96k ) + { + type = ESS_AS02_PCM_24b_96k; + } + else + { + type = ESS_AS02_PCM_24b_48k; + } + } + else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) ) + { + type = ESS_AS02_TIMED_TEXT; + } + } + else + { + DefaultLogSink().Error("Unsupported MXF Operational Pattern.\n"); + return RESULT_FORMAT; } - else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor))) ) - type = ESS_PCM_24b_48k; - else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(MPEG2VideoDescriptor))) ) - type = ESS_MPEG2_VES; - else if ( ASDCP_SUCCESS(TestHeader.GetMDObjectByType(OBJ_TYPE_ARGS(TimedTextDescriptor))) ) - type = ESS_TIMED_TEXT; } return result; } // +static bool +string_is_xml(const ASDCP::FrameBuffer& buffer) +{ + std::string ns_prefix, type_name, namespace_name; + Kumu::AttributeList doc_attr_list; + return GetXMLDocType(buffer.RoData(), buffer.Size(), + ns_prefix, type_name, namespace_name, doc_attr_list); +} + +// ASDCP::Result_t -ASDCP::RawEssenceType(const char* filename, EssenceType_t& type) +ASDCP::RawEssenceType(const std::string& filename, EssenceType_t& type) { - ASDCP_TEST_NULL_STR(filename); type = ESS_UNKNOWN; ASDCP::FrameBuffer FB; Kumu::FileReader Reader; ASDCP::Wav::SimpleWaveHeader WavHeader; + ASDCP::RF64::SimpleRF64Header RF64Header; ASDCP::AIFF::SimpleAIFFHeader AIFFHeader; Kumu::XMLElement TmpElement("Tmp"); @@ -238,24 +310,53 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type) { type = ESS_JPEG_2000; } - else if ( ASDCP_SUCCESS(WavHeader.ReadFromBuffer(FB.RoData(), read_count, &data_offset)) ) + else if ( std::string((const char*)FB.RoData() + 8, 4) == "WAVE" ) { - switch ( WavHeader.samplespersec ) + if ( std::string((const char*)FB.RoData(), 4) == "RIFF" ) { - case 48000: type = ESS_PCM_24b_48k; break; - case 96000: type = ESS_PCM_24b_96k; break; - default: - return RESULT_FORMAT; + result = WavHeader.ReadFromBuffer(FB.RoData(), read_count, &data_offset); + + if ( ASDCP_SUCCESS(result) ) + { + switch ( WavHeader.samplespersec ) + { + case 48000: type = ESS_PCM_24b_48k; break; + case 96000: type = ESS_PCM_24b_96k; break; + default: + DefaultLogSink().Error("Unexpected sample rate: %d\n", WavHeader.samplespersec); + result = RESULT_FORMAT; + } + } + } + else + { + result = RF64Header.ReadFromBuffer(FB.RoData(), read_count, &data_offset); + + if ( ASDCP_SUCCESS(result) ) + { + switch ( RF64Header.samplespersec ) + { + case 48000: type = ESS_PCM_24b_48k; break; + case 96000: type = ESS_PCM_24b_96k; break; + default: + DefaultLogSink().Error("Unexpected sample rate: %d\n", WavHeader.samplespersec); + result = RESULT_FORMAT; + } + } } } else if ( ASDCP_SUCCESS(AIFFHeader.ReadFromBuffer(FB.RoData(), read_count, &data_offset)) ) { type = ESS_PCM_24b_48k; } - else if ( Kumu::StringIsXML((const char*)FB.RoData(), FB.Size()) ) + else if ( string_is_xml(FB) ) { type = ESS_TIMED_TEXT; } + else if ( ASDCP::ATMOS::IsDolbyAtmos(filename) ) + { + type = ESS_DCDATA_DOLBY_ATMOS; + } } } else if ( Kumu::PathIsDirectory(filename) ) @@ -271,10 +372,7 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type) if ( next_file[0] == '.' ) // no hidden files or internal links continue; - std::string Str(filename); - Str += "/"; - Str += next_file; - result = Reader.OpenRead(Str.c_str()); + result = Reader.OpenRead(Kumu::PathJoin(filename, next_file)); if ( ASDCP_SUCCESS(result) ) { @@ -298,8 +396,26 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type) return RESULT_FORMAT; } } + else if ( ASDCP_SUCCESS(RF64Header.ReadFromBuffer(FB.RoData(), read_count, &data_offset)) ) + { + switch ( RF64Header.samplespersec ) + { + case 48000: type = ESS_PCM_24b_48k; break; + case 96000: type = ESS_PCM_24b_96k; break; + default: + return RESULT_FORMAT; + } + } + else if ( ASDCP::ATMOS::IsDolbyAtmos(Kumu::PathJoin(filename, next_file)) ) + { + type = ESS_DCDATA_DOLBY_ATMOS; + } + else + { + type = ESS_DCDATA_UNKNOWN; + } } - + break; } } @@ -439,7 +555,7 @@ ASDCP::DecryptFrameBuffer(const ASDCP::FrameBuffer& FBin, ASDCP::FrameBuffer& FB // Result_t -ASDCP::IntegrityPack::CalcValues(const ASDCP::FrameBuffer& FB, byte_t* AssetID, +ASDCP::IntegrityPack::CalcValues(const ASDCP::FrameBuffer& FB, const byte_t* AssetID, ui32_t sequence, HMACContext* HMAC) { ASDCP_TEST_NULL(AssetID); @@ -489,7 +605,7 @@ ASDCP::IntegrityPack::CalcValues(const ASDCP::FrameBuffer& FB, byte_t* AssetID, Result_t -ASDCP::IntegrityPack::TestValues(const ASDCP::FrameBuffer& FB, byte_t* AssetID, +ASDCP::IntegrityPack::TestValues(const ASDCP::FrameBuffer& FB, const byte_t* AssetID, ui32_t sequence, HMACContext* HMAC) { ASDCP_TEST_NULL(AssetID); diff --git a/asdcplib/src/AS_DCP_PCM.cpp b/asdcplib/src/AS_DCP_PCM.cpp index 385d9035..73ef4efd 100755 --- a/asdcplib/src/AS_DCP_PCM.cpp +++ b/asdcplib/src/AS_DCP_PCM.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP_PCM.cpp - \version $Id: AS_DCP_PCM.cpp,v 1.36 2012/02/07 18:54:25 jhurst Exp $ + \version $Id: AS_DCP_PCM.cpp,v 1.47 2014/10/02 21:02:24 jhurst Exp $ \brief AS-DCP library, PCM essence reader and writer implementation */ @@ -41,7 +41,7 @@ static std::string SOUND_DEF_LABEL = "Sound Track"; // Result_t -PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, MXF::WaveAudioDescriptor* ADescObj) +ASDCP::PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, MXF::WaveAudioDescriptor* ADescObj) { ASDCP_TEST_NULL(ADescObj); ADescObj->SampleRate = ADesc.EditRate; @@ -54,7 +54,7 @@ PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, MXF::WaveAudioDescriptor* ADescObj) ADescObj->LinkedTrackID = ADesc.LinkedTrackID; ADescObj->ContainerDuration = ADesc.ContainerDuration; - ADescObj->ChannelAssignment.Reset(); + ADescObj->ChannelAssignment.get().Reset(); switch ( ADesc.ChannelFormat ) { @@ -78,9 +78,9 @@ PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, MXF::WaveAudioDescriptor* ADescObj) ADescObj->ChannelAssignment = DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_5_7p1_DS).ul; break; - case PCM::CF_NONE: - /* Keep gcc quiet */ - break; + case PCM::CF_CFG_6: + ADescObj->ChannelAssignment = DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_MCA).ul; + break; } return RESULT_OK; @@ -88,7 +88,7 @@ PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, MXF::WaveAudioDescriptor* ADescObj) // ASDCP::Result_t -MD_to_PCM_ADesc(MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor& ADesc) +ASDCP::MD_to_PCM_ADesc(MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor& ADesc) { ASDCP_TEST_NULL(ADescObj); ADesc.EditRate = ADescObj->SampleRate; @@ -104,7 +104,7 @@ MD_to_PCM_ADesc(MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor& ADesc) ADesc.ChannelFormat = PCM::CF_NONE; - if ( ADescObj->ChannelAssignment.HasValue() ) + if ( ! ADescObj->ChannelAssignment.empty() ) { if ( ADescObj->ChannelAssignment == DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_1_5p1).ul ) ADesc.ChannelFormat = PCM::CF_CFG_1; @@ -120,6 +120,9 @@ MD_to_PCM_ADesc(MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor& ADesc) else if ( ADescObj->ChannelAssignment == DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_5_7p1_DS).ul ) ADesc.ChannelFormat = PCM::CF_CFG_5; + + else if ( ADescObj->ChannelAssignment == DefaultSMPTEDict().Type(MDD_DCAudioChannelCfg_MCA).ul ) + ADesc.ChannelFormat = PCM::CF_CFG_6; } return RESULT_OK; @@ -138,6 +141,39 @@ ASDCP::PCM::operator << (std::ostream& strm, const AudioDescriptor& ADesc) strm << " AvgBps: " << (unsigned) ADesc.AvgBps << std::endl; strm << " LinkedTrackID: " << (unsigned) ADesc.LinkedTrackID << std::endl; strm << " ContainerDuration: " << (unsigned) ADesc.ContainerDuration << std::endl; + strm << " ChannelFormat: "; + switch (ADesc.ChannelFormat) + { + case CF_NONE: + default: + strm << "No Channel Format"; + break; + + case CF_CFG_1: + strm << "Config 1 (5.1 with optional HI/VI)"; + break; + + case CF_CFG_2: + strm << "Config 2 (5.1 + center surround with optional HI/VI)"; + break; + + case CF_CFG_3: + strm << "Config 3 (7.1 with optional HI/VI)"; + break; + + case CF_CFG_4: + strm << "Config 4"; + break; + + case CF_CFG_5: + strm << "Config 5 (7.1 DS with optional HI/VI)"; + break; + + case CF_CFG_6: + strm << "Config 6 (ST 377-4 MCA)"; + break; + } + strm << std::endl; return strm; } @@ -158,7 +194,8 @@ ASDCP::PCM::AudioDescriptorDump(const AudioDescriptor& ADesc, FILE* stream) BlockAlign: %u\n\ AvgBps: %u\n\ LinkedTrackID: %u\n\ - ContainerDuration: %u\n", + ContainerDuration: %u\n\ + ChannelFormat: %u\n", ADesc.EditRate.Numerator, ADesc.EditRate.Denominator, ADesc.AudioSamplingRate.Numerator, ADesc.AudioSamplingRate.Denominator, ADesc.Locked, @@ -167,7 +204,8 @@ ASDCP::PCM::AudioDescriptorDump(const AudioDescriptor& ADesc, FILE* stream) ADesc.BlockAlign, ADesc.AvgBps, ADesc.LinkedTrackID, - ADesc.ContainerDuration + ADesc.ContainerDuration, + ADesc.ChannelFormat ); } @@ -200,7 +238,7 @@ calc_CBR_frame_size(ASDCP::WriterInfo& Info, const ASDCP::PCM::AudioDescriptor& //------------------------------------------------------------------------------------------ -class ASDCP::PCM::MXFReader::h__Reader : public ASDCP::h__Reader +class ASDCP::PCM::MXFReader::h__Reader : public ASDCP::h__ASDCPReader { ASDCP_NO_COPY_CONSTRUCT(h__Reader); h__Reader(); @@ -208,9 +246,9 @@ class ASDCP::PCM::MXFReader::h__Reader : public ASDCP::h__Reader public: AudioDescriptor m_ADesc; - h__Reader(const Dictionary& d) : ASDCP::h__Reader(d) {} - ~h__Reader() {} - Result_t OpenRead(const char*); + h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d) {} + virtual ~h__Reader() {} + Result_t OpenRead(const std::string&); Result_t ReadFrame(ui32_t, FrameBuffer&, AESDecContext*, HMACContext*); }; @@ -218,24 +256,32 @@ public: // // ASDCP::Result_t -ASDCP::PCM::MXFReader::h__Reader::OpenRead(const char* filename) +ASDCP::PCM::MXFReader::h__Reader::OpenRead(const std::string& filename) { Result_t result = OpenMXFRead(filename); if( ASDCP_SUCCESS(result) ) { - InterchangeObject* Object; + InterchangeObject* Object = 0 +; if ( ASDCP_SUCCESS(m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(WaveAudioDescriptor), &Object)) ) { - assert(Object); + if ( Object == 0 ) + { + DefaultLogSink().Error("WaveAudioDescriptor object not found.\n"); + return RESULT_FORMAT; + } + result = MD_to_PCM_ADesc((MXF::WaveAudioDescriptor*)Object, m_ADesc); } } - /* This check has been removed so that DCP-o-matic can use any edit rate - it wants. - */ -#if 0 + if ( m_ADesc.ContainerDuration == 0 ) + { + DefaultLogSink().Error("ContainerDuration unset.\n"); + return RESULT_FORMAT; + } + // check for sample/frame rate sanity if ( ASDCP_SUCCESS(result) && m_ADesc.EditRate != EditRate_24 @@ -247,30 +293,28 @@ ASDCP::PCM::MXFReader::h__Reader::OpenRead(const char* filename) && m_ADesc.EditRate != EditRate_96 && m_ADesc.EditRate != EditRate_100 && m_ADesc.EditRate != EditRate_120 + && m_ADesc.EditRate != EditRate_16 + && m_ADesc.EditRate != EditRate_18 + && m_ADesc.EditRate != EditRate_20 + && m_ADesc.EditRate != EditRate_22 && m_ADesc.EditRate != EditRate_23_98 ) { DefaultLogSink().Error("PCM file EditRate is not a supported value: %d/%d\n", // lu m_ADesc.EditRate.Numerator, m_ADesc.EditRate.Denominator); // oh, they gave us the audio sampling rate instead, assume 24/1 - if ( m_ADesc.EditRate == SampleRate_48k ) + if ( m_ADesc.EditRate == SampleRate_48k || m_ADesc.EditRate == SampleRate_96k ) { DefaultLogSink().Warn("adjusting EditRate to 24/1\n"); m_ADesc.EditRate = EditRate_24; } else { + DefaultLogSink().Error("PCM EditRate not in expected value range.\n"); // or we just drop the hammer return RESULT_FORMAT; } } -#endif - - if( ASDCP_SUCCESS(result) ) - result = InitMXFIndex(); - - if( ASDCP_SUCCESS(result) ) - result = InitInfo(); // TODO: test file for sane CBR index BytesPerEditUnit @@ -287,6 +331,11 @@ ASDCP::PCM::MXFReader::h__Reader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameB if ( ! m_File.IsOpen() ) return RESULT_INIT; + if ( (FrameNum+1) > m_ADesc.ContainerDuration ) + { + return RESULT_RANGE; + } + assert(m_Dict); return ReadEKLVFrame(FrameNum, FrameBuf, m_Dict->ul(MDD_WAVEssence), Ctx, HMAC); } @@ -325,13 +374,13 @@ ASDCP::PCM::MXFReader::~MXFReader() // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::PCM::MXFReader::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::PCM::MXFReader::OP1aHeader() { if ( m_Reader.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Reader->m_HeaderPart; @@ -349,13 +398,28 @@ ASDCP::PCM::MXFReader::OPAtomIndexFooter() return *g_OPAtomIndexFooter; } - return m_Reader->m_FooterPart; + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::PCM::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; } // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. ASDCP::Result_t -ASDCP::PCM::MXFReader::OpenRead(const char* filename) const +ASDCP::PCM::MXFReader::OpenRead(const std::string& filename) const { return m_Reader->OpenRead(filename); } @@ -375,6 +439,12 @@ ASDCP::PCM::MXFReader::ReadFrame(ui32_t FrameNum, FrameBuffer& FrameBuf, } +ASDCP::Result_t +ASDCP::PCM::MXFReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const +{ + return m_Reader->LocateFrame(FrameNum, streamOffset, temporalOffset, keyFrameOffset); +} + // Fill the struct with the values from the file's header. // Returns RESULT_INIT if the file is not open. ASDCP::Result_t @@ -417,7 +487,7 @@ void ASDCP::PCM::MXFReader::DumpIndex(FILE* stream) const { if ( m_Reader->m_File.IsOpen() ) - m_Reader->m_FooterPart.Dump(stream); + m_Reader->m_IndexAccess.Dump(stream); } // @@ -437,7 +507,7 @@ ASDCP::PCM::MXFReader::Close() const //------------------------------------------------------------------------------------------ // -class ASDCP::PCM::MXFWriter::h__Writer : public ASDCP::h__Writer +class ASDCP::PCM::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter { ASDCP_NO_COPY_CONSTRUCT(h__Writer); h__Writer(); @@ -446,13 +516,13 @@ public: AudioDescriptor m_ADesc; byte_t m_EssenceUL[SMPTE_UL_LENGTH]; - h__Writer(const Dictionary& d) : ASDCP::h__Writer(d) { + h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d) { memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); } - ~h__Writer(){} + virtual ~h__Writer(){} - Result_t OpenWrite(const char*, ui32_t HeaderSize); + Result_t OpenWrite(const std::string&, ui32_t HeaderSize); Result_t SetSourceStream(const AudioDescriptor&); Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); Result_t Finalize(); @@ -463,7 +533,7 @@ public: // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -ASDCP::PCM::MXFWriter::h__Writer::OpenWrite(const char* filename, ui32_t HeaderSize) +ASDCP::PCM::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize) { if ( ! m_State.Test_BEGIN() ) return RESULT_STATE; @@ -488,10 +558,6 @@ ASDCP::PCM::MXFWriter::h__Writer::SetSourceStream(const AudioDescriptor& ADesc) if ( ! m_State.Test_INIT() ) return RESULT_STATE; -#if 0 - /* This check has been removed so that DCP-o-matic can use anye dit rate - it wants. - */ if ( ADesc.EditRate != EditRate_24 && ADesc.EditRate != EditRate_25 && ADesc.EditRate != EditRate_30 @@ -501,13 +567,16 @@ ASDCP::PCM::MXFWriter::h__Writer::SetSourceStream(const AudioDescriptor& ADesc) && ADesc.EditRate != EditRate_96 && ADesc.EditRate != EditRate_100 && ADesc.EditRate != EditRate_120 + && ADesc.EditRate != EditRate_16 + && ADesc.EditRate != EditRate_18 + && ADesc.EditRate != EditRate_20 + && ADesc.EditRate != EditRate_22 && ADesc.EditRate != EditRate_23_98 ) { DefaultLogSink().Error("AudioDescriptor.EditRate is not a supported value: %d/%d\n", ADesc.EditRate.Numerator, ADesc.EditRate.Denominator); return RESULT_RAW_FORMAT; } -#endif if ( ADesc.AudioSamplingRate != SampleRate_48k && ADesc.AudioSamplingRate != SampleRate_96k ) { @@ -530,11 +599,10 @@ ASDCP::PCM::MXFWriter::h__Writer::SetSourceStream(const AudioDescriptor& ADesc) if ( ASDCP_SUCCESS(result) ) { - ui32_t TCFrameRate = ( m_ADesc.EditRate == EditRate_23_98 ) ? 24 : m_ADesc.EditRate.Numerator; - - result = WriteMXFHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrapping)), - SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)), - m_ADesc.EditRate, TCFrameRate, calc_CBR_frame_size(m_Info, m_ADesc)); + result = WriteASDCPHeader(PCM_PACKAGE_LABEL, UL(m_Dict->ul(MDD_WAVWrappingFrame)), + SOUND_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_SoundDataDef)), + m_ADesc.EditRate, derive_timecode_rate_from_edit_rate(m_ADesc.EditRate), + calc_CBR_frame_size(m_Info, m_ADesc)); } return result; @@ -571,7 +639,7 @@ ASDCP::PCM::MXFWriter::h__Writer::Finalize() m_State.Goto_FINAL(); - return WriteMXFFooter(); + return WriteASDCPFooter(); } @@ -591,13 +659,13 @@ ASDCP::PCM::MXFWriter::~MXFWriter() // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::PCM::MXFWriter::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::PCM::MXFWriter::OP1aHeader() { if ( m_Writer.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Writer->m_HeaderPart; @@ -618,10 +686,25 @@ ASDCP::PCM::MXFWriter::OPAtomIndexFooter() return m_Writer->m_FooterPart; } +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::PCM::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -ASDCP::PCM::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info, +ASDCP::PCM::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, const AudioDescriptor& ADesc, ui32_t HeaderSize) { if ( Info.LabelSetType == LS_MXF_SMPTE ) diff --git a/asdcplib/src/AS_DCP_TimedText.cpp b/asdcplib/src/AS_DCP_TimedText.cpp index 98ecce1a..10651a84 100644 --- a/asdcplib/src/AS_DCP_TimedText.cpp +++ b/asdcplib/src/AS_DCP_TimedText.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2012, John Hurst +Copyright (c) 2008-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP_TimedText.cpp - \version $Id: AS_DCP_TimedText.cpp,v 1.26 2012/02/07 18:54:25 jhurst Exp $ + \version $Id: AS_DCP_TimedText.cpp,v 1.38 2015/10/09 23:41:11 jhurst Exp $ \brief AS-DCP library, PCM essence reader and writer implementation */ @@ -123,7 +123,7 @@ ASDCP::TimedText::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const typedef std::map<UUID, UUID> ResourceMap_t; -class ASDCP::TimedText::MXFReader::h__Reader : public ASDCP::h__Reader +class ASDCP::TimedText::MXFReader::h__Reader : public ASDCP::h__ASDCPReader { MXF::TimedTextDescriptor* m_EssenceDescriptor; ResourceMap_t m_ResourceMap; @@ -133,11 +133,13 @@ class ASDCP::TimedText::MXFReader::h__Reader : public ASDCP::h__Reader public: TimedTextDescriptor m_TDesc; - h__Reader(const Dictionary& d) : ASDCP::h__Reader(d), m_EssenceDescriptor(0) { + h__Reader(const Dictionary& d) : ASDCP::h__ASDCPReader(d), m_EssenceDescriptor(0) { memset(&m_TDesc.AssetID, 0, UUIDlen); } - Result_t OpenRead(const char*); + virtual ~h__Reader() {} + + Result_t OpenRead(const std::string&); Result_t MD_to_TimedText_TDesc(TimedText::TimedTextDescriptor& TDesc); Result_t ReadTimedTextResource(FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC); Result_t ReadAncillaryResource(const byte_t*, FrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC); @@ -158,7 +160,7 @@ ASDCP::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedText::TimedTe TDesc.NamespaceName = TDescObj->NamespaceURI; TDesc.EncodingName = TDescObj->UCSEncoding; - Batch<UUID>::const_iterator sdi = TDescObj->SubDescriptors.begin(); + Array<UUID>::const_iterator sdi = TDescObj->SubDescriptors.begin(); TimedTextResourceSubDescriptor* DescObject = 0; Result_t result = RESULT_OK; @@ -199,7 +201,7 @@ ASDCP::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedText::TimedTe // ASDCP::Result_t -ASDCP::TimedText::MXFReader::h__Reader::OpenRead(char const* filename) +ASDCP::TimedText::MXFReader::h__Reader::OpenRead(const std::string& filename) { Result_t result = OpenMXFRead(filename); @@ -216,12 +218,6 @@ ASDCP::TimedText::MXFReader::h__Reader::OpenRead(char const* filename) result = MD_to_TimedText_TDesc(m_TDesc); } - if( ASDCP_SUCCESS(result) ) - result = InitMXFIndex(); - - if( ASDCP_SUCCESS(result) ) - result = InitInfo(); - return result; } @@ -269,14 +265,14 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid if ( KM_SUCCESS(result) ) { - Array<RIP::Pair>::const_iterator pi; - RIP::Pair TmpPair; - ui32_t sequence = 1; + RIP::const_pair_iterator pi; + RIP::PartitionPair TmpPair; + ui32_t sequence = 0; // Look up the partition start in the RIP using the SID. // Count the sequence length in because this is the sequence // value needed to complete the HMAC. - for ( pi = m_HeaderPart.m_RIP.PairArray.begin(); pi != m_HeaderPart.m_RIP.PairArray.end(); pi++, sequence++ ) + for ( pi = m_RIP.PairArray.begin(); pi != m_RIP.PairArray.end(); ++pi, ++sequence ) { if ( (*pi).BodySID == DescObject->EssenceStreamID ) { @@ -320,7 +316,7 @@ ASDCP::TimedText::MXFReader::h__Reader::ReadAncillaryResource(const byte_t* uuid // read the essence packet assert(m_Dict); if( ASDCP_SUCCESS(result) ) - result = ReadEKLVPacket(0, 1, FrameBuf, m_Dict->ul(MDD_GenericStream_DataElement), Ctx, HMAC); + result = ReadEKLVPacket(0, sequence, FrameBuf, m_Dict->ul(MDD_GenericStream_DataElement), Ctx, HMAC); } } } @@ -344,13 +340,13 @@ ASDCP::TimedText::MXFReader::~MXFReader() // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::TimedText::MXFReader::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::TimedText::MXFReader::OP1aHeader() { if ( m_Reader.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Reader->m_HeaderPart; @@ -368,13 +364,28 @@ ASDCP::TimedText::MXFReader::OPAtomIndexFooter() return *g_OPAtomIndexFooter; } - return m_Reader->m_FooterPart; + return m_Reader->m_IndexAccess; +} + +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::TimedText::MXFReader::RIP() +{ + if ( m_Reader.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Reader->m_RIP; } // Open the file for reading. The file must exist. Returns error if the // operation cannot be completed. ASDCP::Result_t -ASDCP::TimedText::MXFReader::OpenRead(const char* filename) const +ASDCP::TimedText::MXFReader::OpenRead(const std::string& filename) const { return m_Reader->OpenRead(filename); } @@ -458,7 +469,7 @@ void ASDCP::TimedText::MXFReader::DumpIndex(FILE* stream) const { if ( m_Reader->m_File.IsOpen() ) - m_Reader->m_FooterPart.Dump(stream); + m_Reader->m_IndexAccess.Dump(stream); } // @@ -479,7 +490,7 @@ ASDCP::TimedText::MXFReader::Close() const // -class ASDCP::TimedText::MXFWriter::h__Writer : public ASDCP::h__Writer +class ASDCP::TimedText::MXFWriter::h__Writer : public ASDCP::h__ASDCPWriter { ASDCP_NO_COPY_CONSTRUCT(h__Writer); h__Writer(); @@ -489,13 +500,13 @@ public: byte_t m_EssenceUL[SMPTE_UL_LENGTH]; ui32_t m_EssenceStreamID; - h__Writer(const Dictionary& d) : ASDCP::h__Writer(d), m_EssenceStreamID(10) { + h__Writer(const Dictionary& d) : ASDCP::h__ASDCPWriter(d), m_EssenceStreamID(10) { memset(m_EssenceUL, 0, SMPTE_UL_LENGTH); } - ~h__Writer(){} + virtual ~h__Writer() {} - Result_t OpenWrite(const char*, ui32_t HeaderSize); + Result_t OpenWrite(const std::string&, ui32_t HeaderSize); Result_t SetSourceStream(const TimedTextDescriptor&); Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0); Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0); @@ -521,7 +532,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::TimedText_TDesc_to_MD(TimedText::TimedTe // ASDCP::Result_t -ASDCP::TimedText::MXFWriter::h__Writer::OpenWrite(char const* filename, ui32_t HeaderSize) +ASDCP::TimedText::MXFWriter::h__Writer::OpenWrite(const std::string& filename, ui32_t HeaderSize) { if ( ! m_State.Test_BEGIN() ) return RESULT_STATE; @@ -558,6 +569,9 @@ ASDCP::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedT resourceSubdescriptor->EssenceStreamID = m_EssenceStreamID++; m_EssenceSubDescriptorList.push_back((FileDescriptor*)resourceSubdescriptor); m_EssenceDescriptor->SubDescriptors.push_back(resourceSubdescriptor->InstanceUID); + + // 72 == sizeof K, L, instanceuid, uuid + sizeof int32 + tag/len * 4 + m_HeaderSize += ( resourceSubdescriptor->MIMEMediaType.ArchiveLength() * 2 /*ArchiveLength is broken*/ ) + 72; } m_EssenceStreamID = 10; @@ -566,10 +580,23 @@ ASDCP::TimedText::MXFWriter::h__Writer::SetSourceStream(ASDCP::TimedText::TimedT if ( ASDCP_SUCCESS(result) ) { InitHeader(); - AddDMSegment(m_TDesc.EditRate, 24, TIMED_TEXT_DEF_LABEL, - UL(m_Dict->ul(MDD_PictureDataDef)), TIMED_TEXT_PACKAGE_LABEL); - AddEssenceDescriptor(UL(m_Dict->ul(MDD_TimedTextWrapping))); + // First RIP Entry + if ( m_Info.LabelSetType == LS_MXF_SMPTE ) // ERK + { + m_RIP.PairArray.push_back(RIP::PartitionPair(0, 0)); // 3-part, no essence in header + } + else + { + DefaultLogSink().Error("Unable to write Interop timed-text MXF file. Use SMPTE DCP options instead.\n"); + return RESULT_FORMAT; + } + + // timecode rate and essence rate are the same + AddDMSegment(m_TDesc.EditRate, m_TDesc.EditRate, derive_timecode_rate_from_edit_rate(m_TDesc.EditRate), TIMED_TEXT_DEF_LABEL, + UL(m_Dict->ul(MDD_DataDataDef)), TIMED_TEXT_PACKAGE_LABEL); + + AddEssenceDescriptor(UL(m_Dict->ul(MDD_TimedTextWrappingClip))); result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); @@ -637,11 +664,11 @@ ASDCP::TimedText::MXFWriter::h__Writer::WriteAncillaryResource(const ASDCP::Time MXF::Partition GSPart(m_Dict); GSPart.ThisPartition = here; - GSPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset; + GSPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset; GSPart.BodySID = m_EssenceStreamID; GSPart.OperationalPattern = m_HeaderPart.OperationalPattern; - m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(m_EssenceStreamID++, here)); + m_RIP.PairArray.push_back(RIP::PartitionPair(m_EssenceStreamID++, here)); GSPart.EssenceContainers.push_back(UL(m_Dict->ul(MDD_TimedTextEssence))); UL TmpUL(m_Dict->ul(MDD_GenericStreamPartition)); Result_t result = GSPart.WriteToFile(m_File, TmpUL); @@ -663,7 +690,7 @@ ASDCP::TimedText::MXFWriter::h__Writer::Finalize() m_FramesWritten = m_TDesc.ContainerDuration; m_State.Goto_FINAL(); - return WriteMXFFooter(); + return WriteASDCPFooter(); } @@ -680,13 +707,13 @@ ASDCP::TimedText::MXFWriter::~MXFWriter() // Warning: direct manipulation of MXF structures can interfere // with the normal operation of the wrapper. Caveat emptor! // -ASDCP::MXF::OPAtomHeader& -ASDCP::TimedText::MXFWriter::OPAtomHeader() +ASDCP::MXF::OP1aHeader& +ASDCP::TimedText::MXFWriter::OP1aHeader() { if ( m_Writer.empty() ) { - assert(g_OPAtomHeader); - return *g_OPAtomHeader; + assert(g_OP1aHeader); + return *g_OP1aHeader; } return m_Writer->m_HeaderPart; @@ -707,10 +734,25 @@ ASDCP::TimedText::MXFWriter::OPAtomIndexFooter() return m_Writer->m_FooterPart; } +// Warning: direct manipulation of MXF structures can interfere +// with the normal operation of the wrapper. Caveat emptor! +// +ASDCP::MXF::RIP& +ASDCP::TimedText::MXFWriter::RIP() +{ + if ( m_Writer.empty() ) + { + assert(g_RIP); + return *g_RIP; + } + + return m_Writer->m_RIP; +} + // Open the file for writing. The file must not exist. Returns error if // the operation cannot be completed. ASDCP::Result_t -ASDCP::TimedText::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info, +ASDCP::TimedText::MXFWriter::OpenWrite(const std::string& filename, const WriterInfo& Info, const TimedTextDescriptor& TDesc, ui32_t HeaderSize) { if ( Info.LabelSetType != LS_MXF_SMPTE ) diff --git a/asdcplib/src/AS_DCP_internal.h b/asdcplib/src/AS_DCP_internal.h index 73106a26..a52bd75b 100755 --- a/asdcplib/src/AS_DCP_internal.h +++ b/asdcplib/src/AS_DCP_internal.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP_internal.h - \version $Id: AS_DCP_internal.h,v 1.27 2012/02/07 18:54:25 jhurst Exp $ + \version $Id: AS_DCP_internal.h,v 1.45 2014/09/21 13:27:43 jhurst Exp $ \brief AS-DCP library, non-public common elements */ @@ -38,23 +38,53 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Metadata.h" using Kumu::DefaultLogSink; -// using namespace std; using namespace ASDCP; using namespace ASDCP::MXF; +// a magic number identifying asdcplib +#ifndef ASDCP_BUILD_NUMBER +#define ASDCP_BUILD_NUMBER 0x6A68 +#endif + + #ifdef DEFAULT_MD_DECL -ASDCP::MXF::OPAtomHeader *g_OPAtomHeader; +ASDCP::MXF::OP1aHeader *g_OP1aHeader; ASDCP::MXF::OPAtomIndexFooter *g_OPAtomIndexFooter; +ASDCP::MXF::RIP *g_RIP; #else -extern MXF::OPAtomHeader *g_OPAtomHeader; +extern MXF::OP1aHeader *g_OP1aHeader; extern MXF::OPAtomIndexFooter *g_OPAtomIndexFooter; +extern MXF::RIP *g_RIP; #endif namespace ASDCP { - void default_md_object_init(); + // + static std::vector<int> + version_split(const char* str) + { + std::vector<int> result; + const char* pstr = str; + const char* r = strchr(pstr, '.'); + + while ( r != 0 ) + { + assert(r >= pstr); + if ( r > pstr ) + result.push_back(strtol(pstr, 0, 10)); + + pstr = r + 1; + r = strchr(pstr, '.'); + } + + if( strlen(pstr) > 0 ) + result.push_back(strtol(pstr, 0, 10)); + + assert(result.size() == 3); + return result; + } // constant values used to calculate KLV and EKLV packet sizes static const ui32_t klv_cryptinfo_size = @@ -95,11 +125,40 @@ namespace ASDCP //------------------------------------------------------------------------------------------ // + ui32_t derive_timecode_rate_from_edit_rate(const ASDCP::Rational& edit_rate); + Result_t MD_to_WriterInfo(MXF::Identification*, WriterInfo&); Result_t MD_to_CryptoInfo(MXF::CryptographicContext*, WriterInfo&, const Dictionary&); + Result_t EncryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESEncContext*); Result_t DecryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESDecContext*); + Result_t MD_to_JP2K_PDesc(const ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor, + const ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor, + const ASDCP::Rational& EditRate, const ASDCP::Rational& SampleRate, + ASDCP::JP2K::PictureDescriptor& PDesc); + + Result_t JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc, + const ASDCP::Dictionary& dict, + ASDCP::MXF::GenericPictureEssenceDescriptor& EssenceDescriptor, + ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor); + + Result_t PCM_ADesc_to_MD(PCM::AudioDescriptor& ADesc, ASDCP::MXF::WaveAudioDescriptor* ADescObj); + Result_t MD_to_PCM_ADesc(ASDCP::MXF::WaveAudioDescriptor* ADescObj, PCM::AudioDescriptor& ADesc); + + void AddDMScrypt(Partition& HeaderPart, SourcePackage& Package, + WriterInfo& Descr, const UL& WrappingUL, const Dictionary*& Dict); + + Result_t Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, + const ASDCP::WriterInfo& Info, Kumu::fpos_t& LastPosition, ASDCP::FrameBuffer& CtFrameBuf, + ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC); + + Result_t Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart, + const ASDCP::WriterInfo& Info, ASDCP::FrameBuffer& CtFrameBuf, ui32_t& FramesWritten, + ui64_t & StreamOffset, const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL, + AESEncContext* Ctx, HMACContext* HMAC); + // class KLReader : public ASDCP::KLVPacket { @@ -110,140 +169,701 @@ namespace ASDCP KLReader() {} ~KLReader() {} - inline byte_t* Key() { return m_KeyBuf; } - inline ui64_t Length() { return m_ValueLength; } - inline ui64_t KLLength() { return m_KLLength; } - + inline const byte_t* Key() { return m_KeyBuf; } + inline const ui64_t Length() { return m_ValueLength; } + inline const ui64_t KLLength() { return m_KLLength; } + Result_t ReadKLFromFile(Kumu::FileReader& Reader); }; - // - class h__Reader - { - ASDCP_NO_COPY_CONSTRUCT(h__Reader); - h__Reader(); - - public: - const Dictionary* m_Dict; - Kumu::FileReader m_File; - OPAtomHeader m_HeaderPart; - Partition m_BodyPart; - OPAtomIndexFooter m_FooterPart; - ui64_t m_EssenceStart; - WriterInfo m_Info; - ASDCP::FrameBuffer m_CtFrameBuf; - Kumu::fpos_t m_LastPosition; - - h__Reader(const Dictionary&); - virtual ~h__Reader(); - - Result_t InitInfo(); - Result_t OpenMXFRead(const char* filename); - Result_t InitMXFIndex(); + namespace MXF + { + //--------------------------------------------------------------------------------- + // + + /// void default_md_object_init(); + + template <class HeaderType, class IndexAccessType> + class TrackFileReader + { + KM_NO_COPY_CONSTRUCT(TrackFileReader); + TrackFileReader(); + + public: + const Dictionary* m_Dict; + Kumu::FileReader m_File; + HeaderType m_HeaderPart; + IndexAccessType m_IndexAccess; + RIP m_RIP; + WriterInfo m_Info; + ASDCP::FrameBuffer m_CtFrameBuf; + Kumu::fpos_t m_LastPosition; + + TrackFileReader(const Dictionary& d) : + m_HeaderPart(m_Dict), m_IndexAccess(m_Dict), m_RIP(m_Dict), m_Dict(&d) + { + default_md_object_init(); + } + + virtual ~TrackFileReader() { + Close(); + } + + const MXF::RIP& GetRIP() const { return m_RIP; } + + // + Result_t OpenMXFRead(const std::string& filename) + { + m_LastPosition = 0; + Result_t result = m_File.OpenRead(filename); + + if ( ASDCP_SUCCESS(result) ) + result = SeekToRIP(m_File); + + if ( ASDCP_SUCCESS(result) ) + { + result = m_RIP.InitFromFile(m_File); + ui32_t test_s = m_RIP.PairArray.size(); + + if ( ASDCP_FAILURE(result) ) + { + DefaultLogSink().Error("File contains no RIP\n"); + } + else if ( m_RIP.PairArray.empty() ) + { + DefaultLogSink().Error("RIP contains no Pairs.\n"); + } + } + else + { + DefaultLogSink().Error("TrackFileReader::OpenMXFRead, SeekToRIP failed\n"); + } + + m_File.Seek(0); + result = m_HeaderPart.InitFromFile(m_File); + + if ( KM_FAILURE(result) ) + { + DefaultLogSink().Error("TrackFileReader::OpenMXFRead, header init failed\n"); + } + + return result; + } + + // + Result_t InitInfo() + { + assert(m_Dict); + InterchangeObject* Object; + + // Identification + Result_t result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(Identification), &Object); + + // Writer Info and SourcePackage + if ( KM_SUCCESS(result) ) + { + MD_to_WriterInfo((Identification*)Object, m_Info); + result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(SourcePackage), &Object); + } + + if ( KM_SUCCESS(result) ) + { + SourcePackage* SP = (SourcePackage*)Object; + memcpy(m_Info.AssetUUID, SP->PackageUID.Value() + 16, UUIDlen); + } + + // optional CryptographicContext + if ( KM_SUCCESS(result) ) + { + Result_t cr_result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CryptographicContext), &Object); + + if ( KM_SUCCESS(cr_result) ) + MD_to_CryptoInfo((CryptographicContext*)Object, m_Info, *m_Dict); + } + + return result; + } + + // positions file before reading + // allows external control of index offset + Result_t ReadEKLVFrame(const ui64_t& body_offset, + ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) + { + // look up frame index node + IndexTableSegment::IndexEntry TmpEntry; + + if ( KM_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) ) + { + DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); + return RESULT_RANGE; + } + + // get relative frame position, apply offset and go read the frame's key and length + Kumu::fpos_t FilePosition = body_offset + TmpEntry.StreamOffset; + Result_t result = RESULT_OK; + + if ( FilePosition != m_LastPosition ) + { + m_LastPosition = FilePosition; + result = m_File.Seek(FilePosition); + } + + if ( KM_SUCCESS(result) ) + result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC); + + return result; + } + + // positions file before reading + // assumes "processed" index entries have absolute positions + Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) + { + // look up frame index node + IndexTableSegment::IndexEntry TmpEntry; + + if ( KM_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) ) + { + DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); + return RESULT_RANGE; + } + + // get absolute frame position and go read the frame's key and length + Result_t result = RESULT_OK; + + if ( TmpEntry.StreamOffset != m_LastPosition ) + { + m_LastPosition = TmpEntry.StreamOffset; + result = m_File.Seek(TmpEntry.StreamOffset); + } + + if ( KM_SUCCESS(result) ) + result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC); + + return result; + } + + // reads from current position + Result_t ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) + { + assert(m_Dict); + return Read_EKLV_Packet(m_File, *m_Dict, m_Info, m_LastPosition, m_CtFrameBuf, + FrameNum, SequenceNum, FrameBuf, EssenceUL, Ctx, HMAC); + } + + // Get the position of a frame from a track file + Result_t LocateFrame(const ui64_t& body_offset, + ui32_t FrameNum, Kumu::fpos_t& streamOffset, + i8_t& temporalOffset, i8_t& keyFrameOffset) + { + // look up frame index node + IndexTableSegment::IndexEntry TmpEntry; + + if ( KM_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) ) + { + DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); + return RESULT_RANGE; + } + + // get frame position, temporal offset, and key frame ofset + streamOffset = body_offset + TmpEntry.StreamOffset; + temporalOffset = TmpEntry.TemporalOffset; + keyFrameOffset = TmpEntry.KeyFrameOffset; + + return RESULT_OK; + } + + // + void Close() + { + m_File.Close(); + } + }; + + //------------------------------------------------------------------------------------------ + // + + // + template <class ClipT> + struct TrackSet + { + MXF::Track* Track; + MXF::Sequence* Sequence; + ClipT* Clip; + + TrackSet() : Track(0), Sequence(0), Clip(0) {} + }; + + // + template <class PackageT, class ClipT> + TrackSet<ClipT> + CreateTrackAndSequence(OP1aHeader& Header, PackageT& Package, const std::string TrackName, + const MXF::Rational& clip_edit_rate, const UL& Definition, ui32_t TrackID, const Dictionary*& Dict) + { + TrackSet<ClipT> NewTrack; + + NewTrack.Track = new Track(Dict); + Header.AddChildObject(NewTrack.Track); + NewTrack.Track->EditRate = clip_edit_rate; + Package.Tracks.push_back(NewTrack.Track->InstanceUID); + NewTrack.Track->TrackID = TrackID; + NewTrack.Track->TrackName = TrackName.c_str(); + + NewTrack.Sequence = new Sequence(Dict); + Header.AddChildObject(NewTrack.Sequence); + NewTrack.Track->Sequence = NewTrack.Sequence->InstanceUID; + NewTrack.Sequence->DataDefinition = Definition; + + return NewTrack; + } + + // + template <class PackageT> + TrackSet<TimecodeComponent> + CreateTimecodeTrack(OP1aHeader& Header, PackageT& Package, + const MXF::Rational& tc_edit_rate, ui32_t tc_frame_rate, ui64_t TCStart, const Dictionary*& Dict) + { + assert(Dict); + UL TCUL(Dict->ul(MDD_TimecodeDataDef)); + + TrackSet<TimecodeComponent> NewTrack = + CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", + tc_edit_rate, TCUL, 1, Dict); + + NewTrack.Clip = new TimecodeComponent(Dict); + Header.AddChildObject(NewTrack.Clip); + NewTrack.Sequence->StructuralComponents.push_back(NewTrack.Clip->InstanceUID); + NewTrack.Clip->RoundedTimecodeBase = tc_frame_rate; + NewTrack.Clip->StartTimecode = TCStart; + NewTrack.Clip->DataDefinition = TCUL; + + return NewTrack; + } + + + // state machine for mxf writer + enum WriterState_t { + ST_BEGIN, // waiting for Open() + ST_INIT, // waiting for SetSourceStream() + ST_READY, // ready to write frames + ST_RUNNING, // one or more frames written + ST_FINAL, // index written, file closed + ST_MAX + }; + + // implementation of h__WriterState class Goto_* methods +#define Goto_body(s1,s2) \ + if ( m_State != (s1) ) { \ + return RESULT_STATE; \ + } \ + m_State = (s2); \ + return RESULT_OK + // + class h__WriterState + { + ASDCP_NO_COPY_CONSTRUCT(h__WriterState); + + public: + WriterState_t m_State; + h__WriterState() : m_State(ST_BEGIN) {} + ~h__WriterState() {} + + inline bool Test_BEGIN() { return m_State == ST_BEGIN; } + inline bool Test_INIT() { return m_State == ST_INIT; } + inline bool Test_READY() { return m_State == ST_READY;} + inline bool Test_RUNNING() { return m_State == ST_RUNNING; } + inline bool Test_FINAL() { return m_State == ST_FINAL; } + inline Result_t Goto_INIT() { Goto_body(ST_BEGIN, ST_INIT); } + inline Result_t Goto_READY() { Goto_body(ST_INIT, ST_READY); } + inline Result_t Goto_RUNNING() { Goto_body(ST_READY, ST_RUNNING); } + inline Result_t Goto_FINAL() { Goto_body(ST_RUNNING, ST_FINAL); } + }; + + //------------------------------------------------------------------------------------------ + // + + // + template <class HeaderType> + class TrackFileWriter + { + KM_NO_COPY_CONSTRUCT(TrackFileWriter); + TrackFileWriter(); + + public: + const Dictionary* m_Dict; + Kumu::FileWriter m_File; + ui32_t m_HeaderSize; + HeaderType m_HeaderPart; + RIP m_RIP; + + MaterialPackage* m_MaterialPackage; + SourcePackage* m_FilePackage; + ContentStorage* m_ContentStorage; + + FileDescriptor* m_EssenceDescriptor; + std::list<InterchangeObject*> m_EssenceSubDescriptorList; + + ui32_t m_FramesWritten; + ui64_t m_StreamOffset; + ASDCP::FrameBuffer m_CtFrameBuf; + h__WriterState m_State; + WriterInfo m_Info; + + typedef std::list<ui64_t*> DurationElementList_t; + DurationElementList_t m_DurationUpdateList; + + TrackFileWriter(const Dictionary& d) : + m_Dict(&d), m_HeaderSize(0), m_HeaderPart(m_Dict), m_RIP(m_Dict), + m_MaterialPackage(0), m_FilePackage(0), m_ContentStorage(0), + m_EssenceDescriptor(0), m_FramesWritten(0), m_StreamOffset(0) + { + default_md_object_init(); + } + + virtual ~TrackFileWriter() { + Close(); + } + + const MXF::RIP& GetRIP() const { return m_RIP; } + + void InitHeader() + { + assert(m_Dict); + assert(m_EssenceDescriptor); + + m_HeaderPart.m_Primer.ClearTagList(); + m_HeaderPart.m_Preface = new Preface(m_Dict); + m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface); + + // Set the Operational Pattern label -- we're just starting and have no RIP or index, + // so we tell the world by using OP1a + m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a)); + m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern; + + // Identification + Identification* Ident = new Identification(m_Dict); + m_HeaderPart.AddChildObject(Ident); + m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID); + + Kumu::GenRandomValue(Ident->ThisGenerationUID); + Ident->CompanyName = m_Info.CompanyName.c_str(); + Ident->ProductName = m_Info.ProductName.c_str(); + Ident->VersionString = m_Info.ProductVersion.c_str(); + Ident->ProductUID.Set(m_Info.ProductUUID); + Ident->Platform = ASDCP_PLATFORM; + + std::vector<int> version = version_split(Version()); + + Ident->ToolkitVersion.Major = version[0]; + Ident->ToolkitVersion.Minor = version[1]; + Ident->ToolkitVersion.Patch = version[2]; + Ident->ToolkitVersion.Build = ASDCP_BUILD_NUMBER; + Ident->ToolkitVersion.Release = VersionType::RL_RELEASE; + } + + // + void AddSourceClip(const MXF::Rational& clip_edit_rate, + const MXF::Rational& tc_edit_rate, ui32_t TCFrameRate, + const std::string& TrackName, const UL& EssenceUL, + const UL& DataDefinition, const std::string& PackageLabel) + { + if ( m_ContentStorage == 0 ) + { + m_ContentStorage = new ContentStorage(m_Dict); + m_HeaderPart.AddChildObject(m_ContentStorage); + m_HeaderPart.m_Preface->ContentStorage = m_ContentStorage->InstanceUID; + } + + EssenceContainerData* ECD = new EssenceContainerData(m_Dict); + m_HeaderPart.AddChildObject(ECD); + m_ContentStorage->EssenceContainerData.push_back(ECD->InstanceUID); + ECD->IndexSID = 129; + ECD->BodySID = 1; + + UUID assetUUID(m_Info.AssetUUID); + UMID SourcePackageUMID, MaterialPackageUMID; + SourcePackageUMID.MakeUMID(0x0f, assetUUID); + MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence + + // + // Material Package + // + m_MaterialPackage = new MaterialPackage(m_Dict); + m_MaterialPackage->Name = "AS-DCP Material Package"; + m_MaterialPackage->PackageUID = MaterialPackageUMID; + m_HeaderPart.AddChildObject(m_MaterialPackage); + m_ContentStorage->Packages.push_back(m_MaterialPackage->InstanceUID); + + TrackSet<TimecodeComponent> MPTCTrack = + CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage, + tc_edit_rate, TCFrameRate, 0, m_Dict); + + MPTCTrack.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration.get())); + MPTCTrack.Clip->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration.get())); + + TrackSet<SourceClip> MPTrack = + CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage, + TrackName, clip_edit_rate, DataDefinition, + 2, m_Dict); + MPTrack.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration.get())); + + MPTrack.Clip = new SourceClip(m_Dict); + m_HeaderPart.AddChildObject(MPTrack.Clip); + MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID); + MPTrack.Clip->DataDefinition = DataDefinition; + MPTrack.Clip->SourcePackageID = SourcePackageUMID; + MPTrack.Clip->SourceTrackID = 2; + + MPTrack.Clip->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration.get())); - // positions file before reading - Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, - const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC); + + // + // File (Source) Package + // + m_FilePackage = new SourcePackage(m_Dict); + m_FilePackage->Name = PackageLabel.c_str(); + m_FilePackage->PackageUID = SourcePackageUMID; + ECD->LinkedPackageUID = SourcePackageUMID; + + m_HeaderPart.AddChildObject(m_FilePackage); + m_ContentStorage->Packages.push_back(m_FilePackage->InstanceUID); + + TrackSet<TimecodeComponent> FPTCTrack = + CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage, + tc_edit_rate, TCFrameRate, + ui64_C(3600) * TCFrameRate, m_Dict); + + FPTCTrack.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration.get())); + FPTCTrack.Clip->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration.get())); + + TrackSet<SourceClip> FPTrack = + CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage, + TrackName, clip_edit_rate, DataDefinition, + 2, m_Dict); + + FPTrack.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration.get())); + + // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from. + FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12))); + + FPTrack.Clip = new SourceClip(m_Dict); + m_HeaderPart.AddChildObject(FPTrack.Clip); + FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID); + FPTrack.Clip->DataDefinition = DataDefinition; + + // for now we do not allow setting this value, so all files will be 'original' + FPTrack.Clip->SourceTrackID = 0; + FPTrack.Clip->SourcePackageID = NilUMID; + + FPTrack.Clip->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration.get())); + + m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID; + } + + // + void AddDMSegment(const MXF::Rational& clip_edit_rate, + const MXF::Rational& tc_edit_rate, ui32_t tc_frame_rate, + const std::string& TrackName, const UL& DataDefinition, + const std::string& PackageLabel) + { + if ( m_ContentStorage == 0 ) + { + m_ContentStorage = new ContentStorage(m_Dict); + m_HeaderPart.AddChildObject(m_ContentStorage); + m_HeaderPart.m_Preface->ContentStorage = m_ContentStorage->InstanceUID; + } + + EssenceContainerData* ECD = new EssenceContainerData(m_Dict); + m_HeaderPart.AddChildObject(ECD); + m_ContentStorage->EssenceContainerData.push_back(ECD->InstanceUID); + ECD->IndexSID = 129; + ECD->BodySID = 1; + + UUID assetUUID(m_Info.AssetUUID); + UMID SourcePackageUMID, MaterialPackageUMID; + SourcePackageUMID.MakeUMID(0x0f, assetUUID); + MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence + + // + // Material Package + // + m_MaterialPackage = new MaterialPackage(m_Dict); + m_MaterialPackage->Name = "AS-DCP Material Package"; + m_MaterialPackage->PackageUID = MaterialPackageUMID; + m_HeaderPart.AddChildObject(m_MaterialPackage); + m_ContentStorage->Packages.push_back(m_MaterialPackage->InstanceUID); + + TrackSet<TimecodeComponent> MPTCTrack = + CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage, + tc_edit_rate, tc_frame_rate, 0, m_Dict); + + MPTCTrack.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration.get())); + MPTCTrack.Clip->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration.get())); + + TrackSet<DMSegment> MPTrack = + CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage, + TrackName, clip_edit_rate, DataDefinition, + 2, m_Dict); + MPTrack.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration.get())); + + MPTrack.Clip = new DMSegment(m_Dict); + m_HeaderPart.AddChildObject(MPTrack.Clip); + MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID); + MPTrack.Clip->DataDefinition = DataDefinition; + // MPTrack.Clip->SourcePackageID = SourcePackageUMID; + // MPTrack.Clip->SourceTrackID = 2; + + m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration)); - // reads from current position - Result_t ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf, - const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC); - void Close(); - }; + + // + // File (Source) Package + // + m_FilePackage = new SourcePackage(m_Dict); + m_FilePackage->Name = PackageLabel.c_str(); + m_FilePackage->PackageUID = SourcePackageUMID; + ECD->LinkedPackageUID = SourcePackageUMID; + + m_HeaderPart.AddChildObject(m_FilePackage); + m_ContentStorage->Packages.push_back(m_FilePackage->InstanceUID); + + TrackSet<TimecodeComponent> FPTCTrack = + CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage, + clip_edit_rate, tc_frame_rate, + ui64_C(3600) * tc_frame_rate, m_Dict); + + FPTCTrack.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration.get())); + FPTCTrack.Clip->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration.get())); + + TrackSet<DMSegment> FPTrack = + CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage, + TrackName, clip_edit_rate, DataDefinition, + 2, m_Dict); + + FPTrack.Sequence->Duration.set_has_value(); + m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration.get())); + + FPTrack.Clip = new DMSegment(m_Dict); + m_HeaderPart.AddChildObject(FPTrack.Clip); + FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID); + FPTrack.Clip->DataDefinition = DataDefinition; + FPTrack.Clip->EventComment = "ST 429-5 Timed Text"; + + m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration)); + + m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID; + } + + // + void AddEssenceDescriptor(const UL& WrappingUL) + { + // + // Essence Descriptor + // + m_EssenceDescriptor->EssenceContainer = WrappingUL; + m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID; + + // + // Essence Descriptors + // + assert(m_Dict); + UL GenericContainerUL(m_Dict->ul(MDD_GCMulti)); + m_HeaderPart.EssenceContainers.push_back(GenericContainerUL); + + if ( m_Info.EncryptedEssence ) + { + UL CryptEssenceUL(m_Dict->ul(MDD_EncryptedContainerLabel)); + m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL); + m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel))); + AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict); + //// TODO: fix DMSegment Duration value + } + else + { + m_HeaderPart.EssenceContainers.push_back(WrappingUL); + } + + m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers; + m_HeaderPart.AddChildObject(m_EssenceDescriptor); + + std::list<InterchangeObject*>::iterator sdli = m_EssenceSubDescriptorList.begin(); + for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ ) + m_HeaderPart.AddChildObject(*sdli); + + m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID; + } + + // + void Close() + { + m_File.Close(); + } + + }; + + }/// namespace MXF + //------------------------------------------------------------------------------------------ + // - // state machine for mxf writer - enum WriterState_t { - ST_BEGIN, // waiting for Open() - ST_INIT, // waiting for SetSourceStream() - ST_READY, // ready to write frames - ST_RUNNING, // one or more frames written - ST_FINAL, // index written, file closed - }; - - // implementation of h__WriterState class Goto_* methods -#define Goto_body(s1,s2) if ( m_State != (s1) ) \ - return RESULT_STATE; \ - m_State = (s2); \ - return RESULT_OK // - class h__WriterState + class h__ASDCPReader : public MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter> { - ASDCP_NO_COPY_CONSTRUCT(h__WriterState); + ASDCP_NO_COPY_CONSTRUCT(h__ASDCPReader); + h__ASDCPReader(); public: - WriterState_t m_State; - h__WriterState() : m_State(ST_BEGIN) {} - ~h__WriterState() {} - - inline bool Test_BEGIN() { return m_State == ST_BEGIN; } - inline bool Test_INIT() { return m_State == ST_INIT; } - inline bool Test_READY() { return m_State == ST_READY;} - inline bool Test_RUNNING() { return m_State == ST_RUNNING; } - inline bool Test_FINAL() { return m_State == ST_FINAL; } - inline Result_t Goto_INIT() { Goto_body(ST_BEGIN, ST_INIT); } - inline Result_t Goto_READY() { Goto_body(ST_INIT, ST_READY); } - inline Result_t Goto_RUNNING() { Goto_body(ST_READY, ST_RUNNING); } - inline Result_t Goto_FINAL() { Goto_body(ST_RUNNING, ST_FINAL); } - }; + Partition m_BodyPart; - typedef std::list<ui64_t*> DurationElementList_t; + h__ASDCPReader(const Dictionary&); + virtual ~h__ASDCPReader(); + + Result_t OpenMXFRead(const std::string& filename); + Result_t ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC); + Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, + i8_t& temporalOffset, i8_t& keyFrameOffset); + }; // - class h__Writer + class h__ASDCPWriter : public MXF::TrackFileWriter<OP1aHeader> { - ASDCP_NO_COPY_CONSTRUCT(h__Writer); - h__Writer(); + ASDCP_NO_COPY_CONSTRUCT(h__ASDCPWriter); + h__ASDCPWriter(); public: - const Dictionary* m_Dict; - Kumu::FileWriter m_File; - ui32_t m_HeaderSize; - OPAtomHeader m_HeaderPart; Partition m_BodyPart; OPAtomIndexFooter m_FooterPart; - ui64_t m_EssenceStart; - - MaterialPackage* m_MaterialPackage; - SourcePackage* m_FilePackage; - - FileDescriptor* m_EssenceDescriptor; - std::list<InterchangeObject*> m_EssenceSubDescriptorList; - - ui32_t m_FramesWritten; - ui64_t m_StreamOffset; - ASDCP::FrameBuffer m_CtFrameBuf; - h__WriterState m_State; - WriterInfo m_Info; - DurationElementList_t m_DurationUpdateList; - - h__Writer(const Dictionary&); - virtual ~h__Writer(); - - void InitHeader(); - void AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate, - const std::string& TrackName, const UL& EssenceUL, - const UL& DataDefinition, const std::string& PackageLabel); - void AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate, - const std::string& TrackName, const UL& DataDefinition, - const std::string& PackageLabel); - void AddEssenceDescriptor(const UL& WrappingUL); - Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0); - // all the above for a single source clip - Result_t WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL, - const std::string& TrackName, const UL& EssenceUL, - const UL& DataDefinition, const MXF::Rational& EditRate, - ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0); - - Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, - const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC, std::string* hash = 0); + h__ASDCPWriter(const Dictionary&); + virtual ~h__ASDCPWriter(); - Result_t FakeWriteEKLVPacket(int size); - - Result_t WriteMXFFooter(); + // all the above for a single source clip + Result_t WriteASDCPHeader(const std::string& PackageLabel, const UL& WrappingUL, + const std::string& TrackName, const UL& EssenceUL, + const UL& DataDefinition, const MXF::Rational& EditRate, + ui32_t TCFrameRate, ui32_t BytesPerEditUnit = 0); - }; + Result_t CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit = 0); + Result_t WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, + AESEncContext* Ctx, HMACContext* HMAC); + Result_t WriteASDCPFooter(); + }; // helper class for calculating Integrity Packs, used by WriteEKLVPacket() below. @@ -252,15 +872,15 @@ namespace ASDCP { public: byte_t Data[klv_intpack_size]; - + IntegrityPack() { memset(Data, 0, klv_intpack_size); } ~IntegrityPack() {} - - Result_t CalcValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC); - Result_t TestValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC); + + Result_t CalcValues(const ASDCP::FrameBuffer&, const byte_t* AssetID, ui32_t sequence, HMACContext* HMAC); + Result_t TestValues(const ASDCP::FrameBuffer&, const byte_t* AssetID, ui32_t sequence, HMACContext* HMAC); }; diff --git a/asdcplib/src/AtmosSyncChannel_Generator.cpp b/asdcplib/src/AtmosSyncChannel_Generator.cpp new file mode 100644 index 00000000..5bf21114 --- /dev/null +++ b/asdcplib/src/AtmosSyncChannel_Generator.cpp @@ -0,0 +1,149 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AtmosSyncChannel_Generator.cpp + \version $Id: AtmosSyncChannel_Generator.cpp,v 1.1 2013/04/12 23:39:30 mikey Exp $ + \brief Dolby Atmos sync channel generator implementation +*/ + +#include <AtmosSyncChannel_Generator.h> + +#include <AS_DCP.h> + +using namespace ASDCP; + +// +ASDCP::PCM::AtmosSyncChannelGenerator::AtmosSyncChannelGenerator(ui16_t bitsPerSample, ui32_t sampleRate, + const ASDCP::Rational& editRate, const byte_t* uuid) + : m_syncEncoder(), + m_audioTrackUUID(), + m_ADesc(), + m_syncSignalBuffer(NULL), + m_numSamplesPerFrame(0), + m_currentFrameNumber(0), + m_numBytesPerFrame(0), + m_isSyncEncoderInitialized(false) +{ + + m_ADesc.EditRate = editRate; + m_ADesc.ChannelCount = 1; + m_ADesc.QuantizationBits = bitsPerSample; + m_ADesc.AudioSamplingRate = Rational(sampleRate, 1); + m_ADesc.BlockAlign = ((bitsPerSample + 7) / 8); + m_ADesc.AvgBps = (sampleRate * m_ADesc.BlockAlign); + + memcpy(&m_audioTrackUUID.abyUUIDBytes[0], uuid, UUIDlen); + m_numSamplesPerFrame = (editRate.Denominator * sampleRate) / editRate.Numerator; + m_numBytesPerFrame = m_numSamplesPerFrame * m_ADesc.BlockAlign; + + if (bitsPerSample == 24) + { + ui32_t frameRate = editRate.Numerator/editRate.Denominator; // intentionally allowing for imprecise cast to int + m_isSyncEncoderInitialized = (SyncEncoderInit(&m_syncEncoder, sampleRate, frameRate, &m_audioTrackUUID) == SYNC_ENCODER_ERROR_NONE); + m_syncSignalBuffer = new float[m_numSamplesPerFrame]; + } + else + { + m_isSyncEncoderInitialized = false; + } +} + +ASDCP::PCM::AtmosSyncChannelGenerator::~AtmosSyncChannelGenerator() +{ + delete [] m_syncSignalBuffer; +} + +ASDCP::Result_t +ASDCP::PCM::AtmosSyncChannelGenerator::ReadFrame(FrameBuffer& OutFB) +{ + if (OutFB.Capacity() < m_numBytesPerFrame) + { + return RESULT_SMALLBUF; + } + + /** + * Update frame number and size. + */ + OutFB.FrameNumber(m_currentFrameNumber); + OutFB.Size(m_numBytesPerFrame); + + /** + * Get pointer to frame essence. + */ + byte_t* frameEssence = OutFB.Data(); + + if (m_isSyncEncoderInitialized) + { + /** + * Generate sync signal frame. + */ + int ret = EncodeSync(&m_syncEncoder, m_numSamplesPerFrame, m_syncSignalBuffer, m_currentFrameNumber); + if (ret == SYNC_ENCODER_ERROR_NONE) + { + for (unsigned int i = 0; i < m_numSamplesPerFrame; ++i) + { + /** + * Convert each encoded float sample to a signed 24 bit integer and + * copy into the essence buffer. + */ + i32_t sample = convertSampleFloatToInt24(m_syncSignalBuffer[i]); + memcpy(frameEssence, ((byte_t*)(&sample))+1, NUM_BYTES_PER_INT24); + frameEssence += NUM_BYTES_PER_INT24; + } + } + else + { + /** + * Encoding error, zero out the frame. + */ + memset(frameEssence, 0, m_numBytesPerFrame); + } + } + else + { + /** + * Sync encoder not initialize, zero out the frame. + */ + memset(frameEssence, 0, m_numBytesPerFrame); + } + ++m_currentFrameNumber; + return RESULT_OK; +} + +ASDCP::Result_t +ASDCP::PCM::AtmosSyncChannelGenerator::Reset() +{ + m_currentFrameNumber = 0; + return RESULT_OK; +} + +Result_t +ASDCP::PCM::AtmosSyncChannelGenerator::FillAudioDescriptor(AudioDescriptor& ADesc) const +{ + ADesc = m_ADesc; + return RESULT_OK; +} + diff --git a/asdcplib/src/AtmosSyncChannel_Generator.h b/asdcplib/src/AtmosSyncChannel_Generator.h new file mode 100644 index 00000000..f3a32efb --- /dev/null +++ b/asdcplib/src/AtmosSyncChannel_Generator.h @@ -0,0 +1,151 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AtmosSyncChannel_Generator.h + \version $Id: AtmosSyncChannel_Generator.h,v 1.1 2013/04/12 23:39:30 mikey Exp $ + \brief Dolby Atmos sync channel generator +*/ + +#ifndef _ATMOSSYNCCHANNEL_GENERATOR_H_ +#define _ATMOSSYNCCHANNEL_GENERATOR_H_ + +#include <AS_DCP.h> +#include "SyncEncoder.h" +#include "UUIDInformation.h" + +#define INT24_MAX 8388607.0 +#define INT24_MIN -8388608.0 + +namespace ASDCP +{ + namespace ATMOS + { + static const ui32_t SYNC_CHANNEL = 14; + } + + namespace PCM + { + + static const ui16_t NUM_BYTES_PER_INT24 = 3; + + class AtmosSyncChannelGenerator + { + SYNCENCODER m_syncEncoder; + UUIDINFORMATION m_audioTrackUUID; + AudioDescriptor m_ADesc; + float *m_syncSignalBuffer; + ui32_t m_numSamplesPerFrame; + ui32_t m_currentFrameNumber; + ui32_t m_numBytesPerFrame; + bool m_isSyncEncoderInitialized; + + ASDCP_NO_COPY_CONSTRUCT(AtmosSyncChannelGenerator); + + public: + /** + * Constructor + * + * @param bitsPerSample the number of bits in each sample of pcm data + * @param sampleRate the sampling rate + * @param editRate the edit rate of the associated picture track. + * @param atmosUUID the UUID of the associated ATMOS track file. + * + */ + AtmosSyncChannelGenerator(ui16_t bitsPerSample, ui32_t sampleRate, + const ASDCP::Rational& editRate, const byte_t* uuid); + ~AtmosSyncChannelGenerator(); + + /** + * Set the frame number when seeking + * Use override the default starting frame number for a new track or + * to set the frame number when doing random access. + * + * @param frameNumber + * + */ + void setFrameNumber(ui32_t frameNumber) { m_currentFrameNumber = frameNumber; }; + + /** + * Get the number of bytes per frame. + * + * @return Number of bytes per frame + * + */ + ui32_t getBytesPerFrame() { return m_numBytesPerFrame; } + + /** + * Generates the next frame of sync data. + * Generates the next frame of sync data and places it + * the frame buffer. Fails if the buffer is too small. + * **Automatically increments the frame number.** + * + * @param buf the buffer that the generated frame data will be written to. + * + * @return Kumu::RESULT_OK if the buffer is succesfully filled with sync + * data for the next frame. + */ + Result_t ReadFrame(FrameBuffer& buf); + + /** + * Reset the frame count. + * + * @return Kumu::RESULT_OK + */ + Result_t Reset(); + + /** + * Fill the AudioDescriptor with the relevant information. + * + * @return Kumu::RESULT_OK + */ + Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; + + /** + * Converts a sample float into + * 24-bit PCM data. + * + */ + static inline i32_t convertSampleFloatToInt24(float sample) + { + if (sample >= 0.0) + { + return (static_cast<i32_t>(sample * INT24_MAX) << 8); + } + else + { + return (static_cast<i32_t>(-sample * INT24_MIN) << 8); + } + } + }; + + } // namespace PCM +} // namespace ASDCP + +#endif // _ATMOSSYNCCHANNEL_GENERATOR_H_ + +// +// end AtmosSyncChannel_Generator.h +// diff --git a/asdcplib/src/AtmosSyncChannel_Mixer.cpp b/asdcplib/src/AtmosSyncChannel_Mixer.cpp new file mode 100644 index 00000000..80f01d63 --- /dev/null +++ b/asdcplib/src/AtmosSyncChannel_Mixer.cpp @@ -0,0 +1,368 @@ +/* +Copyright (c) 2013-2014, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AtmosSyncChannel_Mixer.cpp + \version $Id: AtmosSyncChannel_Mixer.cpp,v 1.3 2014/09/22 16:17:05 jhurst Exp $ + \brief Read WAV files(s), multiplex multiple PCM frame buffers including Atmos Sync into one +*/ + +#include <AtmosSyncChannel_Mixer.h> + +#include <algorithm> + +#include <AS_DCP.h> +#include <KM_log.h> +#include <PCMDataProviders.h> + +using namespace ASDCP; +using namespace Kumu; + +// +ASDCP::AtmosSyncChannelMixer::AtmosSyncChannelMixer(const byte_t * trackUUID) + : m_inputs(), m_outputs(), m_trackUUID(), m_ADesc(), m_ChannelCount(0), m_FramesRead(0) +{ + ::memcpy(m_trackUUID, trackUUID, UUIDlen); +} + +ASDCP::AtmosSyncChannelMixer::~AtmosSyncChannelMixer() +{ + clear(); +} + +void +ASDCP::AtmosSyncChannelMixer::clear() +{ + m_outputs.clear(); + std::for_each(m_inputs.begin(), m_inputs.end(), delete_input()); + m_inputs.clear(); +} + +// +Result_t +ASDCP::AtmosSyncChannelMixer::OpenRead(ui32_t argc, const char** argv, const Rational& PictureRate) +{ + ASDCP_TEST_NULL(argv); + PathList_t TmpFileList; + + for ( ui32_t i = 0; i < argc; ++i ) + { + ASDCP_TEST_NULL_STR(argv[i]); + TmpFileList.push_back(argv[i]); + } + + return OpenRead(TmpFileList, PictureRate); +} + +// +Result_t +ASDCP::AtmosSyncChannelMixer::OpenRead(const Kumu::PathList_t& argv, const Rational& PictureRate) +{ + Result_t result = RESULT_OK; + PathList_t::iterator fi; + Kumu::PathList_t file_list; + PCM::AudioDescriptor tmpDesc; + + if ( argv.size() == 1 && PathIsDirectory(argv.front()) ) + { + DirScanner Dir; + char name_buf[MaxFilePath]; + result = Dir.Open(argv.front().c_str()); + + if ( KM_SUCCESS(result) ) + result = Dir.GetNext(name_buf); + + while ( KM_SUCCESS(result) ) + { + if ( name_buf[0] != '.' ) // no hidden files + { + std::string tmp_path = argv.front() + "/" + name_buf; + file_list.push_back(tmp_path); + } + + result = Dir.GetNext(name_buf); + } + + if ( result == RESULT_ENDOFFILE ) + { + result = RESULT_OK; + file_list.sort(); + } + } + else + { + file_list = argv; + } + + for ( fi = file_list.begin(); KM_SUCCESS(result) && fi != file_list.end(); ++fi ) + { + result = OpenRead(*fi, PictureRate); + } + + if ( ASDCP_SUCCESS(result) && (m_ChannelCount < ATMOS::SYNC_CHANNEL)) + { + // atmos sync channel has not been added + result = MixInSilenceChannels(); + if ( ASDCP_SUCCESS(result) ) + result = MixInAtmosSyncChannel(); + } + + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.ChannelCount = m_ChannelCount; + m_ADesc.AvgBps = (ui32_t)(ceil(m_ADesc.AudioSamplingRate.Quotient()) * m_ADesc.BlockAlign); + } + else + { + clear(); + } + + return result; +} + +// +Result_t +ASDCP::AtmosSyncChannelMixer::OpenRead(const std::string& file, const Rational& PictureRate) +{ + Result_t result = RESULT_OK; + PCM::AudioDescriptor tmpDesc; + ui32_t numChannels = 0; + mem_ptr<WAVDataProvider> I = new WAVDataProvider; + result = I->OpenRead(file.c_str(), PictureRate); + + if ( ASDCP_SUCCESS(result)) + { + result = I->FillAudioDescriptor(tmpDesc); + } + + if ( ASDCP_SUCCESS(result) ) + { + + if ( m_ChannelCount == 0 ) + { + m_ADesc = tmpDesc; + } + else + { + + if ( tmpDesc.AudioSamplingRate != m_ADesc.AudioSamplingRate ) + { + DefaultLogSink().Error("AudioSamplingRate mismatch in PCM parser list."); + return RESULT_FORMAT; + } + + if ( tmpDesc.QuantizationBits != m_ADesc.QuantizationBits ) + { + DefaultLogSink().Error("QuantizationBits mismatch in PCM parser list."); + return RESULT_FORMAT; + } + + if ( tmpDesc.ContainerDuration < m_ADesc.ContainerDuration ) + m_ADesc.ContainerDuration = tmpDesc.ContainerDuration; + + m_ADesc.BlockAlign += tmpDesc.BlockAlign; + } + } + + + if ( ASDCP_SUCCESS(result) ) + { + numChannels = tmpDesc.ChannelCount; // default to all channels + if ((m_ChannelCount < ATMOS::SYNC_CHANNEL) && (m_ChannelCount + numChannels) > (ATMOS::SYNC_CHANNEL - 1)) + { + // need to insert an atmos channel between the channels of this file. + numChannels = ATMOS::SYNC_CHANNEL - m_ChannelCount - 1; + m_outputs.push_back(std::make_pair(numChannels, I.get())); + m_ChannelCount += numChannels; + MixInAtmosSyncChannel(); + numChannels = tmpDesc.ChannelCount - numChannels; + } + m_outputs.push_back(std::make_pair(numChannels, I.get())); + m_inputs.push_back(I); + I.release(); + m_ChannelCount += numChannels; + } + return result; +} + +Result_t +ASDCP::AtmosSyncChannelMixer::MixInSilenceChannels() +{ + Result_t result = RESULT_OK; + PCM::AudioDescriptor tmpDesc; + ui32_t numSilenceChannels = ATMOS::SYNC_CHANNEL - m_ChannelCount - 1; + if (numSilenceChannels > 0) + { + mem_ptr<SilenceDataProvider> I = new SilenceDataProvider(numSilenceChannels, + m_ADesc.QuantizationBits, + m_ADesc.AudioSamplingRate.Numerator, + m_ADesc.EditRate); + result = I->FillAudioDescriptor(tmpDesc); + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.BlockAlign += tmpDesc.BlockAlign; + m_ChannelCount += tmpDesc.ChannelCount; + m_outputs.push_back(std::make_pair(numSilenceChannels, I.get())); + m_inputs.push_back(I); + I.release(); + assert(m_ChannelCount == (ATMOS::SYNC_CHANNEL - 1)); + } + } + return result; +} + +// +Result_t +ASDCP::AtmosSyncChannelMixer::MixInAtmosSyncChannel() +{ + Result_t result = RESULT_OK; + PCM::AudioDescriptor tmpDesc; + mem_ptr<AtmosSyncDataProvider> I = new AtmosSyncDataProvider(m_ADesc.QuantizationBits, + m_ADesc.AudioSamplingRate.Numerator, + m_ADesc.EditRate, m_trackUUID); + result = I->FillAudioDescriptor(tmpDesc); + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.BlockAlign += tmpDesc.BlockAlign; + m_ChannelCount += tmpDesc.ChannelCount; + m_outputs.push_back(std::make_pair(tmpDesc.ChannelCount, I.get())); + m_inputs.push_back(I); + I.release(); + assert(m_ChannelCount == ATMOS::SYNC_CHANNEL); + } + return result; +} + +// +Result_t +ASDCP::AtmosSyncChannelMixer::AppendSilenceChannels(const ui32_t& channel_count) +{ + if ( m_ADesc.QuantizationBits == 0 ) + { + DefaultLogSink().Error("Mixer object contains no channels, call OpenRead() first.\n"); + return RESULT_PARAM; + } + + Result_t result = RESULT_OK; + PCM::AudioDescriptor tmpDesc; + + if ( channel_count > 0 ) + { + Kumu::mem_ptr<SilenceDataProvider> I = + new SilenceDataProvider(channel_count, + m_ADesc.QuantizationBits, + m_ADesc.AudioSamplingRate.Numerator, + m_ADesc.EditRate); + + result = I->FillAudioDescriptor(tmpDesc); + + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.BlockAlign += tmpDesc.BlockAlign; + m_ChannelCount += tmpDesc.ChannelCount; + m_ADesc.ChannelCount = m_ChannelCount; + m_ADesc.AvgBps = (ui32_t)(ceil(m_ADesc.AudioSamplingRate.Quotient()) * m_ADesc.BlockAlign); + + m_outputs.push_back(std::make_pair(channel_count, I.get())); + m_inputs.push_back(I); + I.release(); + } + } + + return result; +} + +// +Result_t +ASDCP::AtmosSyncChannelMixer::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const +{ + ADesc = m_ADesc; + return RESULT_OK; +} + +// +Result_t +ASDCP::AtmosSyncChannelMixer::Reset() +{ + Result_t result = RESULT_OK; + SourceList::iterator it; + SourceList::iterator lastInput = m_inputs.end(); + + for ( it = m_inputs.begin(); it != lastInput && ASDCP_SUCCESS(result) ; ++it ) + result = (*it)->Reset(); + + return result; +} + + +//2 +Result_t +ASDCP::AtmosSyncChannelMixer::ReadFrame(PCM::FrameBuffer& OutFB) +{ + + + Result_t result = RESULT_OK; + SourceList::iterator iter; + SourceList::iterator lastInput = m_inputs.end(); + ui32_t bufSize = PCM::CalcFrameBufferSize(m_ADesc); + assert( bufSize <= OutFB.Capacity()); + + for ( iter = m_inputs.begin(); iter != lastInput && ASDCP_SUCCESS(result) ; ++iter ) + result = (*iter)->ReadFrame(); + + if ( ASDCP_SUCCESS(result) ) + { + OutFB.Size(bufSize); + byte_t* Out_p = OutFB.Data(); + byte_t* End_p = Out_p + OutFB.Size(); + ui32_t bytesWritten = 0; + OutputList::iterator iter; + OutputList::iterator lastOutput = m_outputs.end(); + + while ( Out_p < End_p && ASDCP_SUCCESS(result) ) + { + iter = m_outputs.begin(); + while ( iter != lastOutput && ASDCP_SUCCESS(result) ) + { + result = ((*iter).second)->PutSample((*iter).first, Out_p, &bytesWritten); + Out_p += bytesWritten; + ++iter; + } + } + + if ( ASDCP_SUCCESS(result) ) + { + assert(Out_p == End_p); + OutFB.FrameNumber(m_FramesRead++); + } + } + + return result; +} + + +// +// end AtmosSyncChannel_Mixer.cpp +// diff --git a/asdcplib/src/AtmosSyncChannel_Mixer.h b/asdcplib/src/AtmosSyncChannel_Mixer.h new file mode 100644 index 00000000..0d93add1 --- /dev/null +++ b/asdcplib/src/AtmosSyncChannel_Mixer.h @@ -0,0 +1,94 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AtmosSyncChannel_Mixer.h + \version $Id: AtmosSyncChannel_Mixer.h,v 1.2 2014/04/14 18:22:27 jhurst Exp $ + \brief Read WAV files(s), multiplex multiple PCM frame buffers including Atmos Sync into one +*/ + +#ifndef _ATMOSSYNCCHANNEL_MIXER_H_ +#define _ATMOSSYNCCHANNEL_MIXER_H_ + +#include <AS_DCP.h> +#include <KM_error.h> +#include <PCMDataProviders.h> +#include <vector> + +namespace ASDCP +{ + + // + class AtmosSyncChannelMixer + { + typedef std::pair<ui32_t, PCMDataProviderInterface*> InputBus; + typedef std::vector<InputBus> OutputList; + typedef std::vector<PCMDataProviderInterface*> SourceList; + + SourceList m_inputs; + OutputList m_outputs; + byte_t m_trackUUID[ASDCP::UUIDlen]; + + Result_t OpenRead(const std::string& file, const Rational& PictureRate); + Result_t MixInSilenceChannels(); + Result_t MixInAtmosSyncChannel(); + void clear(); + + // functor for deleting + struct delete_input + { + void operator()(PCMDataProviderInterface* i) + { + delete i; + } + }; + + ASDCP_NO_COPY_CONSTRUCT(AtmosSyncChannelMixer); + + protected: + PCM::AudioDescriptor m_ADesc; + ui32_t m_ChannelCount; + ui32_t m_FramesRead; + + public: + AtmosSyncChannelMixer(const byte_t * trackUUID); + virtual ~AtmosSyncChannelMixer(); + + const ui32_t& ChannelCount() const { return m_ChannelCount; } + + Result_t OpenRead(ui32_t argc, const char** argv, const Rational& PictureRate); + Result_t OpenRead(const Kumu::PathList_t& argv, const Rational& PictureRate); + Result_t AppendSilenceChannels(const ui32_t& channel_count); + Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; + Result_t Reset(); + Result_t ReadFrame(PCM::FrameBuffer& OutFB); + }; +} // namespace ASDCP + +#endif // _ATMOSSYNCCHANNEL_MIXER_H_ + +// +// end AtmosSyncChannel_Mixer.h +// diff --git a/asdcplib/src/CRC16.c b/asdcplib/src/CRC16.c new file mode 100644 index 00000000..5bd289c1 --- /dev/null +++ b/asdcplib/src/CRC16.c @@ -0,0 +1,86 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file CRC16.c + \version $Id: CRC16.c,v 1.1 2013/04/12 23:39:30 mikey Exp $ + \brief Implementation of a CRC function +*/ + +#include "CRC16.h" + +static const unsigned short g_aushCRC16tab[256]= { + 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, + 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, + 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, + 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, + 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, + 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, + 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, + 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, + 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, + 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, + 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, + 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, + 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, + 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, + 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, + 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, + 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, + 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, + 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, + 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, + 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, + 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, + 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, + 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, + 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, + 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, + 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, + 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, + 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, + 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, + 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, + 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 +}; + +unsigned short CRC16(const void *pData, int ilength) +{ + int n; + unsigned short ushCRC; + unsigned char *puchData; + + + puchData = (unsigned char*)pData; + + ushCRC = 0; + for(n = 0; n < ilength; n ++){ + + ushCRC = (ushCRC << 8) ^ g_aushCRC16tab[((ushCRC>>8) ^ *puchData) & 0x00FF]; + puchData ++; + } + + return ushCRC; +} diff --git a/asdcplib/src/CRC16.h b/asdcplib/src/CRC16.h new file mode 100644 index 00000000..b233d010 --- /dev/null +++ b/asdcplib/src/CRC16.h @@ -0,0 +1,45 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file CRC16.h + \version $Id: CRC16.h,v 1.1 2013/04/12 23:39:30 mikey Exp $ + \brief Declaration of a CRC function +*/ + +#ifndef _CRC_16_H_ +#define _CRC_16_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned short CRC16(const void *pData, int ilength); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/asdcplib/src/DCData_ByteStream_Parser.cpp b/asdcplib/src/DCData_ByteStream_Parser.cpp new file mode 100644 index 00000000..dd2fe38b --- /dev/null +++ b/asdcplib/src/DCData_ByteStream_Parser.cpp @@ -0,0 +1,120 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AtmosSyncChannel_Mixer.h + \version $Id: DCData_ByteStream_Parser.cpp,v 1.2 2014/01/02 23:29:22 jhurst Exp $ + \brief AS-DCP library, Digital Cinema Data bytestream essence reader +*/ + +#include "AS_DCP.h" +#include "KM_fileio.h" +#include "KM_log.h" +using Kumu::DefaultLogSink; + +//------------------------------------------------------------------------------------------ + +class ASDCP::DCData::BytestreamParser::h__BytestreamParser +{ + ASDCP_NO_COPY_CONSTRUCT(h__BytestreamParser); + +public: + DCDataDescriptor m_DDesc; + Kumu::FileReader m_File; + + h__BytestreamParser() + { + memset(&m_DDesc, 0, sizeof(m_DDesc)); + m_DDesc.EditRate = Rational(24,1); + } + + ~h__BytestreamParser() {} + + Result_t OpenReadFrame(const std::string& filename, FrameBuffer& FB) + { + m_File.Close(); + Result_t result = m_File.OpenRead(filename); + + if ( ASDCP_SUCCESS(result) ) + { + Kumu::fsize_t file_size = m_File.Size(); + + if ( FB.Capacity() < file_size ) + { + DefaultLogSink().Error("FrameBuf.Capacity: %u frame length: %u\n", FB.Capacity(), (ui32_t)file_size); + return RESULT_SMALLBUF; + } + } + + ui32_t read_count; + + if ( ASDCP_SUCCESS(result) ) + result = m_File.Read(FB.Data(), FB.Capacity(), &read_count); + + if ( ASDCP_SUCCESS(result) ) + FB.Size(read_count); + + return result; + } +}; + + +//------------------------------------------------------------------------------------------ + +ASDCP::DCData::BytestreamParser::BytestreamParser() +{ +} + +ASDCP::DCData::BytestreamParser::~BytestreamParser() +{ +} + +// Opens the stream for reading, parses enough data to provide a complete +// set of stream metadata for the MXFWriter below. +ASDCP::Result_t +ASDCP::DCData::BytestreamParser::OpenReadFrame(const std::string& filename, FrameBuffer& FB) const +{ + const_cast<ASDCP::DCData::BytestreamParser*>(this)->m_Parser = new h__BytestreamParser; + return m_Parser->OpenReadFrame(filename, FB); +} + +// +ASDCP::Result_t +ASDCP::DCData::BytestreamParser::FillDCDataDescriptor(DCDataDescriptor& DDesc) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + DDesc = m_Parser->m_DDesc; + return RESULT_OK; +} + + +// +// end DCData_Bytestream_Parser.cpp +// + + + diff --git a/asdcplib/src/DCData_Sequence_Parser.cpp b/asdcplib/src/DCData_Sequence_Parser.cpp new file mode 100644 index 00000000..f30671ee --- /dev/null +++ b/asdcplib/src/DCData_Sequence_Parser.cpp @@ -0,0 +1,292 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file AtmosSyncChannel_Mixer.h + \version $Id: DCData_Sequence_Parser.cpp,v 1.2 2014/01/02 23:29:22 jhurst Exp $ + \brief AS-DCP library, DCinema data seqence reader implementation +*/ + +#include "AS_DCP.h" + +#include <algorithm> +#include <list> +#include <string> + +#include "KM_fileio.h" +#include "KM_log.h" + +using ASDCP::Result_t; + +//------------------------------------------------------------------------------------------ +namespace ASDCP +{ +namespace DCData +{ +class FileList; +} // namespace DCData +} // namespace ASDCP + + +class ASDCP::DCData::FileList : public std::list<std::string> +{ + std::string m_DirName; + + public: + FileList() {} + ~FileList() {} + + const FileList& operator=(const std::list<std::string>& pathlist) { + std::list<std::string>::const_iterator i; + for ( i = pathlist.begin(); i != pathlist.end(); i++ ) + push_back(*i); + return *this; + } + + // + Result_t InitFromDirectory(const std::string& path) + { + char next_file[Kumu::MaxFilePath]; + Kumu::DirScanner Scanner; + + Result_t result = Scanner.Open(path); + + if ( ASDCP_SUCCESS(result) ) + { + m_DirName = path; + + while ( ASDCP_SUCCESS(Scanner.GetNext(next_file)) ) + { + if ( next_file[0] == '.' ) // no hidden files or internal links + continue; + + std::string Str(m_DirName); + Str += "/"; + Str += next_file; + + if ( ! Kumu::PathIsDirectory(Str) ) + push_back(Str); + } + + sort(); + } + + return result; + } +}; + +//------------------------------------------------------------------------------------------ + +class ASDCP::DCData::SequenceParser::h__SequenceParser +{ + ui32_t m_FramesRead; + Rational m_PictureRate; + FileList m_FileList; + FileList::iterator m_CurrentFile; + BytestreamParser m_Parser; + + Result_t OpenRead(); + + ASDCP_NO_COPY_CONSTRUCT(h__SequenceParser); + + public: + DCDataDescriptor m_DDesc; + + h__SequenceParser() : m_FramesRead(0) + { + memset(&m_DDesc, 0, sizeof(m_DDesc)); + m_DDesc.EditRate = Rational(24,1); + } + + ~h__SequenceParser() + { + Close(); + } + + Result_t OpenRead(const std::string& filename); + Result_t OpenRead(const std::list<std::string>& file_list); + void Close() {} + + Result_t Reset() + { + m_FramesRead = 0; + m_CurrentFile = m_FileList.begin(); + return RESULT_OK; + } + + Result_t ReadFrame(FrameBuffer&); +}; + + +// +ASDCP::Result_t +ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead() +{ + if ( m_FileList.empty() ) + return RESULT_ENDOFFILE; + + m_CurrentFile = m_FileList.begin(); + BytestreamParser Parser; + FrameBuffer TmpBuffer; + + Kumu::fsize_t file_size = Kumu::FileSize((*m_CurrentFile).c_str()); + + if ( file_size == 0 ) + return RESULT_NOT_FOUND; + + assert(file_size <= 0xFFFFFFFFL); + Result_t result = TmpBuffer.Capacity((ui32_t) file_size); + + if ( ASDCP_SUCCESS(result) ) + result = Parser.OpenReadFrame((*m_CurrentFile).c_str(), TmpBuffer); + + if ( ASDCP_SUCCESS(result) ) + result = Parser.FillDCDataDescriptor(m_DDesc); + + // how big is it? + if ( ASDCP_SUCCESS(result) ) + m_DDesc.ContainerDuration = m_FileList.size(); + + return result; +} + +// +ASDCP::Result_t +ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename) +{ + Result_t result = m_FileList.InitFromDirectory(filename); + + if ( ASDCP_SUCCESS(result) ) + result = OpenRead(); + + return result; +} + + +// +ASDCP::Result_t +ASDCP::DCData::SequenceParser::h__SequenceParser::OpenRead(const std::list<std::string>& file_list) +{ + m_FileList = file_list; + return OpenRead(); +} + +// +ASDCP::Result_t +ASDCP::DCData::SequenceParser::h__SequenceParser::ReadFrame(FrameBuffer& FB) +{ + if ( m_CurrentFile == m_FileList.end() ) + return RESULT_ENDOFFILE; + + // open the file + Result_t result = m_Parser.OpenReadFrame((*m_CurrentFile).c_str(), FB); + + if ( ASDCP_SUCCESS(result) ) + { + FB.FrameNumber(m_FramesRead++); + m_CurrentFile++; + } + + return result; +} + + +//------------------------------------------------------------------------------------------ + +ASDCP::DCData::SequenceParser::SequenceParser() +{ +} + +ASDCP::DCData::SequenceParser::~SequenceParser() +{ +} + +// Opens the stream for reading, parses enough data to provide a complete +// set of stream metadata for the MXFWriter below. +ASDCP::Result_t +ASDCP::DCData::SequenceParser::OpenRead(const std::string& filename) const +{ + const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser = new h__SequenceParser; + + Result_t result = m_Parser->OpenRead(filename); + + if ( ASDCP_FAILURE(result) ) + const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser.release(); + + return result; +} + +// +Result_t +ASDCP::DCData::SequenceParser::OpenRead(const std::list<std::string>& file_list) const +{ + const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser = new h__SequenceParser; + + Result_t result = m_Parser->OpenRead(file_list); + + if ( ASDCP_FAILURE(result) ) + const_cast<ASDCP::DCData::SequenceParser*>(this)->m_Parser.release(); + + return result; +} + + +// Rewinds the stream to the beginning. +ASDCP::Result_t +ASDCP::DCData::SequenceParser::Reset() const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + return m_Parser->Reset(); +} + +// Places a frame of data in the frame buffer. Fails if the buffer is too small +// or the stream is empty. +ASDCP::Result_t +ASDCP::DCData::SequenceParser::ReadFrame(FrameBuffer& FB) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + return m_Parser->ReadFrame(FB); +} + +// +ASDCP::Result_t +ASDCP::DCData::SequenceParser::FillDCDataDescriptor(DCDataDescriptor& DDesc) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + DDesc = m_Parser->m_DDesc; + return RESULT_OK; +} + + +// +// end DCData_Sequence_Parser.cpp +// + diff --git a/asdcplib/src/Dict.cpp b/asdcplib/src/Dict.cpp index c046aa7c..7a64529f 100755 --- a/asdcplib/src/Dict.cpp +++ b/asdcplib/src/Dict.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file Dict.cpp - \version $Id: Dict.cpp,v 1.15 2012/02/08 02:59:21 jhurst Exp $ + \version $Id: Dict.cpp,v 1.16 2013/06/07 00:41:00 jhurst Exp $ \brief MXF dictionary */ @@ -150,22 +150,22 @@ ASDCP::Dictionary::Init() m_md_lookup.clear(); memset(m_MDD_Table, 0, sizeof(m_MDD_Table)); - for ( ui32_t x = 0; x < (ui32_t)ASDCP::MDD_Max; x++ ) + for ( ui32_t x = 0; x < (ui32_t)ASDCP::MDD_Max; ++x ) { if ( x == MDD_PartitionMetadata_IndexSID_DEPRECATED // 30 || x == MDD_PartitionMetadata_BodySID_DEPRECATED // 32 + || x == MDD_PartitionMetadata_OperationalPattern_DEPRECATED // 33 || x == MDD_PartitionMetadata_EssenceContainers_DEPRECATED // 34 || x == MDD_IndexTableSegmentBase_IndexSID_DEPRECATED // 56 || x == MDD_IndexTableSegmentBase_BodySID_DEPRECATED // 57 || x == MDD_PartitionArray_RandomIndexMetadata_BodySID_DEPRECATED // 73 + || x == MDD_Preface_OperationalPattern_DEPRECATED // 84 || x == MDD_Preface_EssenceContainers_DEPRECATED // 85 || x == MDD_EssenceContainerData_IndexSID_DEPRECATED // 103 || x == MDD_EssenceContainerData_BodySID_DEPRECATED // 104 + || x == MDD_TimedTextResourceSubDescriptor_EssenceStreamID_DEPRECATED // 264 || x == MDD_DMSegment_DataDefinition_DEPRECATED // 266 || x == MDD_DMSegment_Duration_DEPRECATED // 267 - || x == MDD_PartitionMetadata_OperationalPattern_DEPRECATED // 33 - || x == MDD_Preface_OperationalPattern_DEPRECATED // 84 - || x == MDD_TimedTextResourceSubDescriptor_EssenceStreamID_DEPRECATED // 264 ) continue; diff --git a/asdcplib/src/Index.cpp b/asdcplib/src/Index.cpp index 702b185c..3f9a5cdf 100755 --- a/asdcplib/src/Index.cpp +++ b/asdcplib/src/Index.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file Index.cpp - \version $Id: Index.cpp,v 1.21 2012/02/03 19:49:56 jhurst Exp $ + \version $Id: Index.cpp,v 1.25 2015/10/07 16:41:23 jhurst Exp $ \brief MXF index segment objects */ @@ -35,7 +35,7 @@ const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH; // ASDCP::MXF::IndexTableSegment::IndexTableSegment(const Dictionary*& d) : - InterchangeObject(d), m_Dict(d), + InterchangeObject(d), m_Dict(d), RtFileOffset(0), RtEntryOffset(0), IndexStartPosition(0), IndexDuration(0), EditUnitByteCount(0), IndexSID(129), BodySID(1), SliceCount(0), PosTableCount(0) { @@ -131,12 +131,12 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream) fprintf(stream, " EditUnitByteCount = %u\n", EditUnitByteCount); fprintf(stream, " IndexSID = %u\n", IndexSID); fprintf(stream, " BodySID = %u\n", BodySID); - fprintf(stream, " SliceCount = %hu\n", SliceCount); - fprintf(stream, " PosTableCount = %hu\n", PosTableCount); + fprintf(stream, " SliceCount = %hhu\n", SliceCount); + fprintf(stream, " PosTableCount = %hhu\n", PosTableCount); fprintf(stream, " DeltaEntryArray:\n"); DeltaEntryArray.Dump(stream); - if ( IndexEntryArray.size() < 100 ) + if ( IndexEntryArray.size() < 1000 ) { fprintf(stream, " IndexEntryArray:\n"); IndexEntryArray.Dump(stream); @@ -154,7 +154,7 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream) const char* ASDCP::MXF::IndexTableSegment::DeltaEntry::EncodeString(char* str_buf, ui32_t buf_len) const { - snprintf(str_buf, buf_len, "%3d %-3hu %-3u", PosTableIndex, Slice, ElementData); + snprintf(str_buf, buf_len, "%3d %-3hhu %-3u", PosTableIndex, Slice, ElementData); return str_buf; } @@ -207,7 +207,7 @@ ASDCP::MXF::IndexTableSegment::IndexEntry::EncodeString(char* str_buf, ui32_t bu txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I'; txt_flags[5] = 0; - snprintf(str_buf, buf_len, "%3i %-3hu %s %s", + snprintf(str_buf, buf_len, "%3i %-3hhu %s %s", TemporalOffset, KeyFrameOffset, txt_flags, i64sz(StreamOffset, intbuf)); diff --git a/asdcplib/src/JP2K.cpp b/asdcplib/src/JP2K.cpp index 4cc0e50a..92a188fb 100755 --- a/asdcplib/src/JP2K.cpp +++ b/asdcplib/src/JP2K.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2009, John Hurst +Copyright (c) 2005-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file JP2K.cpp - \version $Id: JP2K.cpp,v 1.8 2010/06/17 03:33:17 jhurst Exp $ + \version $Id: JP2K.cpp,v 1.11 2015/10/07 16:41:23 jhurst Exp $ \brief JPEG 2000 parser implementation This is not a complete implementation of all things JP2K. There is just enough here to @@ -102,7 +102,7 @@ ASDCP::JP2K::GetNextMarker(const byte_t** buf, JP2K::Marker& Marker) // void -ASDCP::JP2K::Accessor::SIZ::ReadComponent(ui32_t index, ASDCP::JP2K::ImageComponent_t& IC) +ASDCP::JP2K::Accessor::SIZ::ReadComponent(const ui32_t index, ASDCP::JP2K::ImageComponent_t& IC) const { assert ( index < Csize() ); const byte_t* p = m_MarkerData + 36 + (index * 3); @@ -113,7 +113,7 @@ ASDCP::JP2K::Accessor::SIZ::ReadComponent(ui32_t index, ASDCP::JP2K::ImageCompon // void -ASDCP::JP2K::Accessor::SIZ::Dump(FILE* stream) +ASDCP::JP2K::Accessor::SIZ::Dump(FILE* stream) const { if ( stream == 0 ) stream = stderr; @@ -146,19 +146,79 @@ ASDCP::JP2K::Accessor::SIZ::Dump(FILE* stream) // void -ASDCP::JP2K::Accessor::COM::Dump(FILE* stream) +ASDCP::JP2K::Accessor::COD::Dump(FILE* stream) const +{ + if ( stream == 0 ) + stream = stderr; + + fprintf(stream, "COD: \n"); + const char* prog_order_str = "RESERVED"; + const char* transformations_str = prog_order_str; + + switch ( ProgOrder() ) + { + case 0: prog_order_str = "LRCP"; break; + case 1: prog_order_str = "RLCP"; break; + case 2: prog_order_str = "RPCL"; break; + case 3: prog_order_str = "PCRL"; break; + case 4: prog_order_str = "CPRL"; break; + } + + switch ( Transformation() ) + { + case 0: transformations_str = "9/7"; break; + case 1: transformations_str = "5/3"; break; + } + + fprintf(stream, " ProgOrder: %s\n", prog_order_str); + fprintf(stream, " Layers: %hu\n", Layers()); + fprintf(stream, " DecompLevels: %hhu\n", DecompLevels()); + fprintf(stream, " CodeBlockWidth: %d\n", 1 << CodeBlockWidth()); + fprintf(stream, "CodeBlockHeight: %d\n", 1 << CodeBlockHeight()); + fprintf(stream, " CodeBlockStyle: %d\n", CodeBlockStyle()); + fprintf(stream, " Transformation: %s\n", transformations_str); +} + +// +const char* +ASDCP::JP2K::Accessor::GetQuantizationTypeString(const Accessor::QuantizationType_t t) +{ + switch ( t ) + { + case QT_NONE: return "none"; + case QT_DERIVED: return "scalar derived"; + case QT_EXP: return "scalar expounded"; + } + + return "**UNKNOWN**"; +} + +// +void +ASDCP::JP2K::Accessor::QCD::Dump(FILE* stream) const +{ + if ( stream == 0 ) + stream = stderr; + + fprintf(stream, "QCD: \n"); + fprintf(stream, "QuantizationType: %s\n", GetQuantizationTypeString(QuantizationType())); + fprintf(stream, " GuardBits: %d\n", GuardBits()); + fprintf(stream, " SPqcd: %d\n", GuardBits()); + Kumu::hexdump(m_MarkerData, m_DataSize, stream); +} + +// +void +ASDCP::JP2K::Accessor::COM::Dump(FILE* stream) const { if ( stream == 0 ) stream = stderr; if ( IsText() ) { - char* t_str = (char*)malloc(CommentSize() + 1); - assert( t_str != 0 ); - ui32_t cs = CommentSize(); - memcpy(t_str, CommentData(), cs); - t_str[cs] = 0; - fprintf(stream, "COM:%s\n", t_str); + std::string tmp_str; + tmp_str.assign((char*)CommentData(), CommentSize()); + fprintf(stream, "COM:%s\n", tmp_str.c_str()); } else { diff --git a/asdcplib/src/JP2K.h b/asdcplib/src/JP2K.h index d30dbadb..94c5d615 100755 --- a/asdcplib/src/JP2K.h +++ b/asdcplib/src/JP2K.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2009, John Hurst +Copyright (c) 2005-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file JP2K.h - \version $Id: JP2K.h,v 1.4 2009/04/09 19:24:14 msheby Exp $ + \version $Id: JP2K.h,v 1.6 2014/06/02 22:07:51 jhurst Exp $ \brief JPEG 2000 constants and data structures This is not a complete enumeration of all things JP2K. There is just enough here to @@ -113,18 +113,84 @@ namespace JP2K ~SIZ() {} - inline ui16_t Rsize() { return KM_i16_BE(*(ui16_t*)m_MarkerData); } - inline ui32_t Xsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 2)); } - inline ui32_t Ysize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 6)); } - inline ui32_t XOsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 10)); } - inline ui32_t YOsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 14)); } - inline ui32_t XTsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 18)); } - inline ui32_t YTsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 22)); } - inline ui32_t XTOsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 26)); } - inline ui32_t YTOsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 30)); } - inline ui16_t Csize() { return KM_i16_BE(*(ui16_t*)(m_MarkerData + 34)); } - void ReadComponent(ui32_t index, ImageComponent_t& IC); - void Dump(FILE* stream = 0); + inline ui16_t Rsize() const { return KM_i16_BE(*(ui16_t*)m_MarkerData); } + inline ui32_t Xsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 2)); } + inline ui32_t Ysize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 6)); } + inline ui32_t XOsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 10)); } + inline ui32_t YOsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 14)); } + inline ui32_t XTsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 18)); } + inline ui32_t YTsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 22)); } + inline ui32_t XTOsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 26)); } + inline ui32_t YTOsize() const { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 30)); } + inline ui16_t Csize() const { return KM_i16_BE(*(ui16_t*)(m_MarkerData + 34)); } + void ReadComponent(const ui32_t index, ImageComponent_t& IC) const; + void Dump(FILE* stream = 0) const; + }; + + const int SGcodOFST = 1; + const int SPcodOFST = 5; + + // coding style + class COD + { + const byte_t* m_MarkerData; + + KM_NO_COPY_CONSTRUCT(COD); + COD(); + + public: + COD(const Marker& M) + { + assert(M.m_Type == MRK_COD); + m_MarkerData = M.m_Data; + } + + ~COD() {} + + inline ui8_t ProgOrder() const { return *(m_MarkerData + SGcodOFST ); } + inline ui16_t Layers() const { return KM_i16_BE(*(ui16_t*)(m_MarkerData + SGcodOFST + 1));} + inline ui8_t DecompLevels() const { return *(m_MarkerData + SPcodOFST); } + inline ui8_t CodeBlockWidth() const { return *(m_MarkerData + SPcodOFST + 1) + 2; } + inline ui8_t CodeBlockHeight() const { return *(m_MarkerData + SPcodOFST + 2) + 2; } + inline ui8_t CodeBlockStyle() const { return *(m_MarkerData + SPcodOFST + 3); } + inline ui8_t Transformation() const { return *(m_MarkerData + SPcodOFST + 4); } + + void Dump(FILE* stream = 0) const; + }; + + const int SqcdOFST = 1; + const int SPqcdOFST = 2; + + enum QuantizationType_t + { + QT_NONE, + QT_DERIVED, + QT_EXP + }; + + const char* GetQuantizationTypeString(const QuantizationType_t m); + + // Quantization default + class QCD + { + const byte_t* m_MarkerData; + ui32_t m_DataSize; + + KM_NO_COPY_CONSTRUCT(QCD); + QCD(); + + public: + QCD(const Marker& M) + { + assert(M.m_Type == MRK_QCD); + m_MarkerData = M.m_Data + 2; + m_DataSize = M.m_DataSize - 2; + } + + ~QCD() {} + inline QuantizationType_t QuantizationType() const { return static_cast<QuantizationType_t>(*(m_MarkerData + SqcdOFST) & 0x03); } + inline ui8_t GuardBits() const { return (*(m_MarkerData + SqcdOFST) & 0xe0) >> 5; } + void Dump(FILE* stream = 0) const; }; // a comment @@ -148,10 +214,10 @@ namespace JP2K ~COM() {} - inline bool IsText() { return m_IsText; } - inline const byte_t* CommentData() { return m_MarkerData; } - inline ui32_t CommentSize() { return m_DataSize; } - void Dump(FILE* stream = 0); + inline bool IsText() const { return m_IsText; } + inline const byte_t* CommentData() const { return m_MarkerData; } + inline ui32_t CommentSize() const { return m_DataSize; } + void Dump(FILE* stream = 0) const; }; } // namespace Accessor } // namespace JP2K diff --git a/asdcplib/src/JP2K_Codestream_Parser.cpp b/asdcplib/src/JP2K_Codestream_Parser.cpp index 5ab7a322..0513d2f6 100755 --- a/asdcplib/src/JP2K_Codestream_Parser.cpp +++ b/asdcplib/src/JP2K_Codestream_Parser.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2009, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file Codestream_Parser.cpp - \version $Id: JP2K_Codestream_Parser.cpp,v 1.7 2009/04/09 19:16:49 msheby Exp $ + \version $Id: JP2K_Codestream_Parser.cpp,v 1.9 2015/10/09 23:41:11 jhurst Exp $ \brief AS-DCP library, JPEG 2000 codestream essence reader implementation */ @@ -55,9 +55,8 @@ public: ~h__CodestreamParser() {} - Result_t OpenReadFrame(const char* filename, FrameBuffer& FB) + Result_t OpenReadFrame(const std::string& filename, FrameBuffer& FB) { - ASDCP_TEST_NULL_STR(filename); m_File.Close(); Result_t result = m_File.OpenRead(filename); @@ -91,26 +90,6 @@ public: return result; } - - Result_t OpenReadFrame(const unsigned char * data, unsigned int size, FrameBuffer& FB) - { - if ( FB.Capacity() < size ) - { - DefaultLogSink().Error("FrameBuf.Capacity: %u frame length: %u\n", FB.Capacity(), (ui32_t) size); - return RESULT_SMALLBUF; - } - - memcpy (FB.Data(), data, size); - FB.Size(size); - - byte_t start_of_data = 0; // out param - const Result_t result = ParseMetadataIntoDesc(FB, m_PDesc, &start_of_data); - - if ( ASDCP_SUCCESS(result) ) - FB.PlaintextOffset(start_of_data); - - return result; - } }; ASDCP::Result_t @@ -184,9 +163,9 @@ ASDCP::JP2K::ParseMetadataIntoDesc(const FrameBuffer& FB, PictureDescriptor& PDe case MRK_QCD: memset(&PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t)); - if ( NextMarker.m_DataSize < 16 ) + if ( NextMarker.m_DataSize < 3 ) // ( Sqcd = 8 bits, SPqcd = 8 bits ) == 2 bytes, error if not greater { - DefaultLogSink().Error("No quantization signaled\n"); + DefaultLogSink().Error("No quantization signaled. QCD size=%s.\n", NextMarker.m_DataSize); return RESULT_RAW_FORMAT; } @@ -199,26 +178,6 @@ ASDCP::JP2K::ParseMetadataIntoDesc(const FrameBuffer& FB, PictureDescriptor& PDe memcpy(&PDesc.QuantizationDefault, NextMarker.m_Data, NextMarker.m_DataSize); PDesc.QuantizationDefault.SPqcdLength = NextMarker.m_DataSize - 1; break; - - case MRK_NIL: - case MRK_SOC: - case MRK_SOT: - case MRK_EOC: - case MRK_COC: - case MRK_RGN: - case MRK_QCC: - case MRK_POC: - case MRK_TLM: - case MRK_PLM: - case MRK_PLT: - case MRK_PPM: - case MRK_PPT: - case MRK_SOP: - case MRK_EPH: - case MRK_CRG: - case MRK_COM: - /* Keep gcc quiet */ - break; } } @@ -238,21 +197,12 @@ ASDCP::JP2K::CodestreamParser::~CodestreamParser() // Opens the stream for reading, parses enough data to provide a complete // set of stream metadata for the MXFWriter below. ASDCP::Result_t -ASDCP::JP2K::CodestreamParser::OpenReadFrame(const char* filename, FrameBuffer& FB) const +ASDCP::JP2K::CodestreamParser::OpenReadFrame(const std::string& filename, FrameBuffer& FB) const { const_cast<ASDCP::JP2K::CodestreamParser*>(this)->m_Parser = new h__CodestreamParser; return m_Parser->OpenReadFrame(filename, FB); } -// Opens the stream for reading, parses enough data to provide a complete -// set of stream metadata for the MXFWriter below. -ASDCP::Result_t -ASDCP::JP2K::CodestreamParser::OpenReadFrame(const unsigned char* data, unsigned int size, FrameBuffer& FB) const -{ - const_cast<ASDCP::JP2K::CodestreamParser*>(this)->m_Parser = new h__CodestreamParser; - return m_Parser->OpenReadFrame(data, size, FB); -} - // ASDCP::Result_t ASDCP::JP2K::CodestreamParser::FillPictureDescriptor(PictureDescriptor& PDesc) const diff --git a/asdcplib/src/JP2K_Sequence_Parser.cpp b/asdcplib/src/JP2K_Sequence_Parser.cpp index 3b422d4c..a1627f9e 100755 --- a/asdcplib/src/JP2K_Sequence_Parser.cpp +++ b/asdcplib/src/JP2K_Sequence_Parser.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file JP2K_Sequence_Parser.cpp - \version $Id: JP2K_Sequence_Parser.cpp,v 1.8 2011/05/13 01:50:19 jhurst Exp $ + \version $Id: JP2K_Sequence_Parser.cpp,v 1.9 2014/01/02 23:29:22 jhurst Exp $ \brief AS-DCP library, JPEG 2000 codestream essence reader implementation */ @@ -59,7 +59,7 @@ public: } // - Result_t InitFromDirectory(const char* path) + Result_t InitFromDirectory(const std::string& path) { char next_file[Kumu::MaxFilePath]; Kumu::DirScanner Scanner; @@ -119,7 +119,7 @@ public: Close(); } - Result_t OpenRead(const char* filename, bool pedantic); + Result_t OpenRead(const std::string& filename, bool pedantic); Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic); void Close() {} @@ -168,9 +168,8 @@ ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead() // ASDCP::Result_t -ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const char* filename, bool pedantic) +ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename, bool pedantic) { - ASDCP_TEST_NULL_STR(filename); m_Pedantic = pedantic; Result_t result = m_FileList.InitFromDirectory(filename); @@ -327,7 +326,7 @@ ASDCP::JP2K::SequenceParser::~SequenceParser() // Opens the stream for reading, parses enough data to provide a complete // set of stream metadata for the MXFWriter below. ASDCP::Result_t -ASDCP::JP2K::SequenceParser::OpenRead(const char* filename, bool pedantic) const +ASDCP::JP2K::SequenceParser::OpenRead(const std::string& filename, bool pedantic) const { const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser = new h__SequenceParser; diff --git a/asdcplib/src/KLV.cpp b/asdcplib/src/KLV.cpp index 46a8a7a2..5bc88689 100755 --- a/asdcplib/src/KLV.cpp +++ b/asdcplib/src/KLV.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KLV.cpp - \version $Id: KLV.cpp,v 1.13 2012/02/03 19:49:56 jhurst Exp $ + \version $Id: KLV.cpp,v 1.16 2015/10/12 15:30:46 jhurst Exp $ \brief KLV objects */ @@ -94,22 +94,24 @@ ASDCP::KLVPacket::InitFromBuffer(const byte_t* buf, ui32_t buf_len) if ( ber_len > ( buf_len - SMPTE_UL_LENGTH ) ) { - DefaultLogSink().Error("BER encoding length exceeds buffer size\n"); + DefaultLogSink().Error("BER encoding length exceeds buffer size.\n"); return RESULT_FAIL; } if ( ber_len == 0 ) { - DefaultLogSink().Error("KLV format error, zero BER length not allowed\n"); + DefaultLogSink().Error("KLV format error, zero BER length not allowed.\n"); return RESULT_FAIL; } ui64_t tmp_size; if ( ! Kumu::read_BER(buf + SMPTE_UL_LENGTH, &tmp_size) ) - return RESULT_FAIL; + { + DefaultLogSink().Error("KLV format error, BER decode failure.\n"); + return RESULT_FAIL; + } - assert (tmp_size <= 0xFFFFFFFFL); - m_ValueLength = (ui32_t) tmp_size; + m_ValueLength = tmp_size; m_KLLength = SMPTE_UL_LENGTH + Kumu::BER_length(buf + SMPTE_UL_LENGTH); m_KeyStart = buf; m_ValueStart = buf + m_KLLength; @@ -122,7 +124,7 @@ ASDCP::KLVPacket::HasUL(const byte_t* ul) { if ( m_KeyStart != 0 ) { - return ( memcmp(ul, m_KeyStart, SMPTE_UL_LENGTH) == 0 ) ? true : false; + return UL(ul) == UL(m_KeyStart); } if ( m_UL.HasValue() ) @@ -170,10 +172,10 @@ ASDCP::KLVPacket::Dump(FILE* stream, const Dictionary& Dict, bool show_value) fprintf(stream, "%s", TmpUL.EncodeString(buf, 64)); const MDDEntry* Entry = Dict.FindUL(m_KeyStart); - fprintf(stream, " len: %7u (%s)\n", m_ValueLength, (Entry ? Entry->name : "Unknown")); + fprintf(stream, " len: %7qu (%s)\n", m_ValueLength, (Entry ? Entry->name : "Unknown")); if ( show_value && m_ValueLength < 1000 ) - Kumu::hexdump(m_ValueStart, Kumu::xmin(m_ValueLength, (ui32_t)128), stream); + Kumu::hexdump(m_ValueStart, Kumu::xmin(m_ValueLength, (ui64_t)128), stream); } else if ( m_UL.HasValue() ) { diff --git a/asdcplib/src/KLV.h b/asdcplib/src/KLV.h index ec343216..e5256679 100755 --- a/asdcplib/src/KLV.h +++ b/asdcplib/src/KLV.h @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KLV.h - \version $Id: KLV.h,v 1.25 2012/02/08 02:59:21 jhurst Exp $ + \version $Id: KLV.h,v 1.29 2014/09/21 13:27:43 jhurst Exp $ \brief KLV objects */ @@ -146,16 +146,15 @@ inline const char* ui64sz(ui64_t i, char* buf) std::map<ASDCP::UL, ui32_t> m_md_lookup; std::map<std::string, ui32_t> m_md_sym_lookup; std::map<ui32_t, ASDCP::UL> m_md_rev_lookup; - MDDEntry m_MDD_Table[(ui32_t)ASDCP::MDD_Max]; ASDCP_NO_COPY_CONSTRUCT(Dictionary); public: + MDDEntry m_MDD_Table[(ui32_t)ASDCP::MDD_Max]; + Dictionary(); ~Dictionary(); - // bool operator==(const Dictionary& rhs) const { return this == &rhs; } - void Init(); bool AddEntry(const MDDEntry& Entry, ui32_t index); bool DeleteEntry(ui32_t index); @@ -176,6 +175,7 @@ inline const char* ui64sz(ui64_t i, char* buf) const Dictionary& DefaultInteropDict(); const Dictionary& DefaultCompositeDict(); + void default_md_object_init(); // class IPrimerLookup @@ -196,22 +196,22 @@ inline const char* ui64sz(ui64_t i, char* buf) const byte_t* m_KeyStart; ui32_t m_KLLength; const byte_t* m_ValueStart; - ui32_t m_ValueLength; + ui64_t m_ValueLength; UL m_UL; public: KLVPacket() : m_KeyStart(0), m_KLLength(0), m_ValueStart(0), m_ValueLength(0) {} virtual ~KLVPacket() {} - ui32_t PacketLength() { + inline ui64_t PacketLength() { return m_KLLength + m_ValueLength; } - ui32_t ValueLength() { + inline ui64_t ValueLength() { return m_ValueLength; } - ui32_t KLLength() { + inline ui32_t KLLength() { return m_KLLength; } @@ -221,10 +221,16 @@ inline const char* ui64sz(ui64_t i, char* buf) virtual Result_t InitFromBuffer(const byte_t*, ui32_t); virtual Result_t InitFromBuffer(const byte_t*, ui32_t, const UL& label); virtual Result_t WriteKLToBuffer(ASDCP::FrameBuffer&, const UL& label, ui32_t length); - virtual Result_t WriteKLToBuffer(ASDCP::FrameBuffer& fb, ui32_t length) { + + virtual Result_t WriteKLToBuffer(ASDCP::FrameBuffer& fb, ui32_t length) + { if ( ! m_UL.HasValue() ) - return RESULT_STATE; - return WriteKLToBuffer(fb, m_UL, length); } + { + return RESULT_STATE; + } + + return WriteKLToBuffer(fb, m_UL, length); + } virtual void Dump(FILE*, const Dictionary& Dict, bool show_value); }; @@ -234,10 +240,9 @@ inline const char* ui64sz(ui64_t i, char* buf) { ASDCP_NO_COPY_CONSTRUCT(KLVFilePacket); - protected: + public: ASDCP::FrameBuffer m_Buffer; - public: KLVFilePacket() {} virtual ~KLVFilePacket() {} diff --git a/asdcplib/src/KM_error.h b/asdcplib/src/KM_error.h index 76397973..f8ed09d8 100755 --- a/asdcplib/src/KM_error.h +++ b/asdcplib/src/KM_error.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2011, John Hurst +Copyright (c) 2004-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_error.h - \version $Id: KM_error.h,v 1.12 2011/05/16 04:33:31 jhurst Exp $ + \version $Id: KM_error.h,v 1.16 2015/10/14 16:48:22 jhurst Exp $ \brief error reporting support */ @@ -34,6 +34,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef _KM_ERROR_H_ #define _KM_ERROR_H_ +#include <string> + #define KM_DECLARE_RESULT(sym, i, l) const Result_t RESULT_##sym = Result_t(i, #sym, l); namespace Kumu @@ -46,8 +48,7 @@ namespace Kumu class Result_t { int value; - const char* label; - const char* symbol; + std::string label, symbol, message; Result_t(); public: @@ -65,21 +66,26 @@ namespace Kumu static unsigned int End(); static const Result_t& Get(unsigned int); - Result_t(int v, const char* s, const char* l); + Result_t(int v, const std::string& s, const std::string& l); + Result_t(const Result_t& rhs); + const Result_t& operator=(const Result_t& rhs); ~Result_t(); + const Result_t operator()(const std::string& message) const; + const Result_t operator()(const int& line, const char* filename) const; + const Result_t operator()(const std::string& message, const int& line, const char* filename) const; + inline bool operator==(const Result_t& rhs) const { return value == rhs.value; } inline bool operator!=(const Result_t& rhs) const { return value != rhs.value; } - inline bool Success() const { return ( value >= 0 ); } + inline bool Success() const { return ! ( value < 0 ); } inline bool Failure() const { return ( value < 0 ); } inline int Value() const { return value; } inline operator int() const { return value; } - - inline const char* Label() const { return label; } - inline operator const char*() const { return label; } - - inline const char* Symbol() const { return symbol; } + inline const char* Label() const { return label.c_str(); } + inline operator const char*() const { return label.c_str(); } + inline const char* Symbol() const { return symbol.c_str(); } + inline const char* Message() const { return message.c_str(); } }; KM_DECLARE_RESULT(FALSE, 1, "Successful but not true."); @@ -105,7 +111,8 @@ namespace Kumu KM_DECLARE_RESULT(NOTAFILE, -19, "Filename not found."); KM_DECLARE_RESULT(UNKNOWN, -20, "Unknown result code."); KM_DECLARE_RESULT(DIR_CREATE, -21, "Unable to create directory."); - // -22 is reserved + KM_DECLARE_RESULT(NOT_EMPTY, -22, "Unable to delete non-empty directory."); + // 23-100 are reserved } // namespace Kumu @@ -121,7 +128,7 @@ namespace Kumu // See Result_t above for an explanation of RESULT_* symbols. # define KM_TEST_NULL(p) \ if ( (p) == 0 ) { \ - return Kumu::RESULT_PTR; \ + return Kumu::RESULT_PTR(__LINE__, __FILE__); \ } // Returns RESULT_PTR if the given argument is NULL. See Result_t @@ -132,9 +139,25 @@ namespace Kumu # define KM_TEST_NULL_STR(p) \ KM_TEST_NULL(p); \ if ( (p)[0] == '\0' ) { \ - return Kumu::RESULT_NULL_STR; \ + return Kumu::RESULT_NULL_STR(__LINE__, __FILE__); \ + } + +// RESULT_STATE is ambiguous. Use these everywhere it is assigned to provide some context +#define KM_RESULT_STATE_TEST_IMPLICIT() \ + if ( result == Kumu::RESULT_STATE ) { \ + Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__); \ } +#define KM_RESULT_STATE_TEST_THIS(_this__r_) \ + if ( _this__r_ == Kumu::RESULT_STATE ) { \ + Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__); \ + } + +#define KM_RESULT_STATE_HERE() \ + Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__); + + + namespace Kumu { // simple tracing mechanism diff --git a/asdcplib/src/KM_fileio.cpp b/asdcplib/src/KM_fileio.cpp index b20ff7f7..459a08d9 100644 --- a/asdcplib/src/KM_fileio.cpp +++ b/asdcplib/src/KM_fileio.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2011, John Hurst +Copyright (c) 2004-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,15 +25,13 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_fileio.cpp - \version $Id: KM_fileio.cpp,v 1.31 2011/03/08 19:03:47 jhurst Exp $ + \version $Id: KM_fileio.cpp,v 1.40 2015/10/07 16:58:03 jhurst Exp $ \brief portable file i/o */ #include <KM_fileio.h> #include <KM_log.h> #include <fcntl.h> -#include <sstream> -#include <iomanip> #include <assert.h> @@ -45,12 +43,18 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define _rmdir rmdir #endif +// only needed by GetExecutablePath() +#if defined(KM_MACOSX) +#include <mach-o/dyld.h> +#endif + using namespace Kumu; #ifdef KM_WIN32 typedef struct _stati64 fstat_t; #define S_IFLNK 0 + // win32 has WriteFileGather() and ReadFileScatter() but they // demand page alignment and page sizing, making them unsuitable // for use with arbitrary buffer sizes. @@ -71,31 +75,6 @@ struct iovec { typedef struct stat fstat_t; #endif -// -static void -split(const std::string& str, char separator, std::list<std::string>& components) -{ - const char* pstr = str.c_str(); - const char* r = strchr(pstr, separator); - - while ( r != 0 ) - { - assert(r >= pstr); - if ( r > pstr ) - { - std::string tmp_str; - tmp_str.assign(pstr, (r - pstr)); - components.push_back(tmp_str); - } - - pstr = r + 1; - r = strchr(pstr, separator); - } - - if( strlen(pstr) > 0 ) - components.push_back(std::string(pstr)); -} - // static Kumu::Result_t @@ -109,18 +88,9 @@ do_stat(const char* path, fstat_t* stat_info) #ifdef KM_WIN32 UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); - int const wn = MultiByteToWideChar (CP_UTF8, 0, path, -1, 0, 0); - wchar_t* buffer = new wchar_t[wn]; - if (MultiByteToWideChar (CP_UTF8, 0, path, -1, buffer, wn) == 0) { - delete[] buffer; - return Kumu::RESULT_FAIL; - } - - if ( _wstati64(buffer, stat_info) == (__int64)-1 ) + if ( _stati64(path, stat_info) == (__int64)-1 ) result = Kumu::RESULT_FILEOPEN; - delete[] buffer; - ::SetErrorMode( prev ); #else if ( stat(path, stat_info) == -1L ) @@ -226,62 +196,66 @@ Kumu::FileSize(const std::string& pathname) } // -static PathCompList_t& -s_PathMakeCanonical(PathCompList_t& CList, bool is_absolute) +static void +make_canonical_list(const PathCompList_t& in_list, PathCompList_t& out_list) { - PathCompList_t::iterator ci, ri; // component and removal iterators - - for ( ci = CList.begin(); ci != CList.end(); ci++ ) + PathCompList_t::const_iterator i; + for ( i = in_list.begin(); i != in_list.end(); ++i ) { - if ( *ci == "." && ( CList.size() > 1 || is_absolute ) ) - { - ri = ci++; - CList.erase(ri); - } - else if ( *ci == ".." && ci != CList.begin() ) + if ( *i == ".." ) { - ri = ci; - ri--; - - if ( *ri != ".." ) + if ( ! out_list.empty() ) { - CList.erase(ri); - ri = ci++; - CList.erase(ri); - } - } + out_list.pop_back(); + } + } + else if ( *i != "." ) + { + out_list.push_back(*i); + } } - - return CList; } // std::string Kumu::PathMakeCanonical(const std::string& Path, char separator) { - PathCompList_t CList; + PathCompList_t in_list, out_list; bool is_absolute = PathIsAbsolute(Path, separator); - s_PathMakeCanonical(PathToComponents(Path, CList, separator), is_absolute); + PathToComponents(Path, in_list, separator); + make_canonical_list(in_list, out_list); if ( is_absolute ) - return ComponentsToAbsolutePath(CList, separator); + return ComponentsToAbsolutePath(out_list, separator); - return ComponentsToPath(CList, separator); + return ComponentsToPath(out_list, separator); } // bool Kumu::PathsAreEquivalent(const std::string& lhs, const std::string& rhs) { - return PathMakeCanonical(lhs) == PathMakeCanonical(rhs); + return PathMakeAbsolute(lhs) == PathMakeAbsolute(rhs); } // Kumu::PathCompList_t& -Kumu::PathToComponents(const std::string& Path, PathCompList_t& CList, char separator) +Kumu::PathToComponents(const std::string& path, PathCompList_t& component_list, char separator) { - split(Path, separator, CList); - return CList; + std::string s; + s = separator; + PathCompList_t tmp_list = km_token_split(path, std::string(s)); + PathCompList_t::const_iterator i; + + for ( i = tmp_list.begin(); i != tmp_list.end(); ++i ) + { + if ( ! i->empty() ) + { + component_list.push_back(*i); + } + } + + return component_list; } // @@ -344,18 +318,8 @@ Kumu::PathIsAbsolute(const std::string& Path, char separator) // std::string -Kumu::PathMakeAbsolute(const std::string& Path, char separator) +Kumu::PathCwd() { - if ( Path.empty() ) - { - std::string out_path; - out_path = separator; - return out_path; - } - - if ( PathIsAbsolute(Path, separator) ) - return Path; - char cwd_buf [MaxFilePath]; if ( _getcwd(cwd_buf, MaxFilePath) == 0 ) { @@ -363,11 +327,28 @@ Kumu::PathMakeAbsolute(const std::string& Path, char separator) return ""; } - PathCompList_t CList; - PathToComponents(cwd_buf, CList); - CList.push_back(Path); + return cwd_buf; +} + +// +std::string +Kumu::PathMakeAbsolute(const std::string& Path, char separator) +{ + if ( Path.empty() ) + { + std::string tmpstr; + tmpstr = separator; + return tmpstr; + } + + if ( PathIsAbsolute(Path, separator) ) + return PathMakeCanonical(Path); - return ComponentsToAbsolutePath(s_PathMakeCanonical(CList, true), separator); + PathCompList_t in_list, out_list; + PathToComponents(PathJoin(PathCwd(), Path), in_list); + make_canonical_list(in_list, out_list); + + return ComponentsToAbsolutePath(out_list); } // @@ -465,6 +446,69 @@ Kumu::PathJoin(const std::string& Path1, const std::string& Path2, return Path1 + separator + Path2 + separator + Path3 + separator + Path4; } +#ifndef KM_WIN32 +// returns false if link cannot be read +// +bool +Kumu::PathResolveLinks(const std::string& link_path, std::string& resolved_path, char separator) +{ + PathCompList_t in_list, out_list; + PathToComponents(PathMakeCanonical(link_path), in_list, separator); + PathCompList_t::iterator i; + char link_buf[MaxFilePath]; + + for ( i = in_list.begin(); i != in_list.end(); ++i ) + { + assert ( *i != ".." && *i != "." ); + out_list.push_back(*i); + + for (;;) + { + std::string next_link = ComponentsToAbsolutePath(out_list, separator); + ssize_t link_size = readlink(next_link.c_str(), link_buf, MaxFilePath); + + if ( link_size == -1 ) + { + if ( errno == EINVAL ) + break; + + DefaultLogSink().Error("%s: readlink: %s\n", next_link.c_str(), strerror(errno)); + return false; + } + + assert(link_size < MaxFilePath); + link_buf[link_size] = 0; + std::string tmp_path; + out_list.clear(); + + if ( PathIsAbsolute(link_buf) ) + { + tmp_path = link_buf; + } + else + { + tmp_path = PathJoin(PathDirname(next_link), link_buf); + } + + PathToComponents(PathMakeCanonical(tmp_path), out_list, separator); + } + } + + resolved_path = ComponentsToAbsolutePath(out_list, separator); + return true; +} + +#else // KM_WIN32 +// TODO: is there a reasonable equivalent to be written for win32? +// +bool +Kumu::PathResolveLinks(const std::string& link_path, std::string& resolved_path, char separator) +{ + resolved_path = link_path; + return true; +} +#endif + // Kumu::PathList_t& Kumu::FindInPaths(const IPathMatch& Pattern, const Kumu::PathList_t& SearchPaths, @@ -587,6 +631,55 @@ Kumu::PathMatchGlob::Match(const std::string& s) const { #endif + +//------------------------------------------------------------------------------------------ + +#define X_BUFSIZE 1024 + +// +std::string +Kumu::GetExecutablePath(const std::string& default_path) +{ + char path[X_BUFSIZE] = {0}; + bool success = false; + +#if defined(KM_WIN32) + DWORD size = X_BUFSIZE; + DWORD rc = GetModuleFileName(0, path, size); + success = ( rc != 0 ); +#elif defined(KM_MACOSX) + uint32_t size = X_BUFSIZE; + int rc = _NSGetExecutablePath(path, &size); + success = ( rc != -1 ); +#elif defined(__linux__) + size_t size = X_BUFSIZE; + ssize_t rc = readlink("/proc/self/exe", path, size); + success = ( rc != -1 ); +#elif defined(__OpenBSD__) || defined(__FreeBSD__) + size_t size = X_BUFSIZE; + ssize_t rc = readlink("/proc/curproc/file", path, size); + success = ( rc != -1 ); +#elif defined(__FreeBSD__) + size_t size = X_BUFSIZE; + ssize_t rc = readlink("/proc/curproc/file", path, size); + success = ( rc != -1 ); +#elif defined(__NetBSD__) + size_t size = X_BUFSIZE; + ssize_t rc = readlink("/proc/curproc/file", path, size); + success = ( rc != -1 ); +#else +#error GetExecutablePath --> Create a method for obtaining the executable name +#endif + + if ( success ) + { + return Kumu::PathMakeCanonical(path); + } + + return default_path; +} + + //------------------------------------------------------------------------------------------ // portable aspects of the file classes @@ -624,10 +717,7 @@ Kumu::FileReader::Size() const // these are declared here instead of in the header file // because we have a mem_ptr that is managing a hidden class -Kumu::FileWriter::FileWriter() - : m_Hashing (false) -{} - +Kumu::FileWriter::FileWriter() {} Kumu::FileWriter::~FileWriter() {} // @@ -652,59 +742,20 @@ Kumu::FileWriter::Writev(const byte_t* buf, ui32_t buf_len) return RESULT_OK; } -void -Kumu::FileWriter::StartHashing() -{ - m_Hashing = true; - MD5_Init (&m_MD5Context); -} - -void -Kumu::FileWriter::MaybeHash(void const * data, int size) -{ - if (m_Hashing) { - MD5_Update (&m_MD5Context, data, size); - } -} - -std::string -Kumu::FileWriter::StopHashing() -{ - m_Hashing = false; - - unsigned char digest[MD5_DIGEST_LENGTH]; - MD5_Final (digest, &m_MD5Context); - - std::stringstream s; - for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) { - s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]); - } - - return s.str (); -} - #ifdef KM_WIN32 //------------------------------------------------------------------------------------------ // -/** @param filename File name (UTF-8 encoded) */ Kumu::Result_t -Kumu::FileReader::OpenRead(const char* filename) const +Kumu::FileReader::OpenRead(const std::string& filename) const { - KM_TEST_NULL_STR_L(filename); const_cast<FileReader*>(this)->m_Filename = filename; // suppress popup window on error UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); - int const wn = MultiByteToWideChar (CP_UTF8, 0, filename, -1, 0, 0); - wchar_t* buffer = new wchar_t[wn]; - if (MultiByteToWideChar (CP_UTF8, 0, filename, -1, buffer, wn) == 0) { - delete[] buffer; - return Kumu::RESULT_FAIL; - } - const_cast<FileReader*>(this)->m_Handle = ::CreateFileW(buffer, + const_cast<FileReader*>(this)->m_Handle = ::CreateFileA(filename.c_str(), (GENERIC_READ), // open for reading FILE_SHARE_READ, // share for reading NULL, // no security @@ -713,8 +764,6 @@ Kumu::FileReader::OpenRead(const char* filename) const NULL // no template file ); - delete[] buffer; - ::SetErrorMode(prev); return ( m_Handle == INVALID_HANDLE_VALUE ) ? @@ -821,24 +870,16 @@ Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const //------------------------------------------------------------------------------------------ // -/** @param filename File name (UTF-8 encoded) */ +// Kumu::Result_t -Kumu::FileWriter::OpenWrite(const char* filename) +Kumu::FileWriter::OpenWrite(const std::string& filename) { - KM_TEST_NULL_STR_L(filename); m_Filename = filename; // suppress popup window on error UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); - int const wn = MultiByteToWideChar (CP_UTF8, 0, filename, -1, 0, 0); - wchar_t* buffer = new wchar_t[wn]; - if (MultiByteToWideChar (CP_UTF8, 0, filename, -1, buffer, wn) == 0) { - delete[] buffer; - return Kumu::RESULT_FAIL; - } - - m_Handle = ::CreateFileW(buffer, + m_Handle = ::CreateFileA(filename.c_str(), (GENERIC_WRITE|GENERIC_READ), // open for reading FILE_SHARE_READ, // share for reading NULL, // no security @@ -847,45 +888,6 @@ Kumu::FileWriter::OpenWrite(const char* filename) NULL // no template file ); - delete[] buffer; - - ::SetErrorMode(prev); - - if ( m_Handle == INVALID_HANDLE_VALUE ) - return Kumu::RESULT_FILEOPEN; - - m_IOVec = new h__iovec; - return Kumu::RESULT_OK; -} - -/** @param filename File name (UTF-8 encoded) */ -Kumu::Result_t -Kumu::FileWriter::OpenModify(const char* filename) -{ - KM_TEST_NULL_STR_L(filename); - m_Filename = filename; - - // suppress popup window on error - UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); - - int const wn = MultiByteToWideChar (CP_UTF8, 0, filename, -1, 0, 0); - wchar_t* buffer = new wchar_t[wn]; - if (MultiByteToWideChar (CP_UTF8, 0, filename, -1, buffer, wn) == 0) { - delete[] buffer; - return Kumu::RESULT_FAIL; - } - - m_Handle = ::CreateFileW(buffer, - (GENERIC_WRITE|GENERIC_READ), // open for reading - FILE_SHARE_READ, // share for reading - NULL, // no security - OPEN_ALWAYS, // don't truncate existing - FILE_ATTRIBUTE_NORMAL, // normal file - NULL // no template file - ); - - delete[] buffer; - ::SetErrorMode(prev); if ( m_Handle == INVALID_HANDLE_VALUE ) @@ -929,7 +931,6 @@ Kumu::FileWriter::Writev(ui32_t* bytes_written) break; } - MaybeHash (iov->m_iovec[i].iov_base, iov->m_iovec[i].iov_len); *bytes_written += tmp_count; } @@ -960,8 +961,6 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written if ( result == 0 || *bytes_written != buf_len ) return Kumu::RESULT_WRITEFAIL; - MaybeHash (buf, buf_len); - return Kumu::RESULT_OK; } @@ -971,11 +970,10 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written // Kumu::Result_t -Kumu::FileReader::OpenRead(const char* filename) const +Kumu::FileReader::OpenRead(const std::string& filename) const { - KM_TEST_NULL_STR_L(filename); const_cast<FileReader*>(this)->m_Filename = filename; - const_cast<FileReader*>(this)->m_Handle = open(filename, O_RDONLY, 0); + const_cast<FileReader*>(this)->m_Handle = open(filename.c_str(), O_RDONLY, 0); return ( m_Handle == -1L ) ? RESULT_FILEOPEN : RESULT_OK; } @@ -1051,15 +1049,14 @@ Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const // Kumu::Result_t -Kumu::FileWriter::OpenWrite(const char* filename) +Kumu::FileWriter::OpenWrite(const std::string& filename) { - KM_TEST_NULL_STR_L(filename); m_Filename = filename; - m_Handle = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0664); + m_Handle = open(filename.c_str(), O_RDWR|O_CREAT|O_TRUNC, 0664); if ( m_Handle == -1L ) { - DefaultLogSink().Error("Error opening file %s: %s\n", filename, strerror(errno)); + DefaultLogSink().Error("Error opening file %s: %s\n", filename.c_str(), strerror(errno)); return RESULT_FILEOPEN; } @@ -1069,15 +1066,14 @@ Kumu::FileWriter::OpenWrite(const char* filename) // Kumu::Result_t -Kumu::FileWriter::OpenModify(const char* filename) +Kumu::FileWriter::OpenModify(const std::string& filename) { - KM_TEST_NULL_STR_L(filename); m_Filename = filename; - m_Handle = open(filename, O_RDWR|O_CREAT, 0664); + m_Handle = open(filename.c_str(), O_RDWR|O_CREAT, 0664); if ( m_Handle == -1L ) { - DefaultLogSink().Error("Error opening file %s: %s\n", filename, strerror(errno)); + DefaultLogSink().Error("Error opening file %s: %s\n", filename.c_str(), strerror(errno)); return RESULT_FILEOPEN; } @@ -1108,10 +1104,6 @@ Kumu::FileWriter::Writev(ui32_t* bytes_written) if ( write_size == -1L || write_size != total_size ) return RESULT_WRITEFAIL; - for (int i = 0; i < iov->m_Count; ++i) { - MaybeHash (iov->m_iovec[i].iov_base, iov->m_iovec[i].iov_len); - } - iov->m_Count = 0; *bytes_written = write_size; return RESULT_OK; @@ -1131,7 +1123,6 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written return RESULT_STATE; int write_size = write(m_Handle, buf, buf_len); - MaybeHash (buf, buf_len); if ( write_size == -1L || (ui32_t)write_size != buf_len ) return RESULT_WRITEFAIL; @@ -1141,22 +1132,20 @@ Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written } -#endif +#endif // KM_WIN32 //------------------------------------------------------------------------------------------ // Kumu::Result_t -Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size) +Kumu::ReadFileIntoString(const std::string& filename, std::string& outString, ui32_t max_size) { fsize_t fsize = 0; ui32_t read_size = 0; FileReader File; ByteString ReadBuf; - KM_TEST_NULL_STR_L(filename); - Result_t result = File.OpenRead(filename); if ( KM_SUCCESS(result) ) @@ -1165,13 +1154,13 @@ Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t ma if ( fsize > (Kumu::fpos_t)max_size ) { - DefaultLogSink().Error("%s: exceeds available buffer size (%u)\n", filename, max_size); + DefaultLogSink().Error("%s: exceeds available buffer size (%u)\n", filename.c_str(), max_size); return RESULT_ALLOC; } if ( fsize == 0 ) { - DefaultLogSink().Error("%s: zero file size\n", filename); + DefaultLogSink().Error("%s: zero file size\n", filename.c_str()); return RESULT_READFAIL; } @@ -1190,11 +1179,10 @@ Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t ma // Kumu::Result_t -Kumu::WriteStringIntoFile(const char* filename, const std::string& inString) +Kumu::WriteStringIntoFile(const std::string& filename, const std::string& inString) { FileWriter File; ui32_t write_count = 0; - KM_TEST_NULL_STR_L(filename); Result_t result = File.OpenWrite(filename); @@ -1209,7 +1197,7 @@ Kumu::WriteStringIntoFile(const char* filename, const std::string& inString) // Kumu::Result_t -Kumu::ReadFileIntoObject(const std::string& Filename, Kumu::IArchive& Object, ui32_t) +Kumu::ReadFileIntoObject(const std::string& Filename, Kumu::IArchive& Object, ui32_t max_size) { ByteString Buffer; ui32_t file_size = static_cast<ui32_t>(FileSize(Filename)); @@ -1220,7 +1208,7 @@ Kumu::ReadFileIntoObject(const std::string& Filename, Kumu::IArchive& Object, ui ui32_t read_count = 0; FileWriter Reader; - result = Reader.OpenRead(Filename.c_str()); + result = Reader.OpenRead(Filename); if ( KM_SUCCESS(result) ) result = Reader.Read(Buffer.Data(), file_size, &read_count); @@ -1255,7 +1243,7 @@ Kumu::WriteObjectIntoFile(const Kumu::IArchive& Object, const std::string& Filen if ( KM_SUCCESS(result) ) { Buffer.Length(MemWriter.Length()); - result = Writer.OpenWrite(Filename.c_str()); + result = Writer.OpenWrite(Filename); } if ( KM_SUCCESS(result) ) @@ -1270,7 +1258,7 @@ Kumu::WriteObjectIntoFile(const Kumu::IArchive& Object, const std::string& Filen // Result_t -Kumu::ReadFileIntoBuffer(const std::string& Filename, Kumu::ByteString& Buffer, ui32_t) +Kumu::ReadFileIntoBuffer(const std::string& Filename, Kumu::ByteString& Buffer, ui32_t max_size) { ui32_t file_size = FileSize(Filename); Result_t result = Buffer.Capacity(file_size); @@ -1280,7 +1268,7 @@ Kumu::ReadFileIntoBuffer(const std::string& Filename, Kumu::ByteString& Buffer, ui32_t read_count = 0; FileWriter Reader; - result = Reader.OpenRead(Filename.c_str()); + result = Reader.OpenRead(Filename); if ( KM_SUCCESS(result) ) result = Reader.Read(Buffer.Data(), file_size, &read_count); @@ -1304,7 +1292,7 @@ Kumu::WriteBufferIntoFile(const Kumu::ByteString& Buffer, const std::string& Fil ui32_t write_count = 0; FileWriter Writer; - Result_t result = Writer.OpenWrite(Filename.c_str()); + Result_t result = Writer.OpenWrite(Filename); if ( KM_SUCCESS(result) ) result = Writer.Write(Buffer.RoData(), Buffer.Length(), &write_count); @@ -1318,43 +1306,286 @@ Kumu::WriteBufferIntoFile(const Kumu::ByteString& Buffer, const std::string& Fil //------------------------------------------------------------------------------------------ // -Kumu::DirScanner::DirScanner() + +// Win32 directory scanner +// +#ifdef KM_WIN32 + +// +Kumu::DirScanner::DirScanner(void) : m_Handle(-1) {} + +// +// +Result_t +Kumu::DirScanner::Open(const std::string& filename) +{ + // we need to append a '*' to read the entire directory + ui32_t fn_len = filename.size(); + char* tmp_file = (char*)malloc(fn_len + 8); + + if ( tmp_file == 0 ) + return RESULT_ALLOC; + + strcpy(tmp_file, filename.c_str()); + char* p = &tmp_file[fn_len] - 1; + + if ( *p != '/' && *p != '\\' ) + { + p++; + *p++ = '/'; + } + + *p++ = '*'; + *p = 0; + // whew... + + m_Handle = _findfirsti64(tmp_file, &m_FileInfo); + Result_t result = RESULT_OK; + + if ( m_Handle == -1 ) + result = RESULT_NOT_FOUND; + + return result; +} + + +// +// +Result_t +Kumu::DirScanner::Close() { + if ( m_Handle == -1 ) + return RESULT_FILEOPEN; + + if ( _findclose((long)m_Handle) == -1 ) + return RESULT_FAIL; + m_Handle = -1; + return RESULT_OK; } + +// This sets filename param to the same per-instance buffer every time, so +// the value will change on the next call Result_t -Kumu::DirScanner::Open (const char* filename) +Kumu::DirScanner::GetNext(char* filename) { - KM_TEST_NULL_L (filename); + KM_TEST_NULL_L(filename); + + if ( m_Handle == -1 ) + return RESULT_FILEOPEN; + + if ( m_FileInfo.name[0] == '\0' ) + return RESULT_ENDOFFILE; + + strncpy(filename, m_FileInfo.name, MaxFilePath); + Result_t result = RESULT_OK; + + if ( _findnexti64((long)m_Handle, &m_FileInfo) == -1 ) + { + m_FileInfo.name[0] = '\0'; + + if ( errno != ENOENT ) + result = RESULT_FAIL; + } - if (!boost::filesystem::is_directory(filename)) { - return RESULT_NOT_FOUND; + return result; +} + + +#else // KM_WIN32 + +// POSIX directory scanner + +// +Kumu::DirScanner::DirScanner(void) : m_Handle(NULL) {} + +// +Result_t +Kumu::DirScanner::Open(const std::string& dirname) +{ + Result_t result = RESULT_OK; + + if ( ( m_Handle = opendir(dirname.c_str()) ) == NULL ) + { + switch ( errno ) + { + case ENOENT: + case ENOTDIR: + result = RESULT_NOTAFILE; + case EACCES: + result = RESULT_NO_PERM; + case ELOOP: + case ENAMETOOLONG: + result = RESULT_PARAM; + case EMFILE: + case ENFILE: + result = RESULT_STATE; + default: + DefaultLogSink().Error("DirScanner::Open(%s): %s\n", dirname.c_str(), strerror(errno)); + result = RESULT_FAIL; } - - _iterator = boost::filesystem::directory_iterator (filename); - return RESULT_OK; + } + + return result; } + +// Result_t -Kumu::DirScanner::GetNext (char* filename) +Kumu::DirScanner::Close() { - KM_TEST_NULL_L (filename); - - if (_iterator == boost::filesystem::directory_iterator()) { - return RESULT_ENDOFFILE; + if ( m_Handle == NULL ) + return RESULT_FILEOPEN; + + if ( closedir(m_Handle) == -1 ) { + switch ( errno ) + { + case EBADF: + case EINTR: + return RESULT_STATE; + default: + DefaultLogSink().Error("DirScanner::Close(): %s\n", strerror(errno)); + return RESULT_FAIL; + } + } + + m_Handle = NULL; + return RESULT_OK; +} + + +// +Result_t +Kumu::DirScanner::GetNext(char* filename) +{ + KM_TEST_NULL_L(filename); + + if ( m_Handle == NULL ) + return RESULT_FILEOPEN; + + struct dirent* entry; + + for (;;) + { + if ( ( entry = readdir(m_Handle)) == NULL ) + return RESULT_ENDOFFILE; + + break; + } + + strncpy(filename, entry->d_name, MaxFilePath); + return RESULT_OK; +} + + +// +Kumu::DirScannerEx::DirScannerEx() : m_Handle(0) {} + +// +Result_t +Kumu::DirScannerEx::Open(const std::string& dirname) +{ + Result_t result = RESULT_OK; + + if ( ( m_Handle = opendir(dirname.c_str()) ) == 0 ) + { + switch ( errno ) + { + case ENOENT: + case ENOTDIR: + result = RESULT_NOTAFILE; + case EACCES: + result = RESULT_NO_PERM; + case ELOOP: + case ENAMETOOLONG: + result = RESULT_PARAM; + case EMFILE: + case ENFILE: + result = RESULT_STATE; + default: + DefaultLogSink().Error("DirScanner::Open(%s): %s\n", dirname.c_str(), strerror(errno)); + result = RESULT_FAIL; } + } -#if BOOST_FILESYSTEM_VERSION == 3 - std::string f = boost::filesystem::path(*_iterator).filename().generic_string(); -#else - std::string f = boost::filesystem::path(*_iterator).filename(); -#endif - strncpy (filename, f.c_str(), MaxFilePath); - ++_iterator; - return RESULT_OK; + if ( KM_SUCCESS(result) ) + m_Dirname = dirname; + + KM_RESULT_STATE_TEST_IMPLICIT(); + return result; +} + +// +Result_t +Kumu::DirScannerEx::Close() +{ + if ( m_Handle == NULL ) + return RESULT_FILEOPEN; + + if ( closedir(m_Handle) == -1 ) + { + switch ( errno ) + { + case EBADF: + case EINTR: + KM_RESULT_STATE_HERE(); + return RESULT_STATE; + + default: + DefaultLogSink().Error("DirScanner::Close(): %s\n", strerror(errno)); + return RESULT_FAIL; + } + } + + m_Handle = 0; + return RESULT_OK; +} + +// +Result_t +Kumu::DirScannerEx::GetNext(std::string& next_item_name, DirectoryEntryType_t& next_item_type) +{ + if ( m_Handle == 0 ) + return RESULT_FILEOPEN; + + struct dirent* entry; + + for (;;) + { + if ( ( entry = readdir(m_Handle) ) == 0 ) + return RESULT_ENDOFFILE; + + break; + } + + next_item_name.assign(entry->d_name, strlen(entry->d_name)); + + switch ( entry->d_type ) + { + case DT_DIR: + next_item_type = DET_DIR; + break; + + case DT_REG: + next_item_type = DET_FILE; + break; + + case DT_LNK: + next_item_type = DET_LINK; + break; + + default: + next_item_type = DET_DEV; + } + + return RESULT_OK; } + +#endif // KM_WIN32 + + //------------------------------------------------------------------------------------------ // @@ -1484,12 +1715,37 @@ h__DeletePath(const std::string& pathname) Result_t Kumu::DeletePath(const std::string& pathname) { - std::string c_pathname = PathMakeAbsolute(PathMakeCanonical(pathname)); + std::string c_pathname = PathMakeCanonical(PathMakeAbsolute(pathname)); DefaultLogSink().Debug("DeletePath (%s) c(%s)\n", pathname.c_str(), c_pathname.c_str()); return h__DeletePath(c_pathname); } +// +Result_t +Kumu::DeleteDirectoryIfEmpty(const std::string& path) +{ + DirScanner source_dir; + char next_file[Kumu::MaxFilePath]; + + Result_t result = source_dir.Open(path); + + if ( KM_FAILURE(result) ) + return result; + + while ( KM_SUCCESS(source_dir.GetNext(next_file)) ) + { + if ( ( next_file[0] == '.' && next_file[1] == 0 ) + || ( next_file[0] == '.' && next_file[1] == '.' && next_file[2] == 0 ) ) + continue; + + return RESULT_NOT_EMPTY; // anything other than "." and ".." indicates a non-empty directory + } + + return DeletePath(path); +} + + //------------------------------------------------------------------------------------------ // @@ -1498,19 +1754,21 @@ Result_t Kumu::FreeSpaceForPath(const std::string& path, Kumu::fsize_t& free_space, Kumu::fsize_t& total_space) { #ifdef KM_WIN32 - ULARGE_INTEGER lTotalNumberOfBytes; - ULARGE_INTEGER lTotalNumberOfFreeBytes; + ULARGE_INTEGER lTotalNumberOfBytes; + ULARGE_INTEGER lTotalNumberOfFreeBytes; - BOOL fResult = ::GetDiskFreeSpaceExA(path.c_str(), NULL, &lTotalNumberOfBytes, &lTotalNumberOfFreeBytes); - if (fResult) { + BOOL fResult = ::GetDiskFreeSpaceExA(path.c_str(), NULL, &lTotalNumberOfBytes, &lTotalNumberOfFreeBytes); + if ( fResult ) + { free_space = static_cast<Kumu::fsize_t>(lTotalNumberOfFreeBytes.QuadPart); total_space = static_cast<Kumu::fsize_t>(lTotalNumberOfBytes.QuadPart); return RESULT_OK; - } - HRESULT LastError = ::GetLastError(); + } - DefaultLogSink().Error("FreeSpaceForPath GetDiskFreeSpaceEx %s: %lu\n", path.c_str(), ::GetLastError()); - return RESULT_FAIL; + HRESULT last_error = ::GetLastError(); + + DefaultLogSink().Error("FreeSpaceForPath GetDiskFreeSpaceEx %s: %lu\n", path.c_str(), last_error); + return RESULT_FAIL; #else // KM_WIN32 struct statfs s; diff --git a/asdcplib/src/KM_fileio.h b/asdcplib/src/KM_fileio.h index cb00acc8..dd4d2ca1 100755 --- a/asdcplib/src/KM_fileio.h +++ b/asdcplib/src/KM_fileio.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2009, John Hurst +Copyright (c) 2004-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_fileio.h - \version $Id: KM_fileio.h,v 1.17 2009/06/22 05:49:02 jhurst Exp $ + \version $Id: KM_fileio.h,v 1.22 2015/10/07 16:41:23 jhurst Exp $ \brief portable file i/o */ @@ -34,8 +34,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_util.h> #include <string> -#include <boost/filesystem.hpp> -#include <openssl/md5.h> #ifdef KM_WIN32 # include <io.h> @@ -53,15 +51,62 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Kumu { + // class DirScanner + { + public: +#ifdef KM_WIN32 + __int64 m_Handle; + struct _finddatai64_t m_FileInfo; +#else + DIR* m_Handle; +#endif + + DirScanner(void); + ~DirScanner() { Close(); } + + Result_t Open(const std::string&); + Result_t Close(); + Result_t GetNext(char*); + }; + + + // + enum DirectoryEntryType_t { + DET_FILE, + DET_DIR, + DET_DEV, + DET_LINK + }; + + // + class DirScannerEx { + std::string m_Dirname; +#ifdef KM_WIN32 + __int64 m_Handle; + struct _finddatai64_t m_FileInfo; +#else + DIR* m_Handle; +#endif + + KM_NO_COPY_CONSTRUCT(DirScannerEx); + public: - DirScanner(); - Result_t Open(const char *); - Result_t GetNext(char *); - Result_t Close(); - private: - boost::filesystem::directory_iterator _iterator; + + DirScannerEx(); + ~DirScannerEx() { Close(); } + + Result_t Open(const std::string& dirname); + Result_t Close(); + + + inline Result_t GetNext(std::string& next_item_name) { + DirectoryEntryType_t ft; + return GetNext(next_item_name, ft); + } + + Result_t GetNext(std::string& next_item_name, DirectoryEntryType_t& next_item_type); }; #ifdef KM_WIN32 @@ -85,8 +130,8 @@ namespace Kumu SP_POS = SEEK_CUR, SP_END = SEEK_END }; -#endif - +#endif + // #ifndef KM_SMALL_FILES_OK template <bool sizecheck> void compile_time_size_checker(); @@ -127,6 +172,7 @@ namespace Kumu bool PathIsFile(const std::string& Path); // true if the path exists in the filesystem and is a file bool PathIsDirectory(const std::string& Path); // true if the path exists in the filesystem and is a directory fsize_t FileSize(const std::string& Path); // returns the size of a regular file, 0 for a directory or device + std::string PathCwd(); bool PathsAreEquivalent(const std::string& lhs, const std::string& rhs); // true if paths point to the same filesystem entry // Returns free space and total space available for the given path @@ -142,6 +188,7 @@ namespace Kumu std::string PathMakeAbsolute(const std::string& Path, char separator = '/'); // compute position of relative path using getcwd() std::string PathMakeLocal(const std::string& Path, const std::string& Parent); // remove Parent from front of Path, if it exists std::string PathMakeCanonical(const std::string& Path, char separator = '/'); // remove '.' and '..' + bool PathResolveLinks(const std::string& link_path, std::string& resolved_path, char separator = '/'); // common operations std::string PathBasename(const std::string& Path, char separator = '/'); // returns right-most path element (list back()) @@ -214,6 +261,8 @@ namespace Kumu PathList_t& FindInPaths(const IPathMatch& Pattern, const PathList_t& SearchPaths, PathList_t& FoundPaths, bool one_shot = false, char separator = '/'); + std::string GetExecutablePath(const std::string& default_path); + //------------------------------------------------------------------------------------------ // Directory Manipulation //------------------------------------------------------------------------------------------ @@ -227,6 +276,9 @@ namespace Kumu // Recursively remove a file or directory Result_t DeletePath(const std::string& pathname); + // Remove the path only if it is a directory that is empty. + Result_t DeleteDirectoryIfEmpty(const std::string& path); + //------------------------------------------------------------------------------------------ // File I/O Wrappers //------------------------------------------------------------------------------------------ @@ -234,10 +286,10 @@ namespace Kumu // Instant IO for strings // // Reads an entire file into a string. - Result_t ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size = 8 * Megabyte); + Result_t ReadFileIntoString(const std::string& filename, std::string& outString, ui32_t max_size = 8 * Megabyte); // Writes a string to a file, overwrites the existing file if present. - Result_t WriteStringIntoFile(const char* filename, const std::string& inString); + Result_t WriteStringIntoFile(const std::string& filename, const std::string& inString); // Instant IO for archivable objects // @@ -274,7 +326,7 @@ namespace Kumu FileReader() : m_Handle(INVALID_HANDLE_VALUE) {} virtual ~FileReader() { Close(); } - Result_t OpenRead(const char*) const; // open the file for reading + Result_t OpenRead(const std::string&) const; // open the file for reading Result_t Close() const; // close the file fsize_t Size() const; // returns the file's current size Result_t Seek(Kumu::fpos_t = 0, SeekPos_t = SP_BEGIN) const; // move the file pointer @@ -299,15 +351,13 @@ namespace Kumu class h__iovec; mem_ptr<h__iovec> m_IOVec; KM_NO_COPY_CONSTRUCT(FileWriter); - bool m_Hashing; - MD5_CTX m_MD5Context; public: FileWriter(); virtual ~FileWriter(); - Result_t OpenWrite(const char*); // open a new file, overwrites existing - Result_t OpenModify(const char*); // open a file for read/write + Result_t OpenWrite(const std::string&); // open a new file, overwrites existing + Result_t OpenModify(const std::string&); // open a file for read/write // this part of the interface takes advantage of the iovec structure on // platforms that support it. For each call to Writev(const byte_t*, ui32_t, ui32_t*), @@ -320,10 +370,6 @@ namespace Kumu // the iovec list will be written to disk before the given buffer,as though // you had called Writev() first. Result_t Write(const byte_t*, ui32_t, ui32_t* = 0); // write buffer to disk - - void StartHashing(); - void MaybeHash(void const *, int); - std::string StopHashing(); }; Result_t CreateDirectoriesInPath(const std::string& Path); diff --git a/asdcplib/src/KM_log.cpp b/asdcplib/src/KM_log.cpp index 7bd59264..dc7bf3f2 100755 --- a/asdcplib/src/KM_log.cpp +++ b/asdcplib/src/KM_log.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_log.cpp - \version $Id: KM_log.cpp,v 1.15 2011/03/08 19:03:47 jhurst Exp $ + \version $Id: KM_log.cpp,v 1.17 2012/09/20 21:19:23 jhurst Exp $ \brief message logging API */ @@ -90,7 +90,8 @@ Kumu::DefaultLogSink() void Kumu::EntryListLogSink::WriteEntry(const LogEntry& Entry) { - AutoMutex L(m_Lock); + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); if ( Entry.TestFilter(m_filter) ) m_Target.push_back(Entry); @@ -102,13 +103,15 @@ Kumu::EntryListLogSink::WriteEntry(const LogEntry& Entry) void Kumu::StdioLogSink::WriteEntry(const LogEntry& Entry) { - AutoMutex L(m_Lock); std::string buf; + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); if ( Entry.TestFilter(m_filter) ) { Entry.CreateStringWithOptions(buf, m_options); fputs(buf.c_str(), m_stream); + fflush(m_stream); } } @@ -121,8 +124,9 @@ Kumu::StdioLogSink::WriteEntry(const LogEntry& Entry) void Kumu::WinDbgLogSink::WriteEntry(const LogEntry& Entry) { - AutoMutex L(m_Lock); std::string buf; + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); if ( Entry.TestFilter(m_filter) ) { @@ -140,8 +144,9 @@ Kumu::WinDbgLogSink::WriteEntry(const LogEntry& Entry) void Kumu::StreamLogSink::WriteEntry(const LogEntry& Entry) { - AutoMutex L(m_Lock); std::string buf; + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); if ( Entry.TestFilter(m_filter) ) { @@ -186,7 +191,7 @@ Kumu::SyslogLogSink::~SyslogLogSink() void Kumu::SyslogLogSink::WriteEntry(const LogEntry& Entry) { - int priority = 0; + int priority; switch ( Entry.Type ) { @@ -199,7 +204,8 @@ Kumu::SyslogLogSink::WriteEntry(const LogEntry& Entry) case Kumu::LOG_DEBUG: priority = SYSLOG_DEBUG; break; } - AutoMutex L(m_Lock); + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); if ( Entry.TestFilter(m_filter) ) { diff --git a/asdcplib/src/KM_log.h b/asdcplib/src/KM_log.h index 4981b178..1accf5e2 100755 --- a/asdcplib/src/KM_log.h +++ b/asdcplib/src/KM_log.h @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_log.h - \version $Id: KM_log.h,v 1.13 2011/03/05 19:15:35 jhurst Exp $ + \version $Id: KM_log.h,v 1.15 2013/06/17 17:55:54 jhurst Exp $ \brief message logging API */ @@ -39,6 +39,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdarg.h> #include <errno.h> #include <iosfwd> +#include <set> #define LOG_MSG_IMPL(t) \ va_list args; \ @@ -87,6 +88,7 @@ namespace Kumu LOG_NOTICE, // application user info LOG_ALERT, // application non-fatal or near-miss error LOG_CRIT, // application fatal error + LOG_MAX }; @@ -149,6 +151,18 @@ namespace Kumu protected: i32_t m_filter; i32_t m_options; + Mutex m_lock; + std::set<ILogSink*> m_listeners; + + // you must obtain m_lock BEFORE calling this from your own WriteEntry + void WriteEntryToListeners(const LogEntry& entry) + { + std::set<ILogSink*>::iterator i; + for ( i = m_listeners.begin(); i != m_listeners.end(); ++i ) + (*i)->WriteEntry(entry); + } + + KM_NO_COPY_CONSTRUCT(ILogSink); public: ILogSink() : m_filter(LOG_ALLOW_ALL), m_options(LOG_OPTION_NONE) {} @@ -162,6 +176,19 @@ namespace Kumu void UnsetOptionFlag(i32_t o) { m_options &= ~o; } bool TestOptionFlag(i32_t o) const { return ((m_options & o) == o); } + void AddListener(ILogSink& s) { + if ( &s != this ) + { + AutoMutex l(m_lock); + m_listeners.insert(&s); + } + } + + void DelListener(ILogSink& s) { + AutoMutex l(m_lock); + m_listeners.erase(&s); + } + // library messages void Error(const char* fmt, ...) { LOG_MSG_IMPL(LOG_ERROR); } void Warn(const char* fmt, ...) { LOG_MSG_IMPL(LOG_WARN); } @@ -190,51 +217,35 @@ namespace Kumu ILogSink& DefaultLogSink(); - // Sets a log sink as the default until the object is destroyed. - // The original default sink is saved and then restored on delete. - class LogSinkContext - { - KM_NO_COPY_CONSTRUCT(LogSinkContext); - LogSinkContext(); - ILogSink* m_orig; + // attach a log sink as a listener until deleted + class LogSinkListenContext + { + ILogSink* m_log_source; + ILogSink* m_sink; + KM_NO_COPY_CONSTRUCT(LogSinkListenContext); + LogSinkListenContext(); + + public: + LogSinkListenContext(ILogSink& source, ILogSink& sink) + { + m_log_source = &source; + m_sink = &sink; + m_log_source->AddListener(*m_sink); + } + + ~LogSinkListenContext() + { + m_log_source->DelListener(*m_sink); + } + }; - public: - LogSinkContext(ILogSink& sink) { - m_orig = &DefaultLogSink(); - SetDefaultLogSink(&sink); - } - - ~LogSinkContext() { - SetDefaultLogSink(m_orig); - } - }; //------------------------------------------------------------------------------------------ // - // write messages to two subordinate log sinks - class TeeLogSink : public ILogSink - { - KM_NO_COPY_CONSTRUCT(TeeLogSink); - TeeLogSink(); - - ILogSink& m_a; - ILogSink& m_b; - - public: - TeeLogSink(ILogSink& a, ILogSink& b) : m_a(a), m_b(b) {} - virtual ~TeeLogSink() {} - - void WriteEntry(const LogEntry& Entry) { - m_a.WriteEntry(Entry); - m_b.WriteEntry(Entry); - } - }; - // collect log messages into the given list, does not test filter class EntryListLogSink : public ILogSink { - Mutex m_Lock; LogEntryList& m_Target; KM_NO_COPY_CONSTRUCT(EntryListLogSink); EntryListLogSink(); @@ -250,7 +261,6 @@ namespace Kumu // write messages to a POSIX stdio stream class StdioLogSink : public ILogSink { - Mutex m_Lock; FILE* m_stream; KM_NO_COPY_CONSTRUCT(StdioLogSink); @@ -266,7 +276,6 @@ namespace Kumu // write messages to the Win32 debug stream class WinDbgLogSink : public ILogSink { - Mutex m_Lock; KM_NO_COPY_CONSTRUCT(WinDbgLogSink); public: @@ -281,7 +290,6 @@ namespace Kumu // write messages to a POSIX file descriptor class StreamLogSink : public ILogSink { - Mutex m_Lock; int m_fd; KM_NO_COPY_CONSTRUCT(StreamLogSink); StreamLogSink(); @@ -296,7 +304,6 @@ namespace Kumu // write messages to the syslog facility class SyslogLogSink : public ILogSink { - Mutex m_Lock; KM_NO_COPY_CONSTRUCT(SyslogLogSink); SyslogLogSink(); diff --git a/asdcplib/src/KM_memio.h b/asdcplib/src/KM_memio.h index 69942c76..3f730d40 100755 --- a/asdcplib/src/KM_memio.h +++ b/asdcplib/src/KM_memio.h @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_memio.h - \version $Id: KM_memio.h,v 1.9 2011/03/07 06:46:36 jhurst Exp $ + \version $Id: KM_memio.h,v 1.10 2014/04/14 18:22:27 jhurst Exp $ \brief abstraction for byte-oriented conversion of integers and objects */ @@ -128,7 +128,7 @@ namespace Kumu if ( ! WriteRaw((const byte_t*)str.c_str(), len) ) return false; return true; } - }; + }; // class MemIOReader @@ -217,11 +217,16 @@ namespace Kumu inline bool ReadString(std::string& str) { - ui32_t str_length; + ui32_t str_length = 0; if ( ! ReadUi32BE(&str_length) ) return false; - if ( ( m_size + str_length ) > m_capacity ) return false; - str.assign((const char*)CurrentData(), str_length); - if ( ! SkipOffset(str_length) ) return false; + + if ( str_length > 0 ) + { + if ( ( m_size + str_length ) > m_capacity ) return false; + str.assign((const char*)CurrentData(), str_length); + if ( ! SkipOffset(str_length) ) return false; + } + return true; } }; diff --git a/asdcplib/src/KM_platform.h b/asdcplib/src/KM_platform.h index 266c01ae..9dff2cee 100644 --- a/asdcplib/src/KM_platform.h +++ b/asdcplib/src/KM_platform.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2009, John Hurst +Copyright (c) 2004-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,14 +25,15 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_platform.h - \version $Id: KM_platform.h,v 1.6 2010/09/14 19:21:47 msheby Exp $ + \version $Id: KM_platform.h,v 1.9 2015/10/07 16:41:23 jhurst Exp $ \brief platform portability */ #ifndef _KM_PLATFORM_H_ # define _KM_PLATFORM_H_ -# ifdef __APPLE__ +#if defined(__APPLE__) && defined(__MACH__) +# define KM_MACOSX # ifdef __BIG_ENDIAN__ # define KM_BIG_ENDIAN # endif @@ -42,37 +43,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # define WIN32_LEAN_AND_MEAN # define VC_EXTRALEAN # include <windows.h> -/* we like the "SendMessage" name, so get rid of the preprocessor define - * and replace with an inline function */ -# undef SendMessage -#ifdef UNICODE
-inline
-WINUSERAPI
-LRESULT
-WINAPI
-SendMessage(
- HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- return SendMessageW(hWnd, Msg, wParam, lParam);
-}
-#else
-inline
-WINUSERAPI
-LRESULT
-WINAPI
-SendMessage(
- HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- return SendMessageA(hWnd, Msg, wParam, lParam);
-}
-#endif // !UNICODE
- # include <stdlib.h> # include <stdio.h> # include <stdarg.h> @@ -151,11 +121,17 @@ namespace Kumu // template<class T> inline T xclamp(T v, T l, T h) { - if ( v < l ) return l; - if ( v > h ) return h; + if ( v < l ) { return l; } + if ( v > h ) { return h; } return v; } + // + template<class T> + inline T xabs(T n) { + if ( n < 0 ) { return -n; } + return n; + } // read an integer from byte-structured storage template<class T> @@ -165,6 +141,7 @@ namespace Kumu template<class T> inline void i2p(T i, byte_t* p) { *(T*)p = i; } + # ifdef KM_BIG_ENDIAN # define KM_i16_LE(i) Kumu::Swap2(i) # define KM_i32_LE(i) Kumu::Swap4(i) @@ -197,7 +174,7 @@ namespace Kumu ~mem_ptr() { delete m_p; } inline T& operator*() const { return *m_p; } - inline T* operator->() const { return m_p; } + inline T* operator->() const { assert(m_p!=0); return m_p; } inline operator T*()const { return m_p; } inline const mem_ptr<T>& operator=(T* p) { this->set(p); return *this; } inline T* set(T* p) { delete m_p; m_p = p; return m_p; } diff --git a/asdcplib/src/KM_prng.cpp b/asdcplib/src/KM_prng.cpp index 463ae157..5212595f 100755 --- a/asdcplib/src/KM_prng.cpp +++ b/asdcplib/src/KM_prng.cpp @@ -1,5 +1,3 @@ -/* -*- c-basic-offset: 2; -*- */ - /* Copyright (c) 2006-2009, John Hurst All rights reserved. @@ -50,6 +48,7 @@ using namespace Kumu; const char* DEV_URANDOM = "/dev/urandom"; #endif // KM_WIN32 + const ui32_t RNG_KEY_SIZE = 512UL; const ui32_t RNG_KEY_SIZE_BITS = 256UL; const ui32_t RNG_BLOCK_SIZE = 16UL; @@ -65,7 +64,6 @@ public: AES_KEY m_Context; byte_t m_ctr_buf[RNG_BLOCK_SIZE]; Mutex m_Lock; - unsigned int m_libdcp_test_rng_state; h__RNG() { @@ -99,10 +97,6 @@ public: } // end AutoMutex context set_key(rng_key); - -#ifdef LIBDCP_POSIX - reset(); -#endif } // @@ -144,26 +138,7 @@ public: AES_encrypt(m_ctr_buf, tmp, &m_Context); memcpy(buf + gen_count, tmp, len - gen_count); } - -#ifdef LIBDCP_POSIX - if (libdcp_test) - { - for (unsigned int i = 0; i < len; ++i) - buf[i] = rand_r(&m_libdcp_test_rng_state); - } -#endif - -#ifdef LIBDCP_WINDOWS - /* XXX */ -#endif } - -#ifdef LIBDCP_POSIX - void reset () - { - m_libdcp_test_rng_state = 1; - } -#endif }; @@ -217,14 +192,6 @@ Kumu::FortunaRNG::FillRandom(Kumu::ByteString& Buffer) return Buffer.Data(); } -#ifdef LIBDCP_POSIX -void -Kumu::FortunaRNG::Reset() -{ - s_RNG->reset(); -} -#endif - //------------------------------------------------------------------------------------------ // diff --git a/asdcplib/src/KM_prng.h b/asdcplib/src/KM_prng.h index 0b941f3b..2a909d6f 100755 --- a/asdcplib/src/KM_prng.h +++ b/asdcplib/src/KM_prng.h @@ -45,14 +45,12 @@ namespace Kumu ~FortunaRNG(); const byte_t* FillRandom(byte_t* buf, ui32_t len); const byte_t* FillRandom(ByteString&); -#ifdef LIBDCP_POSIX - void Reset(); -#endif }; // key_len must be <= 64 (larger values will be truncated) void Gen_FIPS_186_Value(const byte_t* key_in, ui32_t key_len, byte_t* buf, ui32_t buf_len); + } // namespace Kumu diff --git a/asdcplib/src/KM_tai.cpp b/asdcplib/src/KM_tai.cpp index 509e8632..2cbd1253 100644 --- a/asdcplib/src/KM_tai.cpp +++ b/asdcplib/src/KM_tai.cpp @@ -190,7 +190,6 @@ Kumu::TAI::tai::now() ct.hour = st.wHour; ct.minute = st.wMinute; ct.second = st.wSecond; - ct.offset = 0; caltime_tai(&ct, this); #else struct timeval now; diff --git a/asdcplib/src/KM_util.cpp b/asdcplib/src/KM_util.cpp index b1814840..f738814f 100755 --- a/asdcplib/src/KM_util.cpp +++ b/asdcplib/src/KM_util.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_util.cpp - \version $Id: KM_util.cpp,v 1.40 2012/02/22 19:20:33 jhurst Exp $ + \version $Id: KM_util.cpp,v 1.47 2015/10/12 15:30:46 jhurst Exp $ \brief Utility functions */ @@ -40,8 +40,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <map> #include <string> -bool Kumu::libdcp_test = false; - const char* Kumu::Version() { @@ -131,10 +129,10 @@ Kumu::Result_t::Get(unsigned int i) } // -Kumu::Result_t::Result_t(int v, const char* s, const char* l) : value(v), label(l), symbol(s) +Kumu::Result_t::Result_t(int v, const std::string& s, const std::string& l) : value(v), symbol(s), label(l) { - assert(l); - assert(s); + assert(!l.empty()); + assert(!s.empty()); if ( v == 0 ) return; @@ -164,8 +162,65 @@ Kumu::Result_t::Result_t(int v, const char* s, const char* l) : value(v), label( return; } + +Kumu::Result_t::Result_t(const Result_t& rhs) +{ + value = rhs.value; + symbol = rhs.symbol; + label = rhs.label; + message = rhs.message; +} + Kumu::Result_t::~Result_t() {} +// +const Kumu::Result_t& +Kumu::Result_t::operator=(const Result_t& rhs) +{ + value = rhs.value; + symbol = rhs.symbol; + label = rhs.label; + message = rhs.message; + return *this; +} + +// +const Kumu::Result_t +Kumu::Result_t::operator()(const std::string& message) const +{ + Result_t result = *this; + result.message = message; + return result; +} + +static int const MESSAGE_BUF_MAX = 2048; + +// +const Kumu::Result_t +Kumu::Result_t::operator()(const int& line, const char* filename) const +{ + assert(filename); + char buf[MESSAGE_BUF_MAX]; + snprintf(buf, MESSAGE_BUF_MAX-1, "%s, line %d", filename, line); + + Result_t result = *this; + result.message = buf; + return result; +} + +// +const Kumu::Result_t +Kumu::Result_t::operator()(const std::string& message, const int& line, const char* filename) const +{ + assert(filename); + char buf[MESSAGE_BUF_MAX]; + snprintf(buf, MESSAGE_BUF_MAX-1, "%s, line %d", filename, line); + + Result_t result = *this; + result.message = message + buf; + return result; +} + //------------------------------------------------------------------------------------------ // DTrace internals @@ -534,15 +589,6 @@ Kumu::GenRandomValue(UUID& ID) ID.Set(tmp_buf); } -#ifdef LIBDCP_POSIX -void -Kumu::ResetTestRNG() -{ - FortunaRNG RNG; - RNG.Reset(); -} -#endif - // void Kumu::GenRandomUUID(byte_t* buf) @@ -699,14 +745,7 @@ Kumu::write_BER(byte_t* buf, ui64_t val, ui32_t ber_len) // Kumu::Timestamp::Timestamp() : m_TZOffsetMinutes(0) { - if (libdcp_test) - { - m_Timestamp.x = 42; - } - else - { - m_Timestamp.now(); - } + m_Timestamp.now(); } Kumu::Timestamp::Timestamp(const Timestamp& rhs) { @@ -814,8 +853,8 @@ Kumu::Timestamp::EncodeString(char* str_buf, ui32_t buf_len) const tmp_t.AddMinutes(m_TZOffsetMinutes); tmp_t.GetComponents(year, month, day, hour, minute, second); - ofst_hours = abs(m_TZOffsetMinutes) / 60; - ofst_minutes = abs(m_TZOffsetMinutes) % 60; + ofst_hours = Kumu::xabs(m_TZOffsetMinutes) / 60; + ofst_minutes = Kumu::xabs(m_TZOffsetMinutes) % 60; if ( m_TZOffsetMinutes < 0 ) direction = '-'; @@ -823,14 +862,14 @@ Kumu::Timestamp::EncodeString(char* str_buf, ui32_t buf_len) const // 2004-05-01T13:20:00+00:00 snprintf(str_buf, buf_len, - "%04hu-%02hu-%02huT%02hu:%02hu:%02hu%c%02hu:%02hu", + "%04hu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhu%c%02u:%02u", year, month, day, hour, minute, second, direction, ofst_hours, ofst_minutes); return str_buf; } -// +// ^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(?:([+-]\d{2}):(\d{2}))?)?$ bool Kumu::Timestamp::DecodeString(const char* datestr) { @@ -843,10 +882,13 @@ Kumu::Timestamp::DecodeString(const char* datestr) ui32_t char_count = 10; TAI::caltime YMDhms; + YMDhms.hour = 0; + YMDhms.minute = 0; + YMDhms.second = 0; YMDhms.offset = 0; - YMDhms.date.year = atoi(datestr); - YMDhms.date.month = atoi(datestr + 5); - YMDhms.date.day = atoi(datestr + 8); + YMDhms.date.year = strtol(datestr, 0, 10); + YMDhms.date.month = strtol(datestr + 5, 0, 10); + YMDhms.date.day = strtol(datestr + 8, 0, 10); if ( datestr[10] == 'T' ) { @@ -856,8 +898,8 @@ Kumu::Timestamp::DecodeString(const char* datestr) return false; char_count += 6; - YMDhms.hour = atoi(datestr + 11); - YMDhms.minute = atoi(datestr + 14); + YMDhms.hour = strtol(datestr + 11, 0, 10); + YMDhms.minute = strtol(datestr + 14, 0, 10); if ( datestr[16] == ':' ) { @@ -865,16 +907,23 @@ Kumu::Timestamp::DecodeString(const char* datestr) return false; char_count += 3; - YMDhms.second = atoi(datestr + 17); + YMDhms.second = strtol(datestr + 17, 0, 10); } if ( datestr[19] == '.' ) { - if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) && isdigit(datestr[22]) ) ) - return false; - + if ( ! isdigit(datestr[20]) ) + { + return false; + } + // we don't carry the ms value - datestr += 4; + while ( isdigit(datestr[20]) ) + { + ++datestr; + } + + ++datestr; } if ( datestr[19] == '-' || datestr[19] == '+' ) @@ -886,8 +935,8 @@ Kumu::Timestamp::DecodeString(const char* datestr) char_count += 6; - ui32_t TZ_hh = atoi(datestr + 20); - ui32_t TZ_mm = atoi(datestr + 23); + ui32_t TZ_hh = strtol(datestr + 20, 0, 10); + ui32_t TZ_mm = strtol(datestr + 23, 0, 10); if ((TZ_hh > 14) || (TZ_mm > 59) || ((TZ_hh == 14) && (TZ_mm > 0))) return false; @@ -972,6 +1021,15 @@ Kumu::Timestamp::GetCTime() const return m_Timestamp.x - ui64_C(4611686018427387914); } +// +void +Kumu::Timestamp::SetCTime(const ui64_t& ctime) +{ + m_Timestamp.x = ctime + ui64_C(4611686018427387914); +} + + + //------------------------------------------------------------------------------------------ @@ -1135,6 +1193,58 @@ Kumu::ByteString::Append(const byte_t* buf, ui32_t buf_len) return result; } +//------------------------------------------------------------------------------------------ + +// +const char* +Kumu::km_strnstr(const char *s, const char *find, size_t slen) +{ + char c, sc; + size_t len; + + if ( ( c = *find++ ) != '\0' ) + { + len = strlen(find); + do + { + do + { + if ( slen-- < 1 || ( sc = *s++ ) == '\0' ) + return 0; + } + while ( sc != c ); + + if ( len > slen ) + return 0; + } + while ( strncmp(s, find, len) != 0 ); + --s; + } + + return s; +} + +// +std::list<std::string> +Kumu::km_token_split(const std::string& str, const std::string& separator) +{ + std::list<std::string> components; + const char* pstr = str.c_str(); + const char* r = strstr(pstr, separator.c_str()); + + while ( r != 0 ) + { + assert(r >= pstr); + std::string tmp_str; + tmp_str.assign(pstr, r - pstr); + components.push_back(tmp_str); + pstr = r + separator.size(); + r = strstr(pstr, separator.c_str()); + } + + components.push_back(std::string(pstr)); + return components; +} // // end KM_util.cpp diff --git a/asdcplib/src/KM_util.h b/asdcplib/src/KM_util.h index a9793ba0..8b1db49f 100755 --- a/asdcplib/src/KM_util.h +++ b/asdcplib/src/KM_util.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_util.h - \version $Id: KM_util.h,v 1.32 2012/02/21 02:09:30 jhurst Exp $ + \version $Id: KM_util.h,v 1.39 2015/10/12 15:30:46 jhurst Exp $ \brief Utility functions */ @@ -36,13 +36,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_error.h> #include <KM_tai.h> #include <string.h> -#include <string> #include <list> namespace Kumu { - extern bool libdcp_test; - // The version number declaration and explanation are in ../configure.ac const char* Version(); @@ -246,7 +243,7 @@ namespace Kumu virtual ~ArchivableString() {} bool HasValue() const { return ! this->empty(); } - ui32_t ArchiveLength() const { return static_cast<ui32_t>((sizeof(ui32_t) + this->size())|0xffffffff); } + ui32_t ArchiveLength() const { return sizeof(ui32_t) + static_cast<ui32_t>(this->size()); } bool Archive(MemIOWriter* Writer) const { if ( Writer == 0 ) return false; @@ -381,9 +378,6 @@ namespace Kumu void GenRandomUUID(byte_t* buf); // buf must be UUID_Length or longer void GenRandomValue(UUID&); -#ifdef LIBDCP_POSIX - void ResetTestRNG(); -#endif typedef ArchivableList<UUID> UUIDList; @@ -458,6 +452,9 @@ namespace Kumu // Return the number of seconds since the Unix epoch UTC (1970-01-01T00:00:00+00:00) ui64_t GetCTime() const; + // Set internal time to the number of seconds since the Unix epoch UTC + void SetCTime(const ui64_t& ctime); + // Read and write the timestamp (always UTC) value as a byte string having // the following format: // | 16 bits int, big-endian | 8 bits | 8 bits | 8 bits | 8 bits | 8 bits | @@ -512,7 +509,7 @@ namespace Kumu inline virtual bool HasValue() const { return m_Length > 0; } - inline virtual ui32_t ArchiveLength() const { return m_Length; } + inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + m_Length; } inline virtual bool Archive(MemIOWriter* Writer) const { assert(Writer); @@ -532,10 +529,19 @@ namespace Kumu } }; - inline void hexdump(const ByteString& buf, FILE*) { - hexdump(buf.RoData(), buf.Length()); + inline void hexdump(const ByteString& buf, FILE* stream = 0) { + hexdump(buf.RoData(), buf.Length(), stream); } + // Locates the first occurrence of the null-terminated string s2 in the string s1, where not more + // than n characters are searched. Characters that appear after a `\0' character are not searched. + // Reproduced here from BSD for portability. + const char *km_strnstr(const char *s1, const char *s2, size_t n); + + // Split the input string into tokens using the given separator. If the separator is not found the + // entire string will be returned as a single-item list. Empty items will be recorded for + // adjacent instances of the separator. E.g., "/foo//bar/" will return ["", "foo", "", "bar", ""]. + std::list<std::string> km_token_split(const std::string& str, const std::string& separator); } // namespace Kumu diff --git a/asdcplib/src/KM_xml.cpp b/asdcplib/src/KM_xml.cpp index 98dccc4b..31124f39 100644 --- a/asdcplib/src/KM_xml.cpp +++ b/asdcplib/src/KM_xml.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2010, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_xml.cpp - \version $Id: KM_xml.cpp,v 1.19 2011/12/01 18:42:39 jhurst Exp $ + \version $Id: KM_xml.cpp,v 1.28 2015/08/25 19:03:38 jhurst Exp $ \brief XML writer */ @@ -61,13 +61,13 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. XERCES_CPP_NAMESPACE_USE -namespace Kumu { - void init_xml_dom(); - typedef std::basic_string<XMLCh> XercesString; - bool UTF_8_to_XercesString(const std::string& in_str, XercesString& out_str); - bool UTF_8_to_XercesString(const char* in_str, XercesString& out_str); - bool XercesString_to_UTF_8(const XercesString& in_str, std::string& out_str); - bool XercesString_to_UTF_8(const XMLCh* in_str, std::string& out_str); +extern "C" +{ + void kumu_init_xml_dom(); + bool kumu_UTF_8_to_XercesString(const std::string& in_str, std::basic_string<XMLCh>& out_str); + bool kumu_UTF_8_to_XercesString_p(const char* in_str, std::basic_string<XMLCh>& out_str); + bool kumu_XercesString_to_UTF_8(const std::basic_string<XMLCh>& in_str, std::string& out_str); + bool kumu_XercesString_to_UTF_8_p(const XMLCh* in_str, std::string& out_str); } #endif @@ -186,10 +186,10 @@ Kumu::XMLElement::AddComment(const char* value) // void -Kumu::XMLElement::Render(std::string& outbuf) const +Kumu::XMLElement::Render(std::string& outbuf, const bool& pretty) const { outbuf = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; - RenderElement(outbuf, 0); + RenderElement(outbuf, 0, pretty); } // @@ -202,15 +202,18 @@ add_spacer(std::string& outbuf, i32_t depth) // void -Kumu::XMLElement::RenderElement(std::string& outbuf, ui32_t depth) const +Kumu::XMLElement::RenderElement(std::string& outbuf, const ui32_t& depth, const bool& pretty) const { - add_spacer(outbuf, depth); + if ( pretty ) + { + add_spacer(outbuf, depth); + } outbuf += "<"; outbuf += m_Name; // render attributes - for ( Attr_i i = m_AttrList.begin(); i != m_AttrList.end(); i++ ) + for ( Attr_i i = m_AttrList.begin(); i != m_AttrList.end(); ++i ) { outbuf += " "; outbuf += (*i).name; @@ -228,12 +231,19 @@ Kumu::XMLElement::RenderElement(std::string& outbuf, ui32_t depth) const // render body if ( m_Body.length() > 0 ) - outbuf += m_Body; + { + outbuf += m_Body; + } - for ( Elem_i i = m_ChildList.begin(); i != m_ChildList.end(); i++ ) - (*i)->RenderElement(outbuf, depth + 1); + for ( Elem_i i = m_ChildList.begin(); i != m_ChildList.end(); ++i ) + { + (*i)->RenderElement(outbuf, depth + 1, pretty); + } - add_spacer(outbuf, depth); + if ( pretty ) + { + add_spacer(outbuf, depth); + } } else if ( m_Body.length() > 0 ) { @@ -389,6 +399,20 @@ Kumu::XMLElement::ParseString(const std::string& document) return ParseString(document.c_str(), document.size()); } +// +bool +Kumu::XMLElement::ParseFirstFromString(const ByteString& document) +{ + return ParseFirstFromString((const char*)document.RoData(), document.Length()); +} + +// +bool +Kumu::XMLElement::ParseFirstFromString(const std::string& document) +{ + return ParseFirstFromString(document.c_str(), document.size()); +} + //---------------------------------------------------------------------------------------------------- @@ -515,6 +539,11 @@ xph_namespace_start(void* p, const XML_Char* ns_prefix, const XML_Char* ns_name) bool Kumu::XMLElement::ParseString(const char* document, ui32_t doc_len) { + if ( doc_len == 0 ) + { + return false; + } + XML_Parser Parser = XML_ParserCreateNS("UTF-8", '|'); if ( Parser == 0 ) @@ -531,55 +560,43 @@ Kumu::XMLElement::ParseString(const char* document, ui32_t doc_len) if ( ! XML_Parse(Parser, document, doc_len, 1) ) { - XML_ParserFree(Parser); DefaultLogSink().Error("XML Parse error on line %d: %s\n", XML_GetCurrentLineNumber(Parser), XML_ErrorString(XML_GetErrorCode(Parser))); + XML_ParserFree(Parser); return false; } XML_ParserFree(Parser); if ( ! Ctx.Namespaces->empty() ) - m_NamespaceOwner = (void*)Ctx.Namespaces; + { + m_NamespaceOwner = (void*)Ctx.Namespaces; + } return true; } -//------------------------------------------------------------------------------------------ - -struct xph_test_wrapper -{ - XML_Parser Parser; - bool Status; - - xph_test_wrapper(XML_Parser p) : Parser(p), Status(false) {} -}; - -// expat wrapper functions, map callbacks to IASAXHandler +// expat wrapper functions // static void -xph_test_start(void* p, const XML_Char*, const XML_Char**) +xph_start_one_shot(void* p, const XML_Char* name, const XML_Char** attrs) { - assert(p); - xph_test_wrapper* Wrapper = (xph_test_wrapper*)p; - - Wrapper->Status = true; - XML_StopParser(Wrapper->Parser, false); + xph_start(p, name, attrs); + XML_Parser parser = (XML_Parser)p; + XML_StopParser(parser, false); } - // bool -Kumu::StringIsXML(const char* document, ui32_t len) +Kumu::XMLElement::ParseFirstFromString(const char* document, ui32_t doc_len) { - if ( document == 0 ) - return false; - - if ( len == 0 ) - len = strlen(document); + if ( doc_len == 0 ) + { + return false; + } - XML_Parser Parser = XML_ParserCreate("UTF-8"); + XML_Parser Parser = XML_ParserCreateNS("UTF-8", '|'); if ( Parser == 0 ) { @@ -587,15 +604,33 @@ Kumu::StringIsXML(const char* document, ui32_t len) return false; } - xph_test_wrapper Wrapper(Parser); - XML_SetUserData(Parser, (void*)&Wrapper); - XML_SetStartElementHandler(Parser, xph_test_start); + ExpatParseContext Ctx(this); + XML_SetUserData(Parser, (void*)&Ctx); + XML_SetElementHandler(Parser, xph_start_one_shot, xph_end); + XML_SetCharacterDataHandler(Parser, xph_char); + XML_SetStartNamespaceDeclHandler(Parser, xph_namespace_start); + + if ( ! XML_Parse(Parser, document, doc_len, 1) ) + { + DefaultLogSink().Error("XML Parse error on line %d: %s\n", + XML_GetCurrentLineNumber(Parser), + XML_ErrorString(XML_GetErrorCode(Parser))); + XML_ParserFree(Parser); + return false; + } - XML_Parse(Parser, document, len, 1); XML_ParserFree(Parser); - return Wrapper.Status; + + if ( ! Ctx.Namespaces->empty() ) + { + m_NamespaceOwner = (void*)Ctx.Namespaces; + } + + return true; } + + #endif //---------------------------------------------------------------------------------------------------- @@ -616,7 +651,7 @@ static const XMLCh sg_label_UTF_8[] = { chLatin_U, chLatin_T, chLatin_F, // void -Kumu::init_xml_dom() +kumu_init_xml_dom() { if ( ! sg_xml_init ) { @@ -656,13 +691,13 @@ Kumu::init_xml_dom() // bool -Kumu::XercesString_to_UTF_8(const Kumu::XercesString& in_str, std::string& out_str) { - return XercesString_to_UTF_8(in_str.c_str(), out_str); +kumu_XercesString_to_UTF_8(const std::basic_string<XMLCh>& in_str, std::string& out_str) { + return kumu_XercesString_to_UTF_8_p(in_str.c_str(), out_str); } // bool -Kumu::XercesString_to_UTF_8(const XMLCh* in_str, std::string& out_str) +kumu_XercesString_to_UTF_8_p(const XMLCh* in_str, std::string& out_str) { assert(in_str); assert(sg_xml_init); @@ -699,13 +734,13 @@ Kumu::XercesString_to_UTF_8(const XMLCh* in_str, std::string& out_str) // bool -Kumu::UTF_8_to_XercesString(const std::string& in_str, Kumu::XercesString& out_str) { - return UTF_8_to_XercesString(in_str.c_str(), out_str); +kumu_UTF_8_to_XercesString(const std::string& in_str, std::basic_string<XMLCh>& out_str) { + return kumu_UTF_8_to_XercesString_p(in_str.c_str(), out_str); } // bool -Kumu::UTF_8_to_XercesString(const char* in_str, Kumu::XercesString& out_str) +kumu_UTF_8_to_XercesString_p(const char* in_str, std::basic_string<XMLCh>& out_str) { assert(in_str); assert(sg_xml_init); @@ -787,7 +822,7 @@ public: ns_prefix = ""; } - ns_map::iterator ni = m_Namespaces->find(ns_name); + ns_map::iterator ni = m_Namespaces->find(ns_prefix); if ( ni != m_Namespaces->end() ) { @@ -813,7 +848,7 @@ public: assert(x_name); std::string tx_name; - if ( ! XercesString_to_UTF_8(x_name, tx_name) ) + if ( ! kumu_XercesString_to_UTF_8(x_name, tx_name) ) m_HasEncodeErrors = true; const char* name = tx_name.c_str(); @@ -843,10 +878,10 @@ public: for ( ui32_t i = 0; i < a_len; i++) { std::string aname, value; - if ( ! XercesString_to_UTF_8(attributes.getName(i), aname) ) + if ( ! kumu_XercesString_to_UTF_8(attributes.getName(i), aname) ) m_HasEncodeErrors = true; - if ( ! XercesString_to_UTF_8(attributes.getValue(i), value) ) + if ( ! kumu_XercesString_to_UTF_8(attributes.getValue(i), value) ) m_HasEncodeErrors = true; const char* x_aname = aname.c_str(); @@ -882,7 +917,7 @@ public: if ( length > 0 ) { std::string tmp; - if ( ! XercesString_to_UTF_8(chars, tmp) ) + if ( ! kumu_XercesString_to_UTF_8(chars, tmp) ) m_HasEncodeErrors = true; m_Scope.top()->AppendBody(tmp); @@ -895,9 +930,11 @@ bool Kumu::XMLElement::ParseString(const char* document, ui32_t doc_len) { if ( doc_len == 0 ) - return false; + { + return false; + } - init_xml_dom(); + kumu_init_xml_dom(); int errorCount = 0; SAXParser* parser = new SAXParser(); @@ -948,37 +985,69 @@ Kumu::XMLElement::ParseString(const char* document, ui32_t doc_len) // bool -Kumu::StringIsXML(const char* document, ui32_t len) +Kumu::XMLElement::ParseFirstFromString(const char* document, ui32_t doc_len) { - if ( document == 0 || *document == 0 ) - return false; + if ( doc_len == 0 ) + { + return false; + } - init_xml_dom(); + kumu_init_xml_dom(); + + int errorCount = 0; + SAXParser* parser = new SAXParser(); - if ( len == 0 ) - len = strlen(document); + parser->setValidationScheme(SAXParser::Val_Always); + parser->setDoNamespaces(true); // optional - SAXParser parser; + MyTreeHandler* docHandler = new MyTreeHandler(this); + parser->setDocumentHandler(docHandler); + parser->setErrorHandler(docHandler); XMLPScanToken token; - bool status = false; try { MemBufInputSource xmlSource(reinterpret_cast<const XMLByte*>(document), - static_cast<const unsigned int>(len), + static_cast<const unsigned int>(doc_len), "pidc_rules_file"); - if ( parser.parseFirst(xmlSource, token) ) + if ( ! parser->parseFirst(xmlSource, token) ) { - if ( parser.parseNext(token) ) - status = true; + ++errorCount; + } + + if ( ! parser->parseNext(token) ) + { + ++errorCount; } } + catch (const XMLException& e) + { + char* message = XMLString::transcode(e.getMessage()); + DefaultLogSink().Error("Parser error: %s\n", message); + XMLString::release(&message); + errorCount++; + } + catch (const SAXParseException& e) + { + char* message = XMLString::transcode(e.getMessage()); + DefaultLogSink().Error("Parser error: %s at line %d\n", message, e.getLineNumber()); + XMLString::release(&message); + errorCount++; + } catch (...) { + DefaultLogSink().Error("Unexpected XML parser error\n"); + errorCount++; } - return status; + if ( errorCount == 0 ) + m_NamespaceOwner = (void*)docHandler->TakeNamespaceMap(); + + delete parser; + delete docHandler; + + return errorCount > 0 ? false : true; } @@ -990,15 +1059,14 @@ Kumu::StringIsXML(const char* document, ui32_t len) // bool -Kumu::XMLElement::ParseString(const char*, ui32_t) +Kumu::XMLElement::ParseString(const char* document, ui32_t doc_len) { DefaultLogSink().Error("Kumu compiled without XML parser support.\n"); return false; } -// bool -Kumu::StringIsXML(const char*, ui32_t) +Kumu::XMLElement::ParseFirstFromString(const char* document, ui32_t doc_len) { DefaultLogSink().Error("Kumu compiled without XML parser support.\n"); return false; @@ -1007,6 +1075,50 @@ Kumu::StringIsXML(const char*, ui32_t) #endif +//---------------------------------------------------------------------------------------------------- + +// +bool +Kumu::GetXMLDocType(const ByteString& buf, std::string& ns_prefix, std::string& type_name, std::string& namespace_name, + AttributeList& doc_attr_list) +{ + return GetXMLDocType(buf.RoData(), buf.Length(), ns_prefix, type_name, namespace_name, doc_attr_list); +} + +// +bool +Kumu::GetXMLDocType(const std::string& buf, std::string& ns_prefix, std::string& type_name, std::string& namespace_name, + AttributeList& doc_attr_list) +{ + return GetXMLDocType((const byte_t*)buf.c_str(), buf.size(), ns_prefix, type_name, namespace_name, doc_attr_list); +} + +// +bool +Kumu::GetXMLDocType(const byte_t* buf, ui32_t buf_len, std::string& ns_prefix, std::string& type_name, std::string& namespace_name, + AttributeList& doc_attr_list) +{ + XMLElement tmp_element("tmp"); + + if ( ! tmp_element.ParseFirstFromString((const char*)buf, buf_len) ) + { + return false; + } + + const XMLNamespace* ns = tmp_element.Namespace(); + + if ( ns != 0 ) + { + ns_prefix = ns->Prefix(); + namespace_name = ns->Name(); + } + + type_name = tmp_element.GetName(); + doc_attr_list = tmp_element.GetAttributes(); + return true; +} + + // // end KM_xml.cpp // diff --git a/asdcplib/src/KM_xml.h b/asdcplib/src/KM_xml.h index cf77366a..695b4863 100644 --- a/asdcplib/src/KM_xml.h +++ b/asdcplib/src/KM_xml.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2011, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file KM_xml.h - \version $Id: KM_xml.h,v 1.8 2011/08/15 23:03:26 jhurst Exp $ + \version $Id: KM_xml.h,v 1.11 2015/02/19 19:06:57 jhurst Exp $ \brief XML writer */ @@ -41,9 +41,6 @@ namespace Kumu { class XMLElement; - // Return true if the given string contains an XML document (or the start of one). - bool StringIsXML(const char* document, ui32_t len = 0); - // struct NVPair { @@ -57,6 +54,15 @@ namespace Kumu typedef std::list<XMLElement*> ElementList; typedef ElementList::const_iterator Elem_i; + bool GetXMLDocType(const ByteString& buf, std::string& ns_prefix, std::string& type_name, + std::string& namespace_name, AttributeList& doc_attr_list); + + bool GetXMLDocType(const std::string& buf, std::string& ns_prefix, std::string& type_name, + std::string& namespace_name, AttributeList& doc_attr_list); + + bool GetXMLDocType(const byte_t* buf, ui32_t buf_len, std::string& ns_prefix, std::string& type_name, + std::string& namespace_name, AttributeList& doc_attr_list); + // class XMLNamespace { @@ -100,6 +106,10 @@ namespace Kumu bool ParseString(const ByteString& document); bool ParseString(const std::string& document); + bool ParseFirstFromString(const char* document, ui32_t doc_len); + bool ParseFirstFromString(const ByteString& document); + bool ParseFirstFromString(const std::string& document); + // building void SetName(const char* name); void SetBody(const std::string& value); @@ -112,8 +122,9 @@ namespace Kumu XMLElement* AddChildWithContent(const char* name, const std::string& value); XMLElement* AddChildWithPrefixedContent(const char* name, const char* prefix, const char* value); void AddComment(const char* value); - void Render(std::string&) const; - void RenderElement(std::string& outbuf, ui32_t depth) const; + void Render(std::string& str) const { Render(str, true); } + void Render(std::string&, const bool& pretty) const; + void RenderElement(std::string& outbuf, const ui32_t& depth, const bool& pretty) const; // querying inline const std::string& GetBody() const { return m_Body; } diff --git a/asdcplib/src/MDD.cpp b/asdcplib/src/MDD.cpp index ac8f0dd9..e70d662f 100644 --- a/asdcplib/src/MDD.cpp +++ b/asdcplib/src/MDD.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2006-2012, John Hurst +Copyright (c) 2006-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file MDD.[h|cpp] - \version $Id: MDD.cpp,v 1.34 2012/02/02 01:58:43 jhurst Exp $ + \version $Id: MDD.cpp,v 1.49 2015/04/21 03:55:31 jhurst Exp $ \brief MXF Metadata Dictionary */ // @@ -37,151 +37,151 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "MICAlgorithm_NONE" }, + {0}, false, "MICAlgorithm_NONE" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 1 0x0d, 0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00 }, - {0, 0}, false, "MXFInterop_OPAtom" }, + {0}, false, "MXFInterop_OPAtom" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02, // 2 0x0d, 0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00 }, - {0, 0}, false, "OPAtom" }, + {0}, false, "OPAtom" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 3 0x0d, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00 }, - {0, 0}, false, "OP1a" }, + {0}, false, "OP1a" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x03, // 4 0x0d, 0x01, 0x03, 0x01, 0x02, 0x7f, 0x01, 0x00 }, - {0, 0}, false, "GCMulti" }, + {0}, false, "GCMulti" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 5 0x01, 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PictureDataDef" }, + {0}, false, "PictureDataDef" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 6 0x01, 0x03, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00 }, - {0, 0}, false, "SoundDataDef" }, + {0}, false, "SoundDataDef" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 7 0x01, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "TimecodeDataDef" }, + {0}, false, "TimecodeDataDef" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 8 0x01, 0x03, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00 }, - {0, 0}, false, "DescriptiveMetaDataDef" }, + {0}, false, "DescriptiveMetaDataDef" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 9 0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x01, 0x00 }, - {0, 0}, false, "WAVWrapping" }, + {0}, false, "WAVWrappingFrame" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02, // 10 0x0d, 0x01, 0x03, 0x01, 0x02, 0x04, 0x60, 0x00 }, - {0, 0}, false, "MPEG2_VESWrapping" }, + {0}, false, "MPEG2_VESWrappingFrame" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07, // 11 0x0d, 0x01, 0x03, 0x01, 0x02, 0x0c, 0x01, 0x00 }, - {0, 0}, false, "JPEG_2000Wrapping" }, + {0}, false, "JPEG_2000WrappingFrame" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 12 0x0d, 0x01, 0x03, 0x01, 0x15, 0x01, 0x08, 0x00 }, - {0, 0}, false, "JPEG2000Essence" }, + {0}, false, "JPEG2000Essence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 13 0x0d, 0x01, 0x03, 0x01, 0x15, 0x01, 0x05, 0x00 }, - {0, 0}, false, "MPEG2Essence" }, + {0}, false, "MPEG2Essence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x04, 0x01, 0x07, // 14 0x0d, 0x01, 0x03, 0x01, 0x02, 0x7e, 0x01, 0x00 }, - {0, 0}, false, "MXFInterop_CryptEssence" }, + {0}, false, "MXFInterop_CryptEssence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x04, 0x01, 0x01, // 15 0x0d, 0x01, 0x03, 0x01, 0x02, 0x7e, 0x01, 0x00 }, - {0, 0}, false, "CryptEssence" }, + {0}, false, "CryptEssence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 16 0x0d, 0x01, 0x03, 0x01, 0x16, 0x01, 0x01, 0x00 }, - {0, 0}, false, "WAVEssence" }, + {0}, false, "WAVEssence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x09, // 17 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x03 }, - {0, 0}, false, "JP2KEssenceCompression_2K" }, + {0}, false, "JP2KEssenceCompression_2K" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x09, // 18 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x04 }, - {0, 0}, false, "JP2KEssenceCompression_4K" }, + {0}, false, "JP2KEssenceCompression_4K" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07, // 19 0x02, 0x09, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "CipherAlgorithm_AES" }, + {0}, false, "CipherAlgorithm_AES" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07, // 20 0x02, 0x09, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "MICAlgorithm_HMAC_SHA1" }, + {0}, false, "MICAlgorithm_HMAC_SHA1" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 21 0x03, 0x01, 0x02, 0x10, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "KLVFill" }, + {0}, false, "KLVFill" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 22 0x03, 0x01, 0x02, 0x01, 0x06, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_MajorVersion" }, + {0}, false, "PartitionMetadata_MajorVersion" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 23 0x03, 0x01, 0x02, 0x01, 0x07, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_MinorVersion" }, + {0}, false, "PartitionMetadata_MinorVersion" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 24 0x03, 0x01, 0x02, 0x01, 0x09, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_KAGSize" }, + {0}, false, "PartitionMetadata_KAGSize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 25 0x06, 0x10, 0x10, 0x03, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_ThisPartition" }, + {0}, false, "PartitionMetadata_ThisPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 26 0x06, 0x10, 0x10, 0x02, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_PreviousPartition" }, + {0}, false, "PartitionMetadata_PreviousPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 27 0x06, 0x10, 0x10, 0x05, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_FooterPartition" }, + {0}, false, "PartitionMetadata_FooterPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 28 0x04, 0x06, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_HeaderByteCount" }, + {0}, false, "PartitionMetadata_HeaderByteCount" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 29 0x04, 0x06, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_IndexByteCount" }, + {0}, false, "PartitionMetadata_IndexByteCount" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 30 0x01, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_IndexSID" }, + {0}, false, "PartitionMetadata_IndexSID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 31 0x06, 0x08, 0x01, 0x02, 0x01, 0x03, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_BodyOffset" }, + {0}, false, "PartitionMetadata_BodyOffset" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 32 0x01, 0x03, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_BodySID" }, + {0}, false, "PartitionMetadata_BodySID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 33 0x01, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_OperationalPattern" }, + {0}, false, "PartitionMetadata_OperationalPattern" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 34 0x01, 0x02, 0x02, 0x10, 0x02, 0x01, 0x00, 0x00 }, - {0, 0}, false, "PartitionMetadata_EssenceContainers" }, + {0}, false, "PartitionMetadata_EssenceContainers" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 35 0x0d, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x00 }, - {0, 0}, false, "OpenHeader" }, + {0}, false, "OpenHeader" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 36 0x0d, 0x01, 0x02, 0x01, 0x01, 0x02, 0x03, 0x00 }, - {0, 0}, false, "OpenCompleteHeader" }, + {0}, false, "OpenCompleteHeader" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 37 0x0d, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00 }, - {0, 0}, false, "ClosedHeader" }, + {0}, false, "ClosedHeader" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 38 0x0d, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 0x00 }, - {0, 0}, false, "ClosedCompleteHeader" }, + {0}, false, "ClosedCompleteHeader" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 39 0x0d, 0x01, 0x02, 0x01, 0x01, 0x03, 0x01, 0x00 }, - {0, 0}, false, "OpenBodyPartition" }, + {0}, false, "OpenBodyPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 40 0x0d, 0x01, 0x02, 0x01, 0x01, 0x03, 0x03, 0x00 }, - {0, 0}, false, "OpenCompleteBodyPartition" }, + {0}, false, "OpenCompleteBodyPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 41 0x0d, 0x01, 0x02, 0x01, 0x01, 0x03, 0x02, 0x00 }, - {0, 0}, false, "ClosedBodyPartition" }, + {0}, false, "ClosedBodyPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 42 0x0d, 0x01, 0x02, 0x01, 0x01, 0x03, 0x04, 0x00 }, - {0, 0}, false, "ClosedCompleteBodyPartition" }, + {0}, false, "ClosedCompleteBodyPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 43 0x0d, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x00 }, - {0, 0}, false, "Footer" }, + {0}, false, "Footer" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 44 0x0d, 0x01, 0x02, 0x01, 0x01, 0x04, 0x04, 0x00 }, - {0, 0}, false, "CompleteFooter" }, + {0}, false, "CompleteFooter" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 45 0x0d, 0x01, 0x02, 0x01, 0x01, 0x05, 0x01, 0x00 }, - {0, 0}, false, "Primer" }, + {0}, false, "Primer" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 46 0x06, 0x01, 0x01, 0x07, 0x15, 0x00, 0x00, 0x00 }, - {0, 0}, false, "Primer_LocalTagEntryBatch" }, + {0}, false, "Primer_LocalTagEntryBatch" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 47 0x01, 0x03, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "LocalTagEntryBatch_Primer_LocalTag" }, + {0}, false, "LocalTagEntryBatch_Primer_LocalTag" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 48 0x01, 0x03, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "LocalTagEntryBatch_Primer_UID" }, + {0}, false, "LocalTagEntryBatch_Primer_UID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, // 49 0x01, 0x01, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00 }, {0x3c, 0x0a}, false, "InterchangeObject_InstanceUID" }, @@ -190,7 +190,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x01, 0x02}, true, "GenerationInterchangeObject_GenerationUID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 51 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "DefaultObject" }, + {0}, false, "DefaultObject" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 52 0x05, 0x30, 0x04, 0x06, 0x00, 0x00, 0x00, 0x00 }, {0x3f, 0x0b}, false, "IndexTableSegmentBase_IndexEditRate" }, @@ -217,58 +217,58 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x3f, 0x0e}, true, "IndexTableSegmentBase_PosTableCount" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 60 0x0d, 0x01, 0x02, 0x01, 0x01, 0x10, 0x01, 0x00 }, - {0, 0}, false, "IndexTableSegment" }, + {0}, false, "IndexTableSegment" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 61 0x04, 0x04, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00 }, {0x3f, 0x09}, true, "IndexTableSegment_DeltaEntryArray" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 62 0x04, 0x04, 0x04, 0x01, 0x04, 0x00, 0x00, 0x00 }, - {0, 0}, false, "DeltaEntryArray_IndexTableSegment_PosTableIndex" }, + {0}, false, "DeltaEntryArray_IndexTableSegment_PosTableIndex" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 63 0x04, 0x04, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00 }, - {0, 0}, false, "DeltaEntryArray_IndexTableSegment_Slice" }, + {0}, false, "DeltaEntryArray_IndexTableSegment_Slice" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 64 0x04, 0x04, 0x04, 0x01, 0x03, 0x00, 0x00, 0x00 }, - {0, 0}, false, "DeltaEntryArray_IndexTableSegment_ElementDelta" }, + {0}, false, "DeltaEntryArray_IndexTableSegment_ElementDelta" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 65 0x04, 0x04, 0x04, 0x02, 0x05, 0x00, 0x00, 0x00 }, {0x3f, 0x0a}, false, "IndexTableSegment_IndexEntryArray" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 66 0x04, 0x04, 0x04, 0x02, 0x03, 0x00, 0x00, 0x00 }, - {0, 0}, false, "IndexEntryArray_IndexTableSegment_TemporalOffset" }, + {0}, false, "IndexEntryArray_IndexTableSegment_TemporalOffset" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 67 0x04, 0x04, 0x04, 0x02, 0x04, 0x00, 0x00, 0x00 }, - {0, 0}, false, "IndexEntryArray_IndexTableSegment_AnchorOffset" }, + {0}, false, "IndexEntryArray_IndexTableSegment_AnchorOffset" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 68 0x04, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00 }, - {0, 0}, false, "IndexEntryArray_IndexTableSegment_Flags" }, + {0}, false, "IndexEntryArray_IndexTableSegment_Flags" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 69 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "IndexEntryArray_IndexTableSegment_StreamOffset" }, + {0}, false, "IndexEntryArray_IndexTableSegment_StreamOffset" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 70 0x04, 0x04, 0x04, 0x01, 0x05, 0x00, 0x00, 0x00 }, - {0, 0}, false, "IndexEntryArray_IndexTableSegment_SliceOffsetArray" }, + {0}, false, "IndexEntryArray_IndexTableSegment_SliceOffsetArray" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 71 0x04, 0x04, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00 }, - {0, 0}, false, "IndexEntryArray_IndexTableSegment_PosTableArray" }, + {0}, false, "IndexEntryArray_IndexTableSegment_PosTableArray" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 72 0x0d, 0x01, 0x02, 0x01, 0x01, 0x11, 0x01, 0x00 }, - {0, 0}, false, "RandomIndexMetadata" }, + {0}, false, "RandomIndexMetadata" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 73 0x01, 0x03, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionArray_RandomIndexMetadata_BodySID" }, + {0}, false, "PartitionArray_RandomIndexMetadata_BodySID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 74 0x06, 0x09, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "PartitionArray_RandomIndexMetadata_ByteOffset" }, + {0}, false, "PartitionArray_RandomIndexMetadata_ByteOffset" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 75 0x04, 0x06, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "RandomIndexMetadata_Length" }, + {0}, false, "RandomIndexMetadata_Length" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 76 0x0d, 0x01, 0x02, 0x01, 0x01, 0x11, 0x00, 0x00 }, - {0, 0}, false, "RandomIndexMetadataV10" }, + {0}, false, "RandomIndexMetadataV10" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 77 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2f, 0x00 }, - {0, 0}, false, "Preface" }, + {0}, false, "Preface" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 78 0x07, 0x02, 0x01, 0x10, 0x02, 0x04, 0x00, 0x00 }, {0x3b, 0x02}, false, "Preface_LastModifiedDate" }, @@ -298,7 +298,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x3b, 0x0b}, false, "Preface_DMSchemes" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 87 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x30, 0x00 }, - {0, 0}, false, "Identification" }, + {0}, false, "Identification" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 88 0x05, 0x20, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00 }, {0x3c, 0x09}, false, "Identification_ThisGenerationUID" }, @@ -328,7 +328,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x3c, 0x08}, true, "Identification_Platform" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 97 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, 0x00 }, - {0, 0}, false, "ContentStorage" }, + {0}, false, "ContentStorage" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 98 0x06, 0x01, 0x01, 0x04, 0x05, 0x01, 0x00, 0x00 }, {0x19, 0x01}, false, "ContentStorage_Packages" }, @@ -340,7 +340,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x19, 0x01}, false, "ContentStorageKludge_V10Packages" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 101 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x23, 0x00 }, - {0, 0}, false, "EssenceContainerData" }, + {0}, false, "EssenceContainerData" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 102 0x06, 0x01, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00 }, {0x27, 0x01}, false, "EssenceContainerData_LinkedPackageUID" }, @@ -367,13 +367,13 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x44, 0x03}, false, "GenericPackage_Tracks" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 110 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x32, 0x00 }, - {0, 0}, false, "NetworkLocator" }, + {0}, false, "NetworkLocator" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, // 111 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 }, {0x40, 0x01}, false, "NetworkLocator_URLString" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 112 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x33, 0x00 }, - {0, 0}, false, "TextLocator" }, + {0}, false, "TextLocator" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 113 0x01, 0x04, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00 }, {0x41, 0x01}, false, "TextLocator_LocatorName" }, @@ -391,10 +391,10 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x48, 0x03}, false, "GenericTrack_Sequence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 118 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x3a, 0x00 }, - {0, 0}, false, "StaticTrack" }, + {0}, false, "StaticTrack" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 119 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x3b, 0x00 }, - {0, 0}, false, "Track" }, + {0}, false, "Track" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 120 0x05, 0x30, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00 }, {0x4b, 0x01}, false, "Track_EditRate" }, @@ -403,7 +403,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x4b, 0x02}, false, "Track_Origin" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 122 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x39, 0x00 }, - {0, 0}, false, "EventTrack" }, + {0}, false, "EventTrack" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 123 0x05, 0x30, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00 }, {0x49, 0x01}, false, "EventTrack_EventEditRate" }, @@ -418,13 +418,13 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x02, 0x02}, false, "StructuralComponent_Duration" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 127 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x00 }, - {0, 0}, false, "Sequence" }, + {0}, false, "Sequence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 128 0x06, 0x01, 0x01, 0x04, 0x06, 0x09, 0x00, 0x00 }, {0x10, 0x01}, false, "Sequence_StructuralComponents" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 129 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x14, 0x00 }, - {0, 0}, false, "TimecodeComponent" }, + {0}, false, "TimecodeComponent" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 130 0x04, 0x04, 0x01, 0x01, 0x02, 0x06, 0x00, 0x00 }, {0x15, 0x02}, false, "TimecodeComponent_RoundedTimecodeBase" }, @@ -436,7 +436,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x15, 0x03}, false, "TimecodeComponent_DropFrame" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 133 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, 0x00 }, - {0, 0}, false, "SourceClip" }, + {0}, false, "SourceClip" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 134 0x07, 0x02, 0x01, 0x03, 0x01, 0x04, 0x00, 0x00 }, {0x12, 0x01}, false, "SourceClip_StartPosition" }, @@ -448,7 +448,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x11, 0x02}, false, "SourceClip_SourceTrackID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 137 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x41, 0x00 }, - {0, 0}, false, "DMSegment" }, + {0}, false, "DMSegment" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 138 0x07, 0x02, 0x01, 0x03, 0x03, 0x03, 0x00, 0x00 }, {0x06, 0x01}, false, "DMSegment_EventStartPosition" }, @@ -463,16 +463,16 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x61, 0x01}, false, "DMSegment_DMFramework" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 142 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x45, 0x00 }, - {0, 0}, false, "DMSourceClip" }, + {0}, false, "DMSourceClip" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 143 0x01, 0x07, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00 }, {0x61, 0x03}, true, "DMSourceClip_DMSourceClipTrackIDs" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 144 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x36, 0x00 }, - {0, 0}, false, "MaterialPackage" }, + {0}, false, "MaterialPackage" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 145 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x37, 0x00 }, - {0, 0}, false, "SourcePackage" }, + {0}, false, "SourcePackage" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 146 0x06, 0x01, 0x01, 0x04, 0x02, 0x03, 0x00, 0x00 }, {0x47, 0x01}, false, "SourcePackage_Descriptor" }, @@ -481,10 +481,10 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x2f, 0x01}, true, "GenericDescriptor_Locators" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 148 0x06, 0x01, 0x01, 0x04, 0x06, 0x10, 0x00, 0x00 }, - {0, 0}, true, "GenericDescriptor_SubDescriptors" }, + {0}, true, "GenericDescriptor_SubDescriptors" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 149 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x25, 0x00 }, - {0, 0}, false, "FileDescriptor" }, + {0}, false, "FileDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 150 0x06, 0x01, 0x01, 0x03, 0x05, 0x00, 0x00, 0x00 }, {0x30, 0x06}, true, "FileDescriptor_LinkedTrackID" }, @@ -502,7 +502,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x30, 0x05}, true, "FileDescriptor_Codec" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 155 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x27, 0x00 }, - {0, 0}, false, "GenericPictureEssenceDescriptor" }, + {0}, false, "GenericPictureEssenceDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 156 0x04, 0x05, 0x01, 0x13, 0x00, 0x00, 0x00, 0x00 }, {0x32, 0x15}, true, "GenericPictureEssenceDescriptor_SignalStandard" }, @@ -559,7 +559,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x32, 0x0f}, true, "GenericPictureEssenceDescriptor_AlphaTransparency" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 174 0x04, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x00 }, - {0x32, 0x10}, true, "GenericPictureEssenceDescriptor_Gamma" }, + {0x32, 0x10}, true, "GenericPictureEssenceDescriptor_TransferCharacteristic" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 175 0x04, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 }, {0x32, 0x11}, true, "GenericPictureEssenceDescriptor_ImageAlignmentOffset" }, @@ -577,7 +577,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x32, 0x01}, false, "GenericPictureEssenceDescriptor_PictureEssenceCoding" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 180 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x00 }, - {0, 0}, false, "CDCIEssenceDescriptor" }, + {0}, false, "CDCIEssenceDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 181 0x04, 0x01, 0x05, 0x03, 0x0a, 0x00, 0x00, 0x00 }, {0x33, 0x01}, false, "CDCIEssenceDescriptor_ComponentDepth" }, @@ -610,7 +610,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x33, 0x06}, true, "CDCIEssenceDescriptor_ColorRange" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 191 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x29, 0x00 }, - {0, 0}, false, "RGBAEssenceDescriptor" }, + {0}, false, "RGBAEssenceDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 192 0x04, 0x01, 0x05, 0x03, 0x0b, 0x00, 0x00, 0x00 }, {0x34, 0x06}, true, "RGBAEssenceDescriptor_ComponentMaxRef" }, @@ -637,7 +637,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x34, 0x04}, true, "RGBAEssenceDescriptor_PaletteLayout" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 200 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x42, 0x00 }, - {0, 0}, false, "GenericSoundEssenceDescriptor" }, + {0}, false, "GenericSoundEssenceDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 201 0x04, 0x02, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00 }, {0x3d, 0x03}, false, "GenericSoundEssenceDescriptor_AudioSamplingRate" }, @@ -661,55 +661,55 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x3d, 0x0c}, true, "GenericSoundEssenceDescriptor_DialNorm" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 208 0x04, 0x02, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00 }, - {0x3d, 0x06}, false, "GenericSoundEssenceDescriptor_SoundEssenceCompression" }, + {0x3d, 0x06}, false, "GenericSoundEssenceDescriptor_SoundEssenceCoding" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 209 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x43, 0x00 }, - {0, 0}, false, "GenericDataEssenceDescriptor" }, + {0}, false, "GenericDataEssenceDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 210 0x04, 0x03, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00 }, {0x3e, 0x01}, false, "GenericDataEssenceDescriptor_DataEssenceCoding" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 211 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x44, 0x00 }, - {0, 0}, false, "MultipleDescriptor" }, + {0}, false, "MultipleDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 212 0x06, 0x01, 0x01, 0x04, 0x06, 0x0b, 0x00, 0x00 }, {0x3f, 0x01}, false, "MultipleDescriptor_SubDescriptorUIDs" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 213 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x51, 0x00 }, - {0, 0}, false, "MPEG2VideoDescriptor" }, + {0}, false, "MPEG2VideoDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 214 0x04, 0x01, 0x06, 0x02, 0x01, 0x02, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_SingleSequence" }, + {0}, true, "MPEG2VideoDescriptor_SingleSequence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 215 0x04, 0x01, 0x06, 0x02, 0x01, 0x03, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_ConstantBFrames" }, + {0}, true, "MPEG2VideoDescriptor_ConstantBFrames" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 216 0x04, 0x01, 0x06, 0x02, 0x01, 0x04, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_CodedContentType" }, + {0}, true, "MPEG2VideoDescriptor_CodedContentType" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 217 0x04, 0x01, 0x06, 0x02, 0x01, 0x05, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_LowDelay" }, + {0}, true, "MPEG2VideoDescriptor_LowDelay" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 218 0x04, 0x01, 0x06, 0x02, 0x01, 0x06, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_ClosedGOP" }, + {0}, true, "MPEG2VideoDescriptor_ClosedGOP" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 219 0x04, 0x01, 0x06, 0x02, 0x01, 0x07, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_IdenticalGOP" }, + {0}, true, "MPEG2VideoDescriptor_IdenticalGOP" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 220 0x04, 0x01, 0x06, 0x02, 0x01, 0x08, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_MaxGOP" }, + {0}, true, "MPEG2VideoDescriptor_MaxGOP" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 221 0x04, 0x01, 0x06, 0x02, 0x01, 0x09, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_BPictureCount" }, + {0}, true, "MPEG2VideoDescriptor_BPictureCount" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 222 0x04, 0x01, 0x06, 0x02, 0x01, 0x0b, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_BitRate" }, + {0}, true, "MPEG2VideoDescriptor_BitRate" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 223 0x04, 0x01, 0x06, 0x02, 0x01, 0x0a, 0x00, 0x00 }, - {0, 0}, true, "MPEG2VideoDescriptor_ProfileAndLevel" }, + {0}, true, "MPEG2VideoDescriptor_ProfileAndLevel" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 224 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x48, 0x00 }, - {0, 0}, false, "WaveAudioDescriptor" }, + {0}, false, "WaveAudioDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 225 0x04, 0x02, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00 }, {0x3d, 0x0a}, false, "WaveAudioDescriptor_BlockAlign" }, @@ -724,115 +724,115 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x3d, 0x0e}, true, "WaveAudioDescriptor_PeakEnvelope" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 229 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x5a, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor" }, + {0}, false, "JPEG2000PictureSubDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 230 0x04, 0x01, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_Rsize" }, + {0}, false, "JPEG2000PictureSubDescriptor_Rsize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 231 0x04, 0x01, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_Xsize" }, + {0}, false, "JPEG2000PictureSubDescriptor_Xsize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 232 0x04, 0x01, 0x06, 0x03, 0x03, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_Ysize" }, + {0}, false, "JPEG2000PictureSubDescriptor_Ysize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 233 0x04, 0x01, 0x06, 0x03, 0x04, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_XOsize" }, + {0}, false, "JPEG2000PictureSubDescriptor_XOsize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 234 0x04, 0x01, 0x06, 0x03, 0x05, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_YOsize" }, + {0}, false, "JPEG2000PictureSubDescriptor_YOsize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 235 0x04, 0x01, 0x06, 0x03, 0x06, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_XTsize" }, + {0}, false, "JPEG2000PictureSubDescriptor_XTsize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 236 0x04, 0x01, 0x06, 0x03, 0x07, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_YTsize" }, + {0}, false, "JPEG2000PictureSubDescriptor_YTsize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 237 0x04, 0x01, 0x06, 0x03, 0x08, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_XTOsize" }, + {0}, false, "JPEG2000PictureSubDescriptor_XTOsize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 238 0x04, 0x01, 0x06, 0x03, 0x09, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_YTOsize" }, + {0}, false, "JPEG2000PictureSubDescriptor_YTOsize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 239 0x04, 0x01, 0x06, 0x03, 0x0a, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_Csize" }, + {0}, false, "JPEG2000PictureSubDescriptor_Csize" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 240 0x04, 0x01, 0x06, 0x03, 0x0b, 0x00, 0x00, 0x00 }, - {0, 0}, false, "JPEG2000PictureSubDescriptor_PictureComponentSizing" }, + {0}, false, "JPEG2000PictureSubDescriptor_PictureComponentSizing" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 241 0x04, 0x01, 0x06, 0x03, 0x0c, 0x00, 0x00, 0x00 }, - {0, 0}, true, "JPEG2000PictureSubDescriptor_CodingStyleDefault" }, + {0}, true, "JPEG2000PictureSubDescriptor_CodingStyleDefault" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0a, // 242 0x04, 0x01, 0x06, 0x03, 0x0d, 0x00, 0x00, 0x00 }, - {0, 0}, true, "JPEG2000PictureSubDescriptor_QuantizationDefault" }, + {0}, true, "JPEG2000PictureSubDescriptor_QuantizationDefault" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 243 0x0d, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "DM_Framework" }, + {0}, false, "DM_Framework" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 244 0x0d, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "DM_Set" }, + {0}, false, "DM_Set" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07, // 245 0x0d, 0x01, 0x03, 0x01, 0x02, 0x0b, 0x01, 0x00 }, - {0, 0}, false, "EncryptedContainerLabel" }, + {0}, false, "EncryptedContainerLabel" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07, // 246 0x0d, 0x01, 0x04, 0x01, 0x02, 0x01, 0x01, 0x00 }, - {0, 0}, false, "CryptographicFrameworkLabel" }, + {0}, false, "CryptographicFrameworkLabel" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 247 0x0d, 0x01, 0x04, 0x01, 0x02, 0x01, 0x00, 0x00 }, - {0, 0}, false, "CryptographicFramework" }, + {0}, false, "CryptographicFramework" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 248 0x06, 0x01, 0x01, 0x04, 0x02, 0x0d, 0x00, 0x00 }, - {0, 0}, false, "CryptographicFramework_ContextSR" }, + {0}, false, "CryptographicFramework_ContextSR" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 249 0x0d, 0x01, 0x04, 0x01, 0x02, 0x02, 0x00, 0x00 }, - {0, 0}, false, "CryptographicContext" }, + {0}, false, "CryptographicContext" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 250 0x01, 0x01, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "CryptographicContext_ContextID" }, + {0}, false, "CryptographicContext_ContextID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 251 0x06, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00 }, - {0, 0}, false, "CryptographicContext_SourceEssenceContainer" }, + {0}, false, "CryptographicContext_SourceEssenceContainer" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 252 0x02, 0x09, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "CryptographicContext_CipherAlgorithm" }, + {0}, false, "CryptographicContext_CipherAlgorithm" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 253 0x02, 0x09, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "CryptographicContext_MICAlgorithm" }, + {0}, false, "CryptographicContext_MICAlgorithm" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 254 0x02, 0x09, 0x03, 0x01, 0x02, 0x00, 0x00, 0x00 }, - {0, 0}, false, "CryptographicContext_CryptographicKeyID" }, + {0}, false, "CryptographicContext_CryptographicKeyID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a, // 255 0x0d, 0x01, 0x03, 0x01, 0x02, 0x13, 0x01, 0x01 }, - {0, 0}, false, "TimedTextWrapping" }, + {0}, false, "TimedTextWrappingClip" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 256 0x0d, 0x01, 0x03, 0x01, 0x17, 0x01, 0x0b, 0x01 }, - {0, 0}, false, "TimedTextEssence" }, + {0}, false, "TimedTextEssence" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 257 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x64, 0x00 }, - {0, 0}, false, "TimedTextDescriptor" }, + {0}, false, "TimedTextDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 258 0x01, 0x01, 0x15, 0x12, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "TimedTextDescriptor_ResourceID" }, + {0}, false, "TimedTextDescriptor_ResourceID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 259 0x04, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "TimedTextDescriptor_UCSEncoding" }, + {0}, false, "TimedTextDescriptor_UCSEncoding" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08, // 260 0x01, 0x02, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "TimedTextDescriptor_NamespaceURI" }, + {0}, false, "TimedTextDescriptor_NamespaceURI" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 261 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x65, 0x00 }, - {0, 0}, false, "TimedTextResourceSubDescriptor" }, + {0}, false, "TimedTextResourceSubDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 262 0x01, 0x01, 0x15, 0x13, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "TimedTextResourceSubDescriptor_AncillaryResourceID" }, + {0}, false, "TimedTextResourceSubDescriptor_AncillaryResourceID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, // 263 0x04, 0x09, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "TimedTextResourceSubDescriptor_MIMEMediaType" }, + {0}, false, "TimedTextResourceSubDescriptor_MIMEMediaType" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 264 0x01, 0x03, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "TimedTextResourceSubDescriptor_EssenceStreamID" }, + {0}, false, "TimedTextResourceSubDescriptor_EssenceStreamID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x05, 0x01, 0x01, // 265 0x0d, 0x01, 0x02, 0x01, 0x01, 0x03, 0x11, 0x00 }, - {0, 0}, false, "GenericStreamPartition" }, + {0}, false, "GenericStreamPartition" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 266 0x04, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, {0x02, 0x01}, false, "DMSegment_DataDefinition" }, @@ -842,9 +842,9 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 268 0x01, 0x07, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00 }, {0x61, 0x02}, false, "DMSegment_TrackIDList" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x0c, // 269 + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 269 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x63, 0x00 }, - {0, 0}, false, "StereoscopicPictureSubDescriptor" }, + {0}, false, "StereoscopicPictureSubDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07, // 270 0x04, 0x02, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00 }, {0x3d, 0x32}, true, "WaveAudioDescriptor_ChannelAssignment" }, @@ -853,7 +853,7 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x00, 0x00}, false, "GenericStream_DataElement" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 272 0x06, 0x01, 0x01, 0x04, 0x06, 0x10, 0x00, 0x00 }, - {0, 0}, true, "MXFInterop_GenericDescriptor_SubDescriptors" }, + {0}, true, "MXFInterop_GenericDescriptor_SubDescriptors" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04, // 273 0x01, 0x03, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00 }, {0x3f, 0x07}, false, "BodySID" }, @@ -868,56 +868,326 @@ static const ASDCP::MDDEntry s_MDD_Table[] = { {0x3b, 0x0a}, false, "EssenceContainers" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b, // 277 0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x01, 0x00 }, - {0, 0}, false, "DCAudioChannelCfg_1_5p1" }, + {0}, false, "DCAudioChannelCfg_1_5p1" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b, // 278 0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x02, 0x00 }, - {0, 0}, false, "DCAudioChannelCfg_2_6p1" }, + {0}, false, "DCAudioChannelCfg_2_6p1" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b, // 279 0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x03, 0x00 }, - {0, 0}, false, "DCAudioChannelCfg_3_7p1" }, + {0}, false, "DCAudioChannelCfg_3_7p1" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b, // 280 0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x04, 0x00 }, - {0, 0}, false, "DCAudioChannelCfg_4_WTF" }, + {0}, false, "DCAudioChannelCfg_4_WTF" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0b, // 281 0x04, 0x02, 0x02, 0x10, 0x03, 0x01, 0x05, 0x00 }, - {0, 0}, false, "DCAudioChannelCfg_5_7p1_DS" }, + {0}, false, "DCAudioChannelCfg_5_7p1_DS" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 282 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x6a, 0x00 }, - {0, 0}, false, "MCALabelSubDescriptor" }, + {0}, false, "MCALabelSubDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 283 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x6b, 0x00 }, - {0, 0}, false, "AudioChannelLabelSubDescriptor" }, + {0}, false, "AudioChannelLabelSubDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 284 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x6c, 0x00 }, - {0, 0}, false, "SoundfieldGroupLabelSubDescriptor" }, + {0}, false, "SoundfieldGroupLabelSubDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x01, // 285 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x6d, 0x00 }, - {0, 0}, false, "GroupOfSoundfieldGroupsLabelSubDescriptor" }, + {0}, false, "GroupOfSoundfieldGroupsLabelSubDescriptor" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 286 0x01, 0x03, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00 }, - {0, 0}, false, "MCALabelSubDescriptor_MCALabelDictionaryID" }, + {0}, false, "MCALabelSubDescriptor_MCALabelDictionaryID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 287 0x01, 0x03, 0x07, 0x01, 0x05, 0x00, 0x00, 0x00 }, - {0, 0}, false, "MCALabelSubDescriptor_MCALinkID" }, + {0}, false, "MCALabelSubDescriptor_MCALinkID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 288 0x01, 0x03, 0x07, 0x01, 0x02, 0x00, 0x00, 0x00 }, - {0, 0}, false, "MCALabelSubDescriptor_MCATagSymbol" }, + {0}, false, "MCALabelSubDescriptor_MCATagSymbol" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 289 0x01, 0x03, 0x07, 0x01, 0x03, 0x00, 0x00, 0x00 }, - {0, 0}, false, "MCALabelSubDescriptor_MCATagName" }, + {0}, false, "MCALabelSubDescriptor_MCATagName" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 290 0x01, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00 }, - {0, 0}, false, "MCALabelSubDescriptor_MCAChannelID" }, + {0}, false, "MCALabelSubDescriptor_MCAChannelID" }, { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0d, // 291 0x03, 0x01, 0x01, 0x02, 0x03, 0x15, 0x00, 0x00 }, - {0, 0}, false, "MCALabelSubDescriptor_RFC5646SpokenLanguage" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0d, // 292 - 0x01, 0x03, 0x07, 0x01, 0x03, 0x00, 0x00, 0x00 }, - {0, 0}, false, "AudioChannelLabelSubDescriptor_SoundfieldGroupLinkID" }, - { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0d, // 293 + {0}, false, "MCALabelSubDescriptor_RFC5646SpokenLanguage" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 292 + 0x01, 0x03, 0x07, 0x01, 0x06, 0x00, 0x00, 0x00 }, + {0}, false, "AudioChannelLabelSubDescriptor_SoundfieldGroupLinkID" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 293 0x01, 0x03, 0x07, 0x01, 0x04, 0x00, 0x00, 0x00 }, - {0, 0}, false, "SoundfieldGroupLabelSubDescriptor_GroupOfSoundfieldGroupsLinkID" }, - { {0, 0}, {0, 0}, false, 0 } + {0}, false, "SoundfieldGroupLabelSubDescriptor_GroupOfSoundfieldGroupsLinkID" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, // 294 + 0x0e, 0x09, 0x06, 0x05, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCDataWrappingFrame" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x05, // 295 + 0x0e, 0x09, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCDataEssence" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x05, // 296 + 0x0e, 0x09, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCDataDescriptor" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x05, // 297 + 0x0e, 0x09, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DolbyAtmosSubDescriptor" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 298 + 0x0e, 0x09, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00 }, + {0}, true, "DolbyAtmosSubDescriptor_AtmosVersion" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 299 + 0x0e, 0x09, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00 }, + {0}, true, "DolbyAtmosSubDescriptor_MaxChannelCount" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 300 + 0x0e, 0x09, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00 }, + {0}, true, "DolbyAtmosSubDescriptor_MaxObjectCount" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 301 + 0x0e, 0x09, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00 }, + {0}, true, "DolbyAtmosSubDescriptor_AtmosID" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 302 + 0x0e, 0x09, 0x05, 0x0A, 0x00, 0x00, 0x00, 0x00 }, + {0}, true, "DolbyAtmosSubDescriptor_FirstFrame" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 303 + 0x01, 0x03, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00 }, + {0}, false, "DataDataDef" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 304 + 0x04, 0x02, 0x02, 0x10, 0x03, 0x02, 0x00, 0x00 }, + {0}, false, "DCAudioChannelCfg_MCA" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 305 + 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_L" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 306 + 0x03, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_R" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 307 + 0x03, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_C" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 308 + 0x03, 0x02, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_LFE" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 309 + 0x03, 0x02, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Ls" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 310 + 0x03, 0x02, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Rs" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 311 + 0x03, 0x02, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Lss" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 312 + 0x03, 0x02, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Rss" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 313 + 0x03, 0x02, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Lrs" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 314 + 0x03, 0x02, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Rrs" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 315 + 0x03, 0x02, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Lc" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 316 + 0x03, 0x02, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Rc" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 317 + 0x03, 0x02, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_Cs" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 318 + 0x03, 0x02, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_HI" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 319 + 0x03, 0x02, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioChannel_VIN" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 320 + 0x03, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioSoundfield_51" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 321 + 0x03, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioSoundfield_71" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 322 + 0x03, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioSoundfield_SDS" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 323 + 0x03, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioSoundfield_61" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 324 + 0x03, 0x02, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00 }, + {0}, false, "DCAudioSoundfield_M" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, // 325 + 0x0d, 0x01, 0x03, 0x01, 0x16, 0x01, 0x02, 0x00 }, + {0}, false, "WAVEssenceClip" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 326 + 0x04, 0x02, 0x02, 0x10, 0x04, 0x01, 0x00, 0x00 }, + {0}, false, "IMFAudioChannelCfg_MCA" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 327 + 0x03, 0x02, 0x01, 0x20, 0x01, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioChannel_M1" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 328 + 0x03, 0x02, 0x01, 0x20, 0x02, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioChannel_M2" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 329 + 0x03, 0x02, 0x01, 0x20, 0x03, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioChannel_Lt" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 330 + 0x03, 0x02, 0x01, 0x20, 0x04, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioChannel_Rt" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 331 + 0x03, 0x02, 0x01, 0x20, 0x05, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioChannel_Lst" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 332 + 0x03, 0x02, 0x01, 0x20, 0x06, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioChannel_Rst" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 333 + 0x03, 0x02, 0x01, 0x20, 0x07, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioChannel_S" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 334 + 0x03, 0x02, 0x01, 0x20, 0x08, 0x00, 0x00, 0x00 }, + {0}, false, "IMFNumberedSourceChannel" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 335 + 0x03, 0x02, 0x02, 0x20, 0x01, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_ST" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 336 + 0x03, 0x02, 0x02, 0x20, 0x02, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_DM" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 337 + 0x03, 0x02, 0x02, 0x20, 0x03, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_DNS" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 338 + 0x03, 0x02, 0x02, 0x20, 0x04, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_30" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 339 + 0x03, 0x02, 0x02, 0x20, 0x05, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_40" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 340 + 0x03, 0x02, 0x02, 0x20, 0x06, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_50" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 341 + 0x03, 0x02, 0x02, 0x20, 0x07, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_60" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 342 + 0x03, 0x02, 0x02, 0x20, 0x08, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_70" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 343 + 0x03, 0x02, 0x02, 0x20, 0x09, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_LtRt" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 344 + 0x03, 0x02, 0x02, 0x20, 0x0a, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_51Ex" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 345 + 0x03, 0x02, 0x02, 0x20, 0x0b, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_HI" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 346 + 0x03, 0x02, 0x02, 0x20, 0x0c, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioSoundfield_VIN" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 347 + 0x03, 0x02, 0x03, 0x20, 0x01, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioGroup_MPg" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 348 + 0x03, 0x02, 0x03, 0x20, 0x02, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioGroup_DVS" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 349 + 0x03, 0x02, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00 }, + {0}, false, "IMFAudioGroup_Dcm" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0c, // 350 + 0x06, 0x01, 0x01, 0x04, 0x02, 0x0f, 0x00, 0x00 }, + {0}, false, "MaterialPackage_PackageMarker" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02, // 351 + 0x04, 0x01, 0x02, 0x01, 0x01, 0x03, 0x01, 0x00 }, + {0}, false, "GenericPictureEssenceDescriptor_CodingEquations" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09, // 352 + 0x04, 0x01, 0x02, 0x01, 0x01, 0x06, 0x01, 0x00 }, + {0}, false, "GenericPictureEssenceDescriptor_ColorPrimaries" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 353 + 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x11 }, + {0}, false, "JP2KEssenceCompression_BroadcastProfile_1" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 354 + 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x12 }, + {0}, false, "JP2KEssenceCompression_BroadcastProfile_2" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 355 + 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x13 }, + {0}, false, "JP2KEssenceCompression_BroadcastProfile_3" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 356 + 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x14 }, + {0}, false, "JP2KEssenceCompression_BroadcastProfile_4" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 357 + 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x15 }, + {0}, false, "JP2KEssenceCompression_BroadcastProfile_5" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 358 + 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x16 }, + {0}, false, "JP2KEssenceCompression_BroadcastProfile_6" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 359 + 0x04, 0x01, 0x02, 0x02, 0x03, 0x01, 0x01, 0x17 }, + {0}, false, "JP2KEssenceCompression_BroadcastProfile_7" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 360 + 0x04, 0x02, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00 }, + {0}, false, "WaveAudioDescriptor_ReferenceImageEditRate" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 361 + 0x04, 0x02, 0x01, 0x01, 0x07, 0x00, 0x00, 0x00 }, + {0}, false, "WaveAudioDescriptor_ReferenceAudioAlignmentLevel" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 362 + 0x04, 0x01, 0x03, 0x02, 0x0b, 0x00, 0x00, 0x00 }, + {0}, false, "GenericPictureEssenceDescriptor_AlternativeCenterCuts" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 363 + 0x04, 0x01, 0x05, 0x01, 0x13, 0x00, 0x00, 0x00 }, + {0x32, 0x05}, true, "GenericPictureEssenceDescriptor_ActiveHeight" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 364 + 0x04, 0x01, 0x05, 0x01, 0x14, 0x00, 0x00, 0x00 }, + {0x32, 0x04}, true, "GenericPictureEssenceDescriptor_ActiveWidth" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 365 + 0x04, 0x01, 0x05, 0x01, 0x15, 0x00, 0x00, 0x00 }, + {0x32, 0x06}, true, "GenericPictureEssenceDescriptor_ActiveXOffset" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 366 + 0x04, 0x01, 0x05, 0x01, 0x16, 0x00, 0x00, 0x00 }, + {0x32, 0x07}, true, "GenericPictureEssenceDescriptor_ActiveYOffset" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 367 + 0x03, 0x01, 0x01, 0x02, 0x02, 0x16, 0x00, 0x00 }, + {0}, false, "TimedTextDescriptor_RFC5646LanguageTagList" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 368 + 0x04, 0x01, 0x01, 0x01, 0x00, 0x04, 0x01, 0x00 }, + {0}, false, "AlternativeCenterCuts_4x3" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 369 + 0x04, 0x01, 0x01, 0x01, 0x00, 0x04, 0x02, 0x00 }, + {0}, false, "AlternativeCenterCuts_14x9" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01, // 370 + 0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x02, 0x00 }, + {0}, false, "WAVWrappingClip" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 371 + 0x0e, 0x16, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01 }, + {0}, false, "DBOXMotionCodePrimaryStream" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, // 372 + 0x0e, 0x16, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02 }, + {0}, false, "DBOXMotionCodeSecondaryStream" }, + + // 379-2, Sec. 7: Encoders that conform to this specification shall add a + // ContainerConstraintSubDescriptor to the GenericDescriptor::SubDescriptors + // property of the top-most File Descriptor that describes the essence + // container. + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x7f, 0x01, 0x01, // 373 + 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x67, 0x00 }, + {0}, false, "ContainerConstraintSubDescriptor" }, + + // protype for high dynamic range, values recorded in Dolby registry + { { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05, // 374 + 0x0e, 0x09, 0x06, 0x07, 0x01, 0x01, 0x01, 0x01 }, + {0}, false, "PHDRImageMetadataWrappingFrame" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x05, // 375 + 0x0e, 0x09, 0x06, 0x07, 0x01, 0x01, 0x01, 0x00 }, + {0}, false, "PHDRImageMetadataItem" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x53, 0x01, 0x05, // 376 + 0x0e, 0x09, 0x06, 0x07, 0x01, 0x01, 0x01, 0x03 }, + {0}, false, "PHDRMetadataTrackSubDescriptor" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 377 + 0x0e, 0x09, 0x06, 0x07, 0x01, 0x01, 0x01, 0x04 }, + {0}, false, "PHDRMetadataTrackSubDescriptor_DataDefinition" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 378 + 0x0e, 0x09, 0x06, 0x07, 0x01, 0x01, 0x01, 0x05 }, + {0}, false, "PHDRMetadataTrackSubDescriptor_SourceTrackID" }, + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05, // 379 + 0x0e, 0x09, 0x06, 0x07, 0x01, 0x01, 0x01, 0x06 }, + {0}, false, "PHDRMetadataTrackSubDescriptor_SimplePayloadSID" }, + + { { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x0e, // 380 + 0x04, 0x01, 0x06, 0x03, 0x0e, 0x00, 0x00, 0x00 }, + {0}, true, "JPEG2000PictureSubDescriptor_J2CLayout" }, + + { {0}, {0}, false, 0 } }; // diff --git a/asdcplib/src/MDD.h b/asdcplib/src/MDD.h index 595fd54b..fe18beee 100755 --- a/asdcplib/src/MDD.h +++ b/asdcplib/src/MDD.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2006-2012, John Hurst +Copyright (c) 2006-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file MDD.[h|cpp] - \version $Id: MDD.h,v 1.25 2012/02/02 01:58:43 jhurst Exp $ + \version $Id: MDD.h,v 1.35 2015/01/22 21:05:58 jhurst Exp $ \brief MXF Metadata Dictionary */ @@ -44,9 +44,9 @@ namespace ASDCP { MDD_SoundDataDef, // 6 MDD_TimecodeDataDef, // 7 MDD_DescriptiveMetaDataDef, // 8 - MDD_WAVWrapping, // 9 - MDD_MPEG2_VESWrapping, // 10 - MDD_JPEG_2000Wrapping, // 11 + MDD_WAVWrappingFrame, // 9 + MDD_MPEG2_VESWrappingFrame, // 10 + MDD_JPEG_2000WrappingFrame, // 11 MDD_JPEG2000Essence, // 12 MDD_MPEG2Essence, // 13 MDD_MXFInterop_CryptEssence, // 14 @@ -209,7 +209,7 @@ namespace ASDCP { MDD_GenericPictureEssenceDescriptor_ActiveFormatDescriptor, // 171 MDD_GenericPictureEssenceDescriptor_VideoLineMap, // 172 MDD_GenericPictureEssenceDescriptor_AlphaTransparency, // 173 - MDD_GenericPictureEssenceDescriptor_Gamma, // 174 + MDD_GenericPictureEssenceDescriptor_TransferCharacteristic, // 174 MDD_GenericPictureEssenceDescriptor_ImageAlignmentOffset, // 175 MDD_GenericPictureEssenceDescriptor_ImageStartOffset, // 176 MDD_GenericPictureEssenceDescriptor_ImageEndOffset, // 177 @@ -243,7 +243,7 @@ namespace ASDCP { MDD_GenericSoundEssenceDescriptor_ChannelCount, // 205 MDD_GenericSoundEssenceDescriptor_QuantizationBits, // 206 MDD_GenericSoundEssenceDescriptor_DialNorm, // 207 - MDD_GenericSoundEssenceDescriptor_SoundEssenceCompression, // 208 + MDD_GenericSoundEssenceDescriptor_SoundEssenceCoding, // 208 MDD_GenericDataEssenceDescriptor, // 209 MDD_GenericDataEssenceDescriptor_DataEssenceCoding, // 210 MDD_MultipleDescriptor, // 211 @@ -290,47 +290,133 @@ namespace ASDCP { MDD_CryptographicContext_CipherAlgorithm, // 252 MDD_CryptographicContext_MICAlgorithm, // 253 MDD_CryptographicContext_CryptographicKeyID, // 254 - MDD_TimedTextWrapping, // 255 - MDD_TimedTextEssence, // 256 - MDD_TimedTextDescriptor, // 257 - MDD_TimedTextDescriptor_ResourceID, // 258 - MDD_TimedTextDescriptor_UCSEncoding, // 259 - MDD_TimedTextDescriptor_NamespaceURI, // 260 - MDD_TimedTextResourceSubDescriptor, // 261 - MDD_TimedTextResourceSubDescriptor_AncillaryResourceID, // 262 - MDD_TimedTextResourceSubDescriptor_MIMEMediaType, // 263 - MDD_TimedTextResourceSubDescriptor_EssenceStreamID_DEPRECATED, // 264 - MDD_GenericStreamPartition, // 265 - MDD_DMSegment_DataDefinition_DEPRECATED, // 266 - MDD_DMSegment_Duration_DEPRECATED, // 267 - MDD_DMSegment_TrackIDList, // 268 - MDD_StereoscopicPictureSubDescriptor, // 269 + MDD_TimedTextWrappingClip, // 255 + MDD_TimedTextEssence, // 256 + MDD_TimedTextDescriptor, // 257 + MDD_TimedTextDescriptor_ResourceID, // 258 + MDD_TimedTextDescriptor_UCSEncoding, // 259 + MDD_TimedTextDescriptor_NamespaceURI, // 260 + MDD_TimedTextResourceSubDescriptor, // 261 + MDD_TimedTextResourceSubDescriptor_AncillaryResourceID, // 262 + MDD_TimedTextResourceSubDescriptor_MIMEMediaType, // 263 + MDD_TimedTextResourceSubDescriptor_EssenceStreamID_DEPRECATED, // 264 + MDD_GenericStreamPartition, // 265 + MDD_DMSegment_DataDefinition_DEPRECATED, // 266 + MDD_DMSegment_Duration_DEPRECATED, // 267 + MDD_DMSegment_TrackIDList, // 268 + MDD_StereoscopicPictureSubDescriptor, // 269 MDD_WaveAudioDescriptor_ChannelAssignment, // 270 - MDD_GenericStream_DataElement, // 271 + MDD_GenericStream_DataElement, // 271 MDD_MXFInterop_GenericDescriptor_SubDescriptors, // 272 - MDD_Core_BodySID, // 273 - MDD_Core_IndexSID, // 274 - MDD_Core_OperationalPattern, // 275 - MDD_Core_EssenceContainers, // 276 - MDD_DCAudioChannelCfg_1_5p1, // 277 - MDD_DCAudioChannelCfg_2_6p1, // 278 - MDD_DCAudioChannelCfg_3_7p1, // 279 - MDD_DCAudioChannelCfg_4_WTF, // 280 - MDD_DCAudioChannelCfg_5_7p1_DS, // 281 - MDD_MCALabelSubDescriptor, // 282 - MDD_AudioChannelLabelSubDescriptor, // 283 - MDD_SoundfieldGroupLabelSubDescriptor, // 284 - MDD_GroupOfSoundfieldGroupsLabelSubDescriptor, // 285 - MDD_MCALabelSubDescriptor_MCALabelDictionaryID, // 286 - MDD_MCALabelSubDescriptor_MCALinkID, // 287 - MDD_MCALabelSubDescriptor_MCATagSymbol, // 288 - MDD_MCALabelSubDescriptor_MCATagName, // 289 - MDD_MCALabelSubDescriptor_MCAChannelID, // 290 - MDD_MCALabelSubDescriptor_RFC5646SpokenLanguage, // 291 - MDD_AudioChannelLabelSubDescriptor_SoundfieldGroupLinkID, // 292 - MDD_SoundfieldGroupLabelSubDescriptor_GroupOfSoundfieldGroupsLinkID, // 293 - MDD_Max - + MDD_Core_BodySID, // 273 + MDD_Core_IndexSID, // 274 + MDD_Core_OperationalPattern, // 275 + MDD_Core_EssenceContainers, // 276 + MDD_DCAudioChannelCfg_1_5p1, // 277 + MDD_DCAudioChannelCfg_2_6p1, // 278 + MDD_DCAudioChannelCfg_3_7p1, // 279 + MDD_DCAudioChannelCfg_4_WTF, // 280 + MDD_DCAudioChannelCfg_5_7p1_DS, // 281 + MDD_MCALabelSubDescriptor, // 282 + MDD_AudioChannelLabelSubDescriptor, // 283 + MDD_SoundfieldGroupLabelSubDescriptor, // 284 + MDD_GroupOfSoundfieldGroupsLabelSubDescriptor, // 285 + MDD_MCALabelSubDescriptor_MCALabelDictionaryID, // 286 + MDD_MCALabelSubDescriptor_MCALinkID, // 287 + MDD_MCALabelSubDescriptor_MCATagSymbol, // 288 + MDD_MCALabelSubDescriptor_MCATagName, // 289 + MDD_MCALabelSubDescriptor_MCAChannelID, // 290 + MDD_MCALabelSubDescriptor_RFC5646SpokenLanguage, // 291 + MDD_AudioChannelLabelSubDescriptor_SoundfieldGroupLinkID, // 292 + MDD_SoundfieldGroupLabelSubDescriptor_GroupOfSoundfieldGroupsLinkID, // 293 + MDD_DCDataWrappingFrame, // 294 + MDD_DCDataEssence, // 295 + MDD_DCDataDescriptor, // 296 + MDD_DolbyAtmosSubDescriptor, // 297 + MDD_DolbyAtmosSubDescriptor_AtmosVersion, // 298 + MDD_DolbyAtmosSubDescriptor_MaxChannelCount, // 299 + MDD_DolbyAtmosSubDescriptor_MaxObjectCount, // 300 + MDD_DolbyAtmosSubDescriptor_AtmosID, // 301 + MDD_DolbyAtmosSubDescriptor_FirstFrame, // 302 + MDD_DataDataDef, // 303 + MDD_DCAudioChannelCfg_MCA, // 304 + MDD_DCAudioChannel_L, // 305 + MDD_DCAudioChannel_R, // 306 + MDD_DCAudioChannel_C, // 307 + MDD_DCAudioChannel_LFE, // 308 + MDD_DCAudioChannel_Ls, // 309 + MDD_DCAudioChannel_Rs, // 310 + MDD_DCAudioChannel_Lss, // 311 + MDD_DCAudioChannel_Rss, // 312 + MDD_DCAudioChannel_Lrs, // 313 + MDD_DCAudioChannel_Rrs, // 314 + MDD_DCAudioChannel_Lc, // 315 + MDD_DCAudioChannel_Rc, // 316 + MDD_DCAudioChannel_Cs, // 317 + MDD_DCAudioChannel_HI, // 318 + MDD_DCAudioChannel_VIN, // 319 + MDD_DCAudioSoundfield_51, // 320 + MDD_DCAudioSoundfield_71, // 321 + MDD_DCAudioSoundfield_SDS, // 322 + MDD_DCAudioSoundfield_61, // 323 + MDD_DCAudioSoundfield_M, // 324 + MDD_WAVEssenceClip, // 325 + MDD_IMFAudioChannelCfg_MCA, // 326 + MDD_IMFAudioChannel_M1, // 327 + MDD_IMFAudioChannel_M2, // 328 + MDD_IMFAudioChannel_Lt, // 329 + MDD_IMFAudioChannel_Rt, // 330 + MDD_IMFAudioChannel_Lst, // 331 + MDD_IMFAudioChannel_Rst, // 332 + MDD_IMFAudioChannel_S, // 333 + MDD_IMFNumberedSourceChannel, // 334 + MDD_IMFAudioSoundfield_ST, // 335 + MDD_IMFAudioSoundfield_DM, // 336 + MDD_IMFAudioSoundfield_DNS, // 337 + MDD_IMFAudioSoundfield_30, // 338 + MDD_IMFAudioSoundfield_40, // 339 + MDD_IMFAudioSoundfield_50, // 340 + MDD_IMFAudioSoundfield_60, // 341 + MDD_IMFAudioSoundfield_70, // 342 + MDD_IMFAudioSoundfield_LtRt, // 343 + MDD_IMFAudioSoundfield_51Ex, // 344 + MDD_IMFAudioSoundfield_HI, // 345 + MDD_IMFAudioSoundfield_VIN, // 346 + MDD_IMFAudioGroup_MPg, // 347 + MDD_IMFAudioGroup_DVS, // 348 + MDD_IMFAudioGroup_Dcm, // 349 + MDD_MaterialPackage_PackageMarker, // 350 + MDD_GenericPictureEssenceDescriptor_CodingEquations, // 351 + MDD_GenericPictureEssenceDescriptor_ColorPrimaries, // 352 + MDD_JP2KEssenceCompression_BroadcastProfile_1, // 353 + MDD_JP2KEssenceCompression_BroadcastProfile_2, // 354 + MDD_JP2KEssenceCompression_BroadcastProfile_3, // 355 + MDD_JP2KEssenceCompression_BroadcastProfile_4, // 356 + MDD_JP2KEssenceCompression_BroadcastProfile_5, // 357 + MDD_JP2KEssenceCompression_BroadcastProfile_6, // 358 + MDD_JP2KEssenceCompression_BroadcastProfile_7, // 359 + MDD_WaveAudioDescriptor_ReferenceImageEditRate, // 360 + MDD_WaveAudioDescriptor_ReferenceAudioAlignmentLevel, // 361 + MDD_GenericPictureEssenceDescriptor_AlternativeCenterCuts, // 362 + MDD_GenericPictureEssenceDescriptor_ActiveHeight, // 363 + MDD_GenericPictureEssenceDescriptor_ActiveWidth, // 364 + MDD_GenericPictureEssenceDescriptor_ActiveXOffset, // 365 + MDD_GenericPictureEssenceDescriptor_ActiveYOffset, // 366 + MDD_TimedTextDescriptor_RFC5646LanguageTagList, // 367 + MDD_AlternativeCenterCuts_4x3, // 368 + MDD_AlternativeCenterCuts_14x9, // 369 + MDD_WAVWrappingClip, // 370 + MDD_DBOXMotionCodePrimaryStream, // 371 + MDD_DBOXMotionCodeSecondaryStream, // 372 + MDD_ContainerConstraintSubDescriptor, // 373 + MDD_PHDRImageMetadataWrappingFrame, // 374 + MDD_PHDRImageMetadataItem, // 375 + MDD_PHDRMetadataTrackSubDescriptor, // 376 + MDD_PHDRMetadataTrackSubDescriptor_DataDefinition, // 377 + MDD_PHDRMetadataTrackSubDescriptor_SourceTrackID, // 378 + MDD_PHDRMetadataTrackSubDescriptor_SimplePayloadSID, // 379 + MDD_JPEG2000PictureSubDescriptor_J2CLayout, // 380 + MDD_Max }; // enum MDD_t // @@ -342,7 +428,7 @@ namespace ASDCP { const MDD_t MDD_Preface_EssenceContainers = MDD_Core_EssenceContainers; const MDD_t MDD_Preface_OperationalPattern = MDD_Core_OperationalPattern; const MDD_t MDD_TimedTextResourceSubDescriptor_EssenceStreamID = MDD_Core_BodySID; - + } // namespaceASDCP diff --git a/asdcplib/src/MPEG2_Parser.cpp b/asdcplib/src/MPEG2_Parser.cpp index 3b81f5a9..89d23134 100755 --- a/asdcplib/src/MPEG2_Parser.cpp +++ b/asdcplib/src/MPEG2_Parser.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file MPEG2_Parser.cpp - \version $Id: MPEG2_Parser.cpp,v 1.11 2011/08/30 17:04:25 jhurst Exp $ + \version $Id: MPEG2_Parser.cpp,v 1.12 2014/01/02 23:29:22 jhurst Exp $ \brief AS-DCP library, MPEG2 raw essence reader implementation */ @@ -94,12 +94,6 @@ class h__ParserState case ST_EXT: m_State = ST_SEQ; return RESULT_OK; - case ST_SEQ: - case ST_PIC: - case ST_GOP: - case ST_SLICE: - /* Keep gcc quiet */ - break; } DefaultLogSink().Error("SEQ follows %s\n", StringParserState(m_State)); @@ -116,12 +110,6 @@ class h__ParserState case ST_EXT: m_State = ST_SLICE; return RESULT_OK; - case ST_INIT: - case ST_SEQ: - case ST_GOP: - case ST_SLICE: - /* Keep gcc quiet */ - break; } DefaultLogSink().Error("Slice follows %s\n", StringParserState(m_State)); @@ -140,10 +128,6 @@ class h__ParserState case ST_EXT: m_State = ST_PIC; return RESULT_OK; - case ST_PIC: - case ST_SLICE: - /* Keep gcc quiet */ - break; } DefaultLogSink().Error("PIC follows %s\n", StringParserState(m_State)); @@ -160,12 +144,6 @@ class h__ParserState case ST_SEQ: m_State = ST_GOP; return RESULT_OK; - case ST_INIT: - case ST_PIC: - case ST_GOP: - case ST_SLICE: - /* Keep gcc quiet */ - break; } DefaultLogSink().Error("GOP follows %s\n", StringParserState(m_State)); @@ -183,10 +161,6 @@ class h__ParserState case ST_GOP: m_State = ST_EXT; return RESULT_OK; - case ST_INIT: - case ST_SLICE: - /* Keep gcc quiet */ - break; } DefaultLogSink().Error("EXT follows %s\n", StringParserState(m_State)); @@ -218,7 +192,7 @@ public: ~StreamParams() {} // - Result_t Sequence(VESParser*, const byte_t* b, ui32_t) + Result_t Sequence(VESParser*, const byte_t* b, ui32_t s) { Result_t result = m_State.Goto_SEQ(); @@ -237,7 +211,7 @@ public: } // - Result_t Extension(VESParser*, const byte_t* b, ui32_t) + Result_t Extension(VESParser*, const byte_t* b, ui32_t s) { Result_t result = m_State.Goto_EXT(); @@ -312,7 +286,7 @@ public: m_State.Reset(); } - Result_t Sequence(VESParser*, const byte_t*, ui32_t s) + Result_t Sequence(VESParser*, const byte_t* b, ui32_t s) { if ( m_State.Test_SLICE() ) { @@ -350,7 +324,7 @@ public: return m_State.Test_SLICE() ? RESULT_OK : RESULT_FAIL; } - Result_t Extension(VESParser*, const byte_t*, ui32_t s) + Result_t Extension(VESParser*, const byte_t* b, ui32_t s) { m_FrameSize += s; return m_State.Goto_EXT(); @@ -365,7 +339,7 @@ public: return m_State.Goto_GOP(); } - Result_t Data(VESParser*, const byte_t*, i32_t s) + Result_t Data(VESParser*, const byte_t* b, i32_t s) { m_FrameSize += s; return RESULT_OK; @@ -397,7 +371,7 @@ public: h__Parser() : m_TmpBuffer(VESReadSize*8) {} ~h__Parser() { Close(); } - Result_t OpenRead(const char* filename); + Result_t OpenRead(const std::string& filename); void Close(); Result_t Reset(); Result_t ReadFrame(FrameBuffer&); @@ -425,9 +399,8 @@ ASDCP::MPEG2::Parser::h__Parser::Close() // ASDCP::Result_t -ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename) +ASDCP::MPEG2::Parser::h__Parser::OpenRead(const std::string& filename) { - ASDCP_TEST_NULL_STR(filename) ui32_t read_count = 0; Result_t result = m_FileReader.OpenRead(filename); @@ -469,7 +442,7 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename) if ( ASDCP_FAILURE(result) ) { - DefaultLogSink().Error("Unable to identify a wrapping mode for the essence in file \"%s\"\n", filename); + DefaultLogSink().Error("Unable to identify a wrapping mode for the essence in file \"%s\"\n", filename.c_str()); m_FileReader.Close(); } @@ -592,7 +565,7 @@ ASDCP::MPEG2::Parser::~Parser() // Opens the stream for reading, parses enough data to provide a complete // set of stream metadata for the MXFWriter below. ASDCP::Result_t -ASDCP::MPEG2::Parser::OpenRead(const char* filename) const +ASDCP::MPEG2::Parser::OpenRead(const std::string& filename) const { const_cast<ASDCP::MPEG2::Parser*>(this)->m_Parser = new h__Parser; diff --git a/asdcplib/src/MXF.cpp b/asdcplib/src/MXF.cpp index c35c1d20..cc84797f 100755 --- a/asdcplib/src/MXF.cpp +++ b/asdcplib/src/MXF.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file MXF.cpp - \version $Id: MXF.cpp,v 1.62 2012/03/05 13:11:47 jhurst Exp $ + \version $Id: MXF.cpp,v 1.79 2015/10/12 15:30:46 jhurst Exp $ \brief MXF objects */ @@ -43,8 +43,6 @@ const ui32_t CBRIndexEntriesPerSegment = 5000; //------------------------------------------------------------------------------------------ // -const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH; - // ASDCP::Result_t ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader) @@ -59,7 +57,10 @@ ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader) if ( ASDCP_SUCCESS(result) && end_pos < (SMPTE_UL_LENGTH+MXF_BER_LENGTH) ) - result = RESULT_FAIL; // File is smaller than an empty packet! + { + DefaultLogSink().Error("File is smaller than an empty KLV packet.\n"); + result = RESULT_FAIL; + } if ( ASDCP_SUCCESS(result) ) result = Reader.Seek(end_pos - 4); @@ -74,7 +75,10 @@ ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader) result = Reader.Read(intbuf, MXF_BER_LENGTH, &read_count); if ( ASDCP_SUCCESS(result) && read_count != 4 ) - result = RESULT_FAIL; + { + DefaultLogSink().Error("RIP contains fewer than four bytes.\n"); + result = RESULT_FAIL; + } } if ( ASDCP_SUCCESS(result) ) @@ -82,7 +86,10 @@ ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader) rip_size = KM_i32_BE(Kumu::cp2i<ui32_t>(intbuf)); if ( rip_size > end_pos ) // RIP can't be bigger than the file - return RESULT_FAIL; + { + DefaultLogSink().Error("RIP size impossibly large.\n"); + return RESULT_FAIL; + } } // reposition to start of RIP @@ -93,20 +100,20 @@ ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader) } // -ASDCP::Result_t -ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, Pair& outPair) const +bool +ASDCP::MXF::RIP::GetPairBySID(ui32_t SID, PartitionPair& outPair) const { - Array<Pair>::const_iterator pi = PairArray.begin(); - for ( ; pi != PairArray.end(); pi++ ) + RIP::const_pair_iterator i; + for ( i = PairArray.begin(); i != PairArray.end(); ++i ) { - if ( (*pi).BodySID == SID ) + if ( i->BodySID == SID ) { - outPair = *pi; - return RESULT_OK; + outPair = *i; + return true; } } - return RESULT_FAIL; + return false; } // @@ -119,11 +126,11 @@ ASDCP::MXF::RIP::InitFromFile(const Kumu::FileReader& Reader) if ( ASDCP_SUCCESS(result) ) { Kumu::MemIOReader MemRDR(m_ValueStart, m_ValueLength - 4); - result = PairArray.Unarchive(&MemRDR) ? RESULT_OK : RESULT_KLV_CODING; + result = PairArray.Unarchive(&MemRDR) ? RESULT_OK : RESULT_KLV_CODING(__LINE__, __FILE__); } if ( ASDCP_FAILURE(result) ) - DefaultLogSink().Error("Failed to initialize RIP\n"); + DefaultLogSink().Error("Failed to initialize RIP.\n"); return result; } @@ -142,7 +149,7 @@ ASDCP::MXF::RIP::WriteToFile(Kumu::FileWriter& Writer) if ( ASDCP_SUCCESS(result) ) { - result = RESULT_KLV_CODING; + result = RESULT_KLV_CODING(__LINE__, __FILE__); Kumu::MemIOWriter MemWRT(Buffer.Data(), Buffer.Capacity()); if ( PairArray.Archive(&MemWRT) ) @@ -174,80 +181,77 @@ ASDCP::MXF::RIP::Dump(FILE* stream) // // -class ASDCP::MXF::Partition::h__PacketList -{ -public: - std::list<InterchangeObject*> m_List; - std::map<UUID, InterchangeObject*> m_Map; - - ~h__PacketList() { - while ( ! m_List.empty() ) - { - delete m_List.back(); - m_List.pop_back(); - } - } +ASDCP::MXF::Partition::PacketList::~PacketList() { + while ( ! m_List.empty() ) + { + delete m_List.back(); + m_List.pop_back(); + } +} - // - void AddPacket(InterchangeObject* ThePacket) // takes ownership - { - assert(ThePacket); - m_Map.insert(std::map<UUID, InterchangeObject*>::value_type(ThePacket->InstanceUID, ThePacket)); - m_List.push_back(ThePacket); - } +// +void +ASDCP::MXF::Partition::PacketList::AddPacket(InterchangeObject* ThePacket) // takes ownership +{ + assert(ThePacket); + m_Map.insert(std::map<UUID, InterchangeObject*>::value_type(ThePacket->InstanceUID, ThePacket)); + m_List.push_back(ThePacket); +} - // - Result_t GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object) - { - ASDCP_TEST_NULL(Object); +// +ASDCP::Result_t +ASDCP::MXF::Partition::PacketList::GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object) +{ + ASDCP_TEST_NULL(Object); - std::map<UUID, InterchangeObject*>::iterator mi = m_Map.find(ObjectID); + std::map<UUID, InterchangeObject*>::iterator mi = m_Map.find(ObjectID); + + if ( mi == m_Map.end() ) + { + *Object = 0; + return RESULT_FAIL; + } - if ( mi == m_Map.end() ) - { - *Object = 0; - return RESULT_FAIL; - } + *Object = (*mi).second; + return RESULT_OK; +} - *Object = (*mi).second; - return RESULT_OK; - } +// +ASDCP::Result_t +ASDCP::MXF::Partition::PacketList::GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object) +{ + ASDCP_TEST_NULL(ObjectID); + ASDCP_TEST_NULL(Object); + std::list<InterchangeObject*>::iterator li; + *Object = 0; - // - Result_t GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object) - { - ASDCP_TEST_NULL(ObjectID); - ASDCP_TEST_NULL(Object); - std::list<InterchangeObject*>::iterator li; - *Object = 0; - - for ( li = m_List.begin(); li != m_List.end(); li++ ) - { - if ( (*li)->HasUL(ObjectID) ) - { - *Object = *li; - return RESULT_OK; - } - } + for ( li = m_List.begin(); li != m_List.end(); li++ ) + { + if ( (*li)->HasUL(ObjectID) ) + { + *Object = *li; + return RESULT_OK; + } + } - return RESULT_FAIL; - } + return RESULT_FAIL; +} - // - Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList) - { - ASDCP_TEST_NULL(ObjectID); - std::list<InterchangeObject*>::iterator li; +// +ASDCP::Result_t +ASDCP::MXF::Partition::PacketList::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList) +{ + ASDCP_TEST_NULL(ObjectID); + std::list<InterchangeObject*>::iterator li; - for ( li = m_List.begin(); li != m_List.end(); li++ ) - { - if ( (*li)->HasUL(ObjectID) ) - ObjectList.push_back(*li); - } + for ( li = m_List.begin(); li != m_List.end(); li++ ) + { + if ( (*li)->HasUL(ObjectID) ) + ObjectList.push_back(*li); + } - return ObjectList.empty() ? RESULT_FAIL : RESULT_OK; - } -}; + return ObjectList.empty() ? RESULT_FAIL : RESULT_OK; +} //------------------------------------------------------------------------------------------ // @@ -260,7 +264,7 @@ ASDCP::MXF::Partition::Partition(const Dictionary*& d) : FooterPartition(0), HeaderByteCount(0), IndexByteCount(0), IndexSID(0), BodyOffset(0), BodySID(0) { - m_PacketList = new h__PacketList; + m_PacketList = new PacketList; } ASDCP::MXF::Partition::~Partition() @@ -297,7 +301,7 @@ ASDCP::Result_t ASDCP::MXF::Partition::InitFromBuffer(const byte_t* p, ui32_t l) { Kumu::MemIOReader MemRDR(p, l); - Result_t result = RESULT_KLV_CODING; + Result_t result = RESULT_KLV_CODING(__LINE__, __FILE__); if ( MemRDR.ReadUi16BE(&MajorVersion) ) if ( MemRDR.ReadUi16BE(&MinorVersion) ) @@ -315,7 +319,7 @@ ASDCP::MXF::Partition::InitFromBuffer(const byte_t* p, ui32_t l) result = RESULT_OK; if ( ASDCP_FAILURE(result) ) - DefaultLogSink().Error("Failed to initialize Partition\n"); + DefaultLogSink().Error("Failed to initialize Partition.\n"); return result; } @@ -330,7 +334,7 @@ ASDCP::MXF::Partition::WriteToFile(Kumu::FileWriter& Writer, UL& PartitionLabel) if ( ASDCP_SUCCESS(result) ) { Kumu::MemIOWriter MemWRT(Buffer.Data(), Buffer.Capacity()); - result = RESULT_KLV_CODING; + result = RESULT_KLV_CODING(__LINE__, __FILE__); if ( MemWRT.WriteUi16BE(MajorVersion) ) if ( MemWRT.WriteUi16BE(MinorVersion) ) if ( MemWRT.WriteUi32BE(KAGSize) ) @@ -445,7 +449,7 @@ ASDCP::MXF::Primer::InitFromBuffer(const byte_t* p, ui32_t l) if ( ASDCP_SUCCESS(result) ) { Kumu::MemIOReader MemRDR(m_ValueStart, m_ValueLength); - result = LocalTagEntryBatch.Unarchive(&MemRDR) ? RESULT_OK : RESULT_KLV_CODING; + result = LocalTagEntryBatch.Unarchive(&MemRDR) ? RESULT_OK : RESULT_KLV_CODING(__LINE__, __FILE__); } if ( ASDCP_SUCCESS(result) ) @@ -455,7 +459,7 @@ ASDCP::MXF::Primer::InitFromBuffer(const byte_t* p, ui32_t l) } if ( ASDCP_FAILURE(result) ) - DefaultLogSink().Error("Failed to initialize Primer\n"); + DefaultLogSink().Error("Failed to initialize Primer.\n"); return result; } @@ -483,7 +487,7 @@ ASDCP::MXF::Primer::WriteToBuffer(ASDCP::FrameBuffer& Buffer) assert(m_Dict); ASDCP::FrameBuffer LocalTagBuffer; Kumu::MemIOWriter MemWRT(Buffer.Data() + kl_length, Buffer.Capacity() - kl_length); - Result_t result = LocalTagEntryBatch.Archive(&MemWRT) ? RESULT_OK : RESULT_KLV_CODING; + Result_t result = LocalTagEntryBatch.Archive(&MemWRT) ? RESULT_OK : RESULT_KLV_CODING(__LINE__, __FILE__); if ( ASDCP_SUCCESS(result) ) { @@ -522,7 +526,7 @@ ASDCP::MXF::Primer::InsertTag(const MDDEntry& Entry, ASDCP::TagValue& Tag) TmpEntry.UL = TestUL; TmpEntry.Tag = Tag; - LocalTagEntryBatch.push_back(TmpEntry); + LocalTagEntryBatch.insert(TmpEntry); m_Lookup->insert(std::map<UL, TagValue>::value_type(TmpEntry.UL, TmpEntry.Tag)); } else @@ -582,10 +586,11 @@ ASDCP::MXF::Primer::Dump(FILE* stream) // ASDCP::MXF::Preface::Preface(const Dictionary*& d) : - InterchangeObject(d), m_Dict(d), Version(258), ObjectModelVersion(0) + InterchangeObject(d), m_Dict(d), Version(258) { assert(m_Dict); m_UL = m_Dict->Type(MDD_Preface).ul; + ObjectModelVersion = 0; } // @@ -612,8 +617,8 @@ ASDCP::MXF::Preface::InitFromTLVSet(TLVReader& TLVSet) Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Preface, LastModifiedDate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(Preface, Version)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(Preface, ObjectModelVersion)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Preface, PrimaryPackage)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(Preface, ObjectModelVersion)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(Preface, PrimaryPackage)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Preface, Identifications)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Preface, ContentStorage)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Preface, OperationalPattern)); @@ -629,8 +634,8 @@ ASDCP::MXF::Preface::WriteToTLVSet(TLVWriter& TLVSet) Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Preface, LastModifiedDate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(Preface, Version)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(Preface, ObjectModelVersion)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Preface, PrimaryPackage)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(Preface, ObjectModelVersion)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(Preface, PrimaryPackage)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Preface, Identifications)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Preface, ContentStorage)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Preface, OperationalPattern)); @@ -665,8 +670,13 @@ ASDCP::MXF::Preface::Dump(FILE* stream) InterchangeObject::Dump(stream); fprintf(stream, " %22s = %s\n", "LastModifiedDate", LastModifiedDate.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %hu\n", "Version", Version); - fprintf(stream, " %22s = %u\n", "ObjectModelVersion", ObjectModelVersion); - fprintf(stream, " %22s = %s\n", "PrimaryPackage", PrimaryPackage.EncodeHex(identbuf, IdentBufferLen)); + + if ( ! ObjectModelVersion.empty() ) + fprintf(stream, " %22s = %u\n", "ObjectModelVersion", ObjectModelVersion.get()); + + if ( ! PrimaryPackage.empty() ) + fprintf(stream, " %22s = %s\n", "PrimaryPackage", PrimaryPackage.get().EncodeHex(identbuf, IdentBufferLen)); + fprintf(stream, " %22s:\n", "Identifications"); Identifications.Dump(stream); fprintf(stream, " %22s = %s\n", "ContentStorage", ContentStorage.EncodeHex(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %s\n", "OperationalPattern", OperationalPattern.EncodeString(identbuf, IdentBufferLen)); @@ -677,118 +687,71 @@ ASDCP::MXF::Preface::Dump(FILE* stream) //------------------------------------------------------------------------------------------ // -ASDCP::MXF::OPAtomHeader::OPAtomHeader(const Dictionary*& d) : Partition(d), m_Dict(d), m_RIP(d), m_Primer(d), m_Preface(0), m_HasRIP(false) {} -ASDCP::MXF::OPAtomHeader::~OPAtomHeader() {} +ASDCP::MXF::OP1aHeader::OP1aHeader(const Dictionary*& d) : Partition(d), m_Dict(d), m_Primer(d), m_Preface(0) {} +ASDCP::MXF::OP1aHeader::~OP1aHeader() {} // ASDCP::Result_t -ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader) +ASDCP::MXF::OP1aHeader::InitFromFile(const Kumu::FileReader& Reader) { - m_HasRIP = false; - Result_t result = SeekToRIP(Reader); + Result_t result = Partition::InitFromFile(Reader); - if ( ASDCP_SUCCESS(result) ) - { - result = m_RIP.InitFromFile(Reader); - ui32_t test_s = m_RIP.PairArray.size(); + if ( ASDCP_FAILURE(result) ) + return result; - if ( ASDCP_FAILURE(result) ) + if ( m_Dict == &DefaultCompositeDict() ) + { + // select more explicit dictionary if one is available + if ( OperationalPattern.ExactMatch(MXFInterop_OPAtom_Entry().ul) ) { - DefaultLogSink().Error("File contains no RIP\n"); - result = RESULT_OK; + m_Dict = &DefaultInteropDict(); } - else if ( test_s == 0 ) + else if ( OperationalPattern.ExactMatch(SMPTE_390_OPAtom_Entry().ul) ) { - DefaultLogSink().Error("RIP contains no Pairs.\n"); - result = RESULT_FORMAT; - } - else - { - if ( test_s < 2 ) - { - // OP-Atom states that there will be either two or three partitions: - // one closed header and one closed footer with an optional body - // SMPTE 429-5 files may have many partitions, see SMPTE 410M - DefaultLogSink().Warn("RIP count is less than 2: %u\n", test_s); - } - - m_HasRIP = true; - - if ( m_RIP.PairArray.front().ByteOffset != 0 ) - { - DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n"); - result = RESULT_FORMAT; - } + m_Dict = &DefaultSMPTEDict(); } } - if ( ASDCP_SUCCESS(result) ) - result = Reader.Seek(0); - - if ( ASDCP_SUCCESS(result) ) - result = Partition::InitFromFile(Reader); // test UL and OP - - if ( ASDCP_FAILURE(result) ) - return result; - - // is it really OP-Atom? - assert(m_Dict); - UL OPAtomUL(SMPTE_390_OPAtom_Entry().ul); - UL InteropOPAtomUL(MXFInterop_OPAtom_Entry().ul); - - if ( OperationalPattern.ExactMatch(OPAtomUL) ) // SMPTE - { - if ( m_Dict == &DefaultCompositeDict() ) - m_Dict = &DefaultSMPTEDict(); - } - else if ( OperationalPattern.ExactMatch(InteropOPAtomUL) ) // Interop + // slurp up the remainder of the header + if ( HeaderByteCount < 1024 ) { - if ( m_Dict == &DefaultCompositeDict() ) - m_Dict = &DefaultInteropDict(); + DefaultLogSink().Warn("Improbably small HeaderByteCount value: %qu\n", HeaderByteCount); } - else + else if (HeaderByteCount > ( 4 * Kumu::Megabyte ) ) { - char strbuf[IdentBufferLen]; - const MDDEntry* Entry = m_Dict->FindUL(OperationalPattern.Value()); - if ( Entry == 0 ) - DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", - OperationalPattern.EncodeString(strbuf, IdentBufferLen)); - else - DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", Entry->name); + DefaultLogSink().Warn("Improbably huge HeaderByteCount value: %qu\n", HeaderByteCount); } - - // slurp up the remainder of the header - if ( HeaderByteCount < 1024 ) - DefaultLogSink().Warn("Improbably small HeaderByteCount value: %u\n", HeaderByteCount); - - assert (HeaderByteCount <= 0xFFFFFFFFL); - result = m_Buffer.Capacity((ui32_t) HeaderByteCount); + + result = m_HeaderData.Capacity(Kumu::xmin(4*Kumu::Megabyte, static_cast<ui32_t>(HeaderByteCount))); if ( ASDCP_SUCCESS(result) ) { ui32_t read_count; - result = Reader.Read(m_Buffer.Data(), m_Buffer.Capacity(), &read_count); + result = Reader.Read(m_HeaderData.Data(), m_HeaderData.Capacity(), &read_count); if ( ASDCP_FAILURE(result) ) - return result; + { + DefaultLogSink().Error("OP1aHeader::InitFromFile, Read failed\n"); + return result; + } - if ( read_count != m_Buffer.Capacity() ) + if ( read_count != m_HeaderData.Capacity() ) { - DefaultLogSink().Error("Short read of OP-Atom header metadata; wanted %u, got %u\n", - m_Buffer.Capacity(), read_count); - return RESULT_KLV_CODING; + DefaultLogSink().Error("Short read of OP-Atom header metadata; wanted %u, got %u.\n", + m_HeaderData.Capacity(), read_count); + return RESULT_KLV_CODING(__LINE__, __FILE__); } } if ( ASDCP_SUCCESS(result) ) - result = InitFromBuffer(m_Buffer.RoData(), m_Buffer.Capacity()); + result = InitFromBuffer(m_HeaderData.RoData(), m_HeaderData.Capacity()); return result; } // ASDCP::Result_t -ASDCP::MXF::OPAtomHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l) +ASDCP::MXF::OP1aHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l) { Result_t result = KLVPacket::InitFromBuffer(p, l); @@ -806,7 +769,7 @@ ASDCP::MXF::OPAtomHeader::InitFromPartitionBuffer(const byte_t* p, ui32_t l) // ASDCP::Result_t -ASDCP::MXF::OPAtomHeader::InitFromBuffer(const byte_t* p, ui32_t l) +ASDCP::MXF::OP1aHeader::InitFromBuffer(const byte_t* p, ui32_t l) { assert(m_Dict); Result_t result = RESULT_OK; @@ -820,15 +783,20 @@ ASDCP::MXF::OPAtomHeader::InitFromBuffer(const byte_t* p, ui32_t l) object->m_Lookup = &m_Primer; result = object->InitFromBuffer(p, end_p - p); + const byte_t* redo_p = p; p += object->PacketLength(); - // hexdump(p, object->PacketLength()); if ( ASDCP_SUCCESS(result) ) { if ( object->IsA(m_Dict->ul(MDD_KLVFill)) ) { delete object; + + if ( p > end_p ) + { + DefaultLogSink().Error("Fill item short read: %d.\n", p - end_p); + } } else if ( object->IsA(m_Dict->ul(MDD_Primer)) ) // TODO: only one primer should be found { @@ -845,7 +813,8 @@ ASDCP::MXF::OPAtomHeader::InitFromBuffer(const byte_t* p, ui32_t l) } else { - DefaultLogSink().Error("Error initializing packet\n"); + DefaultLogSink().Error("Error initializing OP1a header packet.\n"); + // Kumu::hexdump(p-object->PacketLength(), object->PacketLength()); delete object; } } @@ -854,14 +823,14 @@ ASDCP::MXF::OPAtomHeader::InitFromBuffer(const byte_t* p, ui32_t l) } ASDCP::Result_t -ASDCP::MXF::OPAtomHeader::GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object) +ASDCP::MXF::OP1aHeader::GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object) { return m_PacketList->GetMDObjectByID(ObjectID, Object); } // ASDCP::Result_t -ASDCP::MXF::OPAtomHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object) +ASDCP::MXF::OP1aHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object) { InterchangeObject* TmpObject; @@ -873,14 +842,14 @@ ASDCP::MXF::OPAtomHeader::GetMDObjectByType(const byte_t* ObjectID, InterchangeO // ASDCP::Result_t -ASDCP::MXF::OPAtomHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList) +ASDCP::MXF::OP1aHeader::GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList) { return m_PacketList->GetMDObjectsByType(ObjectID, ObjectList); } // ASDCP::MXF::Identification* -ASDCP::MXF::OPAtomHeader::GetIdentification() +ASDCP::MXF::OP1aHeader::GetIdentification() { InterchangeObject* Object; @@ -892,7 +861,7 @@ ASDCP::MXF::OPAtomHeader::GetIdentification() // ASDCP::MXF::SourcePackage* -ASDCP::MXF::OPAtomHeader::GetSourcePackage() +ASDCP::MXF::OP1aHeader::GetSourcePackage() { InterchangeObject* Object; @@ -903,12 +872,8 @@ ASDCP::MXF::OPAtomHeader::GetSourcePackage() } // -ASDCP::MXF::RIP& -ASDCP::MXF::OPAtomHeader::GetRIP() { return m_RIP; } - -// ASDCP::Result_t -ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize) +ASDCP::MXF::OP1aHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize) { assert(m_Dict); if ( m_Preface == 0 ) @@ -917,7 +882,7 @@ ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSiz if ( HeaderSize < 4096 ) { DefaultLogSink().Error("HeaderSize %u is too small. Must be >= 4096\n", HeaderSize); - return RESULT_FAIL; + return RESULT_PARAM; } ASDCP::FrameBuffer HeaderBuffer; @@ -998,7 +963,7 @@ ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSiz // void -ASDCP::MXF::OPAtomHeader::Dump(FILE* stream) +ASDCP::MXF::OP1aHeader::Dump(FILE* stream) { if ( stream == 0 ) stream = stderr; @@ -1018,8 +983,8 @@ ASDCP::MXF::OPAtomHeader::Dump(FILE* stream) // ASDCP::MXF::OPAtomIndexFooter::OPAtomIndexFooter(const Dictionary*& d) : - Partition(d), - m_CurrentSegment(0), m_BytesPerEditUnit(0), m_BodySID(0), m_Dict(d), + Partition(d), m_Dict(d), + m_CurrentSegment(0), m_BytesPerEditUnit(0), m_BodySID(0), m_ECOffset(0), m_Lookup(0) { BodySID = 0; @@ -1035,26 +1000,36 @@ ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::FileReader& Reader) Result_t result = Partition::InitFromFile(Reader); // test UL and OP // slurp up the remainder of the footer - ui32_t read_count; + ui32_t read_count = 0; - if ( ASDCP_SUCCESS(result) ) + if ( ASDCP_SUCCESS(result) && IndexByteCount > 0 ) { assert (IndexByteCount <= 0xFFFFFFFFL); - result = m_Buffer.Capacity((ui32_t) IndexByteCount); - } + // At this point, m_FooterData may not have been initialized + // so it's capacity is zero and data pointer is NULL + // However, if IndexByteCount is zero then the capacity + // doesn't change and the data pointer is not set. + result = m_FooterData.Capacity((ui32_t) IndexByteCount); - if ( ASDCP_SUCCESS(result) ) - result = Reader.Read(m_Buffer.Data(), m_Buffer.Capacity(), &read_count); + if ( ASDCP_SUCCESS(result) ) + result = Reader.Read(m_FooterData.Data(), m_FooterData.Capacity(), &read_count); - if ( ASDCP_SUCCESS(result) && read_count != m_Buffer.Capacity() ) - { - DefaultLogSink().Error("Short read of footer partition: got %u, expecting %u\n", - read_count, m_Buffer.Capacity()); - return RESULT_FAIL; - } + if ( ASDCP_SUCCESS(result) && read_count != m_FooterData.Capacity() ) + { + DefaultLogSink().Error("Short read of footer partition: got %u, expecting %u\n", + read_count, m_FooterData.Capacity()); + return RESULT_FAIL; + } + else if( ASDCP_SUCCESS(result) && !m_FooterData.Data() ) + { + DefaultLogSink().Error( "Buffer for footer partition not created: IndexByteCount = %u\n", + IndexByteCount ); + return RESULT_FAIL; + } - if ( ASDCP_SUCCESS(result) ) - result = InitFromBuffer(m_Buffer.RoData(), m_Buffer.Capacity()); + if ( ASDCP_SUCCESS(result) ) + result = InitFromBuffer(m_FooterData.RoData(), m_FooterData.Capacity()); + } return result; } @@ -1100,13 +1075,15 @@ ASDCP::MXF::OPAtomIndexFooter::InitFromBuffer(const byte_t* p, ui32_t l) } else { - DefaultLogSink().Error("Error initializing packet\n"); + DefaultLogSink().Error("Error initializing OPAtom footer packet.\n"); delete object; } } if ( ASDCP_FAILURE(result) ) - DefaultLogSink().Error("Failed to initialize OPAtomIndexFooter\n"); + { + DefaultLogSink().Error("Failed to initialize OPAtomIndexFooter.\n"); + } return result; } @@ -1130,17 +1107,17 @@ ASDCP::MXF::OPAtomIndexFooter::WriteToFile(Kumu::FileWriter& Writer, ui64_t dura std::list<InterchangeObject*>::iterator pl_i = m_PacketList->m_List.begin(); for ( ; pl_i != m_PacketList->m_List.end() && ASDCP_SUCCESS(result); pl_i++ ) { - if ( (*pl_i)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) ) + IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*pl_i); + + if ( segment != 0 ) { iseg_count++; - IndexTableSegment* Segment = (IndexTableSegment*)(*pl_i); - if ( m_BytesPerEditUnit != 0 ) { if ( iseg_count != 1 ) return RESULT_STATE; - Segment->IndexDuration = duration; + segment->IndexDuration = duration; } } @@ -1217,28 +1194,29 @@ ASDCP::MXF::OPAtomIndexFooter::Lookup(ui32_t frame_num, IndexTableSegment::Index std::list<InterchangeObject*>::iterator li; for ( li = m_PacketList->m_List.begin(); li != m_PacketList->m_List.end(); li++ ) { - if ( (*li)->IsA(OBJ_TYPE_ARGS(IndexTableSegment)) ) + IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*li); + + if ( segment != 0 ) { - IndexTableSegment* Segment = (IndexTableSegment*)(*li); - ui64_t start_pos = Segment->IndexStartPosition; + ui64_t start_pos = segment->IndexStartPosition; - if ( Segment->EditUnitByteCount > 0 ) + if ( segment->EditUnitByteCount > 0 ) { if ( m_PacketList->m_List.size() > 1 ) DefaultLogSink().Error("Unexpected multiple IndexTableSegment in CBR file\n"); - if ( ! Segment->IndexEntryArray.empty() ) + if ( ! segment->IndexEntryArray.empty() ) DefaultLogSink().Error("Unexpected IndexEntryArray contents in CBR file\n"); - Entry.StreamOffset = (ui64_t)frame_num * Segment->EditUnitByteCount; + Entry.StreamOffset = (ui64_t)frame_num * segment->EditUnitByteCount; return RESULT_OK; } else if ( (ui64_t)frame_num >= start_pos - && (ui64_t)frame_num < (start_pos + Segment->IndexDuration) ) + && (ui64_t)frame_num < (start_pos + segment->IndexDuration) ) { ui64_t tmp = frame_num - start_pos; assert(tmp <= 0xFFFFFFFFL); - Entry = Segment->IndexEntryArray[(ui32_t) tmp]; + Entry = segment->IndexEntryArray[(ui32_t) tmp]; return RESULT_OK; } } @@ -1249,6 +1227,13 @@ ASDCP::MXF::OPAtomIndexFooter::Lookup(ui32_t frame_num, IndexTableSegment::Index // void +ASDCP::MXF::OPAtomIndexFooter::SetDeltaParams(const IndexTableSegment::DeltaEntry& delta) +{ + m_DefaultDeltaEntry = delta; +} + +// +void ASDCP::MXF::OPAtomIndexFooter::SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate) { assert(lookup); @@ -1289,7 +1274,7 @@ ASDCP::MXF::OPAtomIndexFooter::PushIndexEntry(const IndexTableSegment::IndexEntr m_CurrentSegment = new IndexTableSegment(m_Dict); assert(m_CurrentSegment); AddChildObject(m_CurrentSegment); - m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry()); + m_CurrentSegment->DeltaEntryArray.push_back(m_DefaultDeltaEntry); m_CurrentSegment->IndexEditRate = m_EditRate; m_CurrentSegment->IndexStartPosition = 0; } @@ -1301,7 +1286,7 @@ ASDCP::MXF::OPAtomIndexFooter::PushIndexEntry(const IndexTableSegment::IndexEntr m_CurrentSegment = new IndexTableSegment(m_Dict); assert(m_CurrentSegment); AddChildObject(m_CurrentSegment); - m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry()); + m_CurrentSegment->DeltaEntryArray.push_back(m_DefaultDeltaEntry); m_CurrentSegment->IndexEditRate = m_EditRate; m_CurrentSegment->IndexStartPosition = StartPosition; } @@ -1327,7 +1312,7 @@ ASDCP::MXF::InterchangeObject::InitFromTLVSet(TLVReader& TLVSet) { Result_t result = TLVSet.ReadObject(OBJ_READ_ARGS(InterchangeObject, InstanceUID)); if ( ASDCP_SUCCESS(result) ) - result = TLVSet.ReadObject(OBJ_READ_ARGS(GenerationInterchangeObject, GenerationUID)); + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(GenerationInterchangeObject, GenerationUID)); return result; } @@ -1337,7 +1322,7 @@ ASDCP::MXF::InterchangeObject::WriteToTLVSet(TLVWriter& TLVSet) { Result_t result = TLVSet.WriteObject(OBJ_WRITE_ARGS(InterchangeObject, InstanceUID)); if ( ASDCP_SUCCESS(result) ) - result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenerationInterchangeObject, GenerationUID)); + result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(GenerationInterchangeObject, GenerationUID)); return result; } @@ -1397,14 +1382,16 @@ ASDCP::MXF::InterchangeObject::Dump(FILE* stream) fputc('\n', stream); KLVPacket::Dump(stream, *m_Dict, false); fprintf(stream, " InstanceUID = %s\n", InstanceUID.EncodeHex(identbuf, IdentBufferLen)); - fprintf(stream, " GenerationUID = %s\n", GenerationUID.EncodeHex(identbuf, IdentBufferLen)); + + if ( ! GenerationUID.empty() ) + fprintf(stream, " GenerationUID = %s\n", GenerationUID.get().EncodeHex(identbuf, IdentBufferLen)); } // bool ASDCP::MXF::InterchangeObject::IsA(const byte_t* label) { - if ( m_KLLength == 0 ) + if ( m_KLLength == 0 || m_KeyStart == 0 ) return false; return ( memcmp(label, m_KeyStart, SMPTE_UL_LENGTH) == 0 ); @@ -1455,7 +1442,7 @@ static bool s_TypesInit = false; // void -ASDCP::MXF::SetObjectFactory(ASDCP::UL label, ASDCP::MXF::MXFObjectFactory_t factory) +ASDCP::MXF::SetObjectFactory(const ASDCP::UL& label, ASDCP::MXF::MXFObjectFactory_t factory) { s_FactoryList.Insert(label, factory); } @@ -1484,6 +1471,371 @@ ASDCP::MXF::CreateObject(const Dictionary*& Dict, const UL& label) } +//------------------------------------------------------------------------------------------ + +// +bool +ASDCP::MXF::decode_mca_string(const std::string& s, const mca_label_map_t& labels, const Dictionary*& dict, const std::string& language, + InterchangeObject_list_t& descriptor_list, ui32_t& channel_count) +{ + std::string symbol_buf; + channel_count = 0; + ASDCP::MXF::SoundfieldGroupLabelSubDescriptor *current_soundfield = 0; + std::string::const_iterator i; + + for ( i = s.begin(); i != s.end(); ++i ) + { + if ( *i == '(' ) + { + if ( current_soundfield != 0 ) + { + DefaultLogSink().Error("Encountered '(', already processing a soundfield group.\n"); + return false; + } + + if ( symbol_buf.empty() ) + { + DefaultLogSink().Error("Encountered '(', without leading soundfield group symbol.\n"); + return false; + } + + mca_label_map_t::const_iterator i = labels.find(symbol_buf); + + if ( i == labels.end() ) + { + DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str()); + return false; + } + + if ( i->second.ul.Value()[10] != 2 ) // magic depends on UL "Essence Facet" byte (see ST 428-12) + { + DefaultLogSink().Error("Not a soundfield group symbol: '%s'\n", symbol_buf.c_str()); + return false; + } + + current_soundfield = new ASDCP::MXF::SoundfieldGroupLabelSubDescriptor(dict); + GenRandomValue(current_soundfield->MCALinkID); + + current_soundfield->MCATagSymbol = (i->second.requires_prefix ? "sg" : "") + i->first; + current_soundfield->MCATagName = i->second.tag_name; + current_soundfield->RFC5646SpokenLanguage = language; + current_soundfield->MCALabelDictionaryID = i->second.ul; + descriptor_list.push_back(reinterpret_cast<ASDCP::MXF::InterchangeObject*>(current_soundfield)); + symbol_buf.clear(); + } + else if ( *i == ')' ) + { + if ( current_soundfield == 0 ) + { + DefaultLogSink().Error("Encountered ')', not currently processing a soundfield group.\n"); + return false; + } + + if ( symbol_buf.empty() ) + { + DefaultLogSink().Error("Soundfield group description contains no channels.\n"); + return false; + } + + mca_label_map_t::const_iterator i = labels.find(symbol_buf); + + if ( i == labels.end() ) + { + DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str()); + return false; + } + + assert(current_soundfield); + + ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr = + new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict); + GenRandomValue(channel_descr->MCALinkID); + + channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID; + channel_descr->MCAChannelID = channel_count++ + 1; + channel_descr->MCATagSymbol = (i->second.requires_prefix ? "ch" : "") + i->first; + channel_descr->MCATagName = i->second.tag_name; + channel_descr->RFC5646SpokenLanguage = language; + channel_descr->MCALabelDictionaryID = i->second.ul; + descriptor_list.push_back(reinterpret_cast<ASDCP::MXF::InterchangeObject*>(channel_descr)); + symbol_buf.clear(); + current_soundfield = 0; + } + else if ( *i == ',' ) + { + if ( ! symbol_buf.empty() && ! symbol_buf.compare("-") ) + { + channel_count++; + symbol_buf.clear(); + } + else if ( ! symbol_buf.empty() ) + { + mca_label_map_t::const_iterator i = labels.find(symbol_buf); + + if ( i == labels.end() ) + { + DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str()); + return false; + } + + if ( i->second.ul.Value()[10] != 1 ) // magic depends on UL "Essence Facet" byte (see ST 428-12) + { + DefaultLogSink().Error("Not a channel symbol: '%s'\n", symbol_buf.c_str()); + return false; + } + + ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr = + new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict); + GenRandomValue(channel_descr->MCALinkID); + + if ( current_soundfield != 0 ) + { + channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID; + } + + channel_descr->MCAChannelID = channel_count++ + 1; + channel_descr->MCATagSymbol = (i->second.requires_prefix ? "ch" : "") + i->first; + channel_descr->MCATagName = i->second.tag_name; + channel_descr->RFC5646SpokenLanguage = language; + channel_descr->MCALabelDictionaryID = i->second.ul; + descriptor_list.push_back(reinterpret_cast<ASDCP::MXF::InterchangeObject*>(channel_descr)); + symbol_buf.clear(); + } + } + else if ( *i == '-' || isalnum(*i) ) + { + symbol_buf += *i; + } + else if ( ! isspace(*i) ) + { + DefaultLogSink().Error("Unexpected character '%c'.\n", *i); + return false; + } + } + + if ( ! symbol_buf.empty() && ! symbol_buf.compare("-") ) + { + channel_count++; + } + else if ( ! symbol_buf.empty() ) + { + mca_label_map_t::const_iterator i = labels.find(symbol_buf); + + if ( i == labels.end() ) + { + DefaultLogSink().Error("Unknown symbol: '%s'\n", symbol_buf.c_str()); + return false; + } + + ASDCP::MXF::AudioChannelLabelSubDescriptor *channel_descr = + new ASDCP::MXF::AudioChannelLabelSubDescriptor(dict); + GenRandomValue(channel_descr->MCALinkID); + + if ( current_soundfield != 0 ) + { + channel_descr->SoundfieldGroupLinkID = current_soundfield->MCALinkID; + } + + channel_descr->MCAChannelID = channel_count++ + 1; + channel_descr->MCATagSymbol = (i->second.requires_prefix ? "ch" : "") + i->first; + channel_descr->MCATagName = i->second.tag_name; + channel_descr->RFC5646SpokenLanguage = language; + channel_descr->MCALabelDictionaryID = i->second.ul; + descriptor_list.push_back(reinterpret_cast<ASDCP::MXF::InterchangeObject*>(channel_descr)); + } + + return true; +} + +// +ASDCP::MXF::ASDCP_MCAConfigParser::ASDCP_MCAConfigParser(const Dictionary*& d) : m_Dict(d), m_ChannelCount(0) +{ + typedef mca_label_map_t::value_type pair; + m_LabelMap.insert(pair("L", label_traits("Left" , true, m_Dict->ul(MDD_DCAudioChannel_L)))); + m_LabelMap.insert(pair("R", label_traits("Right" , true, m_Dict->ul(MDD_DCAudioChannel_R)))); + m_LabelMap.insert(pair("C", label_traits("Center" , true, m_Dict->ul(MDD_DCAudioChannel_C)))); + m_LabelMap.insert(pair("LFE", label_traits("LFE" , true, m_Dict->ul(MDD_DCAudioChannel_LFE)))); + m_LabelMap.insert(pair("Ls", label_traits("Left Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Ls)))); + m_LabelMap.insert(pair("Rs", label_traits("Right Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Rs)))); + m_LabelMap.insert(pair("Lss", label_traits("Left Side Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Lss)))); + m_LabelMap.insert(pair("Rss", label_traits("Right Side Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Rss)))); + m_LabelMap.insert(pair("Lrs", label_traits("Left Rear Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Lrs)))); + m_LabelMap.insert(pair("Rrs", label_traits("Right Rear Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Rrs)))); + m_LabelMap.insert(pair("Lc", label_traits("Left Center" , true, m_Dict->ul(MDD_DCAudioChannel_Lc)))); + m_LabelMap.insert(pair("Rc", label_traits("Right Center" , true, m_Dict->ul(MDD_DCAudioChannel_Rc)))); + m_LabelMap.insert(pair("Cs", label_traits("Center Surround" , true, m_Dict->ul(MDD_DCAudioChannel_Cs)))); + m_LabelMap.insert(pair("HI", label_traits("Hearing Impaired" , true, m_Dict->ul(MDD_DCAudioChannel_HI)))); + m_LabelMap.insert(pair("VIN", label_traits("Visually Impaired-Narrative" , true, m_Dict->ul(MDD_DCAudioChannel_VIN)))); + m_LabelMap.insert(pair("51", label_traits("5.1" , true, m_Dict->ul(MDD_DCAudioSoundfield_51)))); + m_LabelMap.insert(pair("71", label_traits("7.1DS" , true, m_Dict->ul(MDD_DCAudioSoundfield_71)))); + m_LabelMap.insert(pair("SDS", label_traits("7.1SDS" , true, m_Dict->ul(MDD_DCAudioSoundfield_SDS)))); + m_LabelMap.insert(pair("61", label_traits("6.1" , true, m_Dict->ul(MDD_DCAudioSoundfield_61)))); + m_LabelMap.insert(pair("M", label_traits("1.0 Monaural" , true, m_Dict->ul(MDD_DCAudioSoundfield_M)))); + m_LabelMap.insert(pair("DBOX", label_traits("D-BOX Motion Code Primary Stream" , false, m_Dict->ul(MDD_DBOXMotionCodePrimaryStream)))); + m_LabelMap.insert(pair("DBOX2", label_traits("D-BOX Motion Code Secondary Stream", false, m_Dict->ul(MDD_DBOXMotionCodeSecondaryStream)))); +} + +// +ui32_t +ASDCP::MXF::ASDCP_MCAConfigParser::ChannelCount() const +{ + return m_ChannelCount; +} + +// 51(L,R,C,LFE,Ls,Rs),HI,VIN +bool +ASDCP::MXF::ASDCP_MCAConfigParser::DecodeString(const std::string& s, const std::string& language) +{ + return decode_mca_string(s, m_LabelMap, m_Dict, language, *this, m_ChannelCount); +} + + + +ASDCP::MXF::AS02_MCAConfigParser::AS02_MCAConfigParser(const Dictionary*& d) : ASDCP::MXF::ASDCP_MCAConfigParser(d) +{ + typedef mca_label_map_t::value_type pair; + m_LabelMap.insert(pair("M1", label_traits("M1", true, m_Dict->ul(MDD_IMFAudioChannel_M1)))); + m_LabelMap.insert(pair("M2", label_traits("M2", true, m_Dict->ul(MDD_IMFAudioChannel_M2)))); + m_LabelMap.insert(pair("Lt", label_traits("Lt", true, m_Dict->ul(MDD_IMFAudioChannel_Lt)))); + m_LabelMap.insert(pair("Rt", label_traits("Rt", true, m_Dict->ul(MDD_IMFAudioChannel_Rt)))); + m_LabelMap.insert(pair("Lst", label_traits("Lst", true, m_Dict->ul(MDD_IMFAudioChannel_Lst)))); + m_LabelMap.insert(pair("Rst", label_traits("Rst", true, m_Dict->ul(MDD_IMFAudioChannel_Rst)))); + m_LabelMap.insert(pair("S", label_traits("S", true, m_Dict->ul(MDD_IMFAudioChannel_S)))); + m_LabelMap.insert(pair("ST", label_traits("ST", true, m_Dict->ul(MDD_IMFAudioSoundfield_ST)))); + m_LabelMap.insert(pair("DM", label_traits("DM", true, m_Dict->ul(MDD_IMFAudioSoundfield_DM)))); + m_LabelMap.insert(pair("DNS", label_traits("DNS", true, m_Dict->ul(MDD_IMFAudioSoundfield_DNS)))); + m_LabelMap.insert(pair("30", label_traits("30", true, m_Dict->ul(MDD_IMFAudioSoundfield_30)))); + m_LabelMap.insert(pair("40", label_traits("40", true, m_Dict->ul(MDD_IMFAudioSoundfield_40)))); + m_LabelMap.insert(pair("50", label_traits("50", true, m_Dict->ul(MDD_IMFAudioSoundfield_50)))); + m_LabelMap.insert(pair("60", label_traits("60", true, m_Dict->ul(MDD_IMFAudioSoundfield_60)))); + m_LabelMap.insert(pair("70", label_traits("70", true, m_Dict->ul(MDD_IMFAudioSoundfield_70)))); + m_LabelMap.insert(pair("LtRt", label_traits("LtRt",true, m_Dict->ul(MDD_IMFAudioSoundfield_LtRt)))); + m_LabelMap.insert(pair("51Ex", label_traits("51Ex",true, m_Dict->ul(MDD_IMFAudioSoundfield_51Ex)))); + m_LabelMap.insert(pair("HI", label_traits("HI", true, m_Dict->ul(MDD_IMFAudioSoundfield_HI)))); + m_LabelMap.insert(pair("VIN", label_traits("VIN", true, m_Dict->ul(MDD_IMFAudioSoundfield_VIN)))); +} + + + +// +bool +ASDCP::MXF::GetEditRateFromFP(ASDCP::MXF::OP1aHeader& header, ASDCP::Rational& edit_rate) +{ + bool has_first_item = false; + + MXF::InterchangeObject* temp_item; + std::list<MXF::InterchangeObject*> temp_items; + + Result_t result = header.GetMDObjectsByType(DefaultCompositeDict().ul(MDD_SourcePackage), temp_items); + + if ( KM_FAILURE(result) ) + { + DefaultLogSink().Error("The MXF header does not contain a FilePackage item.\n"); + return false; + } + + if ( temp_items.size() != 1 ) + { + DefaultLogSink().Error("The MXF header must contain one FilePackage item, found %d.\n", temp_items.size()); + return false; + } + + char buf[64]; + MXF::Array<UUID>::const_iterator i; + MXF::SourcePackage *source_package = dynamic_cast<MXF::SourcePackage*>(temp_items.front()); + assert(source_package); + + for ( i = source_package->Tracks.begin(); i != source_package->Tracks.end(); ++i ) + { + // Track + result = header.GetMDObjectByID(*i, &temp_item); + + if ( KM_FAILURE(result) ) + { + DefaultLogSink().Error("The MXF header is incomplete: strong reference %s leads nowhere.\n", + i->EncodeHex(buf, 64)); + return false; + } + + MXF::Track *track = dynamic_cast<MXF::Track*>(temp_item); + + if ( track == 0 ) + { + DefaultLogSink().Error("The MXF header is incomplete: %s is not a Track item.\n", + i->EncodeHex(buf, 64)); + return false; + } + + // Sequence + result = header.GetMDObjectByID(track->Sequence, &temp_item); + + if ( KM_FAILURE(result) ) + { + DefaultLogSink().Error("The MXF header is incomplete: strong reference %s leads nowhere.\n", + i->EncodeHex(buf, 64)); + return false; + } + + MXF::Sequence *sequence = dynamic_cast<MXF::Sequence*>(temp_item); + + if ( sequence == 0 ) + { + DefaultLogSink().Error("The MXF header is incomplete: %s is not a Sequence item.\n", + track->Sequence.get().EncodeHex(buf, 64)); + return false; + } + + if ( sequence->StructuralComponents.size() != 1 ) + { + DefaultLogSink().Error("The Sequence item must contain one reference to an esence item, found %d.\n", + sequence->StructuralComponents.size()); + return false; + } + + // SourceClip + result = header.GetMDObjectByID(sequence->StructuralComponents.front(), &temp_item); + + if ( KM_FAILURE(result) ) + { + DefaultLogSink().Error("The MXF header is incomplete: strong reference %s leads nowhere.\n", + sequence->StructuralComponents.front().EncodeHex(buf, 64)); + return false; + } + + if ( temp_item->IsA(DefaultCompositeDict().ul(MDD_SourceClip)) ) + { + MXF::SourceClip *source_clip = dynamic_cast<MXF::SourceClip*>(temp_item); + + if ( source_clip == 0 ) + { + DefaultLogSink().Error("The MXF header is incomplete: %s is not a SourceClip item.\n", + sequence->StructuralComponents.front().EncodeHex(buf, 64)); + return false; + } + + if ( ! has_first_item ) + { + edit_rate = track->EditRate; + has_first_item = true; + } + else if ( edit_rate != track->EditRate ) + { + DefaultLogSink().Error("The MXF header is incomplete: %s EditRate value does not match others in the file.\n", + sequence->StructuralComponents.front().EncodeHex(buf, 64)); + return false; + } + } + else if ( ! temp_item->IsA(DefaultCompositeDict().ul(MDD_TimecodeComponent)) ) + { + DefaultLogSink().Error("Reference from Sequence to an unexpected type: %s.\n", temp_item->ObjectName()); + return false; + } + } + + return true; +} + + // // end MXF.cpp // diff --git a/asdcplib/src/MXF.h b/asdcplib/src/MXF.h index c170a2d5..93a4dbbd 100755 --- a/asdcplib/src/MXF.h +++ b/asdcplib/src/MXF.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file MXF.h - \version $Id: MXF.h,v 1.42 2012/03/05 13:11:47 jhurst Exp $ + \version $Id: MXF.h,v 1.57 2015/10/10 20:26:29 jhurst Exp $ \brief MXF objects */ @@ -33,6 +33,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define _MXF_H_ #include "MXFTypes.h" +#include <algorithm> namespace ASDCP { @@ -40,11 +41,13 @@ namespace ASDCP { class InterchangeObject; + const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH; + // typedef ASDCP::MXF::InterchangeObject* (*MXFObjectFactory_t)(const Dictionary*&); // - void SetObjectFactory(UL label, MXFObjectFactory_t factory); + void SetObjectFactory(const UL& label, MXFObjectFactory_t factory); // InterchangeObject* CreateObject(const Dictionary*& Dict, const UL& label); @@ -61,15 +64,15 @@ namespace ASDCP public: // - class Pair : public Kumu::IArchive + class PartitionPair : public Kumu::IArchive { public: ui32_t BodySID; ui64_t ByteOffset; - Pair() : BodySID(0), ByteOffset(0) {} - Pair(ui32_t sid, ui64_t offset) : BodySID(sid), ByteOffset(offset) {} - virtual ~Pair() {} + PartitionPair() : BodySID(0), ByteOffset(0) {} + PartitionPair(ui32_t sid, ui64_t offset) : BodySID(sid), ByteOffset(offset) {} + virtual ~PartitionPair() {} ui32_t Size() { return sizeof(ui32_t) + sizeof(ui64_t); } @@ -96,13 +99,17 @@ namespace ASDCP }; const Dictionary*& m_Dict; - Array<Pair> PairArray; + + typedef SimpleArray<PartitionPair>::iterator pair_iterator; + typedef SimpleArray<PartitionPair>::const_iterator const_pair_iterator; + + SimpleArray<PartitionPair> PairArray; RIP(const Dictionary*& d) : m_Dict(d) {} virtual ~RIP() {} virtual Result_t InitFromFile(const Kumu::FileReader& Reader); virtual Result_t WriteToFile(Kumu::FileWriter& Writer); - virtual Result_t GetPairBySID(ui32_t, Pair&) const; + virtual bool GetPairBySID(ui32_t, PartitionPair&) const; virtual void Dump(FILE* = 0); }; @@ -114,8 +121,20 @@ namespace ASDCP Partition(); protected: - class h__PacketList; - mem_ptr<h__PacketList> m_PacketList; + class PacketList + { + public: + std::list<InterchangeObject*> m_List; + std::map<UUID, InterchangeObject*> m_Map; + + ~PacketList(); + void AddPacket(InterchangeObject* ThePacket); // takes ownership + Result_t GetMDObjectByID(const UUID& ObjectID, InterchangeObject** Object); + Result_t GetMDObjectByType(const byte_t* ObjectID, InterchangeObject** Object); + Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList); + }; + + mem_ptr<PacketList> m_PacketList; public: const Dictionary*& m_Dict; @@ -165,6 +184,10 @@ namespace ASDCP LocalTagEntry() { Tag.a = Tag.b = 0; } LocalTagEntry(const TagValue& tag, ASDCP::UL& ul) : Tag(tag), UL(ul) {} + bool operator<(const LocalTagEntry& rhs) const { + return ( ( Tag.a < rhs.Tag.a ) || ( Tag.b < rhs.Tag.b ) ); + } + inline const char* EncodeString(char* str_buf, ui32_t buf_len) const { snprintf(str_buf, buf_len, "%02x %02x: ", Tag.a, Tag.b); UL.EncodeString(str_buf + strlen(str_buf), buf_len - strlen(str_buf)); @@ -203,7 +226,57 @@ namespace ASDCP virtual void Dump(FILE* = 0); }; + // wrapper object manages optional properties + template <class PropertyType> + class optional_property + { + PropertyType m_property; + bool m_has_value; + + public: + optional_property() : m_has_value(false) {} + optional_property(const PropertyType& value) : m_property(value), m_has_value(true) {} + const optional_property<PropertyType>& operator=(const PropertyType& rhs) { + this->m_property = rhs; + this->m_has_value = true; + return *this; + } + bool operator==(const PropertyType& rhs) const { return this->m_property == rhs; } + bool operator==(const optional_property<PropertyType>& rhs) const { return this->m_property == rhs.m_property; } + operator PropertyType&() { return this->m_property; } + void set(const PropertyType& rhs) { this->m_property = rhs; this->m_has_value = true; } + void set_has_value(bool has_value = true) { this->m_has_value = has_value; } + void reset(const PropertyType& rhs) { this->m_has_value = false; } + bool empty() const { return ! m_has_value; } + PropertyType& get() { return m_property; } + const PropertyType& const_get() const { return m_property; } + }; + + // wrapper object manages optional properties + template <class PropertyType> + class optional_container_property + { + PropertyType m_property; + + public: + optional_container_property() {} + optional_container_property(const PropertyType& value) : m_property(value) {} + const optional_container_property<PropertyType>& operator=(const PropertyType& rhs) { + this->Copy(rhs.m_property); + return *this; + } + + bool operator==(const PropertyType& rhs) const { return this->m_property == rhs; } + bool operator==(const optional_property<PropertyType>& rhs) const { return this->m_property == rhs.m_property; } + operator PropertyType&() { return this->m_property; } + void set(const PropertyType& rhs) { this->m_property = rhs; } + void reset(const PropertyType& rhs) { this->clear(); } + bool empty() const { return ! this->m_property.HasValue(); } + PropertyType& get() { return m_property; } + const PropertyType& const_get() const { return m_property; } + }; + // base class of all metadata objects // class InterchangeObject : public ASDCP::KLVPacket { @@ -213,7 +286,7 @@ namespace ASDCP const Dictionary*& m_Dict; IPrimerLookup* m_Lookup; UUID InstanceUID; - UUID GenerationUID; + optional_property<UUID> GenerationUID; InterchangeObject(const Dictionary*& d) : m_Dict(d), m_Lookup(0) {} virtual ~InterchangeObject() {} @@ -229,6 +302,9 @@ namespace ASDCP }; // + typedef std::list<InterchangeObject*> InterchangeObject_list_t; + + // class Preface : public InterchangeObject { ASDCP_NO_COPY_CONSTRUCT(Preface); @@ -238,13 +314,14 @@ namespace ASDCP const Dictionary*& m_Dict; Kumu::Timestamp LastModifiedDate; ui16_t Version; - ui32_t ObjectModelVersion; - UUID PrimaryPackage; - Batch<UUID> Identifications; + optional_property<ui32_t> ObjectModelVersion; + optional_property<UUID> PrimaryPackage; + Array<UUID> Identifications; UUID ContentStorage; UL OperationalPattern; Batch<UL> EssenceContainers; Batch<UL> DMSchemes; + optional_property<Batch<UL> > ApplicationSchemes; Preface(const Dictionary*& d); virtual ~Preface() {} @@ -262,6 +339,7 @@ namespace ASDCP // class IndexTableSegment : public InterchangeObject { + IndexTableSegment(); ASDCP_NO_COPY_CONSTRUCT(IndexTableSegment); public: @@ -273,7 +351,7 @@ namespace ASDCP ui8_t Slice; ui32_t ElementData; - DeltaEntry() : PosTableIndex(-1), Slice(0), ElementData(0) {} + DeltaEntry() : PosTableIndex(0), Slice(0), ElementData(0) {} DeltaEntry(i8_t pos, ui8_t slice, ui32_t data) : PosTableIndex(pos), Slice(slice), ElementData(data) {} inline bool HasValue() const { return true; } ui32_t ArchiveLength() const { return sizeof(ui32_t) + 2; } @@ -307,6 +385,8 @@ namespace ASDCP }; const Dictionary*& m_Dict; + ui64_t RtFileOffset; // not part of the MXF structure: used to manage runtime index access + ui64_t RtEntryOffset; Rational IndexEditRate; ui64_t IndexStartPosition; @@ -316,8 +396,8 @@ namespace ASDCP ui32_t BodySID; ui8_t SliceCount; ui8_t PosTableCount; - Batch<DeltaEntry> DeltaEntryArray; - Batch<IndexEntry> IndexEntryArray; + Array<DeltaEntry> DeltaEntryArray; + Array<IndexEntry> IndexEntryArray; IndexTableSegment(const Dictionary*&); virtual ~IndexTableSegment(); @@ -336,21 +416,19 @@ namespace ASDCP class SourcePackage; // - class OPAtomHeader : public Partition + class OP1aHeader : public Partition { - ASDCP_NO_COPY_CONSTRUCT(OPAtomHeader); - OPAtomHeader(); + Kumu::ByteString m_HeaderData; + ASDCP_NO_COPY_CONSTRUCT(OP1aHeader); + OP1aHeader(); public: - const Dictionary*& m_Dict; - ASDCP::MXF::RIP m_RIP; + const Dictionary*& m_Dict; ASDCP::MXF::Primer m_Primer; Preface* m_Preface; - ASDCP::FrameBuffer m_Buffer; - bool m_HasRIP; - OPAtomHeader(const Dictionary*&); - virtual ~OPAtomHeader(); + OP1aHeader(const Dictionary*&); + virtual ~OP1aHeader(); virtual Result_t InitFromFile(const Kumu::FileReader& Reader); virtual Result_t InitFromPartitionBuffer(const byte_t* p, ui32_t l); virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l); @@ -359,19 +437,23 @@ namespace ASDCP virtual Result_t GetMDObjectByID(const UUID&, InterchangeObject** = 0); virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0); virtual Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<InterchangeObject*>& ObjectList); - virtual ASDCP::MXF::RIP& GetRIP(); Identification* GetIdentification(); SourcePackage* GetSourcePackage(); }; + // Searches the header object and returns the edit rate based on the contents of the + // File Package items. Logs an error message and returns false if anthing goes wrong. + bool GetEditRateFromFP(ASDCP::MXF::OP1aHeader& header, ASDCP::Rational& edit_rate); + // class OPAtomIndexFooter : public Partition { + Kumu::ByteString m_FooterData; IndexTableSegment* m_CurrentSegment; - ASDCP::FrameBuffer m_Buffer; ui32_t m_BytesPerEditUnit; Rational m_EditRate; ui32_t m_BodySID; + IndexTableSegment::DeltaEntry m_DefaultDeltaEntry; ASDCP_NO_COPY_CONSTRUCT(OPAtomIndexFooter); OPAtomIndexFooter(); @@ -395,10 +477,73 @@ namespace ASDCP virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&) const; virtual void PushIndexEntry(const IndexTableSegment::IndexEntry&); + virtual void SetDeltaParams(const IndexTableSegment::DeltaEntry&); virtual void SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t size, const Rational& Rate); virtual void SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset); }; + //--------------------------------------------------------------------------------- + // + + // + inline std::string to_lower(std::string str) { + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + return str; + } + + // ignore case when searching for audio labels + struct ci_comp + { + inline bool operator()(const std::string& a, const std::string& b) const { + return to_lower(a) < to_lower(b); + } + }; + + struct label_traits + { + const std::string tag_name; + const bool requires_prefix; + const UL ul; + + label_traits(const std::string& tag_name, const bool requires_prefix, const UL ul) : + tag_name(tag_name), requires_prefix(requires_prefix), ul(ul) { } + }; + + typedef std::map<const std::string, const label_traits, ci_comp> mca_label_map_t; + + bool decode_mca_string(const std::string& s, const mca_label_map_t& labels, + const Dictionary*& dict, const std::string& language, InterchangeObject_list_t&, ui32_t&); + + // + class ASDCP_MCAConfigParser : public InterchangeObject_list_t + { + KM_NO_COPY_CONSTRUCT(ASDCP_MCAConfigParser); + ASDCP_MCAConfigParser(); + + protected: + mca_label_map_t m_LabelMap; + ui32_t m_ChannelCount; + const Dictionary*& m_Dict; + + + public: + ASDCP_MCAConfigParser(const Dictionary*&); + bool DecodeString(const std::string& s, const std::string& language = "en-US"); + + // Valid only after a successful call to DecodeString + ui32_t ChannelCount() const; + }; + + // + class AS02_MCAConfigParser : public ASDCP_MCAConfigParser + { + KM_NO_COPY_CONSTRUCT(AS02_MCAConfigParser); + AS02_MCAConfigParser(); + + public: + AS02_MCAConfigParser(const Dictionary*&); + }; + } // namespace MXF } // namespace ASDCP diff --git a/asdcplib/src/MXFTypes.cpp b/asdcplib/src/MXFTypes.cpp index 13bdaa0d..39a25210 100755 --- a/asdcplib/src/MXFTypes.cpp +++ b/asdcplib/src/MXFTypes.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file MXFTypes.cpp - \version $Id: MXFTypes.cpp,v 1.27 2012/02/21 02:09:31 jhurst Exp $ + \version $Id: MXFTypes.cpp,v 1.33 2015/10/12 15:30:46 jhurst Exp $ \brief MXF objects */ @@ -123,7 +123,7 @@ ASDCP::UL::EncodeString(char* str_buf, ui32_t buf_len) const if ( buf_len > 38 ) // room for dotted notation? { snprintf(str_buf, buf_len, - "%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x", + "%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x", m_Value[0], m_Value[1], m_Value[2], m_Value[3], m_Value[4], m_Value[5], m_Value[6], m_Value[7], m_Value[8], m_Value[9], m_Value[10], m_Value[11], @@ -189,7 +189,7 @@ ASDCP::UMID::EncodeString(char* str_buf, ui32_t buf_len) const { assert(str_buf); - snprintf(str_buf, buf_len, "[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x],%02x,%02x,%02x,%02x,", + snprintf(str_buf, buf_len, "[%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x],%02x,%02x,%02x,%02x,", m_Value[0], m_Value[1], m_Value[2], m_Value[3], m_Value[4], m_Value[5], m_Value[6], m_Value[7], m_Value[8], m_Value[9], m_Value[10], m_Value[11], @@ -202,7 +202,7 @@ ASDCP::UMID::EncodeString(char* str_buf, ui32_t buf_len) const { // half-swapped UL, use [bbaa9988.ddcc.ffee.00010203.04050607] snprintf(str_buf + offset, buf_len - offset, - "[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x]", + "[%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x]", m_Value[24], m_Value[25], m_Value[26], m_Value[27], m_Value[28], m_Value[29], m_Value[30], m_Value[31], m_Value[16], m_Value[17], m_Value[18], m_Value[19], @@ -228,6 +228,20 @@ ASDCP::UMID::EncodeString(char* str_buf, ui32_t buf_len) const // // +ASDCP::MXF::UTF16String::UTF16String(const char* sz) +{ + if ( sz != 0 && *sz != 0 ) + { + this->assign(sz); + } +} + +ASDCP::MXF::UTF16String::UTF16String(const std::string& str) +{ + this->assign(str); +} + +// const ASDCP::MXF::UTF16String& ASDCP::MXF::UTF16String::operator=(const char* sz) { @@ -312,7 +326,9 @@ ASDCP::MXF::UTF16String::Archive(Kumu::MemIOWriter* Writer) const return false; } else if ( count == 0 ) - break; + { + break; + } bool result = Writer->WriteUi16BE((ui16_t)wcp); @@ -333,6 +349,21 @@ ASDCP::MXF::UTF16String::Archive(Kumu::MemIOWriter* Writer) const // // +ASDCP::MXF::ISO8String::ISO8String(const char* sz) +{ + if ( sz != 0 && *sz != 0 ) + { + this->assign(sz); + } +} + +ASDCP::MXF::ISO8String::ISO8String(const std::string& str) +{ + this->assign(str); +} + + +// const ASDCP::MXF::ISO8String& ASDCP::MXF::ISO8String::operator=(const char* sz) { @@ -381,7 +412,7 @@ ASDCP::MXF::ISO8String::Archive(Kumu::MemIOWriter* Writer) const return false; } - return Writer->WriteString(*this); + return Writer->WriteRaw((const byte_t*)c_str(), size()); } //------------------------------------------------------------------------------------------ @@ -408,7 +439,7 @@ ASDCP::MXF::TLVReader::TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* Prime DefaultLogSink().Error("Malformed Set\n"); m_ElementMap.clear(); - result = RESULT_KLV_CODING; + result = RESULT_KLV_CODING(__LINE__, __FILE__); } } @@ -458,7 +489,10 @@ ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, Kumu::IArchive* Object) if ( FindTL(Entry) ) { if ( m_size < m_capacity ) // don't try to unarchive an empty item - return Object->Unarchive(this) ? RESULT_OK : RESULT_KLV_CODING; + { + // TODO: carry on if uachive fails + return Object->Unarchive(this) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__); + } } return RESULT_FALSE; @@ -471,7 +505,7 @@ ASDCP::MXF::TLVReader::ReadUi8(const MDDEntry& Entry, ui8_t* value) ASDCP_TEST_NULL(value); if ( FindTL(Entry) ) - return MemIOReader::ReadUi8(value) ? RESULT_OK : RESULT_KLV_CODING; + return MemIOReader::ReadUi8(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__); return RESULT_FALSE; } @@ -483,7 +517,7 @@ ASDCP::MXF::TLVReader::ReadUi16(const MDDEntry& Entry, ui16_t* value) ASDCP_TEST_NULL(value); if ( FindTL(Entry) ) - return MemIOReader::ReadUi16BE(value) ? RESULT_OK : RESULT_KLV_CODING; + return MemIOReader::ReadUi16BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__); return RESULT_FALSE; } @@ -495,7 +529,7 @@ ASDCP::MXF::TLVReader::ReadUi32(const MDDEntry& Entry, ui32_t* value) ASDCP_TEST_NULL(value); if ( FindTL(Entry) ) - return MemIOReader::ReadUi32BE(value) ? RESULT_OK : RESULT_KLV_CODING; + return MemIOReader::ReadUi32BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__); return RESULT_FALSE; } @@ -507,7 +541,7 @@ ASDCP::MXF::TLVReader::ReadUi64(const MDDEntry& Entry, ui64_t* value) ASDCP_TEST_NULL(value); if ( FindTL(Entry) ) - return MemIOReader::ReadUi64BE(value) ? RESULT_OK : RESULT_KLV_CODING; + return MemIOReader::ReadUi64BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__); return RESULT_FALSE; } @@ -539,8 +573,8 @@ ASDCP::MXF::TLVWriter::WriteTag(const MDDEntry& Entry) return RESULT_FAIL; } - if ( ! MemIOWriter::WriteUi8(TmpTag.a) ) return RESULT_KLV_CODING; - if ( ! MemIOWriter::WriteUi8(TmpTag.b) ) return RESULT_KLV_CODING; + if ( ! MemIOWriter::WriteUi8(TmpTag.a) ) return RESULT_KLV_CODING(__LINE__, __FILE__); + if ( ! MemIOWriter::WriteUi8(TmpTag.b) ) return RESULT_KLV_CODING(__LINE__, __FILE__); return RESULT_OK; } @@ -560,11 +594,11 @@ ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, Kumu::IArchive* Object // write a temp length byte_t* l_p = CurrentData(); - if ( ! MemIOWriter::WriteUi16BE(0) ) return RESULT_KLV_CODING; + if ( ! MemIOWriter::WriteUi16BE(0) ) return RESULT_KLV_CODING(__LINE__, __FILE__); ui32_t before = Length(); - if ( ! Object->Archive(this) ) return RESULT_KLV_CODING; - if ( (Length() - before) > 0xffffL ) return RESULT_KLV_CODING; + if ( ! Object->Archive(this) ) return RESULT_KLV_CODING(__LINE__, __FILE__); + if ( (Length() - before) > 0xffffL ) return RESULT_KLV_CODING(__LINE__, __FILE__); Kumu::i2p<ui16_t>(KM_i16_BE(Length() - before), l_p); } @@ -580,8 +614,8 @@ ASDCP::MXF::TLVWriter::WriteUi8(const MDDEntry& Entry, ui8_t* value) if ( ASDCP_SUCCESS(result) ) { - if ( ! MemIOWriter::WriteUi16BE(sizeof(ui8_t)) ) return RESULT_KLV_CODING; - if ( ! MemIOWriter::WriteUi8(*value) ) return RESULT_KLV_CODING; + if ( ! MemIOWriter::WriteUi16BE(sizeof(ui8_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__); + if ( ! MemIOWriter::WriteUi8(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__); } return result; @@ -596,8 +630,8 @@ ASDCP::MXF::TLVWriter::WriteUi16(const MDDEntry& Entry, ui16_t* value) if ( KM_SUCCESS(result) ) { - if ( ! MemIOWriter::WriteUi16BE(sizeof(ui16_t)) ) return RESULT_KLV_CODING; - if ( ! MemIOWriter::WriteUi16BE(*value) ) return RESULT_KLV_CODING; + if ( ! MemIOWriter::WriteUi16BE(sizeof(ui16_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__); + if ( ! MemIOWriter::WriteUi16BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__); } return result; @@ -612,8 +646,8 @@ ASDCP::MXF::TLVWriter::WriteUi32(const MDDEntry& Entry, ui32_t* value) if ( KM_SUCCESS(result) ) { - if ( ! MemIOWriter::WriteUi16BE(sizeof(ui32_t)) ) return RESULT_KLV_CODING; - if ( ! MemIOWriter::WriteUi32BE(*value) ) return RESULT_KLV_CODING; + if ( ! MemIOWriter::WriteUi16BE(sizeof(ui32_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__); + if ( ! MemIOWriter::WriteUi32BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__); } return result; @@ -628,8 +662,8 @@ ASDCP::MXF::TLVWriter::WriteUi64(const MDDEntry& Entry, ui64_t* value) if ( KM_SUCCESS(result) ) { - if ( ! MemIOWriter::WriteUi16BE(sizeof(ui64_t)) ) return RESULT_KLV_CODING; - if ( ! MemIOWriter::WriteUi64BE(*value) ) return RESULT_KLV_CODING; + if ( ! MemIOWriter::WriteUi16BE(sizeof(ui64_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__); + if ( ! MemIOWriter::WriteUi64BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__); } return result; @@ -639,6 +673,63 @@ ASDCP::MXF::TLVWriter::WriteUi64(const MDDEntry& Entry, ui64_t* value) //---------------------------------------------------------------------------------------------------- // + +ASDCP::MXF::RGBALayout::RGBALayout() +{ + memset(m_value, 0, RGBAValueLength); +} + +ASDCP::MXF::RGBALayout::RGBALayout(const byte_t* value) +{ + memcpy(m_value, value, RGBAValueLength); +} + +ASDCP::MXF::RGBALayout::~RGBALayout() +{ +} + +static char +get_char_for_code(byte_t c) +{ + for ( int i = 0; ASDCP::MXF::RGBALayoutTable[i].code != 0; ++i ) + { + if ( ASDCP::MXF::RGBALayoutTable[i].code == c ) + { + return ASDCP::MXF::RGBALayoutTable[i].symbol; + } + } + + return '_'; +} + +// +const char* +ASDCP::MXF::RGBALayout::EncodeString(char* buf, ui32_t buf_len) const +{ + std::string tmp_str; + char tmp_buf[64]; + + for ( int i = 0; i < RGBAValueLength && m_value[i] != 0; i += 2 ) + { + snprintf(tmp_buf, 64, "%c(%d)", get_char_for_code(m_value[i]), m_value[i+1]); + + if ( ! tmp_str.empty() ) + { + tmp_str += " "; + } + + tmp_str += tmp_buf; + } + + assert(tmp_str.size() < buf_len); + strncpy(buf, tmp_str.c_str(), tmp_str.size()); + return buf; +} + + +//---------------------------------------------------------------------------------------------------- +// + ASDCP::MXF::Raw::Raw() { Capacity(256); diff --git a/asdcplib/src/MXFTypes.h b/asdcplib/src/MXFTypes.h index 4ab67721..19f97c38 100755 --- a/asdcplib/src/MXFTypes.h +++ b/asdcplib/src/MXFTypes.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file MXFTypes.h - \version $Id: MXFTypes.h,v 1.29 2012/02/21 02:09:31 jhurst Exp $ + \version $Id: MXFTypes.h,v 1.38 2015/10/12 15:30:46 jhurst Exp $ \brief MXF objects */ @@ -35,6 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "KLV.h" #include <list> #include <vector> +#include <set> #include <map> #include <wchar.h> @@ -43,6 +44,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // these are used below to manufacture arguments #define OBJ_READ_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l #define OBJ_WRITE_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l +#define OBJ_READ_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get() +#define OBJ_WRITE_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get() #define OBJ_TYPE_ARGS(t) m_Dict->Type(MDD_##t).ul @@ -94,97 +97,117 @@ namespace ASDCP }; // - template <class T> - class Batch : public std::vector<T>, public Kumu::IArchive + template <class ContainerType> + class FixedSizeItemCollection : public ContainerType, public Kumu::IArchive { public: - Batch() {} - ~Batch() {} + FixedSizeItemCollection() {} + virtual ~FixedSizeItemCollection() {} - // - virtual bool Unarchive(Kumu::MemIOReader* Reader) { - ui32_t ItemCount, ItemSize; - if ( ! Reader->ReadUi32BE(&ItemCount) ) return false; - if ( ! Reader->ReadUi32BE(&ItemSize) ) return false; + ui32_t ItemSize() const { + typename ContainerType::value_type tmp_item; + return tmp_item.ArchiveLength(); + } - if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) ) - return false; + bool HasValue() const { return ! this->empty(); } + ui32_t ArchiveLength() const { + return ( sizeof(ui32_t) * 2 ) + ( this->size() * this->ItemSize() ); + } + + bool Archive(Kumu::MemIOWriter* Writer) const { + if ( ! Writer->WriteUi32BE(this->size()) ) return false; + if ( ! Writer->WriteUi32BE(this->ItemSize()) ) return false; + if ( this->empty() ) return true; + + typename ContainerType::const_iterator i; bool result = true; - for ( ui32_t i = 0; i < ItemCount && result; i++ ) + for ( i = this->begin(); i != this->end() && result; ++i ) { - T Tmp; - result = Tmp.Unarchive(Reader); - - if ( result ) - this->push_back(Tmp); + result = i->Archive(Writer); } return result; } - inline virtual bool HasValue() const { return ! this->empty(); } - - virtual ui32_t ArchiveLength() const { - ui32_t arch_size = sizeof(ui32_t)*2; - - typename std::vector<T>::const_iterator l_i = this->begin(); - assert(l_i != this->end()); - - for ( ; l_i != this->end(); l_i++ ) - arch_size += l_i->ArchiveLength(); - - return arch_size; - } - // - virtual bool Archive(Kumu::MemIOWriter* Writer) const { - if ( ! Writer->WriteUi32BE(this->size()) ) return false; - byte_t* p = Writer->CurrentData(); + bool Unarchive(Kumu::MemIOReader* Reader) { + ui32_t item_count, item_size; + if ( ! Reader->ReadUi32BE(&item_count) ) return false; + if ( ! Reader->ReadUi32BE(&item_size) ) return false; - if ( ! Writer->WriteUi32BE(0) ) return false; - if ( this->empty() ) return true; - - typename std::vector<T>::const_iterator l_i = this->begin(); - assert(l_i != this->end()); - - ui32_t ItemSize = Writer->Remainder(); - if ( ! (*l_i).Archive(Writer) ) return false; - ItemSize -= Writer->Remainder(); - Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p); - l_i++; + if ( item_count > 0 ) + { + if ( this->ItemSize() != item_size ) return false; + } bool result = true; - for ( ; l_i != this->end() && result; l_i++ ) - result = (*l_i).Archive(Writer); + for ( ui32_t i = 0; i < item_count && result; ++i ) + { + typename ContainerType::value_type tmp_item; + result = tmp_item.Unarchive(Reader); + + if ( result ) + { + this->push_back(tmp_item); + } + } return result; } - // - void Dump(FILE* stream = 0, ui32_t = 0) - { - char identbuf[IdentBufferLen]; + void Dump(FILE* stream = 0, ui32_t depth = 0) { + char identbuf[IdentBufferLen]; - if ( stream == 0 ) + if ( stream == 0 ) + { stream = stderr; - - typename std::vector<T>::iterator i = this->begin(); - for ( ; i != this->end(); i++ ) + } + + typename ContainerType::const_iterator i; + for ( i = this->begin(); i != this->end(); ++i ) + { fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen)); - } + } + } }; + + template <class item_type> + class PushSet : public std::set<item_type> + { + public: + PushSet() {} + virtual ~PushSet() {} + void push_back(const item_type& item) { this->insert(item); } + }; + + template <class ItemType> + class Batch : public FixedSizeItemCollection<PushSet<ItemType> > + { + public: + Batch() {} + virtual ~Batch() {} + }; + + template <class ItemType> + class Array : public FixedSizeItemCollection<std::vector<ItemType> > + { + public: + Array() {} + virtual ~Array() {} + }; + // template <class T> - class Array : public std::list<T>, public Kumu::IArchive + class SimpleArray : public std::list<T>, public Kumu::IArchive { public: - Array() {} - ~Array() {} + SimpleArray() {} + virtual ~SimpleArray() {} // - virtual bool Unarchive(Kumu::MemIOReader* Reader) + bool Unarchive(Kumu::MemIOReader* Reader) { bool result = true; @@ -192,15 +215,19 @@ namespace ASDCP { T Tmp; result = Tmp.Unarchive(Reader); - this->push_back(Tmp); + + if ( result ) + { + this->push_back(Tmp); + } } return result; } - inline virtual bool HasValue() const { return ! this->empty(); } + inline bool HasValue() const { return ! this->empty(); } - virtual ui32_t ArchiveLength() const { + ui32_t ArchiveLength() const { ui32_t arch_size = 0; typename std::list<T>::const_iterator l_i = this->begin(); @@ -212,7 +239,7 @@ namespace ASDCP } // - virtual bool Archive(Kumu::MemIOWriter* Writer) const { + bool Archive(Kumu::MemIOWriter* Writer) const { bool result = true; typename std::list<T>::const_iterator l_i = this->begin(); @@ -223,7 +250,7 @@ namespace ASDCP } // - void Dump(FILE* stream = 0, ui32_t = 0) + void Dump(FILE* stream = 0, ui32_t depth = 0) { char identbuf[IdentBufferLen]; @@ -241,6 +268,8 @@ namespace ASDCP { public: ISO8String() {} + ISO8String(const char*); + ISO8String(const std::string&); ~ISO8String() {} const ISO8String& operator=(const char*); @@ -258,6 +287,8 @@ namespace ASDCP { public: UTF16String() {} + UTF16String(const char*); + UTF16String(const std::string&); ~UTF16String() {} const UTF16String& operator=(const char*); @@ -325,7 +356,7 @@ namespace ASDCP class VersionType : public Kumu::IArchive { public: - enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE }; + enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX }; ui16_t Major; ui16_t Minor; ui16_t Patch; @@ -348,7 +379,7 @@ namespace ASDCP void Dump(FILE* = 0); const char* EncodeString(char* str_buf, ui32_t buf_len) const { - snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, Release); + snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release)); return str_buf; } @@ -376,12 +407,120 @@ namespace ASDCP } }; + /* + The RGBALayout type shall be a fixed-size 8 element sequence with a total length + of 16 bytes, where each element shall consist of the RGBAComponent type with the + following fields: + + Code (UInt8): Enumerated value specifying component (i.e., component identifier). + "0" is the layout terminator. + + Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26) + 1->32 indicates integer depth + 253 = HALF (floating point 16-bit value) + 254 = IEEE floating point 32-bit value + 255 = IEEE floating point 64-bit value + 0 = RGBALayout terminator + + A Fill component indicates unused bits. After the components have been specified, + the remaining Code and Size fields shall be set to zero (0). + + For each component in the Pixel, one of the following Codes or the terminator + shall be specified (explained below): + + Code ASCII + + */ + struct RGBALayoutTableEntry + { + byte_t code; + char symbol; + const char* label; + }; + + struct RGBALayoutTableEntry const RGBALayoutTable[] = { + { 0x52, 'R', "Red component" }, + { 0x47, 'G', "Green component" }, + { 0x42, 'B', "Blue component" }, + { 0x41, 'A', "Alpha component" }, + { 0x72, 'r', "Red component (LSBs)" }, + { 0x67, 'g', "Green component (LSBs)" }, + { 0x62, 'b', "Blue component (LSBs)" }, + { 0x61, 'a', "Alpha component (LSBs)" }, + { 0x46, 'F', "Fill component" }, + { 0x50, 'P', "Palette code" }, + { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" }, + { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" }, + { 0x57, 'W', "Composite Video" }, + { 0x58, 'X', "Non co-sited luma component" }, + { 0x59, 'Y', "Luma component" }, + { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" }, + { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" }, + { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" }, + { 0x77, 'w', "Composite Video (LSBs)" }, + { 0x78, 'x', "Non co-sited luma component (LSBs)" }, + { 0x79, 'y', "Luma component (LSBs)" }, + { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" }, + { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" }, + { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" }, + { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" }, + { 0x00, '_', "Terminator" } + }; + + + size_t const RGBAValueLength = 16; + + byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 }; + byte_t const RGBAValue_RGB_8[RGBAValueLength] = { 'R', 8, 'G', 8, 'B', 8, 0, 0 }; + byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 }; + byte_t const RGBAValue_YUV_8[RGBAValueLength] = { 'Y', 8, 'U', 8, 'V', 8, 0, 0 }; + byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 }; + + + class RGBALayout : public Kumu::IArchive + { + byte_t m_value[RGBAValueLength]; + + public: + RGBALayout(); + RGBALayout(const byte_t* value); + ~RGBALayout(); + + RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); } + const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; } + + void Set(const byte_t* value) { + memcpy(m_value, value, RGBAValueLength); + } + + const char* EncodeString(char* buf, ui32_t buf_len) const; + + bool HasValue() const { return true; } + ui32_t ArchiveLength() const { return RGBAValueLength; } + + bool Archive(Kumu::MemIOWriter* Writer) const { + return Writer->WriteRaw(m_value, RGBAValueLength); + } + + bool Unarchive(Kumu::MemIOReader* Reader) { + if ( Reader->Remainder() < RGBAValueLength ) + { + return false; + } + + memcpy(m_value, Reader->CurrentData(), RGBAValueLength); + Reader->SkipOffset(RGBAValueLength); + return true; + } + }; + + // class Raw : public Kumu::ByteString { public: Raw(); - Raw(const Raw& rhs) : Kumu::ByteString () { Copy(rhs); } + Raw(const Raw& rhs) { Copy(rhs); } virtual ~Raw(); const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; } diff --git a/asdcplib/src/Makefile.am b/asdcplib/src/Makefile.am index 85c1e9fc..c345e086 100644 --- a/asdcplib/src/Makefile.am +++ b/asdcplib/src/Makefile.am @@ -1,7 +1,8 @@ ## Makefile.am -- Process this file with automake to produce Makefile.in # -# $Id: Makefile.am,v 1.53 2012/02/05 21:30:18 jhurst Exp $ -# Copyright (c) 2007-2011 John Hurst. All rights reserved. +# $Id: Makefile.am,v 1.83 2015/10/07 16:41:23 jhurst Exp $ +# +# Copyright (c) 2007-2013 John Hurst. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -38,18 +39,65 @@ if ENABLE_RANDOM_UUID AM_CPPFLAGS += -DCONFIG_RANDOM_UUID endif +AM_CPPFLAGS += -g + # list of all the header files that should be installed -include_HEADERS = KM_error.h KM_fileio.h KM_log.h KM_memio.h KM_mutex.h \ - KM_platform.h KM_prng.h KM_util.h KM_tai.h KM_xml.h AS_DCP.h +include_HEADERS = \ + KM_error.h \ + KM_fileio.h \ + KM_log.h \ + KM_memio.h \ + KM_mutex.h \ + KM_platform.h \ + KM_prng.h \ + KM_util.h \ + KM_tai.h \ + KM_xml.h \ + AS_DCP.h + if DEV_HEADERS -include_HEADERS += S12MTimecode.h MDD.h Metadata.h KLV.h MXFTypes.h MXF.h Wav.h \ - PCMParserList.h -nodist_include_HEADERS = TimedText_Transform.h +include_HEADERS += \ + S12MTimecode.h \ + ST2095_PinkNoise.h \ + MDD.h \ + Metadata.h \ + KLV.h \ + JP2K.h \ + MXFTypes.h \ + MXF.h \ + Wav.h \ + PCMParserList.h \ + AtmosSyncChannel_Mixer.h \ + AtmosSyncChannel_Generator.h \ + PCMDataProviders.h \ + SyncCommon.h \ + SyncEncoder.h \ + UUIDInformation.h + + +endif + +if USE_AS_02 +include_HEADERS += AS_02.h +endif + +if USE_PHDR +include_HEADERS += AS_02_PHDR.h endif # list of the libraries to build and install + lib_LTLIBRARIES = libkumu.la libasdcp.la -# sources for a library + +if USE_AS_02 +lib_LTLIBRARIES += libas02.la +endif + +if USE_PHDR +lib_LTLIBRARIES += libphdr.la +endif + +# sources for kumu library libkumu_la_SOURCES = KM_error.h KM_fileio.cpp KM_fileio.h KM_log.cpp KM_log.h \ KM_memio.h KM_mutex.h KM_platform.h KM_prng.cpp KM_prng.h KM_util.cpp \ KM_util.h KM_xml.cpp KM_xml.h KM_tai.h KM_tai.cpp @@ -57,34 +105,68 @@ libkumu_la_SOURCES = KM_error.h KM_fileio.cpp KM_fileio.h KM_log.cpp KM_log.h \ # linker flags (*not* including libraries to link against) for a library libkumu_la_LDFLAGS = -release @VERSION@ -# sources for a library that don't get added to a distribution + +# sources for asdcp library that don't get added to a distribution nodist_libasdcp_la_SOURCES = Metadata_h.tt2 Metadata_cpp.tt2 \ mxfgen.pl MXF_def.pl ullist.pl ULList.xml dict.xml DMS_Crypto.xml - +# sources for asdcp library libasdcp_la_SOURCES = MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp \ - JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp \ - TimedText_Parser.cpp KLV.cpp Dict.cpp MXFTypes.cpp MXF.cpp \ - Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp AS_DCP_AES.cpp \ - h__Reader.cpp h__Writer.cpp AS_DCP_MPEG2.cpp AS_DCP_JP2K.cpp \ - AS_DCP_PCM.cpp AS_DCP_TimedText.cpp PCMParserList.cpp \ - Wav.h WavFileWriter.h MXF.h Metadata.h \ - JP2K.h AS_DCP.h AS_DCP_internal.h KLV.h MPEG.h MXFTypes.h MDD.h \ - PCMParserList.h S12MTimecode.h MDD.cpp + JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp \ + TimedText_Parser.cpp KLV.cpp Dict.cpp MXFTypes.cpp MXF.cpp \ + Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp AS_DCP_AES.cpp \ + h__Reader.cpp h__Writer.cpp AS_DCP_MPEG2.cpp AS_DCP_JP2K.cpp \ + AS_DCP_PCM.cpp AS_DCP_TimedText.cpp PCMParserList.cpp \ + Wav.h WavFileWriter.h MXF.h Metadata.h \ + JP2K.h AS_DCP.h AS_DCP_internal.h KLV.h MPEG.h MXFTypes.h MDD.h \ + PCMParserList.h S12MTimecode.h MDD.cpp \ + AS_DCP_ATMOS.cpp AS_DCP_DCData.cpp AS_DCP_DCData_internal.h \ + DCData_ByteStream_Parser.cpp DCData_Sequence_Parser.cpp \ + AtmosSyncChannel_Generator.cpp AtmosSyncChannel_Generator.h \ + AtmosSyncChannel_Mixer.cpp AtmosSyncChannel_Mixer.h \ + PCMDataProviders.cpp PCMDataProviders.h \ + SyncEncoder.c SyncEncoder.h SyncCommon.h CRC16.c CRC16.h \ + UUIDInformation.c UUIDInformation.h \ + ST2095_PinkNoise.cpp -if DEV_HEADERS -nodist_libasdcp_la_SOURCES += TimedText_Transform.h TimedText_Transform.cpp -endif libasdcp_la_LDFLAGS = -release @VERSION@ - # additional libraries to link against for a library libasdcp_la_LIBADD = libkumu.la libasdcp_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\" +if USE_AS_02 +# sources for as-02 library +libas02_la_SOURCES = \ + AS_02.h \ + AS_02_internal.h \ + h__02_Reader.cpp \ + h__02_Writer.cpp \ + AS_02_JP2K.cpp \ + AS_02_PCM.cpp \ + ST2052_TextParser.cpp \ + AS_02_TimedText.cpp + +libas02_la_LDFLAGS = -release @VERSION@ +libas02_la_LIBADD = libasdcp.la libkumu.la +libas02_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\" +endif + + +if USE_PHDR +# sources for PHDR library +libphdr_la_SOURCES = \ + AS_02_PHDR.h \ + PHDR_Sequence_Parser.cpp \ + AS_02_PHDR.cpp + +libphdr_la_LDFLAGS = -release @VERSION@ +libphdr_la_LIBADD = libasdcp.la libkumu.la +libphdr_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\" +endif + # Python extension if PYTHON_USE lib_LTLIBRARIES += libpyasdcp.la -#### libnapali.la nodist_libpyasdcp_la_SOURCES = \ kumu_python.cpp \ @@ -96,25 +178,23 @@ nodist_libpyasdcp_la_SOURCES = \ asdcp_python_writerinfo.h \ asdcp_wrappers.h \ asdcp_python_mxf.cpp \ + asdcp_python_mxf.h \ asdcp_python_mxf_text.cpp \ asdcp_python_mxf_metadata.cpp -####nodist_libnapali_la_SOURCES = \ -#### napali_python.cpp napali_python.h libpyasdcp_la_CPPFLAGS = @PYTHON_CPPFLAGS@ libpyasdcp_la_LDFLAGS = @PYTHON_LSPEC@ -release @VERSION@ libpyasdcp_la_LIBADD = libkumu.la libasdcp.la -####libnapali_la_CPPFLAGS = @PYTHON_CPPFLAGS@ -####libnapali_la_LDFLAGS = @PYTHON_LSPEC@ -release @VERSION@ -####libnapali_la_LIBADD = libkumu.la libasdcp.la +if USE_AS_02 +libpyasdcp_la_LIBADD += libas02.la +endif pyexecdir = @PYTHON_EXECDIR@ pyexec_includedir = $(PYTHON_PREFIX)/include/python$(PYTHON_SHORTVERSION) nodist_pyexec_include_HEADERS = kumu_python.h asdcp_python.h asdcp_wrappers.h pyexec_LTLIBRARIES = kumu.la asdcp.la -#### napali_python.h napali.la nodist_kumu_la_SOURCES = pykumu.cpp kumu_python.h kumu_la_CPPFLAGS = @PYTHON_CPPFLAGS@ @@ -125,55 +205,95 @@ nodist_asdcp_la_SOURCES = pyasdcp.cpp kumu_python.h asdcp_python.h asdcp_wrapper asdcp_la_CPPFLAGS = @PYTHON_CPPFLAGS@ asdcp_la_LDFLAGS = @PYTHON_LSPEC@ -avoid-version -module asdcp_la_LIBADD = libpyasdcp.la - -####nodist_napali_la_SOURCES = pynapali.cpp kumu_python.h napali_python.h -####napali_la_CPPFLAGS = @PYTHON_CPPFLAGS@ -####napali_la_LDFLAGS = @PYTHON_LSPEC@ -avoid-version -module -####napali_la_LIBADD = libnapali.la libpyasdcp.la endif # list of programs to be built and installed bin_PROGRAMS = \ - asdcp-wrap asdcp-unwrap asdcp-util asdcp-info asdcp-test \ - j2c-test blackwave klvwalk wavesplit \ - kmfilegen kmrandgen kmuuidgen + asdcp-wrap \ + asdcp-unwrap \ + asdcp-util \ + asdcp-info \ + asdcp-test \ + j2c-test \ + blackwave \ + pinkwave \ + klvwalk \ + wavesplit \ + klvsplit \ + kmfilegen \ + kmrandgen \ + kmuuidgen + +if USE_AS_02 +bin_PROGRAMS += \ + as-02-wrap \ + as-02-unwrap +endif + +if USE_PHDR +bin_PROGRAMS += \ + phdr-wrap \ + phdr-unwrap +endif # sources and linkage for CLI utilities asdcp_test_SOURCES = asdcp-test.cpp -asdcp_test_LDADD = libasdcp.la +asdcp_test_LDADD = libasdcp.la libkumu.la asdcp_wrap_SOURCES = asdcp-wrap.cpp -asdcp_wrap_LDADD = libasdcp.la +asdcp_wrap_LDADD = libasdcp.la libkumu.la asdcp_unwrap_SOURCES = asdcp-unwrap.cpp -asdcp_unwrap_LDADD = libasdcp.la +asdcp_unwrap_LDADD = libasdcp.la libkumu.la asdcp_util_SOURCES = asdcp-util.cpp -asdcp_util_LDADD = libasdcp.la +asdcp_util_LDADD = libasdcp.la libkumu.la asdcp_info_SOURCES = asdcp-info.cpp -asdcp_info_LDADD = libasdcp.la +asdcp_info_LDADD = libasdcp.la libkumu.la kmfilegen_SOURCES = kmfilegen.cpp -kmfilegen_LDADD = libkumu.la +kmfilegen_LDADD = libkumu.la kmrandgen_SOURCES = kmrandgen.cpp -kmrandgen_LDADD = libkumu.la +kmrandgen_LDADD = libkumu.la kmuuidgen_SOURCES = kmuuidgen.cpp -kmuuidgen_LDADD = libkumu.la +kmuuidgen_LDADD = libkumu.la blackwave_SOURCES = blackwave.cpp -blackwave_LDADD = libasdcp.la +blackwave_LDADD = libasdcp.la libkumu.la + +pinkwave_SOURCES = pinkwave.cpp +pinkwave_LDADD = libasdcp.la libkumu.la klvwalk_SOURCES = klvwalk.cpp -klvwalk_LDADD = libasdcp.la +klvwalk_LDADD = libasdcp.la libkumu.la wavesplit_SOURCES = wavesplit.cpp -wavesplit_LDADD = libasdcp.la +wavesplit_LDADD = libasdcp.la libkumu.la j2c_test_SOURCES = j2c-test.cpp -j2c_test_LDADD = libasdcp.la +j2c_test_LDADD = libasdcp.la libkumu.la + +klvsplit_SOURCES = klvsplit.cpp +klvsplit_LDADD = libasdcp.la libkumu.la + +if USE_AS_02 +as_02_wrap_SOURCES = as-02-wrap.cpp +as_02_wrap_LDADD = libas02.la libasdcp.la libkumu.la + +as_02_unwrap_SOURCES = as-02-unwrap.cpp +as_02_unwrap_LDADD = libas02.la libasdcp.la libkumu.la +endif + +if USE_PHDR +phdr_wrap_SOURCES = phdr-wrap.cpp +phdr_wrap_LDADD = libphdr.la libas02.la libasdcp.la libkumu.la + +phdr_unwrap_SOURCES = phdr-unwrap.cpp +phdr_unwrap_LDADD = libphdr.la libas02.la libasdcp.la libkumu.la +endif # list of programs that need to be compiled for use in test suite check_PROGRAMS = asdcp-mem-test path-test \ @@ -194,10 +314,10 @@ fips_186_rng_test_SOURCES = fips-186-rng-test.cpp fips_186_rng_test_LDADD = libasdcp.la asdcp_version_SOURCES = asdcp-version.cpp -asdcp_version_LDADD = libkumu.la +asdcp_version_LDADD = libkumu.la if DEV_HEADERS -nodist_tt_xform_SOURCES = tt-xform.cpp +nodist_tt_xform_SOURCES = tt-xform.cpp TimedText_Transform.h tt_xform_LDADD = libasdcp.la endif @@ -217,11 +337,9 @@ EXTRA_DIST = fips-186-test-harness.pl $(TESTS) if !FREEDIST if DEV_HEADERS EXTRA_DIST += $(nodist_libasdcp_la_SOURCES) $(nodist_tt_xform_SOURCES) -#### $(nodist_napali_la_SOURCES) $(nodist_libnapali_la_SOURCES) endif if PYTHON_USE EXTRA_DIST += $(nodist_pyexec_include_HEADERS) $(nodist_libpyasdcp_la_SOURCES) $(nodist_kumu_la_SOURCES) $(nodist_asdcp_la_SOURCES) -#### $(nodist_napali_la_SOURCES) $(nodist_libnapali_la_SOURCES) endif endif diff --git a/asdcplib/src/Makefile.in b/asdcplib/src/Makefile.in index f086f49d..a545f342 100644 --- a/asdcplib/src/Makefile.in +++ b/asdcplib/src/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,8 +15,9 @@ @SET_MAKE@ # -# $Id: Makefile.am,v 1.53 2012/02/05 21:30:18 jhurst Exp $ -# Copyright (c) 2007-2011 John Hurst. All rights reserved. +# $Id: Makefile.am,v 1.83 2015/10/07 16:41:23 jhurst Exp $ +# +# Copyright (c) 2007-2013 John Hurst. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -44,6 +44,51 @@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -65,28 +110,56 @@ host_triplet = @host@ @OPENBSD_HOST_TRUE@am__append_1 = -I/var/local/include -I/usr/local/include @OPENBSD_HOST_TRUE@am__append_2 = -L./.libs -L/var/local/lib -L/usr/local/lib @ENABLE_RANDOM_UUID_TRUE@am__append_3 = -DCONFIG_RANDOM_UUID -@DEV_HEADERS_TRUE@am__append_4 = S12MTimecode.h MDD.h Metadata.h KLV.h MXFTypes.h MXF.h Wav.h \ -@DEV_HEADERS_TRUE@ PCMParserList.h - -@DEV_HEADERS_TRUE@am__append_5 = TimedText_Transform.h TimedText_Transform.cpp +@DEV_HEADERS_TRUE@am__append_4 = \ +@DEV_HEADERS_TRUE@ S12MTimecode.h \ +@DEV_HEADERS_TRUE@ ST2095_PinkNoise.h \ +@DEV_HEADERS_TRUE@ MDD.h \ +@DEV_HEADERS_TRUE@ Metadata.h \ +@DEV_HEADERS_TRUE@ KLV.h \ +@DEV_HEADERS_TRUE@ JP2K.h \ +@DEV_HEADERS_TRUE@ MXFTypes.h \ +@DEV_HEADERS_TRUE@ MXF.h \ +@DEV_HEADERS_TRUE@ Wav.h \ +@DEV_HEADERS_TRUE@ PCMParserList.h \ +@DEV_HEADERS_TRUE@ AtmosSyncChannel_Mixer.h \ +@DEV_HEADERS_TRUE@ AtmosSyncChannel_Generator.h \ +@DEV_HEADERS_TRUE@ PCMDataProviders.h \ +@DEV_HEADERS_TRUE@ SyncCommon.h \ +@DEV_HEADERS_TRUE@ SyncEncoder.h \ +@DEV_HEADERS_TRUE@ UUIDInformation.h + +@USE_AS_02_TRUE@am__append_5 = AS_02.h +@USE_PHDR_TRUE@am__append_6 = AS_02_PHDR.h +@USE_AS_02_TRUE@am__append_7 = libas02.la +@USE_PHDR_TRUE@am__append_8 = libphdr.la # Python extension -@PYTHON_USE_TRUE@am__append_6 = libpyasdcp.la +@PYTHON_USE_TRUE@am__append_9 = libpyasdcp.la +@PYTHON_USE_TRUE@@USE_AS_02_TRUE@am__append_10 = libas02.la bin_PROGRAMS = asdcp-wrap$(EXEEXT) asdcp-unwrap$(EXEEXT) \ asdcp-util$(EXEEXT) asdcp-info$(EXEEXT) asdcp-test$(EXEEXT) \ - j2c-test$(EXEEXT) blackwave$(EXEEXT) klvwalk$(EXEEXT) \ - wavesplit$(EXEEXT) kmfilegen$(EXEEXT) kmrandgen$(EXEEXT) \ - kmuuidgen$(EXEEXT) + j2c-test$(EXEEXT) blackwave$(EXEEXT) pinkwave$(EXEEXT) \ + klvwalk$(EXEEXT) wavesplit$(EXEEXT) klvsplit$(EXEEXT) \ + kmfilegen$(EXEEXT) kmrandgen$(EXEEXT) kmuuidgen$(EXEEXT) \ + $(am__EXEEXT_1) $(am__EXEEXT_2) +@USE_AS_02_TRUE@am__append_11 = \ +@USE_AS_02_TRUE@ as-02-wrap \ +@USE_AS_02_TRUE@ as-02-unwrap + +@USE_PHDR_TRUE@am__append_12 = \ +@USE_PHDR_TRUE@ phdr-wrap \ +@USE_PHDR_TRUE@ phdr-unwrap + check_PROGRAMS = asdcp-mem-test$(EXEEXT) path-test$(EXEEXT) \ fips-186-rng-test$(EXEEXT) asdcp-version$(EXEEXT) \ - $(am__EXEEXT_1) -@DEV_HEADERS_TRUE@am__append_7 = tt-xform -@DEV_HEADERS_TRUE@@FREEDIST_FALSE@am__append_8 = $(nodist_libasdcp_la_SOURCES) $(nodist_tt_xform_SOURCES) -#### $(nodist_napali_la_SOURCES) $(nodist_libnapali_la_SOURCES) -@FREEDIST_FALSE@@PYTHON_USE_TRUE@am__append_9 = $(nodist_pyexec_include_HEADERS) $(nodist_libpyasdcp_la_SOURCES) $(nodist_kumu_la_SOURCES) $(nodist_asdcp_la_SOURCES) + $(am__EXEEXT_3) +@DEV_HEADERS_TRUE@am__append_13 = tt-xform +@DEV_HEADERS_TRUE@@FREEDIST_FALSE@am__append_14 = $(nodist_libasdcp_la_SOURCES) $(nodist_tt_xform_SOURCES) +@FREEDIST_FALSE@@PYTHON_USE_TRUE@am__append_15 = $(nodist_pyexec_include_HEADERS) $(nodist_libpyasdcp_la_SOURCES) $(nodist_kumu_la_SOURCES) $(nodist_asdcp_la_SOURCES) subdir = src -DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp $(am__include_HEADERS_DIST) \ + $(top_srcdir)/build-aux/test-driver ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_expat.m4 \ $(top_srcdir)/m4/ax_lib_openssl.m4 \ @@ -129,22 +202,41 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pyexecdir)" \ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)" \ - "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pyexec_includedir)" + "$(DESTDIR)$(pyexec_includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(pyexec_LTLIBRARIES) @PYTHON_USE_TRUE@asdcp_la_DEPENDENCIES = libpyasdcp.la @PYTHON_USE_TRUE@nodist_asdcp_la_OBJECTS = asdcp_la-pyasdcp.lo asdcp_la_OBJECTS = $(nodist_asdcp_la_OBJECTS) -asdcp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +asdcp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(asdcp_la_LDFLAGS) $(LDFLAGS) -o $@ @PYTHON_USE_TRUE@am_asdcp_la_rpath = -rpath $(pyexecdir) @PYTHON_USE_TRUE@kumu_la_DEPENDENCIES = libpyasdcp.la @PYTHON_USE_TRUE@nodist_kumu_la_OBJECTS = kumu_la-pykumu.lo kumu_la_OBJECTS = $(nodist_kumu_la_OBJECTS) -kumu_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ - $(kumu_la_LDFLAGS) $(LDFLAGS) -o $@ +kumu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(kumu_la_LDFLAGS) $(LDFLAGS) -o $@ @PYTHON_USE_TRUE@am_kumu_la_rpath = -rpath $(pyexecdir) +@USE_AS_02_TRUE@libas02_la_DEPENDENCIES = libasdcp.la libkumu.la +am__libas02_la_SOURCES_DIST = AS_02.h AS_02_internal.h \ + h__02_Reader.cpp h__02_Writer.cpp AS_02_JP2K.cpp AS_02_PCM.cpp \ + ST2052_TextParser.cpp AS_02_TimedText.cpp +@USE_AS_02_TRUE@am_libas02_la_OBJECTS = libas02_la-h__02_Reader.lo \ +@USE_AS_02_TRUE@ libas02_la-h__02_Writer.lo \ +@USE_AS_02_TRUE@ libas02_la-AS_02_JP2K.lo \ +@USE_AS_02_TRUE@ libas02_la-AS_02_PCM.lo \ +@USE_AS_02_TRUE@ libas02_la-ST2052_TextParser.lo \ +@USE_AS_02_TRUE@ libas02_la-AS_02_TimedText.lo +libas02_la_OBJECTS = $(am_libas02_la_OBJECTS) +libas02_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libas02_la_LDFLAGS) $(LDFLAGS) -o $@ +@USE_AS_02_TRUE@am_libas02_la_rpath = -rpath $(libdir) libasdcp_la_DEPENDENCIES = libkumu.la am_libasdcp_la_OBJECTS = libasdcp_la-MPEG2_Parser.lo \ libasdcp_la-MPEG.lo libasdcp_la-JP2K_Codestream_Parser.lo \ @@ -158,22 +250,41 @@ am_libasdcp_la_OBJECTS = libasdcp_la-MPEG2_Parser.lo \ libasdcp_la-h__Writer.lo libasdcp_la-AS_DCP_MPEG2.lo \ libasdcp_la-AS_DCP_JP2K.lo libasdcp_la-AS_DCP_PCM.lo \ libasdcp_la-AS_DCP_TimedText.lo libasdcp_la-PCMParserList.lo \ - libasdcp_la-MDD.lo -@DEV_HEADERS_TRUE@am__objects_1 = libasdcp_la-TimedText_Transform.lo -nodist_libasdcp_la_OBJECTS = $(am__objects_1) + libasdcp_la-MDD.lo libasdcp_la-AS_DCP_ATMOS.lo \ + libasdcp_la-AS_DCP_DCData.lo \ + libasdcp_la-DCData_ByteStream_Parser.lo \ + libasdcp_la-DCData_Sequence_Parser.lo \ + libasdcp_la-AtmosSyncChannel_Generator.lo \ + libasdcp_la-AtmosSyncChannel_Mixer.lo \ + libasdcp_la-PCMDataProviders.lo libasdcp_la-SyncEncoder.lo \ + libasdcp_la-CRC16.lo libasdcp_la-UUIDInformation.lo \ + libasdcp_la-ST2095_PinkNoise.lo +nodist_libasdcp_la_OBJECTS = libasdcp_la_OBJECTS = $(am_libasdcp_la_OBJECTS) \ $(nodist_libasdcp_la_OBJECTS) -libasdcp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ +libasdcp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libasdcp_la_LDFLAGS) $(LDFLAGS) -o $@ libkumu_la_LIBADD = am_libkumu_la_OBJECTS = KM_fileio.lo KM_log.lo KM_prng.lo KM_util.lo \ KM_xml.lo KM_tai.lo libkumu_la_OBJECTS = $(am_libkumu_la_OBJECTS) -libkumu_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ +libkumu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libkumu_la_LDFLAGS) $(LDFLAGS) -o $@ -@PYTHON_USE_TRUE@libpyasdcp_la_DEPENDENCIES = libkumu.la libasdcp.la +@USE_PHDR_TRUE@libphdr_la_DEPENDENCIES = libasdcp.la libkumu.la +am__libphdr_la_SOURCES_DIST = AS_02_PHDR.h PHDR_Sequence_Parser.cpp \ + AS_02_PHDR.cpp +@USE_PHDR_TRUE@am_libphdr_la_OBJECTS = \ +@USE_PHDR_TRUE@ libphdr_la-PHDR_Sequence_Parser.lo \ +@USE_PHDR_TRUE@ libphdr_la-AS_02_PHDR.lo +libphdr_la_OBJECTS = $(am_libphdr_la_OBJECTS) +libphdr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libphdr_la_LDFLAGS) $(LDFLAGS) -o $@ +@USE_PHDR_TRUE@am_libphdr_la_rpath = -rpath $(libdir) +@PYTHON_USE_TRUE@libpyasdcp_la_DEPENDENCIES = libkumu.la libasdcp.la \ +@PYTHON_USE_TRUE@ $(am__append_10) @PYTHON_USE_TRUE@nodist_libpyasdcp_la_OBJECTS = \ @PYTHON_USE_TRUE@ libpyasdcp_la-kumu_python.lo \ @PYTHON_USE_TRUE@ libpyasdcp_la-asdcp_python.lo \ @@ -183,45 +294,62 @@ libkumu_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ @PYTHON_USE_TRUE@ libpyasdcp_la-asdcp_python_mxf_text.lo \ @PYTHON_USE_TRUE@ libpyasdcp_la-asdcp_python_mxf_metadata.lo libpyasdcp_la_OBJECTS = $(nodist_libpyasdcp_la_OBJECTS) -libpyasdcp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(libpyasdcp_la_LDFLAGS) $(LDFLAGS) -o $@ +libpyasdcp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(libpyasdcp_la_LDFLAGS) $(LDFLAGS) \ + -o $@ @PYTHON_USE_TRUE@am_libpyasdcp_la_rpath = -rpath $(libdir) -@DEV_HEADERS_TRUE@am__EXEEXT_1 = tt-xform$(EXEEXT) +@USE_AS_02_TRUE@am__EXEEXT_1 = as-02-wrap$(EXEEXT) \ +@USE_AS_02_TRUE@ as-02-unwrap$(EXEEXT) +@USE_PHDR_TRUE@am__EXEEXT_2 = phdr-wrap$(EXEEXT) phdr-unwrap$(EXEEXT) +@DEV_HEADERS_TRUE@am__EXEEXT_3 = tt-xform$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) +am__as_02_unwrap_SOURCES_DIST = as-02-unwrap.cpp +@USE_AS_02_TRUE@am_as_02_unwrap_OBJECTS = as-02-unwrap.$(OBJEXT) +as_02_unwrap_OBJECTS = $(am_as_02_unwrap_OBJECTS) +@USE_AS_02_TRUE@as_02_unwrap_DEPENDENCIES = libas02.la libasdcp.la \ +@USE_AS_02_TRUE@ libkumu.la +am__as_02_wrap_SOURCES_DIST = as-02-wrap.cpp +@USE_AS_02_TRUE@am_as_02_wrap_OBJECTS = as-02-wrap.$(OBJEXT) +as_02_wrap_OBJECTS = $(am_as_02_wrap_OBJECTS) +@USE_AS_02_TRUE@as_02_wrap_DEPENDENCIES = libas02.la libasdcp.la \ +@USE_AS_02_TRUE@ libkumu.la am_asdcp_info_OBJECTS = asdcp-info.$(OBJEXT) asdcp_info_OBJECTS = $(am_asdcp_info_OBJECTS) -asdcp_info_DEPENDENCIES = libasdcp.la +asdcp_info_DEPENDENCIES = libasdcp.la libkumu.la am_asdcp_mem_test_OBJECTS = asdcp-mem-test.$(OBJEXT) asdcp_mem_test_OBJECTS = $(am_asdcp_mem_test_OBJECTS) asdcp_mem_test_DEPENDENCIES = libasdcp.la am_asdcp_test_OBJECTS = asdcp-test.$(OBJEXT) asdcp_test_OBJECTS = $(am_asdcp_test_OBJECTS) -asdcp_test_DEPENDENCIES = libasdcp.la +asdcp_test_DEPENDENCIES = libasdcp.la libkumu.la am_asdcp_unwrap_OBJECTS = asdcp-unwrap.$(OBJEXT) asdcp_unwrap_OBJECTS = $(am_asdcp_unwrap_OBJECTS) -asdcp_unwrap_DEPENDENCIES = libasdcp.la +asdcp_unwrap_DEPENDENCIES = libasdcp.la libkumu.la am_asdcp_util_OBJECTS = asdcp-util.$(OBJEXT) asdcp_util_OBJECTS = $(am_asdcp_util_OBJECTS) -asdcp_util_DEPENDENCIES = libasdcp.la +asdcp_util_DEPENDENCIES = libasdcp.la libkumu.la am_asdcp_version_OBJECTS = asdcp-version.$(OBJEXT) asdcp_version_OBJECTS = $(am_asdcp_version_OBJECTS) asdcp_version_DEPENDENCIES = libkumu.la am_asdcp_wrap_OBJECTS = asdcp-wrap.$(OBJEXT) asdcp_wrap_OBJECTS = $(am_asdcp_wrap_OBJECTS) -asdcp_wrap_DEPENDENCIES = libasdcp.la +asdcp_wrap_DEPENDENCIES = libasdcp.la libkumu.la am_blackwave_OBJECTS = blackwave.$(OBJEXT) blackwave_OBJECTS = $(am_blackwave_OBJECTS) -blackwave_DEPENDENCIES = libasdcp.la +blackwave_DEPENDENCIES = libasdcp.la libkumu.la am_fips_186_rng_test_OBJECTS = fips-186-rng-test.$(OBJEXT) fips_186_rng_test_OBJECTS = $(am_fips_186_rng_test_OBJECTS) fips_186_rng_test_DEPENDENCIES = libasdcp.la am_j2c_test_OBJECTS = j2c-test.$(OBJEXT) j2c_test_OBJECTS = $(am_j2c_test_OBJECTS) -j2c_test_DEPENDENCIES = libasdcp.la +j2c_test_DEPENDENCIES = libasdcp.la libkumu.la +am_klvsplit_OBJECTS = klvsplit.$(OBJEXT) +klvsplit_OBJECTS = $(am_klvsplit_OBJECTS) +klvsplit_DEPENDENCIES = libasdcp.la libkumu.la am_klvwalk_OBJECTS = klvwalk.$(OBJEXT) klvwalk_OBJECTS = $(am_klvwalk_OBJECTS) -klvwalk_DEPENDENCIES = libasdcp.la +klvwalk_DEPENDENCIES = libasdcp.la libkumu.la am_kmfilegen_OBJECTS = kmfilegen.$(OBJEXT) kmfilegen_OBJECTS = $(am_kmfilegen_OBJECTS) kmfilegen_DEPENDENCIES = libkumu.la @@ -234,66 +362,318 @@ kmuuidgen_DEPENDENCIES = libkumu.la am_path_test_OBJECTS = path-test.$(OBJEXT) path_test_OBJECTS = $(am_path_test_OBJECTS) path_test_DEPENDENCIES = libkumu.la +am__phdr_unwrap_SOURCES_DIST = phdr-unwrap.cpp +@USE_PHDR_TRUE@am_phdr_unwrap_OBJECTS = phdr-unwrap.$(OBJEXT) +phdr_unwrap_OBJECTS = $(am_phdr_unwrap_OBJECTS) +@USE_PHDR_TRUE@phdr_unwrap_DEPENDENCIES = libphdr.la libas02.la \ +@USE_PHDR_TRUE@ libasdcp.la libkumu.la +am__phdr_wrap_SOURCES_DIST = phdr-wrap.cpp +@USE_PHDR_TRUE@am_phdr_wrap_OBJECTS = phdr-wrap.$(OBJEXT) +phdr_wrap_OBJECTS = $(am_phdr_wrap_OBJECTS) +@USE_PHDR_TRUE@phdr_wrap_DEPENDENCIES = libphdr.la libas02.la \ +@USE_PHDR_TRUE@ libasdcp.la libkumu.la +am_pinkwave_OBJECTS = pinkwave.$(OBJEXT) +pinkwave_OBJECTS = $(am_pinkwave_OBJECTS) +pinkwave_DEPENDENCIES = libasdcp.la libkumu.la @DEV_HEADERS_TRUE@nodist_tt_xform_OBJECTS = tt-xform.$(OBJEXT) tt_xform_OBJECTS = $(nodist_tt_xform_OBJECTS) @DEV_HEADERS_TRUE@tt_xform_DEPENDENCIES = libasdcp.la am_wavesplit_OBJECTS = wavesplit.$(OBJEXT) wavesplit_OBJECTS = $(am_wavesplit_OBJECTS) -wavesplit_DEPENDENCIES = libasdcp.la +wavesplit_DEPENDENCIES = libasdcp.la libkumu.la +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = SOURCES = $(nodist_asdcp_la_SOURCES) $(nodist_kumu_la_SOURCES) \ - $(libasdcp_la_SOURCES) $(nodist_libasdcp_la_SOURCES) \ - $(libkumu_la_SOURCES) $(nodist_libpyasdcp_la_SOURCES) \ - $(asdcp_info_SOURCES) $(asdcp_mem_test_SOURCES) \ - $(asdcp_test_SOURCES) $(asdcp_unwrap_SOURCES) \ - $(asdcp_util_SOURCES) $(asdcp_version_SOURCES) \ - $(asdcp_wrap_SOURCES) $(blackwave_SOURCES) \ - $(fips_186_rng_test_SOURCES) $(j2c_test_SOURCES) \ - $(klvwalk_SOURCES) $(kmfilegen_SOURCES) $(kmrandgen_SOURCES) \ - $(kmuuidgen_SOURCES) $(path_test_SOURCES) \ - $(nodist_tt_xform_SOURCES) $(wavesplit_SOURCES) -DIST_SOURCES = $(libasdcp_la_SOURCES) $(libkumu_la_SOURCES) \ + $(libas02_la_SOURCES) $(libasdcp_la_SOURCES) \ + $(nodist_libasdcp_la_SOURCES) $(libkumu_la_SOURCES) \ + $(libphdr_la_SOURCES) $(nodist_libpyasdcp_la_SOURCES) \ + $(as_02_unwrap_SOURCES) $(as_02_wrap_SOURCES) \ $(asdcp_info_SOURCES) $(asdcp_mem_test_SOURCES) \ $(asdcp_test_SOURCES) $(asdcp_unwrap_SOURCES) \ $(asdcp_util_SOURCES) $(asdcp_version_SOURCES) \ $(asdcp_wrap_SOURCES) $(blackwave_SOURCES) \ $(fips_186_rng_test_SOURCES) $(j2c_test_SOURCES) \ - $(klvwalk_SOURCES) $(kmfilegen_SOURCES) $(kmrandgen_SOURCES) \ - $(kmuuidgen_SOURCES) $(path_test_SOURCES) $(wavesplit_SOURCES) + $(klvsplit_SOURCES) $(klvwalk_SOURCES) $(kmfilegen_SOURCES) \ + $(kmrandgen_SOURCES) $(kmuuidgen_SOURCES) $(path_test_SOURCES) \ + $(phdr_unwrap_SOURCES) $(phdr_wrap_SOURCES) \ + $(pinkwave_SOURCES) $(nodist_tt_xform_SOURCES) \ + $(wavesplit_SOURCES) +DIST_SOURCES = $(am__libas02_la_SOURCES_DIST) $(libasdcp_la_SOURCES) \ + $(libkumu_la_SOURCES) $(am__libphdr_la_SOURCES_DIST) \ + $(am__as_02_unwrap_SOURCES_DIST) \ + $(am__as_02_wrap_SOURCES_DIST) $(asdcp_info_SOURCES) \ + $(asdcp_mem_test_SOURCES) $(asdcp_test_SOURCES) \ + $(asdcp_unwrap_SOURCES) $(asdcp_util_SOURCES) \ + $(asdcp_version_SOURCES) $(asdcp_wrap_SOURCES) \ + $(blackwave_SOURCES) $(fips_186_rng_test_SOURCES) \ + $(j2c_test_SOURCES) $(klvsplit_SOURCES) $(klvwalk_SOURCES) \ + $(kmfilegen_SOURCES) $(kmrandgen_SOURCES) $(kmuuidgen_SOURCES) \ + $(path_test_SOURCES) $(am__phdr_unwrap_SOURCES_DIST) \ + $(am__phdr_wrap_SOURCES_DIST) $(pinkwave_SOURCES) \ + $(wavesplit_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__include_HEADERS_DIST = KM_error.h KM_fileio.h KM_log.h KM_memio.h \ KM_mutex.h KM_platform.h KM_prng.h KM_util.h KM_tai.h KM_xml.h \ - AS_DCP.h S12MTimecode.h MDD.h Metadata.h KLV.h MXFTypes.h \ - MXF.h Wav.h PCMParserList.h -HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) \ - $(nodist_pyexec_include_HEADERS) + AS_DCP.h S12MTimecode.h ST2095_PinkNoise.h MDD.h Metadata.h \ + KLV.h JP2K.h MXFTypes.h MXF.h Wav.h PCMParserList.h \ + AtmosSyncChannel_Mixer.h AtmosSyncChannel_Generator.h \ + PCMDataProviders.h SyncCommon.h SyncEncoder.h \ + UUIDInformation.h AS_02.h AS_02_PHDR.h +HEADERS = $(include_HEADERS) $(nodist_pyexec_include_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__tty_colors = \ -red=; grn=; lgn=; blu=; std= +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -432,18 +812,19 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # Allow for configure's changes to this makefile -AM_CPPFLAGS = $(am__append_1) $(am__append_3) +AM_CPPFLAGS = $(am__append_1) $(am__append_3) -g AM_LDFLAGS = $(am__append_2) # list of all the header files that should be installed include_HEADERS = KM_error.h KM_fileio.h KM_log.h KM_memio.h \ KM_mutex.h KM_platform.h KM_prng.h KM_util.h KM_tai.h KM_xml.h \ - AS_DCP.h $(am__append_4) -@DEV_HEADERS_TRUE@nodist_include_HEADERS = TimedText_Transform.h + AS_DCP.h $(am__append_4) $(am__append_5) $(am__append_6) # list of the libraries to build and install -lib_LTLIBRARIES = libkumu.la libasdcp.la $(am__append_6) -# sources for a library +lib_LTLIBRARIES = libkumu.la libasdcp.la $(am__append_7) \ + $(am__append_8) $(am__append_9) + +# sources for kumu library libkumu_la_SOURCES = KM_error.h KM_fileio.cpp KM_fileio.h KM_log.cpp KM_log.h \ KM_memio.h KM_mutex.h KM_platform.h KM_prng.cpp KM_prng.h KM_util.cpp \ KM_util.h KM_xml.cpp KM_xml.h KM_tai.h KM_tai.cpp @@ -452,26 +833,58 @@ libkumu_la_SOURCES = KM_error.h KM_fileio.cpp KM_fileio.h KM_log.cpp KM_log.h \ # linker flags (*not* including libraries to link against) for a library libkumu_la_LDFLAGS = -release @VERSION@ -# sources for a library that don't get added to a distribution -nodist_libasdcp_la_SOURCES = Metadata_h.tt2 Metadata_cpp.tt2 mxfgen.pl \ - MXF_def.pl ullist.pl ULList.xml dict.xml DMS_Crypto.xml \ - $(am__append_5) +# sources for asdcp library that don't get added to a distribution +nodist_libasdcp_la_SOURCES = Metadata_h.tt2 Metadata_cpp.tt2 \ + mxfgen.pl MXF_def.pl ullist.pl ULList.xml dict.xml DMS_Crypto.xml + +# sources for asdcp library libasdcp_la_SOURCES = MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp \ - JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp \ - TimedText_Parser.cpp KLV.cpp Dict.cpp MXFTypes.cpp MXF.cpp \ - Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp AS_DCP_AES.cpp \ - h__Reader.cpp h__Writer.cpp AS_DCP_MPEG2.cpp AS_DCP_JP2K.cpp \ - AS_DCP_PCM.cpp AS_DCP_TimedText.cpp PCMParserList.cpp \ - Wav.h WavFileWriter.h MXF.h Metadata.h \ - JP2K.h AS_DCP.h AS_DCP_internal.h KLV.h MPEG.h MXFTypes.h MDD.h \ - PCMParserList.h S12MTimecode.h MDD.cpp + JP2K_Sequence_Parser.cpp JP2K.cpp PCM_Parser.cpp Wav.cpp \ + TimedText_Parser.cpp KLV.cpp Dict.cpp MXFTypes.cpp MXF.cpp \ + Index.cpp Metadata.cpp AS_DCP.cpp AS_DCP_MXF.cpp AS_DCP_AES.cpp \ + h__Reader.cpp h__Writer.cpp AS_DCP_MPEG2.cpp AS_DCP_JP2K.cpp \ + AS_DCP_PCM.cpp AS_DCP_TimedText.cpp PCMParserList.cpp \ + Wav.h WavFileWriter.h MXF.h Metadata.h \ + JP2K.h AS_DCP.h AS_DCP_internal.h KLV.h MPEG.h MXFTypes.h MDD.h \ + PCMParserList.h S12MTimecode.h MDD.cpp \ + AS_DCP_ATMOS.cpp AS_DCP_DCData.cpp AS_DCP_DCData_internal.h \ + DCData_ByteStream_Parser.cpp DCData_Sequence_Parser.cpp \ + AtmosSyncChannel_Generator.cpp AtmosSyncChannel_Generator.h \ + AtmosSyncChannel_Mixer.cpp AtmosSyncChannel_Mixer.h \ + PCMDataProviders.cpp PCMDataProviders.h \ + SyncEncoder.c SyncEncoder.h SyncCommon.h CRC16.c CRC16.h \ + UUIDInformation.c UUIDInformation.h \ + ST2095_PinkNoise.cpp libasdcp_la_LDFLAGS = -release @VERSION@ - # additional libraries to link against for a library libasdcp_la_LIBADD = libkumu.la libasdcp_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\" -#### libnapali.la + +# sources for as-02 library +@USE_AS_02_TRUE@libas02_la_SOURCES = \ +@USE_AS_02_TRUE@ AS_02.h \ +@USE_AS_02_TRUE@ AS_02_internal.h \ +@USE_AS_02_TRUE@ h__02_Reader.cpp \ +@USE_AS_02_TRUE@ h__02_Writer.cpp \ +@USE_AS_02_TRUE@ AS_02_JP2K.cpp \ +@USE_AS_02_TRUE@ AS_02_PCM.cpp \ +@USE_AS_02_TRUE@ ST2052_TextParser.cpp \ +@USE_AS_02_TRUE@ AS_02_TimedText.cpp + +@USE_AS_02_TRUE@libas02_la_LDFLAGS = -release @VERSION@ +@USE_AS_02_TRUE@libas02_la_LIBADD = libasdcp.la libkumu.la +@USE_AS_02_TRUE@libas02_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\" + +# sources for PHDR library +@USE_PHDR_TRUE@libphdr_la_SOURCES = \ +@USE_PHDR_TRUE@ AS_02_PHDR.h \ +@USE_PHDR_TRUE@ PHDR_Sequence_Parser.cpp \ +@USE_PHDR_TRUE@ AS_02_PHDR.cpp + +@USE_PHDR_TRUE@libphdr_la_LDFLAGS = -release @VERSION@ +@USE_PHDR_TRUE@libphdr_la_LIBADD = libasdcp.la libkumu.la +@USE_PHDR_TRUE@libphdr_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\" @PYTHON_USE_TRUE@nodist_libpyasdcp_la_SOURCES = \ @PYTHON_USE_TRUE@ kumu_python.cpp \ @PYTHON_USE_TRUE@ kumu_python.h \ @@ -482,24 +895,18 @@ libasdcp_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\" @PYTHON_USE_TRUE@ asdcp_python_writerinfo.h \ @PYTHON_USE_TRUE@ asdcp_wrappers.h \ @PYTHON_USE_TRUE@ asdcp_python_mxf.cpp \ +@PYTHON_USE_TRUE@ asdcp_python_mxf.h \ @PYTHON_USE_TRUE@ asdcp_python_mxf_text.cpp \ @PYTHON_USE_TRUE@ asdcp_python_mxf_metadata.cpp - -####nodist_libnapali_la_SOURCES = \ -#### napali_python.cpp napali_python.h @PYTHON_USE_TRUE@libpyasdcp_la_CPPFLAGS = @PYTHON_CPPFLAGS@ @PYTHON_USE_TRUE@libpyasdcp_la_LDFLAGS = @PYTHON_LSPEC@ -release @VERSION@ -@PYTHON_USE_TRUE@libpyasdcp_la_LIBADD = libkumu.la libasdcp.la - -####libnapali_la_CPPFLAGS = @PYTHON_CPPFLAGS@ -####libnapali_la_LDFLAGS = @PYTHON_LSPEC@ -release @VERSION@ -####libnapali_la_LIBADD = libkumu.la libasdcp.la +@PYTHON_USE_TRUE@libpyasdcp_la_LIBADD = libkumu.la libasdcp.la \ +@PYTHON_USE_TRUE@ $(am__append_10) @PYTHON_USE_TRUE@pyexecdir = @PYTHON_EXECDIR@ @PYTHON_USE_TRUE@pyexec_includedir = $(PYTHON_PREFIX)/include/python$(PYTHON_SHORTVERSION) @PYTHON_USE_TRUE@nodist_pyexec_include_HEADERS = kumu_python.h asdcp_python.h asdcp_wrappers.h @PYTHON_USE_TRUE@pyexec_LTLIBRARIES = kumu.la asdcp.la -#### napali_python.h napali.la @PYTHON_USE_TRUE@nodist_kumu_la_SOURCES = pykumu.cpp kumu_python.h @PYTHON_USE_TRUE@kumu_la_CPPFLAGS = @PYTHON_CPPFLAGS@ @PYTHON_USE_TRUE@kumu_la_LDFLAGS = @PYTHON_LSPEC@ -avoid-version -module @@ -511,29 +918,41 @@ libasdcp_la_CPPFLAGS = -DASDCP_PLATFORM=\"@host@\" # sources and linkage for CLI utilities asdcp_test_SOURCES = asdcp-test.cpp -asdcp_test_LDADD = libasdcp.la +asdcp_test_LDADD = libasdcp.la libkumu.la asdcp_wrap_SOURCES = asdcp-wrap.cpp -asdcp_wrap_LDADD = libasdcp.la +asdcp_wrap_LDADD = libasdcp.la libkumu.la asdcp_unwrap_SOURCES = asdcp-unwrap.cpp -asdcp_unwrap_LDADD = libasdcp.la +asdcp_unwrap_LDADD = libasdcp.la libkumu.la asdcp_util_SOURCES = asdcp-util.cpp -asdcp_util_LDADD = libasdcp.la +asdcp_util_LDADD = libasdcp.la libkumu.la asdcp_info_SOURCES = asdcp-info.cpp -asdcp_info_LDADD = libasdcp.la +asdcp_info_LDADD = libasdcp.la libkumu.la kmfilegen_SOURCES = kmfilegen.cpp -kmfilegen_LDADD = libkumu.la +kmfilegen_LDADD = libkumu.la kmrandgen_SOURCES = kmrandgen.cpp -kmrandgen_LDADD = libkumu.la +kmrandgen_LDADD = libkumu.la kmuuidgen_SOURCES = kmuuidgen.cpp -kmuuidgen_LDADD = libkumu.la +kmuuidgen_LDADD = libkumu.la blackwave_SOURCES = blackwave.cpp -blackwave_LDADD = libasdcp.la +blackwave_LDADD = libasdcp.la libkumu.la +pinkwave_SOURCES = pinkwave.cpp +pinkwave_LDADD = libasdcp.la libkumu.la klvwalk_SOURCES = klvwalk.cpp -klvwalk_LDADD = libasdcp.la +klvwalk_LDADD = libasdcp.la libkumu.la wavesplit_SOURCES = wavesplit.cpp -wavesplit_LDADD = libasdcp.la +wavesplit_LDADD = libasdcp.la libkumu.la j2c_test_SOURCES = j2c-test.cpp -j2c_test_LDADD = libasdcp.la +j2c_test_LDADD = libasdcp.la libkumu.la +klvsplit_SOURCES = klvsplit.cpp +klvsplit_LDADD = libasdcp.la libkumu.la +@USE_AS_02_TRUE@as_02_wrap_SOURCES = as-02-wrap.cpp +@USE_AS_02_TRUE@as_02_wrap_LDADD = libas02.la libasdcp.la libkumu.la +@USE_AS_02_TRUE@as_02_unwrap_SOURCES = as-02-unwrap.cpp +@USE_AS_02_TRUE@as_02_unwrap_LDADD = libas02.la libasdcp.la libkumu.la +@USE_PHDR_TRUE@phdr_wrap_SOURCES = phdr-wrap.cpp +@USE_PHDR_TRUE@phdr_wrap_LDADD = libphdr.la libas02.la libasdcp.la libkumu.la +@USE_PHDR_TRUE@phdr_unwrap_SOURCES = phdr-unwrap.cpp +@USE_PHDR_TRUE@phdr_unwrap_LDADD = libphdr.la libas02.la libasdcp.la libkumu.la # sources for a test program # list of libraries to link against for a test program @@ -544,8 +963,8 @@ path_test_LDADD = libkumu.la fips_186_rng_test_SOURCES = fips-186-rng-test.cpp fips_186_rng_test_LDADD = libasdcp.la asdcp_version_SOURCES = asdcp-version.cpp -asdcp_version_LDADD = libkumu.la -@DEV_HEADERS_TRUE@nodist_tt_xform_SOURCES = tt-xform.cpp +asdcp_version_LDADD = libkumu.la +@DEV_HEADERS_TRUE@nodist_tt_xform_SOURCES = tt-xform.cpp TimedText_Transform.h @DEV_HEADERS_TRUE@tt_xform_LDADD = libasdcp.la # list of test scripts to execute during "make check" @@ -561,9 +980,8 @@ TESTS_ENVIRONMENT = BUILD_DIR="." TEST_FILES=../tests TEST_FILE_PREFIX=DCPd1-M1 # files to include in the distribution that automake doesn't automatically include -EXTRA_DIST = fips-186-test-harness.pl $(TESTS) $(am__append_8) \ - $(am__append_9) -#### $(nodist_napali_la_SOURCES) $(nodist_libnapali_la_SOURCES) +EXTRA_DIST = fips-186-test-harness.pl $(TESTS) $(am__append_14) \ + $(am__append_15) # source files that are themselves built BUILT_SOURCES = Metadata.h Metadata.cpp MDD.h MDD.cpp @@ -573,7 +991,7 @@ all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: -.SUFFIXES: .cpp .lo .o .obj +.SUFFIXES: .c .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -604,9 +1022,9 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): + install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -614,6 +1032,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } @@ -629,15 +1049,17 @@ uninstall-libLTLIBRARIES: clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + install-pyexecLTLIBRARIES: $(pyexec_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(pyexecdir)" || $(MKDIR_P) "$(DESTDIR)$(pyexecdir)" @list='$(pyexec_LTLIBRARIES)'; test -n "$(pyexecdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -645,6 +1067,8 @@ install-pyexecLTLIBRARIES: $(pyexec_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pyexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pyexecdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pyexecdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pyexecdir)"; \ } @@ -660,32 +1084,50 @@ uninstall-pyexecLTLIBRARIES: clean-pyexecLTLIBRARIES: -test -z "$(pyexec_LTLIBRARIES)" || rm -f $(pyexec_LTLIBRARIES) - @list='$(pyexec_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done + @list='$(pyexec_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + asdcp.la: $(asdcp_la_OBJECTS) $(asdcp_la_DEPENDENCIES) $(EXTRA_asdcp_la_DEPENDENCIES) - $(asdcp_la_LINK) $(am_asdcp_la_rpath) $(asdcp_la_OBJECTS) $(asdcp_la_LIBADD) $(LIBS) + $(AM_V_CXXLD)$(asdcp_la_LINK) $(am_asdcp_la_rpath) $(asdcp_la_OBJECTS) $(asdcp_la_LIBADD) $(LIBS) + kumu.la: $(kumu_la_OBJECTS) $(kumu_la_DEPENDENCIES) $(EXTRA_kumu_la_DEPENDENCIES) - $(kumu_la_LINK) $(am_kumu_la_rpath) $(kumu_la_OBJECTS) $(kumu_la_LIBADD) $(LIBS) + $(AM_V_CXXLD)$(kumu_la_LINK) $(am_kumu_la_rpath) $(kumu_la_OBJECTS) $(kumu_la_LIBADD) $(LIBS) + +libas02.la: $(libas02_la_OBJECTS) $(libas02_la_DEPENDENCIES) $(EXTRA_libas02_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libas02_la_LINK) $(am_libas02_la_rpath) $(libas02_la_OBJECTS) $(libas02_la_LIBADD) $(LIBS) + libasdcp.la: $(libasdcp_la_OBJECTS) $(libasdcp_la_DEPENDENCIES) $(EXTRA_libasdcp_la_DEPENDENCIES) - $(libasdcp_la_LINK) -rpath $(libdir) $(libasdcp_la_OBJECTS) $(libasdcp_la_LIBADD) $(LIBS) + $(AM_V_CXXLD)$(libasdcp_la_LINK) -rpath $(libdir) $(libasdcp_la_OBJECTS) $(libasdcp_la_LIBADD) $(LIBS) + libkumu.la: $(libkumu_la_OBJECTS) $(libkumu_la_DEPENDENCIES) $(EXTRA_libkumu_la_DEPENDENCIES) - $(libkumu_la_LINK) -rpath $(libdir) $(libkumu_la_OBJECTS) $(libkumu_la_LIBADD) $(LIBS) + $(AM_V_CXXLD)$(libkumu_la_LINK) -rpath $(libdir) $(libkumu_la_OBJECTS) $(libkumu_la_LIBADD) $(LIBS) + +libphdr.la: $(libphdr_la_OBJECTS) $(libphdr_la_DEPENDENCIES) $(EXTRA_libphdr_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libphdr_la_LINK) $(am_libphdr_la_rpath) $(libphdr_la_OBJECTS) $(libphdr_la_LIBADD) $(LIBS) + libpyasdcp.la: $(libpyasdcp_la_OBJECTS) $(libpyasdcp_la_DEPENDENCIES) $(EXTRA_libpyasdcp_la_DEPENDENCIES) - $(libpyasdcp_la_LINK) $(am_libpyasdcp_la_rpath) $(libpyasdcp_la_OBJECTS) $(libpyasdcp_la_LIBADD) $(LIBS) + $(AM_V_CXXLD)$(libpyasdcp_la_LINK) $(am_libpyasdcp_la_rpath) $(libpyasdcp_la_OBJECTS) $(libpyasdcp_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p || test -f $$p1; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -706,7 +1148,8 @@ uninstall-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files @@ -728,57 +1171,98 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list + +as-02-unwrap$(EXEEXT): $(as_02_unwrap_OBJECTS) $(as_02_unwrap_DEPENDENCIES) $(EXTRA_as_02_unwrap_DEPENDENCIES) + @rm -f as-02-unwrap$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(as_02_unwrap_OBJECTS) $(as_02_unwrap_LDADD) $(LIBS) + +as-02-wrap$(EXEEXT): $(as_02_wrap_OBJECTS) $(as_02_wrap_DEPENDENCIES) $(EXTRA_as_02_wrap_DEPENDENCIES) + @rm -f as-02-wrap$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(as_02_wrap_OBJECTS) $(as_02_wrap_LDADD) $(LIBS) + asdcp-info$(EXEEXT): $(asdcp_info_OBJECTS) $(asdcp_info_DEPENDENCIES) $(EXTRA_asdcp_info_DEPENDENCIES) @rm -f asdcp-info$(EXEEXT) - $(CXXLINK) $(asdcp_info_OBJECTS) $(asdcp_info_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(asdcp_info_OBJECTS) $(asdcp_info_LDADD) $(LIBS) + asdcp-mem-test$(EXEEXT): $(asdcp_mem_test_OBJECTS) $(asdcp_mem_test_DEPENDENCIES) $(EXTRA_asdcp_mem_test_DEPENDENCIES) @rm -f asdcp-mem-test$(EXEEXT) - $(CXXLINK) $(asdcp_mem_test_OBJECTS) $(asdcp_mem_test_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(asdcp_mem_test_OBJECTS) $(asdcp_mem_test_LDADD) $(LIBS) + asdcp-test$(EXEEXT): $(asdcp_test_OBJECTS) $(asdcp_test_DEPENDENCIES) $(EXTRA_asdcp_test_DEPENDENCIES) @rm -f asdcp-test$(EXEEXT) - $(CXXLINK) $(asdcp_test_OBJECTS) $(asdcp_test_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(asdcp_test_OBJECTS) $(asdcp_test_LDADD) $(LIBS) + asdcp-unwrap$(EXEEXT): $(asdcp_unwrap_OBJECTS) $(asdcp_unwrap_DEPENDENCIES) $(EXTRA_asdcp_unwrap_DEPENDENCIES) @rm -f asdcp-unwrap$(EXEEXT) - $(CXXLINK) $(asdcp_unwrap_OBJECTS) $(asdcp_unwrap_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(asdcp_unwrap_OBJECTS) $(asdcp_unwrap_LDADD) $(LIBS) + asdcp-util$(EXEEXT): $(asdcp_util_OBJECTS) $(asdcp_util_DEPENDENCIES) $(EXTRA_asdcp_util_DEPENDENCIES) @rm -f asdcp-util$(EXEEXT) - $(CXXLINK) $(asdcp_util_OBJECTS) $(asdcp_util_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(asdcp_util_OBJECTS) $(asdcp_util_LDADD) $(LIBS) + asdcp-version$(EXEEXT): $(asdcp_version_OBJECTS) $(asdcp_version_DEPENDENCIES) $(EXTRA_asdcp_version_DEPENDENCIES) @rm -f asdcp-version$(EXEEXT) - $(CXXLINK) $(asdcp_version_OBJECTS) $(asdcp_version_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(asdcp_version_OBJECTS) $(asdcp_version_LDADD) $(LIBS) + asdcp-wrap$(EXEEXT): $(asdcp_wrap_OBJECTS) $(asdcp_wrap_DEPENDENCIES) $(EXTRA_asdcp_wrap_DEPENDENCIES) @rm -f asdcp-wrap$(EXEEXT) - $(CXXLINK) $(asdcp_wrap_OBJECTS) $(asdcp_wrap_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(asdcp_wrap_OBJECTS) $(asdcp_wrap_LDADD) $(LIBS) + blackwave$(EXEEXT): $(blackwave_OBJECTS) $(blackwave_DEPENDENCIES) $(EXTRA_blackwave_DEPENDENCIES) @rm -f blackwave$(EXEEXT) - $(CXXLINK) $(blackwave_OBJECTS) $(blackwave_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(blackwave_OBJECTS) $(blackwave_LDADD) $(LIBS) + fips-186-rng-test$(EXEEXT): $(fips_186_rng_test_OBJECTS) $(fips_186_rng_test_DEPENDENCIES) $(EXTRA_fips_186_rng_test_DEPENDENCIES) @rm -f fips-186-rng-test$(EXEEXT) - $(CXXLINK) $(fips_186_rng_test_OBJECTS) $(fips_186_rng_test_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(fips_186_rng_test_OBJECTS) $(fips_186_rng_test_LDADD) $(LIBS) + j2c-test$(EXEEXT): $(j2c_test_OBJECTS) $(j2c_test_DEPENDENCIES) $(EXTRA_j2c_test_DEPENDENCIES) @rm -f j2c-test$(EXEEXT) - $(CXXLINK) $(j2c_test_OBJECTS) $(j2c_test_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(j2c_test_OBJECTS) $(j2c_test_LDADD) $(LIBS) + +klvsplit$(EXEEXT): $(klvsplit_OBJECTS) $(klvsplit_DEPENDENCIES) $(EXTRA_klvsplit_DEPENDENCIES) + @rm -f klvsplit$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(klvsplit_OBJECTS) $(klvsplit_LDADD) $(LIBS) + klvwalk$(EXEEXT): $(klvwalk_OBJECTS) $(klvwalk_DEPENDENCIES) $(EXTRA_klvwalk_DEPENDENCIES) @rm -f klvwalk$(EXEEXT) - $(CXXLINK) $(klvwalk_OBJECTS) $(klvwalk_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(klvwalk_OBJECTS) $(klvwalk_LDADD) $(LIBS) + kmfilegen$(EXEEXT): $(kmfilegen_OBJECTS) $(kmfilegen_DEPENDENCIES) $(EXTRA_kmfilegen_DEPENDENCIES) @rm -f kmfilegen$(EXEEXT) - $(CXXLINK) $(kmfilegen_OBJECTS) $(kmfilegen_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(kmfilegen_OBJECTS) $(kmfilegen_LDADD) $(LIBS) + kmrandgen$(EXEEXT): $(kmrandgen_OBJECTS) $(kmrandgen_DEPENDENCIES) $(EXTRA_kmrandgen_DEPENDENCIES) @rm -f kmrandgen$(EXEEXT) - $(CXXLINK) $(kmrandgen_OBJECTS) $(kmrandgen_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(kmrandgen_OBJECTS) $(kmrandgen_LDADD) $(LIBS) + kmuuidgen$(EXEEXT): $(kmuuidgen_OBJECTS) $(kmuuidgen_DEPENDENCIES) $(EXTRA_kmuuidgen_DEPENDENCIES) @rm -f kmuuidgen$(EXEEXT) - $(CXXLINK) $(kmuuidgen_OBJECTS) $(kmuuidgen_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(kmuuidgen_OBJECTS) $(kmuuidgen_LDADD) $(LIBS) + path-test$(EXEEXT): $(path_test_OBJECTS) $(path_test_DEPENDENCIES) $(EXTRA_path_test_DEPENDENCIES) @rm -f path-test$(EXEEXT) - $(CXXLINK) $(path_test_OBJECTS) $(path_test_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(path_test_OBJECTS) $(path_test_LDADD) $(LIBS) + +phdr-unwrap$(EXEEXT): $(phdr_unwrap_OBJECTS) $(phdr_unwrap_DEPENDENCIES) $(EXTRA_phdr_unwrap_DEPENDENCIES) + @rm -f phdr-unwrap$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(phdr_unwrap_OBJECTS) $(phdr_unwrap_LDADD) $(LIBS) + +phdr-wrap$(EXEEXT): $(phdr_wrap_OBJECTS) $(phdr_wrap_DEPENDENCIES) $(EXTRA_phdr_wrap_DEPENDENCIES) + @rm -f phdr-wrap$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(phdr_wrap_OBJECTS) $(phdr_wrap_LDADD) $(LIBS) + +pinkwave$(EXEEXT): $(pinkwave_OBJECTS) $(pinkwave_DEPENDENCIES) $(EXTRA_pinkwave_DEPENDENCIES) + @rm -f pinkwave$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(pinkwave_OBJECTS) $(pinkwave_LDADD) $(LIBS) + tt-xform$(EXEEXT): $(tt_xform_OBJECTS) $(tt_xform_DEPENDENCIES) $(EXTRA_tt_xform_DEPENDENCIES) @rm -f tt-xform$(EXEEXT) - $(CXXLINK) $(tt_xform_OBJECTS) $(tt_xform_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(tt_xform_OBJECTS) $(tt_xform_LDADD) $(LIBS) + wavesplit$(EXEEXT): $(wavesplit_OBJECTS) $(wavesplit_DEPENDENCIES) $(EXTRA_wavesplit_DEPENDENCIES) @rm -f wavesplit$(EXEEXT) - $(CXXLINK) $(wavesplit_OBJECTS) $(wavesplit_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(wavesplit_OBJECTS) $(wavesplit_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -792,6 +1276,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KM_tai.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KM_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KM_xml.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/as-02-unwrap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/as-02-wrap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asdcp-info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asdcp-mem-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asdcp-test.Po@am__quote@ @@ -803,18 +1289,32 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blackwave.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips-186-rng-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/j2c-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/klvsplit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/klvwalk.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kmfilegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kmrandgen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kmuuidgen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kumu_la-pykumu.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libas02_la-AS_02_JP2K.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libas02_la-AS_02_PCM.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libas02_la-AS_02_TimedText.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libas02_la-ST2052_TextParser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libas02_la-h__02_Reader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libas02_la-h__02_Writer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP_AES.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP_ATMOS.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP_DCData.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP_JP2K.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP_MPEG2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP_MXF.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP_PCM.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AS_DCP_TimedText.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AtmosSyncChannel_Generator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-AtmosSyncChannel_Mixer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-CRC16.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-DCData_ByteStream_Parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-DCData_Sequence_Parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-Dict.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-Index.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-JP2K.Plo@am__quote@ @@ -827,13 +1327,18 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-MXF.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-MXFTypes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-Metadata.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-PCMDataProviders.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-PCMParserList.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-PCM_Parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-ST2095_PinkNoise.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-SyncEncoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-TimedText_Parser.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-TimedText_Transform.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-UUIDInformation.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-Wav.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-h__Reader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libasdcp_la-h__Writer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libphdr_la-AS_02_PHDR.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libphdr_la-PHDR_Sequence_Parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpyasdcp_la-asdcp_python.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpyasdcp_la-asdcp_python_descriptor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpyasdcp_la-asdcp_python_misc.Plo@am__quote@ @@ -842,274 +1347,424 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_text.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpyasdcp_la-kumu_python.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path-test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phdr-unwrap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phdr-wrap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pinkwave.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt-xform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wavesplit.Po@am__quote@ +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libasdcp_la-SyncEncoder.lo: SyncEncoder.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libasdcp_la-SyncEncoder.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-SyncEncoder.Tpo -c -o libasdcp_la-SyncEncoder.lo `test -f 'SyncEncoder.c' || echo '$(srcdir)/'`SyncEncoder.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-SyncEncoder.Tpo $(DEPDIR)/libasdcp_la-SyncEncoder.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='SyncEncoder.c' object='libasdcp_la-SyncEncoder.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libasdcp_la-SyncEncoder.lo `test -f 'SyncEncoder.c' || echo '$(srcdir)/'`SyncEncoder.c + +libasdcp_la-CRC16.lo: CRC16.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libasdcp_la-CRC16.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-CRC16.Tpo -c -o libasdcp_la-CRC16.lo `test -f 'CRC16.c' || echo '$(srcdir)/'`CRC16.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-CRC16.Tpo $(DEPDIR)/libasdcp_la-CRC16.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='CRC16.c' object='libasdcp_la-CRC16.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libasdcp_la-CRC16.lo `test -f 'CRC16.c' || echo '$(srcdir)/'`CRC16.c + +libasdcp_la-UUIDInformation.lo: UUIDInformation.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libasdcp_la-UUIDInformation.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-UUIDInformation.Tpo -c -o libasdcp_la-UUIDInformation.lo `test -f 'UUIDInformation.c' || echo '$(srcdir)/'`UUIDInformation.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-UUIDInformation.Tpo $(DEPDIR)/libasdcp_la-UUIDInformation.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UUIDInformation.c' object='libasdcp_la-UUIDInformation.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libasdcp_la-UUIDInformation.lo `test -f 'UUIDInformation.c' || echo '$(srcdir)/'`UUIDInformation.c + .cpp.o: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< asdcp_la-pyasdcp.lo: pyasdcp.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(asdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT asdcp_la-pyasdcp.lo -MD -MP -MF $(DEPDIR)/asdcp_la-pyasdcp.Tpo -c -o asdcp_la-pyasdcp.lo `test -f 'pyasdcp.cpp' || echo '$(srcdir)/'`pyasdcp.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/asdcp_la-pyasdcp.Tpo $(DEPDIR)/asdcp_la-pyasdcp.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='pyasdcp.cpp' object='asdcp_la-pyasdcp.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(asdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT asdcp_la-pyasdcp.lo -MD -MP -MF $(DEPDIR)/asdcp_la-pyasdcp.Tpo -c -o asdcp_la-pyasdcp.lo `test -f 'pyasdcp.cpp' || echo '$(srcdir)/'`pyasdcp.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/asdcp_la-pyasdcp.Tpo $(DEPDIR)/asdcp_la-pyasdcp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pyasdcp.cpp' object='asdcp_la-pyasdcp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(asdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o asdcp_la-pyasdcp.lo `test -f 'pyasdcp.cpp' || echo '$(srcdir)/'`pyasdcp.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(asdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o asdcp_la-pyasdcp.lo `test -f 'pyasdcp.cpp' || echo '$(srcdir)/'`pyasdcp.cpp kumu_la-pykumu.lo: pykumu.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(kumu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT kumu_la-pykumu.lo -MD -MP -MF $(DEPDIR)/kumu_la-pykumu.Tpo -c -o kumu_la-pykumu.lo `test -f 'pykumu.cpp' || echo '$(srcdir)/'`pykumu.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/kumu_la-pykumu.Tpo $(DEPDIR)/kumu_la-pykumu.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='pykumu.cpp' object='kumu_la-pykumu.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(kumu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT kumu_la-pykumu.lo -MD -MP -MF $(DEPDIR)/kumu_la-pykumu.Tpo -c -o kumu_la-pykumu.lo `test -f 'pykumu.cpp' || echo '$(srcdir)/'`pykumu.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/kumu_la-pykumu.Tpo $(DEPDIR)/kumu_la-pykumu.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pykumu.cpp' object='kumu_la-pykumu.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(kumu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o kumu_la-pykumu.lo `test -f 'pykumu.cpp' || echo '$(srcdir)/'`pykumu.cpp + +libas02_la-h__02_Reader.lo: h__02_Reader.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libas02_la-h__02_Reader.lo -MD -MP -MF $(DEPDIR)/libas02_la-h__02_Reader.Tpo -c -o libas02_la-h__02_Reader.lo `test -f 'h__02_Reader.cpp' || echo '$(srcdir)/'`h__02_Reader.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libas02_la-h__02_Reader.Tpo $(DEPDIR)/libas02_la-h__02_Reader.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='h__02_Reader.cpp' object='libas02_la-h__02_Reader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(kumu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o kumu_la-pykumu.lo `test -f 'pykumu.cpp' || echo '$(srcdir)/'`pykumu.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libas02_la-h__02_Reader.lo `test -f 'h__02_Reader.cpp' || echo '$(srcdir)/'`h__02_Reader.cpp + +libas02_la-h__02_Writer.lo: h__02_Writer.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libas02_la-h__02_Writer.lo -MD -MP -MF $(DEPDIR)/libas02_la-h__02_Writer.Tpo -c -o libas02_la-h__02_Writer.lo `test -f 'h__02_Writer.cpp' || echo '$(srcdir)/'`h__02_Writer.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libas02_la-h__02_Writer.Tpo $(DEPDIR)/libas02_la-h__02_Writer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='h__02_Writer.cpp' object='libas02_la-h__02_Writer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libas02_la-h__02_Writer.lo `test -f 'h__02_Writer.cpp' || echo '$(srcdir)/'`h__02_Writer.cpp + +libas02_la-AS_02_JP2K.lo: AS_02_JP2K.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libas02_la-AS_02_JP2K.lo -MD -MP -MF $(DEPDIR)/libas02_la-AS_02_JP2K.Tpo -c -o libas02_la-AS_02_JP2K.lo `test -f 'AS_02_JP2K.cpp' || echo '$(srcdir)/'`AS_02_JP2K.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libas02_la-AS_02_JP2K.Tpo $(DEPDIR)/libas02_la-AS_02_JP2K.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_02_JP2K.cpp' object='libas02_la-AS_02_JP2K.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libas02_la-AS_02_JP2K.lo `test -f 'AS_02_JP2K.cpp' || echo '$(srcdir)/'`AS_02_JP2K.cpp + +libas02_la-AS_02_PCM.lo: AS_02_PCM.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libas02_la-AS_02_PCM.lo -MD -MP -MF $(DEPDIR)/libas02_la-AS_02_PCM.Tpo -c -o libas02_la-AS_02_PCM.lo `test -f 'AS_02_PCM.cpp' || echo '$(srcdir)/'`AS_02_PCM.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libas02_la-AS_02_PCM.Tpo $(DEPDIR)/libas02_la-AS_02_PCM.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_02_PCM.cpp' object='libas02_la-AS_02_PCM.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libas02_la-AS_02_PCM.lo `test -f 'AS_02_PCM.cpp' || echo '$(srcdir)/'`AS_02_PCM.cpp + +libas02_la-ST2052_TextParser.lo: ST2052_TextParser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libas02_la-ST2052_TextParser.lo -MD -MP -MF $(DEPDIR)/libas02_la-ST2052_TextParser.Tpo -c -o libas02_la-ST2052_TextParser.lo `test -f 'ST2052_TextParser.cpp' || echo '$(srcdir)/'`ST2052_TextParser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libas02_la-ST2052_TextParser.Tpo $(DEPDIR)/libas02_la-ST2052_TextParser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ST2052_TextParser.cpp' object='libas02_la-ST2052_TextParser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libas02_la-ST2052_TextParser.lo `test -f 'ST2052_TextParser.cpp' || echo '$(srcdir)/'`ST2052_TextParser.cpp + +libas02_la-AS_02_TimedText.lo: AS_02_TimedText.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libas02_la-AS_02_TimedText.lo -MD -MP -MF $(DEPDIR)/libas02_la-AS_02_TimedText.Tpo -c -o libas02_la-AS_02_TimedText.lo `test -f 'AS_02_TimedText.cpp' || echo '$(srcdir)/'`AS_02_TimedText.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libas02_la-AS_02_TimedText.Tpo $(DEPDIR)/libas02_la-AS_02_TimedText.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_02_TimedText.cpp' object='libas02_la-AS_02_TimedText.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libas02_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libas02_la-AS_02_TimedText.lo `test -f 'AS_02_TimedText.cpp' || echo '$(srcdir)/'`AS_02_TimedText.cpp libasdcp_la-MPEG2_Parser.lo: MPEG2_Parser.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MPEG2_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MPEG2_Parser.Tpo -c -o libasdcp_la-MPEG2_Parser.lo `test -f 'MPEG2_Parser.cpp' || echo '$(srcdir)/'`MPEG2_Parser.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-MPEG2_Parser.Tpo $(DEPDIR)/libasdcp_la-MPEG2_Parser.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MPEG2_Parser.cpp' object='libasdcp_la-MPEG2_Parser.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MPEG2_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MPEG2_Parser.Tpo -c -o libasdcp_la-MPEG2_Parser.lo `test -f 'MPEG2_Parser.cpp' || echo '$(srcdir)/'`MPEG2_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-MPEG2_Parser.Tpo $(DEPDIR)/libasdcp_la-MPEG2_Parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MPEG2_Parser.cpp' object='libasdcp_la-MPEG2_Parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MPEG2_Parser.lo `test -f 'MPEG2_Parser.cpp' || echo '$(srcdir)/'`MPEG2_Parser.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MPEG2_Parser.lo `test -f 'MPEG2_Parser.cpp' || echo '$(srcdir)/'`MPEG2_Parser.cpp libasdcp_la-MPEG.lo: MPEG.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MPEG.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MPEG.Tpo -c -o libasdcp_la-MPEG.lo `test -f 'MPEG.cpp' || echo '$(srcdir)/'`MPEG.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-MPEG.Tpo $(DEPDIR)/libasdcp_la-MPEG.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MPEG.cpp' object='libasdcp_la-MPEG.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MPEG.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MPEG.Tpo -c -o libasdcp_la-MPEG.lo `test -f 'MPEG.cpp' || echo '$(srcdir)/'`MPEG.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-MPEG.Tpo $(DEPDIR)/libasdcp_la-MPEG.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MPEG.cpp' object='libasdcp_la-MPEG.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MPEG.lo `test -f 'MPEG.cpp' || echo '$(srcdir)/'`MPEG.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MPEG.lo `test -f 'MPEG.cpp' || echo '$(srcdir)/'`MPEG.cpp libasdcp_la-JP2K_Codestream_Parser.lo: JP2K_Codestream_Parser.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-JP2K_Codestream_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-JP2K_Codestream_Parser.Tpo -c -o libasdcp_la-JP2K_Codestream_Parser.lo `test -f 'JP2K_Codestream_Parser.cpp' || echo '$(srcdir)/'`JP2K_Codestream_Parser.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-JP2K_Codestream_Parser.Tpo $(DEPDIR)/libasdcp_la-JP2K_Codestream_Parser.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='JP2K_Codestream_Parser.cpp' object='libasdcp_la-JP2K_Codestream_Parser.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-JP2K_Codestream_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-JP2K_Codestream_Parser.Tpo -c -o libasdcp_la-JP2K_Codestream_Parser.lo `test -f 'JP2K_Codestream_Parser.cpp' || echo '$(srcdir)/'`JP2K_Codestream_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-JP2K_Codestream_Parser.Tpo $(DEPDIR)/libasdcp_la-JP2K_Codestream_Parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='JP2K_Codestream_Parser.cpp' object='libasdcp_la-JP2K_Codestream_Parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-JP2K_Codestream_Parser.lo `test -f 'JP2K_Codestream_Parser.cpp' || echo '$(srcdir)/'`JP2K_Codestream_Parser.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-JP2K_Codestream_Parser.lo `test -f 'JP2K_Codestream_Parser.cpp' || echo '$(srcdir)/'`JP2K_Codestream_Parser.cpp libasdcp_la-JP2K_Sequence_Parser.lo: JP2K_Sequence_Parser.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-JP2K_Sequence_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-JP2K_Sequence_Parser.Tpo -c -o libasdcp_la-JP2K_Sequence_Parser.lo `test -f 'JP2K_Sequence_Parser.cpp' || echo '$(srcdir)/'`JP2K_Sequence_Parser.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-JP2K_Sequence_Parser.Tpo $(DEPDIR)/libasdcp_la-JP2K_Sequence_Parser.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='JP2K_Sequence_Parser.cpp' object='libasdcp_la-JP2K_Sequence_Parser.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-JP2K_Sequence_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-JP2K_Sequence_Parser.Tpo -c -o libasdcp_la-JP2K_Sequence_Parser.lo `test -f 'JP2K_Sequence_Parser.cpp' || echo '$(srcdir)/'`JP2K_Sequence_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-JP2K_Sequence_Parser.Tpo $(DEPDIR)/libasdcp_la-JP2K_Sequence_Parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='JP2K_Sequence_Parser.cpp' object='libasdcp_la-JP2K_Sequence_Parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-JP2K_Sequence_Parser.lo `test -f 'JP2K_Sequence_Parser.cpp' || echo '$(srcdir)/'`JP2K_Sequence_Parser.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-JP2K_Sequence_Parser.lo `test -f 'JP2K_Sequence_Parser.cpp' || echo '$(srcdir)/'`JP2K_Sequence_Parser.cpp libasdcp_la-JP2K.lo: JP2K.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-JP2K.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-JP2K.Tpo -c -o libasdcp_la-JP2K.lo `test -f 'JP2K.cpp' || echo '$(srcdir)/'`JP2K.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-JP2K.Tpo $(DEPDIR)/libasdcp_la-JP2K.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='JP2K.cpp' object='libasdcp_la-JP2K.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-JP2K.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-JP2K.Tpo -c -o libasdcp_la-JP2K.lo `test -f 'JP2K.cpp' || echo '$(srcdir)/'`JP2K.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-JP2K.Tpo $(DEPDIR)/libasdcp_la-JP2K.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='JP2K.cpp' object='libasdcp_la-JP2K.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-JP2K.lo `test -f 'JP2K.cpp' || echo '$(srcdir)/'`JP2K.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-JP2K.lo `test -f 'JP2K.cpp' || echo '$(srcdir)/'`JP2K.cpp libasdcp_la-PCM_Parser.lo: PCM_Parser.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-PCM_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-PCM_Parser.Tpo -c -o libasdcp_la-PCM_Parser.lo `test -f 'PCM_Parser.cpp' || echo '$(srcdir)/'`PCM_Parser.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-PCM_Parser.Tpo $(DEPDIR)/libasdcp_la-PCM_Parser.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PCM_Parser.cpp' object='libasdcp_la-PCM_Parser.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-PCM_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-PCM_Parser.Tpo -c -o libasdcp_la-PCM_Parser.lo `test -f 'PCM_Parser.cpp' || echo '$(srcdir)/'`PCM_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-PCM_Parser.Tpo $(DEPDIR)/libasdcp_la-PCM_Parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PCM_Parser.cpp' object='libasdcp_la-PCM_Parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-PCM_Parser.lo `test -f 'PCM_Parser.cpp' || echo '$(srcdir)/'`PCM_Parser.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-PCM_Parser.lo `test -f 'PCM_Parser.cpp' || echo '$(srcdir)/'`PCM_Parser.cpp libasdcp_la-Wav.lo: Wav.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-Wav.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-Wav.Tpo -c -o libasdcp_la-Wav.lo `test -f 'Wav.cpp' || echo '$(srcdir)/'`Wav.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-Wav.Tpo $(DEPDIR)/libasdcp_la-Wav.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Wav.cpp' object='libasdcp_la-Wav.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-Wav.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-Wav.Tpo -c -o libasdcp_la-Wav.lo `test -f 'Wav.cpp' || echo '$(srcdir)/'`Wav.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-Wav.Tpo $(DEPDIR)/libasdcp_la-Wav.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Wav.cpp' object='libasdcp_la-Wav.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-Wav.lo `test -f 'Wav.cpp' || echo '$(srcdir)/'`Wav.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-Wav.lo `test -f 'Wav.cpp' || echo '$(srcdir)/'`Wav.cpp libasdcp_la-TimedText_Parser.lo: TimedText_Parser.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-TimedText_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-TimedText_Parser.Tpo -c -o libasdcp_la-TimedText_Parser.lo `test -f 'TimedText_Parser.cpp' || echo '$(srcdir)/'`TimedText_Parser.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-TimedText_Parser.Tpo $(DEPDIR)/libasdcp_la-TimedText_Parser.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TimedText_Parser.cpp' object='libasdcp_la-TimedText_Parser.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-TimedText_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-TimedText_Parser.Tpo -c -o libasdcp_la-TimedText_Parser.lo `test -f 'TimedText_Parser.cpp' || echo '$(srcdir)/'`TimedText_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-TimedText_Parser.Tpo $(DEPDIR)/libasdcp_la-TimedText_Parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimedText_Parser.cpp' object='libasdcp_la-TimedText_Parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-TimedText_Parser.lo `test -f 'TimedText_Parser.cpp' || echo '$(srcdir)/'`TimedText_Parser.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-TimedText_Parser.lo `test -f 'TimedText_Parser.cpp' || echo '$(srcdir)/'`TimedText_Parser.cpp libasdcp_la-KLV.lo: KLV.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-KLV.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-KLV.Tpo -c -o libasdcp_la-KLV.lo `test -f 'KLV.cpp' || echo '$(srcdir)/'`KLV.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-KLV.Tpo $(DEPDIR)/libasdcp_la-KLV.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='KLV.cpp' object='libasdcp_la-KLV.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-KLV.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-KLV.Tpo -c -o libasdcp_la-KLV.lo `test -f 'KLV.cpp' || echo '$(srcdir)/'`KLV.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-KLV.Tpo $(DEPDIR)/libasdcp_la-KLV.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='KLV.cpp' object='libasdcp_la-KLV.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-KLV.lo `test -f 'KLV.cpp' || echo '$(srcdir)/'`KLV.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-KLV.lo `test -f 'KLV.cpp' || echo '$(srcdir)/'`KLV.cpp libasdcp_la-Dict.lo: Dict.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-Dict.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-Dict.Tpo -c -o libasdcp_la-Dict.lo `test -f 'Dict.cpp' || echo '$(srcdir)/'`Dict.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-Dict.Tpo $(DEPDIR)/libasdcp_la-Dict.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Dict.cpp' object='libasdcp_la-Dict.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-Dict.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-Dict.Tpo -c -o libasdcp_la-Dict.lo `test -f 'Dict.cpp' || echo '$(srcdir)/'`Dict.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-Dict.Tpo $(DEPDIR)/libasdcp_la-Dict.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Dict.cpp' object='libasdcp_la-Dict.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-Dict.lo `test -f 'Dict.cpp' || echo '$(srcdir)/'`Dict.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-Dict.lo `test -f 'Dict.cpp' || echo '$(srcdir)/'`Dict.cpp libasdcp_la-MXFTypes.lo: MXFTypes.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MXFTypes.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MXFTypes.Tpo -c -o libasdcp_la-MXFTypes.lo `test -f 'MXFTypes.cpp' || echo '$(srcdir)/'`MXFTypes.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-MXFTypes.Tpo $(DEPDIR)/libasdcp_la-MXFTypes.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MXFTypes.cpp' object='libasdcp_la-MXFTypes.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MXFTypes.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MXFTypes.Tpo -c -o libasdcp_la-MXFTypes.lo `test -f 'MXFTypes.cpp' || echo '$(srcdir)/'`MXFTypes.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-MXFTypes.Tpo $(DEPDIR)/libasdcp_la-MXFTypes.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MXFTypes.cpp' object='libasdcp_la-MXFTypes.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MXFTypes.lo `test -f 'MXFTypes.cpp' || echo '$(srcdir)/'`MXFTypes.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MXFTypes.lo `test -f 'MXFTypes.cpp' || echo '$(srcdir)/'`MXFTypes.cpp libasdcp_la-MXF.lo: MXF.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MXF.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MXF.Tpo -c -o libasdcp_la-MXF.lo `test -f 'MXF.cpp' || echo '$(srcdir)/'`MXF.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-MXF.Tpo $(DEPDIR)/libasdcp_la-MXF.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MXF.cpp' object='libasdcp_la-MXF.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MXF.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MXF.Tpo -c -o libasdcp_la-MXF.lo `test -f 'MXF.cpp' || echo '$(srcdir)/'`MXF.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-MXF.Tpo $(DEPDIR)/libasdcp_la-MXF.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MXF.cpp' object='libasdcp_la-MXF.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MXF.lo `test -f 'MXF.cpp' || echo '$(srcdir)/'`MXF.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MXF.lo `test -f 'MXF.cpp' || echo '$(srcdir)/'`MXF.cpp libasdcp_la-Index.lo: Index.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-Index.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-Index.Tpo -c -o libasdcp_la-Index.lo `test -f 'Index.cpp' || echo '$(srcdir)/'`Index.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-Index.Tpo $(DEPDIR)/libasdcp_la-Index.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Index.cpp' object='libasdcp_la-Index.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-Index.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-Index.Tpo -c -o libasdcp_la-Index.lo `test -f 'Index.cpp' || echo '$(srcdir)/'`Index.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-Index.Tpo $(DEPDIR)/libasdcp_la-Index.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Index.cpp' object='libasdcp_la-Index.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-Index.lo `test -f 'Index.cpp' || echo '$(srcdir)/'`Index.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-Index.lo `test -f 'Index.cpp' || echo '$(srcdir)/'`Index.cpp libasdcp_la-Metadata.lo: Metadata.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-Metadata.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-Metadata.Tpo -c -o libasdcp_la-Metadata.lo `test -f 'Metadata.cpp' || echo '$(srcdir)/'`Metadata.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-Metadata.Tpo $(DEPDIR)/libasdcp_la-Metadata.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Metadata.cpp' object='libasdcp_la-Metadata.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-Metadata.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-Metadata.Tpo -c -o libasdcp_la-Metadata.lo `test -f 'Metadata.cpp' || echo '$(srcdir)/'`Metadata.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-Metadata.Tpo $(DEPDIR)/libasdcp_la-Metadata.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Metadata.cpp' object='libasdcp_la-Metadata.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-Metadata.lo `test -f 'Metadata.cpp' || echo '$(srcdir)/'`Metadata.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-Metadata.lo `test -f 'Metadata.cpp' || echo '$(srcdir)/'`Metadata.cpp libasdcp_la-AS_DCP.lo: AS_DCP.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP.Tpo -c -o libasdcp_la-AS_DCP.lo `test -f 'AS_DCP.cpp' || echo '$(srcdir)/'`AS_DCP.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP.Tpo $(DEPDIR)/libasdcp_la-AS_DCP.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='AS_DCP.cpp' object='libasdcp_la-AS_DCP.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP.Tpo -c -o libasdcp_la-AS_DCP.lo `test -f 'AS_DCP.cpp' || echo '$(srcdir)/'`AS_DCP.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP.Tpo $(DEPDIR)/libasdcp_la-AS_DCP.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP.cpp' object='libasdcp_la-AS_DCP.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP.lo `test -f 'AS_DCP.cpp' || echo '$(srcdir)/'`AS_DCP.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP.lo `test -f 'AS_DCP.cpp' || echo '$(srcdir)/'`AS_DCP.cpp libasdcp_la-AS_DCP_MXF.lo: AS_DCP_MXF.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_MXF.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_MXF.Tpo -c -o libasdcp_la-AS_DCP_MXF.lo `test -f 'AS_DCP_MXF.cpp' || echo '$(srcdir)/'`AS_DCP_MXF.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_MXF.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_MXF.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='AS_DCP_MXF.cpp' object='libasdcp_la-AS_DCP_MXF.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_MXF.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_MXF.Tpo -c -o libasdcp_la-AS_DCP_MXF.lo `test -f 'AS_DCP_MXF.cpp' || echo '$(srcdir)/'`AS_DCP_MXF.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_MXF.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_MXF.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP_MXF.cpp' object='libasdcp_la-AS_DCP_MXF.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_MXF.lo `test -f 'AS_DCP_MXF.cpp' || echo '$(srcdir)/'`AS_DCP_MXF.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_MXF.lo `test -f 'AS_DCP_MXF.cpp' || echo '$(srcdir)/'`AS_DCP_MXF.cpp libasdcp_la-AS_DCP_AES.lo: AS_DCP_AES.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_AES.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_AES.Tpo -c -o libasdcp_la-AS_DCP_AES.lo `test -f 'AS_DCP_AES.cpp' || echo '$(srcdir)/'`AS_DCP_AES.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_AES.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_AES.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='AS_DCP_AES.cpp' object='libasdcp_la-AS_DCP_AES.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_AES.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_AES.Tpo -c -o libasdcp_la-AS_DCP_AES.lo `test -f 'AS_DCP_AES.cpp' || echo '$(srcdir)/'`AS_DCP_AES.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_AES.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_AES.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP_AES.cpp' object='libasdcp_la-AS_DCP_AES.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_AES.lo `test -f 'AS_DCP_AES.cpp' || echo '$(srcdir)/'`AS_DCP_AES.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_AES.lo `test -f 'AS_DCP_AES.cpp' || echo '$(srcdir)/'`AS_DCP_AES.cpp libasdcp_la-h__Reader.lo: h__Reader.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-h__Reader.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-h__Reader.Tpo -c -o libasdcp_la-h__Reader.lo `test -f 'h__Reader.cpp' || echo '$(srcdir)/'`h__Reader.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-h__Reader.Tpo $(DEPDIR)/libasdcp_la-h__Reader.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='h__Reader.cpp' object='libasdcp_la-h__Reader.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-h__Reader.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-h__Reader.Tpo -c -o libasdcp_la-h__Reader.lo `test -f 'h__Reader.cpp' || echo '$(srcdir)/'`h__Reader.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-h__Reader.Tpo $(DEPDIR)/libasdcp_la-h__Reader.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='h__Reader.cpp' object='libasdcp_la-h__Reader.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-h__Reader.lo `test -f 'h__Reader.cpp' || echo '$(srcdir)/'`h__Reader.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-h__Reader.lo `test -f 'h__Reader.cpp' || echo '$(srcdir)/'`h__Reader.cpp libasdcp_la-h__Writer.lo: h__Writer.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-h__Writer.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-h__Writer.Tpo -c -o libasdcp_la-h__Writer.lo `test -f 'h__Writer.cpp' || echo '$(srcdir)/'`h__Writer.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-h__Writer.Tpo $(DEPDIR)/libasdcp_la-h__Writer.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='h__Writer.cpp' object='libasdcp_la-h__Writer.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-h__Writer.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-h__Writer.Tpo -c -o libasdcp_la-h__Writer.lo `test -f 'h__Writer.cpp' || echo '$(srcdir)/'`h__Writer.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-h__Writer.Tpo $(DEPDIR)/libasdcp_la-h__Writer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='h__Writer.cpp' object='libasdcp_la-h__Writer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-h__Writer.lo `test -f 'h__Writer.cpp' || echo '$(srcdir)/'`h__Writer.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-h__Writer.lo `test -f 'h__Writer.cpp' || echo '$(srcdir)/'`h__Writer.cpp libasdcp_la-AS_DCP_MPEG2.lo: AS_DCP_MPEG2.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_MPEG2.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_MPEG2.Tpo -c -o libasdcp_la-AS_DCP_MPEG2.lo `test -f 'AS_DCP_MPEG2.cpp' || echo '$(srcdir)/'`AS_DCP_MPEG2.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_MPEG2.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_MPEG2.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='AS_DCP_MPEG2.cpp' object='libasdcp_la-AS_DCP_MPEG2.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_MPEG2.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_MPEG2.Tpo -c -o libasdcp_la-AS_DCP_MPEG2.lo `test -f 'AS_DCP_MPEG2.cpp' || echo '$(srcdir)/'`AS_DCP_MPEG2.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_MPEG2.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_MPEG2.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP_MPEG2.cpp' object='libasdcp_la-AS_DCP_MPEG2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_MPEG2.lo `test -f 'AS_DCP_MPEG2.cpp' || echo '$(srcdir)/'`AS_DCP_MPEG2.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_MPEG2.lo `test -f 'AS_DCP_MPEG2.cpp' || echo '$(srcdir)/'`AS_DCP_MPEG2.cpp libasdcp_la-AS_DCP_JP2K.lo: AS_DCP_JP2K.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_JP2K.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_JP2K.Tpo -c -o libasdcp_la-AS_DCP_JP2K.lo `test -f 'AS_DCP_JP2K.cpp' || echo '$(srcdir)/'`AS_DCP_JP2K.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_JP2K.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_JP2K.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='AS_DCP_JP2K.cpp' object='libasdcp_la-AS_DCP_JP2K.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_JP2K.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_JP2K.Tpo -c -o libasdcp_la-AS_DCP_JP2K.lo `test -f 'AS_DCP_JP2K.cpp' || echo '$(srcdir)/'`AS_DCP_JP2K.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_JP2K.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_JP2K.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP_JP2K.cpp' object='libasdcp_la-AS_DCP_JP2K.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_JP2K.lo `test -f 'AS_DCP_JP2K.cpp' || echo '$(srcdir)/'`AS_DCP_JP2K.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_JP2K.lo `test -f 'AS_DCP_JP2K.cpp' || echo '$(srcdir)/'`AS_DCP_JP2K.cpp libasdcp_la-AS_DCP_PCM.lo: AS_DCP_PCM.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_PCM.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_PCM.Tpo -c -o libasdcp_la-AS_DCP_PCM.lo `test -f 'AS_DCP_PCM.cpp' || echo '$(srcdir)/'`AS_DCP_PCM.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_PCM.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_PCM.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='AS_DCP_PCM.cpp' object='libasdcp_la-AS_DCP_PCM.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_PCM.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_PCM.Tpo -c -o libasdcp_la-AS_DCP_PCM.lo `test -f 'AS_DCP_PCM.cpp' || echo '$(srcdir)/'`AS_DCP_PCM.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_PCM.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_PCM.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP_PCM.cpp' object='libasdcp_la-AS_DCP_PCM.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_PCM.lo `test -f 'AS_DCP_PCM.cpp' || echo '$(srcdir)/'`AS_DCP_PCM.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_PCM.lo `test -f 'AS_DCP_PCM.cpp' || echo '$(srcdir)/'`AS_DCP_PCM.cpp libasdcp_la-AS_DCP_TimedText.lo: AS_DCP_TimedText.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_TimedText.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_TimedText.Tpo -c -o libasdcp_la-AS_DCP_TimedText.lo `test -f 'AS_DCP_TimedText.cpp' || echo '$(srcdir)/'`AS_DCP_TimedText.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_TimedText.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_TimedText.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='AS_DCP_TimedText.cpp' object='libasdcp_la-AS_DCP_TimedText.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_TimedText.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_TimedText.Tpo -c -o libasdcp_la-AS_DCP_TimedText.lo `test -f 'AS_DCP_TimedText.cpp' || echo '$(srcdir)/'`AS_DCP_TimedText.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_TimedText.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_TimedText.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP_TimedText.cpp' object='libasdcp_la-AS_DCP_TimedText.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_TimedText.lo `test -f 'AS_DCP_TimedText.cpp' || echo '$(srcdir)/'`AS_DCP_TimedText.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_TimedText.lo `test -f 'AS_DCP_TimedText.cpp' || echo '$(srcdir)/'`AS_DCP_TimedText.cpp libasdcp_la-PCMParserList.lo: PCMParserList.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-PCMParserList.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-PCMParserList.Tpo -c -o libasdcp_la-PCMParserList.lo `test -f 'PCMParserList.cpp' || echo '$(srcdir)/'`PCMParserList.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-PCMParserList.Tpo $(DEPDIR)/libasdcp_la-PCMParserList.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='PCMParserList.cpp' object='libasdcp_la-PCMParserList.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-PCMParserList.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-PCMParserList.Tpo -c -o libasdcp_la-PCMParserList.lo `test -f 'PCMParserList.cpp' || echo '$(srcdir)/'`PCMParserList.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-PCMParserList.Tpo $(DEPDIR)/libasdcp_la-PCMParserList.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PCMParserList.cpp' object='libasdcp_la-PCMParserList.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-PCMParserList.lo `test -f 'PCMParserList.cpp' || echo '$(srcdir)/'`PCMParserList.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-PCMParserList.lo `test -f 'PCMParserList.cpp' || echo '$(srcdir)/'`PCMParserList.cpp libasdcp_la-MDD.lo: MDD.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MDD.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MDD.Tpo -c -o libasdcp_la-MDD.lo `test -f 'MDD.cpp' || echo '$(srcdir)/'`MDD.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-MDD.Tpo $(DEPDIR)/libasdcp_la-MDD.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='MDD.cpp' object='libasdcp_la-MDD.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-MDD.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-MDD.Tpo -c -o libasdcp_la-MDD.lo `test -f 'MDD.cpp' || echo '$(srcdir)/'`MDD.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-MDD.Tpo $(DEPDIR)/libasdcp_la-MDD.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MDD.cpp' object='libasdcp_la-MDD.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MDD.lo `test -f 'MDD.cpp' || echo '$(srcdir)/'`MDD.cpp + +libasdcp_la-AS_DCP_ATMOS.lo: AS_DCP_ATMOS.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_ATMOS.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_ATMOS.Tpo -c -o libasdcp_la-AS_DCP_ATMOS.lo `test -f 'AS_DCP_ATMOS.cpp' || echo '$(srcdir)/'`AS_DCP_ATMOS.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_ATMOS.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_ATMOS.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP_ATMOS.cpp' object='libasdcp_la-AS_DCP_ATMOS.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_ATMOS.lo `test -f 'AS_DCP_ATMOS.cpp' || echo '$(srcdir)/'`AS_DCP_ATMOS.cpp + +libasdcp_la-AS_DCP_DCData.lo: AS_DCP_DCData.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AS_DCP_DCData.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AS_DCP_DCData.Tpo -c -o libasdcp_la-AS_DCP_DCData.lo `test -f 'AS_DCP_DCData.cpp' || echo '$(srcdir)/'`AS_DCP_DCData.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AS_DCP_DCData.Tpo $(DEPDIR)/libasdcp_la-AS_DCP_DCData.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_DCP_DCData.cpp' object='libasdcp_la-AS_DCP_DCData.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AS_DCP_DCData.lo `test -f 'AS_DCP_DCData.cpp' || echo '$(srcdir)/'`AS_DCP_DCData.cpp + +libasdcp_la-DCData_ByteStream_Parser.lo: DCData_ByteStream_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-DCData_ByteStream_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-DCData_ByteStream_Parser.Tpo -c -o libasdcp_la-DCData_ByteStream_Parser.lo `test -f 'DCData_ByteStream_Parser.cpp' || echo '$(srcdir)/'`DCData_ByteStream_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-DCData_ByteStream_Parser.Tpo $(DEPDIR)/libasdcp_la-DCData_ByteStream_Parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DCData_ByteStream_Parser.cpp' object='libasdcp_la-DCData_ByteStream_Parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-MDD.lo `test -f 'MDD.cpp' || echo '$(srcdir)/'`MDD.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-DCData_ByteStream_Parser.lo `test -f 'DCData_ByteStream_Parser.cpp' || echo '$(srcdir)/'`DCData_ByteStream_Parser.cpp -libasdcp_la-TimedText_Transform.lo: TimedText_Transform.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-TimedText_Transform.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-TimedText_Transform.Tpo -c -o libasdcp_la-TimedText_Transform.lo `test -f 'TimedText_Transform.cpp' || echo '$(srcdir)/'`TimedText_Transform.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libasdcp_la-TimedText_Transform.Tpo $(DEPDIR)/libasdcp_la-TimedText_Transform.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TimedText_Transform.cpp' object='libasdcp_la-TimedText_Transform.lo' libtool=yes @AMDEPBACKSLASH@ +libasdcp_la-DCData_Sequence_Parser.lo: DCData_Sequence_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-DCData_Sequence_Parser.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-DCData_Sequence_Parser.Tpo -c -o libasdcp_la-DCData_Sequence_Parser.lo `test -f 'DCData_Sequence_Parser.cpp' || echo '$(srcdir)/'`DCData_Sequence_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-DCData_Sequence_Parser.Tpo $(DEPDIR)/libasdcp_la-DCData_Sequence_Parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DCData_Sequence_Parser.cpp' object='libasdcp_la-DCData_Sequence_Parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-TimedText_Transform.lo `test -f 'TimedText_Transform.cpp' || echo '$(srcdir)/'`TimedText_Transform.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-DCData_Sequence_Parser.lo `test -f 'DCData_Sequence_Parser.cpp' || echo '$(srcdir)/'`DCData_Sequence_Parser.cpp + +libasdcp_la-AtmosSyncChannel_Generator.lo: AtmosSyncChannel_Generator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AtmosSyncChannel_Generator.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AtmosSyncChannel_Generator.Tpo -c -o libasdcp_la-AtmosSyncChannel_Generator.lo `test -f 'AtmosSyncChannel_Generator.cpp' || echo '$(srcdir)/'`AtmosSyncChannel_Generator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AtmosSyncChannel_Generator.Tpo $(DEPDIR)/libasdcp_la-AtmosSyncChannel_Generator.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AtmosSyncChannel_Generator.cpp' object='libasdcp_la-AtmosSyncChannel_Generator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AtmosSyncChannel_Generator.lo `test -f 'AtmosSyncChannel_Generator.cpp' || echo '$(srcdir)/'`AtmosSyncChannel_Generator.cpp + +libasdcp_la-AtmosSyncChannel_Mixer.lo: AtmosSyncChannel_Mixer.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-AtmosSyncChannel_Mixer.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-AtmosSyncChannel_Mixer.Tpo -c -o libasdcp_la-AtmosSyncChannel_Mixer.lo `test -f 'AtmosSyncChannel_Mixer.cpp' || echo '$(srcdir)/'`AtmosSyncChannel_Mixer.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-AtmosSyncChannel_Mixer.Tpo $(DEPDIR)/libasdcp_la-AtmosSyncChannel_Mixer.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AtmosSyncChannel_Mixer.cpp' object='libasdcp_la-AtmosSyncChannel_Mixer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-AtmosSyncChannel_Mixer.lo `test -f 'AtmosSyncChannel_Mixer.cpp' || echo '$(srcdir)/'`AtmosSyncChannel_Mixer.cpp + +libasdcp_la-PCMDataProviders.lo: PCMDataProviders.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-PCMDataProviders.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-PCMDataProviders.Tpo -c -o libasdcp_la-PCMDataProviders.lo `test -f 'PCMDataProviders.cpp' || echo '$(srcdir)/'`PCMDataProviders.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-PCMDataProviders.Tpo $(DEPDIR)/libasdcp_la-PCMDataProviders.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PCMDataProviders.cpp' object='libasdcp_la-PCMDataProviders.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-PCMDataProviders.lo `test -f 'PCMDataProviders.cpp' || echo '$(srcdir)/'`PCMDataProviders.cpp + +libasdcp_la-ST2095_PinkNoise.lo: ST2095_PinkNoise.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libasdcp_la-ST2095_PinkNoise.lo -MD -MP -MF $(DEPDIR)/libasdcp_la-ST2095_PinkNoise.Tpo -c -o libasdcp_la-ST2095_PinkNoise.lo `test -f 'ST2095_PinkNoise.cpp' || echo '$(srcdir)/'`ST2095_PinkNoise.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libasdcp_la-ST2095_PinkNoise.Tpo $(DEPDIR)/libasdcp_la-ST2095_PinkNoise.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ST2095_PinkNoise.cpp' object='libasdcp_la-ST2095_PinkNoise.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libasdcp_la-ST2095_PinkNoise.lo `test -f 'ST2095_PinkNoise.cpp' || echo '$(srcdir)/'`ST2095_PinkNoise.cpp + +libphdr_la-PHDR_Sequence_Parser.lo: PHDR_Sequence_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libphdr_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libphdr_la-PHDR_Sequence_Parser.lo -MD -MP -MF $(DEPDIR)/libphdr_la-PHDR_Sequence_Parser.Tpo -c -o libphdr_la-PHDR_Sequence_Parser.lo `test -f 'PHDR_Sequence_Parser.cpp' || echo '$(srcdir)/'`PHDR_Sequence_Parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libphdr_la-PHDR_Sequence_Parser.Tpo $(DEPDIR)/libphdr_la-PHDR_Sequence_Parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PHDR_Sequence_Parser.cpp' object='libphdr_la-PHDR_Sequence_Parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libphdr_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libphdr_la-PHDR_Sequence_Parser.lo `test -f 'PHDR_Sequence_Parser.cpp' || echo '$(srcdir)/'`PHDR_Sequence_Parser.cpp + +libphdr_la-AS_02_PHDR.lo: AS_02_PHDR.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libphdr_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libphdr_la-AS_02_PHDR.lo -MD -MP -MF $(DEPDIR)/libphdr_la-AS_02_PHDR.Tpo -c -o libphdr_la-AS_02_PHDR.lo `test -f 'AS_02_PHDR.cpp' || echo '$(srcdir)/'`AS_02_PHDR.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libphdr_la-AS_02_PHDR.Tpo $(DEPDIR)/libphdr_la-AS_02_PHDR.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AS_02_PHDR.cpp' object='libphdr_la-AS_02_PHDR.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libphdr_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libphdr_la-AS_02_PHDR.lo `test -f 'AS_02_PHDR.cpp' || echo '$(srcdir)/'`AS_02_PHDR.cpp libpyasdcp_la-kumu_python.lo: kumu_python.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-kumu_python.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-kumu_python.Tpo -c -o libpyasdcp_la-kumu_python.lo `test -f 'kumu_python.cpp' || echo '$(srcdir)/'`kumu_python.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libpyasdcp_la-kumu_python.Tpo $(DEPDIR)/libpyasdcp_la-kumu_python.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='kumu_python.cpp' object='libpyasdcp_la-kumu_python.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-kumu_python.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-kumu_python.Tpo -c -o libpyasdcp_la-kumu_python.lo `test -f 'kumu_python.cpp' || echo '$(srcdir)/'`kumu_python.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpyasdcp_la-kumu_python.Tpo $(DEPDIR)/libpyasdcp_la-kumu_python.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='kumu_python.cpp' object='libpyasdcp_la-kumu_python.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-kumu_python.lo `test -f 'kumu_python.cpp' || echo '$(srcdir)/'`kumu_python.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-kumu_python.lo `test -f 'kumu_python.cpp' || echo '$(srcdir)/'`kumu_python.cpp libpyasdcp_la-asdcp_python.lo: asdcp_python.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python.Tpo -c -o libpyasdcp_la-asdcp_python.lo `test -f 'asdcp_python.cpp' || echo '$(srcdir)/'`asdcp_python.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='asdcp_python.cpp' object='libpyasdcp_la-asdcp_python.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python.Tpo -c -o libpyasdcp_la-asdcp_python.lo `test -f 'asdcp_python.cpp' || echo '$(srcdir)/'`asdcp_python.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='asdcp_python.cpp' object='libpyasdcp_la-asdcp_python.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python.lo `test -f 'asdcp_python.cpp' || echo '$(srcdir)/'`asdcp_python.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python.lo `test -f 'asdcp_python.cpp' || echo '$(srcdir)/'`asdcp_python.cpp libpyasdcp_la-asdcp_python_descriptor.lo: asdcp_python_descriptor.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_descriptor.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_descriptor.Tpo -c -o libpyasdcp_la-asdcp_python_descriptor.lo `test -f 'asdcp_python_descriptor.cpp' || echo '$(srcdir)/'`asdcp_python_descriptor.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_descriptor.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_descriptor.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='asdcp_python_descriptor.cpp' object='libpyasdcp_la-asdcp_python_descriptor.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_descriptor.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_descriptor.Tpo -c -o libpyasdcp_la-asdcp_python_descriptor.lo `test -f 'asdcp_python_descriptor.cpp' || echo '$(srcdir)/'`asdcp_python_descriptor.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_descriptor.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_descriptor.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='asdcp_python_descriptor.cpp' object='libpyasdcp_la-asdcp_python_descriptor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_descriptor.lo `test -f 'asdcp_python_descriptor.cpp' || echo '$(srcdir)/'`asdcp_python_descriptor.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_descriptor.lo `test -f 'asdcp_python_descriptor.cpp' || echo '$(srcdir)/'`asdcp_python_descriptor.cpp libpyasdcp_la-asdcp_python_misc.lo: asdcp_python_misc.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_misc.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_misc.Tpo -c -o libpyasdcp_la-asdcp_python_misc.lo `test -f 'asdcp_python_misc.cpp' || echo '$(srcdir)/'`asdcp_python_misc.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_misc.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_misc.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='asdcp_python_misc.cpp' object='libpyasdcp_la-asdcp_python_misc.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_misc.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_misc.Tpo -c -o libpyasdcp_la-asdcp_python_misc.lo `test -f 'asdcp_python_misc.cpp' || echo '$(srcdir)/'`asdcp_python_misc.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_misc.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_misc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='asdcp_python_misc.cpp' object='libpyasdcp_la-asdcp_python_misc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_misc.lo `test -f 'asdcp_python_misc.cpp' || echo '$(srcdir)/'`asdcp_python_misc.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_misc.lo `test -f 'asdcp_python_misc.cpp' || echo '$(srcdir)/'`asdcp_python_misc.cpp libpyasdcp_la-asdcp_python_mxf.lo: asdcp_python_mxf.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_mxf.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf.Tpo -c -o libpyasdcp_la-asdcp_python_mxf.lo `test -f 'asdcp_python_mxf.cpp' || echo '$(srcdir)/'`asdcp_python_mxf.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='asdcp_python_mxf.cpp' object='libpyasdcp_la-asdcp_python_mxf.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_mxf.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf.Tpo -c -o libpyasdcp_la-asdcp_python_mxf.lo `test -f 'asdcp_python_mxf.cpp' || echo '$(srcdir)/'`asdcp_python_mxf.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='asdcp_python_mxf.cpp' object='libpyasdcp_la-asdcp_python_mxf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_mxf.lo `test -f 'asdcp_python_mxf.cpp' || echo '$(srcdir)/'`asdcp_python_mxf.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_mxf.lo `test -f 'asdcp_python_mxf.cpp' || echo '$(srcdir)/'`asdcp_python_mxf.cpp libpyasdcp_la-asdcp_python_mxf_text.lo: asdcp_python_mxf_text.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_mxf_text.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_text.Tpo -c -o libpyasdcp_la-asdcp_python_mxf_text.lo `test -f 'asdcp_python_mxf_text.cpp' || echo '$(srcdir)/'`asdcp_python_mxf_text.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_text.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_text.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='asdcp_python_mxf_text.cpp' object='libpyasdcp_la-asdcp_python_mxf_text.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_mxf_text.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_text.Tpo -c -o libpyasdcp_la-asdcp_python_mxf_text.lo `test -f 'asdcp_python_mxf_text.cpp' || echo '$(srcdir)/'`asdcp_python_mxf_text.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_text.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_text.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='asdcp_python_mxf_text.cpp' object='libpyasdcp_la-asdcp_python_mxf_text.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_mxf_text.lo `test -f 'asdcp_python_mxf_text.cpp' || echo '$(srcdir)/'`asdcp_python_mxf_text.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_mxf_text.lo `test -f 'asdcp_python_mxf_text.cpp' || echo '$(srcdir)/'`asdcp_python_mxf_text.cpp libpyasdcp_la-asdcp_python_mxf_metadata.lo: asdcp_python_mxf_metadata.cpp -@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_mxf_metadata.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_metadata.Tpo -c -o libpyasdcp_la-asdcp_python_mxf_metadata.lo `test -f 'asdcp_python_mxf_metadata.cpp' || echo '$(srcdir)/'`asdcp_python_mxf_metadata.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_metadata.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_metadata.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='asdcp_python_mxf_metadata.cpp' object='libpyasdcp_la-asdcp_python_mxf_metadata.lo' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libpyasdcp_la-asdcp_python_mxf_metadata.lo -MD -MP -MF $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_metadata.Tpo -c -o libpyasdcp_la-asdcp_python_mxf_metadata.lo `test -f 'asdcp_python_mxf_metadata.cpp' || echo '$(srcdir)/'`asdcp_python_mxf_metadata.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_metadata.Tpo $(DEPDIR)/libpyasdcp_la-asdcp_python_mxf_metadata.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='asdcp_python_mxf_metadata.cpp' object='libpyasdcp_la-asdcp_python_mxf_metadata.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_mxf_metadata.lo `test -f 'asdcp_python_mxf_metadata.cpp' || echo '$(srcdir)/'`asdcp_python_mxf_metadata.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyasdcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libpyasdcp_la-asdcp_python_mxf_metadata.lo `test -f 'asdcp_python_mxf_metadata.cpp' || echo '$(srcdir)/'`asdcp_python_mxf_metadata.cpp mostlyclean-libtool: -rm -f *.lo @@ -1118,8 +1773,11 @@ clean-libtool: -rm -rf .libs _libs install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) - test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -1134,28 +1792,13 @@ uninstall-includeHEADERS: @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) -install-nodist_includeHEADERS: $(nodist_include_HEADERS) - @$(NORMAL_INSTALL) - test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" - @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ - done - -uninstall-nodist_includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) install-nodist_pyexec_includeHEADERS: $(nodist_pyexec_include_HEADERS) @$(NORMAL_INSTALL) - test -z "$(pyexec_includedir)" || $(MKDIR_P) "$(DESTDIR)$(pyexec_includedir)" @list='$(nodist_pyexec_include_HEADERS)'; test -n "$(pyexec_includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pyexec_includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pyexec_includedir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -1171,26 +1814,15 @@ uninstall-nodist_pyexec_includeHEADERS: files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pyexec_includedir)'; $(am__uninstall_files_from_dir) -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -1202,15 +1834,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -1219,102 +1847,250 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ - done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ - else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + else \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ else \ - skipped="($$skip tests were not run)"; \ + color_start= color_end=; \ fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$${col}$$dashes$${std}"; \ - echo "$${col}$$banner$${std}"; \ - test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ - test -z "$$report" || echo "$${col}$$report$${std}"; \ - echo "$${col}$$dashes$${std}"; \ - test "$$failed" -eq 0; \ - else :; fi + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +rng-tst.sh.log: rng-tst.sh + @p='rng-tst.sh'; \ + b='rng-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +gen-tst.sh.log: gen-tst.sh + @p='gen-tst.sh'; \ + b='gen-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +jp2k-tst.sh.log: jp2k-tst.sh + @p='jp2k-tst.sh'; \ + b='jp2k-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +jp2k-crypt-tst.sh.log: jp2k-crypt-tst.sh + @p='jp2k-crypt-tst.sh'; \ + b='jp2k-crypt-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +jp2k-stereo-tst.sh.log: jp2k-stereo-tst.sh + @p='jp2k-stereo-tst.sh'; \ + b='jp2k-stereo-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +jp2k-stereo-crypt-tst.sh.log: jp2k-stereo-crypt-tst.sh + @p='jp2k-stereo-crypt-tst.sh'; \ + b='jp2k-stereo-crypt-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +wav-tst.sh.log: wav-tst.sh + @p='wav-tst.sh'; \ + b='wav-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +wav-crypt-tst.sh.log: wav-crypt-tst.sh + @p='wav-crypt-tst.sh'; \ + b='wav-crypt-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +mpeg-tst.sh.log: mpeg-tst.sh + @p='mpeg-tst.sh'; \ + b='mpeg-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +mpeg-crypt-tst.sh.log: mpeg-crypt-tst.sh + @p='mpeg-crypt-tst.sh'; \ + b='mpeg-crypt-tst.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -1355,7 +2131,7 @@ all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) install-binPROGRAMS: install-libLTLIBRARIES installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pyexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pyexec_includedir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pyexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pyexec_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1379,6 +2155,9 @@ install-strip: "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: @@ -1415,7 +2194,7 @@ info: info-am info-am: -install-data-am: install-includeHEADERS install-nodist_includeHEADERS +install-data-am: install-includeHEADERS install-dvi: install-dvi-am @@ -1463,32 +2242,31 @@ ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES uninstall-nodist_includeHEADERS \ + uninstall-libLTLIBRARIES \ uninstall-nodist_pyexec_includeHEADERS \ uninstall-pyexecLTLIBRARIES .MAKE: all check check-am install install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libLTLIBRARIES clean-libtool clean-pyexecLTLIBRARIES \ - ctags distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-binPROGRAMS \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man \ - install-nodist_includeHEADERS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man \ install-nodist_pyexec_includeHEADERS install-pdf \ install-pdf-am install-ps install-ps-am \ install-pyexecLTLIBRARIES install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-binPROGRAMS \ - uninstall-includeHEADERS uninstall-libLTLIBRARIES \ - uninstall-nodist_includeHEADERS \ + recheck tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES \ uninstall-nodist_pyexec_includeHEADERS \ uninstall-pyexecLTLIBRARIES diff --git a/asdcplib/src/Metadata.cpp b/asdcplib/src/Metadata.cpp index a9a15e5b..2b25503e 100755 --- a/asdcplib/src/Metadata.cpp +++ b/asdcplib/src/Metadata.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file Metadata.cpp - \version $Id: Metadata.cpp,v 1.31 2012/02/21 02:09:31 jhurst Exp $ + \version $Id: Metadata.cpp,v 1.40 2015/10/10 20:26:29 jhurst Exp $ \brief AS-DCP library, MXF Metadata Sets implementation */ @@ -68,11 +68,15 @@ static InterchangeObject* GenericDataEssenceDescriptor_Factory(const Dictionary* static InterchangeObject* TimedTextDescriptor_Factory(const Dictionary*& Dict) { return new TimedTextDescriptor(Dict); } static InterchangeObject* TimedTextResourceSubDescriptor_Factory(const Dictionary*& Dict) { return new TimedTextResourceSubDescriptor(Dict); } static InterchangeObject* StereoscopicPictureSubDescriptor_Factory(const Dictionary*& Dict) { return new StereoscopicPictureSubDescriptor(Dict); } +static InterchangeObject* ContainerConstraintSubDescriptor_Factory(const Dictionary*& Dict) { return new ContainerConstraintSubDescriptor(Dict); } static InterchangeObject* NetworkLocator_Factory(const Dictionary*& Dict) { return new NetworkLocator(Dict); } static InterchangeObject* MCALabelSubDescriptor_Factory(const Dictionary*& Dict) { return new MCALabelSubDescriptor(Dict); } static InterchangeObject* AudioChannelLabelSubDescriptor_Factory(const Dictionary*& Dict) { return new AudioChannelLabelSubDescriptor(Dict); } static InterchangeObject* SoundfieldGroupLabelSubDescriptor_Factory(const Dictionary*& Dict) { return new SoundfieldGroupLabelSubDescriptor(Dict); } static InterchangeObject* GroupOfSoundfieldGroupsLabelSubDescriptor_Factory(const Dictionary*& Dict) { return new GroupOfSoundfieldGroupsLabelSubDescriptor(Dict); } +static InterchangeObject* DCDataDescriptor_Factory(const Dictionary*& Dict) { return new DCDataDescriptor(Dict); } +static InterchangeObject* DolbyAtmosSubDescriptor_Factory(const Dictionary*& Dict) { return new DolbyAtmosSubDescriptor(Dict); } +static InterchangeObject* PHDRMetadataTrackSubDescriptor_Factory(const Dictionary*& Dict) { return new PHDRMetadataTrackSubDescriptor(Dict); } void @@ -107,11 +111,15 @@ ASDCP::MXF::Metadata_InitTypes(const Dictionary*& Dict) SetObjectFactory(Dict->ul(MDD_TimedTextDescriptor), TimedTextDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_TimedTextResourceSubDescriptor), TimedTextResourceSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_StereoscopicPictureSubDescriptor), StereoscopicPictureSubDescriptor_Factory); + SetObjectFactory(Dict->ul(MDD_ContainerConstraintSubDescriptor), ContainerConstraintSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_NetworkLocator), NetworkLocator_Factory); SetObjectFactory(Dict->ul(MDD_MCALabelSubDescriptor), MCALabelSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_AudioChannelLabelSubDescriptor), AudioChannelLabelSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_SoundfieldGroupLabelSubDescriptor), SoundfieldGroupLabelSubDescriptor_Factory); SetObjectFactory(Dict->ul(MDD_GroupOfSoundfieldGroupsLabelSubDescriptor), GroupOfSoundfieldGroupsLabelSubDescriptor_Factory); + SetObjectFactory(Dict->ul(MDD_DCDataDescriptor), DCDataDescriptor_Factory); + SetObjectFactory(Dict->ul(MDD_DolbyAtmosSubDescriptor), DolbyAtmosSubDescriptor_Factory); + SetObjectFactory(Dict->ul(MDD_PHDRMetadataTrackSubDescriptor), PHDRMetadataTrackSubDescriptor_Factory); } //------------------------------------------------------------------------------------------ @@ -152,7 +160,10 @@ Identification::InitFromTLVSet(TLVReader& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Identification, ProductUID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Identification, ModificationDate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Identification, ToolkitVersion)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(Identification, Platform)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(Identification, Platform)); + Platform.set_has_value( result == RESULT_OK ); + } return result; } @@ -170,7 +181,7 @@ Identification::WriteToTLVSet(TLVWriter& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Identification, ProductUID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Identification, ModificationDate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Identification, ToolkitVersion)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(Identification, Platform)); + if ( ASDCP_SUCCESS(result) && ! Platform.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(Identification, Platform)); return result; } @@ -209,7 +220,9 @@ Identification::Dump(FILE* stream) fprintf(stream, " %22s = %s\n", "ProductUID", ProductUID.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %s\n", "ModificationDate", ModificationDate.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %s\n", "ToolkitVersion", ToolkitVersion.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "Platform", Platform.EncodeString(identbuf, IdentBufferLen)); + if ( ! Platform.empty() ) { + fprintf(stream, " %22s = %s\n", "Platform", Platform.get().EncodeString(identbuf, IdentBufferLen)); + } } // @@ -312,7 +325,7 @@ ContentStorage::WriteToBuffer(ASDCP::FrameBuffer& Buffer) // -EssenceContainerData::EssenceContainerData(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), IndexSID(0), BodySID(0) +EssenceContainerData::EssenceContainerData(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), IndexSID(0) { assert(m_Dict); m_UL = m_Dict->ul(MDD_EssenceContainerData); @@ -333,7 +346,10 @@ EssenceContainerData::InitFromTLVSet(TLVReader& TLVSet) assert(m_Dict); Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(EssenceContainerData, LinkedPackageUID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(EssenceContainerData, IndexSID)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(EssenceContainerData, IndexSID)); + IndexSID.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(EssenceContainerData, BodySID)); return result; } @@ -345,7 +361,7 @@ EssenceContainerData::WriteToTLVSet(TLVWriter& TLVSet) assert(m_Dict); Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(EssenceContainerData, LinkedPackageUID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(EssenceContainerData, IndexSID)); + if ( ASDCP_SUCCESS(result) && ! IndexSID.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(EssenceContainerData, IndexSID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(EssenceContainerData, BodySID)); return result; } @@ -372,7 +388,9 @@ EssenceContainerData::Dump(FILE* stream) InterchangeObject::Dump(stream); fprintf(stream, " %22s = %s\n", "LinkedPackageUID", LinkedPackageUID.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %d\n", "IndexSID", IndexSID); + if ( ! IndexSID.empty() ) { + fprintf(stream, " %22s = %d\n", "IndexSID", IndexSID.get()); + } fprintf(stream, " %22s = %d\n", "BodySID", BodySID); } @@ -409,7 +427,10 @@ GenericPackage::InitFromTLVSet(TLVReader& TLVSet) assert(m_Dict); Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPackage, PackageUID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPackage, Name)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(GenericPackage, Name)); + Name.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPackage, PackageCreationDate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPackage, PackageModifiedDate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPackage, Tracks)); @@ -423,7 +444,7 @@ GenericPackage::WriteToTLVSet(TLVWriter& TLVSet) assert(m_Dict); Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPackage, PackageUID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPackage, Name)); + if ( ASDCP_SUCCESS(result) && ! Name.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(GenericPackage, Name)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPackage, PackageCreationDate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPackage, PackageModifiedDate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPackage, Tracks)); @@ -454,7 +475,9 @@ GenericPackage::Dump(FILE* stream) InterchangeObject::Dump(stream); fprintf(stream, " %22s = %s\n", "PackageUID", PackageUID.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "Name", Name.EncodeString(identbuf, IdentBufferLen)); + if ( ! Name.empty() ) { + fprintf(stream, " %22s = %s\n", "Name", Name.get().EncodeString(identbuf, IdentBufferLen)); + } fprintf(stream, " %22s = %s\n", "PackageCreationDate", PackageCreationDate.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %s\n", "PackageModifiedDate", PackageModifiedDate.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s:\n", "Tracks"); @@ -487,6 +510,10 @@ MaterialPackage::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = GenericPackage::InitFromTLVSet(TLVSet); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(MaterialPackage, PackageMarker)); + PackageMarker.set_has_value( result == RESULT_OK ); + } return result; } @@ -496,6 +523,7 @@ MaterialPackage::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = GenericPackage::WriteToTLVSet(TLVSet); + if ( ASDCP_SUCCESS(result) && ! PackageMarker.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(MaterialPackage, PackageMarker)); return result; } @@ -504,6 +532,7 @@ void MaterialPackage::Copy(const MaterialPackage& rhs) { GenericPackage::Copy(rhs); + PackageMarker = rhs.PackageMarker; } // @@ -517,6 +546,9 @@ MaterialPackage::Dump(FILE* stream) stream = stderr; GenericPackage::Dump(stream); + if ( ! PackageMarker.empty() ) { + fprintf(stream, " %22s = %s\n", "PackageMarker", PackageMarker.get().EncodeString(identbuf, IdentBufferLen)); + } } // @@ -628,8 +660,14 @@ GenericTrack::InitFromTLVSet(TLVReader& TLVSet) Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericTrack, TrackID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericTrack, TrackNumber)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericTrack, TrackName)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericTrack, Sequence)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(GenericTrack, TrackName)); + TrackName.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(GenericTrack, Sequence)); + Sequence.set_has_value( result == RESULT_OK ); + } return result; } @@ -641,8 +679,8 @@ GenericTrack::WriteToTLVSet(TLVWriter& TLVSet) Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericTrack, TrackID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericTrack, TrackNumber)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericTrack, TrackName)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericTrack, Sequence)); + if ( ASDCP_SUCCESS(result) && ! TrackName.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(GenericTrack, TrackName)); + if ( ASDCP_SUCCESS(result) && ! Sequence.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(GenericTrack, Sequence)); return result; } @@ -670,8 +708,12 @@ GenericTrack::Dump(FILE* stream) InterchangeObject::Dump(stream); fprintf(stream, " %22s = %d\n", "TrackID", TrackID); fprintf(stream, " %22s = %d\n", "TrackNumber", TrackNumber); - fprintf(stream, " %22s = %s\n", "TrackName", TrackName.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "Sequence", Sequence.EncodeString(identbuf, IdentBufferLen)); + if ( ! TrackName.empty() ) { + fprintf(stream, " %22s = %s\n", "TrackName", TrackName.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! Sequence.empty() ) { + fprintf(stream, " %22s = %s\n", "Sequence", Sequence.get().EncodeString(identbuf, IdentBufferLen)); + } } @@ -844,7 +886,10 @@ StructuralComponent::InitFromTLVSet(TLVReader& TLVSet) assert(m_Dict); Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(StructuralComponent, DataDefinition)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(StructuralComponent, Duration)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi64(OBJ_READ_ARGS_OPT(StructuralComponent, Duration)); + Duration.set_has_value( result == RESULT_OK ); + } return result; } @@ -855,7 +900,7 @@ StructuralComponent::WriteToTLVSet(TLVWriter& TLVSet) assert(m_Dict); Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(StructuralComponent, DataDefinition)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(StructuralComponent, Duration)); + if ( ASDCP_SUCCESS(result) && ! Duration.empty() ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS_OPT(StructuralComponent, Duration)); return result; } @@ -880,7 +925,9 @@ StructuralComponent::Dump(FILE* stream) InterchangeObject::Dump(stream); fprintf(stream, " %22s = %s\n", "DataDefinition", DataDefinition.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "Duration", i64sz(Duration, identbuf)); + if ( ! Duration.empty() ) { + fprintf(stream, " %22s = %s\n", "Duration", i64sz(Duration.get(), identbuf)); + } } @@ -1192,7 +1239,7 @@ GenericDescriptor::Dump(FILE* stream) // -FileDescriptor::FileDescriptor(const Dictionary*& d) : GenericDescriptor(d), m_Dict(d), LinkedTrackID(0), ContainerDuration(0) +FileDescriptor::FileDescriptor(const Dictionary*& d) : GenericDescriptor(d), m_Dict(d), LinkedTrackID(0) { assert(m_Dict); m_UL = m_Dict->ul(MDD_FileDescriptor); @@ -1212,11 +1259,20 @@ FileDescriptor::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = GenericDescriptor::InitFromTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(FileDescriptor, LinkedTrackID)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(FileDescriptor, LinkedTrackID)); + LinkedTrackID.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(FileDescriptor, SampleRate)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(FileDescriptor, ContainerDuration)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi64(OBJ_READ_ARGS_OPT(FileDescriptor, ContainerDuration)); + ContainerDuration.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(FileDescriptor, EssenceContainer)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(FileDescriptor, Codec)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(FileDescriptor, Codec)); + Codec.set_has_value( result == RESULT_OK ); + } return result; } @@ -1226,11 +1282,11 @@ FileDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = GenericDescriptor::WriteToTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(FileDescriptor, LinkedTrackID)); + if ( ASDCP_SUCCESS(result) && ! LinkedTrackID.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(FileDescriptor, LinkedTrackID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(FileDescriptor, SampleRate)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(FileDescriptor, ContainerDuration)); + if ( ASDCP_SUCCESS(result) && ! ContainerDuration.empty() ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS_OPT(FileDescriptor, ContainerDuration)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(FileDescriptor, EssenceContainer)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(FileDescriptor, Codec)); + if ( ASDCP_SUCCESS(result) && ! Codec.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(FileDescriptor, Codec)); return result; } @@ -1257,11 +1313,17 @@ FileDescriptor::Dump(FILE* stream) stream = stderr; GenericDescriptor::Dump(stream); - fprintf(stream, " %22s = %d\n", "LinkedTrackID", LinkedTrackID); + if ( ! LinkedTrackID.empty() ) { + fprintf(stream, " %22s = %d\n", "LinkedTrackID", LinkedTrackID.get()); + } fprintf(stream, " %22s = %s\n", "SampleRate", SampleRate.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "ContainerDuration", i64sz(ContainerDuration, identbuf)); + if ( ! ContainerDuration.empty() ) { + fprintf(stream, " %22s = %s\n", "ContainerDuration", i64sz(ContainerDuration.get(), identbuf)); + } fprintf(stream, " %22s = %s\n", "EssenceContainer", EssenceContainer.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "Codec", Codec.EncodeString(identbuf, IdentBufferLen)); + if ( ! Codec.empty() ) { + fprintf(stream, " %22s = %s\n", "Codec", Codec.get().EncodeString(identbuf, IdentBufferLen)); + } } // @@ -1305,10 +1367,21 @@ GenericSoundEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet) Result_t result = FileDescriptor::InitFromTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericSoundEssenceDescriptor, AudioSamplingRate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(GenericSoundEssenceDescriptor, Locked)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(GenericSoundEssenceDescriptor, AudioRefLevel)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(GenericSoundEssenceDescriptor, AudioRefLevel)); + AudioRefLevel.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(GenericSoundEssenceDescriptor, ElectroSpatialFormulation)); + ElectroSpatialFormulation.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericSoundEssenceDescriptor, ChannelCount)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericSoundEssenceDescriptor, QuantizationBits)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(GenericSoundEssenceDescriptor, DialNorm)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(GenericSoundEssenceDescriptor, DialNorm)); + DialNorm.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericSoundEssenceDescriptor, SoundEssenceCoding)); return result; } @@ -1320,10 +1393,12 @@ GenericSoundEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet) Result_t result = FileDescriptor::WriteToTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericSoundEssenceDescriptor, AudioSamplingRate)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(GenericSoundEssenceDescriptor, Locked)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(GenericSoundEssenceDescriptor, AudioRefLevel)); + if ( ASDCP_SUCCESS(result) && ! AudioRefLevel.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(GenericSoundEssenceDescriptor, AudioRefLevel)); + if ( ASDCP_SUCCESS(result) && ! ElectroSpatialFormulation.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(GenericSoundEssenceDescriptor, ElectroSpatialFormulation)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericSoundEssenceDescriptor, ChannelCount)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericSoundEssenceDescriptor, QuantizationBits)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(GenericSoundEssenceDescriptor, DialNorm)); + if ( ASDCP_SUCCESS(result) && ! DialNorm.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(GenericSoundEssenceDescriptor, DialNorm)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericSoundEssenceDescriptor, SoundEssenceCoding)); return result; } @@ -1335,9 +1410,11 @@ GenericSoundEssenceDescriptor::Copy(const GenericSoundEssenceDescriptor& rhs) AudioSamplingRate = rhs.AudioSamplingRate; Locked = rhs.Locked; AudioRefLevel = rhs.AudioRefLevel; + ElectroSpatialFormulation = rhs.ElectroSpatialFormulation; ChannelCount = rhs.ChannelCount; QuantizationBits = rhs.QuantizationBits; DialNorm = rhs.DialNorm; + SoundEssenceCoding = rhs.SoundEssenceCoding; } // @@ -1353,10 +1430,18 @@ GenericSoundEssenceDescriptor::Dump(FILE* stream) FileDescriptor::Dump(stream); fprintf(stream, " %22s = %s\n", "AudioSamplingRate", AudioSamplingRate.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %d\n", "Locked", Locked); - fprintf(stream, " %22s = %d\n", "AudioRefLevel", AudioRefLevel); + if ( ! AudioRefLevel.empty() ) { + fprintf(stream, " %22s = %d\n", "AudioRefLevel", AudioRefLevel.get()); + } + if ( ! ElectroSpatialFormulation.empty() ) { + fprintf(stream, " %22s = %d\n", "ElectroSpatialFormulation", ElectroSpatialFormulation.get()); + } fprintf(stream, " %22s = %d\n", "ChannelCount", ChannelCount); fprintf(stream, " %22s = %d\n", "QuantizationBits", QuantizationBits); - fprintf(stream, " %22s = %d\n", "DialNorm", DialNorm); + if ( ! DialNorm.empty() ) { + fprintf(stream, " %22s = %d\n", "DialNorm", DialNorm.get()); + } + fprintf(stream, " %22s = %s\n", "SoundEssenceCoding", SoundEssenceCoding.EncodeString(identbuf, IdentBufferLen)); } // @@ -1378,7 +1463,7 @@ GenericSoundEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) // -WaveAudioDescriptor::WaveAudioDescriptor(const Dictionary*& d) : GenericSoundEssenceDescriptor(d), m_Dict(d), BlockAlign(0), SequenceOffset(0), AvgBps(0) +WaveAudioDescriptor::WaveAudioDescriptor(const Dictionary*& d) : GenericSoundEssenceDescriptor(d), m_Dict(d), BlockAlign(0), SequenceOffset(0) { assert(m_Dict); m_UL = m_Dict->ul(MDD_WaveAudioDescriptor); @@ -1399,9 +1484,23 @@ WaveAudioDescriptor::InitFromTLVSet(TLVReader& TLVSet) assert(m_Dict); Result_t result = GenericSoundEssenceDescriptor::InitFromTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(WaveAudioDescriptor, BlockAlign)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(WaveAudioDescriptor, SequenceOffset)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(WaveAudioDescriptor, SequenceOffset)); + SequenceOffset.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(WaveAudioDescriptor, AvgBps)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(WaveAudioDescriptor, ChannelAssignment)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(WaveAudioDescriptor, ChannelAssignment)); + ChannelAssignment.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(WaveAudioDescriptor, ReferenceImageEditRate)); + ReferenceImageEditRate.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(WaveAudioDescriptor, ReferenceAudioAlignmentLevel)); + ReferenceAudioAlignmentLevel.set_has_value( result == RESULT_OK ); + } return result; } @@ -1412,9 +1511,11 @@ WaveAudioDescriptor::WriteToTLVSet(TLVWriter& TLVSet) assert(m_Dict); Result_t result = GenericSoundEssenceDescriptor::WriteToTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(WaveAudioDescriptor, BlockAlign)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(WaveAudioDescriptor, SequenceOffset)); + if ( ASDCP_SUCCESS(result) && ! SequenceOffset.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(WaveAudioDescriptor, SequenceOffset)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(WaveAudioDescriptor, AvgBps)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(WaveAudioDescriptor, ChannelAssignment)); + if ( ASDCP_SUCCESS(result) && ! ChannelAssignment.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(WaveAudioDescriptor, ChannelAssignment)); + if ( ASDCP_SUCCESS(result) && ! ReferenceImageEditRate.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(WaveAudioDescriptor, ReferenceImageEditRate)); + if ( ASDCP_SUCCESS(result) && ! ReferenceAudioAlignmentLevel.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(WaveAudioDescriptor, ReferenceAudioAlignmentLevel)); return result; } @@ -1427,6 +1528,8 @@ WaveAudioDescriptor::Copy(const WaveAudioDescriptor& rhs) SequenceOffset = rhs.SequenceOffset; AvgBps = rhs.AvgBps; ChannelAssignment = rhs.ChannelAssignment; + ReferenceImageEditRate = rhs.ReferenceImageEditRate; + ReferenceAudioAlignmentLevel = rhs.ReferenceAudioAlignmentLevel; } // @@ -1441,9 +1544,19 @@ WaveAudioDescriptor::Dump(FILE* stream) GenericSoundEssenceDescriptor::Dump(stream); fprintf(stream, " %22s = %d\n", "BlockAlign", BlockAlign); - fprintf(stream, " %22s = %d\n", "SequenceOffset", SequenceOffset); + if ( ! SequenceOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "SequenceOffset", SequenceOffset.get()); + } fprintf(stream, " %22s = %d\n", "AvgBps", AvgBps); - fprintf(stream, " %22s = %s\n", "ChannelAssignment", ChannelAssignment.EncodeString(identbuf, IdentBufferLen)); + if ( ! ChannelAssignment.empty() ) { + fprintf(stream, " %22s = %s\n", "ChannelAssignment", ChannelAssignment.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! ReferenceImageEditRate.empty() ) { + fprintf(stream, " %22s = %s\n", "ReferenceImageEditRate", ReferenceImageEditRate.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! ReferenceAudioAlignmentLevel.empty() ) { + fprintf(stream, " %22s = %d\n", "ReferenceAudioAlignmentLevel", ReferenceAudioAlignmentLevel.get()); + } } // @@ -1465,7 +1578,7 @@ WaveAudioDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) // -GenericPictureEssenceDescriptor::GenericPictureEssenceDescriptor(const Dictionary*& d) : FileDescriptor(d), m_Dict(d), FrameLayout(0), StoredWidth(0), StoredHeight(0) +GenericPictureEssenceDescriptor::GenericPictureEssenceDescriptor(const Dictionary*& d) : FileDescriptor(d), m_Dict(d), SignalStandard(0), SampledWidth(0), SampledXOffset(0), DisplayHeight(0), DisplayXOffset(0), DisplayF2Offset(0), AlphaTransparency(0), ImageAlignmentOffset(0), ImageEndOffset(0), ActiveHeight(0), ActiveYOffset(0) { assert(m_Dict); m_UL = m_Dict->ul(MDD_GenericPictureEssenceDescriptor); @@ -1485,11 +1598,110 @@ GenericPictureEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = FileDescriptor::InitFromTLVSet(TLVSet); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, SignalStandard)); + SignalStandard.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, FrameLayout)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, StoredWidth)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, StoredHeight)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, StoredF2Offset)); + StoredF2Offset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, SampledWidth)); + SampledWidth.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, SampledHeight)); + SampledHeight.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, SampledXOffset)); + SampledXOffset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, SampledYOffset)); + SampledYOffset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayHeight)); + DisplayHeight.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayWidth)); + DisplayWidth.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayXOffset)); + DisplayXOffset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayYOffset)); + DisplayYOffset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayF2Offset)); + DisplayF2Offset.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, AspectRatio)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveFormatDescriptor)); + ActiveFormatDescriptor.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, AlphaTransparency)); + AlphaTransparency.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, TransferCharacteristic)); + TransferCharacteristic.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ImageAlignmentOffset)); + ImageAlignmentOffset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ImageStartOffset)); + ImageStartOffset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ImageEndOffset)); + ImageEndOffset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, FieldDominance)); + FieldDominance.set_has_value( result == RESULT_OK ); + } if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(GenericPictureEssenceDescriptor, PictureEssenceCoding)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, CodingEquations)); + CodingEquations.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ColorPrimaries)); + ColorPrimaries.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, AlternativeCenterCuts)); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveWidth)); + ActiveWidth.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveHeight)); + ActiveHeight.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveXOffset)); + ActiveXOffset.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveYOffset)); + ActiveYOffset.set_has_value( result == RESULT_OK ); + } return result; } @@ -1499,11 +1711,36 @@ GenericPictureEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = FileDescriptor::WriteToTLVSet(TLVSet); + if ( ASDCP_SUCCESS(result) && ! SignalStandard.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, SignalStandard)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, FrameLayout)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, StoredWidth)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, StoredHeight)); + if ( ASDCP_SUCCESS(result) && ! StoredF2Offset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, StoredF2Offset)); + if ( ASDCP_SUCCESS(result) && ! SampledWidth.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, SampledWidth)); + if ( ASDCP_SUCCESS(result) && ! SampledHeight.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, SampledHeight)); + if ( ASDCP_SUCCESS(result) && ! SampledXOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, SampledXOffset)); + if ( ASDCP_SUCCESS(result) && ! SampledYOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, SampledYOffset)); + if ( ASDCP_SUCCESS(result) && ! DisplayHeight.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayHeight)); + if ( ASDCP_SUCCESS(result) && ! DisplayWidth.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayWidth)); + if ( ASDCP_SUCCESS(result) && ! DisplayXOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayXOffset)); + if ( ASDCP_SUCCESS(result) && ! DisplayYOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayYOffset)); + if ( ASDCP_SUCCESS(result) && ! DisplayF2Offset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, DisplayF2Offset)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, AspectRatio)); + if ( ASDCP_SUCCESS(result) && ! ActiveFormatDescriptor.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveFormatDescriptor)); + if ( ASDCP_SUCCESS(result) && ! AlphaTransparency.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, AlphaTransparency)); + if ( ASDCP_SUCCESS(result) && ! TransferCharacteristic.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, TransferCharacteristic)); + if ( ASDCP_SUCCESS(result) && ! ImageAlignmentOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ImageAlignmentOffset)); + if ( ASDCP_SUCCESS(result) && ! ImageStartOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ImageStartOffset)); + if ( ASDCP_SUCCESS(result) && ! ImageEndOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ImageEndOffset)); + if ( ASDCP_SUCCESS(result) && ! FieldDominance.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, FieldDominance)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(GenericPictureEssenceDescriptor, PictureEssenceCoding)); + if ( ASDCP_SUCCESS(result) && ! CodingEquations.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, CodingEquations)); + if ( ASDCP_SUCCESS(result) && ! ColorPrimaries.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ColorPrimaries)); + if ( ASDCP_SUCCESS(result) && ! AlternativeCenterCuts.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, AlternativeCenterCuts)); + if ( ASDCP_SUCCESS(result) && ! ActiveWidth.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveWidth)); + if ( ASDCP_SUCCESS(result) && ! ActiveHeight.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveHeight)); + if ( ASDCP_SUCCESS(result) && ! ActiveXOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveXOffset)); + if ( ASDCP_SUCCESS(result) && ! ActiveYOffset.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(GenericPictureEssenceDescriptor, ActiveYOffset)); return result; } @@ -1512,11 +1749,36 @@ void GenericPictureEssenceDescriptor::Copy(const GenericPictureEssenceDescriptor& rhs) { FileDescriptor::Copy(rhs); + SignalStandard = rhs.SignalStandard; FrameLayout = rhs.FrameLayout; StoredWidth = rhs.StoredWidth; StoredHeight = rhs.StoredHeight; + StoredF2Offset = rhs.StoredF2Offset; + SampledWidth = rhs.SampledWidth; + SampledHeight = rhs.SampledHeight; + SampledXOffset = rhs.SampledXOffset; + SampledYOffset = rhs.SampledYOffset; + DisplayHeight = rhs.DisplayHeight; + DisplayWidth = rhs.DisplayWidth; + DisplayXOffset = rhs.DisplayXOffset; + DisplayYOffset = rhs.DisplayYOffset; + DisplayF2Offset = rhs.DisplayF2Offset; AspectRatio = rhs.AspectRatio; + ActiveFormatDescriptor = rhs.ActiveFormatDescriptor; + AlphaTransparency = rhs.AlphaTransparency; + TransferCharacteristic = rhs.TransferCharacteristic; + ImageAlignmentOffset = rhs.ImageAlignmentOffset; + ImageStartOffset = rhs.ImageStartOffset; + ImageEndOffset = rhs.ImageEndOffset; + FieldDominance = rhs.FieldDominance; PictureEssenceCoding = rhs.PictureEssenceCoding; + CodingEquations = rhs.CodingEquations; + ColorPrimaries = rhs.ColorPrimaries; + AlternativeCenterCuts = rhs.AlternativeCenterCuts; + ActiveWidth = rhs.ActiveWidth; + ActiveHeight = rhs.ActiveHeight; + ActiveXOffset = rhs.ActiveXOffset; + ActiveYOffset = rhs.ActiveYOffset; } // @@ -1530,11 +1792,87 @@ GenericPictureEssenceDescriptor::Dump(FILE* stream) stream = stderr; FileDescriptor::Dump(stream); + if ( ! SignalStandard.empty() ) { + fprintf(stream, " %22s = %d\n", "SignalStandard", SignalStandard.get()); + } fprintf(stream, " %22s = %d\n", "FrameLayout", FrameLayout); fprintf(stream, " %22s = %d\n", "StoredWidth", StoredWidth); fprintf(stream, " %22s = %d\n", "StoredHeight", StoredHeight); + if ( ! StoredF2Offset.empty() ) { + fprintf(stream, " %22s = %d\n", "StoredF2Offset", StoredF2Offset.get()); + } + if ( ! SampledWidth.empty() ) { + fprintf(stream, " %22s = %d\n", "SampledWidth", SampledWidth.get()); + } + if ( ! SampledHeight.empty() ) { + fprintf(stream, " %22s = %d\n", "SampledHeight", SampledHeight.get()); + } + if ( ! SampledXOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "SampledXOffset", SampledXOffset.get()); + } + if ( ! SampledYOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "SampledYOffset", SampledYOffset.get()); + } + if ( ! DisplayHeight.empty() ) { + fprintf(stream, " %22s = %d\n", "DisplayHeight", DisplayHeight.get()); + } + if ( ! DisplayWidth.empty() ) { + fprintf(stream, " %22s = %d\n", "DisplayWidth", DisplayWidth.get()); + } + if ( ! DisplayXOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "DisplayXOffset", DisplayXOffset.get()); + } + if ( ! DisplayYOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "DisplayYOffset", DisplayYOffset.get()); + } + if ( ! DisplayF2Offset.empty() ) { + fprintf(stream, " %22s = %d\n", "DisplayF2Offset", DisplayF2Offset.get()); + } fprintf(stream, " %22s = %s\n", "AspectRatio", AspectRatio.EncodeString(identbuf, IdentBufferLen)); + if ( ! ActiveFormatDescriptor.empty() ) { + fprintf(stream, " %22s = %d\n", "ActiveFormatDescriptor", ActiveFormatDescriptor.get()); + } + if ( ! AlphaTransparency.empty() ) { + fprintf(stream, " %22s = %d\n", "AlphaTransparency", AlphaTransparency.get()); + } + if ( ! TransferCharacteristic.empty() ) { + fprintf(stream, " %22s = %s\n", "TransferCharacteristic", TransferCharacteristic.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! ImageAlignmentOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "ImageAlignmentOffset", ImageAlignmentOffset.get()); + } + if ( ! ImageStartOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "ImageStartOffset", ImageStartOffset.get()); + } + if ( ! ImageEndOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "ImageEndOffset", ImageEndOffset.get()); + } + if ( ! FieldDominance.empty() ) { + fprintf(stream, " %22s = %d\n", "FieldDominance", FieldDominance.get()); + } fprintf(stream, " %22s = %s\n", "PictureEssenceCoding", PictureEssenceCoding.EncodeString(identbuf, IdentBufferLen)); + if ( ! CodingEquations.empty() ) { + fprintf(stream, " %22s = %s\n", "CodingEquations", CodingEquations.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! ColorPrimaries.empty() ) { + fprintf(stream, " %22s = %s\n", "ColorPrimaries", ColorPrimaries.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! AlternativeCenterCuts.empty() ) { + fprintf(stream, " %22s:\n", "AlternativeCenterCuts"); + AlternativeCenterCuts.get().Dump(stream); + } + if ( ! ActiveWidth.empty() ) { + fprintf(stream, " %22s = %d\n", "ActiveWidth", ActiveWidth.get()); + } + if ( ! ActiveHeight.empty() ) { + fprintf(stream, " %22s = %d\n", "ActiveHeight", ActiveHeight.get()); + } + if ( ! ActiveXOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "ActiveXOffset", ActiveXOffset.get()); + } + if ( ! ActiveYOffset.empty() ) { + fprintf(stream, " %22s = %d\n", "ActiveYOffset", ActiveYOffset.get()); + } } // @@ -1556,7 +1894,7 @@ GenericPictureEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) // -RGBAEssenceDescriptor::RGBAEssenceDescriptor(const Dictionary*& d) : GenericPictureEssenceDescriptor(d), m_Dict(d), ComponentMaxRef(0), ComponentMinRef(0) +RGBAEssenceDescriptor::RGBAEssenceDescriptor(const Dictionary*& d) : GenericPictureEssenceDescriptor(d), m_Dict(d), ComponentMaxRef(0), AlphaMinRef(0), ScanningDirection(0) { assert(m_Dict); m_UL = m_Dict->ul(MDD_RGBAEssenceDescriptor); @@ -1576,8 +1914,26 @@ RGBAEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = GenericPictureEssenceDescriptor::InitFromTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(RGBAEssenceDescriptor, ComponentMaxRef)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(RGBAEssenceDescriptor, ComponentMinRef)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(RGBAEssenceDescriptor, ComponentMaxRef)); + ComponentMaxRef.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(RGBAEssenceDescriptor, ComponentMinRef)); + ComponentMinRef.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(RGBAEssenceDescriptor, AlphaMinRef)); + AlphaMinRef.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(RGBAEssenceDescriptor, AlphaMaxRef)); + AlphaMaxRef.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(RGBAEssenceDescriptor, ScanningDirection)); + ScanningDirection.set_has_value( result == RESULT_OK ); + } return result; } @@ -1587,8 +1943,11 @@ RGBAEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = GenericPictureEssenceDescriptor::WriteToTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(RGBAEssenceDescriptor, ComponentMaxRef)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(RGBAEssenceDescriptor, ComponentMinRef)); + if ( ASDCP_SUCCESS(result) && ! ComponentMaxRef.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(RGBAEssenceDescriptor, ComponentMaxRef)); + if ( ASDCP_SUCCESS(result) && ! ComponentMinRef.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(RGBAEssenceDescriptor, ComponentMinRef)); + if ( ASDCP_SUCCESS(result) && ! AlphaMinRef.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(RGBAEssenceDescriptor, AlphaMinRef)); + if ( ASDCP_SUCCESS(result) && ! AlphaMaxRef.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(RGBAEssenceDescriptor, AlphaMaxRef)); + if ( ASDCP_SUCCESS(result) && ! ScanningDirection.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(RGBAEssenceDescriptor, ScanningDirection)); return result; } @@ -1599,6 +1958,9 @@ RGBAEssenceDescriptor::Copy(const RGBAEssenceDescriptor& rhs) GenericPictureEssenceDescriptor::Copy(rhs); ComponentMaxRef = rhs.ComponentMaxRef; ComponentMinRef = rhs.ComponentMinRef; + AlphaMinRef = rhs.AlphaMinRef; + AlphaMaxRef = rhs.AlphaMaxRef; + ScanningDirection = rhs.ScanningDirection; } // @@ -1612,8 +1974,21 @@ RGBAEssenceDescriptor::Dump(FILE* stream) stream = stderr; GenericPictureEssenceDescriptor::Dump(stream); - fprintf(stream, " %22s = %d\n", "ComponentMaxRef", ComponentMaxRef); - fprintf(stream, " %22s = %d\n", "ComponentMinRef", ComponentMinRef); + if ( ! ComponentMaxRef.empty() ) { + fprintf(stream, " %22s = %d\n", "ComponentMaxRef", ComponentMaxRef.get()); + } + if ( ! ComponentMinRef.empty() ) { + fprintf(stream, " %22s = %d\n", "ComponentMinRef", ComponentMinRef.get()); + } + if ( ! AlphaMinRef.empty() ) { + fprintf(stream, " %22s = %d\n", "AlphaMinRef", AlphaMinRef.get()); + } + if ( ! AlphaMaxRef.empty() ) { + fprintf(stream, " %22s = %d\n", "AlphaMaxRef", AlphaMaxRef.get()); + } + if ( ! ScanningDirection.empty() ) { + fprintf(stream, " %22s = %d\n", "ScanningDirection", ScanningDirection.get()); + } } // @@ -1665,9 +2040,22 @@ JPEG2000PictureSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(JPEG2000PictureSubDescriptor, XTOsize)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(JPEG2000PictureSubDescriptor, YTOsize)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(JPEG2000PictureSubDescriptor, Csize)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(JPEG2000PictureSubDescriptor, PictureComponentSizing)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(JPEG2000PictureSubDescriptor, CodingStyleDefault)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(JPEG2000PictureSubDescriptor, QuantizationDefault)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(JPEG2000PictureSubDescriptor, PictureComponentSizing)); + PictureComponentSizing.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(JPEG2000PictureSubDescriptor, CodingStyleDefault)); + CodingStyleDefault.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(JPEG2000PictureSubDescriptor, QuantizationDefault)); + QuantizationDefault.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(JPEG2000PictureSubDescriptor, J2CLayout)); + J2CLayout.set_has_value( result == RESULT_OK ); + } return result; } @@ -1687,9 +2075,10 @@ JPEG2000PictureSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(JPEG2000PictureSubDescriptor, XTOsize)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(JPEG2000PictureSubDescriptor, YTOsize)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(JPEG2000PictureSubDescriptor, Csize)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(JPEG2000PictureSubDescriptor, PictureComponentSizing)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(JPEG2000PictureSubDescriptor, CodingStyleDefault)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(JPEG2000PictureSubDescriptor, QuantizationDefault)); + if ( ASDCP_SUCCESS(result) && ! PictureComponentSizing.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(JPEG2000PictureSubDescriptor, PictureComponentSizing)); + if ( ASDCP_SUCCESS(result) && ! CodingStyleDefault.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(JPEG2000PictureSubDescriptor, CodingStyleDefault)); + if ( ASDCP_SUCCESS(result) && ! QuantizationDefault.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(JPEG2000PictureSubDescriptor, QuantizationDefault)); + if ( ASDCP_SUCCESS(result) && ! J2CLayout.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(JPEG2000PictureSubDescriptor, J2CLayout)); return result; } @@ -1711,6 +2100,7 @@ JPEG2000PictureSubDescriptor::Copy(const JPEG2000PictureSubDescriptor& rhs) PictureComponentSizing = rhs.PictureComponentSizing; CodingStyleDefault = rhs.CodingStyleDefault; QuantizationDefault = rhs.QuantizationDefault; + J2CLayout = rhs.J2CLayout; } // @@ -1734,9 +2124,18 @@ JPEG2000PictureSubDescriptor::Dump(FILE* stream) fprintf(stream, " %22s = %d\n", "XTOsize", XTOsize); fprintf(stream, " %22s = %d\n", "YTOsize", YTOsize); fprintf(stream, " %22s = %d\n", "Csize", Csize); - fprintf(stream, " %22s = %s\n", "PictureComponentSizing", PictureComponentSizing.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "CodingStyleDefault", CodingStyleDefault.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "QuantizationDefault", QuantizationDefault.EncodeString(identbuf, IdentBufferLen)); + if ( ! PictureComponentSizing.empty() ) { + fprintf(stream, " %22s = %s\n", "PictureComponentSizing", PictureComponentSizing.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! CodingStyleDefault.empty() ) { + fprintf(stream, " %22s = %s\n", "CodingStyleDefault", CodingStyleDefault.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! QuantizationDefault.empty() ) { + fprintf(stream, " %22s = %s\n", "QuantizationDefault", QuantizationDefault.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! J2CLayout.empty() ) { + fprintf(stream, " %22s = %s\n", "J2CLayout", J2CLayout.get().EncodeString(identbuf, IdentBufferLen)); + } } // @@ -1758,7 +2157,7 @@ JPEG2000PictureSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) // -CDCIEssenceDescriptor::CDCIEssenceDescriptor(const Dictionary*& d) : GenericPictureEssenceDescriptor(d), m_Dict(d), ComponentDepth(0), HorizontalSubsampling(0), VerticalSubsampling(0), ColorSiting(0) +CDCIEssenceDescriptor::CDCIEssenceDescriptor(const Dictionary*& d) : GenericPictureEssenceDescriptor(d), m_Dict(d), ComponentDepth(0), HorizontalSubsampling(0), VerticalSubsampling(0), ReversedByteOrder(0), AlphaSampleDepth(0), WhiteReflevel(0) { assert(m_Dict); m_UL = m_Dict->ul(MDD_CDCIEssenceDescriptor); @@ -1780,8 +2179,38 @@ CDCIEssenceDescriptor::InitFromTLVSet(TLVReader& TLVSet) Result_t result = GenericPictureEssenceDescriptor::InitFromTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(CDCIEssenceDescriptor, ComponentDepth)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(CDCIEssenceDescriptor, HorizontalSubsampling)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(CDCIEssenceDescriptor, VerticalSubsampling)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(CDCIEssenceDescriptor, ColorSiting)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(CDCIEssenceDescriptor, VerticalSubsampling)); + VerticalSubsampling.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(CDCIEssenceDescriptor, ColorSiting)); + ColorSiting.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(CDCIEssenceDescriptor, ReversedByteOrder)); + ReversedByteOrder.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi16(OBJ_READ_ARGS_OPT(CDCIEssenceDescriptor, PaddingBits)); + PaddingBits.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(CDCIEssenceDescriptor, AlphaSampleDepth)); + AlphaSampleDepth.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(CDCIEssenceDescriptor, BlackRefLevel)); + BlackRefLevel.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(CDCIEssenceDescriptor, WhiteReflevel)); + WhiteReflevel.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(CDCIEssenceDescriptor, ColorRange)); + ColorRange.set_has_value( result == RESULT_OK ); + } return result; } @@ -1793,8 +2222,14 @@ CDCIEssenceDescriptor::WriteToTLVSet(TLVWriter& TLVSet) Result_t result = GenericPictureEssenceDescriptor::WriteToTLVSet(TLVSet); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(CDCIEssenceDescriptor, ComponentDepth)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(CDCIEssenceDescriptor, HorizontalSubsampling)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(CDCIEssenceDescriptor, VerticalSubsampling)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(CDCIEssenceDescriptor, ColorSiting)); + if ( ASDCP_SUCCESS(result) && ! VerticalSubsampling.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(CDCIEssenceDescriptor, VerticalSubsampling)); + if ( ASDCP_SUCCESS(result) && ! ColorSiting.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(CDCIEssenceDescriptor, ColorSiting)); + if ( ASDCP_SUCCESS(result) && ! ReversedByteOrder.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(CDCIEssenceDescriptor, ReversedByteOrder)); + if ( ASDCP_SUCCESS(result) && ! PaddingBits.empty() ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS_OPT(CDCIEssenceDescriptor, PaddingBits)); + if ( ASDCP_SUCCESS(result) && ! AlphaSampleDepth.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(CDCIEssenceDescriptor, AlphaSampleDepth)); + if ( ASDCP_SUCCESS(result) && ! BlackRefLevel.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(CDCIEssenceDescriptor, BlackRefLevel)); + if ( ASDCP_SUCCESS(result) && ! WhiteReflevel.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(CDCIEssenceDescriptor, WhiteReflevel)); + if ( ASDCP_SUCCESS(result) && ! ColorRange.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(CDCIEssenceDescriptor, ColorRange)); return result; } @@ -1807,6 +2242,12 @@ CDCIEssenceDescriptor::Copy(const CDCIEssenceDescriptor& rhs) HorizontalSubsampling = rhs.HorizontalSubsampling; VerticalSubsampling = rhs.VerticalSubsampling; ColorSiting = rhs.ColorSiting; + ReversedByteOrder = rhs.ReversedByteOrder; + PaddingBits = rhs.PaddingBits; + AlphaSampleDepth = rhs.AlphaSampleDepth; + BlackRefLevel = rhs.BlackRefLevel; + WhiteReflevel = rhs.WhiteReflevel; + ColorRange = rhs.ColorRange; } // @@ -1822,8 +2263,30 @@ CDCIEssenceDescriptor::Dump(FILE* stream) GenericPictureEssenceDescriptor::Dump(stream); fprintf(stream, " %22s = %d\n", "ComponentDepth", ComponentDepth); fprintf(stream, " %22s = %d\n", "HorizontalSubsampling", HorizontalSubsampling); - fprintf(stream, " %22s = %d\n", "VerticalSubsampling", VerticalSubsampling); - fprintf(stream, " %22s = %d\n", "ColorSiting", ColorSiting); + if ( ! VerticalSubsampling.empty() ) { + fprintf(stream, " %22s = %d\n", "VerticalSubsampling", VerticalSubsampling.get()); + } + if ( ! ColorSiting.empty() ) { + fprintf(stream, " %22s = %d\n", "ColorSiting", ColorSiting.get()); + } + if ( ! ReversedByteOrder.empty() ) { + fprintf(stream, " %22s = %d\n", "ReversedByteOrder", ReversedByteOrder.get()); + } + if ( ! PaddingBits.empty() ) { + fprintf(stream, " %22s = %d\n", "PaddingBits", PaddingBits.get()); + } + if ( ! AlphaSampleDepth.empty() ) { + fprintf(stream, " %22s = %d\n", "AlphaSampleDepth", AlphaSampleDepth.get()); + } + if ( ! BlackRefLevel.empty() ) { + fprintf(stream, " %22s = %d\n", "BlackRefLevel", BlackRefLevel.get()); + } + if ( ! WhiteReflevel.empty() ) { + fprintf(stream, " %22s = %d\n", "WhiteReflevel", WhiteReflevel.get()); + } + if ( ! ColorRange.empty() ) { + fprintf(stream, " %22s = %d\n", "ColorRange", ColorRange.get()); + } } // @@ -1845,7 +2308,7 @@ CDCIEssenceDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) // -MPEG2VideoDescriptor::MPEG2VideoDescriptor(const Dictionary*& d) : CDCIEssenceDescriptor(d), m_Dict(d), CodedContentType(0), LowDelay(0), BitRate(0), ProfileAndLevel(0) +MPEG2VideoDescriptor::MPEG2VideoDescriptor(const Dictionary*& d) : CDCIEssenceDescriptor(d), m_Dict(d), SingleSequence(0), CodedContentType(0), ClosedGOP(0), MaxGOP(0), BitRate(0) { assert(m_Dict); m_UL = m_Dict->ul(MDD_MPEG2VideoDescriptor); @@ -1865,10 +2328,46 @@ MPEG2VideoDescriptor::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = CDCIEssenceDescriptor::InitFromTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(MPEG2VideoDescriptor, CodedContentType)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(MPEG2VideoDescriptor, LowDelay)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(MPEG2VideoDescriptor, BitRate)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(MPEG2VideoDescriptor, ProfileAndLevel)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, SingleSequence)); + SingleSequence.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, ConstantBFrames)); + ConstantBFrames.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, CodedContentType)); + CodedContentType.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, LowDelay)); + LowDelay.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, ClosedGOP)); + ClosedGOP.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, IdenticalGOP)); + IdenticalGOP.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, MaxGOP)); + MaxGOP.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, BPictureCount)); + BPictureCount.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, BitRate)); + BitRate.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi8(OBJ_READ_ARGS_OPT(MPEG2VideoDescriptor, ProfileAndLevel)); + ProfileAndLevel.set_has_value( result == RESULT_OK ); + } return result; } @@ -1878,10 +2377,16 @@ MPEG2VideoDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = CDCIEssenceDescriptor::WriteToTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(MPEG2VideoDescriptor, CodedContentType)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(MPEG2VideoDescriptor, LowDelay)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(MPEG2VideoDescriptor, BitRate)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(MPEG2VideoDescriptor, ProfileAndLevel)); + if ( ASDCP_SUCCESS(result) && ! SingleSequence.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, SingleSequence)); + if ( ASDCP_SUCCESS(result) && ! ConstantBFrames.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, ConstantBFrames)); + if ( ASDCP_SUCCESS(result) && ! CodedContentType.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, CodedContentType)); + if ( ASDCP_SUCCESS(result) && ! LowDelay.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, LowDelay)); + if ( ASDCP_SUCCESS(result) && ! ClosedGOP.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, ClosedGOP)); + if ( ASDCP_SUCCESS(result) && ! IdenticalGOP.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, IdenticalGOP)); + if ( ASDCP_SUCCESS(result) && ! MaxGOP.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, MaxGOP)); + if ( ASDCP_SUCCESS(result) && ! BPictureCount.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, BPictureCount)); + if ( ASDCP_SUCCESS(result) && ! BitRate.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, BitRate)); + if ( ASDCP_SUCCESS(result) && ! ProfileAndLevel.empty() ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS_OPT(MPEG2VideoDescriptor, ProfileAndLevel)); return result; } @@ -1890,8 +2395,14 @@ void MPEG2VideoDescriptor::Copy(const MPEG2VideoDescriptor& rhs) { CDCIEssenceDescriptor::Copy(rhs); + SingleSequence = rhs.SingleSequence; + ConstantBFrames = rhs.ConstantBFrames; CodedContentType = rhs.CodedContentType; LowDelay = rhs.LowDelay; + ClosedGOP = rhs.ClosedGOP; + IdenticalGOP = rhs.IdenticalGOP; + MaxGOP = rhs.MaxGOP; + BPictureCount = rhs.BPictureCount; BitRate = rhs.BitRate; ProfileAndLevel = rhs.ProfileAndLevel; } @@ -1907,10 +2418,36 @@ MPEG2VideoDescriptor::Dump(FILE* stream) stream = stderr; CDCIEssenceDescriptor::Dump(stream); - fprintf(stream, " %22s = %d\n", "CodedContentType", CodedContentType); - fprintf(stream, " %22s = %d\n", "LowDelay", LowDelay); - fprintf(stream, " %22s = %d\n", "BitRate", BitRate); - fprintf(stream, " %22s = %d\n", "ProfileAndLevel", ProfileAndLevel); + if ( ! SingleSequence.empty() ) { + fprintf(stream, " %22s = %d\n", "SingleSequence", SingleSequence.get()); + } + if ( ! ConstantBFrames.empty() ) { + fprintf(stream, " %22s = %d\n", "ConstantBFrames", ConstantBFrames.get()); + } + if ( ! CodedContentType.empty() ) { + fprintf(stream, " %22s = %d\n", "CodedContentType", CodedContentType.get()); + } + if ( ! LowDelay.empty() ) { + fprintf(stream, " %22s = %d\n", "LowDelay", LowDelay.get()); + } + if ( ! ClosedGOP.empty() ) { + fprintf(stream, " %22s = %d\n", "ClosedGOP", ClosedGOP.get()); + } + if ( ! IdenticalGOP.empty() ) { + fprintf(stream, " %22s = %d\n", "IdenticalGOP", IdenticalGOP.get()); + } + if ( ! MaxGOP.empty() ) { + fprintf(stream, " %22s = %d\n", "MaxGOP", MaxGOP.get()); + } + if ( ! BPictureCount.empty() ) { + fprintf(stream, " %22s = %d\n", "BPictureCount", BPictureCount.get()); + } + if ( ! BitRate.empty() ) { + fprintf(stream, " %22s = %d\n", "BitRate", BitRate.get()); + } + if ( ! ProfileAndLevel.empty() ) { + fprintf(stream, " %22s = %d\n", "ProfileAndLevel", ProfileAndLevel.get()); + } } // @@ -2287,6 +2824,10 @@ TimedTextDescriptor::InitFromTLVSet(TLVReader& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(TimedTextDescriptor, ResourceID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(TimedTextDescriptor, UCSEncoding)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(TimedTextDescriptor, NamespaceURI)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(TimedTextDescriptor, RFC5646LanguageTagList)); + RFC5646LanguageTagList.set_has_value( result == RESULT_OK ); + } return result; } @@ -2299,6 +2840,7 @@ TimedTextDescriptor::WriteToTLVSet(TLVWriter& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(TimedTextDescriptor, ResourceID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(TimedTextDescriptor, UCSEncoding)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(TimedTextDescriptor, NamespaceURI)); + if ( ASDCP_SUCCESS(result) && ! RFC5646LanguageTagList.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(TimedTextDescriptor, RFC5646LanguageTagList)); return result; } @@ -2310,6 +2852,7 @@ TimedTextDescriptor::Copy(const TimedTextDescriptor& rhs) ResourceID = rhs.ResourceID; UCSEncoding = rhs.UCSEncoding; NamespaceURI = rhs.NamespaceURI; + RFC5646LanguageTagList = rhs.RFC5646LanguageTagList; } // @@ -2326,6 +2869,9 @@ TimedTextDescriptor::Dump(FILE* stream) fprintf(stream, " %22s = %s\n", "ResourceID", ResourceID.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %s\n", "UCSEncoding", UCSEncoding.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %s\n", "NamespaceURI", NamespaceURI.EncodeString(identbuf, IdentBufferLen)); + if ( ! RFC5646LanguageTagList.empty() ) { + fprintf(stream, " %22s = %s\n", "RFC5646LanguageTagList", RFC5646LanguageTagList.get().EncodeString(identbuf, IdentBufferLen)); + } } // @@ -2497,6 +3043,77 @@ StereoscopicPictureSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) } //------------------------------------------------------------------------------------------ +// ContainerConstraintSubDescriptor + +// + +ContainerConstraintSubDescriptor::ContainerConstraintSubDescriptor(const Dictionary*& d) : InterchangeObject(d), m_Dict(d) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_ContainerConstraintSubDescriptor); +} + +ContainerConstraintSubDescriptor::ContainerConstraintSubDescriptor(const ContainerConstraintSubDescriptor& rhs) : InterchangeObject(rhs.m_Dict), m_Dict(rhs.m_Dict) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_ContainerConstraintSubDescriptor); + Copy(rhs); +} + + +// +ASDCP::Result_t +ContainerConstraintSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) +{ + assert(m_Dict); + Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); + return result; +} + +// +ASDCP::Result_t +ContainerConstraintSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +{ + assert(m_Dict); + Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); + return result; +} + +// +void +ContainerConstraintSubDescriptor::Copy(const ContainerConstraintSubDescriptor& rhs) +{ + InterchangeObject::Copy(rhs); +} + +// +void +ContainerConstraintSubDescriptor::Dump(FILE* stream) +{ + char identbuf[IdentBufferLen]; + *identbuf = 0; + + if ( stream == 0 ) + stream = stderr; + + InterchangeObject::Dump(stream); +} + +// +ASDCP::Result_t +ContainerConstraintSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +{ + return InterchangeObject::InitFromBuffer(p, l); +} + +// +ASDCP::Result_t +ContainerConstraintSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +{ + return InterchangeObject::WriteToBuffer(Buffer); +} + +//------------------------------------------------------------------------------------------ // NetworkLocator // @@ -2576,7 +3193,7 @@ NetworkLocator::WriteToBuffer(ASDCP::FrameBuffer& Buffer) // -MCALabelSubDescriptor::MCALabelSubDescriptor(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), MCAChannelID(0) +MCALabelSubDescriptor::MCALabelSubDescriptor(const Dictionary*& d) : InterchangeObject(d), m_Dict(d) { assert(m_Dict); m_UL = m_Dict->ul(MDD_MCALabelSubDescriptor); @@ -2599,9 +3216,18 @@ MCALabelSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(MCALabelSubDescriptor, MCALabelDictionaryID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(MCALabelSubDescriptor, MCALinkID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(MCALabelSubDescriptor, MCATagSymbol)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(MCALabelSubDescriptor, MCATagName)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(MCALabelSubDescriptor, MCAChannelID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(MCALabelSubDescriptor, RFC5646SpokenLanguage)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(MCALabelSubDescriptor, MCATagName)); + MCATagName.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadUi32(OBJ_READ_ARGS_OPT(MCALabelSubDescriptor, MCAChannelID)); + MCAChannelID.set_has_value( result == RESULT_OK ); + } + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(MCALabelSubDescriptor, RFC5646SpokenLanguage)); + RFC5646SpokenLanguage.set_has_value( result == RESULT_OK ); + } return result; } @@ -2614,9 +3240,9 @@ MCALabelSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(MCALabelSubDescriptor, MCALabelDictionaryID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(MCALabelSubDescriptor, MCALinkID)); if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(MCALabelSubDescriptor, MCATagSymbol)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(MCALabelSubDescriptor, MCATagName)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(MCALabelSubDescriptor, MCAChannelID)); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(MCALabelSubDescriptor, RFC5646SpokenLanguage)); + if ( ASDCP_SUCCESS(result) && ! MCATagName.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(MCALabelSubDescriptor, MCATagName)); + if ( ASDCP_SUCCESS(result) && ! MCAChannelID.empty() ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS_OPT(MCALabelSubDescriptor, MCAChannelID)); + if ( ASDCP_SUCCESS(result) && ! RFC5646SpokenLanguage.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(MCALabelSubDescriptor, RFC5646SpokenLanguage)); return result; } @@ -2647,9 +3273,15 @@ MCALabelSubDescriptor::Dump(FILE* stream) fprintf(stream, " %22s = %s\n", "MCALabelDictionaryID", MCALabelDictionaryID.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %s\n", "MCALinkID", MCALinkID.EncodeString(identbuf, IdentBufferLen)); fprintf(stream, " %22s = %s\n", "MCATagSymbol", MCATagSymbol.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %s\n", "MCATagName", MCATagName.EncodeString(identbuf, IdentBufferLen)); - fprintf(stream, " %22s = %d\n", "MCAChannelID", MCAChannelID); - fprintf(stream, " %22s = %s\n", "RFC5646SpokenLanguage", RFC5646SpokenLanguage.EncodeString(identbuf, IdentBufferLen)); + if ( ! MCATagName.empty() ) { + fprintf(stream, " %22s = %s\n", "MCATagName", MCATagName.get().EncodeString(identbuf, IdentBufferLen)); + } + if ( ! MCAChannelID.empty() ) { + fprintf(stream, " %22s = %d\n", "MCAChannelID", MCAChannelID.get()); + } + if ( ! RFC5646SpokenLanguage.empty() ) { + fprintf(stream, " %22s = %s\n", "RFC5646SpokenLanguage", RFC5646SpokenLanguage.get().EncodeString(identbuf, IdentBufferLen)); + } } // @@ -2691,7 +3323,10 @@ AudioChannelLabelSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = MCALabelSubDescriptor::InitFromTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(AudioChannelLabelSubDescriptor, SoundfieldGroupLinkID)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(AudioChannelLabelSubDescriptor, SoundfieldGroupLinkID)); + SoundfieldGroupLinkID.set_has_value( result == RESULT_OK ); + } return result; } @@ -2701,7 +3336,7 @@ AudioChannelLabelSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = MCALabelSubDescriptor::WriteToTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(AudioChannelLabelSubDescriptor, SoundfieldGroupLinkID)); + if ( ASDCP_SUCCESS(result) && ! SoundfieldGroupLinkID.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(AudioChannelLabelSubDescriptor, SoundfieldGroupLinkID)); return result; } @@ -2724,7 +3359,9 @@ AudioChannelLabelSubDescriptor::Dump(FILE* stream) stream = stderr; MCALabelSubDescriptor::Dump(stream); - fprintf(stream, " %22s = %s\n", "SoundfieldGroupLinkID", SoundfieldGroupLinkID.EncodeString(identbuf, IdentBufferLen)); + if ( ! SoundfieldGroupLinkID.empty() ) { + fprintf(stream, " %22s = %s\n", "SoundfieldGroupLinkID", SoundfieldGroupLinkID.get().EncodeString(identbuf, IdentBufferLen)); + } } // @@ -2766,7 +3403,9 @@ SoundfieldGroupLabelSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) { assert(m_Dict); Result_t result = MCALabelSubDescriptor::InitFromTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(SoundfieldGroupLabelSubDescriptor, GroupOfSoundfieldGroupsLinkID)); + if ( ASDCP_SUCCESS(result) ) { + result = TLVSet.ReadObject(OBJ_READ_ARGS_OPT(SoundfieldGroupLabelSubDescriptor, GroupOfSoundfieldGroupsLinkID)); + } return result; } @@ -2776,7 +3415,7 @@ SoundfieldGroupLabelSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) { assert(m_Dict); Result_t result = MCALabelSubDescriptor::WriteToTLVSet(TLVSet); - if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(SoundfieldGroupLabelSubDescriptor, GroupOfSoundfieldGroupsLinkID)); + if ( ASDCP_SUCCESS(result) && ! GroupOfSoundfieldGroupsLinkID.empty() ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS_OPT(SoundfieldGroupLabelSubDescriptor, GroupOfSoundfieldGroupsLinkID)); return result; } @@ -2799,8 +3438,10 @@ SoundfieldGroupLabelSubDescriptor::Dump(FILE* stream) stream = stderr; MCALabelSubDescriptor::Dump(stream); - fprintf(stream, " %22s:\n", "GroupOfSoundfieldGroupsLinkID"); - GroupOfSoundfieldGroupsLinkID.Dump(stream); + if ( ! GroupOfSoundfieldGroupsLinkID.empty() ) { + fprintf(stream, " %22s:\n", "GroupOfSoundfieldGroupsLinkID"); + GroupOfSoundfieldGroupsLinkID.get().Dump(stream); + } } // @@ -2888,6 +3529,251 @@ GroupOfSoundfieldGroupsLabelSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buf return InterchangeObject::WriteToBuffer(Buffer); } +//------------------------------------------------------------------------------------------ +// DCDataDescriptor + +// + +DCDataDescriptor::DCDataDescriptor(const Dictionary*& d) : GenericDataEssenceDescriptor(d), m_Dict(d) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_DCDataDescriptor); +} + +DCDataDescriptor::DCDataDescriptor(const DCDataDescriptor& rhs) : GenericDataEssenceDescriptor(rhs.m_Dict), m_Dict(rhs.m_Dict) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_DCDataDescriptor); + Copy(rhs); +} + + +// +ASDCP::Result_t +DCDataDescriptor::InitFromTLVSet(TLVReader& TLVSet) +{ + assert(m_Dict); + Result_t result = GenericDataEssenceDescriptor::InitFromTLVSet(TLVSet); + return result; +} + +// +ASDCP::Result_t +DCDataDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +{ + assert(m_Dict); + Result_t result = GenericDataEssenceDescriptor::WriteToTLVSet(TLVSet); + return result; +} + +// +void +DCDataDescriptor::Copy(const DCDataDescriptor& rhs) +{ + GenericDataEssenceDescriptor::Copy(rhs); +} + +// +void +DCDataDescriptor::Dump(FILE* stream) +{ + char identbuf[IdentBufferLen]; + *identbuf = 0; + + if ( stream == 0 ) + stream = stderr; + + GenericDataEssenceDescriptor::Dump(stream); +} + +// +ASDCP::Result_t +DCDataDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +{ + return InterchangeObject::InitFromBuffer(p, l); +} + +// +ASDCP::Result_t +DCDataDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +{ + return InterchangeObject::WriteToBuffer(Buffer); +} + +//------------------------------------------------------------------------------------------ +// DolbyAtmosSubDescriptor + +// + +DolbyAtmosSubDescriptor::DolbyAtmosSubDescriptor(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), FirstFrame(0), MaxChannelCount(0), MaxObjectCount(0), AtmosVersion(0) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_DolbyAtmosSubDescriptor); +} + +DolbyAtmosSubDescriptor::DolbyAtmosSubDescriptor(const DolbyAtmosSubDescriptor& rhs) : InterchangeObject(rhs.m_Dict), m_Dict(rhs.m_Dict) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_DolbyAtmosSubDescriptor); + Copy(rhs); +} + + +// +ASDCP::Result_t +DolbyAtmosSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) +{ + assert(m_Dict); + Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, AtmosID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, FirstFrame)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, MaxChannelCount)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi16(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, MaxObjectCount)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(DolbyAtmosSubDescriptor, AtmosVersion)); + return result; +} + +// +ASDCP::Result_t +DolbyAtmosSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +{ + assert(m_Dict); + Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, AtmosID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, FirstFrame)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, MaxChannelCount)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi16(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, MaxObjectCount)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(DolbyAtmosSubDescriptor, AtmosVersion)); + return result; +} + +// +void +DolbyAtmosSubDescriptor::Copy(const DolbyAtmosSubDescriptor& rhs) +{ + InterchangeObject::Copy(rhs); + AtmosID = rhs.AtmosID; + FirstFrame = rhs.FirstFrame; + MaxChannelCount = rhs.MaxChannelCount; + MaxObjectCount = rhs.MaxObjectCount; + AtmosVersion = rhs.AtmosVersion; +} + +// +void +DolbyAtmosSubDescriptor::Dump(FILE* stream) +{ + char identbuf[IdentBufferLen]; + *identbuf = 0; + + if ( stream == 0 ) + stream = stderr; + + InterchangeObject::Dump(stream); + fprintf(stream, " %22s = %s\n", "AtmosID", AtmosID.EncodeString(identbuf, IdentBufferLen)); + fprintf(stream, " %22s = %d\n", "FirstFrame", FirstFrame); + fprintf(stream, " %22s = %d\n", "MaxChannelCount", MaxChannelCount); + fprintf(stream, " %22s = %d\n", "MaxObjectCount", MaxObjectCount); + fprintf(stream, " %22s = %d\n", "AtmosVersion", AtmosVersion); +} + +// +ASDCP::Result_t +DolbyAtmosSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +{ + return InterchangeObject::InitFromBuffer(p, l); +} + +// +ASDCP::Result_t +DolbyAtmosSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +{ + return InterchangeObject::WriteToBuffer(Buffer); +} + +//------------------------------------------------------------------------------------------ +// PHDRMetadataTrackSubDescriptor + +// + +PHDRMetadataTrackSubDescriptor::PHDRMetadataTrackSubDescriptor(const Dictionary*& d) : InterchangeObject(d), m_Dict(d), SourceTrackID(0), SimplePayloadSID(0) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_PHDRMetadataTrackSubDescriptor); +} + +PHDRMetadataTrackSubDescriptor::PHDRMetadataTrackSubDescriptor(const PHDRMetadataTrackSubDescriptor& rhs) : InterchangeObject(rhs.m_Dict), m_Dict(rhs.m_Dict) +{ + assert(m_Dict); + m_UL = m_Dict->ul(MDD_PHDRMetadataTrackSubDescriptor); + Copy(rhs); +} + + +// +ASDCP::Result_t +PHDRMetadataTrackSubDescriptor::InitFromTLVSet(TLVReader& TLVSet) +{ + assert(m_Dict); + Result_t result = InterchangeObject::InitFromTLVSet(TLVSet); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(PHDRMetadataTrackSubDescriptor, DataDefinition)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(PHDRMetadataTrackSubDescriptor, SourceTrackID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(PHDRMetadataTrackSubDescriptor, SimplePayloadSID)); + return result; +} + +// +ASDCP::Result_t +PHDRMetadataTrackSubDescriptor::WriteToTLVSet(TLVWriter& TLVSet) +{ + assert(m_Dict); + Result_t result = InterchangeObject::WriteToTLVSet(TLVSet); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(PHDRMetadataTrackSubDescriptor, DataDefinition)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(PHDRMetadataTrackSubDescriptor, SourceTrackID)); + if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(PHDRMetadataTrackSubDescriptor, SimplePayloadSID)); + return result; +} + +// +void +PHDRMetadataTrackSubDescriptor::Copy(const PHDRMetadataTrackSubDescriptor& rhs) +{ + InterchangeObject::Copy(rhs); + DataDefinition = rhs.DataDefinition; + SourceTrackID = rhs.SourceTrackID; + SimplePayloadSID = rhs.SimplePayloadSID; +} + +// +void +PHDRMetadataTrackSubDescriptor::Dump(FILE* stream) +{ + char identbuf[IdentBufferLen]; + *identbuf = 0; + + if ( stream == 0 ) + stream = stderr; + + InterchangeObject::Dump(stream); + fprintf(stream, " %22s = %s\n", "DataDefinition", DataDefinition.EncodeString(identbuf, IdentBufferLen)); + fprintf(stream, " %22s = %d\n", "SourceTrackID", SourceTrackID); + fprintf(stream, " %22s = %d\n", "SimplePayloadSID", SimplePayloadSID); +} + +// +ASDCP::Result_t +PHDRMetadataTrackSubDescriptor::InitFromBuffer(const byte_t* p, ui32_t l) +{ + return InterchangeObject::InitFromBuffer(p, l); +} + +// +ASDCP::Result_t +PHDRMetadataTrackSubDescriptor::WriteToBuffer(ASDCP::FrameBuffer& Buffer) +{ + return InterchangeObject::WriteToBuffer(Buffer); +} + // // end Metadata.cpp // diff --git a/asdcplib/src/Metadata.h b/asdcplib/src/Metadata.h index 3360cdfe..3faa4067 100755 --- a/asdcplib/src/Metadata.h +++ b/asdcplib/src/Metadata.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file Metadata.h - \version $Id: Metadata.h,v 1.29 2012/02/21 02:09:31 jhurst Exp $ + \version $Id: Metadata.h,v 1.39 2015/10/10 20:26:29 jhurst Exp $ \brief MXF metadata objects */ @@ -57,7 +57,7 @@ namespace ASDCP UUID ProductUID; Kumu::Timestamp ModificationDate; VersionType ToolkitVersion; - UTF16String Platform; + optional_property<UTF16String > Platform; Identification(const Dictionary*& d); Identification(const Identification& rhs); @@ -105,7 +105,7 @@ namespace ASDCP public: const Dictionary*& m_Dict; UMID LinkedPackageUID; - ui32_t IndexSID; + optional_property<ui32_t > IndexSID; ui32_t BodySID; EssenceContainerData(const Dictionary*& d); @@ -130,10 +130,10 @@ namespace ASDCP public: const Dictionary*& m_Dict; UMID PackageUID; - UTF16String Name; + optional_property<UTF16String > Name; Kumu::Timestamp PackageCreationDate; Kumu::Timestamp PackageModifiedDate; - Batch<UUID> Tracks; + Array<UUID> Tracks; GenericPackage(const Dictionary*& d); GenericPackage(const GenericPackage& rhs); @@ -154,6 +154,7 @@ namespace ASDCP public: const Dictionary*& m_Dict; + optional_property<UUID > PackageMarker; MaterialPackage(const Dictionary*& d); MaterialPackage(const MaterialPackage& rhs); @@ -201,8 +202,8 @@ namespace ASDCP const Dictionary*& m_Dict; ui32_t TrackID; ui32_t TrackNumber; - UTF16String TrackName; - UUID Sequence; + optional_property<UTF16String > TrackName; + optional_property<UUID > Sequence; GenericTrack(const Dictionary*& d); GenericTrack(const GenericTrack& rhs); @@ -270,7 +271,7 @@ namespace ASDCP public: const Dictionary*& m_Dict; UL DataDefinition; - ui64_t Duration; + optional_property<ui64_t > Duration; StructuralComponent(const Dictionary*& d); StructuralComponent(const StructuralComponent& rhs); @@ -291,7 +292,7 @@ namespace ASDCP public: const Dictionary*& m_Dict; - Batch<UUID> StructuralComponents; + Array<UUID> StructuralComponents; Sequence(const Dictionary*& d); Sequence(const Sequence& rhs); @@ -364,8 +365,8 @@ namespace ASDCP public: const Dictionary*& m_Dict; - Batch<UUID> Locators; - Batch<UUID> SubDescriptors; + Array<UUID> Locators; + Array<UUID> SubDescriptors; GenericDescriptor(const Dictionary*& d); GenericDescriptor(const GenericDescriptor& rhs); @@ -386,11 +387,11 @@ namespace ASDCP public: const Dictionary*& m_Dict; - ui32_t LinkedTrackID; + optional_property<ui32_t > LinkedTrackID; Rational SampleRate; - ui64_t ContainerDuration; + optional_property<ui64_t > ContainerDuration; UL EssenceContainer; - UL Codec; + optional_property<UL > Codec; FileDescriptor(const Dictionary*& d); FileDescriptor(const FileDescriptor& rhs); @@ -415,10 +416,12 @@ namespace ASDCP const Dictionary*& m_Dict; Rational AudioSamplingRate; ui8_t Locked; - ui8_t AudioRefLevel; + optional_property<ui8_t > AudioRefLevel; + optional_property<ui8_t > ElectroSpatialFormulation; ui32_t ChannelCount; ui32_t QuantizationBits; - ui8_t DialNorm; + optional_property<ui8_t > DialNorm; + UL SoundEssenceCoding; GenericSoundEssenceDescriptor(const Dictionary*& d); GenericSoundEssenceDescriptor(const GenericSoundEssenceDescriptor& rhs); @@ -442,9 +445,11 @@ namespace ASDCP public: const Dictionary*& m_Dict; ui16_t BlockAlign; - ui8_t SequenceOffset; + optional_property<ui8_t > SequenceOffset; ui32_t AvgBps; - UL ChannelAssignment; + optional_property<UL > ChannelAssignment; + optional_property<Rational > ReferenceImageEditRate; + optional_property<ui8_t > ReferenceAudioAlignmentLevel; WaveAudioDescriptor(const Dictionary*& d); WaveAudioDescriptor(const WaveAudioDescriptor& rhs); @@ -467,11 +472,36 @@ namespace ASDCP public: const Dictionary*& m_Dict; + optional_property<ui8_t > SignalStandard; ui8_t FrameLayout; ui32_t StoredWidth; ui32_t StoredHeight; + optional_property<ui32_t > StoredF2Offset; + optional_property<ui32_t > SampledWidth; + optional_property<ui32_t > SampledHeight; + optional_property<ui32_t > SampledXOffset; + optional_property<ui32_t > SampledYOffset; + optional_property<ui32_t > DisplayHeight; + optional_property<ui32_t > DisplayWidth; + optional_property<ui32_t > DisplayXOffset; + optional_property<ui32_t > DisplayYOffset; + optional_property<ui32_t > DisplayF2Offset; Rational AspectRatio; + optional_property<ui8_t > ActiveFormatDescriptor; + optional_property<ui8_t > AlphaTransparency; + optional_property<UL > TransferCharacteristic; + optional_property<ui32_t > ImageAlignmentOffset; + optional_property<ui32_t > ImageStartOffset; + optional_property<ui32_t > ImageEndOffset; + optional_property<ui8_t > FieldDominance; UL PictureEssenceCoding; + optional_property<UL > CodingEquations; + optional_property<UL > ColorPrimaries; + optional_property<Batch<UL> > AlternativeCenterCuts; + optional_property<ui32_t > ActiveWidth; + optional_property<ui32_t > ActiveHeight; + optional_property<ui32_t > ActiveXOffset; + optional_property<ui32_t > ActiveYOffset; GenericPictureEssenceDescriptor(const Dictionary*& d); GenericPictureEssenceDescriptor(const GenericPictureEssenceDescriptor& rhs); @@ -494,8 +524,11 @@ namespace ASDCP public: const Dictionary*& m_Dict; - ui32_t ComponentMaxRef; - ui32_t ComponentMinRef; + optional_property<ui32_t > ComponentMaxRef; + optional_property<ui32_t > ComponentMinRef; + optional_property<ui32_t > AlphaMinRef; + optional_property<ui32_t > AlphaMaxRef; + optional_property<ui8_t > ScanningDirection; RGBAEssenceDescriptor(const Dictionary*& d); RGBAEssenceDescriptor(const RGBAEssenceDescriptor& rhs); @@ -528,9 +561,10 @@ namespace ASDCP ui32_t XTOsize; ui32_t YTOsize; ui16_t Csize; - Raw PictureComponentSizing; - Raw CodingStyleDefault; - Raw QuantizationDefault; + optional_property<Raw > PictureComponentSizing; + optional_property<Raw > CodingStyleDefault; + optional_property<Raw > QuantizationDefault; + optional_property<RGBALayout > J2CLayout; JPEG2000PictureSubDescriptor(const Dictionary*& d); JPEG2000PictureSubDescriptor(const JPEG2000PictureSubDescriptor& rhs); @@ -555,8 +589,14 @@ namespace ASDCP const Dictionary*& m_Dict; ui32_t ComponentDepth; ui32_t HorizontalSubsampling; - ui32_t VerticalSubsampling; - ui8_t ColorSiting; + optional_property<ui32_t > VerticalSubsampling; + optional_property<ui8_t > ColorSiting; + optional_property<ui8_t > ReversedByteOrder; + optional_property<ui16_t > PaddingBits; + optional_property<ui32_t > AlphaSampleDepth; + optional_property<ui32_t > BlackRefLevel; + optional_property<ui32_t > WhiteReflevel; + optional_property<ui32_t > ColorRange; CDCIEssenceDescriptor(const Dictionary*& d); CDCIEssenceDescriptor(const CDCIEssenceDescriptor& rhs); @@ -579,10 +619,16 @@ namespace ASDCP public: const Dictionary*& m_Dict; - ui8_t CodedContentType; - ui8_t LowDelay; - ui32_t BitRate; - ui8_t ProfileAndLevel; + optional_property<ui8_t > SingleSequence; + optional_property<ui8_t > ConstantBFrames; + optional_property<ui8_t > CodedContentType; + optional_property<ui8_t > LowDelay; + optional_property<ui8_t > ClosedGOP; + optional_property<ui8_t > IdenticalGOP; + optional_property<ui8_t > MaxGOP; + optional_property<ui8_t > BPictureCount; + optional_property<ui32_t > BitRate; + optional_property<ui8_t > ProfileAndLevel; MPEG2VideoDescriptor(const Dictionary*& d); MPEG2VideoDescriptor(const MPEG2VideoDescriptor& rhs); @@ -708,6 +754,7 @@ namespace ASDCP UUID ResourceID; UTF16String UCSEncoding; UTF16String NamespaceURI; + optional_property<UTF16String > RFC5646LanguageTagList; TimedTextDescriptor(const Dictionary*& d); TimedTextDescriptor(const TimedTextDescriptor& rhs); @@ -771,6 +818,28 @@ namespace ASDCP }; // + class ContainerConstraintSubDescriptor : public InterchangeObject + { + ContainerConstraintSubDescriptor(); + + public: + const Dictionary*& m_Dict; + + ContainerConstraintSubDescriptor(const Dictionary*& d); + ContainerConstraintSubDescriptor(const ContainerConstraintSubDescriptor& rhs); + virtual ~ContainerConstraintSubDescriptor() {} + + const ContainerConstraintSubDescriptor& operator=(const ContainerConstraintSubDescriptor& rhs) { Copy(rhs); return *this; } + virtual void Copy(const ContainerConstraintSubDescriptor& rhs); + virtual const char* HasName() { return "ContainerConstraintSubDescriptor"; } + virtual Result_t InitFromTLVSet(TLVReader& TLVSet); + virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); + virtual void Dump(FILE* = 0); + virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l); + virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&); + }; + + // class NetworkLocator : public InterchangeObject { NetworkLocator(); @@ -803,9 +872,9 @@ namespace ASDCP UL MCALabelDictionaryID; UUID MCALinkID; UTF16String MCATagSymbol; - UTF16String MCATagName; - ui32_t MCAChannelID; - ISO8String RFC5646SpokenLanguage; + optional_property<UTF16String > MCATagName; + optional_property<ui32_t > MCAChannelID; + optional_property<ISO8String > RFC5646SpokenLanguage; MCALabelSubDescriptor(const Dictionary*& d); MCALabelSubDescriptor(const MCALabelSubDescriptor& rhs); @@ -828,7 +897,7 @@ namespace ASDCP public: const Dictionary*& m_Dict; - UUID SoundfieldGroupLinkID; + optional_property<UUID > SoundfieldGroupLinkID; AudioChannelLabelSubDescriptor(const Dictionary*& d); AudioChannelLabelSubDescriptor(const AudioChannelLabelSubDescriptor& rhs); @@ -851,7 +920,7 @@ namespace ASDCP public: const Dictionary*& m_Dict; - Array<UUID> GroupOfSoundfieldGroupsLinkID; + optional_property<Array<UUID> > GroupOfSoundfieldGroupsLinkID; SoundfieldGroupLabelSubDescriptor(const Dictionary*& d); SoundfieldGroupLabelSubDescriptor(const SoundfieldGroupLabelSubDescriptor& rhs); @@ -889,6 +958,80 @@ namespace ASDCP virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&); }; + // + class DCDataDescriptor : public GenericDataEssenceDescriptor + { + DCDataDescriptor(); + + public: + const Dictionary*& m_Dict; + + DCDataDescriptor(const Dictionary*& d); + DCDataDescriptor(const DCDataDescriptor& rhs); + virtual ~DCDataDescriptor() {} + + const DCDataDescriptor& operator=(const DCDataDescriptor& rhs) { Copy(rhs); return *this; } + virtual void Copy(const DCDataDescriptor& rhs); + virtual const char* HasName() { return "DCDataDescriptor"; } + virtual Result_t InitFromTLVSet(TLVReader& TLVSet); + virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); + virtual void Dump(FILE* = 0); + virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l); + virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&); + }; + + // + class DolbyAtmosSubDescriptor : public InterchangeObject + { + DolbyAtmosSubDescriptor(); + + public: + const Dictionary*& m_Dict; + UUID AtmosID; + ui32_t FirstFrame; + ui16_t MaxChannelCount; + ui16_t MaxObjectCount; + ui8_t AtmosVersion; + + DolbyAtmosSubDescriptor(const Dictionary*& d); + DolbyAtmosSubDescriptor(const DolbyAtmosSubDescriptor& rhs); + virtual ~DolbyAtmosSubDescriptor() {} + + const DolbyAtmosSubDescriptor& operator=(const DolbyAtmosSubDescriptor& rhs) { Copy(rhs); return *this; } + virtual void Copy(const DolbyAtmosSubDescriptor& rhs); + virtual const char* HasName() { return "DolbyAtmosSubDescriptor"; } + virtual Result_t InitFromTLVSet(TLVReader& TLVSet); + virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); + virtual void Dump(FILE* = 0); + virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l); + virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&); + }; + + // + class PHDRMetadataTrackSubDescriptor : public InterchangeObject + { + PHDRMetadataTrackSubDescriptor(); + + public: + const Dictionary*& m_Dict; + UL DataDefinition; + ui32_t SourceTrackID; + ui32_t SimplePayloadSID; + + PHDRMetadataTrackSubDescriptor(const Dictionary*& d); + PHDRMetadataTrackSubDescriptor(const PHDRMetadataTrackSubDescriptor& rhs); + virtual ~PHDRMetadataTrackSubDescriptor() {} + + const PHDRMetadataTrackSubDescriptor& operator=(const PHDRMetadataTrackSubDescriptor& rhs) { Copy(rhs); return *this; } + virtual void Copy(const PHDRMetadataTrackSubDescriptor& rhs); + virtual const char* HasName() { return "PHDRMetadataTrackSubDescriptor"; } + virtual Result_t InitFromTLVSet(TLVReader& TLVSet); + virtual Result_t WriteToTLVSet(TLVWriter& TLVSet); + virtual void Dump(FILE* = 0); + virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l); + virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&); + }; + } // namespace MXF } // namespace ASDCP diff --git a/asdcplib/src/PCMDataProviders.cpp b/asdcplib/src/PCMDataProviders.cpp new file mode 100644 index 00000000..2ba78363 --- /dev/null +++ b/asdcplib/src/PCMDataProviders.cpp @@ -0,0 +1,210 @@ +/* +Copyright (c) 20013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file PCMDataProviders.cpp + \version $Id: PCMDataProviders.cpp,v 1.1 2013/04/12 23:39:31 mikey Exp $ + \brief Implementation of PCM sample data providers for WAV, AtmosSync and Silence. +*/ + +#include <PCMDataProviders.h> + +#include <KM_log.h> + +using namespace ASDCP; +using namespace Kumu; + +ASDCP::PCMDataProviderInterface::~PCMDataProviderInterface() {} + +// +ASDCP::WAVDataProvider::WAVDataProvider() + : m_Parser(), m_FB(), m_ADesc(), m_SampleSize(0), m_ptr(NULL) +{} + +ASDCP::WAVDataProvider::~WAVDataProvider() +{} + +Result_t +ASDCP::WAVDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten) +{ + ASDCP_TEST_NULL(buf); + ASDCP_TEST_NULL(m_ptr); + if ( numChannels > m_ADesc.ChannelCount) + { + DefaultLogSink().Error("Requested %u channels from a wav file with %u channel.", numChannels, + m_ADesc.ChannelCount); + return RESULT_FAIL; + } + *bytesWritten = m_SampleSize * numChannels; + ::memcpy(buf, m_ptr, *bytesWritten); + m_ptr += *bytesWritten; + return RESULT_OK; +} + +Result_t +ASDCP::WAVDataProvider::ReadFrame() +{ + Result_t result = m_Parser.ReadFrame(m_FB); + m_ptr = ASDCP_SUCCESS(result) ? m_FB.RoData() : NULL; + return result; +} + +Result_t +ASDCP::WAVDataProvider::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const +{ + ADesc = m_ADesc; + return RESULT_OK; +} + +Result_t +ASDCP::WAVDataProvider::Reset() +{ + return m_Parser.Reset(); +} + +Result_t +ASDCP::WAVDataProvider::OpenRead(const char* filename, const Rational& PictureRate) +{ + ASDCP_TEST_NULL_STR(filename); + + Result_t result = m_Parser.OpenRead(filename, PictureRate); + + if ( ASDCP_SUCCESS(result) ) + result = m_Parser.FillAudioDescriptor(m_ADesc); + + if ( ASDCP_SUCCESS(result) ) + { + m_ADesc.EditRate = PictureRate; + m_SampleSize = ((m_ADesc.QuantizationBits + 7) / 8); + result = m_FB.Capacity(PCM::CalcFrameBufferSize(m_ADesc)); + } + + return result; +} + +// +ASDCP::AtmosSyncDataProvider::AtmosSyncDataProvider(const ui16_t bitsPerSample, const ui32_t sampleRate, + const ASDCP::Rational& editRate, const byte_t* uuid) + : m_Generator(bitsPerSample, sampleRate, editRate, uuid), m_FB(), m_ADesc(), m_SampleSize() +{ + m_Generator.FillAudioDescriptor(m_ADesc); + m_SampleSize = PCM::CalcSampleSize(m_ADesc); + m_FB.Capacity(PCM::CalcFrameBufferSize(m_ADesc)); +} + +ASDCP::AtmosSyncDataProvider::~AtmosSyncDataProvider() +{} + +Result_t +ASDCP::AtmosSyncDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten) +{ + ASDCP_TEST_NULL(buf); + ASDCP_TEST_NULL(m_ptr); + if ( numChannels > m_ADesc.ChannelCount) + { + DefaultLogSink().Error("Requested %u channels from a wav file with %u channel.", numChannels, + m_ADesc.ChannelCount); + return RESULT_FAIL; + } + + (*bytesWritten) = m_SampleSize; + ::memcpy(buf, m_ptr, m_SampleSize); + m_ptr += m_SampleSize; + return RESULT_OK; +} + +Result_t +ASDCP::AtmosSyncDataProvider::ReadFrame() +{ + Result_t result = m_Generator.ReadFrame(m_FB); + m_ptr = ASDCP_SUCCESS(result) ? m_FB.RoData() : NULL; + return result; +} + +Result_t +ASDCP::AtmosSyncDataProvider::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const +{ + ADesc = m_ADesc; + return RESULT_OK; +} + +Result_t +ASDCP::AtmosSyncDataProvider::Reset() +{ + return m_Generator.Reset(); +} + +// +ASDCP::SilenceDataProvider::SilenceDataProvider(const ui16_t numChannels, const ui16_t bitsPerSample, + const ui32_t sampleRate, const ASDCP::Rational& editRate) + : m_ADesc(), m_SampleSize(0) +{ + m_SampleSize = ((bitsPerSample + 7) / 8); + m_ADesc.EditRate = editRate; + m_ADesc.AudioSamplingRate = Rational(sampleRate, 1); + m_ADesc.ChannelCount = numChannels; + m_ADesc.QuantizationBits = bitsPerSample; + m_ADesc.BlockAlign = numChannels * m_SampleSize; + m_ADesc.AvgBps = sampleRate * m_ADesc.BlockAlign; +} + +ASDCP::SilenceDataProvider::~SilenceDataProvider() +{} + +Result_t +ASDCP::SilenceDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten) +{ + ASDCP_TEST_NULL(buf); + if ( numChannels > m_ADesc.ChannelCount) + { + DefaultLogSink().Error("Requested %u channels from a wav file with %u channel.", numChannels, + m_ADesc.ChannelCount); + return RESULT_FAIL; + } + (*bytesWritten) = m_SampleSize * numChannels; + ::memset(buf, 0, (*bytesWritten)); + return RESULT_OK; +} + +Result_t +ASDCP::SilenceDataProvider::ReadFrame() +{ + // no op + return RESULT_OK; +} + +Result_t +ASDCP::SilenceDataProvider::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const +{ + ADesc = m_ADesc; + return RESULT_OK; +} + +Result_t +ASDCP::SilenceDataProvider::Reset() +{ + //no op + return RESULT_OK; +} diff --git a/asdcplib/src/PCMDataProviders.h b/asdcplib/src/PCMDataProviders.h new file mode 100644 index 00000000..960f87ae --- /dev/null +++ b/asdcplib/src/PCMDataProviders.h @@ -0,0 +1,119 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file PCMDataProviders.h + \version $Id: PCMDataProviders.h,v 1.1 2013/04/12 23:39:31 mikey Exp $ + \brief PCM sample data providers for WAV, AtmosSync and Silence. +*/ + +#ifndef _PCMDATAPROVIDERS_H_ +#define _PCMDATAPROVIDERS_H_ + +#include <AS_DCP.h> +#include <AtmosSyncChannel_Generator.h> + +namespace ASDCP +{ + + // PCM Data Provider Interface + class PCMDataProviderInterface + { + ASDCP_NO_COPY_CONSTRUCT(PCMDataProviderInterface); + + public: + PCMDataProviderInterface() {}; + virtual ~PCMDataProviderInterface() = 0; + virtual Result_t PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten) = 0; + virtual Result_t ReadFrame() = 0; + virtual Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const = 0; + virtual Result_t Reset() = 0; + }; + + // WAV file implementation of the PCM Data Provider Interface + class WAVDataProvider : public PCMDataProviderInterface + { + ASDCP_NO_COPY_CONSTRUCT(WAVDataProvider); + PCM::WAVParser m_Parser; + PCM::FrameBuffer m_FB; + PCM::AudioDescriptor m_ADesc; + const byte_t* m_ptr; + ui32_t m_SampleSize; + + public: + WAVDataProvider(); + virtual ~WAVDataProvider(); + virtual Result_t PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten); + virtual Result_t ReadFrame(); + virtual Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; + virtual Result_t Reset(); + Result_t OpenRead(const char* filename, const Rational& PictureRate); + + }; + + // Atmos Sync Channel implementation of the PCM Data Provider Interface + class AtmosSyncDataProvider : public PCMDataProviderInterface + { + ASDCP_NO_COPY_CONSTRUCT(AtmosSyncDataProvider); + PCM::AtmosSyncChannelGenerator m_Generator; + PCM::FrameBuffer m_FB; + PCM::AudioDescriptor m_ADesc; + const byte_t* m_ptr; + ui32_t m_SampleSize; + + public: + AtmosSyncDataProvider(const ui16_t bitsPerSample, const ui32_t sampleRate, + const ASDCP::Rational& PictureRate, const byte_t* uuid); + virtual ~AtmosSyncDataProvider(); + virtual Result_t PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten); + virtual Result_t ReadFrame(); + virtual Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; + virtual Result_t Reset(); + }; + + // Silence Channel(s) implementation of the PCM Data Provider Interface + class SilenceDataProvider : public PCMDataProviderInterface + { + ASDCP_NO_COPY_CONSTRUCT(SilenceDataProvider); + PCM::AudioDescriptor m_ADesc; + ui32_t m_SampleSize; + + public: + SilenceDataProvider(const ui16_t numChannels, const ui16_t bitsPerSample, + const ui32_t sampleRate, const ASDCP::Rational& editRate); + virtual ~SilenceDataProvider(); + virtual Result_t PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten); + virtual Result_t ReadFrame(); + virtual Result_t FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const; + virtual Result_t Reset(); + }; + +} // namespace ASDCP + +#endif // _PCMDATAPROVIDERS_H_ + +// +// end PCMDataProviders.h +// diff --git a/asdcplib/src/PCMParserList.cpp b/asdcplib/src/PCMParserList.cpp index 444b8838..ee5dd3ec 100755 --- a/asdcplib/src/PCMParserList.cpp +++ b/asdcplib/src/PCMParserList.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file PCMParserList.cpp - \version $Id: PCMParserList.cpp,v 1.9 2012/02/21 02:09:31 jhurst Exp $ + \version $Id: PCMParserList.cpp,v 1.12 2015/02/19 19:06:57 jhurst Exp $ \brief Read WAV file(s), multiplex multiple PCM frame buffers into one */ @@ -48,10 +48,8 @@ ASDCP::ParserInstance::~ParserInstance() // PCM::CalcSampleSize(ADesc); Result_t -ASDCP::ParserInstance::OpenRead(const char* filename, const Rational& PictureRate) +ASDCP::ParserInstance::OpenRead(const std::string& filename, const Rational& PictureRate) { - ASDCP_TEST_NULL_STR(filename); - Result_t result = Parser.OpenRead(filename, PictureRate); if ( ASDCP_SUCCESS(result) ) @@ -74,11 +72,18 @@ ASDCP::ParserInstance::PutSample(byte_t* p) { ASDCP_TEST_NULL(p); - memcpy(p, m_p, m_SampleSize); - m_p += m_SampleSize; - return RESULT_OK; -} + if ( m_p != 0 ) + { + if ( m_p < ( FB.RoData() + FB.Size() ) ) + { + memcpy(p, m_p, m_SampleSize); + m_p += m_SampleSize; + return RESULT_OK; + } + } + return RESULT_ENDOFFILE; +} // Result_t @@ -112,11 +117,14 @@ ASDCP::PCMParserList::~PCMParserList() Result_t ASDCP::PCMParserList::OpenRead(ui32_t argc, const char** argv, const Rational& PictureRate) { - ASDCP_TEST_NULL_STR(argv); + ASDCP_TEST_NULL(argv); PathList_t TmpFileList; for ( ui32_t i = 0; i < argc; ++i ) - TmpFileList.push_back(argv[i]); + { + ASDCP_TEST_NULL(argv[i]); + TmpFileList.push_back(argv[i]); + } return OpenRead(TmpFileList, PictureRate); } @@ -246,21 +254,23 @@ ASDCP::PCMParserList::ReadFrame(PCM::FrameBuffer& OutFB) Result_t result = RESULT_OK; if ( size() == 1 ) - return front()->Parser.ReadFrame(OutFB); + { + return front()->Parser.ReadFrame(OutFB); + } PCMParserList::iterator self_i; assert(PCM::CalcFrameBufferSize(m_ADesc) <= OutFB.Capacity()); for ( self_i = begin(); self_i != end() && ASDCP_SUCCESS(result) ; self_i++ ) - result = (*self_i)->ReadFrame(); + { + result = (*self_i)->ReadFrame(); + } if ( ASDCP_SUCCESS(result) ) { - OutFB.Size(PCM::CalcFrameBufferSize(m_ADesc)); - - // ui32_t sample_size = (PCM::CalcSampleSize(m_ADesc)); byte_t* Out_p = OutFB.Data(); - byte_t* End_p = Out_p + OutFB.Size(); + byte_t* End_p = Out_p + OutFB.Capacity(); + ui64_t total_sample_bytes = 0; while ( Out_p < End_p && ASDCP_SUCCESS(result) ) { @@ -269,12 +279,22 @@ ASDCP::PCMParserList::ReadFrame(PCM::FrameBuffer& OutFB) while ( self_i != end() && ASDCP_SUCCESS(result) ) { result = (*self_i)->PutSample(Out_p); - Out_p += (*self_i)->SampleSize(); - self_i++; + + if ( ASDCP_SUCCESS(result) ) + { + Out_p += (*self_i)->SampleSize(); + total_sample_bytes += (*self_i)->SampleSize(); + self_i++; + } } } - assert(Out_p == End_p); + OutFB.Size(total_sample_bytes); + + if ( result == RESULT_ENDOFFILE ) + { + result = RESULT_OK; + } } return result; diff --git a/asdcplib/src/PCMParserList.h b/asdcplib/src/PCMParserList.h index b7445311..71122699 100755 --- a/asdcplib/src/PCMParserList.h +++ b/asdcplib/src/PCMParserList.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2013, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file PCMParserList.h - \version $Id: PCMParserList.h,v 1.4 2012/02/03 19:49:56 jhurst Exp $ + \version $Id: PCMParserList.h,v 1.5 2014/01/02 23:29:22 jhurst Exp $ \brief Read WAV file(s), multiplex multiple PCM frame buffers into one */ @@ -54,7 +54,7 @@ namespace ASDCP ParserInstance(); virtual ~ParserInstance(); - Result_t OpenRead(const char* filename, const Rational& PictureRate); + Result_t OpenRead(const std::string& filename, const Rational& PictureRate); Result_t PutSample(byte_t* p); Result_t ReadFrame(); inline ui32_t SampleSize() { return m_SampleSize; } diff --git a/asdcplib/src/PCM_Parser.cpp b/asdcplib/src/PCM_Parser.cpp index e5563413..c5f743fe 100755 --- a/asdcplib/src/PCM_Parser.cpp +++ b/asdcplib/src/PCM_Parser.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file PCM_Parser.cpp - \version $Id: PCM_Parser.cpp,v 1.7 2011/05/13 01:50:19 jhurst Exp $ + \version $Id: PCM_Parser.cpp,v 1.10 2015/02/19 19:06:57 jhurst Exp $ \brief AS-DCP library, PCM raw essence reader implementation */ @@ -37,6 +37,7 @@ using Kumu::DefaultLogSink; using namespace ASDCP; using namespace ASDCP::PCM; using namespace ASDCP::Wav; +using namespace ASDCP::RF64; //------------------------------------------------------------------------------------------ @@ -47,8 +48,8 @@ class ASDCP::PCM::WAVParser::h__WAVParser Kumu::FileReader m_FileReader; bool m_EOF; ui32_t m_DataStart; - ui32_t m_DataLength; - ui32_t m_ReadCount; + ui64_t m_DataLength; + ui64_t m_ReadCount; ui32_t m_FrameBufferSize; ui32_t m_FramesRead; Rational m_PictureRate; @@ -68,7 +69,7 @@ public: Close(); } - Result_t OpenRead(const char* filename, const Rational& PictureRate); + Result_t OpenRead(const std::string& filename, const Rational& PictureRate); void Close(); void Reset(); Result_t ReadFrame(FrameBuffer&); @@ -93,10 +94,8 @@ ASDCP::PCM::WAVParser::h__WAVParser::Reset() // ASDCP::Result_t -ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const char* filename, const Rational& PictureRate) +ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const std::string& filename, const Rational& PictureRate) { - ASDCP_TEST_NULL_STR(filename); - Result_t result = m_FileReader.OpenRead(filename); if ( ASDCP_SUCCESS(result) ) @@ -129,6 +128,22 @@ ASDCP::PCM::WAVParser::h__WAVParser::OpenRead(const char* filename, const Ration m_ADesc.ChannelFormat = PCM::CF_NONE; Reset(); } + else + { + SimpleRF64Header RF64Header; + m_FileReader.Seek(0); + result = RF64Header.ReadFromFile(m_FileReader, &m_DataStart); + + if ( ASDCP_SUCCESS(result) ) + { + RF64Header.FillADesc(m_ADesc, PictureRate); + m_FrameBufferSize = ASDCP::PCM::CalcFrameBufferSize(m_ADesc); + m_DataLength = RF64Header.data_len; + m_ADesc.ContainerDuration = m_DataLength / m_FrameBufferSize; + m_ADesc.ChannelFormat = PCM::CF_NONE; + Reset(); + } + } } } @@ -141,8 +156,10 @@ ASDCP::PCM::WAVParser::h__WAVParser::ReadFrame(FrameBuffer& FB) { FB.Size(0); - if ( m_EOF || m_ReadCount >= m_DataLength ) - return RESULT_ENDOFFILE; + if ( m_EOF ) + { + return RESULT_ENDOFFILE; + } if ( FB.Capacity() < m_FrameBufferSize ) { @@ -159,7 +176,9 @@ ASDCP::PCM::WAVParser::h__WAVParser::ReadFrame(FrameBuffer& FB) m_EOF = true; if ( read_count > 0 ) - result = RESULT_OK; + { + result = RESULT_OK; + } } if ( ASDCP_SUCCESS(result) ) @@ -167,6 +186,11 @@ ASDCP::PCM::WAVParser::h__WAVParser::ReadFrame(FrameBuffer& FB) m_ReadCount += read_count; FB.Size(read_count); FB.FrameNumber(m_FramesRead++); + + if ( read_count < FB.Capacity() ) + { + memset(FB.Data() + FB.Size(), 0, FB.Capacity() - FB.Size()); + } } return result; @@ -186,7 +210,7 @@ ASDCP::PCM::WAVParser::~WAVParser() // Opens the stream for reading, parses enough data to provide a complete // set of stream metadata for the MXFWriter below. ASDCP::Result_t -ASDCP::PCM::WAVParser::OpenRead(const char* filename, const Rational& PictureRate) const +ASDCP::PCM::WAVParser::OpenRead(const std::string& filename, const Rational& PictureRate) const { const_cast<ASDCP::PCM::WAVParser*>(this)->m_Parser = new h__WAVParser; diff --git a/asdcplib/src/PHDR_Sequence_Parser.cpp b/asdcplib/src/PHDR_Sequence_Parser.cpp new file mode 100755 index 00000000..1081a745 --- /dev/null +++ b/asdcplib/src/PHDR_Sequence_Parser.cpp @@ -0,0 +1,405 @@ +/* +Copyright (c) 2004-2015, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file PHDR_Sequence_Parser.cpp + \version $Id: PHDR_Sequence_Parser.cpp,v 1.2 2015/01/22 21:05:58 jhurst Exp $ + \brief AS-DCP library, JPEG 2000 codestream essence reader implementation +*/ + +#include <AS_02_PHDR.h> +#include <KM_fileio.h> +#include <KM_log.h> +#include <list> +#include <string> +#include <algorithm> +#include <string.h> +#include <assert.h> + +using namespace Kumu; +using namespace ASDCP; + + +//------------------------------------------------------------------------------------------ + +class FileList : public std::list<std::string> +{ + std::string m_DirName; + +public: + FileList() {} + ~FileList() {} + + const FileList& operator=(const std::list<std::string>& pathlist) { + std::list<std::string>::const_iterator i; + for ( i = pathlist.begin(); i != pathlist.end(); i++ ) + push_back(*i); + return *this; + } + + // + Result_t InitFromDirectory(const std::string& path) + { + char next_file[Kumu::MaxFilePath]; + Kumu::DirScanner Scanner; + + Result_t result = Scanner.Open(path); + + if ( ASDCP_SUCCESS(result) ) + { + m_DirName = path; + + while ( ASDCP_SUCCESS(Scanner.GetNext(next_file)) ) + { + if ( PathGetExtension(next_file) == "j2c" ) + { + std::string path = PathJoin(m_DirName, next_file); + + if ( ! Kumu::PathIsDirectory(path) ) + push_back(path); + } + } + + sort(); + } + + return result; + } +}; + +//------------------------------------------------------------------------------------------ + +class AS_02::PHDR::SequenceParser::h__SequenceParser +{ + ui32_t m_FramesRead; + Rational m_PictureRate; + FileList m_FileList; + FileList::iterator m_CurrentFile; + ASDCP::JP2K::CodestreamParser m_Parser; + bool m_Pedantic; + + Result_t OpenRead(); + + ASDCP_NO_COPY_CONSTRUCT(h__SequenceParser); + +public: + ASDCP::JP2K::PictureDescriptor m_PDesc; + + h__SequenceParser() : m_FramesRead(0), m_Pedantic(false) + { + memset(&m_PDesc, 0, sizeof(m_PDesc)); + m_PDesc.EditRate = Rational(24,1); + } + + ~h__SequenceParser() + { + Close(); + } + + Result_t OpenRead(const std::string& filename, bool pedantic); + Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic); + void Close() {} + + Result_t Reset() + { + m_FramesRead = 0; + m_CurrentFile = m_FileList.begin(); + return RESULT_OK; + } + + Result_t ReadFrame(FrameBuffer&); +}; + + +// +ASDCP::Result_t +AS_02::PHDR::SequenceParser::h__SequenceParser::OpenRead() +{ + if ( m_FileList.empty() ) + return RESULT_ENDOFFILE; + + m_CurrentFile = m_FileList.begin(); + ASDCP::JP2K::CodestreamParser Parser; + AS_02::PHDR::FrameBuffer TmpBuffer; + + Kumu::fsize_t file_size = Kumu::FileSize(*m_CurrentFile); + + if ( file_size == 0 ) + return RESULT_NOT_FOUND; + + assert(file_size <= 0xFFFFFFFFL); + Result_t result = TmpBuffer.Capacity((ui32_t) file_size); + + if ( ASDCP_SUCCESS(result) ) + result = Parser.OpenReadFrame(*m_CurrentFile, TmpBuffer); + + if ( ASDCP_SUCCESS(result) ) + result = Parser.FillPictureDescriptor(m_PDesc); + + // how big is it? + if ( ASDCP_SUCCESS(result) ) + m_PDesc.ContainerDuration = m_FileList.size(); + + return result; +} + +// +ASDCP::Result_t +AS_02::PHDR::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename, bool pedantic) +{ + m_Pedantic = pedantic; + + Result_t result = m_FileList.InitFromDirectory(filename); + + if ( ASDCP_SUCCESS(result) ) + result = OpenRead(); + + return result; +} + + +// +ASDCP::Result_t +AS_02::PHDR::SequenceParser::h__SequenceParser::OpenRead(const std::list<std::string>& file_list, bool pedantic) +{ + m_Pedantic = pedantic; + m_FileList = file_list; + return OpenRead(); +} + + +// +bool +operator==(const ASDCP::JP2K::ImageComponent_t& lhs, const ASDCP::JP2K::ImageComponent_t& rhs) +{ + if ( lhs.Ssize != rhs.Ssize ) return false; + if ( lhs.XRsize != rhs.XRsize ) return false; + if ( lhs.YRsize != rhs.YRsize ) return false; + return true; +} + +// +bool +operator==(const ASDCP::JP2K::QuantizationDefault_t& lhs, const ASDCP::JP2K::QuantizationDefault_t& rhs) +{ + if ( lhs.Sqcd != rhs.Sqcd ) return false; + if ( lhs.SPqcdLength != rhs.SPqcdLength ) return false; + + for ( ui32_t i = 0; i < JP2K::MaxDefaults; i++ ) + { + if ( lhs.SPqcd[i] != rhs.SPqcd[i] ) + return false; + } + + return true; +} + +// +bool +operator==(const ASDCP::JP2K::CodingStyleDefault_t& lhs, const ASDCP::JP2K::CodingStyleDefault_t& rhs) +{ + if ( lhs.Scod != rhs.Scod ) return false; + + // SGcod + if ( lhs.SGcod.ProgressionOrder != rhs.SGcod.ProgressionOrder ) return false; + if ( lhs.SGcod.MultiCompTransform != rhs.SGcod.MultiCompTransform ) return false; + + for ( ui32_t i = 0; i < sizeof(ui16_t); i++ ) + { + if ( lhs.SGcod.NumberOfLayers[i] != lhs.SGcod.NumberOfLayers[i] ) + return false; + } + + // SPcod + if ( lhs.SPcod.DecompositionLevels != rhs.SPcod.DecompositionLevels ) return false; + if ( lhs.SPcod.CodeblockWidth != rhs.SPcod.CodeblockWidth ) return false; + if ( lhs.SPcod.CodeblockHeight != rhs.SPcod.CodeblockHeight ) return false; + if ( lhs.SPcod.CodeblockStyle != rhs.SPcod.CodeblockStyle ) return false; + if ( lhs.SPcod.Transformation != rhs.SPcod.Transformation ) return false; + + for ( ui32_t i = 0; i < JP2K::MaxPrecincts; i++ ) + { + if ( lhs.SPcod.PrecinctSize[i] != rhs.SPcod.PrecinctSize[i] ) + return false; + } + + return true; +} + +// +bool +operator==(const ASDCP::JP2K::PictureDescriptor& lhs, const ASDCP::JP2K::PictureDescriptor& rhs) +{ + if ( lhs.EditRate != rhs.EditRate ) return false; + // if ( lhs.ContainerDuration != rhs.ContainerDuration ) return false; + if ( lhs.SampleRate != rhs.SampleRate ) return false; + if ( lhs.StoredWidth != rhs.StoredWidth ) return false; + if ( lhs.StoredHeight != rhs.StoredHeight ) return false; + if ( lhs.AspectRatio != rhs.AspectRatio ) return false; + if ( lhs.Rsize != rhs.Rsize ) return false; + if ( lhs.Xsize != rhs.Xsize ) return false; + if ( lhs.Ysize != rhs.Ysize ) return false; + if ( lhs.XOsize != rhs.XOsize ) return false; + if ( lhs.YOsize != rhs.YOsize ) return false; + if ( lhs.XTsize != rhs.XTsize ) return false; + if ( lhs.YTsize != rhs.YTsize ) return false; + if ( lhs.XTOsize != rhs.XTOsize ) return false; + if ( lhs.YTOsize != rhs.YTOsize ) return false; + if ( lhs.Csize != rhs.Csize ) return false; + if ( ! ( lhs.CodingStyleDefault == rhs.CodingStyleDefault ) ) return false; + if ( ! ( lhs.QuantizationDefault == rhs.QuantizationDefault ) ) return false; + + for ( ui32_t i = 0; i < JP2K::MaxComponents; i++ ) + { + if ( ! ( lhs.ImageComponents[i] == rhs.ImageComponents[i] ) ) + return false; + } + + return true; +} + +// +ASDCP::Result_t +AS_02::PHDR::SequenceParser::h__SequenceParser::ReadFrame(FrameBuffer& FB) +{ + if ( m_CurrentFile == m_FileList.end() ) + return RESULT_ENDOFFILE; + + // open the file + Result_t result = m_Parser.OpenReadFrame(*m_CurrentFile, FB); + std::string metadata_path = PathJoin(PathDirname(*m_CurrentFile), PathSetExtension(*m_CurrentFile, "xml")); + + if ( KM_SUCCESS(result) ) + { + result = ReadFileIntoString(metadata_path, FB.OpaqueMetadata); + + if ( KM_FAILURE(result) ) + { + DefaultLogSink().Error("%s: %s\n", metadata_path.c_str(), result.Label()); + } + } + else + { + DefaultLogSink().Error("%s: %s\n", m_CurrentFile->c_str(), result.Label()); + } + + if ( KM_SUCCESS(result) && m_Pedantic ) + { + ASDCP::JP2K::PictureDescriptor PDesc; + result = m_Parser.FillPictureDescriptor(PDesc); + + if ( KM_SUCCESS(result) && ! ( m_PDesc == PDesc ) ) + { + Kumu::DefaultLogSink().Error("JPEG-2000 codestream parameters do not match at frame %d\n", m_FramesRead + 1); + result = RESULT_RAW_FORMAT; + } + } + + if ( KM_SUCCESS(result) ) + { + FB.FrameNumber(m_FramesRead++); + m_CurrentFile++; + } + + return result; +} + + +//------------------------------------------------------------------------------------------ + +AS_02::PHDR::SequenceParser::SequenceParser() +{ +} + +AS_02::PHDR::SequenceParser::~SequenceParser() +{ +} + +// Opens the stream for reading, parses enough data to provide a complete +// set of stream metadata for the MXFWriter below. +ASDCP::Result_t +AS_02::PHDR::SequenceParser::OpenRead(const std::string& filename, bool pedantic) const +{ + const_cast<AS_02::PHDR::SequenceParser*>(this)->m_Parser = new h__SequenceParser; + + Result_t result = m_Parser->OpenRead(filename, pedantic); + + if ( ASDCP_FAILURE(result) ) + const_cast<AS_02::PHDR::SequenceParser*>(this)->m_Parser.release(); + + return result; +} + +// +Result_t +AS_02::PHDR::SequenceParser::OpenRead(const std::list<std::string>& file_list, bool pedantic) const +{ + const_cast<AS_02::PHDR::SequenceParser*>(this)->m_Parser = new h__SequenceParser; + + Result_t result = m_Parser->OpenRead(file_list, pedantic); + + if ( ASDCP_FAILURE(result) ) + const_cast<AS_02::PHDR::SequenceParser*>(this)->m_Parser.release(); + + return result; +} + + +// Rewinds the stream to the beginning. +ASDCP::Result_t +AS_02::PHDR::SequenceParser::Reset() const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + return m_Parser->Reset(); +} + +// Places a frame of data in the frame buffer. Fails if the buffer is too small +// or the stream is empty. +ASDCP::Result_t +AS_02::PHDR::SequenceParser::ReadFrame(AS_02::PHDR::FrameBuffer& FB) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + return m_Parser->ReadFrame(FB); +} + +// +ASDCP::Result_t +AS_02::PHDR::SequenceParser::FillPictureDescriptor(ASDCP::JP2K::PictureDescriptor& PDesc) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + PDesc = m_Parser->m_PDesc; + return RESULT_OK; +} + + +// +// end PHDR_Sequence_Parser.cpp +// diff --git a/asdcplib/src/S12MTimecode.h b/asdcplib/src/S12MTimecode.h index 7e355a6c..6abd09b1 100644 --- a/asdcplib/src/S12MTimecode.h +++ b/asdcplib/src/S12MTimecode.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2007-2009, John Hurst +Copyright (c) 2007-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file S12MTimecode.cpp - \version $Id: S12MTimecode.h,v 1.5 2009/04/09 19:24:14 msheby Exp $ + \version $Id: S12MTimecode.h,v 1.6 2014/09/21 13:27:43 jhurst Exp $ \brief AS-DCP library, Timecode PCM essence reader and writer implementation */ @@ -106,10 +106,10 @@ public: if ( *p != 0 ) { - ui32_t hours = atoi(p); - ui32_t minutes = atoi(p+3); - ui32_t seconds = atoi(p+6); - ui32_t frames = atoi(p+9); + ui32_t hours = strtol(p, 0, 10); + ui32_t minutes = strtol(p+3, 0, 10); + ui32_t seconds = strtol(p+6, 0, 10); + ui32_t frames = strtol(p+9, 0, 10); m_FrameCount = (((((hours * 60) + minutes) * 60) + seconds) * m_FPS)+ frames; } diff --git a/asdcplib/src/ST2052_TextParser.cpp b/asdcplib/src/ST2052_TextParser.cpp new file mode 100644 index 00000000..b5d7fe6d --- /dev/null +++ b/asdcplib/src/ST2052_TextParser.cpp @@ -0,0 +1,498 @@ +/* +Copyright (c) 2013-2015, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file ST2052_TimedText.cpp + \version $Id: ST2052_TextParser.cpp,v 1.4 2015/10/07 16:41:23 jhurst Exp $ + \brief AS-DCP library, PCM essence reader and writer implementation +*/ + + +#include "AS_02_internal.h" +#include "KM_xml.h" +#include <openssl/sha.h> + +using namespace Kumu; +using namespace ASDCP; + +using Kumu::DefaultLogSink; + +const char* c_tt_namespace_name = "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"; + + +//------------------------------------------------------------------------------------------ + +// +int const NS_ID_LENGTH = 16; + +// +static byte_t s_png_id_prefix[NS_ID_LENGTH] = { + // RFC 4122 type 5 + // 2067-2 5.4.5 / RFC4122 Appendix C + 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 +}; + +// +static byte_t s_font_id_prefix[NS_ID_LENGTH] = { + // RFC 4122 type 5 + // 2067-2 5.4.6 + 0xb6, 0xcc, 0x57, 0xa0, 0x87, 0xe7, 0x4e, 0x75, + 0xb1, 0xc3, 0x33, 0x59, 0xf3, 0xae, 0x88, 0x17 +}; + +// +static Kumu::UUID +create_4122_type5_id(const std::string& subject_name, const byte_t* ns_id) +{ + SHA_CTX ctx; + SHA1_Init(&ctx); + SHA1_Update(&ctx, ns_id, NS_ID_LENGTH); + SHA1_Update(&ctx, (byte_t*)subject_name.c_str(), subject_name.size()); + + const ui32_t sha_len = 20; + byte_t bin_buf[sha_len]; + SHA1_Final(bin_buf, &ctx); + + // Derive the asset ID from the digest. Make it a type-5 UUID + byte_t buf[UUID_Length]; + memcpy(buf, bin_buf, UUID_Length); + buf[6] &= 0x0f; // clear bits 4-7 + buf[6] |= 0x50; // set UUID version 'digest' + buf[8] &= 0x3f; // clear bits 6&7 + buf[8] |= 0x80; // set bit 7 + return Kumu::UUID(buf); +} + +// +static Kumu::UUID +create_png_name_id(const std::string& image_name) +{ + return create_4122_type5_id(image_name, s_png_id_prefix); +} + +// +static Kumu::UUID +create_font_name_id(const std::string& font_name) +{ + return create_4122_type5_id(font_name, s_font_id_prefix); +} + +//------------------------------------------------------------------------------------------ + + +AS_02::TimedText::Type5UUIDFilenameResolver::Type5UUIDFilenameResolver() {} +AS_02::TimedText::Type5UUIDFilenameResolver::~Type5UUIDFilenameResolver() {} + +const byte_t PNGMagic[8] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; +const byte_t OpenTypeMagic[5] = { 0x4f, 0x54, 0x54, 0x4f, 0x00 }; +const byte_t TrueTypeMagic[5] = { 0x00, 0x01, 0x00, 0x00, 0x00 }; + +// +Result_t +AS_02::TimedText::Type5UUIDFilenameResolver::OpenRead(const std::string& dirname) +{ + DirScannerEx dir_reader; + DirectoryEntryType_t ft; + std::string next_item; + std::string abs_dirname = PathMakeCanonical(dirname); + byte_t read_buffer[16]; + + if ( abs_dirname.empty() ) + { + abs_dirname = "."; + } + + Result_t result = dir_reader.Open(abs_dirname); + + if ( KM_SUCCESS(result) ) + { + while ( KM_SUCCESS(dir_reader.GetNext(next_item, ft)) ) + { + if ( next_item[0] == '.' ) continue; // no hidden files + std::string tmp_path = PathJoin(abs_dirname, next_item); + + if ( ft == DET_FILE ) + { + FileReader reader; + Result_t read_result = reader.OpenRead(tmp_path); + + if ( KM_SUCCESS(read_result) ) + { + read_result = reader.Read(read_buffer, 16); + } + + if ( KM_SUCCESS(read_result) ) + { + // is it PNG? + if ( memcmp(read_buffer, PNGMagic, sizeof(PNGMagic)) == 0 ) + { + UUID asset_id = create_png_name_id(next_item); + m_ResourceMap.insert(ResourceMap::value_type(asset_id, next_item)); + } + // is it a font? + else if ( memcmp(read_buffer, OpenTypeMagic, sizeof(OpenTypeMagic)) == 0 + || memcmp(read_buffer, TrueTypeMagic, sizeof(TrueTypeMagic)) == 0 ) + { + fprintf(stderr, "wrap font!\n"); + UUID asset_id = create_font_name_id(next_item); + m_ResourceMap.insert(ResourceMap::value_type(asset_id, next_item)); + } + } + } + } + } + + return result; +} + +// +Result_t +AS_02::TimedText::Type5UUIDFilenameResolver::ResolveRID(const byte_t* uuid, ASDCP::TimedText::FrameBuffer& FrameBuf) const +{ + Kumu::UUID tmp_id(uuid); + char buf[64]; + + ResourceMap::const_iterator i = m_ResourceMap.find(tmp_id); + + if ( i == m_ResourceMap.end() ) + { + DefaultLogSink().Debug("Missing timed-text resource \"%s\"\n", tmp_id.EncodeHex(buf, 64)); + return RESULT_NOT_FOUND; + } + + FileReader Reader; + + DefaultLogSink().Debug("Retrieving resource %s from file %s\n", tmp_id.EncodeHex(buf, 64), i->second.c_str()); + + Result_t result = Reader.OpenRead(i->second.c_str()); + + if ( KM_SUCCESS(result) ) + { + ui32_t read_count, read_size = Reader.Size(); + result = FrameBuf.Capacity(read_size); + + if ( KM_SUCCESS(result) ) + result = Reader.Read(FrameBuf.Data(), read_size, &read_count); + + if ( KM_SUCCESS(result) ) + FrameBuf.Size(read_count); + } + + return result; +} + +//------------------------------------------------------------------------------------------ + +typedef std::map<Kumu::UUID, ASDCP::TimedText::MIMEType_t> ResourceTypeMap_t; + +class AS_02::TimedText::ST2052_TextParser::h__TextParser +{ + XMLElement m_Root; + ResourceTypeMap_t m_ResourceTypes; + Result_t OpenRead(); + + ASDCP_NO_COPY_CONSTRUCT(h__TextParser); + +public: + std::string m_Filename; + std::string m_XMLDoc; + TimedTextDescriptor m_TDesc; + ASDCP::mem_ptr<ASDCP::TimedText::IResourceResolver> m_DefaultResolver; + + h__TextParser() : m_Root("**ParserRoot**") + { + memset(&m_TDesc.AssetID, 0, UUIDlen); + } + + ~h__TextParser() {} + + ASDCP::TimedText::IResourceResolver* GetDefaultResolver() + { + if ( m_DefaultResolver.empty() ) + { + AS_02::TimedText::Type5UUIDFilenameResolver *resolver = new AS_02::TimedText::Type5UUIDFilenameResolver; + resolver->OpenRead(PathDirname(m_Filename)); + m_DefaultResolver = resolver; + } + + return m_DefaultResolver; + } + + Result_t OpenRead(const std::string& filename); + Result_t OpenRead(const std::string& xml_doc, const std::string& filename); + Result_t ReadAncillaryResource(const byte_t *uuid, ASDCP::TimedText::FrameBuffer& FrameBuf, + const ASDCP::TimedText::IResourceResolver& Resolver) const; +}; + +// +Result_t +AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string& filename) +{ + Result_t result = ReadFileIntoString(filename, m_XMLDoc); + + if ( KM_SUCCESS(result) ) + { + m_Filename = filename; + result = OpenRead(); + } + + return result; +} + +// +Result_t +AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead(const std::string& xml_doc, const std::string& filename) +{ + m_XMLDoc = xml_doc; + m_Filename = filename; + return OpenRead(); +} + +// +template <class VisitorType> +bool +apply_visitor(const XMLElement& element, VisitorType& visitor) +{ + const ElementList& l = element.GetChildren(); + ElementList::const_iterator i; + + for ( i = l.begin(); i != l.end(); ++i ) + { + if ( ! visitor.Element(**i) ) + { + return false; + } + + if ( ! apply_visitor(**i, visitor) ) + { + return false; + } + } + + return true; +} + +// +class AttributeVisitor +{ + std::string attr_name; + +public: + AttributeVisitor(const std::string& n) : attr_name(n) {} + std::set<std::string> value_list; + + bool Element(const XMLElement& e) + { + const AttributeList& l = e.GetAttributes(); + AttributeList::const_iterator i; + + for ( i = l.begin(); i != l.end(); ++i ) + { + if ( i->name == attr_name ) + { + value_list.insert(i->value); + } + } + + return true; + } +}; + +// +Result_t +AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead() +{ + if ( ! m_Root.ParseString(m_XMLDoc.c_str()) ) + { + return RESULT_FORMAT; + } + + m_TDesc.EncodingName = "UTF-8"; // the XML parser demands UTF-8 + m_TDesc.ResourceList.clear(); + m_TDesc.ContainerDuration = 0; + const XMLNamespace* ns = m_Root.Namespace(); + + if ( ns == 0 ) + { + DefaultLogSink(). Warn("Document has no namespace name, assuming %s\n", c_tt_namespace_name); + m_TDesc.NamespaceName = c_tt_namespace_name; + } + else + { + m_TDesc.NamespaceName = ns->Name(); + } + + AttributeVisitor png_visitor("backgroundImage"); + apply_visitor(m_Root, png_visitor); + std::set<std::string>::const_iterator i; + + for ( i = png_visitor.value_list.begin(); i != png_visitor.value_list.end(); ++i ) + { + UUID asset_id = create_png_name_id(*i); + TimedTextResourceDescriptor png_resource; + memcpy(png_resource.ResourceID, asset_id.Value(), UUIDlen); + png_resource.Type = ASDCP::TimedText::MT_PNG; + m_TDesc.ResourceList.push_back(png_resource); + m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(png_resource.ResourceID), + ASDCP::TimedText::MT_PNG)); + } + + AttributeVisitor font_visitor("fontFamily"); + apply_visitor(m_Root, font_visitor); + + for ( i = font_visitor.value_list.begin(); i != font_visitor.value_list.end(); ++i ) + { + UUID font_id = create_font_name_id(*i); + TimedTextResourceDescriptor font_resource; + memcpy(font_resource.ResourceID, font_id.Value(), UUIDlen); + font_resource.Type = ASDCP::TimedText::MT_OPENTYPE; + m_TDesc.ResourceList.push_back(font_resource); + m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(font_resource.ResourceID), + ASDCP::TimedText::MT_OPENTYPE)); + } + + return RESULT_OK; +} + +// +Result_t +AS_02::TimedText::ST2052_TextParser::h__TextParser::ReadAncillaryResource(const byte_t* uuid, ASDCP::TimedText::FrameBuffer& FrameBuf, + const ASDCP::TimedText::IResourceResolver& Resolver) const +{ + FrameBuf.AssetID(uuid); + UUID TmpID(uuid); + char buf[64]; + + ResourceTypeMap_t::const_iterator rmi = m_ResourceTypes.find(TmpID); + + if ( rmi == m_ResourceTypes.end() ) + { + DefaultLogSink().Error("Unknown ancillary resource id: %s\n", TmpID.EncodeHex(buf, 64)); + return RESULT_RANGE; + } + + Result_t result = Resolver.ResolveRID(uuid, FrameBuf); + + if ( KM_SUCCESS(result) ) + { + if ( (*rmi).second == ASDCP::TimedText::MT_PNG ) + { + FrameBuf.MIMEType("image/png"); + } + else if ( (*rmi).second == ASDCP::TimedText::MT_OPENTYPE ) + { + FrameBuf.MIMEType("application/x-font-opentype"); + } + else + { + FrameBuf.MIMEType("application/octet-stream"); + } + } + + return result; +} + + + +//------------------------------------------------------------------------------------------ + +AS_02::TimedText::ST2052_TextParser::ST2052_TextParser() +{ +} + +AS_02::TimedText::ST2052_TextParser::~ST2052_TextParser() +{ +} + +// Opens the stream for reading, parses enough data to provide a complete +// set of stream metadata for the MXFWriter below. +ASDCP::Result_t +AS_02::TimedText::ST2052_TextParser::OpenRead(const std::string& filename) const +{ + const_cast<AS_02::TimedText::ST2052_TextParser*>(this)->m_Parser = new h__TextParser; + + Result_t result = m_Parser->OpenRead(filename); + + if ( ASDCP_FAILURE(result) ) + const_cast<AS_02::TimedText::ST2052_TextParser*>(this)->m_Parser = 0; + + return result; +} + +// Parses an XML document to provide a complete set of stream metadata for the MXFWriter below. +Result_t +AS_02::TimedText::ST2052_TextParser::OpenRead(const std::string& xml_doc, const std::string& filename) const +{ + const_cast<AS_02::TimedText::ST2052_TextParser*>(this)->m_Parser = new h__TextParser; + + Result_t result = m_Parser->OpenRead(xml_doc, filename); + + if ( ASDCP_FAILURE(result) ) + const_cast<AS_02::TimedText::ST2052_TextParser*>(this)->m_Parser = 0; + + return result; +} + +// +ASDCP::Result_t +AS_02::TimedText::ST2052_TextParser::FillTimedTextDescriptor(TimedTextDescriptor& TDesc) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + TDesc = m_Parser->m_TDesc; + return RESULT_OK; +} + +// Reads the complete Timed Text Resource into the given string. +ASDCP::Result_t +AS_02::TimedText::ST2052_TextParser::ReadTimedTextResource(std::string& s) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + s = m_Parser->m_XMLDoc; + return RESULT_OK; +} + +// +ASDCP::Result_t +AS_02::TimedText::ST2052_TextParser::ReadAncillaryResource(const Kumu::UUID& uuid, ASDCP::TimedText::FrameBuffer& FrameBuf, + const ASDCP::TimedText::IResourceResolver* Resolver) const +{ + if ( m_Parser.empty() ) + return RESULT_INIT; + + if ( Resolver == 0 ) + Resolver = m_Parser->GetDefaultResolver(); + + return m_Parser->ReadAncillaryResource(uuid.Value(), FrameBuf, *Resolver); +} + + +// +// end ST2052_TextParser.cpp +// diff --git a/asdcplib/src/ST2095_PinkNoise.cpp b/asdcplib/src/ST2095_PinkNoise.cpp new file mode 100644 index 00000000..a4150589 --- /dev/null +++ b/asdcplib/src/ST2095_PinkNoise.cpp @@ -0,0 +1,184 @@ +/* +Copyright (c) 2015, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file ST2095_PinkNoise.cpp + \version $Id: ST2095_PinkNoise.cpp,v 1.1 2015/10/07 16:43:23 jhurst Exp $ + \brief Pink Noise filter and LCG generator +*/ + +#include "ST2095_PinkNoise.h" + +// +// This file is full of magic numbers. Details behind the +// selection of these values can be found in SMPTE ST 2095-1:2015. +// + +static ui32_t const C_rand_step = 52737; +static float const C_max_ampl_32 = pow(2.0, 31) - 1.0; +static float const C_max_peak = -9.5; // Clipping Threshold in dB FS (+/-1.0 = 0 dB) +static float const C_max_amp = pow(10.0, C_max_peak / 20.0); + + +// +ASDCP::LinearCongruentialGenerator::LinearCongruentialGenerator(const ui32_t sample_rate) : m_Seed(0) +{ + ui32_t samples_per_period = 524288; + + if ( sample_rate > 48000 ) + { + samples_per_period = 1048576; + } + + m_RandMax = samples_per_period - 1; + m_ScaleFactor = 2.0 / float(m_RandMax); +} + +// +float +ASDCP::LinearCongruentialGenerator::GetNextSample() +{ + m_Seed = (1664525 * m_Seed + C_rand_step) & m_RandMax; + float out = float(m_Seed) * m_ScaleFactor - 1.0; + return out; +} + +// +ASDCP::PinkFilter::PinkFilter(const i32_t sample_rate, float high_pass_fc, float low_pass_fc) +{ + // Disaster check: filters in order, low_pass_fc <= Nyquist + assert(high_pass_fc < low_pass_fc); + assert(low_pass_fc < sample_rate / 2.0); + + // Calculate omegaT for matched Z transform highpass filters + const float w0t = 2.0 * M_PI * high_pass_fc / sample_rate; + + // Calculate k for bilinear transform lowpass filters + const float k = tan(( 2.0 * M_PI * low_pass_fc / sample_rate ) / 2.0); + + // precalculate k^2 (makes for a little bit cleaner code) + const float k2 = k * k; + + // Calculate biquad coefficients for bandpass filter components + hp1_a1 = -2.0 * exp(-0.3826835 * w0t) * cos(0.9238795 * w0t); + hp1_a2 = exp(2.0 * -0.3826835 * w0t); + hp1_b0 = (1.0 - hp1_a1 + hp1_a2) / 4.0; + hp1_b1 = -2.0 * hp1_b0; + hp1_b2 = hp1_b0; + + hp2_a1 = -2.0 * exp(-0.9238795 * w0t) * cos(0.3826835 * w0t); + hp2_a2 = exp(2.0 * -0.9238795 * w0t); + hp2_b0 = (1.0 - hp2_a1 + hp2_a2) / 4.0; + hp2_b1 = -2.0 * hp2_b0; + hp2_b2 = hp2_b0; + + lp1_a1 = (2.0 * (k2 - 1.0)) / (k2 + (k / 1.306563) + 1.0); + lp1_a2 = (k2 - (k / 1.306563) + 1.0) / (k2 + (k / 1.306563) + 1.0); + lp1_b0 = k2 / (k2 + (k / 1.306563) + 1.0); + lp1_b1 = 2.0 * lp1_b0; + lp1_b2 = lp1_b0; + + lp2_a1 = (2.0 * (k2 - 1.0)) / (k2 + (k / 0.541196) + 1.0); + lp2_a2 = (k2 - (k / 0.541196) + 1.0) / (k2 + (k / 0.541196) + 1.0); + lp2_b0 = k2 / (k2 + (k / 0.541196) + 1.0); + lp2_b1 = 2.0 * lp2_b0; + lp2_b2 = lp2_b0; + + // Declare delay line variables for bandpass filter and initialize to zero + hp1w1 = hp1w2 = hp2w1 = hp2w2 = 0.0; + lp1w1 = lp1w2 = lp2w1 = lp2w2 = 0.0; + + // Declare delay lines for pink filter network and initialize to zero + lp1 = lp2 = lp3 = lp4 = lp5 = lp6 = 0.0; +} + + +// +float +ASDCP::PinkFilter::GetNextSample(const float white) +{ + // Run pink filter; a parallel network of 1st order LP filters + // Scaled for conventional RNG (need to rescale by sqrt(1/3) for MLS) + lp1 = 0.9994551 * lp1 + 0.00198166688621989 * white; + lp2 = 0.9969859 * lp2 + 0.00263702334184061 * white; + lp3 = 0.9844470 * lp3 + 0.00643213710202331 * white; + lp4 = 0.9161757 * lp4 + 0.01438952538362820 * white; + lp5 = 0.6563399 * lp5 + 0.02698408541064610 * white; + float pink = lp1 + lp2 + lp3 + lp4 + lp5 + lp6 + white * 0.0342675832159306; + lp6 = white * 0.0088766118009356; + + // Run bandpass filter; a series network of 4 biquad filters + // Biquad filters implemented in Direct Form II + float w = pink - hp1_a1 * hp1w1 - hp1_a2 * hp1w2; + pink = hp1_b0 * w + hp1_b1 * hp1w1 + hp1_b2 * hp1w2; + hp1w2 = hp1w1; + hp1w1 = w; + + w = pink - hp2_a1 * hp2w1 - hp2_a2 * hp2w2; + pink = hp2_b0 * w + hp2_b1 * hp2w1 + hp2_b2 * hp2w2; + hp2w2 = hp2w1; + hp2w1 = w; + + w = pink - lp1_a1 * lp1w1 - lp1_a2 * lp1w2; + pink = lp1_b0 * w + lp1_b1 * lp1w1 + lp1_b2 * lp1w2; + lp1w2 = lp1w1; + lp1w1 = w; + + w = pink - lp2_a1 * lp2w1 - lp2_a2 * lp2w2; + pink = lp2_b0 * w + lp2_b1 * lp2w1 + lp2_b2 * lp2w2; + lp2w2 = lp2w1; + lp2w1 = w; + + // Limit peaks to +/-C_max_amp + if ( pink > C_max_amp ) + { + pink = C_max_amp; + } + else if ( pink < -C_max_amp ) + { + pink = -C_max_amp; + } + + return pink; +} + +// +void +ASDCP::ScalePackSample(float sample, byte_t* p, ui32_t word_size) +{ + byte_t tmp_buf[4]; + Kumu::i2p<i32_t>(KM_i32_LE(sample * C_max_ampl_32), tmp_buf); + + switch ( word_size ) + { + case 4: *p++ = tmp_buf[0]; + case 3: *p++ = tmp_buf[1]; + case 2: *p++ = tmp_buf[2]; + case 1: *p++ = tmp_buf[3]; + } +} +// +// end ST2095_PinkNoise.cpp +// diff --git a/asdcplib/src/ST2095_PinkNoise.h b/asdcplib/src/ST2095_PinkNoise.h new file mode 100644 index 00000000..5c32c03a --- /dev/null +++ b/asdcplib/src/ST2095_PinkNoise.h @@ -0,0 +1,113 @@ +/* +Copyright (c) 2015, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file ST2095_PinkNoise.h + \version $Id: ST2095_PinkNoise.h,v 1.1 2015/10/07 16:43:23 jhurst Exp $ + \brief Pink Noise filter and LCG generator +*/ + + +#ifndef _ST2095_PINKNOISE_H_ +#define _ST2095_PINKNOISE_H_ + +#include <KM_fileio.h> +#include <cmath> + +// +// No attempt will be made here to explain the theory of operation of +// this noise source since all of the gory detail can be found in SMPTE +// ST 2095-1:2015. Get your copy from SMPTE today! +// + + +namespace ASDCP +{ + // A source of pseudo-random numbers suitable for use in generating + // noise signals. NOT TO BE USED FOR CRYPTOGRAPHIC FUNCTIONS as its + // output is 100% deterministic. + class LinearCongruentialGenerator + { + ui32_t m_Seed, m_RandMax; + float m_ScaleFactor; + + KM_NO_COPY_CONSTRUCT(LinearCongruentialGenerator); + + public: + + LinearCongruentialGenerator(const ui32_t sample_rate); + float GetNextSample(); + }; + + // + float const PinkFilterHighPassConstant = 10.0; // Hz + float const PinkFilterLowPassConstant = 22400.0; // Hz + + // + class PinkFilter + { + // storage for biquad coefficients for bandpass filter components + float hp1_a1, hp1_a2; + float hp1_b0, hp1_b1, hp1_b2; + float hp2_a1, hp2_a2; + float hp2_b0, hp2_b1, hp2_b2; + float lp1_a1, lp1_a2; + float lp1_b0, lp1_b1, lp1_b2; + float lp2_a1, lp2_a2; + float lp2_b0, lp2_b1, lp2_b2; + + // storage for delay line variables for bandpass filter and initialize to zero + float hp1w1, hp1w2, hp2w1, hp2w2; + float lp1w1, lp1w2, lp2w1, lp2w2; + + // storage for delay lines for pink filter network and initialize to zero + float lp1, lp2, lp3, lp4, lp5, lp6; + + KM_NO_COPY_CONSTRUCT(PinkFilter); + + public: + + PinkFilter(const i32_t SampleRate, const float HpFc, const float LpFc); + + // Using a white noise sample as input, produce a pink noise sample + // having properties as defined by SMPTE ST 2095-1:2015. + float GetNextSample(const float white); + }; + + // Create a little-endian integer audio sample of the sepcified word size + // (1-4 bytes) from the normalized input value, write it to the buffer at p. + void ScalePackSample(float sample, byte_t* p, ui32_t word_size); + + +} // namespace ASDCP + + + +#endif // _ST2095_PINKNOISE_H_ + + +// +// end ST2095_PinkNoise.h +// diff --git a/asdcplib/src/SyncCommon.h b/asdcplib/src/SyncCommon.h new file mode 100644 index 00000000..20df6e85 --- /dev/null +++ b/asdcplib/src/SyncCommon.h @@ -0,0 +1,80 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file SyncCommon.h + \version $Id: SyncCommon.h,v 1.1 2013/04/12 23:39:31 mikey Exp $ + \brief Common elements for ATMOS Sync Channel generation +*/ + +#ifndef _SYNC_COMMON_H_ +#define _SYNC_COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BYTE +typedef unsigned char BYTE; +#endif + +#ifndef USHORT +typedef unsigned short USHORT; +#endif + +#ifndef INT +typedef int INT; +#endif + +#ifndef FLOAT +typedef float FLOAT; +#endif + +#define SYMBOL_RATE (12000) + +#define SYMBOL_LENGTH_48 (4) +#define SYMBOL_LENGTH_96 (8) + +#define SYNC_HEADER (0x4D56) +#define SYNC_HEADER1 (0x4D) +#define SYNC_HEADER2 (0x56) + +#define SYNC_HEADER_BITS (16) +#define FRAME_RATE_BITS (4) +#define RESERVE_BITS (2) +#define UUID_SUB_INDEX_BITS (2) +#define UUID_SUB_BITS (32) +#define FRAME_INDEX_BITS (24) +#define CRC_BITS (16) +#define MESSAGE_TOTAL_BITS (96) +#define MESSAGE_TOTAL_BYTES (12) + +#define MAX_PACKET (32) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/asdcplib/src/SyncEncoder.c b/asdcplib/src/SyncEncoder.c new file mode 100644 index 00000000..b4666991 --- /dev/null +++ b/asdcplib/src/SyncEncoder.c @@ -0,0 +1,346 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file SyncEncoder.c + \version $Id: SyncEncoder.c,v 1.1 2013/04/12 23:39:31 mikey Exp $ + \brief Implementation of Atmos Sync Frame Encoder +*/ + +#include "SyncEncoder.h" +#include "CRC16.h" + +#include <memory.h> + +void ConstructFrame(LPSYNCENCODER pSyncEncoder, + INT iFrameIndex); + +FLOAT SEWriteBits( INT iSampleRate, /* In: Sample rate of signal */ + FLOAT *pfAudioBuffer, /* Out: Audio buffer containing signal */ + INT iBits, /* In: Number of bits to write */ + BYTE *pbyData, /* In: Data to write */ + FLOAT fSymbolPhase); /* In: Symbol phase */ + + + +INT SyncEncoderInit(LPSYNCENCODER pSyncEncoder, /* Out: SYNCENCODER structure to be initialized */ + INT iSampleRate, /* In: Signal sample rate */ + INT iFrameRate, /* In: frame rate */ + LPUUIDINFORMATION pUUID) /* In: UUID */ +{ + pSyncEncoder->iError = SYNC_ENCODER_ERROR_NONE; + + /* Check and set sample rate */ + pSyncEncoder->iSymbolLength = 1; + switch(iSampleRate){ + case 48000: + pSyncEncoder->iSampleRate = iSampleRate; + pSyncEncoder->iSymbolLength = SYMBOL_LENGTH_48; + break; + case 96000: + pSyncEncoder->iSampleRate = iSampleRate; + pSyncEncoder->iSymbolLength = SYMBOL_LENGTH_96; + break; + default: + pSyncEncoder->iError = SYNC_ENCODER_ERROR_INVALID_SR; + }; + + if(pSyncEncoder->iError != SYNC_ENCODER_ERROR_NONE){ + return pSyncEncoder->iError; + } + + /* check and set frame rate */ + switch(iFrameRate){ + case 24: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 0; + pSyncEncoder->iPacketsPerFrame = 4; + break; + case 25: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 1; + pSyncEncoder->iPacketsPerFrame = 4; + break; + case 30: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 2; + pSyncEncoder->iPacketsPerFrame = 4; + break; + case 48: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 3; + pSyncEncoder->iPacketsPerFrame = 2; + break; + case 50: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 4; + pSyncEncoder->iPacketsPerFrame = 2; + break; + case 60: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 5; + pSyncEncoder->iPacketsPerFrame = 2; + break; + case 96: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 6; + pSyncEncoder->iPacketsPerFrame = 1; + break; + case 100: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 7; + pSyncEncoder->iPacketsPerFrame = 1; + break; + case 120: + pSyncEncoder->iFrameRate = iFrameRate; + pSyncEncoder->iFrameRateCode = 8; + pSyncEncoder->iPacketsPerFrame = 1; + break; + default: + pSyncEncoder->iError = SYNC_ENCODER_ERROR_INVALID_FR; + }; + + if(pSyncEncoder->iError != SYNC_ENCODER_ERROR_NONE){ + return pSyncEncoder->iError; + } + + /* calculate required buffer length */ + pSyncEncoder->iAudioBufferLength = pSyncEncoder->iSampleRate / pSyncEncoder->iFrameRate; + + /* Calculate total packet bits including wash bits */ + pSyncEncoder->iPacketBits = pSyncEncoder->iAudioBufferLength / (pSyncEncoder->iSymbolLength * pSyncEncoder->iPacketsPerFrame); + + /* Initialize symbol phase */ + pSyncEncoder->fSymbolPhase = 1.0f; + + /* Initialize UUD information */ + pSyncEncoder->iUUIDSubIndex = 0; + memcpy(&pSyncEncoder->UUID,pUUID,sizeof(UUIDINFORMATION)); + + return pSyncEncoder->iError; +} + +INT GetSyncEncoderAudioBufferLength(LPSYNCENCODER pSyncEncoder) /* In: Sync encoder structure */ +{ + if(pSyncEncoder->iError != SYNC_ENCODER_ERROR_NONE){ + return pSyncEncoder->iError; + } + + return pSyncEncoder->iAudioBufferLength; +} + + + +INT EncodeSync( LPSYNCENCODER pSyncEncoder, /* In: Sync encoder structure */ + INT iBufferLength, /* In: Length of audio buffer */ + FLOAT *pfAudioBuffer, /* Out: Audio buffer with signal */ + INT iFrameIndex) /* In: Frame Index */ +{ + INT n; + INT iBufferIndex; + + + if(pSyncEncoder->iError != SYNC_ENCODER_ERROR_NONE){ + return pSyncEncoder->iError; + } + if(iBufferLength != pSyncEncoder->iAudioBufferLength){ + return SYNC_ENCODER_ERROR_INVALID_BL; + } + + iBufferIndex = 0; + for(n = 0; n < pSyncEncoder->iPacketsPerFrame; n ++){ + /* Construct message */ + ConstructFrame(pSyncEncoder,iFrameIndex); + + /* Write Message */ + pSyncEncoder->fSymbolPhase = SEWriteBits(pSyncEncoder->iSampleRate, + &pfAudioBuffer[iBufferIndex], + pSyncEncoder->iPacketBits, + pSyncEncoder->abyPacket, + pSyncEncoder->fSymbolPhase); + + iBufferIndex += (pSyncEncoder->iPacketBits * pSyncEncoder->iSymbolLength); + + } + + return pSyncEncoder->iError; +} + +void ConstructFrame(LPSYNCENCODER pSyncEncoder, + INT iFrameIndex) +{ + USHORT ushCRC; + BYTE byByte; + INT iUUIDIndex; + + /* Flush the packet buffer */ + memset(pSyncEncoder->abyPacket,0,MAX_PACKET); + + /* Sync Header */ + pSyncEncoder->abyPacket[0] = SYNC_HEADER1; + pSyncEncoder->abyPacket[1] = SYNC_HEADER2; + + /* Frame Rate code */ + byByte = 0; + byByte = (unsigned char)(pSyncEncoder->iFrameRateCode << 4); + + /* UUID sub index */ + byByte |= (unsigned char)(pSyncEncoder->iUUIDSubIndex & 0x3); + + pSyncEncoder->abyPacket[2] = byByte; + + /* UUID Sub */ + iUUIDIndex = pSyncEncoder->iUUIDSubIndex << 2; + pSyncEncoder->abyPacket[3] = pSyncEncoder->UUID.abyUUIDBytes[iUUIDIndex]; + pSyncEncoder->abyPacket[4] = pSyncEncoder->UUID.abyUUIDBytes[iUUIDIndex + 1]; + pSyncEncoder->abyPacket[5] = pSyncEncoder->UUID.abyUUIDBytes[iUUIDIndex + 2]; + pSyncEncoder->abyPacket[6] = pSyncEncoder->UUID.abyUUIDBytes[iUUIDIndex + 3]; + + /* Update UUID sub index */ + pSyncEncoder->iUUIDSubIndex ++; + pSyncEncoder->iUUIDSubIndex &= 0x3; + + /* Frame Index */ + byByte = (unsigned char)((iFrameIndex >> 16) & 0XFF); + pSyncEncoder->abyPacket[7] = byByte; + byByte = (unsigned char)((iFrameIndex >> 8) & 0XFF); + pSyncEncoder->abyPacket[8] = byByte; + byByte = (unsigned char)(iFrameIndex & 0XFF); + pSyncEncoder->abyPacket[9] = byByte; + + /* calculate CRC */ + ushCRC = CRC16(&pSyncEncoder->abyPacket[2],MESSAGE_TOTAL_BYTES - 4); + + /* Insert CRC */ + byByte = (unsigned char)((ushCRC >> 8) & 0XFF); + pSyncEncoder->abyPacket[10] = byByte; + byByte = (unsigned char)(ushCRC & 0XFF); + pSyncEncoder->abyPacket[11] = byByte; + +} + +static FLOAT g_afSymbol0_48[SYMBOL_LENGTH_48] = { + 0.3827f, + 0.9239f, + 0.9239f, + 0.3827f, +}; + +static FLOAT g_afSymbol1_48[SYMBOL_LENGTH_48] = { + 0.7071f, + 0.7071f, + -0.7071f, + -0.7071f, +}; + +static FLOAT g_afSymbol0_96[SYMBOL_LENGTH_96] = { + 0.1951f, + 0.5556f, + 0.8315f, + 0.9808f, + 0.9808f, + 0.8315f, + 0.5556f, + 0.1951f, +}; + +static FLOAT g_afSymbol1_96[SYMBOL_LENGTH_96] = { + 0.3827f, + 0.9239f, + 0.9239f, + 0.3827f, + -0.3827f, + -0.9239f, + -0.9239f, + -0.3827f, +}; + +/* Symbol gain */ +static FLOAT g_fGain = 0.1f; + +FLOAT SEWriteBits( INT iSampleRate, /* In: Sample rate of signal */ + FLOAT *pfAudioBuffer, /* Out: Audio buffer containing signal */ + INT iBits, /* In: Number of bits to write */ + BYTE *pbyData, /* In: Data to write */ + FLOAT fSymbolPhase) /* In: Symbol phase */ +{ + INT n; + INT i; + INT iSymbolLength; + FLOAT *pfSymbol0; + FLOAT *pfSymbol1; + BYTE byByte; + + /* Select the correct symbol length and symbol signal based on sample rate */ + switch (iSampleRate){ + case 96000: + iSymbolLength = SYMBOL_LENGTH_96; + pfSymbol0 = g_afSymbol0_96; + pfSymbol1 = g_afSymbol1_96; + break; + case 48000: + iSymbolLength = SYMBOL_LENGTH_48; + pfSymbol0 = g_afSymbol0_48; + pfSymbol1 = g_afSymbol1_48; + break; + default: + iSymbolLength = 0; + pfSymbol0 = g_afSymbol0_96; + pfSymbol1 = g_afSymbol1_96; + }; + + /* Write bits */ + n = 0; + i = 0; + while(n < iBits){ + INT k; + FLOAT *pfSymbol; + + /* Grab next byte of data */ + if(i == 0){ + byByte = *pbyData; + pbyData ++; + } + + pfSymbol = (byByte & 0x80) ? pfSymbol1 : pfSymbol0; + + for(k = 0; k < iSymbolLength; k ++){ + *pfAudioBuffer = *pfSymbol * fSymbolPhase * g_fGain; + pfAudioBuffer ++; + pfSymbol ++; + } + + fSymbolPhase *= (byByte & 0x80) ? 1.0f : -1.0f; + + byByte <<= 1; + + n ++; + + i ++; + i &= 0x7; + } + + return fSymbolPhase; +} diff --git a/asdcplib/src/SyncEncoder.h b/asdcplib/src/SyncEncoder.h new file mode 100644 index 00000000..3a73e1c8 --- /dev/null +++ b/asdcplib/src/SyncEncoder.h @@ -0,0 +1,86 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file SyncEncoder.h + \version $Id: SyncEncoder.h,v 1.1 2013/04/12 23:39:31 mikey Exp $ + \brief Declaration of Atmos Sync Frame Encoder +*/ + +#ifndef _SYNC_ENCODER_H_ +#define _SYNC_ENCODER_H_ + +#include "SyncCommon.h" +#include "UUIDInformation.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SyncEncoder{ + INT iSampleRate; /* Signal sample rate */ + INT iSymbolLength; /* Symbol Length */ + INT iFrameRate; /* Frame rate */ + INT iFrameRateCode; /* Frame rate code */ + INT iAudioBufferLength; /* Length of audio buffer */ + INT iPacketBits; /* Bits in each packet includes wash bits */ + INT iPacketsPerFrame; /* Number of packets per frame */ + FLOAT fSymbolPhase; /* Symbol phase */ + + INT iUUIDSubIndex; /* UUID transmission sub index */ + UUIDINFORMATION UUID; /* UUID */ + + BYTE abyPacket[MAX_PACKET]; + + INT iError; /* Error state */ +}SYNCENCODER,*LPSYNCENCODER; + +enum{ + SYNC_ENCODER_ERROR_NONE = 0, /* No error */ + SYNC_ENCODER_ERROR_INVALID_SR = -1, /* Invalid sample rate */ + SYNC_ENCODER_ERROR_INVALID_FR = -2, /* Invalid frame rate */ + SYNC_ENCODER_ERROR_INVALID_BL = -10, /* Buffer length is incorrect */ + SYNC_ENCODER_ERROR_UNKNOWN = -100, /* Unknown */ +}; + + +INT SyncEncoderInit(LPSYNCENCODER pSyncEncoder, /* Out: SYNCENCODER structure to be initialized */ + INT iSampleRate, /* In: Signal sample rate */ + INT iFrameRate, /* In: frame rate */ + LPUUIDINFORMATION pUUID); /* In: UUID */ + +INT GetSyncEncoderAudioBufferLength(LPSYNCENCODER pSyncEncoder); + +INT EncodeSync( LPSYNCENCODER pSyncEncoder, /* In: Sync encoder structure */ + INT iBufferLength, /* In: Length of audio buffer */ + FLOAT *pfAudioBuffer, /* Out: Audio buffer with signal */ + INT iFrameIndex); /* In: Frame Index */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/asdcplib/src/TimedText_Parser.cpp b/asdcplib/src/TimedText_Parser.cpp index ce16aee7..11fce6c9 100644 --- a/asdcplib/src/TimedText_Parser.cpp +++ b/asdcplib/src/TimedText_Parser.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2007-2009, John Hurst +Copyright (c) 2007-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file AS_DCP_TimedText.cpp - \version $Id: TimedText_Parser.cpp,v 1.15 2010/11/15 17:04:13 jhurst Exp $ + \version $Id: TimedText_Parser.cpp,v 1.23 2015/10/16 16:55:33 jhurst Exp $ \brief AS-DCP library, PCM essence reader and writer implementation */ @@ -44,54 +44,65 @@ const char* c_dcst_namespace_name = "http://www.smpte-ra.org/schemas/428-7/2007/ //------------------------------------------------------------------------------------------ +ASDCP::TimedText::LocalFilenameResolver::LocalFilenameResolver() {} +ASDCP::TimedText::LocalFilenameResolver::~LocalFilenameResolver() {} -class FilenameResolver : public ASDCP::TimedText::IResourceResolver +// +Result_t +ASDCP::TimedText::LocalFilenameResolver::OpenRead(const std::string& dirname) { - std::string m_Dirname; - - FilenameResolver(); - bool operator==(const FilenameResolver&); - -public: - FilenameResolver(const std::string& dirname) - { - if ( PathIsDirectory(dirname) ) - { - m_Dirname = dirname; - return; - } - - DefaultLogSink().Error("Path '%s' is not a directory, defaulting to '.'\n", dirname.c_str()); - m_Dirname = "."; - } + if ( PathIsDirectory(dirname) ) + { + m_Dirname = dirname; + return RESULT_OK; + } - // - Result_t ResolveRID(const byte_t* uuid, TimedText::FrameBuffer& FrameBuf) const - { - FileReader Reader; - char buf[64]; - UUID RID(uuid); - std::string filename = m_Dirname + "/" + RID.EncodeHex(buf, 64); - DefaultLogSink().Debug("retrieving resource %s from file %s\n", buf, filename.c_str()); + DefaultLogSink().Error("Path '%s' is not a directory, defaulting to '.'\n", dirname.c_str()); + m_Dirname = "."; + return RESULT_FALSE; +} - Result_t result = Reader.OpenRead(filename.c_str()); +// +Result_t +ASDCP::TimedText::LocalFilenameResolver::ResolveRID(const byte_t* uuid, TimedText::FrameBuffer& FrameBuf) const +{ + Result_t result = RESULT_NOT_FOUND; + char buf[64]; + UUID RID(uuid); + PathList_t found_list; - if ( KM_SUCCESS(result) ) - { - ui32_t read_count, read_size = Reader.Size(); +#ifndef KM_WIN32 + // TODO, fix this for win32 (needs regex) + FindInPath(PathMatchRegex(RID.EncodeHex(buf, 64)), m_Dirname, found_list); +#endif - result = FrameBuf.Capacity(read_size); + if ( found_list.size() == 1 ) + { + FileReader Reader; + DefaultLogSink().Debug("Retrieving resource %s from file %s\n", buf, found_list.front().c_str()); - if ( KM_SUCCESS(result) ) - result = Reader.Read(FrameBuf.Data(), read_size, &read_count); + result = Reader.OpenRead(found_list.front().c_str()); - if ( KM_SUCCESS(result) ) - FrameBuf.Size(read_count); - } + if ( KM_SUCCESS(result) ) + { + ui32_t read_count, read_size = Reader.Size(); + result = FrameBuf.Capacity(read_size); + + if ( KM_SUCCESS(result) ) + result = Reader.Read(FrameBuf.Data(), read_size, &read_count); + + if ( KM_SUCCESS(result) ) + FrameBuf.Size(read_count); + } + } + else if ( ! found_list.empty() ) + { + DefaultLogSink().Error("More than one file in %s matches %s.\n", m_Dirname.c_str(), buf); + result = RESULT_RAW_FORMAT; + } - return result; - } -}; + return result; +} //------------------------------------------------------------------------------------------ @@ -109,7 +120,7 @@ public: std::string m_Filename; std::string m_XMLDoc; TimedTextDescriptor m_TDesc; - mem_ptr<FilenameResolver> m_DefaultResolver; + mem_ptr<LocalFilenameResolver> m_DefaultResolver; h__SubtitleParser() : m_Root("**ParserRoot**") { @@ -121,13 +132,16 @@ public: TimedText::IResourceResolver* GetDefaultResolver() { if ( m_DefaultResolver.empty() ) - m_DefaultResolver = new FilenameResolver(PathDirname(m_Filename)); - + { + m_DefaultResolver = new LocalFilenameResolver(); + m_DefaultResolver->OpenRead(PathDirname(m_Filename)); + } + return m_DefaultResolver; } - Result_t OpenRead(const char* filename); - Result_t OpenRead(const std::string& xml_doc, const char* filename); + Result_t OpenRead(const std::string& filename); + Result_t OpenRead(const std::string& xml_doc, const std::string& filename); Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer& FrameBuf, const IResourceResolver& Resolver) const; }; @@ -152,23 +166,8 @@ get_UUID_from_child_element(const char* name, XMLElement* Parent, UUID& outID) } // -static ASDCP::Rational -decode_rational(const char* str_rat) -{ - assert(str_rat); - ui32_t Num = atoi(str_rat); - ui32_t Den = 0; - - const char* den_str = strrchr(str_rat, ' '); - if ( den_str != 0 ) - Den = atoi(den_str+1); - - return ASDCP::Rational(Num, Den); -} - -// Result_t -ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* filename) +ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& filename) { Result_t result = ReadFileIntoString(filename, m_XMLDoc); @@ -181,14 +180,18 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const char* file // Result_t -ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& xml_doc, const char* filename) +ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead(const std::string& xml_doc, const std::string& filename) { m_XMLDoc = xml_doc; - if ( filename != 0 ) - m_Filename = filename; + if ( filename.empty() ) + { + m_Filename = "<string>"; + } else - m_Filename = "<string>"; + { + m_Filename = filename; + } return OpenRead(); } @@ -207,7 +210,7 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead() if ( ns == 0 ) { - DefaultLogSink(). Warn("Document has no namespace name, assuming %s\n", c_dcst_namespace_name); + DefaultLogSink(). Warn("Document has no namespace name, assuming \"%s\".\n", c_dcst_namespace_name); m_TDesc.NamespaceName = c_dcst_namespace_name; } else @@ -218,7 +221,7 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead() UUID DocID; if ( ! get_UUID_from_child_element("Id", &m_Root, DocID) ) { - DefaultLogSink(). Error("Id element missing from input document\n"); + DefaultLogSink(). Error("Id element missing from input document.\n"); return RESULT_FORMAT; } @@ -227,11 +230,15 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead() if ( EditRate == 0 ) { - DefaultLogSink(). Error("EditRate element missing from input document\n"); + DefaultLogSink().Error("EditRate element missing from input document.\n"); return RESULT_FORMAT; } - m_TDesc.EditRate = decode_rational(EditRate->GetBody().c_str()); + if ( ! DecodeRational(EditRate->GetBody().c_str(), m_TDesc.EditRate) ) + { + DefaultLogSink().Error("Error decoding edit rate value: \"%s\"\n", EditRate->GetBody().c_str()); + return RESULT_FORMAT; + } if ( m_TDesc.EditRate != EditRate_23_98 && m_TDesc.EditRate != EditRate_24 @@ -269,6 +276,7 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead() // list of images ElementList ImageList; m_Root.GetChildrenWithName("Image", ImageList); + std::set<Kumu::UUID> visited_items; for ( Elem_i i = ImageList.begin(); i != ImageList.end(); i++ ) { @@ -279,11 +287,15 @@ ASDCP::TimedText::DCSubtitleParser::h__SubtitleParser::OpenRead() return RESULT_FORMAT; } - TimedTextResourceDescriptor TmpResource; - memcpy(TmpResource.ResourceID, AssetID.Value(), UUIDlen); - TmpResource.Type = MT_PNG; - m_TDesc.ResourceList.push_back(TmpResource); - m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(TmpResource.ResourceID), MT_PNG)); + if ( visited_items.find(AssetID) == visited_items.end() ) + { + TimedTextResourceDescriptor TmpResource; + memcpy(TmpResource.ResourceID, AssetID.Value(), UUIDlen); + TmpResource.Type = MT_PNG; + m_TDesc.ResourceList.push_back(TmpResource); + m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(TmpResource.ResourceID), MT_PNG)); + visited_items.insert(AssetID); + } } // Calculate the timeline duration. @@ -379,7 +391,7 @@ ASDCP::TimedText::DCSubtitleParser::~DCSubtitleParser() // Opens the stream for reading, parses enough data to provide a complete // set of stream metadata for the MXFWriter below. ASDCP::Result_t -ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const +ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& filename) const { const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__SubtitleParser; @@ -393,7 +405,7 @@ ASDCP::TimedText::DCSubtitleParser::OpenRead(const char* filename) const // Parses an XML document to provide a complete set of stream metadata for the MXFWriter below. Result_t -ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& xml_doc, const char* filename) const +ASDCP::TimedText::DCSubtitleParser::OpenRead(const std::string& xml_doc, const std::string& filename) const { const_cast<ASDCP::TimedText::DCSubtitleParser*>(this)->m_Parser = new h__SubtitleParser; @@ -443,5 +455,5 @@ ASDCP::TimedText::DCSubtitleParser::ReadAncillaryResource(const byte_t* uuid, Fr // -// end AS_DCP_timedText.cpp +// end AS_DCP_TimedTextParser.cpp // diff --git a/asdcplib/src/UUIDInformation.c b/asdcplib/src/UUIDInformation.c new file mode 100644 index 00000000..7d00e4b4 --- /dev/null +++ b/asdcplib/src/UUIDInformation.c @@ -0,0 +1,119 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file SyncEncoder.h + \version $Id: UUIDInformation.c,v 1.1 2013/04/12 23:39:31 mikey Exp $ + \brief Implementation of Atmos Sync UUID +*/ + +#include "UUIDInformation.h" +#include <stdlib.h> + + +void UUIDSynthesize(LPUUIDINFORMATION pUUID) +{ + INT n; + + for(n = 0; n < 16; n ++){ + pUUID->abyUUIDBytes[n] = (BYTE)(rand() & 0xFF); + } + + pUUID->abyUUIDBytes[6] &= 0x0F; + pUUID->abyUUIDBytes[6] |= 0x40; + + pUUID->abyUUIDBytes[8] &= 0x0F; + pUUID->abyUUIDBytes[8] |= 0xA0; +} + +void UUIDPrint( FILE *pFilePtr, + LPUUIDINFORMATION pUUID) +{ + if(pFilePtr != NULL){ + INT n; + + for(n = 0; n < 16; n ++){ + fprintf(pFilePtr,"%02x",pUUID->abyUUIDBytes[n]); + } + } + else{ + INT n; + + for(n = 0; n < 16; n ++){ + fprintf(stdout,"%02x",pUUID->abyUUIDBytes[n]); + } + } +} + +void UUIDPrintFormated( FILE *pFilePtr, + LPUUIDINFORMATION pUUID) +{ + if(pFilePtr != NULL){ + INT n; + + for(n = 0; n < 4; n ++){ + fprintf(pFilePtr,"%02x",pUUID->abyUUIDBytes[n]); + } + fprintf(pFilePtr,"-"); + for(n = 4; n < 6; n ++){ + fprintf(pFilePtr,"%02x",pUUID->abyUUIDBytes[n]); + } + fprintf(pFilePtr,"-"); + for(n = 6; n < 8; n ++){ + fprintf(pFilePtr,"%02x",pUUID->abyUUIDBytes[n]); + } + fprintf(pFilePtr,"-"); + for(n = 8; n < 10; n ++){ + fprintf(pFilePtr,"%02x",pUUID->abyUUIDBytes[n]); + } + fprintf(pFilePtr,"-"); + for(n = 10; n < 16; n ++){ + fprintf(pFilePtr,"%02x",pUUID->abyUUIDBytes[n]); + } + } + else{ + INT n; + + for(n = 0; n < 4; n ++){ + fprintf(stdout,"%02x",pUUID->abyUUIDBytes[n]); + } + fprintf(stdout,"-"); + for(n = 4; n < 6; n ++){ + fprintf(stdout,"%02x",pUUID->abyUUIDBytes[n]); + } + fprintf(stdout,"-"); + for(n = 6; n < 8; n ++){ + fprintf(stdout,"%02x",pUUID->abyUUIDBytes[n]); + } + fprintf(stdout,"-"); + for(n = 8; n < 10; n ++){ + fprintf(stdout,"%02x",pUUID->abyUUIDBytes[n]); + } + fprintf(stdout,"-"); + for(n = 10; n < 16; n ++){ + fprintf(stdout,"%02x",pUUID->abyUUIDBytes[n]); + } + } +} diff --git a/asdcplib/src/UUIDInformation.h b/asdcplib/src/UUIDInformation.h new file mode 100644 index 00000000..0d574498 --- /dev/null +++ b/asdcplib/src/UUIDInformation.h @@ -0,0 +1,58 @@ +/* +Copyright (c) 2013-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file SyncEncoder.h + \version $Id: UUIDInformation.h,v 1.1 2013/04/12 23:39:31 mikey Exp $ + \brief Declaration of Atmos Sync UUID +*/ + +#ifndef _UUID_INFORMATION_H_ +#define _UUID_INFORMATION_H_ + +#include "SyncCommon.h" +#include <stdio.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct UUIInformation{ + BYTE abyUUIDBytes[16]; +} UUIDINFORMATION,*LPUUIDINFORMATION; + +void UUIDSynthesize(LPUUIDINFORMATION pUUID); + +void UUIDPrint( FILE *pFilePtr, + LPUUIDINFORMATION pUUID); + +void UUIDPrintFormated( FILE *pFilePtr, + LPUUIDINFORMATION pUUID); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/asdcplib/src/Wav.cpp b/asdcplib/src/Wav.cpp index ee1e93d5..7cc53a44 100755 --- a/asdcplib/src/Wav.cpp +++ b/asdcplib/src/Wav.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2009, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file Wav.cpp - \version $Id: Wav.cpp,v 1.11 2010/02/16 18:40:57 jhurst Exp $ + \version $Id: Wav.cpp,v 1.15 2015/04/21 03:55:31 jhurst Exp $ \brief Wave file common elements */ @@ -44,7 +44,7 @@ ASDCP::Wav::SimpleWaveHeader::SimpleWaveHeader(ASDCP::PCM::AudioDescriptor& ADes nchannels = ADesc.ChannelCount; bitspersample = ADesc.QuantizationBits; samplespersec = (ui32_t)ceil(ADesc.AudioSamplingRate.Quotient()); - blockalign = nchannels * (bitspersample / 8); + blockalign = nchannels * ((bitspersample + 7) / 8); avgbps = samplespersec * blockalign; cbsize = 0; data_len = ASDCP::PCM::CalcFrameBufferSize(ADesc) * ADesc.ContainerDuration; @@ -175,7 +175,7 @@ ASDCP::Wav::SimpleWaveHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len, { ui16_t format = KM_i16_LE(*(ui16_t*)p); p += 2; - if ( format != WAVE_FORMAT_PCM && format != WAVE_FORMAT_EXTENSIBLE ) + if ( format != ASDCP_WAVE_FORMAT_PCM && format != ASDCP_WAVE_FORMAT_EXTENSIBLE ) { DefaultLogSink().Error("Expecting uncompressed PCM data, got format type %hd\n", format); return RESULT_RAW_FORMAT; @@ -363,7 +363,234 @@ ASDCP::AIFF::SimpleAIFFHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len, return RESULT_OK; } +ASDCP::RF64::SimpleRF64Header::SimpleRF64Header(ASDCP::PCM::AudioDescriptor& ADesc) +{ + format = 1; + nchannels = ADesc.ChannelCount; + bitspersample = ADesc.QuantizationBits; + samplespersec = (ui32_t)ceil(ADesc.AudioSamplingRate.Quotient()); + blockalign = nchannels * ((bitspersample + 7) / 8); + avgbps = samplespersec * blockalign; + cbsize = 0; + data_len = static_cast<ui64_t>(ASDCP::PCM::CalcFrameBufferSize(ADesc)) * ADesc.ContainerDuration; +} + +// +void +ASDCP::RF64::SimpleRF64Header::FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, ASDCP::Rational PictureRate) const +{ + ADesc.EditRate = PictureRate; + + ADesc.LinkedTrackID = 0; + ADesc.Locked = 0; + ADesc.ChannelCount = nchannels; + ADesc.AudioSamplingRate = Rational(samplespersec, 1); + ADesc.AvgBps = avgbps; + ADesc.BlockAlign = blockalign; + ADesc.QuantizationBits = bitspersample; + ui32_t FrameBufferSize = ASDCP::PCM::CalcFrameBufferSize(ADesc); + ADesc.ContainerDuration = data_len / FrameBufferSize; + ADesc.ChannelFormat = PCM::CF_NONE; +} + +// +ASDCP::Result_t +ASDCP::RF64::SimpleRF64Header::WriteToFile(Kumu::FileWriter& OutFile) const +{ + static ui32_t fmt_len = + sizeof(format) + + sizeof(nchannels) + + sizeof(samplespersec) + + sizeof(avgbps) + + sizeof(blockalign) + + sizeof(bitspersample) + + sizeof(cbsize); + + ui32_t write_count = 0; + ui64_t RIFF_len = data_len + SimpleWavHeaderLength - 8; + // DefaultLogSink().Debug("RIFF_len is %llu.\n", RIFF_len); + byte_t* tmp_header = NULL; + ui32_t header_len = 0; + + if (RIFF_len > MAX_RIFF_LEN) + { + DefaultLogSink().Debug("Will write out an RF64 wave file.\n"); + ui32_t data32_len = ((data_len < MAX_RIFF_LEN) ? data_len : MAX_RIFF_LEN); + ui64_t data64_len = ((data_len < MAX_RIFF_LEN) ? 0 : data_len); + static ui32_t ds64_len = + sizeof(RIFF_len) + + sizeof(data64_len) + + sizeof(SAMPLE_COUNT) + + sizeof(TABLE_LEN); + + header_len = SIMPLE_RF64_HEADER_LEN; + tmp_header = new byte_t[header_len]; + byte_t* p = tmp_header; + memcpy(p, &FCC_RF64, sizeof(fourcc)); p += 4; + *((ui32_t*)p) = KM_i32_LE(MAX_RIFF_LEN); p += 4; + memcpy(p, &Wav::FCC_WAVE, sizeof(fourcc)); p += 4; + memcpy(p, &FCC_ds64, sizeof(fourcc)); p += 4; + *((ui32_t*)p) = KM_i32_LE(ds64_len); p += 4; + *((ui64_t*)p) = KM_i64_LE(RIFF_len); p += 8; + *((ui64_t*)p) = KM_i64_LE(data64_len); p += 8; + *((ui64_t*)p) = KM_i64_LE(SAMPLE_COUNT); p += 8; + *((ui32_t*)p) = KM_i32_LE(TABLE_LEN); p += 4; + memcpy(p, &Wav::FCC_fmt_, sizeof(fourcc)); p += 4; + *((ui32_t*)p) = KM_i32_LE(fmt_len); p += 4; + *((ui16_t*)p) = KM_i16_LE(format); p += 2; + *((ui16_t*)p) = KM_i16_LE(nchannels); p += 2; + *((ui32_t*)p) = KM_i32_LE(samplespersec); p += 4; + *((ui32_t*)p) = KM_i32_LE(avgbps); p += 4; + *((ui16_t*)p) = KM_i16_LE(blockalign); p += 2; + *((ui16_t*)p) = KM_i16_LE(bitspersample); p += 2; + *((ui16_t*)p) = KM_i16_LE(cbsize); p += 2; + memcpy(p, &Wav::FCC_data, sizeof(fourcc)); p += 4; + *((ui32_t*)p) = KM_i32_LE(data32_len); p += 4; + write_count = (p - tmp_header); + } + else + { + DefaultLogSink().Debug("Will write out a regular wave file.\n"); + header_len = SimpleWavHeaderLength; + tmp_header = new byte_t[header_len]; + byte_t* p = tmp_header; + memcpy(p, &Wav::FCC_RIFF, sizeof(fourcc)); p += 4; + *((ui32_t*)p) = KM_i32_LE(RIFF_len); p += 4; + memcpy(p, &Wav::FCC_WAVE, sizeof(fourcc)); p += 4; + memcpy(p, &Wav::FCC_fmt_, sizeof(fourcc)); p += 4; + *((ui32_t*)p) = KM_i32_LE(fmt_len); p += 4; + *((ui16_t*)p) = KM_i16_LE(format); p += 2; + *((ui16_t*)p) = KM_i16_LE(nchannels); p += 2; + *((ui32_t*)p) = KM_i32_LE(samplespersec); p += 4; + *((ui32_t*)p) = KM_i32_LE(avgbps); p += 4; + *((ui16_t*)p) = KM_i16_LE(blockalign); p += 2; + *((ui16_t*)p) = KM_i16_LE(bitspersample); p += 2; + *((ui16_t*)p) = KM_i16_LE(cbsize); p += 2; + memcpy(p, &Wav::FCC_data, sizeof(fourcc)); p += 4; + *((ui32_t*)p) = KM_i32_LE(data_len); p += 4; + write_count = (p - tmp_header); + } + if (header_len != write_count) + { + DefaultLogSink().Warn("Expected to write %u bytes but wrote %u bytes for header.\n", + header_len, write_count); + } + write_count = 0; + ASDCP::Result_t r = OutFile.Write(tmp_header, header_len, &write_count); + delete [] tmp_header; + return r; +} + +// +ASDCP::Result_t +ASDCP::RF64::SimpleRF64Header::ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start) +{ + ui32_t read_count = 0; + ui32_t local_data_start = 0; + ASDCP::PCM::FrameBuffer TmpBuffer(Wav::MaxWavHeader); + + if ( data_start == 0 ) + data_start = &local_data_start; + + Result_t result = InFile.Read(TmpBuffer.Data(), TmpBuffer.Capacity(), &read_count); + + if ( ASDCP_SUCCESS(result) ) + result = ReadFromBuffer(TmpBuffer.RoData(), read_count, data_start); + else + DefaultLogSink().Error("Failed to read %d bytes from file\n", Wav::MaxWavHeader); + + return result; +} + +ASDCP::Result_t +ASDCP::RF64::SimpleRF64Header::ReadFromBuffer(const byte_t* buf, ui32_t buf_len, ui32_t* data_start) +{ + if ( buf_len < SIMPLE_RF64_HEADER_LEN ) + return RESULT_SMALLBUF; + + *data_start = 0; + const byte_t* p = buf; + const byte_t* end_p = p + buf_len; + + fourcc test_RF64(p); p += 4; + if ( test_RF64 != FCC_RF64 ) + { + DefaultLogSink().Debug("File does not begin with RF64 header\n"); + return RESULT_RAW_FORMAT; + } + + ui32_t tmp_len = KM_i32_LE(*(ui32_t*)p); p += 4; + + fourcc test_WAVE(p); p += 4; + if ( test_WAVE != Wav::FCC_WAVE ) + { + DefaultLogSink().Debug("File does not contain a WAVE header\n"); + return RESULT_RAW_FORMAT; + } + + fourcc test_ds64(p); p += 4; + if ( test_ds64 != FCC_ds64 ) + { + DefaultLogSink().Debug("File does not contain a ds64 chunk\n"); + return RESULT_RAW_FORMAT; + } + ui32_t ds64_len = KM_i32_LE(*(ui32_t*)p); p += 4; + ui64_t RIFF_len = ((tmp_len == MAX_RIFF_LEN) ? KM_i64_LE(*(ui64_t*)p) : tmp_len); p += 8; + data_len = KM_i64_LE(*(ui64_t*)p); p += 8; + p += (ds64_len - 16); // skip rest of ds64 chunk + + fourcc test_fcc; + + while ( p < end_p ) + { + test_fcc = fourcc(p); p += 4; + ui32_t chunk_size = KM_i32_LE(*(ui32_t*)p); p += 4; + + if ( test_fcc == Wav::FCC_data ) + { + if ( chunk_size > RIFF_len ) + { + DefaultLogSink().Error("Chunk size %u larger than file: %u\n", chunk_size, RIFF_len); + return RESULT_RAW_FORMAT; + } + + if (chunk_size != MAX_RIFF_LEN) + data_len = chunk_size; + *data_start = p - buf; + break; + } + if ( test_fcc == Wav::FCC_fmt_ ) + { + ui16_t format = KM_i16_LE(*(ui16_t*)p); p += 2; + + if ( format != Wav::ASDCP_WAVE_FORMAT_PCM && format != Wav::ASDCP_WAVE_FORMAT_EXTENSIBLE ) + { + DefaultLogSink().Error("Expecting uncompressed PCM data, got format type %hd\n", format); + return RESULT_RAW_FORMAT; + } + + nchannels = KM_i16_LE(*(ui16_t*)p); p += 2; + samplespersec = KM_i32_LE(*(ui32_t*)p); p += 4; + avgbps = KM_i32_LE(*(ui32_t*)p); p += 4; + blockalign = KM_i16_LE(*(ui16_t*)p); p += 2; + bitspersample = KM_i16_LE(*(ui16_t*)p); p += 2; + p += chunk_size - 16; // 16 is the number of bytes read in this block + } + else + { + p += chunk_size; + } + } + + if ( *data_start == 0 ) // can't have no data! + { + DefaultLogSink().Error("No data chunk found, file contains no essence\n"); + return RESULT_RAW_FORMAT; + } + + return RESULT_OK; +} // // end Wav.cpp diff --git a/asdcplib/src/Wav.h b/asdcplib/src/Wav.h index 09ee48a9..f1d82572 100755 --- a/asdcplib/src/Wav.h +++ b/asdcplib/src/Wav.h @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file Wav.h - \version $Id: Wav.h,v 1.5 2009/04/09 19:24:14 msheby Exp $ + \version $Id: Wav.h,v 1.8 2015/04/21 03:55:31 jhurst Exp $ \brief Wave file common elements */ @@ -89,8 +89,8 @@ namespace ASDCP const fourcc FCC_fmt_("fmt "); const fourcc FCC_data("data"); - const ui16_t WAVE_FORMAT_PCM = 1; - const ui16_t WAVE_FORMAT_EXTENSIBLE = 65534; + const ui16_t ASDCP_WAVE_FORMAT_PCM = 1; + const ui16_t ASDCP_WAVE_FORMAT_EXTENSIBLE = 65534; // class SimpleWaveHeader @@ -118,6 +118,46 @@ namespace ASDCP }; } // namespace Wav + + namespace RF64 + { + const fourcc FCC_RF64("RF64"); + const fourcc FCC_ds64("ds64"); + + + static const ui32_t MAX_RIFF_LEN = 0xFFFFFFFF; + static const ui32_t DS64_HEADER_LEN = 28; + static const ui32_t SIMPLE_RF64_HEADER_LEN = 82; + // + class SimpleRF64Header + { + public: + ui16_t format; + ui16_t nchannels; + ui32_t samplespersec; + ui32_t avgbps; + ui16_t blockalign; + ui16_t bitspersample; + ui16_t cbsize; + ui64_t data_len; + + SimpleRF64Header() : + format(0), nchannels(0), samplespersec(0), avgbps(0), + blockalign(0), bitspersample(0), cbsize(0), data_len(0) {} + + SimpleRF64Header(ASDCP::PCM::AudioDescriptor& ADesc); + + Result_t ReadFromBuffer(const byte_t* buf, ui32_t buf_len, ui32_t* data_start); + Result_t ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start); + Result_t WriteToFile(Kumu::FileWriter& OutFile) const; + void FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, Rational PictureRate) const; + + private: + static const ui64_t SAMPLE_COUNT = 0; + static const ui32_t TABLE_LEN = 0; + }; + + } // namespace RF64 } // namespace ASDCP #endif // _WAV_H_ diff --git a/asdcplib/src/WavFileWriter.h b/asdcplib/src/WavFileWriter.h index daf26ead..763930bb 100755 --- a/asdcplib/src/WavFileWriter.h +++ b/asdcplib/src/WavFileWriter.h @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file WavFileWriter.h - \version $Id: WavFileWriter.h,v 1.6 2009/04/09 19:16:49 msheby Exp $ + \version $Id: WavFileWriter.h,v 1.8 2013/06/17 17:55:54 jhurst Exp $ \brief demux and write PCM data to WAV file(s) */ @@ -98,7 +98,8 @@ class WavFileWriter enum SplitType_t { ST_NONE, // write all channels to a single WAV file ST_MONO, // write each channel a separate WAV file - ST_STEREO // write channel pairs to separate WAV files + ST_STEREO, // write channel pairs to separate WAV files + ST_MAX }; ASDCP::Result_t @@ -136,22 +137,36 @@ class WavFileWriter assert(file_count && m_ChannelCount); ui32_t element_size = ASDCP::PCM::CalcFrameBufferSize(m_ADesc) / file_count; - - for ( ui32_t i = 0; i < file_count && ASDCP_SUCCESS(result); i++ ) - { - snprintf(filename, Kumu::MaxFilePath, "%s_%u.wav", file_root, (i + 1)); - m_OutFile.push_back(new WavFileElement(element_size)); - result = m_OutFile.back()->OpenWrite(filename); - - if ( ASDCP_SUCCESS(result) ) - { - ASDCP::PCM::AudioDescriptor tmpDesc = m_ADesc; - tmpDesc.ChannelCount = m_ChannelCount; - ASDCP::Wav::SimpleWaveHeader Wav(tmpDesc); - result = Wav.WriteToFile(*(m_OutFile.back())); - } - } - + if (split == ST_NONE) + { + snprintf(filename, Kumu::MaxFilePath, "%s", file_root); + m_OutFile.push_back(new WavFileElement(element_size)); + result = m_OutFile.back()->OpenWrite(filename); + if ( ASDCP_SUCCESS(result) ) + { + ASDCP::PCM::AudioDescriptor tmpDesc = m_ADesc; + tmpDesc.ChannelCount = m_ChannelCount; + ASDCP::RF64::SimpleRF64Header Wav(tmpDesc); + result = Wav.WriteToFile(*(m_OutFile.back())); + } + } + else + { + for ( ui32_t i = 0; i < file_count && ASDCP_SUCCESS(result); i++ ) + { + snprintf(filename, Kumu::MaxFilePath, "%s_%u.wav", file_root, (i + 1)); + m_OutFile.push_back(new WavFileElement(element_size)); + result = m_OutFile.back()->OpenWrite(filename); + + if ( ASDCP_SUCCESS(result) ) + { + ASDCP::PCM::AudioDescriptor tmpDesc = m_ADesc; + tmpDesc.ChannelCount = m_ChannelCount; + ASDCP::RF64::SimpleRF64Header Wav(tmpDesc); + result = Wav.WriteToFile(*(m_OutFile.back())); + } + } + } return result; } diff --git a/asdcplib/src/as-02-unwrap.cpp b/asdcplib/src/as-02-unwrap.cpp new file mode 100755 index 00000000..3d702e7b --- /dev/null +++ b/asdcplib/src/as-02-unwrap.cpp @@ -0,0 +1,631 @@ +/* +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file as-02-unwrap.cpp + \version $Id: as-02-unwrap.cpp,v 1.13 2015/10/07 16:41:23 jhurst Exp $ + \brief AS-02 file manipulation utility + + This program extracts picture and sound from AS-02 files. + + For more information about AS-02, please refer to the header file AS_02.h + For more information about asdcplib, please refer to the header file AS_DCP.h +*/ + +#include <KM_fileio.h> +#include <AS_02.h> +#include <WavFileWriter.h> + +namespace ASDCP { + Result_t MD_to_PCM_ADesc(ASDCP::MXF::WaveAudioDescriptor* ADescObj, ASDCP::PCM::AudioDescriptor& ADesc); +} + +using namespace ASDCP; + +const ui32_t FRAME_BUFFER_SIZE = 4 * Kumu::Megabyte; + +//------------------------------------------------------------------------------------------ +// +// command line option parser class + +static const char* PROGRAM_NAME = "as-02-unwrap"; // program name for messages + +// Increment the iterator, test for an additional non-option command line argument. +// Causes the caller to return if there are no remaining arguments or if the next +// argument begins with '-'. +#define TEST_EXTRA_ARG(i,c) \ + if ( ++i >= argc || argv[(i)][0] == '-' ) { \ + fprintf(stderr, "Argument not found for option -%c.\n", (c)); \ + return; \ + } + +// +void +banner(FILE* stream = stdout) +{ + fprintf(stream, "\n\ +%s (asdcplib %s)\n\n\ +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst\n\n\ +asdcplib may be copied only under the terms of the license found at\n\ +the top of every file in the asdcplib distribution kit.\n\n\ +Specify the -h (help) option for further information about %s\n\n", + PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME); +} + +// +void +usage(FILE* stream = stdout) +{ + fprintf(stream, "\ +USAGE: %s [-h|-help] [-V]\n\ +\n\ + %s [-1|-2] [-b <buffer-size>] [-d <duration>]\n\ + [-f <starting-frame>] [-m] [-p <frame-rate>] [-R] [-s <size>] [-v] [-W]\n\ + [-w] <input-file> [<file-prefix>]\n\n", + PROGRAM_NAME, PROGRAM_NAME); + + fprintf(stream, "\ +Options:\n\ + -1 - Split Wave essence to mono WAV files during extract.\n\ + Default is multichannel WAV\n\ + -2 - Split Wave essence to stereo WAV files during extract.\n\ + Default is multichannel WAV\n\ + -b <buffer-size> - Specify size in bytes of picture frame buffer\n\ + Defaults to 4,194,304 (4MB)\n\ + -d <duration> - Number of frames to process, default all\n\ + -f <start-frame> - Starting frame number, default 0\n\ + -h | -help - Show help\n\ + -k <key-string> - Use key for ciphertext operations\n\ + -m - verify HMAC values when reading\n\ + -s <size> - Number of bytes to dump to output when -v is given\n\ + -V - Show version information\n\ + -v - Verbose, prints informative messages to stderr\n\ + -W - Read input file only, do not write destination file\n\ + -w <width> - Width of numeric element in a series of frame file names\n\ + (default 6)\n\ + -z - Fail if j2c inputs have unequal parameters (default)\n\ + -Z - Ignore unequal parameters in j2c inputs\n\ +\n\ + NOTES: o There is no option grouping, all options must be distinct arguments.\n\ + o All option arguments must be separated from the option by whitespace.\n\n"); +} + +// +class CommandOptions +{ + CommandOptions(); + +public: + bool error_flag; // true if the given options are in error or not complete + bool key_flag; // true if an encryption key was given + bool read_hmac; // true if HMAC values are to be validated + bool split_wav; // true if PCM is to be extracted to stereo WAV files + bool mono_wav; // true if PCM is to be extracted to mono WAV files + bool verbose_flag; // true if the verbose option was selected + ui32_t fb_dump_size; // number of bytes of frame buffer to dump + bool no_write_flag; // true if no output files are to be written + bool version_flag; // true if the version display option was selected + bool help_flag; // true if the help display option was selected + bool stereo_image_flag; // if true, expect stereoscopic JP2K input (left eye first) + ui32_t number_width; // number of digits in a serialized filename (for JPEG extract) + ui32_t start_frame; // frame number to begin processing + ui32_t duration; // number of frames to be processed + bool duration_flag; // true if duration argument given + bool j2c_pedantic; // passed to JP2K::SequenceParser::OpenRead + ui32_t picture_rate; // fps of picture when wrapping PCM + ui32_t fb_size; // size of picture frame buffer + Rational edit_rate; // frame buffer size for reading clip-wrapped PCM + const char* file_prefix; // filename pre for files written by the extract mode + byte_t key_value[KeyLen]; // value of given encryption key (when key_flag is true) + byte_t key_id_value[UUIDlen];// value of given key ID (when key_id_flag is true) + PCM::ChannelFormat_t channel_fmt; // audio channel arrangement + const char* input_filename; + std::string prefix_buffer; + + // + CommandOptions(int argc, const char** argv) : + error_flag(true), key_flag(false), read_hmac(false), split_wav(false), + mono_wav(false), verbose_flag(false), fb_dump_size(0), no_write_flag(false), + version_flag(false), help_flag(false), number_width(6), + start_frame(0), duration(0xffffffff), duration_flag(false), j2c_pedantic(true), + picture_rate(24), fb_size(FRAME_BUFFER_SIZE), file_prefix(0), + input_filename(0) + { + memset(key_value, 0, KeyLen); + memset(key_id_value, 0, UUIDlen); + + for ( int i = 1; i < argc; ++i ) + { + + if ( (strcmp( argv[i], "-help") == 0) ) + { + help_flag = true; + continue; + } + + if ( argv[i][0] == '-' + && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) + && argv[i][2] == 0 ) + { + switch ( argv[i][1] ) + { + case '1': mono_wav = true; break; + case '2': split_wav = true; break; + + case 'b': + TEST_EXTRA_ARG(i, 'b'); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); + + if ( verbose_flag ) + fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); + + break; + + case 'd': + TEST_EXTRA_ARG(i, 'd'); + duration_flag = true; + duration = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'f': + TEST_EXTRA_ARG(i, 'f'); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'h': help_flag = true; break; + case 'm': read_hmac = true; break; + + case 'p': + TEST_EXTRA_ARG(i, 'p'); + picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 's': + TEST_EXTRA_ARG(i, 's'); + fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'V': version_flag = true; break; + case 'v': verbose_flag = true; break; + case 'W': no_write_flag = true; break; + + case 'w': + TEST_EXTRA_ARG(i, 'w'); + number_width = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'Z': j2c_pedantic = false; break; + case 'z': j2c_pedantic = true; break; + + default: + fprintf(stderr, "Unrecognized option: %s\n", argv[i]); + return; + } + } + else + { + if ( argv[i][0] != '-' ) + { + if ( input_filename == 0 ) + { + input_filename = argv[i]; + } + else if ( file_prefix == 0 ) + { + file_prefix = argv[i]; + } + } + else + { + fprintf(stderr, "Unrecognized argument: %s\n", argv[i]); + return; + } + } + } + + if ( help_flag || version_flag ) + return; + + if ( input_filename == 0 ) + { + fputs("At least one filename argument is required.\n", stderr); + return; + } + + if ( file_prefix == 0 ) + { + prefix_buffer = Kumu::PathSetExtension(input_filename, "") + "_"; + file_prefix = prefix_buffer.c_str(); + } + + error_flag = false; + } +}; + + +//------------------------------------------------------------------------------------------ +// JPEG 2000 essence + + +// Read one or more plaintext JPEG 2000 codestreams from a plaintext ASDCP file +// Read one or more plaintext JPEG 2000 codestreams from a ciphertext ASDCP file +// Read one or more ciphertext JPEG 2000 codestreams from a ciphertext ASDCP file +// +Result_t +read_JP2K_file(CommandOptions& Options) +{ + AESDecContext* Context = 0; + HMACContext* HMAC = 0; + AS_02::JP2K::MXFReader Reader; + JP2K::FrameBuffer FrameBuffer(Options.fb_size); + ui32_t frame_count = 0; + + Result_t result = Reader.OpenRead(Options.input_filename); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + { + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + } + + ASDCP::MXF::RGBAEssenceDescriptor *rgba_descriptor = 0; + ASDCP::MXF::CDCIEssenceDescriptor *cdci_descriptor = 0; + + result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&rgba_descriptor)); + + if ( KM_SUCCESS(result) ) + { + assert(rgba_descriptor); + frame_count = rgba_descriptor->ContainerDuration; + + if ( Options.verbose_flag ) + { + rgba_descriptor->Dump(); + } + } + else + { + result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_CDCIEssenceDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&cdci_descriptor)); + + if ( KM_SUCCESS(result) ) + { + assert(cdci_descriptor); + frame_count = cdci_descriptor->ContainerDuration; + + if ( Options.verbose_flag ) + { + cdci_descriptor->Dump(); + } + } + else + { + fprintf(stderr, "File does not contain an essence descriptor.\n"); + frame_count = Reader.AS02IndexReader().GetDuration(); + } + } + + if ( frame_count == 0 ) + { + frame_count = Reader.AS02IndexReader().GetDuration(); + } + + if ( frame_count == 0 ) + { + fprintf(stderr, "Unable to determine file duration.\n"); + return RESULT_FAIL; + } + } + + if ( ASDCP_SUCCESS(result) && Options.key_flag ) + { + Context = new AESDecContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) && Options.read_hmac ) + { + WriterInfo Info; + Reader.FillWriterInfo(Info); + + if ( Info.UsesHMAC ) + { + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + else + { + fputs("File does not contain HMAC values, ignoring -m option.\n", stderr); + } + } + } + + ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); + if ( last_frame > frame_count ) + last_frame = frame_count; + + char name_format[64]; + snprintf(name_format, 64, "%%s%%0%du.j2c", Options.number_width); + + for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ ) + { + result = Reader.ReadFrame(i, FrameBuffer, Context, HMAC); + + char filename[1024]; + snprintf(filename, 1024, name_format, Options.file_prefix, i); + + if ( ASDCP_SUCCESS(result) && Options.verbose_flag ) + { + printf("Frame %d, %d bytes", i, FrameBuffer.Size()); + + if ( ! Options.no_write_flag ) + { + printf(" -> %s", filename); + } + + printf("\n"); + } + + if ( ASDCP_SUCCESS(result) && ( ! Options.no_write_flag ) ) + { + Kumu::FileWriter OutFile; + ui32_t write_count; + result = OutFile.OpenWrite(filename); + + if ( ASDCP_SUCCESS(result) ) + result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count); + + if ( ASDCP_SUCCESS(result) && Options.verbose_flag ) + { + FrameBuffer.Dump(stderr, Options.fb_dump_size); + } + } + } + + return result; +} + +//------------------------------------------------------------------------------------------ +// PCM essence + +// Read one or more plaintext PCM audio streams from a plaintext ASDCP file +// Read one or more plaintext PCM audio streams from a ciphertext ASDCP file +// Read one or more ciphertext PCM audio streams from a ciphertext ASDCP file +// +Result_t +read_PCM_file(CommandOptions& Options) +{ + AESDecContext* Context = 0; + HMACContext* HMAC = 0; + AS_02::PCM::MXFReader Reader; + PCM::FrameBuffer FrameBuffer; + WavFileWriter OutWave; + ui32_t last_frame = 0; + ASDCP::MXF::WaveAudioDescriptor *wave_descriptor = 0; + + if ( Options.edit_rate == Rational(0,0) ) // todo, make this available to the CLI + { + Options.edit_rate = EditRate_24; + } + + Result_t result = Reader.OpenRead(Options.input_filename, Options.edit_rate); + + if ( KM_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + { + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + } + + ASDCP::MXF::InterchangeObject* tmp_obj = 0; + + result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor), &tmp_obj); + + if ( KM_SUCCESS(result) ) + { + wave_descriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(tmp_obj); + + if ( wave_descriptor == 0 ) + { + fprintf(stderr, "File does not contain an essence descriptor.\n"); + return RESULT_FAIL; + } + + if ( Options.verbose_flag ) + { + wave_descriptor->Dump(); + } + + if ( wave_descriptor->ContainerDuration.get() == 0 ) + { + fprintf(stderr, "ContainerDuration not set in file descriptor, attempting to use index duration.\n"); + last_frame = Reader.AS02IndexReader().GetDuration(); + } + else + { + last_frame = wave_descriptor->ContainerDuration; + } + + if ( last_frame == 0 ) + { + fprintf(stderr, "Unable to determine file duration.\n"); + return RESULT_FAIL; + } + + assert(wave_descriptor); + FrameBuffer.Capacity(AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, Options.edit_rate)); + last_frame = AS_02::MXF::CalcFramesFromDurationInSamples(last_frame, *wave_descriptor, Options.edit_rate); + } + } + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.duration > 0 && Options.duration < last_frame ) + last_frame = Options.duration; + + if ( Options.start_frame > 0 ) + { + if ( Options.start_frame > last_frame ) + { + fprintf(stderr, "Start value greater than file duration.\n"); + return RESULT_FAIL; + } + + last_frame = Kumu::xmin(Options.start_frame + last_frame, last_frame); + } + + last_frame = last_frame - Options.start_frame; + + PCM::AudioDescriptor ADesc; + + result = MD_to_PCM_ADesc(wave_descriptor, ADesc); + + if ( ASDCP_SUCCESS(result) ) + { + ADesc.ContainerDuration = last_frame; + ADesc.EditRate = Options.edit_rate; + + result = OutWave.OpenWrite(ADesc, Options.file_prefix, + ( Options.split_wav ? WavFileWriter::ST_STEREO : + ( Options.mono_wav ? WavFileWriter::ST_MONO : WavFileWriter::ST_NONE ) )); + } + } + + if ( ASDCP_SUCCESS(result) && Options.key_flag ) + { + Context = new AESDecContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) && Options.read_hmac ) + { + WriterInfo Info; + Reader.FillWriterInfo(Info); + + if ( Info.UsesHMAC ) + { + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + else + { + fputs("File does not contain HMAC values, ignoring -m option.\n", stderr); + } + } + } + + for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ ) + { + result = Reader.ReadFrame(i, FrameBuffer, Context, HMAC); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + { + FrameBuffer.FrameNumber(i); + FrameBuffer.Dump(stderr, Options.fb_dump_size); + } + + if ( FrameBuffer.Size() != FrameBuffer.Capacity() ) + { + fprintf(stderr, "Last frame is incomplete, padding with zeros.\n"); + // actually, it has already been zeroed for us, we just need to recognize the appropriate size + FrameBuffer.Size(FrameBuffer.Capacity()); + } + + result = OutWave.WriteFrame(FrameBuffer); + } + } + + return result; +} + + +// +int +main(int argc, const char** argv) +{ + char str_buf[64]; + CommandOptions Options(argc, argv); + + if ( Options.version_flag ) + banner(); + + if ( Options.help_flag ) + usage(); + + if ( Options.version_flag || Options.help_flag ) + return 0; + + if ( Options.error_flag ) + { + fprintf(stderr, "There was a problem. Type %s -h for help.\n", PROGRAM_NAME); + return 3; + } + + EssenceType_t EssenceType; + Result_t result = ASDCP::EssenceType(Options.input_filename, EssenceType); + + if ( ASDCP_SUCCESS(result) ) + { + switch ( EssenceType ) + { + case ESS_AS02_JPEG_2000: + result = read_JP2K_file(Options); + break; + + case ESS_AS02_PCM_24b_48k: + case ESS_AS02_PCM_24b_96k: + result = read_PCM_file(Options); + break; + + default: + fprintf(stderr, "%s: Unknown file type, not AS-02 essence.\n", Options.input_filename); + return 5; + } + } + + if ( ASDCP_FAILURE(result) ) + { + fputs("Program stopped on error.\n", stderr); + + if ( result != RESULT_FAIL ) + { + fputs(result, stderr); + fputc('\n', stderr); + } + + return 1; + } + + return 0; +} + + +// +// end as-02-unwrap.cpp +// diff --git a/asdcplib/src/as-02-wrap.cpp b/asdcplib/src/as-02-wrap.cpp new file mode 100755 index 00000000..2aa9dd45 --- /dev/null +++ b/asdcplib/src/as-02-wrap.cpp @@ -0,0 +1,987 @@ +/* +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file as-02-wrap.cpp + \version $Id: as-02-wrap.cpp,v 1.22 2015/10/16 16:55:33 jhurst Exp $ + \brief AS-02 file manipulation utility + + This program wraps IMF essence (picture or sound) in to an AS-02 MXF file. + + For more information about AS-02, please refer to the header file AS_02.h + For more information about asdcplib, please refer to the header file AS_DCP.h +*/ + +#include <KM_fileio.h> +#include <KM_prng.h> +#include <AS_02.h> +#include <PCMParserList.h> +#include <Metadata.h> + +using namespace ASDCP; + +const ui32_t FRAME_BUFFER_SIZE = 4 * Kumu::Megabyte; +const ASDCP::Dictionary *g_dict = 0; + + +const char* +RationalToString(const ASDCP::Rational& r, char* buf, const ui32_t& len) +{ + snprintf(buf, len, "%d/%d", r.Numerator, r.Denominator); + return buf; +} + + + +//------------------------------------------------------------------------------------------ +// +// command line option parser class + +static const char* PROGRAM_NAME = "as-02-wrap"; // program name for messages + +// local program identification info written to file headers +class MyInfo : public WriterInfo +{ +public: + MyInfo() + { + static byte_t default_ProductUUID_Data[UUIDlen] = + { 0x7d, 0x83, 0x6e, 0x16, 0x37, 0xc7, 0x4c, 0x22, + 0xb2, 0xe0, 0x46, 0xa7, 0x17, 0xe8, 0x4f, 0x42 }; + + memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen); + CompanyName = "WidgetCo"; + ProductName = "as-02-wrap"; + ProductVersion = ASDCP::Version(); + } +} s_MyInfo; + + + +// Increment the iterator, test for an additional non-option command line argument. +// Causes the caller to return if there are no remaining arguments or if the next +// argument begins with '-'. +#define TEST_EXTRA_ARG(i,c) \ + if ( ++i >= argc || argv[(i)][0] == '-' ) { \ + fprintf(stderr, "Argument not found for option -%c.\n", (c)); \ + return; \ + } + + +// +static void +create_random_uuid(byte_t* uuidbuf) +{ + Kumu::UUID tmp_id; + GenRandomValue(tmp_id); + memcpy(uuidbuf, tmp_id.Value(), tmp_id.Size()); +} + +// +void +banner(FILE* stream = stdout) +{ + fprintf(stream, "\n\ +%s (asdcplib %s)\n\n\ +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst\n\n\ +asdcplib may be copied only under the terms of the license found at\n\ +the top of every file in the asdcplib distribution kit.\n\n\ +Specify the -h (help) option for further information about %s\n\n", + PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME); +} + +// +void +usage(FILE* stream = stdout) +{ + fprintf(stream, "\ +USAGE: %s [-h|-help] [-V]\n\ +\n\ + %s [-a <uuid>] [-A <w>/<h>] [-b <buffer-size>] [-C <UL>] [-d <duration>]\n\ + [-D <depth>] [-e|-E] [-i] [-j <key-id-string>] [-k <key-string>]\n\ + [-M] [-m <expr>] [-p <ul>] [-r <n>/<d>] [-R] [-s <seconds>]\n\ + [-t <min>] [-T <max>] [-u] [-v] [-W] [-x <int>] [-X <int>] [-Y]\n\ + [-z|-Z] <input-file>+ <output-file>\n\n", + PROGRAM_NAME, PROGRAM_NAME); + + fprintf(stream, "\ +Options:\n\ + -h | -help - Show help\n\ + -V - Show version information\n\ + -a <uuid> - Specify the Asset ID of the file\n\ + -A <w>/<h> - Set aspect ratio for image (default 4/3)\n\ + -b <buffer-size> - Specify size in bytes of picture frame buffer\n\ + Defaults to 4,194,304 (4MB)\n\ + -C <ul> - Set ChannelAssignment UL value\n\ + -d <duration> - Number of frames to process, default all\n\ + -D <depth> - Component depth for YCbCr images (default: 10)\n\ + -e - Encrypt JP2K headers (default)\n\ + -E - Do not encrypt JP2K headers\n\ + -F (0|1) - Set field dominance for interlaced image (default: 0)\n\ + -i - Indicates input essence is interlaced fields (forces -Y)\n\ + -j <key-id-str> - Write key ID instead of creating a random value\n\ + -k <key-string> - Use key for ciphertext operations\n\ + -M - Do not create HMAC values when writing\n\ + -m <expr> - Write MCA labels using <expr>. Example:\n\ + 51(L,R,C,LFE,Ls,Rs,),HI,VIN\n\ + -p <ul> - Set broadcast profile\n\ + -r <n>/<d> - Edit Rate of the output file. 24/1 is the default\n\ + -R - Indicates RGB image essence (default)\n\ + -s <seconds> - Duration of a frame-wrapped partition (default 60)\n\ + -t <min> - Set RGB component minimum code value (default: 0)\n\ + -T <max> - Set RGB component maximum code value (default: 1023)\n\ + -u - Print UL catalog to stderr\n\ + -v - Verbose, prints informative messages to stderr\n\ + -W - Read input file only, do not write source file\n\ + -x <int> - Horizontal subsampling degree (default: 2)\n\ + -X <int> - Vertical subsampling degree (default: 2)\n\ + -Y - Indicates YCbCr image essence (default: RGB)\n\ + -z - Fail if j2c inputs have unequal parameters (default)\n\ + -Z - Ignore unequal parameters in j2c inputs\n\ +\n\ + NOTES: o There is no option grouping, all options must be distinct arguments.\n\ + o All option arguments must be separated from the option by whitespace.\n\n"); +} + + +// +// +class CommandOptions +{ + CommandOptions(); + +public: + bool error_flag; // true if the given options are in error or not complete + bool key_flag; // true if an encryption key was given + bool asset_id_flag; // true if an asset ID was given + bool encrypt_header_flag; // true if j2c headers are to be encrypted + bool write_hmac; // true if HMAC values are to be generated and written + bool verbose_flag; // true if the verbose option was selected + ui32_t fb_dump_size; // number of bytes of frame buffer to dump + bool no_write_flag; // true if no output files are to be written + bool version_flag; // true if the version display option was selected + bool help_flag; // true if the help display option was selected + ui32_t duration; // number of frames to be processed + bool j2c_pedantic; // passed to JP2K::SequenceParser::OpenRead + bool use_cdci_descriptor; // + Rational edit_rate; // edit rate of JP2K sequence + ui32_t fb_size; // size of picture frame buffer + byte_t key_value[KeyLen]; // value of given encryption key (when key_flag is true) + bool key_id_flag; // true if a key ID was given + byte_t key_id_value[UUIDlen];// value of given key ID (when key_id_flag is true) + byte_t asset_id_value[UUIDlen];// value of asset ID (when asset_id_flag is true) + std::string out_file; // + bool show_ul_values_flag; /// if true, dump the UL table before going tp work. + Kumu::PathList_t filenames; // list of filenames to be processed + + UL channel_assignment; + ASDCP::MXF::AS02_MCAConfigParser mca_config; + + UL picture_coding; + ui32_t rgba_MaxRef; + ui32_t rgba_MinRef; + + ui32_t horizontal_subsampling; + ui32_t vertical_subsampling; + ui32_t component_depth; + ui8_t frame_layout; + ASDCP::Rational aspect_ratio; + ui8_t field_dominance; + ui32_t mxf_header_size; + + //new attributes for AS-02 support + AS_02::IndexStrategy_t index_strategy; //Shim parameter index_strategy_frame/clip + ui32_t partition_space; //Shim parameter partition_spacing + + // + CommandOptions(int argc, const char** argv) : + error_flag(true), key_flag(false), key_id_flag(false), asset_id_flag(false), + encrypt_header_flag(true), write_hmac(true), verbose_flag(false), fb_dump_size(0), + no_write_flag(false), version_flag(false), help_flag(false), + duration(0xffffffff), j2c_pedantic(true), use_cdci_descriptor(false), edit_rate(24,1), fb_size(FRAME_BUFFER_SIZE), + show_ul_values_flag(false), index_strategy(AS_02::IS_FOLLOW), partition_space(60), + mca_config(g_dict), rgba_MaxRef(1023), rgba_MinRef(0), + horizontal_subsampling(2), vertical_subsampling(2), component_depth(10), + frame_layout(0), aspect_ratio(ASDCP::Rational(4,3)), field_dominance(0), + mxf_header_size(16384) + { + memset(key_value, 0, KeyLen); + memset(key_id_value, 0, UUIDlen); + + for ( int i = 1; i < argc; i++ ) + { + + if ( (strcmp( argv[i], "-help") == 0) ) + { + help_flag = true; + continue; + } + + if ( argv[i][0] == '-' + && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) + && argv[i][2] == 0 ) + { + switch ( argv[i][1] ) + { + case 'A': + TEST_EXTRA_ARG(i, 'A'); + if ( ! DecodeRational(argv[i], aspect_ratio) ) + { + fprintf(stderr, "Error decoding aspect ratio value: %s\n", argv[i]); + return; + } + break; + + case 'a': + asset_id_flag = true; + TEST_EXTRA_ARG(i, 'a'); + { + ui32_t length; + Kumu::hex2bin(argv[i], asset_id_value, UUIDlen, &length); + + if ( length != UUIDlen ) + { + fprintf(stderr, "Unexpected asset ID length: %u, expecting %u characters.\n", length, UUIDlen); + return; + } + } + break; + + case 'b': + TEST_EXTRA_ARG(i, 'b'); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); + + if ( verbose_flag ) + fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); + + break; + + case 'C': + TEST_EXTRA_ARG(i, 'C'); + if ( ! channel_assignment.DecodeHex(argv[i]) ) + { + fprintf(stderr, "Error decoding ChannelAssignment UL value: %s\n", argv[i]); + return; + } + break; + + case 'D': + TEST_EXTRA_ARG(i, 'D'); + component_depth = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'd': + TEST_EXTRA_ARG(i, 'd'); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'E': encrypt_header_flag = false; break; + case 'e': encrypt_header_flag = true; break; + + case 'F': + TEST_EXTRA_ARG(i, 'F'); + field_dominance = Kumu::xabs(strtol(argv[i], 0, 10)); + if ( field_dominance > 1 ) + { + fprintf(stderr, "Field dominance value must be \"0\" or \"1\"\n"); + return; + } + break; + + case 'h': help_flag = true; break; + + case 'i': + frame_layout = 1; + use_cdci_descriptor = true; + break; + + case 'j': + key_id_flag = true; + TEST_EXTRA_ARG(i, 'j'); + { + ui32_t length; + Kumu::hex2bin(argv[i], key_id_value, UUIDlen, &length); + + if ( length != UUIDlen ) + { + fprintf(stderr, "Unexpected key ID length: %u, expecting %u characters.\n", length, UUIDlen); + return; + } + } + break; + + case 'k': key_flag = true; + TEST_EXTRA_ARG(i, 'k'); + { + ui32_t length; + Kumu::hex2bin(argv[i], key_value, KeyLen, &length); + + if ( length != KeyLen ) + { + fprintf(stderr, "Unexpected key length: %u, expecting %u characters.\n", length, KeyLen); + return; + } + } + break; + + case 'M': write_hmac = false; break; + + case 'm': + TEST_EXTRA_ARG(i, 'm'); + if ( ! mca_config.DecodeString(argv[i]) ) + { + return; + } + break; + + case 'p': + TEST_EXTRA_ARG(i, 'p'); + if ( ! picture_coding.DecodeHex(argv[i]) ) + { + fprintf(stderr, "Error decoding PictureEssenceCoding UL value: %s\n", argv[i]); + return; + } + break; + + case 'r': + TEST_EXTRA_ARG(i, 'r'); + if ( ! DecodeRational(argv[i], edit_rate) ) + { + fprintf(stderr, "Error decoding edit rate value: %s\n", argv[i]); + return; + } + + break; + + case 'R': + use_cdci_descriptor = false; + break; + + case 's': + TEST_EXTRA_ARG(i, 's'); + partition_space = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 't': + TEST_EXTRA_ARG(i, 't'); + rgba_MinRef = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'T': + TEST_EXTRA_ARG(i, 'T'); + rgba_MaxRef = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'u': show_ul_values_flag = true; break; + case 'V': version_flag = true; break; + case 'v': verbose_flag = true; break; + case 'W': no_write_flag = true; break; + + case 'x': + TEST_EXTRA_ARG(i, 'x'); + horizontal_subsampling = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'X': + TEST_EXTRA_ARG(i, 'X'); + vertical_subsampling = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'Y': + use_cdci_descriptor = true; + break; + + case 'Z': j2c_pedantic = false; break; + case 'z': j2c_pedantic = true; break; + + default: + fprintf(stderr, "Unrecognized option: %s\n", argv[i]); + return; + } + } + else + { + + if ( argv[i][0] != '-' ) + { + filenames.push_back(argv[i]); + } + else + { + fprintf(stderr, "Unrecognized argument: %s\n", argv[i]); + return; + } + } + } + + if ( help_flag || version_flag ) + return; + + if ( filenames.size() < 2 ) + { + fputs("Option requires at least two filename arguments: <input-file> <output-file>\n", stderr); + return; + } + + out_file = filenames.back(); + filenames.pop_back(); + + if ( ! picture_coding.HasValue() ) + { + picture_coding = UL(g_dict->ul(MDD_JP2KEssenceCompression_BroadcastProfile_1)); + } + + error_flag = false; + } +}; + + +//------------------------------------------------------------------------------------------ +// JPEG 2000 essence + +namespace ASDCP { + Result_t JP2K_PDesc_to_MD(const ASDCP::JP2K::PictureDescriptor& PDesc, + const ASDCP::Dictionary& dict, + ASDCP::MXF::GenericPictureEssenceDescriptor& GenericPictureEssenceDescriptor, + ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor); + + Result_t PCM_ADesc_to_MD(ASDCP::PCM::AudioDescriptor& ADesc, ASDCP::MXF::WaveAudioDescriptor* ADescObj); +} + +// Write one or more plaintext JPEG 2000 codestreams to a plaintext AS-02 file +// Write one or more plaintext JPEG 2000 codestreams to a ciphertext AS-02 file +// +Result_t +write_JP2K_file(CommandOptions& Options) +{ + AESEncContext* Context = 0; + HMACContext* HMAC = 0; + AS_02::JP2K::MXFWriter Writer; + JP2K::FrameBuffer FrameBuffer(Options.fb_size); + JP2K::SequenceParser Parser; + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; + ASDCP::MXF::FileDescriptor *essence_descriptor = 0; + ASDCP::MXF::InterchangeObject_list_t essence_sub_descriptors; + + // set up essence parser + Result_t result = Parser.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic); + + // set up MXF writer + if ( ASDCP_SUCCESS(result) ) + { + ASDCP::JP2K::PictureDescriptor PDesc; + Parser.FillPictureDescriptor(PDesc); + PDesc.EditRate = Options.edit_rate; + + if ( Options.verbose_flag ) + { + fprintf(stderr, "JPEG 2000 pictures\n"); + fputs("PictureDescriptor:\n", stderr); + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + JP2K::PictureDescriptorDump(PDesc); + } + + if ( Options.use_cdci_descriptor ) + { + ASDCP::MXF::CDCIEssenceDescriptor* tmp_dscr = new ASDCP::MXF::CDCIEssenceDescriptor(g_dict); + essence_sub_descriptors.push_back(new ASDCP::MXF::JPEG2000PictureSubDescriptor(g_dict)); + + result = ASDCP::JP2K_PDesc_to_MD(PDesc, *g_dict, + *static_cast<ASDCP::MXF::GenericPictureEssenceDescriptor*>(tmp_dscr), + *static_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back())); + + if ( ASDCP_SUCCESS(result) ) + { + tmp_dscr->PictureEssenceCoding = Options.picture_coding; + tmp_dscr->HorizontalSubsampling = Options.horizontal_subsampling; + tmp_dscr->VerticalSubsampling = Options.vertical_subsampling; + tmp_dscr->ComponentDepth = Options.component_depth; + tmp_dscr->FrameLayout = Options.frame_layout; + tmp_dscr->AspectRatio = Options.aspect_ratio; + tmp_dscr->FieldDominance = Options.field_dominance; + essence_descriptor = static_cast<ASDCP::MXF::FileDescriptor*>(tmp_dscr); + } + } + else + { // use RGB + ASDCP::MXF::RGBAEssenceDescriptor* tmp_dscr = new ASDCP::MXF::RGBAEssenceDescriptor(g_dict); + essence_sub_descriptors.push_back(new ASDCP::MXF::JPEG2000PictureSubDescriptor(g_dict)); + + result = ASDCP::JP2K_PDesc_to_MD(PDesc, *g_dict, + *static_cast<ASDCP::MXF::GenericPictureEssenceDescriptor*>(tmp_dscr), + *static_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back())); + + if ( ASDCP_SUCCESS(result) ) + { + tmp_dscr->PictureEssenceCoding = UL(g_dict->ul(MDD_JP2KEssenceCompression_BroadcastProfile_1)); + tmp_dscr->ComponentMaxRef = Options.rgba_MaxRef; + tmp_dscr->ComponentMinRef = Options.rgba_MinRef; + essence_descriptor = static_cast<ASDCP::MXF::FileDescriptor*>(tmp_dscr); + } + } + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here + Info.LabelSetType = LS_MXF_SMPTE; + + if ( Options.asset_id_flag ) + memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen); + else + Kumu::GenRandomUUID(Info.AssetUUID); + + // configure encryption + if( Options.key_flag ) + { + Kumu::GenRandomUUID(Info.ContextID); + Info.EncryptedEssence = true; + + if ( Options.key_id_flag ) + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } + else + { + create_random_uuid(Info.CryptographicKeyID); + } + + Context = new AESEncContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) ) + result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + + if ( ASDCP_SUCCESS(result) && Options.write_hmac ) + { + Info.UsesHMAC = true; + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + } + + if ( ASDCP_SUCCESS(result) ) + { + result = Writer.OpenWrite(Options.out_file, Info, essence_descriptor, essence_sub_descriptors, + Options.edit_rate, Options.mxf_header_size, Options.index_strategy, Options.partition_space); + } + } + + if ( ASDCP_SUCCESS(result) ) + { + ui32_t duration = 0; + result = Parser.Reset(); + + while ( ASDCP_SUCCESS(result) && duration++ < Options.duration ) + { + result = Parser.ReadFrame(FrameBuffer); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + + if ( Options.encrypt_header_flag ) + FrameBuffer.PlaintextOffset(0); + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + result = Writer.WriteFrame(FrameBuffer, Context, HMAC); + + // The Writer class will forward the last block of ciphertext + // to the encryption context for use as the IV for the next + // frame. If you want to use non-sequitur IV values, un-comment + // the following line of code. + // if ( ASDCP_SUCCESS(result) && Options.key_flag ) + // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + } + } + + if ( result == RESULT_ENDOFFILE ) + result = RESULT_OK; + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + result = Writer.Finalize(); + + return result; +} + +//------------------------------------------------------------------------------------------ +// PCM essence + + +// Write one or more plaintext PCM audio streams to a plaintext AS-02 file +// Write one or more plaintext PCM audio streams to a ciphertext AS-02 file +// +Result_t +write_PCM_file(CommandOptions& Options) +{ + AESEncContext* Context = 0; + HMACContext* HMAC = 0; + PCMParserList Parser; + AS_02::PCM::MXFWriter Writer; + PCM::FrameBuffer FrameBuffer; + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; + ASDCP::MXF::WaveAudioDescriptor *essence_descriptor = 0; + + // set up essence parser + Result_t result = Parser.OpenRead(Options.filenames, Options.edit_rate); + + // set up MXF writer + if ( ASDCP_SUCCESS(result) ) + { + ASDCP::PCM::AudioDescriptor ADesc; + Parser.FillAudioDescriptor(ADesc); + + ADesc.EditRate = Options.edit_rate; + FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc)); + + if ( Options.verbose_flag ) + { + char buf[64]; + fprintf(stderr, "%.1fkHz PCM Audio, %s fps (%u spf)\n", + ADesc.AudioSamplingRate.Quotient() / 1000.0, + RationalToString(Options.edit_rate, buf, 64), + PCM::CalcSamplesPerFrame(ADesc)); + fputs("AudioDescriptor:\n", stderr); + PCM::AudioDescriptorDump(ADesc); + } + + essence_descriptor = new ASDCP::MXF::WaveAudioDescriptor(g_dict); + + result = ASDCP::PCM_ADesc_to_MD(ADesc, essence_descriptor); + + if ( Options.mca_config.empty() ) + { + essence_descriptor->ChannelAssignment = Options.channel_assignment; + } + else + { + if ( Options.mca_config.ChannelCount() != essence_descriptor->ChannelCount ) + { + fprintf(stderr, "MCA label count (%d) differs from essence stream channel count (%d).\n", + Options.mca_config.ChannelCount(), essence_descriptor->ChannelCount); + return RESULT_FAIL; + } + + // this is the d-cinema MCA label, what is the one for IMF? + essence_descriptor->ChannelAssignment = g_dict->ul(MDD_IMFAudioChannelCfg_MCA); + } + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here + Info.LabelSetType = LS_MXF_SMPTE; + + if ( Options.asset_id_flag ) + memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen); + else + Kumu::GenRandomUUID(Info.AssetUUID); + + // configure encryption + if( Options.key_flag ) + { + Kumu::GenRandomUUID(Info.ContextID); + Info.EncryptedEssence = true; + + if ( Options.key_id_flag ) + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } + else + { + create_random_uuid(Info.CryptographicKeyID); + } + + Context = new AESEncContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) ) + result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + + if ( ASDCP_SUCCESS(result) && Options.write_hmac ) + { + Info.UsesHMAC = true; + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + } + + if ( ASDCP_SUCCESS(result) ) + { + result = Writer.OpenWrite(Options.out_file.c_str(), Info, essence_descriptor, + Options.mca_config, Options.edit_rate); + } + } + + if ( ASDCP_SUCCESS(result) ) + { + result = Parser.Reset(); + ui32_t duration = 0; + + while ( ASDCP_SUCCESS(result) && duration++ < Options.duration ) + { + result = Parser.ReadFrame(FrameBuffer); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + + if ( ! Options.no_write_flag ) + { + result = Writer.WriteFrame(FrameBuffer, Context, HMAC); + + // The Writer class will forward the last block of ciphertext + // to the encryption context for use as the IV for the next + // frame. If you want to use non-sequitur IV values, un-comment + // the following line of code. + // if ( ASDCP_SUCCESS(result) && Options.key_flag ) + // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + } + } + } + + if ( result == RESULT_ENDOFFILE ) + result = RESULT_OK; + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + result = Writer.Finalize(); + + return result; +} + + + + +//------------------------------------------------------------------------------------------ +// TimedText essence + + +// Write one or more plaintext timed text streams to a plaintext AS-02 file +// Write one or more plaintext timed text streams to a ciphertext AS-02 file +// +Result_t +write_timed_text_file(CommandOptions& Options) +{ + AESEncContext* Context = 0; + HMACContext* HMAC = 0; + AS_02::TimedText::ST2052_TextParser Parser; + AS_02::TimedText::MXFWriter Writer; + TimedText::FrameBuffer FrameBuffer; + TimedText::TimedTextDescriptor TDesc; + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; + + // set up essence parser + Result_t result = Parser.OpenRead(Options.filenames.front().c_str()); + + // set up MXF writer + if ( ASDCP_SUCCESS(result) ) + { + Parser.FillTimedTextDescriptor(TDesc); + TDesc.EditRate = Options.edit_rate; + TDesc.ContainerDuration = Options.duration; + FrameBuffer.Capacity(Options.fb_size); + + if ( Options.verbose_flag ) + { + fputs("IMF Timed-Text Descriptor:\n", stderr); + TimedText::DescriptorDump(TDesc); + } + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here + Info.LabelSetType = LS_MXF_SMPTE; + + if ( Options.asset_id_flag ) + memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen); + else + Kumu::GenRandomUUID(Info.AssetUUID); + + // configure encryption + if( Options.key_flag ) + { + Kumu::GenRandomUUID(Info.ContextID); + Info.EncryptedEssence = true; + + if ( Options.key_id_flag ) + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } + else + { + create_random_uuid(Info.CryptographicKeyID); + } + + Context = new AESEncContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) ) + result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + + if ( ASDCP_SUCCESS(result) && Options.write_hmac ) + { + Info.UsesHMAC = true; + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + } + + if ( ASDCP_SUCCESS(result) ) + result = Writer.OpenWrite(Options.out_file.c_str(), Info, TDesc); + } + + if ( ASDCP_FAILURE(result) ) + return result; + + std::string XMLDoc; + TimedText::ResourceList_t::const_iterator ri; + + result = Parser.ReadTimedTextResource(XMLDoc); + + if ( ASDCP_SUCCESS(result) ) + result = Writer.WriteTimedTextResource(XMLDoc, Context, HMAC); + + for ( ri = TDesc.ResourceList.begin() ; ri != TDesc.ResourceList.end() && ASDCP_SUCCESS(result); ri++ ) + { + result = Parser.ReadAncillaryResource((*ri).ResourceID, FrameBuffer); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + + if ( ! Options.no_write_flag ) + { + result = Writer.WriteAncillaryResource(FrameBuffer, Context, HMAC); + + // The Writer class will forward the last block of ciphertext + // to the encryption context for use as the IV for the next + // frame. If you want to use non-sequitur IV values, un-comment + // the following line of code. + // if ( ASDCP_SUCCESS(result) && Options.key_flag ) + // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + } + } + + if ( result == RESULT_ENDOFFILE ) + result = RESULT_OK; + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + result = Writer.Finalize(); + + return result; +} + +// +int +main(int argc, const char** argv) +{ + Result_t result = RESULT_OK; + char str_buf[64]; + g_dict = &ASDCP::DefaultSMPTEDict(); + assert(g_dict); + + CommandOptions Options(argc, argv); + + if ( Options.version_flag ) + banner(); + + if ( Options.help_flag ) + usage(); + + if ( Options.show_ul_values_flag ) + { + g_dict->Dump(stdout); + } + + if ( Options.version_flag || Options.help_flag || Options.show_ul_values_flag ) + return 0; + + if ( Options.error_flag ) + { + fprintf(stderr, "There was a problem. Type %s -h for help.\n", PROGRAM_NAME); + return 3; + } + + EssenceType_t EssenceType; + result = ASDCP::RawEssenceType(Options.filenames.front().c_str(), EssenceType); + + if ( ASDCP_SUCCESS(result) ) + { + switch ( EssenceType ) + { + case ESS_JPEG_2000: + result = write_JP2K_file(Options); + break; + + case ESS_PCM_24b_48k: + case ESS_PCM_24b_96k: + result = write_PCM_file(Options); + break; + + case ESS_TIMED_TEXT: + result = write_timed_text_file(Options); + break; + + default: + fprintf(stderr, "%s: Unknown file type, not ASDCP-compatible essence.\n", + Options.filenames.front().c_str()); + return 5; + } + } + + if ( ASDCP_FAILURE(result) ) + { + fputs("Program stopped on error.\n", stderr); + + if ( result != RESULT_FAIL ) + { + fputs(result, stderr); + fputc('\n', stderr); + } + + return 1; + } + + return 0; +} + + +// +// end as-02-wrap.cpp +// diff --git a/asdcplib/src/asdcp-info.cpp b/asdcplib/src/asdcp-info.cpp index 06227632..e20ae91c 100755 --- a/asdcplib/src/asdcp-info.cpp +++ b/asdcplib/src/asdcp-info.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2012, John Hurst +Copyright (c) 2003-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file asdcp-info.cpp - \version $Id: asdcp-info.cpp,v 1.1 2012/02/03 19:49:56 jhurst Exp $ + \version $Id: asdcp-info.cpp,v 1.12 2015/10/07 16:41:23 jhurst Exp $ \brief AS-DCP file metadata utility This program provides metadata information about an AS-DCP file. @@ -35,15 +35,25 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_fileio.h> #include <AS_DCP.h> +#include <AS_02.h> #include <MXF.h> #include <Metadata.h> -#include <openssl/sha.h> using namespace Kumu; using namespace ASDCP; const ui32_t FRAME_BUFFER_SIZE = 4 * Kumu::Megabyte; +const byte_t P_HFR_UL_2K[16] = { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, + 0x0e, 0x16, 0x02, 0x02, 0x03, 0x01, 0x01, 0x03 +}; + +const byte_t P_HFR_UL_4K[16] = { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, + 0x0e, 0x16, 0x02, 0x02, 0x03, 0x01, 0x01, 0x04 +}; + //------------------------------------------------------------------------------------------ // // command line option parser class @@ -66,7 +76,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2003-2012 John Hurst\n\n\ +Copyright (c) 2003-2015 John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", @@ -80,14 +90,19 @@ usage(FILE* stream = stdout) fprintf(stream, "\ USAGE:%s [-h|-help] [-V]\n\ \n\ - %s [-3] [-H] [-n] <input-file>+\n\ + %s [options] <input-file>+\n\ \n\ Options:\n\ - -3 - Force stereoscopic interpretation of a JP2K file\n\ - -h | -help - Show help\n\ - -H - Show MXF header metadata\n\ - -n - Show index\n\ - -V - Show version information\n\ + -3 - Force stereoscopic interpretation of a JP2K file\n\ + -c - Show essence coding UL\n\ + -d - Show essence descriptor info\n\ + -h | -help - Show help\n\ + -H - Show MXF header metadata\n\ + -i - Show identity info\n\ + -n - Show index\n\ + -r - Show bit-rate (Mb/s)\n\ + -t <int> - Set high-bitrate threshold (Mb/s)\n\ + -V - Show version information\n\ \n\ NOTES: o There is no option grouping, all options must be distinct arguments.\n\ o All option arguments must be separated from the option by whitespace.\n\n", @@ -104,15 +119,24 @@ public: bool error_flag; // true if the given options are in error or not complete bool version_flag; // true if the version display option was selected bool help_flag; // true if the help display option was selected + bool verbose_flag; // true if the verbose option was selected PathList_t filenames; // list of filenames to be processed bool showindex_flag; // true if index is to be displayed bool showheader_flag; // true if MXF file header is to be displayed bool stereo_image_flag; // if true, expect stereoscopic JP2K input (left eye first) + bool showid_flag; // if true, show file identity info (the WriterInfo struct) + bool showdescriptor_flag; // if true, show the essence descriptor + bool showcoding_flag; // if true, show the coding UL + bool showrate_flag; // if true and is image file, show bit rate + bool max_bitrate_flag; // true if -t option given + double max_bitrate; // if true and is image file, max bit rate for rate test // CommandOptions(int argc, const char** argv) : - error_flag(true), version_flag(false), help_flag(false), - showindex_flag(), showheader_flag(), stereo_image_flag(false) + error_flag(true), version_flag(false), help_flag(false), verbose_flag(false), + showindex_flag(), showheader_flag(), stereo_image_flag(false), + showid_flag(false), showdescriptor_flag(false), showcoding_flag(false), + showrate_flag(false), max_bitrate_flag(false), max_bitrate(0.0) { for ( int i = 1; i < argc; ++i ) { @@ -122,7 +146,7 @@ public: help_flag = true; continue; } - + if ( argv[i][0] == '-' && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) && argv[i][2] == 0 ) @@ -130,10 +154,22 @@ public: switch ( argv[i][1] ) { case '3': stereo_image_flag = true; break; + case 'c': showcoding_flag = true; break; + case 'd': showdescriptor_flag = true; break; case 'H': showheader_flag = true; break; case 'h': help_flag = true; break; + case 'i': showid_flag = true; break; case 'n': showindex_flag = true; break; + case 'r': showrate_flag = true; break; + + case 't': + TEST_EXTRA_ARG(i, 't'); + max_bitrate = Kumu::xabs(strtol(argv[i], 0, 10)); + max_bitrate_flag = true; + break; + case 'V': version_flag = true; break; + case 'v': verbose_flag = true; break; default: fprintf(stderr, "Unrecognized option: %s\n", argv[i]); @@ -156,10 +192,10 @@ public: if ( help_flag || version_flag ) return; - + if ( filenames.empty() ) { - fputs("Option requires at least one filename argument.\n", stderr); + fputs("At least one filename argument is required.\n", stderr); return; } @@ -235,12 +271,48 @@ class MyTextDescriptor : public TimedText::TimedTextDescriptor } }; -// MSVC didn't like the function template, so now it's a static class method +class MyDCDataDescriptor : public DCData::DCDataDescriptor +{ + public: + void FillDescriptor(DCData::MXFReader& Reader) { + Reader.FillDCDataDescriptor(*this); + } + + void Dump(FILE* stream) { + DCData::DCDataDescriptorDump(*this, stream); + } +}; + +class MyAtmosDescriptor : public ATMOS::AtmosDescriptor +{ + public: + void FillDescriptor(ATMOS::MXFReader& Reader) { + Reader.FillAtmosDescriptor(*this); + } + + void Dump(FILE* stream) { + ATMOS::AtmosDescriptorDump(*this, stream); + } +}; + +// +// template<class ReaderT, class DescriptorT> class FileInfoWrapper { + ReaderT m_Reader; + DescriptorT m_Desc; + WriterInfo m_WriterInfo; + double m_MaxBitrate, m_AvgBitrate; + UL m_PictureEssenceCoding; + + KM_NO_COPY_CONSTRUCT(FileInfoWrapper); + public: - static Result_t + FileInfoWrapper() : m_MaxBitrate(0.0), m_AvgBitrate(0.0) {} + virtual ~FileInfoWrapper() {} + + Result_t file_info(CommandOptions& Options, const char* type_string, FILE* stream = 0) { assert(type_string); @@ -248,36 +320,215 @@ public: stream = stdout; Result_t result = RESULT_OK; - ReaderT Reader; - result = Reader.OpenRead(Options.filenames.front().c_str()); + result = m_Reader.OpenRead(Options.filenames.front().c_str()); if ( ASDCP_SUCCESS(result) ) { - fprintf(stdout, "File essence type is %s.\n", type_string); + m_Desc.FillDescriptor(m_Reader); + m_Reader.FillWriterInfo(m_WriterInfo); + + fprintf(stdout, "%s file essence type is %s, (%d edit unit%s).\n", + ( m_WriterInfo.LabelSetType == LS_MXF_SMPTE ? "SMPTE 429" : LS_MXF_INTEROP ? "Interop" : "Unknown" ), + type_string, m_Desc.ContainerDuration, (m_Desc.ContainerDuration==1?"":"s")); if ( Options.showheader_flag ) - Reader.DumpHeaderMetadata(stream); + m_Reader.DumpHeaderMetadata(stream); - WriterInfo WI; - Reader.FillWriterInfo(WI); - WriterInfoDump(WI, stream); + if ( Options.showid_flag ) + WriterInfoDump(m_WriterInfo, stream); - DescriptorT Desc; - Desc.FillDescriptor(Reader); - Desc.Dump(stream); + if ( Options.showdescriptor_flag ) + m_Desc.Dump(stream); if ( Options.showindex_flag ) - Reader.DumpIndex(stream); + m_Reader.DumpIndex(stream); } else if ( result == RESULT_FORMAT && Options.showheader_flag ) { - Reader.DumpHeaderMetadata(stream); + m_Reader.DumpHeaderMetadata(stream); } return result; } + + // + void get_PictureEssenceCoding(FILE* stream = 0) + { + const Dictionary& Dict = DefaultCompositeDict(); + MXF::RGBAEssenceDescriptor *descriptor = 0; + + Result_t result = m_Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&descriptor)); + + if ( KM_SUCCESS(result) ) + m_PictureEssenceCoding = descriptor->PictureEssenceCoding; + } + + + // + void dump_PictureEssenceCoding(FILE* stream = 0) + { + char buf[64]; + + if ( m_PictureEssenceCoding.HasValue() ) + { + const char *encoding_ul_type = "**UNKNOWN**"; + + if ( m_PictureEssenceCoding == UL(P_HFR_UL_2K) ) + encoding_ul_type = "P-HFR-2K"; + else if ( m_PictureEssenceCoding == UL(P_HFR_UL_4K) ) + encoding_ul_type = "**P-HFR-4K**"; + else if ( m_PictureEssenceCoding == DefaultCompositeDict().ul(MDD_JP2KEssenceCompression_2K) ) + encoding_ul_type = "ST-429-4-2K"; + else if ( m_PictureEssenceCoding == DefaultCompositeDict().ul(MDD_JP2KEssenceCompression_4K) ) + encoding_ul_type = "ST-429-4-4K"; + + fprintf(stream, "PictureEssenceCoding: %s (%s)\n", m_PictureEssenceCoding.EncodeString(buf, 64), encoding_ul_type); + } + } + + // + Result_t + test_rates(CommandOptions& Options, FILE* stream = 0) + { + static const double dci_max_bitrate = 250.0; + static const double p_hfr_max_bitrate = 400.0; + + double max_bitrate = Options.max_bitrate_flag ? Options.max_bitrate : dci_max_bitrate; + ui32_t errors = 0; + + if ( m_PictureEssenceCoding == UL(P_HFR_UL_2K) ) + { + if ( m_Desc.StoredWidth > 2048 ) // 4k + { + fprintf(stream, "4k images marked as 2k HFR.\n"); + ++errors; + } + + if ( m_Desc.SampleRate < ASDCP::EditRate_96 ) + { + fprintf(stream, "HFR UL used for fps < 96.\n"); + ++errors; + } + + if ( ! Options.max_bitrate_flag ) + max_bitrate = p_hfr_max_bitrate; + } + else if ( m_PictureEssenceCoding == UL(P_HFR_UL_4K) ) + { + fprintf(stream, "4k HFR support undefined.\n"); + ++errors; + + if ( m_Desc.StoredWidth <= 2048 ) // 2k + { + fprintf(stream, "2k images marked as 4k HFR.\n"); + ++errors; + } + } + else if ( m_PictureEssenceCoding != DefaultCompositeDict().ul(MDD_JP2KEssenceCompression_2K) + && m_PictureEssenceCoding != DefaultCompositeDict().ul(MDD_JP2KEssenceCompression_4K) ) + { + fprintf(stream, "Unknown PictureEssenceCoding UL value.\n"); + ++errors; + } + else + { + if ( m_PictureEssenceCoding == DefaultCompositeDict().ul(MDD_JP2KEssenceCompression_2K) ) + { + if ( m_Desc.StoredWidth > 2048 ) // 4k + { + fprintf(stream, "4k images marked as 2k ST 429-4.\n"); + ++errors; + } + } + else if ( m_PictureEssenceCoding == DefaultCompositeDict().ul(MDD_JP2KEssenceCompression_4K) ) + { + if ( m_Desc.StoredWidth <= 2048 ) // 2k + { + fprintf(stream, "2k images marked as 4k ST 429-4.\n"); + ++errors; + } + } + } + + if ( m_MaxBitrate > max_bitrate ) + { + fprintf(stream, "Bitrate %0.0f exceeds maximum %0.0f (see option -r).\n", m_MaxBitrate, max_bitrate); + ++errors; + } + + return errors ? RESULT_FAIL : RESULT_OK; + } + + // + void + calc_Bitrate(FILE* stream = 0) + { + MXF::OPAtomIndexFooter& footer = m_Reader.OPAtomIndexFooter(); + ui64_t total_frame_bytes = 0, last_stream_offset = 0; + ui32_t largest_frame = 0; + Result_t result = RESULT_OK; + + for ( ui32_t i = 0; KM_SUCCESS(result) && i < m_Desc.ContainerDuration; ++i ) + { + MXF::IndexTableSegment::IndexEntry entry; + result = footer.Lookup(i, entry); + + if ( KM_SUCCESS(result) ) + { + if ( last_stream_offset != 0 ) + { + ui64_t this_frame_size = entry.StreamOffset - last_stream_offset - 20; // do not count the bytes that represent the KLV wrapping + total_frame_bytes += this_frame_size; + + if ( this_frame_size > largest_frame ) + largest_frame = this_frame_size; + } + + last_stream_offset = entry.StreamOffset; + } + } + + if ( KM_SUCCESS(result) ) + { + // scale bytes to megabits + static const double mega_const = 1.0 / ( 1000000 / 8.0 ); + + // we did not accumulate the first or last frame, so duration -= 2 + double avg_bytes_frame = total_frame_bytes / ( m_Desc.ContainerDuration - 2 ); + + m_MaxBitrate = largest_frame * mega_const * m_Desc.EditRate.Quotient(); + m_AvgBitrate = avg_bytes_frame * mega_const * m_Desc.EditRate.Quotient(); + } + } + + // + void + dump_Bitrate(FILE* stream = 0) + { + fprintf(stream, "Max BitRate: %0.2f Mb/s\n", m_MaxBitrate); + fprintf(stream, "Average BitRate: %0.2f Mb/s\n", m_AvgBitrate); + } + + // + void dump_WaveAudioDescriptor(FILE* stream = 0) + { + const Dictionary& Dict = DefaultCompositeDict(); + MXF::WaveAudioDescriptor *descriptor = 0; + + Result_t result = m_Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&descriptor)); + + if ( KM_SUCCESS(result) ) + { + char buf[64]; + fprintf(stream, "ChannelAssignment: %s\n", descriptor->ChannelAssignment.const_get().EncodeString(buf, 64)); + } + } + }; + // Read header metadata from an ASDCP file // Result_t @@ -291,59 +542,108 @@ show_file_info(CommandOptions& Options) if ( EssenceType == ESS_MPEG2_VES ) { - result = FileInfoWrapper<ASDCP::MPEG2::MXFReader, MyVideoDescriptor>::file_info(Options, "MPEG2 video"); + FileInfoWrapper<ASDCP::MPEG2::MXFReader, MyVideoDescriptor> wrapper; + result = wrapper.file_info(Options, "MPEG2 video"); + + if ( ASDCP_SUCCESS(result) && Options.showrate_flag ) + wrapper.dump_Bitrate(stdout); } else if ( EssenceType == ESS_PCM_24b_48k || EssenceType == ESS_PCM_24b_96k ) { - result = FileInfoWrapper<ASDCP::PCM::MXFReader, MyAudioDescriptor>::file_info(Options, "PCM audio"); - - if ( ASDCP_SUCCESS(result) ) - { - const Dictionary* Dict = &DefaultCompositeDict(); - PCM::MXFReader Reader; - MXF::OPAtomHeader OPAtomHeader(Dict); - MXF::WaveAudioDescriptor *descriptor = 0; - - result = Reader.OpenRead(Options.filenames.front().c_str()); - - if ( ASDCP_SUCCESS(result) ) - result = Reader.OPAtomHeader().GetMDObjectByType(Dict->ul(MDD_WaveAudioDescriptor), reinterpret_cast<MXF::InterchangeObject**>(&descriptor)); + FileInfoWrapper<ASDCP::PCM::MXFReader, MyAudioDescriptor> wrapper; + result = wrapper.file_info(Options, "PCM audio"); - if ( ASDCP_SUCCESS(result) ) - { - char buf[64]; - fprintf(stdout, " ChannelAssignment: %s\n", descriptor->ChannelAssignment.EncodeString(buf, 64)); - } - } + if ( ASDCP_SUCCESS(result) && Options.showcoding_flag ) + wrapper.dump_WaveAudioDescriptor(); } else if ( EssenceType == ESS_JPEG_2000 ) { if ( Options.stereo_image_flag ) { - result = FileInfoWrapper<ASDCP::JP2K::MXFSReader, - MyStereoPictureDescriptor>::file_info(Options, "JPEG 2000 stereoscopic pictures"); + FileInfoWrapper<ASDCP::JP2K::MXFSReader, MyStereoPictureDescriptor> wrapper; + result = wrapper.file_info(Options, "JPEG 2000 stereoscopic pictures"); + + if ( KM_SUCCESS(result) ) + { + wrapper.get_PictureEssenceCoding(); + wrapper.calc_Bitrate(); + + if ( Options.showcoding_flag ) + wrapper.dump_PictureEssenceCoding(stdout); + + if ( Options.showrate_flag ) + wrapper.dump_Bitrate(stdout); + + result = wrapper.test_rates(Options, stdout); + } } else { - result = FileInfoWrapper<ASDCP::JP2K::MXFReader, - MyPictureDescriptor>::file_info(Options, "JPEG 2000 pictures"); + FileInfoWrapper<ASDCP::JP2K::MXFReader, MyPictureDescriptor>wrapper; + result = wrapper.file_info(Options, "JPEG 2000 pictures"); + + if ( KM_SUCCESS(result) ) + { + wrapper.get_PictureEssenceCoding(); + wrapper.calc_Bitrate(); + + if ( Options.showcoding_flag ) + wrapper.dump_PictureEssenceCoding(stdout); + + if ( Options.showrate_flag ) + wrapper.dump_Bitrate(stdout); + + result = wrapper.test_rates(Options, stdout); + } } } else if ( EssenceType == ESS_JPEG_2000_S ) { - result = FileInfoWrapper<ASDCP::JP2K::MXFSReader, - MyStereoPictureDescriptor>::file_info(Options, "JPEG 2000 stereoscopic pictures"); + FileInfoWrapper<ASDCP::JP2K::MXFSReader, MyStereoPictureDescriptor>wrapper; + result = wrapper.file_info(Options, "JPEG 2000 stereoscopic pictures"); + + if ( KM_SUCCESS(result) ) + { + wrapper.get_PictureEssenceCoding(); + wrapper.calc_Bitrate(); + + if ( Options.showcoding_flag ) + wrapper.dump_PictureEssenceCoding(stdout); + + if ( Options.showrate_flag ) + wrapper.dump_Bitrate(stdout); + + result = wrapper.test_rates(Options, stdout); + } } else if ( EssenceType == ESS_TIMED_TEXT ) { - result = FileInfoWrapper<ASDCP::TimedText::MXFReader, MyTextDescriptor>::file_info(Options, "Timed Text"); + FileInfoWrapper<ASDCP::TimedText::MXFReader, MyTextDescriptor>wrapper; + result = wrapper.file_info(Options, "Timed Text"); + } + else if ( EssenceType == ESS_DCDATA_UNKNOWN ) + { + FileInfoWrapper<ASDCP::DCData::MXFReader, MyDCDataDescriptor> wrapper; + result = wrapper.file_info(Options, "D-Cinema Generic Data"); + } + else if ( EssenceType == ESS_DCDATA_DOLBY_ATMOS ) + { + FileInfoWrapper<ASDCP::ATMOS::MXFReader, MyAtmosDescriptor> wrapper; + result = wrapper.file_info(Options, "Dolby ATMOS"); + } + else if ( EssenceType == ESS_AS02_PCM_24b_48k + || EssenceType == ESS_AS02_PCM_24b_96k + || EssenceType == ESS_AS02_JPEG_2000 + || EssenceType == ESS_AS02_TIMED_TEXT ) + { + fprintf(stderr, "File is AS-02. Inspection in not supported by this command.\n"); } else { fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames.front().c_str()); Kumu::FileReader Reader; const Dictionary* Dict = &DefaultCompositeDict(); - MXF::OPAtomHeader TestHeader(Dict); + MXF::OP1aHeader TestHeader(Dict); result = Reader.OpenRead(Options.filenames.front().c_str()); diff --git a/asdcplib/src/asdcp-test.cpp b/asdcplib/src/asdcp-test.cpp index 05f486f5..a7ee1901 100755 --- a/asdcplib/src/asdcp-test.cpp +++ b/asdcplib/src/asdcp-test.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2012, John Hurst +Copyright (c) 2003-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file asdcp-test.cpp - \version $Id: asdcp-test.cpp,v 1.46 2012/02/03 19:49:56 jhurst Exp $ + \version $Id: asdcp-test.cpp,v 1.53 2015/10/07 16:41:23 jhurst Exp $ \brief AS-DCP file manipulation utility This program provides command line access to the major features of the asdcplib @@ -103,7 +103,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2003-2012 John Hurst\n\n\ +Copyright (c) 2003-2015 John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", @@ -292,6 +292,10 @@ public: // Rational PictureRate() { + if ( picture_rate == 16 ) return EditRate_16; + if ( picture_rate == 18 ) return EditRate_18; + if ( picture_rate == 20 ) return EditRate_20; + if ( picture_rate == 22 ) return EditRate_22; if ( picture_rate == 23 ) return EditRate_23_98; if ( picture_rate == 24 ) return EditRate_24; if ( picture_rate == 25 ) return EditRate_25; @@ -308,6 +312,10 @@ public: // const char* szPictureRate() { + if ( picture_rate == 16 ) return "16"; + if ( picture_rate == 18 ) return "18.182"; + if ( picture_rate == 20 ) return "20"; + if ( picture_rate == 22 ) return "21.818"; if ( picture_rate == 23 ) return "23.976"; if ( picture_rate == 24 ) return "24"; if ( picture_rate == 25 ) return "25"; @@ -371,7 +379,7 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); if ( verbose_flag ) fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); @@ -387,7 +395,7 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); duration_flag = true; - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'E': encrypt_header_flag = false; break; @@ -395,7 +403,7 @@ public: case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(atoi(argv[i])); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'G': mode = MMT_GOP_START; break; @@ -444,7 +452,7 @@ public: case 'p': TEST_EXTRA_ARG(i, 'p'); - picture_rate = abs(atoi(argv[i])); + picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'R': do_repeat = true; break; @@ -452,7 +460,7 @@ public: case 's': TEST_EXTRA_ARG(i, 's'); - fb_dump_size = abs(atoi(argv[i])); + fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 't': mode = MMT_DIGEST; break; @@ -464,7 +472,7 @@ public: case 'w': TEST_EXTRA_ARG(i, 'w'); - number_width = abs(atoi(argv[i])); + number_width = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'x': @@ -1794,18 +1802,18 @@ show_file_info(CommandOptions& Options) { const Dictionary* Dict = &DefaultCompositeDict(); PCM::MXFReader Reader; - MXF::OPAtomHeader OPAtomHeader(Dict); + MXF::OP1aHeader Header(Dict); MXF::WaveAudioDescriptor *descriptor = 0; result = Reader.OpenRead(Options.filenames[0]); if ( ASDCP_SUCCESS(result) ) - result = Reader.OPAtomHeader().GetMDObjectByType(Dict->ul(MDD_WaveAudioDescriptor), reinterpret_cast<MXF::InterchangeObject**>(&descriptor)); + result = Reader.OP1aHeader().GetMDObjectByType(Dict->ul(MDD_WaveAudioDescriptor), reinterpret_cast<MXF::InterchangeObject**>(&descriptor)); if ( ASDCP_SUCCESS(result) ) { char buf[64]; - fprintf(stdout, " ChannelAssignment: %s\n", descriptor->ChannelAssignment.EncodeString(buf, 64)); + fprintf(stdout, " ChannelAssignment: %s\n", descriptor->ChannelAssignment.const_get().EncodeString(buf, 64)); } } } @@ -1836,7 +1844,7 @@ show_file_info(CommandOptions& Options) fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames[0]); Kumu::FileReader Reader; const Dictionary* Dict = &DefaultCompositeDict(); - MXF::OPAtomHeader TestHeader(Dict); + MXF::OP1aHeader TestHeader(Dict); result = Reader.OpenRead(Options.filenames[0]); diff --git a/asdcplib/src/asdcp-unwrap.cpp b/asdcplib/src/asdcp-unwrap.cpp index b7b7fef9..2f57fa3a 100755 --- a/asdcplib/src/asdcp-unwrap.cpp +++ b/asdcplib/src/asdcp-unwrap.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2012, John Hurst +Copyright (c) 2003-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file asdcp-unwrap.cpp - \version $Id: asdcp-unwrap.cpp,v 1.1 2012/02/03 19:49:57 jhurst Exp $ + \version $Id: asdcp-unwrap.cpp,v 1.7 2015/10/07 16:41:23 jhurst Exp $ \brief AS-DCP file manipulation utility This program extracts picture, sound and text essence from AS-DCP files. @@ -61,7 +61,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2003-2012 John Hurst\n\n\ +Copyright (c) 2003-2015 John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", @@ -89,10 +89,11 @@ Options:\n\ -2 - Split Wave essence to stereo WAV files during extract.\n\ Default is multichannel WAV\n\ -3 - Force stereoscopic interpretation of a JP2K file.\n\ - -b <buffer-size> - Specify size in bytes of picture frame buffer.\n\ + -b <buffer-size> - Specify size in bytes of picture frame buffer\n\ Defaults to 4,194,304 (4MB)\n\ -d <duration> - Number of frames to process, default all\n\ - -f <start-frame> - Starting frame number, default 0\n\ + -e <extension> - Extension to use for Unknown D-Cinema Data files. default dcdata\n\ + -f <start-frame> - Starting frame number, default 0\n \ -G - Perform GOP start lookup test on MXF+Interop MPEG file\n\ -h | -help - Show help\n\ -k <key-string> - Use key for ciphertext operations\n\ @@ -104,7 +105,7 @@ Options:\n\ -v - Verbose, prints informative messages to stderr\n\ -W - Read input file only, do not write destination file\n\ -w <width> - Width of numeric element in a series of frame file names\n\ - (default 6).\n\ + (default 6)\n\ -z - Fail if j2c inputs have unequal parameters (default)\n\ -Z - Ignore unequal parameters in j2c inputs\n\ \n\ @@ -153,10 +154,15 @@ public: PCM::ChannelFormat_t channel_fmt; // audio channel arrangement const char* input_filename; std::string prefix_buffer; + const char* extension; // file extension to use for unknown D-Cinema Data track files. // Rational PictureRate() { + if ( picture_rate == 16 ) return EditRate_16; + if ( picture_rate == 18 ) return EditRate_18; + if ( picture_rate == 20 ) return EditRate_20; + if ( picture_rate == 22 ) return EditRate_22; if ( picture_rate == 23 ) return EditRate_23_98; if ( picture_rate == 24 ) return EditRate_24; if ( picture_rate == 25 ) return EditRate_25; @@ -177,7 +183,7 @@ public: version_flag(false), help_flag(false), stereo_image_flag(false), number_width(6), start_frame(0), duration(0xffffffff), duration_flag(false), j2c_pedantic(true), picture_rate(24), fb_size(FRAME_BUFFER_SIZE), file_prefix(0), - channel_fmt(PCM::CF_NONE), input_filename(0) + channel_fmt(PCM::CF_NONE), input_filename(0), extension("dcdata") { memset(key_value, 0, KeyLen); memset(key_id_value, 0, UUIDlen); @@ -190,7 +196,7 @@ public: help_flag = true; continue; } - + if ( argv[i][0] == '-' && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) && argv[i][2] == 0 ) @@ -203,37 +209,52 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); - - if ( verbose_flag ) - fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); - + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'd': TEST_EXTRA_ARG(i, 'd'); duration_flag = true; - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; + case 'e': + TEST_EXTRA_ARG(i, 'e'); + extension = argv[i]; + break; + case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(atoi(argv[i])); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'G': mode = MMT_GOP_START; break; case 'h': help_flag = true; break; + case 'k': key_flag = true; + TEST_EXTRA_ARG(i, 'k'); + { + ui32_t length; + Kumu::hex2bin(argv[i], key_value, KeyLen, &length); + + if ( length != KeyLen ) + { + fprintf(stderr, "Unexpected key length: %u, expecting %u characters.\n", length, KeyLen); + return; + } + } + break; + case 'm': read_hmac = true; break; case 'p': TEST_EXTRA_ARG(i, 'p'); - picture_rate = abs(atoi(argv[i])); + picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 's': TEST_EXTRA_ARG(i, 's'); - fb_dump_size = abs(atoi(argv[i])); + fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'V': version_flag = true; break; @@ -242,7 +263,7 @@ public: case 'w': TEST_EXTRA_ARG(i, 'w'); - number_width = abs(atoi(argv[i])); + number_width = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'Z': j2c_pedantic = false; break; @@ -276,7 +297,7 @@ public: if ( help_flag || version_flag ) return; - + if ( ( mode == MMT_EXTRACT || mode == MMT_GOP_START ) && input_filename == 0 ) { fputs("Option requires at least one filename argument.\n", stderr); @@ -325,7 +346,7 @@ read_MPEG2_file(CommandOptions& Options) } } - if ( ASDCP_SUCCESS(result) ) + if ( ASDCP_SUCCESS(result) && ( ! Options.no_write_flag ) ) { char filename[256]; snprintf(filename, 256, "%s.ves", Options.file_prefix); @@ -367,10 +388,13 @@ read_MPEG2_file(CommandOptions& Options) if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); + if ( ! Options.no_write_flag ) + { ui32_t write_count = 0; result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count); } } + } return result; } @@ -494,6 +518,8 @@ read_JP2K_S_file(CommandOptions& Options) if ( ASDCP_SUCCESS(result) ) { + if ( ! Options.no_write_flag ) + { Kumu::FileWriter OutFile; ui32_t write_count; snprintf(filename, filename_max, left_format, Options.file_prefix, i); @@ -501,6 +527,7 @@ read_JP2K_S_file(CommandOptions& Options) if ( ASDCP_SUCCESS(result) ) result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count); + } if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); @@ -511,6 +538,8 @@ read_JP2K_S_file(CommandOptions& Options) if ( ASDCP_SUCCESS(result) ) { + if ( ! Options.no_write_flag ) + { Kumu::FileWriter OutFile; ui32_t write_count; snprintf(filename, filename_max, right_format, Options.file_prefix, i); @@ -519,6 +548,10 @@ read_JP2K_S_file(CommandOptions& Options) if ( ASDCP_SUCCESS(result) ) result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count); } + + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + } } return result; @@ -588,6 +621,8 @@ read_JP2K_file(CommandOptions& Options) if ( ASDCP_SUCCESS(result) ) { + if ( ! Options.no_write_flag ) + { Kumu::FileWriter OutFile; char filename[256]; ui32_t write_count; @@ -596,6 +631,7 @@ read_JP2K_file(CommandOptions& Options) if ( ASDCP_SUCCESS(result) ) result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count); + } if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); @@ -638,11 +674,21 @@ read_PCM_file(CommandOptions& Options) && ADesc.EditRate != EditRate_60 ) ADesc.EditRate = Options.PictureRate(); + if ( Options.fb_size != FRAME_BUFFER_SIZE ) + { + FrameBuffer.Capacity(Options.fb_size); + } + else + { FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc)); + } if ( Options.verbose_flag ) + { + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); PCM::AudioDescriptorDump(ADesc); } + } if ( ASDCP_SUCCESS(result) ) { @@ -663,10 +709,14 @@ read_PCM_file(CommandOptions& Options) } ADesc.ContainerDuration = last_frame - Options.start_frame; + + if ( ! Options.no_write_flag ) + { OutWave.OpenWrite(ADesc, Options.file_prefix, - ( Options.split_wav ? WavFileWriter::ST_STEREO : + ( Options.split_wav ? WavFileWriter::ST_STEREO : ( Options.mono_wav ? WavFileWriter::ST_MONO : WavFileWriter::ST_NONE ) )); } + } if ( ASDCP_SUCCESS(result) && Options.key_flag ) { @@ -699,9 +749,12 @@ read_PCM_file(CommandOptions& Options) if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); + if ( ! Options.no_write_flag ) + { result = OutWave.WriteFrame(FrameBuffer); } } + } return result; } @@ -767,7 +820,7 @@ read_timed_text_file(CommandOptions& Options) result = Reader.ReadTimedTextResource(XMLDoc, Context, HMAC); - if ( ASDCP_SUCCESS(result) ) + if ( ASDCP_SUCCESS(result) && ( ! Options.no_write_flag ) ) { Kumu::FileWriter Writer; result = Writer.OpenWrite(Options.file_prefix); @@ -780,21 +833,103 @@ read_timed_text_file(CommandOptions& Options) { result = Reader.ReadAncillaryResource(ri->ResourceID, FrameBuffer, Context, HMAC); - if ( ASDCP_SUCCESS(result) ) + if ( ASDCP_SUCCESS(result) && ( ! Options.no_write_flag ) ) { Kumu::FileWriter Writer; result = Writer.OpenWrite(Kumu::PathJoin(out_path, Kumu::UUID(ri->ResourceID).EncodeHex(buf, 64)).c_str()); if ( ASDCP_SUCCESS(result) ) - { + result = Writer.Write(FrameBuffer.RoData(), FrameBuffer.Size(), &write_count); + if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); + } + } + + return result; +} + +// Read one or more plaintext DCData bytestreams from a plaintext ASDCP file +// Read one or more plaintext DCData bytestreams from a ciphertext ASDCP file +// Read one or more ciphertext DCData byestreams from a ciphertext ASDCP file +// +Result_t +read_DCData_file(CommandOptions& Options) +{ + AESDecContext* Context = 0; + HMACContext* HMAC = 0; + DCData::MXFReader Reader; + DCData::FrameBuffer FrameBuffer(Options.fb_size); + ui32_t frame_count = 0; + + Result_t result = Reader.OpenRead(Options.input_filename); + + if ( ASDCP_SUCCESS(result) ) + { + DCData::DCDataDescriptor DDesc; + Reader.FillDCDataDescriptor(DDesc); + + frame_count = DDesc.ContainerDuration; - result = Writer.Write(FrameBuffer.RoData(), FrameBuffer.Size(), &write_count); + if ( Options.verbose_flag ) + { + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + DCData::DCDataDescriptorDump(DDesc); + } + } + + if ( ASDCP_SUCCESS(result) && Options.key_flag ) + { + Context = new AESDecContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) && Options.read_hmac ) + { + WriterInfo Info; + Reader.FillWriterInfo(Info); + + if ( Info.UsesHMAC ) + { + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + else + { + fputs("File does not contain HMAC values, ignoring -m option.\n", stderr); } } } + ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); + if ( last_frame > frame_count ) + last_frame = frame_count; + + char name_format[64]; + snprintf(name_format, 64, "%%s%%0%du.%s", Options.number_width, Options.extension); + + for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ ) + { + result = Reader.ReadFrame(i, FrameBuffer, Context, HMAC); + + if ( ASDCP_SUCCESS(result) ) + { + if ( ! Options.no_write_flag ) + { + Kumu::FileWriter OutFile; + char filename[256]; + ui32_t write_count; + snprintf(filename, 256, name_format, Options.file_prefix, i); + result = OutFile.OpenWrite(filename); + + if ( ASDCP_SUCCESS(result) ) + result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count); + } + + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + } + } + return result; } @@ -858,6 +993,15 @@ main(int argc, const char** argv) result = read_timed_text_file(Options); break; + case ESS_DCDATA_UNKNOWN: + result = read_DCData_file(Options); + break; + + case ESS_DCDATA_DOLBY_ATMOS: + Options.extension = "atmos"; + result = read_DCData_file(Options); + break; + default: fprintf(stderr, "%s: Unknown file type, not ASDCP essence.\n", Options.input_filename); return 5; diff --git a/asdcplib/src/asdcp-util.cpp b/asdcplib/src/asdcp-util.cpp index 0d9ed4c9..1750f5ef 100755 --- a/asdcplib/src/asdcp-util.cpp +++ b/asdcplib/src/asdcp-util.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file asdcp-util.cpp - \version $Id: asdcp-util.cpp,v 1.1 2012/02/03 19:49:57 jhurst Exp $ + \version $Id: asdcp-util.cpp,v 1.3 2015/05/21 00:10:39 jhurst Exp $ \brief Utility functions for working with AS-DCP files This program provides utility features commonly useful in DCP workflows. @@ -78,10 +78,8 @@ USAGE: %s [-h|-help] [-V]\n\ \n\ %s -d <input-file>\n\ \n\ - %s -g | -u\n\ -\n\ - %s -u\n\n", - PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME); + %s -g | -u\n", + PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME); fprintf(stream, "\ Major modes:\n\ diff --git a/asdcplib/src/asdcp-wrap.cpp b/asdcplib/src/asdcp-wrap.cpp index e1182aeb..8e683e18 100755 --- a/asdcplib/src/asdcp-wrap.cpp +++ b/asdcplib/src/asdcp-wrap.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2012, John Hurst +Copyright (c) 2003-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,10 +25,10 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file asdcp-wrap.cpp - \version $Id: asdcp-wrap.cpp,v 1.5 2012/03/07 18:47:02 mikey Exp $ + \version $Id: asdcp-wrap.cpp,v 1.23 2015/10/14 16:48:22 jhurst Exp $ \brief AS-DCP file manipulation utility - This program wraps d-cinema essence (picture, sound or text) in t an AS-DCP + This program wraps d-cinema essence (picture, sound or text) into an AS-DCP MXF file. For more information about asdcplib, please refer to the header file AS_DCP.h @@ -48,6 +48,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_fileio.h> #include <KM_prng.h> +#include <AtmosSyncChannel_Mixer.h> #include <AS_DCP.h> #include <PCMParserList.h> #include <Metadata.h> @@ -56,6 +57,13 @@ using namespace ASDCP; const ui32_t FRAME_BUFFER_SIZE = 4 * Kumu::Megabyte; +const byte_t P_HFR_UL_2K[16] = { + 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0d, + 0x0e, 0x16, 0x02, 0x02, 0x03, 0x01, 0x01, 0x03 +}; + +const ASDCP::Dictionary *g_dict = 0; + //------------------------------------------------------------------------------------------ // // command line option parser class @@ -71,7 +79,7 @@ public: static byte_t default_ProductUUID_Data[UUIDlen] = { 0x7d, 0x83, 0x6e, 0x16, 0x37, 0xc7, 0x4c, 0x22, 0xb2, 0xe0, 0x46, 0xa7, 0x17, 0xe8, 0x4f, 0x42 }; - + memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen); CompanyName = "WidgetCo"; ProductName = "asdcp-wrap"; @@ -91,12 +99,21 @@ public: } // +static void +create_random_uuid(byte_t* uuidbuf) +{ + Kumu::UUID tmp_id; + GenRandomValue(tmp_id); + memcpy(uuidbuf, tmp_id.Value(), tmp_id.Size()); +} + +// void banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2003-2012 John Hurst\n\n\ +Copyright (c) 2003-2015 John Hurst\n\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ Specify the -h (help) option for further information about %s\n\n", @@ -112,16 +129,17 @@ USAGE: %s [-h|-help] [-V]\n\ \n\ %s [-3] [-a <uuid>] [-b <buffer-size>] [-C <UL>] [-d <duration>]\n\ [-e|-E] [-f <start-frame>] [-j <key-id-string>] [-k <key-string>]\n\ - [-l <label>] [-L] [-M] [-p <frame-rate>] [-s <num>] [-v] [-W]\n\ - [-z|-Z] <input-file>+ <output-file>\n\n", + [-l <label>] [-L] [-M] [-m <expr>] [-p <frame-rate>] [-s] [-v]\n\ + [-W] [-z|-Z] <input-file>+ <output-file>\n\n", PROGRAM_NAME, PROGRAM_NAME); fprintf(stream, "\ Options:\n\ -3 - Create a stereoscopic image file. Expects two\n\ directories of JP2K codestreams (directories must have\n\ - an equal number of frames; left eye is first).\n\ - -C <UL> - Set ChannelAssignment UL value\n\ + an equal number of frames; the left eye is first)\n\ + -A <UL> - Set DataEssenceCoding UL value in an Aux Data file\n\ + -C <UL> - Set ChannelAssignment UL value in a PCM file\n\ -h | -help - Show help\n\ -V - Show version information\n\ -e - Encrypt MPEG or JP2K headers (default)\n\ @@ -129,8 +147,12 @@ Options:\n\ -j <key-id-str> - Write key ID instead of creating a random value\n\ -k <key-string> - Use key for ciphertext operations\n\ -M - Do not create HMAC values when writing\n\ - -a <UUID> - Specify the Asset ID of a file (with -c)\n\ - -b <buffer-size> - Specify size in bytes of picture frame buffer.\n\ + -m <expr> - Write MCA labels using <expr>. Example:\n\ + 51(L,R,C,LFE,Ls,Rs,),HI,VIN\n\ + Note: The symbol '-' may be used for an unlabeled\n\ + channel, but not within a soundfield.\n\ + -a <UUID> - Specify the Asset ID of the file\n\ + -b <buffer-size> - Specify size in bytes of picture frame buffer\n\ Defaults to 4,194,304 (4MB)\n\ -d <duration> - Number of frames to process, default all\n\ -f <start-frame> - Starting frame number, default 0\n\ @@ -139,10 +161,17 @@ Options:\n\ '7.1DS', 'WTF'\n\ Default is no label (valid for Interop only).\n\ -L - Write SMPTE UL values instead of MXF Interop\n\ + -P <UL> - Set PictureEssenceCoding UL value in a JP2K file\n\ -p <rate> - fps of picture when wrapping PCM or JP2K:\n\ Use one of [23|24|25|30|48|50|60], 24 is default\n\ + -s - Insert a Dolby Atmos synchronization channel when\n\ + wrapping PCM. This implies a -L option(SMPTE ULs) and \n\ + will overide -C and -l options with Configuration 4 \n\ + Channel Assigment and no format label respectively. \n\ -v - Verbose, prints informative messages to stderr\n\ - -W - Read input file only, do not write source file\n\ + -w - When writing 377-4 MCA labels, use the WTF Channel\n\ + assignment label instead of the standard MCA label\n\ + -W - Read input file only, do not write output file\n\ -z - Fail if j2c inputs have unequal parameters (default)\n\ -Z - Ignore unequal parameters in j2c inputs\n\ \n\ @@ -162,7 +191,7 @@ decode_channel_fmt(const std::string& label_name) else if ( label_name == "6.1" ) return PCM::CF_CFG_2; - + else if ( label_name == "7.1" ) return PCM::CF_CFG_3; @@ -189,18 +218,13 @@ public: bool asset_id_flag; // true if an asset ID was given bool encrypt_header_flag; // true if mpeg headers are to be encrypted bool write_hmac; // true if HMAC values are to be generated and written - /// bool read_hmac; // true if HMAC values are to be validated - /// bool split_wav; // true if PCM is to be extracted to stereo WAV files - /// bool mono_wav; // true if PCM is to be extracted to mono WAV files bool verbose_flag; // true if the verbose option was selected ui32_t fb_dump_size; // number of bytes of frame buffer to dump - /// bool showindex_flag; // true if index is to be displayed - /// bool showheader_flag; // true if MXF file header is to be displayed bool no_write_flag; // true if no output files are to be written bool version_flag; // true if the version display option was selected bool help_flag; // true if the help display option was selected bool stereo_image_flag; // if true, expect stereoscopic JP2K input (left eye first) - /// ui32_t number_width; // number of digits in a serialized filename (for JPEG extract) + bool write_partial_pcm_flag; // if true, write the last frame of PCM input even when it is incomplete ui32_t start_frame; // frame number to begin processing ui32_t duration; // number of frames to be processed bool use_smpte_labels; // if true, SMPTE UL values will be written instead of MXF Interop values @@ -213,13 +237,25 @@ public: byte_t asset_id_value[UUIDlen];// value of asset ID (when asset_id_flag is true) PCM::ChannelFormat_t channel_fmt; // audio channel arrangement std::string out_file; // - bool show_ul_values; /// if true, dump the UL table before going tp work. + bool show_ul_values_flag; /// if true, dump the UL table before going to work. Kumu::PathList_t filenames; // list of filenames to be processed UL channel_assignment; + UL picture_coding; + UL aux_data_coding; + bool dolby_atmos_sync_flag; // if true, insert a Dolby Atmos Synchronization channel. + ui32_t ffoa; // first frame of action for atmos wrapping + ui32_t max_channel_count; // max channel count for atmos wrapping + ui32_t max_object_count; // max object count for atmos wrapping + bool use_interop_sound_wtf; // make true to force WTF assignment label instead of MCA + ASDCP::MXF::ASDCP_MCAConfigParser mca_config; // Rational PictureRate() { + if ( picture_rate == 16 ) return EditRate_16; + if ( picture_rate == 18 ) return EditRate_18; + if ( picture_rate == 20 ) return EditRate_20; + if ( picture_rate == 22 ) return EditRate_22; if ( picture_rate == 23 ) return EditRate_23_98; if ( picture_rate == 24 ) return EditRate_24; if ( picture_rate == 25 ) return EditRate_25; @@ -236,6 +272,10 @@ public: // const char* szPictureRate() { + if ( picture_rate == 16 ) return "16"; + if ( picture_rate == 18 ) return "18.182"; + if ( picture_rate == 20 ) return "20"; + if ( picture_rate == 22 ) return "21.818"; if ( picture_rate == 23 ) return "23.976"; if ( picture_rate == 24 ) return "24"; if ( picture_rate == 25 ) return "25"; @@ -255,11 +295,15 @@ public: encrypt_header_flag(true), write_hmac(true), verbose_flag(false), fb_dump_size(0), no_write_flag(false), version_flag(false), help_flag(false), stereo_image_flag(false), - start_frame(0), + write_partial_pcm_flag(false), start_frame(0), duration(0xffffffff), use_smpte_labels(false), j2c_pedantic(true), fb_size(FRAME_BUFFER_SIZE), channel_fmt(PCM::CF_NONE), - show_ul_values(false) + ffoa(0), max_channel_count(10), max_object_count(118), // hard-coded sample atmos properties + dolby_atmos_sync_flag(false), + show_ul_values_flag(false), + mca_config(g_dict), + use_interop_sound_wtf(false) { memset(key_value, 0, KeyLen); memset(key_id_value, 0, UUIDlen); @@ -272,7 +316,7 @@ public: help_flag = true; continue; } - + if ( argv[i][0] == '-' && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) && argv[i][2] == 0 ) @@ -281,6 +325,15 @@ public: { case '3': stereo_image_flag = true; break; + case 'A': + TEST_EXTRA_ARG(i, 'A'); + if ( ! aux_data_coding.DecodeHex(argv[i]) ) + { + fprintf(stderr, "Error decoding UL value: %s\n", argv[i]); + return; + } + break; + case 'a': asset_id_flag = true; TEST_EXTRA_ARG(i, 'a'); @@ -298,7 +351,7 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); if ( verbose_flag ) fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); @@ -306,7 +359,7 @@ public: break; case 'C': - TEST_EXTRA_ARG(i, 'U'); + TEST_EXTRA_ARG(i, 'C'); if ( ! channel_assignment.DecodeHex(argv[i]) ) { fprintf(stderr, "Error decoding UL value: %s\n", argv[i]); @@ -316,7 +369,7 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'E': encrypt_header_flag = false; break; @@ -324,9 +377,10 @@ public: case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(atoi(argv[i])); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; + case 'g': write_partial_pcm_flag = true; break; case 'h': help_flag = true; break; case 'j': key_id_flag = true; @@ -365,13 +419,33 @@ public: case 'L': use_smpte_labels = true; break; case 'M': write_hmac = false; break; + case 'm': + TEST_EXTRA_ARG(i, 'm'); + if ( ! mca_config.DecodeString(argv[i]) ) + { + return; + } + break; + + case 'P': + TEST_EXTRA_ARG(i, 'P'); + if ( ! picture_coding.DecodeHex(argv[i]) ) + { + fprintf(stderr, "Error decoding UL value: %s\n", argv[i]); + return; + } + break; + case 'p': TEST_EXTRA_ARG(i, 'p'); - picture_rate = abs(atoi(argv[i])); + picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); break; + case 's': dolby_atmos_sync_flag = true; break; + case 'u': show_ul_values_flag = true; break; case 'V': version_flag = true; break; case 'v': verbose_flag = true; break; + case 'w': use_interop_sound_wtf = true; break; case 'W': no_write_flag = true; break; case 'Z': j2c_pedantic = false; break; case 'z': j2c_pedantic = true; break; @@ -398,7 +472,7 @@ public: if ( help_flag || version_flag ) return; - + if ( filenames.size() < 2 ) { fputs("Option requires at least two filename arguments: <input-file> <output-file>\n", stderr); @@ -430,7 +504,7 @@ write_MPEG2_file(CommandOptions& Options) Kumu::FortunaRNG RNG; // set up essence parser - Result_t result = Parser.OpenRead(Options.filenames.front().c_str()); + Result_t result = Parser.OpenRead(Options.filenames.front()); // set up MXF writer if ( ASDCP_SUCCESS(result) ) @@ -467,9 +541,13 @@ write_MPEG2_file(CommandOptions& Options) Info.EncryptedEssence = true; if ( Options.key_id_flag ) - memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } else - RNG.FillRandom(Info.CryptographicKeyID, UUIDlen); + { + create_random_uuid(Info.CryptographicKeyID); + } Context = new AESEncContext; result = Context->InitKey(Options.key_value); @@ -486,7 +564,7 @@ write_MPEG2_file(CommandOptions& Options) } if ( ASDCP_SUCCESS(result) ) - result = Writer.OpenWrite(Options.out_file.c_str(), Info, VDesc); + result = Writer.OpenWrite(Options.out_file, Info, VDesc); } if ( ASDCP_SUCCESS(result) ) @@ -497,19 +575,16 @@ write_MPEG2_file(CommandOptions& Options) while ( ASDCP_SUCCESS(result) && duration++ < Options.duration ) { - if ( duration == 1 ) - { result = Parser.ReadFrame(FrameBuffer); if ( ASDCP_SUCCESS(result) ) { if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); - + if ( Options.encrypt_header_flag ) FrameBuffer.PlaintextOffset(0); } - } if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) { @@ -536,6 +611,35 @@ write_MPEG2_file(CommandOptions& Options) //------------------------------------------------------------------------------------------ + +// return false if an error is discovered +bool +check_phfr_params(CommandOptions& Options, JP2K::PictureDescriptor& PDesc) +{ + Rational rate = Options.PictureRate(); + if ( rate != EditRate_96 && rate != EditRate_100 && rate != EditRate_120 ) + return true; + + if ( PDesc.StoredWidth > 2048 ) + { + fprintf(stderr, "P-HFR files currently limited to 2K.\n"); + return false; + } + + if ( ! Options.use_smpte_labels ) + { + fprintf(stderr, "P-HFR files must be written using SMPTE labels. Use option '-L'.\n"); + return false; + } + + // do not set the label if the user has already done so + if ( ! Options.picture_coding.HasValue() ) + Options.picture_coding = UL(P_HFR_UL_2K); + + return true; +} + +//------------------------------------------------------------------------------------------ // JPEG 2000 essence // Write one or more plaintext JPEG 2000 stereoscopic codestream pairs to a plaintext ASDCP file @@ -560,12 +664,12 @@ write_JP2K_S_file(CommandOptions& Options) } // set up essence parser - Result_t result = ParserLeft.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic); + Result_t result = ParserLeft.OpenRead(Options.filenames.front(), Options.j2c_pedantic); if ( ASDCP_SUCCESS(result) ) { Options.filenames.pop_front(); - result = ParserRight.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic); + result = ParserRight.OpenRead(Options.filenames.front(), Options.j2c_pedantic); } // set up MXF writer @@ -582,6 +686,9 @@ write_JP2K_S_file(CommandOptions& Options) } } + if ( ! check_phfr_params(Options, PDesc) ) + return RESULT_FAIL; + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) { WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here @@ -603,9 +710,13 @@ write_JP2K_S_file(CommandOptions& Options) Info.EncryptedEssence = true; if ( Options.key_id_flag ) - memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } else - RNG.FillRandom(Info.CryptographicKeyID, UUIDlen); + { + create_random_uuid(Info.CryptographicKeyID); + } Context = new AESEncContext; result = Context->InitKey(Options.key_value); @@ -622,7 +733,15 @@ write_JP2K_S_file(CommandOptions& Options) } if ( ASDCP_SUCCESS(result) ) - result = Writer.OpenWrite(Options.out_file.c_str(), Info, PDesc); + result = Writer.OpenWrite(Options.out_file, Info, PDesc); + + if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() ) + { + MXF::RGBAEssenceDescriptor *descriptor = 0; + Writer.OP1aHeader().GetMDObjectByType(g_dict->ul(MDD_RGBAEssenceDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&descriptor)); + descriptor->PictureEssenceCoding = Options.picture_coding; + } } if ( ASDCP_SUCCESS(result) ) @@ -639,7 +758,7 @@ write_JP2K_S_file(CommandOptions& Options) { if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); - + if ( Options.encrypt_header_flag ) FrameBuffer.PlaintextOffset(0); } @@ -654,7 +773,7 @@ write_JP2K_S_file(CommandOptions& Options) { if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); - + if ( Options.encrypt_header_flag ) FrameBuffer.PlaintextOffset(0); } @@ -689,7 +808,7 @@ write_JP2K_file(CommandOptions& Options) Kumu::FortunaRNG RNG; // set up essence parser - Result_t result = Parser.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic); + Result_t result = Parser.OpenRead(Options.filenames.front(), Options.j2c_pedantic); // set up MXF writer if ( ASDCP_SUCCESS(result) ) @@ -706,6 +825,9 @@ write_JP2K_file(CommandOptions& Options) } } + if ( ! check_phfr_params(Options, PDesc) ) + return RESULT_FAIL; + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) { WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here @@ -727,9 +849,13 @@ write_JP2K_file(CommandOptions& Options) Info.EncryptedEssence = true; if ( Options.key_id_flag ) - memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } else - RNG.FillRandom(Info.CryptographicKeyID, UUIDlen); + { + create_random_uuid(Info.CryptographicKeyID); + } Context = new AESEncContext; result = Context->InitKey(Options.key_value); @@ -746,7 +872,15 @@ write_JP2K_file(CommandOptions& Options) } if ( ASDCP_SUCCESS(result) ) - result = Writer.OpenWrite(Options.out_file.c_str(), Info, PDesc); + result = Writer.OpenWrite(Options.out_file, Info, PDesc); + + if ( ASDCP_SUCCESS(result) && Options.picture_coding.HasValue() ) + { + MXF::RGBAEssenceDescriptor *descriptor = 0; + Writer.OP1aHeader().GetMDObjectByType(g_dict->ul(MDD_RGBAEssenceDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&descriptor)); + descriptor->PictureEssenceCoding = Options.picture_coding; + } } if ( ASDCP_SUCCESS(result) ) @@ -756,19 +890,16 @@ write_JP2K_file(CommandOptions& Options) while ( ASDCP_SUCCESS(result) && duration++ < Options.duration ) { - if ( duration == 1 ) - { result = Parser.ReadFrame(FrameBuffer); if ( ASDCP_SUCCESS(result) ) { if ( Options.verbose_flag ) FrameBuffer.Dump(stderr, Options.fb_dump_size); - + if ( Options.encrypt_header_flag ) FrameBuffer.PlaintextOffset(0); } - } if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) { @@ -825,9 +956,9 @@ write_PCM_file(CommandOptions& Options) FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc)); ADesc.ChannelFormat = Options.channel_fmt; - if ( Options.use_smpte_labels && ADesc.ChannelFormat == PCM::CF_NONE) + if ( Options.use_smpte_labels && ADesc.ChannelFormat == PCM::CF_NONE && Options.mca_config.empty() ) { - fprintf(stderr, "ATTENTION! Writing SMPTE audio without ChannelAssignment property (see option -l)\n"); + fprintf(stderr, "ATTENTION! Writing SMPTE audio without ChannelAssignment property (see options -C, -l and -m)\n"); } if ( Options.verbose_flag ) @@ -862,9 +993,13 @@ write_PCM_file(CommandOptions& Options) Info.EncryptedEssence = true; if ( Options.key_id_flag ) - memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } else - RNG.FillRandom(Info.CryptographicKeyID, UUIDlen); + { + create_random_uuid(Info.CryptographicKeyID); + } Context = new AESEncContext; result = Context->InitKey(Options.key_value); @@ -881,14 +1016,60 @@ write_PCM_file(CommandOptions& Options) } if ( ASDCP_SUCCESS(result) ) - result = Writer.OpenWrite(Options.out_file.c_str(), Info, ADesc); + result = Writer.OpenWrite(Options.out_file, Info, ADesc); - if ( ASDCP_SUCCESS(result) && Options.channel_assignment.HasValue() ) + if ( ASDCP_SUCCESS(result) + && ( Options.channel_assignment.HasValue() + || ! Options.mca_config.empty() ) ) { - MXF::WaveAudioDescriptor *descriptor = 0; - Writer.OPAtomHeader().GetMDObjectByType(DefaultSMPTEDict().ul(MDD_WaveAudioDescriptor), - reinterpret_cast<MXF::InterchangeObject**>(&descriptor)); - descriptor->ChannelAssignment = Options.channel_assignment; + MXF::WaveAudioDescriptor *essence_descriptor = 0; + Writer.OP1aHeader().GetMDObjectByType(g_dict->ul(MDD_WaveAudioDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&essence_descriptor)); + assert(essence_descriptor); + + if ( Options.mca_config.empty() ) + { + essence_descriptor->ChannelAssignment = Options.channel_assignment; + } + else + { + if ( Options.mca_config.ChannelCount() != essence_descriptor->ChannelCount ) + { + fprintf(stderr, "MCA label count (%d) differs from essence stream channel count (%d).\n", + Options.mca_config.ChannelCount(), essence_descriptor->ChannelCount); + return RESULT_FAIL; + } + + if ( Options.channel_assignment.HasValue() ) + { + essence_descriptor->ChannelAssignment = Options.channel_assignment; + } + else if ( Options.use_interop_sound_wtf ) + { + essence_descriptor->ChannelAssignment = g_dict->ul(MDD_DCAudioChannelCfg_4_WTF); + } + else + { + essence_descriptor->ChannelAssignment = g_dict->ul(MDD_DCAudioChannelCfg_MCA); + } + + // add descriptors to the essence_descriptor and header + ASDCP::MXF::InterchangeObject_list_t::iterator i; + for ( i = Options.mca_config.begin(); i != Options.mca_config.end(); ++i ) + { + if ( (*i)->GetUL() != UL(g_dict->ul(MDD_AudioChannelLabelSubDescriptor)) + && (*i)->GetUL() != UL(g_dict->ul(MDD_SoundfieldGroupLabelSubDescriptor)) + && (*i)->GetUL() != UL(g_dict->ul(MDD_GroupOfSoundfieldGroupsLabelSubDescriptor)) ) + { + fprintf(stderr, "Essence sub-descriptor is not an MCALabelSubDescriptor.\n"); + (*i)->Dump(); + } + + Writer.OP1aHeader().AddChildObject(*i); + essence_descriptor->SubDescriptors.push_back((*i)->InstanceUID); + *i = 0; // parent will only free the ones we don't keep + } + } } } @@ -907,8 +1088,12 @@ write_PCM_file(CommandOptions& Options) { fprintf(stderr, "WARNING: Last frame read was short, PCM input is possibly not frame aligned.\n"); fprintf(stderr, "Expecting %u bytes, got %u.\n", FrameBuffer.Capacity(), FrameBuffer.Size()); - result = RESULT_ENDOFFILE; - continue; + + if ( Options.write_partial_pcm_flag ) + { + result = RESULT_ENDOFFILE; + continue; + } } if ( Options.verbose_flag ) @@ -938,6 +1123,139 @@ write_PCM_file(CommandOptions& Options) return result; } +// Mix one or more plaintext PCM audio streams with a Dolby Atmos Synchronization channel and write them to a plaintext ASDCP file +// Mix one or more plaintext PCM audio streams with a Dolby Atmos Synchronization channel and write them to a ciphertext ASDCP file +// +Result_t +write_PCM_with_ATMOS_sync_file(CommandOptions& Options) +{ + AESEncContext* Context = 0; + HMACContext* HMAC = 0; + PCM::MXFWriter Writer; + PCM::FrameBuffer FrameBuffer; + PCM::AudioDescriptor ADesc; + Rational PictureRate = Options.PictureRate(); + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; + + WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here + if ( Options.asset_id_flag ) + memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen); + else + Kumu::GenRandomUUID(Info.AssetUUID); + AtmosSyncChannelMixer Mixer(Info.AssetUUID); + + // set up essence parser + Result_t result = Mixer.OpenRead(Options.filenames, PictureRate); + + // set up MXF writer + if ( ASDCP_SUCCESS(result) ) + { + Mixer.FillAudioDescriptor(ADesc); + + ADesc.EditRate = PictureRate; + FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc)); + ADesc.ChannelFormat = PCM::CF_CFG_4; + + if ( Options.verbose_flag ) + { + fprintf(stderr, "%.1fkHz PCM Audio, %s fps (%u spf)\n", + ADesc.AudioSamplingRate.Quotient() / 1000.0, + Options.szPictureRate(), + PCM::CalcSamplesPerFrame(ADesc)); + fputs("AudioDescriptor:\n", stderr); + PCM::AudioDescriptorDump(ADesc); + } + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + Info.LabelSetType = LS_MXF_SMPTE; + fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); + + // configure encryption + if( Options.key_flag ) + { + Kumu::GenRandomUUID(Info.ContextID); + Info.EncryptedEssence = true; + + if ( Options.key_id_flag ) + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } + else + { + create_random_uuid(Info.CryptographicKeyID); + } + + Context = new AESEncContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) ) + result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + + if ( ASDCP_SUCCESS(result) && Options.write_hmac ) + { + Info.UsesHMAC = true; + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + } + + if ( ASDCP_SUCCESS(result) ) + result = Writer.OpenWrite(Options.out_file, Info, ADesc); + } + + if ( ASDCP_SUCCESS(result) ) + { + result = Mixer.Reset(); + ui32_t duration = 0; + + while ( ASDCP_SUCCESS(result) && duration++ < Options.duration ) + { + result = Mixer.ReadFrame(FrameBuffer); + + if ( ASDCP_SUCCESS(result) ) + { + if ( FrameBuffer.Size() != FrameBuffer.Capacity() ) + { + fprintf(stderr, "WARNING: Last frame read was short, PCM input is possibly not frame aligned.\n"); + fprintf(stderr, "Expecting %u bytes, got %u.\n", FrameBuffer.Capacity(), FrameBuffer.Size()); + + if ( Options.write_partial_pcm_flag ) + { + result = RESULT_ENDOFFILE; + continue; + } + } + + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + + if ( ! Options.no_write_flag ) + { + result = Writer.WriteFrame(FrameBuffer, Context, HMAC); + + // The Writer class will forward the last block of ciphertext + // to the encryption context for use as the IV for the next + // frame. If you want to use non-sequitur IV values, un-comment + // the following line of code. + // if ( ASDCP_SUCCESS(result) && Options.key_flag ) + // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + } + } + } + + if ( result == RESULT_ENDOFFILE ) + result = RESULT_OK; + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + result = Writer.Finalize(); + + return result; +} + //------------------------------------------------------------------------------------------ // TimedText essence @@ -959,7 +1277,7 @@ write_timed_text_file(CommandOptions& Options) Kumu::FortunaRNG RNG; // set up essence parser - Result_t result = Parser.OpenRead(Options.filenames.front().c_str()); + Result_t result = Parser.OpenRead(Options.filenames.front()); // set up MXF writer if ( ASDCP_SUCCESS(result) ) @@ -982,11 +1300,9 @@ write_timed_text_file(CommandOptions& Options) else Kumu::GenRandomUUID(Info.AssetUUID); - if ( Options.use_smpte_labels ) - { - Info.LabelSetType = LS_MXF_SMPTE; - fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); - } + // 428-7 IN 429-5 always uses SMPTE labels + Info.LabelSetType = LS_MXF_SMPTE; + fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n"); // configure encryption if( Options.key_flag ) @@ -995,9 +1311,13 @@ write_timed_text_file(CommandOptions& Options) Info.EncryptedEssence = true; if ( Options.key_id_flag ) - memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } else - RNG.FillRandom(Info.CryptographicKeyID, UUIDlen); + { + create_random_uuid(Info.CryptographicKeyID); + } Context = new AESEncContext; result = Context->InitKey(Options.key_value); @@ -1014,7 +1334,7 @@ write_timed_text_file(CommandOptions& Options) } if ( ASDCP_SUCCESS(result) ) - result = Writer.OpenWrite(Options.out_file.c_str(), Info, TDesc); + result = Writer.OpenWrite(Options.out_file, Info, TDesc); } if ( ASDCP_FAILURE(result) ) @@ -1040,7 +1360,7 @@ write_timed_text_file(CommandOptions& Options) if ( ! Options.no_write_flag ) { result = Writer.WriteAncillaryResource(FrameBuffer, Context, HMAC); - + // The Writer class will forward the last block of ciphertext // to the encryption context for use as the IV for the next // frame. If you want to use non-sequitur IV values, un-comment @@ -1060,12 +1380,253 @@ write_timed_text_file(CommandOptions& Options) return result; } +// Write one or more plaintext Dolby ATMOS bytestreams to a plaintext ASDCP file +// Write one or more plaintext Dolby ATMOS bytestreams to a ciphertext ASDCP file +// +Result_t +write_dolby_atmos_file(CommandOptions& Options) +{ + AESEncContext* Context = 0; + HMACContext* HMAC = 0; + ATMOS::MXFWriter Writer; + DCData::FrameBuffer FrameBuffer(Options.fb_size); + ATMOS::AtmosDescriptor ADesc; + DCData::SequenceParser Parser; + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; + + // set up essence parser + Result_t result = Parser.OpenRead(Options.filenames.front()); + + // set up MXF writer + if ( ASDCP_SUCCESS(result) ) + { + Parser.FillDCDataDescriptor(ADesc); + ADesc.EditRate = Options.PictureRate(); + // TODO: fill AtmosDescriptor + ADesc.FirstFrame = Options.ffoa; + ADesc.MaxChannelCount = Options.max_channel_count; + ADesc.MaxObjectCount = Options.max_object_count; + Kumu::GenRandomUUID(ADesc.AtmosID); + ADesc.AtmosVersion = 1; + if ( Options.verbose_flag ) + { + fprintf(stderr, "Dolby ATMOS Data\n"); + fputs("AtmosDescriptor:\n", stderr); + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + ATMOS::AtmosDescriptorDump(ADesc); + } + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here + if ( Options.asset_id_flag ) + memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen); + else + Kumu::GenRandomUUID(Info.AssetUUID); + + Info.LabelSetType = LS_MXF_SMPTE; + + // configure encryption + if( Options.key_flag ) + { + Kumu::GenRandomUUID(Info.ContextID); + Info.EncryptedEssence = true; + + if ( Options.key_id_flag ) + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } + else + { + create_random_uuid(Info.CryptographicKeyID); + } + + Context = new AESEncContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) ) + result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + + if ( ASDCP_SUCCESS(result) && Options.write_hmac ) + { + Info.UsesHMAC = true; + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + } + + if ( ASDCP_SUCCESS(result) ) + result = Writer.OpenWrite(Options.out_file, Info, ADesc); + } + + if ( ASDCP_SUCCESS(result) ) + { + ui32_t duration = 0; + result = Parser.Reset(); + + while ( ASDCP_SUCCESS(result) && duration++ < Options.duration ) + { + result = Parser.ReadFrame(FrameBuffer); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + + if ( Options.encrypt_header_flag ) + FrameBuffer.PlaintextOffset(0); + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + result = Writer.WriteFrame(FrameBuffer, Context, HMAC); + + // The Writer class will forward the last block of ciphertext + // to the encryption context for use as the IV for the next + // frame. If you want to use non-sequitur IV values, un-comment + // the following line of code. + // if ( ASDCP_SUCCESS(result) && Options.key_flag ) + // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + } + } + + if ( result == RESULT_ENDOFFILE ) + result = RESULT_OK; + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + result = Writer.Finalize(); + + return result; +} + +// Write one or more plaintext Aux Data (ST 429-14) bytestreams to a plaintext ASDCP file +// Write one or more plaintext Aux Data (ST 429-14) bytestreams to a ciphertext ASDCP file +// +Result_t +write_aux_data_file(CommandOptions& Options) +{ + AESEncContext* Context = 0; + HMACContext* HMAC = 0; + DCData::MXFWriter Writer; + DCData::FrameBuffer FrameBuffer(Options.fb_size); + DCData::DCDataDescriptor DDesc; + DCData::SequenceParser Parser; + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; + + // set up essence parser + Result_t result = Parser.OpenRead(Options.filenames.front()); + + // set up MXF writer + if ( ASDCP_SUCCESS(result) ) + { + Parser.FillDCDataDescriptor(DDesc); + memcpy(DDesc.DataEssenceCoding, Options.aux_data_coding.Value(), Options.aux_data_coding.Size()); + DDesc.EditRate = Options.PictureRate(); + + if ( Options.verbose_flag ) + { + fprintf(stderr, "Aux Data\n"); + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + DCData::DCDataDescriptorDump(DDesc); + } + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here + if ( Options.asset_id_flag ) + memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen); + else + Kumu::GenRandomUUID(Info.AssetUUID); + + Info.LabelSetType = LS_MXF_SMPTE; + + // configure encryption + if( Options.key_flag ) + { + Kumu::GenRandomUUID(Info.ContextID); + Info.EncryptedEssence = true; + + if ( Options.key_id_flag ) + { + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + } + else + { + create_random_uuid(Info.CryptographicKeyID); + } + + Context = new AESEncContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) ) + result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + + if ( ASDCP_SUCCESS(result) && Options.write_hmac ) + { + Info.UsesHMAC = true; + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + } + + if ( ASDCP_SUCCESS(result) ) + result = Writer.OpenWrite(Options.out_file, Info, DDesc); + } + + if ( ASDCP_SUCCESS(result) ) + { + ui32_t duration = 0; + result = Parser.Reset(); + + while ( ASDCP_SUCCESS(result) && duration++ < Options.duration ) + { + result = Parser.ReadFrame(FrameBuffer); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + + if ( Options.encrypt_header_flag ) + FrameBuffer.PlaintextOffset(0); + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + result = Writer.WriteFrame(FrameBuffer, Context, HMAC); + + // The Writer class will forward the last block of ciphertext + // to the encryption context for use as the IV for the next + // frame. If you want to use non-sequitur IV values, un-comment + // the following line of code. + // if ( ASDCP_SUCCESS(result) && Options.key_flag ) + // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + } + } + + if ( result == RESULT_ENDOFFILE ) + result = RESULT_OK; + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + result = Writer.Finalize(); + + return result; +} + // int main(int argc, const char** argv) { Result_t result = RESULT_OK; char str_buf[64]; + g_dict = &ASDCP::DefaultSMPTEDict(); + CommandOptions Options(argc, argv); if ( Options.version_flag ) @@ -1074,7 +1635,15 @@ main(int argc, const char** argv) if ( Options.help_flag ) usage(); - if ( Options.version_flag || Options.help_flag ) + if ( Options.show_ul_values_flag ) + { + if ( Options.use_smpte_labels ) + DefaultSMPTEDict().Dump(stdout); + else + DefaultInteropDict().Dump(stdout); + } + + if ( Options.version_flag || Options.help_flag || Options.show_ul_values_flag ) return 0; if ( Options.error_flag ) @@ -1083,16 +1652,8 @@ main(int argc, const char** argv) return 3; } - if ( Options.show_ul_values ) - { - if ( Options.use_smpte_labels ) - DefaultSMPTEDict().Dump(stdout); - else - DefaultInteropDict().Dump(stdout); - } - EssenceType_t EssenceType; - result = ASDCP::RawEssenceType(Options.filenames.front().c_str(), EssenceType); + result = ASDCP::RawEssenceType(Options.filenames.front(), EssenceType); if ( ASDCP_SUCCESS(result) ) { @@ -1115,13 +1676,36 @@ main(int argc, const char** argv) case ESS_PCM_24b_48k: case ESS_PCM_24b_96k: - result = write_PCM_file(Options); + if ( Options.dolby_atmos_sync_flag ) + { + result = write_PCM_with_ATMOS_sync_file(Options); + } + else + { + result = write_PCM_file(Options); + } break; - + case ESS_TIMED_TEXT: result = write_timed_text_file(Options); break; + case ESS_DCDATA_DOLBY_ATMOS: + result = write_dolby_atmos_file(Options); + break; + + case ESS_DCDATA_UNKNOWN: + if ( ! Options.aux_data_coding.HasValue() ) + { + fprintf(stderr, "Option \"-A <UL>\" is required for Aux Data essence.\n"); + return 3; + } + else + { + result = write_aux_data_file(Options); + } + break; + default: fprintf(stderr, "%s: Unknown file type, not ASDCP-compatible essence.\n", Options.filenames.front().c_str()); diff --git a/asdcplib/src/blackwave.cpp b/asdcplib/src/blackwave.cpp index 8498655b..0ae901b0 100644 --- a/asdcplib/src/blackwave.cpp +++ b/asdcplib/src/blackwave.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2009, John Hurst +Copyright (c) 2005-2012, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file wavsplit.cpp - \version $Id: blackwave.cpp,v 1.10 2010/02/16 18:40:57 jhurst Exp $ + \version $Id: blackwave.cpp,v 1.15 2015/10/16 16:55:33 jhurst Exp $ \brief Black WAV file generator */ @@ -56,7 +56,7 @@ banner(FILE* stream = stderr) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2005-2009 John Hurst\n\n\ +Copyright (c) 2005-2012 John Hurst\n\n\ %s is part of asdcplib.\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ @@ -73,7 +73,8 @@ USAGE: %s [-v|-h[-d]] <filename>\n\ \n\ -V - Show version\n\ -h - Show help\n\ - -d <duration> - Number of 2k-sample frames to process, default 1440\n\ + -d <duration> - Number of edit units to process, default 1440\n\ + -9 - Make a 96 kHz file (default 48 kHz)\n\ \n\ Other Options:\n\ -v - Verbose, show extra detail during run\n\ @@ -94,16 +95,17 @@ public: bool verbose_flag; // true if the verbose option was selected bool version_flag; // true if the version display option was selected bool help_flag; // true if the help display option was selected + bool s96_flag; // true if the samples should be at 96 kHz ui32_t duration; // number of frames to be processed const char* filename; // filename prefix for files written by the extract mode CommandOptions(int argc, const char** argv) : - error_flag(true), verbose_flag(false), version_flag(false), help_flag(false), + error_flag(true), verbose_flag(false), version_flag(false), help_flag(false), s96_flag(false), duration(1440), filename(0) { for ( int i = 1; i < argc; i++ ) { - if ( argv[i][0] == '-' && isalpha(argv[i][1]) && argv[i][2] == 0 ) + if ( argv[i][0] == '-' && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) && argv[i][2] == 0 ) { switch ( argv[i][1] ) { @@ -113,7 +115,11 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); - duration = atoi(argv[i]); // TODO: test for negative value, should use strtol() + duration = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case '9': + s96_flag = true; break; default: @@ -153,12 +159,12 @@ make_black_wav_file(CommandOptions& Options) PCM::AudioDescriptor ADesc; ADesc.EditRate = Rational(24,1); - ADesc.AudioSamplingRate = ASDCP::SampleRate_48k; + ADesc.AudioSamplingRate = Options.s96_flag ? ASDCP::SampleRate_96k : ASDCP::SampleRate_48k; ADesc.Locked = 0; ADesc.ChannelCount = 1; ADesc.QuantizationBits = 24; ADesc.BlockAlign = 3; - ADesc.AvgBps = 14400; + ADesc.AvgBps = ADesc.BlockAlign * ADesc.AudioSamplingRate.Quotient(); ADesc.LinkedTrackID = 1; ADesc.ContainerDuration = Options.duration; @@ -169,8 +175,8 @@ make_black_wav_file(CommandOptions& Options) if ( Options.verbose_flag ) { - fprintf(stderr, "48Khz PCM Audio, %s fps (%u spf)\n", "24", - PCM::CalcSamplesPerFrame(ADesc)); + fprintf(stderr, "%s kHz PCM Audio, 24 fps (%u spf)\n", + (Options.s96_flag?"96":"48"), PCM::CalcSamplesPerFrame(ADesc)); fputs("AudioDescriptor:\n", stderr); PCM::AudioDescriptorDump(ADesc); } @@ -181,8 +187,8 @@ make_black_wav_file(CommandOptions& Options) if ( ASDCP_SUCCESS(result) ) { - Wav::SimpleWaveHeader WavHeader(ADesc); - result = WavHeader.WriteToFile(OutFile); + RF64::SimpleRF64Header WavHeader(ADesc); + result = WavHeader.WriteToFile(OutFile); } if ( ASDCP_SUCCESS(result) ) diff --git a/asdcplib/src/h__02_Reader.cpp b/asdcplib/src/h__02_Reader.cpp new file mode 100644 index 00000000..b83fdffc --- /dev/null +++ b/asdcplib/src/h__02_Reader.cpp @@ -0,0 +1,484 @@ +/* +Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file h__02_Reader.cpp + \version $Id: h__02_Reader.cpp,v 1.15 2015/10/12 15:30:46 jhurst Exp $ + \brief MXF file reader base class +*/ + +#define DEFAULT_02_MD_DECL +#include "AS_02_internal.h" + +using namespace ASDCP; +using namespace ASDCP::MXF; + +static Kumu::Mutex sg_DefaultMDInitLock; +static bool sg_DefaultMDTypesInit = false; +static const ASDCP::Dictionary *sg_dict; + +// +void +AS_02::default_md_object_init() +{ + if ( ! sg_DefaultMDTypesInit ) + { + Kumu::AutoMutex BlockLock(sg_DefaultMDInitLock); + + if ( ! sg_DefaultMDTypesInit ) + { + sg_dict = &DefaultSMPTEDict(); + g_AS02IndexReader = new AS_02::MXF::AS02IndexReader(sg_dict); + sg_DefaultMDTypesInit = true; + } + } +} + + +//--------------------------------------------------------------------------------- +// + + +AS_02::MXF::AS02IndexReader::AS02IndexReader(const ASDCP::Dictionary*& d) : + m_Duration(0), m_BytesPerEditUnit(0), + ASDCP::MXF::Partition(d), m_Dict(d) {} + +AS_02::MXF::AS02IndexReader::~AS02IndexReader() {} + +// +Result_t +AS_02::MXF::AS02IndexReader::InitFromFile(const Kumu::FileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence) +{ + typedef std::list<Kumu::mem_ptr<ASDCP::MXF::Partition> > body_part_array_t; + body_part_array_t body_part_array; + body_part_array_t::const_iterator body_part_iter; + + RIP::const_pair_iterator i; + Result_t result = m_IndexSegmentData.Capacity(128*Kumu::Kilobyte); // will be grown if needed + ui32_t first_body_sid = 0; + + // create a list of body parts and index parts + for ( i = rip.PairArray.begin(); KM_SUCCESS(result) && i != rip.PairArray.end(); ++i ) + { + if ( i->BodySID == 0 ) + continue; + + if ( first_body_sid == 0 ) + { + first_body_sid = i->BodySID; + } + else if ( i->BodySID != first_body_sid ) + { + DefaultLogSink().Debug("The index assembler is ignoring BodySID %d.\n", i->BodySID); + continue; + } + + reader.Seek(i->ByteOffset); + ASDCP::MXF::Partition *this_partition = new ASDCP::MXF::Partition(m_Dict); + assert(this_partition); + + result = this_partition->InitFromFile(reader); + + if ( KM_FAILURE(result) ) + { + delete this_partition; + return result; + } + + if ( this_partition->BodySID != i->BodySID ) + { + DefaultLogSink().Error("Partition BodySID %d does not match RIP BodySID %d.\n", + this_partition->BodySID, i->BodySID); + } + + body_part_array.push_back(0); + body_part_array.back().set(this_partition); + } + + if ( body_part_array.empty() ) + { + DefaultLogSink().Error("File has no partitions with essence data.\n"); + return RESULT_AS02_FORMAT; + } + + body_part_iter = body_part_array.begin(); + + for ( i = rip.PairArray.begin(); KM_SUCCESS(result) && i != rip.PairArray.end(); ++i ) + { + reader.Seek(i->ByteOffset); + ASDCP::MXF::Partition plain_part(m_Dict); + result = plain_part.InitFromFile(reader); + + if ( KM_FAILURE(result) ) + return result; + + if ( plain_part.IndexByteCount > 0 ) + { + if ( body_part_iter == body_part_array.end() ) + { + DefaultLogSink().Error("Index and Body partitions do not match.\n"); + break; + } + + if ( plain_part.ThisPartition == plain_part.FooterPartition ) + { + DefaultLogSink().Warn("File footer partition contains index data.\n"); + } + + // slurp up the remainder of the partition + ui32_t read_count = 0; + + assert (plain_part.IndexByteCount <= 0xFFFFFFFFL); + ui32_t bytes_this_partition = (ui32_t)plain_part.IndexByteCount; + + result = m_IndexSegmentData.Capacity(m_IndexSegmentData.Length() + bytes_this_partition); + + if ( KM_SUCCESS(result) ) + result = reader.Read(m_IndexSegmentData.Data() + m_IndexSegmentData.Length(), + bytes_this_partition, &read_count); + + if ( KM_SUCCESS(result) && read_count != bytes_this_partition ) + { + DefaultLogSink().Error("Short read of index partition: got %u, expecting %u\n", + read_count, bytes_this_partition); + return RESULT_AS02_FORMAT; + } + + if ( KM_SUCCESS(result) ) + { + ui64_t current_body_offset = 0; + ui64_t current_ec_offset = 0; + assert(body_part_iter != body_part_array.end()); + + assert(!body_part_iter->empty()); + ASDCP::MXF::Partition *tmp_partition = body_part_iter->get(); + + if ( has_header_essence && tmp_partition->ThisPartition == 0 ) + { + current_body_offset = 0; + current_ec_offset = tmp_partition->HeaderByteCount + tmp_partition->ArchiveSize(); + } + else + { + current_body_offset = tmp_partition->BodyOffset; + current_ec_offset += tmp_partition->ThisPartition + tmp_partition->ArchiveSize(); + } + + result = InitFromBuffer(m_IndexSegmentData.RoData() + m_IndexSegmentData.Length(), bytes_this_partition, current_body_offset, current_ec_offset); + m_IndexSegmentData.Length(m_IndexSegmentData.Length() + bytes_this_partition); + ++body_part_iter; + } + } + } + + if ( KM_SUCCESS(result) ) + { + std::list<InterchangeObject*>::const_iterator ii; + + for ( ii = m_PacketList->m_List.begin(); ii != m_PacketList->m_List.end(); ++ii ) + { + IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*ii); + + if ( segment != 0 ) + { + m_Duration += segment->IndexDuration; + } + } + } + +#if 0 + char identbuf[IdentBufferLen]; + std::list<InterchangeObject*>::iterator j; + std::vector<ASDCP::MXF::IndexTableSegment::IndexEntry>::iterator k; + ui32_t entry_count = 0; + + for ( j = m_PacketList->m_List.begin(); j != m_PacketList->m_List.end(); ++j ) + { + assert(*j); + ASDCP::MXF::IndexTableSegment* segment = static_cast<ASDCP::MXF::IndexTableSegment*>(*j); + + fprintf(stderr, " --------------------------------------\n"); + fprintf(stderr, " IndexEditRate = %d/%d\n", segment->IndexEditRate.Numerator, segment->IndexEditRate.Denominator); + fprintf(stderr, " IndexStartPosition = %s\n", i64sz(segment->IndexStartPosition, identbuf)); + fprintf(stderr, " IndexDuration = %s\n", i64sz(segment->IndexDuration, identbuf)); + fprintf(stderr, " EditUnitByteCount = %u\n", segment->EditUnitByteCount); + fprintf(stderr, " IndexSID = %u\n", segment->IndexSID); + fprintf(stderr, " BodySID = %u\n", segment->BodySID); + fprintf(stderr, " SliceCount = %hu\n", segment->SliceCount); + fprintf(stderr, " PosTableCount = %hu\n", segment->PosTableCount); + fprintf(stderr, " RtFileOffset = %s\n", i64sz(segment->RtFileOffset, identbuf)); + fprintf(stderr, " RtEntryOffset = %s\n", i64sz(segment->RtEntryOffset, identbuf)); + fprintf(stderr, " IndexEntryArray:\n"); + + for ( k = segment->IndexEntryArray.begin(); k != segment->IndexEntryArray.end(); ++k ) + { + fprintf(stderr, " 0x%010qx\n", k->StreamOffset); + ++entry_count; + } + } + + fprintf(stderr, "Actual entries: %d\n", entry_count); +#endif + + return result; +} + +// +ASDCP::Result_t +AS_02::MXF::AS02IndexReader::InitFromBuffer(const byte_t* p, ui32_t l, const ui64_t& body_offset, const ui64_t& essence_container_offset) +{ + Result_t result = RESULT_OK; + const byte_t* end_p = p + l; + + while ( KM_SUCCESS(result) && p < end_p ) + { + // parse the packets and index them by uid, discard KLVFill items + InterchangeObject* object = CreateObject(m_Dict, p); + assert(object); + + object->m_Lookup = m_Lookup; + result = object->InitFromBuffer(p, end_p - p); + p += object->PacketLength(); + + if ( KM_SUCCESS(result) ) + { + IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(object); + + if ( segment != 0 ) + { + segment->RtFileOffset = essence_container_offset; + segment->RtEntryOffset = body_offset; + m_PacketList->AddPacket(object); // takes ownership + } + else + { + delete object; + } + } + else + { + DefaultLogSink().Error("Error initializing index segment packet.\n"); + delete object; + } + } + + if ( KM_FAILURE(result) ) + { + DefaultLogSink().Error("Failed to initialize AS02IndexReader.\n"); + } + + return result; +} + +// +void +AS_02::MXF::AS02IndexReader::Dump(FILE* stream) +{ + if ( stream == 0 ) + stream = stderr; + + std::list<InterchangeObject*>::iterator i = m_PacketList->m_List.begin(); + for ( ; i != m_PacketList->m_List.end(); ++i ) + (*i)->Dump(stream); +} + +// +Result_t +AS_02::MXF::AS02IndexReader::GetMDObjectByID(const UUID& object_id, InterchangeObject** Object) +{ + return m_PacketList->GetMDObjectByID(object_id, Object); +} + +// +Result_t +AS_02::MXF::AS02IndexReader::GetMDObjectByType(const byte_t* type_id, InterchangeObject** Object) +{ + InterchangeObject* TmpObject; + + if ( Object == 0 ) + Object = &TmpObject; + + return m_PacketList->GetMDObjectByType(type_id, Object); +} + +// +Result_t +AS_02::MXF::AS02IndexReader::GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList) +{ + return m_PacketList->GetMDObjectsByType(ObjectID, ObjectList); +} + + +// +ui32_t +AS_02::MXF::AS02IndexReader::GetDuration() const +{ + return m_Duration; +} + +// +Result_t +AS_02::MXF::AS02IndexReader::Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry& Entry) const +{ + std::list<InterchangeObject*>::iterator i; + for ( i = m_PacketList->m_List.begin(); i != m_PacketList->m_List.end(); ++i ) + { + IndexTableSegment *segment = dynamic_cast<IndexTableSegment*>(*i); + + if ( segment != 0 ) + { + ui64_t start_pos = segment->IndexStartPosition; + + if ( segment->EditUnitByteCount > 0 ) + { + if ( m_PacketList->m_List.size() > 1 ) + DefaultLogSink().Error("Unexpected multiple IndexTableSegment in CBR file\n"); + + if ( ! segment->IndexEntryArray.empty() ) + DefaultLogSink().Error("Unexpected IndexEntryArray contents in CBR file\n"); + + Entry.StreamOffset = ((ui64_t)frame_num * segment->EditUnitByteCount) + segment->RtFileOffset; + return RESULT_OK; + } + else if ( (ui64_t)frame_num >= start_pos + && (ui64_t)frame_num < (start_pos + segment->IndexDuration) ) + { + ui64_t tmp = frame_num - start_pos; + assert(tmp <= 0xFFFFFFFFL); + Entry = segment->IndexEntryArray[(ui32_t) tmp]; + Entry.StreamOffset = Entry.StreamOffset - segment->RtEntryOffset + segment->RtFileOffset; + return RESULT_OK; + } + } + } + + DefaultLogSink().Error("AS_02::MXF::AS02IndexReader::Lookup FAILED: frame_num=%d\n", frame_num); + return RESULT_FAIL; +} + + +//--------------------------------------------------------------------------------- +// + + +AS_02::h__AS02Reader::h__AS02Reader(const ASDCP::Dictionary& d) : ASDCP::MXF::TrackFileReader<ASDCP::MXF::OP1aHeader, AS_02::MXF::AS02IndexReader>(d) {} +AS_02::h__AS02Reader::~h__AS02Reader() {} + + +// AS-DCP method of opening an MXF file for read +Result_t +AS_02::h__AS02Reader::OpenMXFRead(const char* filename) +{ + bool has_header_essence = false; + Result_t result = ASDCP::MXF::TrackFileReader<OP1aHeader, AS_02::MXF::AS02IndexReader>::OpenMXFRead(filename); + + if ( KM_SUCCESS(result) ) + result = ASDCP::MXF::TrackFileReader<OP1aHeader, AS_02::MXF::AS02IndexReader>::InitInfo(); + + if( KM_SUCCESS(result) ) + { + // + UL OP1a_ul(m_Dict->ul(MDD_OP1a)); + InterchangeObject* Object; + m_Info.LabelSetType = LS_MXF_SMPTE; + + if ( m_HeaderPart.OperationalPattern != OP1a_ul ) + { + char strbuf[IdentBufferLen]; + const MDDEntry* Entry = m_Dict->FindUL(m_HeaderPart.OperationalPattern.Value()); + + if ( Entry == 0 ) + { + DefaultLogSink().Warn("Operational pattern is not OP-1a: %s\n", + m_HeaderPart.OperationalPattern.EncodeString(strbuf, IdentBufferLen)); + } + else + { + DefaultLogSink().Warn("Operational pattern is not OP-1a: %s\n", Entry->name); + } + } + + // + if ( m_RIP.PairArray.front().ByteOffset != 0 ) + { + DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n"); + return RESULT_AS02_FORMAT; + } + + Kumu::fpos_t first_partition_after_header = 0; + bool has_body_sid = false; + RIP::pair_iterator r_i; + + for ( r_i = m_RIP.PairArray.begin(); r_i != m_RIP.PairArray.end(); ++r_i ) + { + if ( r_i->BodySID != 0 ) + { + has_body_sid = true; + } + + if ( first_partition_after_header == 0 && r_i->ByteOffset != 0 ) + { + first_partition_after_header = r_i->ByteOffset; + } + } + + // essence in header partition? + Kumu::fpos_t header_end = m_HeaderPart.HeaderByteCount + m_HeaderPart.ArchiveSize(); + has_header_essence = header_end < first_partition_after_header; + + if ( has_header_essence ) + { + DefaultLogSink().Warn("File header partition contains essence data.\n"); + } + + if ( ! has_body_sid ) + { + DefaultLogSink().Error("File contains no essence.\n"); + return RESULT_AS02_FORMAT; + } + } + + if ( KM_SUCCESS(result) ) + { + m_IndexAccess.m_Lookup = &m_HeaderPart.m_Primer; + result = m_IndexAccess.InitFromFile(m_File, m_RIP, has_header_essence); + } + + return result; +} + +// AS-DCP method of reading a plaintext or encrypted frame +Result_t +AS_02::h__AS02Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) +{ + return ASDCP::MXF::TrackFileReader<OP1aHeader, AS_02::MXF::AS02IndexReader>::ReadEKLVFrame(FrameNum, FrameBuf, EssenceUL, Ctx, HMAC); +} + +// +// end h__02_Reader.cpp +// diff --git a/asdcplib/src/h__02_Writer.cpp b/asdcplib/src/h__02_Writer.cpp new file mode 100644 index 00000000..972e556c --- /dev/null +++ b/asdcplib/src/h__02_Writer.cpp @@ -0,0 +1,379 @@ +/* +Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, +John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file h__02_Writer.cpp + \version $Id: h__02_Writer.cpp,v 1.14 2015/10/09 23:41:11 jhurst Exp $ + \brief MXF file writer base class +*/ + +#include "AS_02_internal.h" + +using namespace ASDCP; +using namespace ASDCP::MXF; + +static const ui32_t CBRIndexEntriesPerSegment = 5000; + + +//------------------------------------------------------------------------------------------ +// + +AS_02::MXF::AS02IndexWriterVBR::AS02IndexWriterVBR(const ASDCP::Dictionary*& d) : + Partition(d), m_CurrentSegment(0), m_Dict(d), m_Lookup(0) +{ + BodySID = 0; + IndexSID = 129; +} + +AS_02::MXF::AS02IndexWriterVBR::~AS02IndexWriterVBR() {} + +// +Result_t +AS_02::MXF::AS02IndexWriterVBR::WriteToFile(Kumu::FileWriter& Writer) +{ + assert(m_Dict); + ASDCP::FrameBuffer index_body_buffer; + ui32_t index_body_size = m_PacketList->m_List.size() * MaxIndexSegmentSize; // segment-count * max-segment-size + Result_t result = index_body_buffer.Capacity(index_body_size); + ui64_t start_position = 0; + + if ( m_CurrentSegment != 0 ) + { + m_CurrentSegment->IndexDuration = m_CurrentSegment->IndexEntryArray.size(); + start_position = m_CurrentSegment->IndexStartPosition + m_CurrentSegment->IndexDuration; + m_CurrentSegment = 0; + } + + std::list<InterchangeObject*>::iterator pl_i = m_PacketList->m_List.begin(); + for ( ; pl_i != m_PacketList->m_List.end() && KM_SUCCESS(result); pl_i++ ) + { + InterchangeObject* object = *pl_i; + object->m_Lookup = m_Lookup; + + ASDCP::FrameBuffer WriteWrapper; + WriteWrapper.SetData(index_body_buffer.Data() + index_body_buffer.Size(), + index_body_buffer.Capacity() - index_body_buffer.Size()); + result = object->WriteToBuffer(WriteWrapper); + index_body_buffer.Size(index_body_buffer.Size() + WriteWrapper.Size()); + delete *pl_i; + *pl_i = 0; + } + + m_PacketList->m_List.clear(); + + if ( KM_SUCCESS(result) ) + { + IndexByteCount = index_body_buffer.Size(); + UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); + result = Partition::WriteToFile(Writer, body_ul); + } + + if ( KM_SUCCESS(result) ) + { + ui32_t write_count = 0; + result = Writer.Write(index_body_buffer.RoData(), index_body_buffer.Size(), &write_count); + assert(write_count == index_body_buffer.Size()); + } + + if ( KM_SUCCESS(result) ) + { + m_CurrentSegment = new IndexTableSegment(m_Dict); + assert(m_CurrentSegment); + AddChildObject(m_CurrentSegment); + m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry()); + m_CurrentSegment->IndexEditRate = m_EditRate; + m_CurrentSegment->IndexStartPosition = start_position; + } + + return result; +} + +// +void +AS_02::MXF::AS02IndexWriterVBR::Dump(FILE* stream) +{ + if ( stream == 0 ) + stream = stderr; + + Partition::Dump(stream); + + std::list<InterchangeObject*>::iterator i = m_PacketList->m_List.begin(); + for ( ; i != m_PacketList->m_List.end(); ++i ) + { + (*i)->Dump(stream); + } +} + +// +ui32_t +AS_02::MXF::AS02IndexWriterVBR::GetDuration() const +{ + ui32_t duration = 0; + std::list<InterchangeObject*>::const_iterator i; + + for ( i = m_PacketList->m_List.begin(); i != m_PacketList->m_List.end(); ++i ) + { + IndexTableSegment* segment = dynamic_cast<IndexTableSegment*>(*i); + if ( segment != 0 ) + { + duration += segment->IndexEntryArray.size(); + } + } + + return duration; +} + +// +void +AS_02::MXF::AS02IndexWriterVBR::PushIndexEntry(const IndexTableSegment::IndexEntry& Entry) +{ + // do we have an available segment? + if ( m_CurrentSegment == 0 ) + { // no, set up a new segment + m_CurrentSegment = new IndexTableSegment(m_Dict); + assert(m_CurrentSegment); + AddChildObject(m_CurrentSegment); + m_CurrentSegment->DeltaEntryArray.push_back(IndexTableSegment::DeltaEntry()); + m_CurrentSegment->IndexEditRate = m_EditRate; + m_CurrentSegment->IndexStartPosition = 0; + } + + m_CurrentSegment->IndexEntryArray.push_back(Entry); +} + + +//------------------------------------------------------------------------------------------ +// + +// +AS_02::h__AS02WriterFrame::h__AS02WriterFrame(const ASDCP::Dictionary& d) : + h__AS02Writer<AS_02::MXF::AS02IndexWriterVBR>(d), m_IndexStrategy(AS_02::IS_FOLLOW) {} + +AS_02::h__AS02WriterFrame::~h__AS02WriterFrame() {} + +// +Result_t +AS_02::h__AS02WriterFrame::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC) +{ + ui64_t this_stream_offset = m_StreamOffset; // m_StreamOffset will be changed by the call to Write_EKLV_Packet + + Result_t result = Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten, + m_StreamOffset, FrameBuf, EssenceUL, Ctx, HMAC); + + if ( KM_SUCCESS(result) ) + { + IndexTableSegment::IndexEntry Entry; + Entry.StreamOffset = this_stream_offset; + m_IndexWriter.PushIndexEntry(Entry); + } + + if ( m_FramesWritten > 1 && ( ( m_FramesWritten + 1 ) % m_PartitionSpace ) == 0 ) + { + m_IndexWriter.ThisPartition = m_File.Tell(); + m_IndexWriter.WriteToFile(m_File); + m_RIP.PairArray.push_back(RIP::PartitionPair(0, m_IndexWriter.ThisPartition)); + + UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); + Partition body_part(m_Dict); + body_part.BodySID = 1; + body_part.OperationalPattern = m_HeaderPart.OperationalPattern; + body_part.EssenceContainers = m_HeaderPart.EssenceContainers; + body_part.ThisPartition = m_File.Tell(); + + body_part.BodyOffset = m_StreamOffset; + result = body_part.WriteToFile(m_File, body_ul); + m_RIP.PairArray.push_back(RIP::PartitionPair(1, body_part.ThisPartition)); + } + + return result; +} + + +//------------------------------------------------------------------------------------------ +// + + +AS_02::MXF::AS02IndexWriterCBR::AS02IndexWriterCBR(const ASDCP::Dictionary*& d) : + Partition(d), m_CurrentSegment(0), m_Dict(d), m_Lookup(0), m_Duration(0), m_SampleSize(0) +{ + BodySID = 0; + IndexSID = 129; +} + +AS_02::MXF::AS02IndexWriterCBR::~AS02IndexWriterCBR() {} + +// +Result_t +AS_02::MXF::AS02IndexWriterCBR::WriteToFile(Kumu::FileWriter& Writer) +{ + assert(m_Dict); + ASDCP::FrameBuffer index_body_buffer; + ui32_t index_body_size = MaxIndexSegmentSize; // segment-count * max-segment-size + Result_t result = index_body_buffer.Capacity(index_body_size); + + m_CurrentSegment = new IndexTableSegment(m_Dict); + assert(m_CurrentSegment); + m_CurrentSegment->m_Lookup = m_Lookup; + m_CurrentSegment->IndexEditRate = m_EditRate; + m_CurrentSegment->IndexStartPosition = 0; + m_CurrentSegment->IndexDuration = m_Duration; + m_CurrentSegment->EditUnitByteCount = m_SampleSize; + AddChildObject(m_CurrentSegment); + + ASDCP::FrameBuffer WriteWrapper; + WriteWrapper.SetData(index_body_buffer.Data() + index_body_buffer.Size(), + index_body_buffer.Capacity() - index_body_buffer.Size()); + + result = m_CurrentSegment->WriteToBuffer(WriteWrapper); + index_body_buffer.Size(index_body_buffer.Size() + WriteWrapper.Size()); + delete m_CurrentSegment; + m_CurrentSegment = 0; + m_PacketList->m_List.clear(); + + if ( KM_SUCCESS(result) ) + { + IndexByteCount = index_body_buffer.Size(); + UL body_ul(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); + result = Partition::WriteToFile(Writer, body_ul); + } + + if ( KM_SUCCESS(result) ) + { + ui32_t write_count = 0; + result = Writer.Write(index_body_buffer.RoData(), index_body_buffer.Size(), &write_count); + assert(write_count == index_body_buffer.Size()); + } + + return result; +} + +// +ui32_t +AS_02::MXF::AS02IndexWriterCBR::GetDuration() const +{ + return m_Duration; +} + +// +void +AS_02::MXF::AS02IndexWriterCBR::SetEditRate(const ASDCP::Rational& edit_rate, const ui32_t& sample_size) +{ + m_EditRate = edit_rate; + m_SampleSize = sample_size; +} + + +//------------------------------------------------------------------------------------------ +// + +// +AS_02::h__AS02WriterClip::h__AS02WriterClip(const ASDCP::Dictionary& d) : + h__AS02Writer<AS_02::MXF::AS02IndexWriterCBR>(d), + m_ECStart(0), m_ClipStart(0), m_IndexStrategy(AS_02::IS_FOLLOW) {} + +AS_02::h__AS02WriterClip::~h__AS02WriterClip() {} + +// +bool +AS_02::h__AS02WriterClip::HasOpenClip() const +{ + return m_ClipStart != 0; +} + +// +Result_t +AS_02::h__AS02WriterClip::StartClip(const byte_t* EssenceUL, AESEncContext* Ctx, HMACContext* HMAC) +{ + if ( Ctx != 0 ) + { + DefaultLogSink().Error("Encryption not yet supported for PCM clip-wrap.\n"); + return RESULT_STATE; + } + + if ( m_ClipStart != 0 ) + { + DefaultLogSink().Error("Cannot open clip, clip already open.\n"); + return RESULT_STATE; + } + + m_ClipStart = m_File.Tell(); + byte_t clip_buffer[24] = {0}; + memcpy(clip_buffer, EssenceUL, 16); + bool check = Kumu::write_BER(clip_buffer+16, 0, 8); + assert(check); + return m_File.Write(clip_buffer, 24); +} + +// +Result_t +AS_02::h__AS02WriterClip::WriteClipBlock(const ASDCP::FrameBuffer& FrameBuf) +{ + if ( m_ClipStart == 0 ) + { + DefaultLogSink().Error("Cannot write clip block, no clip open.\n"); + return RESULT_STATE; + } + + return m_File.Write(FrameBuf.RoData(), FrameBuf.Size()); +} + +// +Result_t +AS_02::h__AS02WriterClip::FinalizeClip(ui32_t bytes_per_frame) +{ + if ( m_ClipStart == 0 ) + { + DefaultLogSink().Error("Cannot close clip, clip not open.\n"); + return RESULT_STATE; + } + + ui64_t current_position = m_File.Tell(); + Result_t result = m_File.Seek(m_ClipStart+16); + + if ( KM_SUCCESS(result) ) + { + byte_t clip_buffer[8] = {0}; + ui64_t size = static_cast<ui64_t>(m_FramesWritten) * bytes_per_frame; + bool check = Kumu::write_BER(clip_buffer, size, 8); + assert(check); + result = m_File.Write(clip_buffer, 8); + } + + if ( KM_SUCCESS(result) ) + { + result = m_File.Seek(current_position); + m_ClipStart = 0; + } + + return result; +} + + + +// +// end h__02_Writer.cpp +// diff --git a/asdcplib/src/h__Reader.cpp b/asdcplib/src/h__Reader.cpp index ebf34434..04f31236 100755 --- a/asdcplib/src/h__Reader.cpp +++ b/asdcplib/src/h__Reader.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file h__Reader.cpp - \version $Id: h__Reader.cpp,v 1.31 2012/02/07 18:54:25 jhurst Exp $ + \version $Id: h__Reader.cpp,v 1.39 2015/10/09 23:41:11 jhurst Exp $ \brief MXF file reader base class */ @@ -38,7 +38,7 @@ using namespace ASDCP::MXF; static Kumu::Mutex sg_DefaultMDInitLock; static bool sg_DefaultMDTypesInit = false; -static const ASDCP::Dictionary *sg_dict; +static const ASDCP::Dictionary *sg_dict = 0; // void @@ -51,128 +51,134 @@ ASDCP::default_md_object_init() if ( ! sg_DefaultMDTypesInit ) { sg_dict = &DefaultSMPTEDict(); - g_OPAtomHeader = new ASDCP::MXF::OPAtomHeader(sg_dict); + g_OP1aHeader = new ASDCP::MXF::OP1aHeader(sg_dict); g_OPAtomIndexFooter = new ASDCP::MXF::OPAtomIndexFooter(sg_dict); + g_RIP = new ASDCP::MXF::RIP(sg_dict); sg_DefaultMDTypesInit = true; } } } -// -ASDCP::h__Reader::h__Reader(const Dictionary& d) : - m_Dict(&d), m_HeaderPart(m_Dict), m_BodyPart(m_Dict), m_FooterPart(m_Dict), m_EssenceStart(0) -{ - default_md_object_init(); -} - -ASDCP::h__Reader::~h__Reader() -{ - Close(); -} - -void -ASDCP::h__Reader::Close() -{ - m_File.Close(); -} - //------------------------------------------------------------------------------------------ // // +ASDCP::h__ASDCPReader::h__ASDCPReader(const Dictionary& d) : MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>(d), m_BodyPart(m_Dict) {} +ASDCP::h__ASDCPReader::~h__ASDCPReader() {} + + +// AS-DCP method of opening an MXF file for read Result_t -ASDCP::h__Reader::InitInfo() +ASDCP::h__ASDCPReader::OpenMXFRead(const std::string& filename) { - assert(m_Dict); - InterchangeObject* Object; + Result_t result = ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::OpenMXFRead(filename); - m_Info.LabelSetType = LS_MXF_UNKNOWN; + if ( KM_SUCCESS(result) ) + result = ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::InitInfo(); - if ( m_HeaderPart.OperationalPattern.ExactMatch(MXFInterop_OPAtom_Entry().ul) ) - m_Info.LabelSetType = LS_MXF_INTEROP; - else if ( m_HeaderPart.OperationalPattern.ExactMatch(SMPTE_390_OPAtom_Entry().ul) ) - m_Info.LabelSetType = LS_MXF_SMPTE; + if( KM_SUCCESS(result) ) + { + // + InterchangeObject* Object; - // Identification - Result_t result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(Identification), &Object); + m_Info.LabelSetType = LS_MXF_UNKNOWN; - if( ASDCP_SUCCESS(result) ) - MD_to_WriterInfo((Identification*)Object, m_Info); + if ( m_HeaderPart.OperationalPattern.ExactMatch(MXFInterop_OPAtom_Entry().ul) ) + { + m_Info.LabelSetType = LS_MXF_INTEROP; + } + else if ( m_HeaderPart.OperationalPattern.ExactMatch(SMPTE_390_OPAtom_Entry().ul) ) + { + m_Info.LabelSetType = LS_MXF_SMPTE; + } + else + { + char strbuf[IdentBufferLen]; + const MDDEntry* Entry = m_Dict->FindUL(m_HeaderPart.OperationalPattern.Value()); - // SourcePackage - if( ASDCP_SUCCESS(result) ) - result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(SourcePackage), &Object); + if ( Entry == 0 ) + { + DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", + m_HeaderPart.OperationalPattern.EncodeString(strbuf, IdentBufferLen)); + } + else + { + DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", Entry->name); + } + } - if( ASDCP_SUCCESS(result) ) - { - SourcePackage* SP = (SourcePackage*)Object; - memcpy(m_Info.AssetUUID, SP->PackageUID.Value() + 16, UUIDlen); - } + if ( m_RIP.PairArray.front().ByteOffset != 0 ) + { + DefaultLogSink().Error("First Partition in RIP is not at offset 0.\n"); + result = RESULT_FORMAT; + } - // optional CryptographicContext - if( ASDCP_SUCCESS(result) ) - { - Result_t cr_result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CryptographicContext), &Object); + // + if ( m_RIP.PairArray.size() < 2 ) + { + // OP-Atom states that there will be either two or three partitions: + // one closed header and one closed footer with an optional body + // SMPTE 429-5 files may have many partitions, see SMPTE ST 410. + DefaultLogSink().Warn("RIP entry count is less than 2: %u\n", m_RIP.PairArray.size()); + } + else if ( m_RIP.PairArray.size() > 2 ) + { + // if this is a three partition file, go to the body + // partition and read the partition pack + RIP::const_pair_iterator r_i = m_RIP.PairArray.begin(); + r_i++; + m_File.Seek((*r_i).ByteOffset); + result = m_BodyPart.InitFromFile(m_File); - if( ASDCP_SUCCESS(cr_result) ) - MD_to_CryptoInfo((CryptographicContext*)Object, m_Info, *m_Dict); + if( ASDCP_FAILURE(result) ) + { + DefaultLogSink().Error("ASDCP::h__ASDCPReader::OpenMXFRead, m_BodyPart.InitFromFile failed\n"); + } + } } - return result; -} - - -// standard method of opening an MXF file for read -Result_t -ASDCP::h__Reader::OpenMXFRead(const char* filename) -{ - m_LastPosition = 0; - Result_t result = m_File.OpenRead(filename); + if ( KM_SUCCESS(result) ) + { + // this position will be at either + // a) the spot in the header partition where essence units appear, or + // b) right after the body partition header (where essence units appear) + m_HeaderPart.BodyOffset = m_File.Tell(); - if ( ASDCP_SUCCESS(result) ) - result = m_HeaderPart.InitFromFile(m_File); + result = m_File.Seek(m_HeaderPart.FooterPartition); - if ( ASDCP_SUCCESS(result) ) - { - // if this is a three partition file, go to the body - // partition and read the partition pack - if ( m_HeaderPart.m_RIP.PairArray.size() > 2 ) + if ( ASDCP_SUCCESS(result) ) { - Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin(); - r_i++; - m_File.Seek((*r_i).ByteOffset); - - result = m_BodyPart.InitFromFile(m_File); + m_IndexAccess.m_Lookup = &m_HeaderPart.m_Primer; + result = m_IndexAccess.InitFromFile(m_File); } - - m_EssenceStart = m_File.Tell(); } + m_File.Seek(m_HeaderPart.BodyOffset); return result; } +// AS-DCP method of reading a plaintext or encrypted frame +Result_t +ASDCP::h__ASDCPReader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) +{ + return ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::ReadEKLVFrame(m_HeaderPart.BodyOffset, FrameNum, FrameBuf, + EssenceUL, Ctx, HMAC); +} -// standard method of populating the in-memory index Result_t -ASDCP::h__Reader::InitMXFIndex() +ASDCP::h__ASDCPReader::LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, + i8_t& temporalOffset, i8_t& keyFrameOffset) { - if ( ! m_File.IsOpen() ) - return RESULT_INIT; + return ASDCP::MXF::TrackFileReader<OP1aHeader, OPAtomIndexFooter>::LocateFrame(m_HeaderPart.BodyOffset, FrameNum, + streamOffset, temporalOffset, keyFrameOffset); +} - Result_t result = m_File.Seek(m_HeaderPart.FooterPartition); - if ( ASDCP_SUCCESS(result) ) - { - m_FooterPart.m_Lookup = &m_HeaderPart.m_Primer; - result = m_FooterPart.InitFromFile(m_File); - } - - if ( ASDCP_SUCCESS(result) ) - m_File.Seek(m_EssenceStart); +//------------------------------------------------------------------------------------------ +// - return result; -} // Result_t @@ -206,7 +212,7 @@ ASDCP::KLReader::ReadKLFromFile(Kumu::FileReader& Reader) if ( ber_size < MXF_BER_LENGTH ) { - DefaultLogSink().Error("BER size %d shorter than AS-DCP minimum %d.\n", + DefaultLogSink().Error("BER size %d shorter than AS-DCP/AS-02 minimum %d.\n", ber_size, MXF_BER_LENGTH); return RESULT_FORMAT; } @@ -229,55 +235,31 @@ ASDCP::KLReader::ReadKLFromFile(Kumu::FileReader& Reader) return InitFromBuffer(m_KeyBuf, header_length); } -// standard method of reading a plaintext or encrypted frame -Result_t -ASDCP::h__Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf, - const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) -{ - // look up frame index node - IndexTableSegment::IndexEntry TmpEntry; - - if ( ASDCP_FAILURE(m_FooterPart.Lookup(FrameNum, TmpEntry)) ) - { - DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum); - return RESULT_RANGE; - } - - // get frame position and go read the frame's key and length - Kumu::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset; - Result_t result = RESULT_OK; - if ( FilePosition != m_LastPosition ) - { - m_LastPosition = FilePosition; - result = m_File.Seek(FilePosition); - } - - if( ASDCP_SUCCESS(result) ) - result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC); - - return result; -} +//------------------------------------------------------------------------------------------ +// +// base subroutine for reading a KLV packet, assumes file position is at the first byte of the packet Result_t -ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf, - const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) +ASDCP::Read_EKLV_Packet(Kumu::FileReader& File, const ASDCP::Dictionary& Dict, + const ASDCP::WriterInfo& Info, Kumu::fpos_t& LastPosition, ASDCP::FrameBuffer& CtFrameBuf, + ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf, + const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC) { KLReader Reader; - Result_t result = Reader.ReadKLFromFile(m_File); + Result_t result = Reader.ReadKLFromFile(File); - if ( ASDCP_FAILURE(result) ) + if ( KM_FAILURE(result) ) return result; UL Key(Reader.Key()); ui64_t PacketLength = Reader.Length(); - m_LastPosition = m_LastPosition + Reader.KLLength() + PacketLength; - assert(m_Dict); + LastPosition = LastPosition + Reader.KLLength() + PacketLength; - if ( Key.MatchIgnoreStream(m_Dict->ul(MDD_CryptEssence)) ) // ignore the stream numbers + if ( Key.MatchIgnoreStream(Dict.ul(MDD_CryptEssence)) ) // ignore the stream numbers { - if ( ! m_Info.EncryptedEssence ) + if ( ! Info.EncryptedEssence ) { DefaultLogSink().Error("EKLV packet found, no Cryptographic Context in header.\n"); return RESULT_FORMAT; @@ -285,10 +267,9 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::Fra // read encrypted triplet value into internal buffer assert(PacketLength <= 0xFFFFFFFFL); - m_CtFrameBuf.Capacity((ui32_t) PacketLength); + CtFrameBuf.Capacity((ui32_t) PacketLength); ui32_t read_count; - result = m_File.Read(m_CtFrameBuf.Data(), (ui32_t) PacketLength, - &read_count); + result = File.Read(CtFrameBuf.Data(), (ui32_t) PacketLength, &read_count); if ( ASDCP_FAILURE(result) ) return result; @@ -299,17 +280,17 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::Fra return RESULT_FORMAT; } - m_CtFrameBuf.Size((ui32_t) PacketLength); + CtFrameBuf.Size((ui32_t) PacketLength); // should be const but mxflib::ReadBER is not - byte_t* ess_p = m_CtFrameBuf.Data(); + byte_t* ess_p = CtFrameBuf.Data(); // read context ID length if ( ! Kumu::read_test_BER(&ess_p, UUIDlen) ) return RESULT_FORMAT; // test the context ID - if ( memcmp(ess_p, m_Info.ContextID, UUIDlen) != 0 ) + if ( memcmp(ess_p, Info.ContextID, UUIDlen) != 0 ) { DefaultLogSink().Error("Packet's Cryptographic Context ID does not match the header.\n"); return RESULT_FORMAT; @@ -331,13 +312,20 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::Fra if ( ! UL(ess_p).MatchIgnoreStream(EssenceUL) ) // ignore the stream number { char strbuf[IntBufferLen]; - const MDDEntry* Entry = m_Dict->FindUL(Key.Value()); + const MDDEntry* Entry = Dict.FindUL(Key.Value()); + if ( Entry == 0 ) - DefaultLogSink().Warn("Unexpected Encrypted Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen)); + { + DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen)); + } else - DefaultLogSink().Warn("Unexpected Encrypted Essence UL found: %s.\n", Entry->name); + { + DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name); + } + return RESULT_FORMAT; } + ess_p += SMPTE_UL_LENGTH; // read SourceLength length @@ -363,7 +351,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::Fra return RESULT_FORMAT; } - ui32_t tmp_len = esv_length + (m_Info.UsesHMAC ? klv_intpack_size : 0); + ui32_t tmp_len = esv_length + (Info.UsesHMAC ? klv_intpack_size : 0); if ( PacketLength < tmp_len ) { @@ -385,10 +373,10 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::Fra FrameBuf.FrameNumber(FrameNum); // detect and test integrity pack - if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC && HMAC ) + if ( ASDCP_SUCCESS(result) && Info.UsesHMAC && HMAC ) { IntegrityPack IntPack; - result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, SequenceNum, HMAC); + result = IntPack.TestValues(TmpWrapper, Info.AssetUUID, SequenceNum, HMAC); } } else // return ciphertext to caller @@ -421,7 +409,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::Fra // read the data into the supplied buffer ui32_t read_count; assert(PacketLength <= 0xFFFFFFFFL); - result = m_File.Read(FrameBuf.Data(), (ui32_t) PacketLength, &read_count); + result = File.Read(FrameBuf.Data(), (ui32_t) PacketLength, &read_count); if ( ASDCP_FAILURE(result) ) return result; @@ -443,11 +431,17 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::Fra else { char strbuf[IntBufferLen]; - const MDDEntry* Entry = m_Dict->FindUL(Key.Value()); + const MDDEntry* Entry = Dict.FindUL(Key.Value()); + if ( Entry == 0 ) - DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen)); + { + DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen)); + } else - DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name); + { + DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name); + } + return RESULT_FORMAT; } diff --git a/asdcplib/src/h__Writer.cpp b/asdcplib/src/h__Writer.cpp index 676267ce..c0ed2d3b 100755 --- a/asdcplib/src/h__Writer.cpp +++ b/asdcplib/src/h__Writer.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file h__Writer.cpp - \version $Id: h__Writer.cpp,v 1.51 2012/02/07 18:54:25 jhurst Exp $ + \version $Id: h__Writer.cpp,v 1.59 2015/10/09 23:41:11 jhurst Exp $ \brief MXF file writer base class */ @@ -35,56 +35,18 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace ASDCP; using namespace ASDCP::MXF; -// a magic number identifying asdcplib -#ifndef ASDCP_BUILD_NUMBER -#define ASDCP_BUILD_NUMBER 0x6A68 -#endif - - -static std::vector<int> -version_split(const char* str) -{ - std::vector<int> result; - - const char* pstr = str; - const char* r = strchr(pstr, '.'); - - while ( r != 0 ) - { - assert(r >= pstr); - if ( r > pstr ) - result.push_back(atoi(pstr)); - - pstr = r + 1; - r = strchr(pstr, '.'); - } - - if( strlen(pstr) > 0 ) - result.push_back(atoi(pstr)); - - assert(result.size() == 3); - return result; -} - - // -ASDCP::h__Writer::h__Writer(const Dictionary& d) : - m_Dict(&d), m_HeaderSize(0), m_HeaderPart(m_Dict), - m_BodyPart(m_Dict), m_FooterPart(m_Dict), m_EssenceStart(0), - m_EssenceDescriptor(0), m_FramesWritten(0), m_StreamOffset(0) -{ - default_md_object_init(); -} - -ASDCP::h__Writer::~h__Writer() +ui32_t +ASDCP::derive_timecode_rate_from_edit_rate(const ASDCP::Rational& edit_rate) { + return floor(0.5 + edit_rate.Quotient()); } // // add DMS CryptographicFramework entry to source package void -AddDMScrypt(Partition& HeaderPart, SourcePackage& Package, - WriterInfo& Descr, const UL& WrappingUL, const Dictionary*& Dict) +ASDCP::AddDMScrypt(Partition& HeaderPart, SourcePackage& Package, + WriterInfo& Descr, const UL& WrappingUL, const Dictionary*& Dict) { assert(Dict); // Essence Track @@ -103,7 +65,7 @@ AddDMScrypt(Partition& HeaderPart, SourcePackage& Package, HeaderPart.AddChildObject(Segment); Seq->StructuralComponents.push_back(Segment->InstanceUID); Segment->EventComment = "AS-DCP KLV Encryption"; - + CryptographicFramework* CFW = new CryptographicFramework(Dict); HeaderPart.AddChildObject(CFW); Segment->DMFramework = CFW->InstanceUID; @@ -119,326 +81,18 @@ AddDMScrypt(Partition& HeaderPart, SourcePackage& Package, Context->CryptographicKeyID.Set(Descr.CryptographicKeyID); } -// -void -ASDCP::h__Writer::InitHeader() -{ - assert(m_Dict); - assert(m_EssenceDescriptor); - - m_HeaderPart.m_Primer.ClearTagList(); - m_HeaderPart.m_Preface = new Preface(m_Dict); - m_HeaderPart.AddChildObject(m_HeaderPart.m_Preface); - - // Set the Operational Pattern label -- we're just starting and have no RIP or index, - // so we tell the world by using OP1a - m_HeaderPart.m_Preface->OperationalPattern = UL(m_Dict->ul(MDD_OP1a)); - m_HeaderPart.OperationalPattern = m_HeaderPart.m_Preface->OperationalPattern; - - // First RIP Entry - if ( m_Info.LabelSetType == LS_MXF_SMPTE ) - m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, 0)); // 3-part, no essence in header - else - m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, 0)); // 2-part, essence in header - - // - // Identification - // - Identification* Ident = new Identification(m_Dict); - m_HeaderPart.AddChildObject(Ident); - m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID); - - Kumu::GenRandomValue(Ident->ThisGenerationUID); - Ident->CompanyName = m_Info.CompanyName.c_str(); - Ident->ProductName = m_Info.ProductName.c_str(); - Ident->VersionString = m_Info.ProductVersion.c_str(); - Ident->ProductUID.Set(m_Info.ProductUUID); - Ident->Platform = ASDCP_PLATFORM; - - std::vector<int> version = version_split(Version()); - - Ident->ToolkitVersion.Major = version[0]; - Ident->ToolkitVersion.Minor = version[1]; - Ident->ToolkitVersion.Patch = version[2]; - Ident->ToolkitVersion.Build = ASDCP_BUILD_NUMBER; - Ident->ToolkitVersion.Release = VersionType::RL_RELEASE; -} - -// -template <class ClipT> -struct TrackSet -{ - MXF::Track* Track; - MXF::Sequence* Sequence; - ClipT* Clip; - - TrackSet() : Track(0), Sequence(0), Clip(0) {} -}; -// -template <class PackageT, class ClipT> -TrackSet<ClipT> -CreateTrackAndSequence(OPAtomHeader& Header, PackageT& Package, const std::string TrackName, - const MXF::Rational& EditRate, const UL& Definition, ui32_t TrackID, const Dictionary*& Dict) -{ - TrackSet<ClipT> NewTrack; - - NewTrack.Track = new Track(Dict); - Header.AddChildObject(NewTrack.Track); - NewTrack.Track->EditRate = EditRate; - Package.Tracks.push_back(NewTrack.Track->InstanceUID); - NewTrack.Track->TrackID = TrackID; - NewTrack.Track->TrackName = TrackName.c_str(); - - NewTrack.Sequence = new Sequence(Dict); - Header.AddChildObject(NewTrack.Sequence); - NewTrack.Track->Sequence = NewTrack.Sequence->InstanceUID; - NewTrack.Sequence->DataDefinition = Definition; - - return NewTrack; -} // -template <class PackageT> -TrackSet<TimecodeComponent> -CreateTimecodeTrack(OPAtomHeader& Header, PackageT& Package, - const MXF::Rational& EditRate, ui32_t TCFrameRate, ui64_t TCStart, const Dictionary*& Dict) -{ - assert(Dict); - UL TCUL(Dict->ul(MDD_TimecodeDataDef)); - - TrackSet<TimecodeComponent> NewTrack = CreateTrackAndSequence<PackageT, TimecodeComponent>(Header, Package, "Timecode Track", EditRate, TCUL, 1, Dict); +ASDCP::h__ASDCPWriter::h__ASDCPWriter(const Dictionary& d) : + MXF::TrackFileWriter<OP1aHeader>(d), m_BodyPart(m_Dict), m_FooterPart(m_Dict) {} - NewTrack.Clip = new TimecodeComponent(Dict); - Header.AddChildObject(NewTrack.Clip); - NewTrack.Sequence->StructuralComponents.push_back(NewTrack.Clip->InstanceUID); - NewTrack.Clip->RoundedTimecodeBase = TCFrameRate; - NewTrack.Clip->StartTimecode = TCStart; - NewTrack.Clip->DataDefinition = TCUL; - - return NewTrack; -} +ASDCP::h__ASDCPWriter::~h__ASDCPWriter() {} // -void -ASDCP::h__Writer::AddSourceClip(const MXF::Rational& EditRate, ui32_t TCFrameRate, - const std::string& TrackName, const UL& EssenceUL, - const UL& DataDefinition, const std::string& PackageLabel) -{ - // - ContentStorage* Storage = new ContentStorage(m_Dict); - m_HeaderPart.AddChildObject(Storage); - m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID; - - EssenceContainerData* ECD = new EssenceContainerData(m_Dict); - m_HeaderPart.AddChildObject(ECD); - Storage->EssenceContainerData.push_back(ECD->InstanceUID); - ECD->IndexSID = 129; - ECD->BodySID = 1; - - UUID assetUUID(m_Info.AssetUUID); - UMID SourcePackageUMID, MaterialPackageUMID; - SourcePackageUMID.MakeUMID(0x0f, assetUUID); - MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence - - // - // Material Package - // - m_MaterialPackage = new MaterialPackage(m_Dict); - m_MaterialPackage->Name = "AS-DCP Material Package"; - m_MaterialPackage->PackageUID = MaterialPackageUMID; - m_HeaderPart.AddChildObject(m_MaterialPackage); - Storage->Packages.push_back(m_MaterialPackage->InstanceUID); - - TrackSet<TimecodeComponent> MPTCTrack = - CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage, - EditRate, TCFrameRate, 0, m_Dict); - m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration)); - m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration)); - - TrackSet<SourceClip> MPTrack = - CreateTrackAndSequence<MaterialPackage, SourceClip>(m_HeaderPart, *m_MaterialPackage, - TrackName, EditRate, DataDefinition, - 2, m_Dict); - m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration)); - - MPTrack.Clip = new SourceClip(m_Dict); - m_HeaderPart.AddChildObject(MPTrack.Clip); - MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID); - MPTrack.Clip->DataDefinition = DataDefinition; - MPTrack.Clip->SourcePackageID = SourcePackageUMID; - MPTrack.Clip->SourceTrackID = 2; - m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration)); - - - // - // File (Source) Package - // - m_FilePackage = new SourcePackage(m_Dict); - m_FilePackage->Name = PackageLabel.c_str(); - m_FilePackage->PackageUID = SourcePackageUMID; - ECD->LinkedPackageUID = SourcePackageUMID; - - m_HeaderPart.AddChildObject(m_FilePackage); - Storage->Packages.push_back(m_FilePackage->InstanceUID); - - TrackSet<TimecodeComponent> FPTCTrack = - CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage, - EditRate, TCFrameRate, - ui64_C(3600) * TCFrameRate, m_Dict); - m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration)); - m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration)); - TrackSet<SourceClip> FPTrack = - CreateTrackAndSequence<SourcePackage, SourceClip>(m_HeaderPart, *m_FilePackage, - TrackName, EditRate, DataDefinition, - 2, m_Dict); - m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration)); - - // Consult ST 379:2004 Sec. 6.3, "Element to track relationship" to see where "12" comes from. - FPTrack.Track->TrackNumber = KM_i32_BE(Kumu::cp2i<ui32_t>((EssenceUL.Value() + 12))); - - FPTrack.Clip = new SourceClip(m_Dict); - m_HeaderPart.AddChildObject(FPTrack.Clip); - FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID); - FPTrack.Clip->DataDefinition = DataDefinition; - - // for now we do not allow setting this value, so all files will be 'original' - FPTrack.Clip->SourceTrackID = 0; - FPTrack.Clip->SourcePackageID = NilUMID; - m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration)); - - m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID; -} - -// -void -ASDCP::h__Writer::AddDMSegment(const MXF::Rational& EditRate, ui32_t TCFrameRate, - const std::string& TrackName, const UL& DataDefinition, - const std::string& PackageLabel) -{ - // - ContentStorage* Storage = new ContentStorage(m_Dict); - m_HeaderPart.AddChildObject(Storage); - m_HeaderPart.m_Preface->ContentStorage = Storage->InstanceUID; - - EssenceContainerData* ECD = new EssenceContainerData(m_Dict); - m_HeaderPart.AddChildObject(ECD); - Storage->EssenceContainerData.push_back(ECD->InstanceUID); - ECD->IndexSID = 129; - ECD->BodySID = 1; - - UUID assetUUID(m_Info.AssetUUID); - UMID SourcePackageUMID, MaterialPackageUMID; - SourcePackageUMID.MakeUMID(0x0f, assetUUID); - MaterialPackageUMID.MakeUMID(0x0f); // unidentified essence - - // - // Material Package - // - m_MaterialPackage = new MaterialPackage(m_Dict); - m_MaterialPackage->Name = "AS-DCP Material Package"; - m_MaterialPackage->PackageUID = MaterialPackageUMID; - m_HeaderPart.AddChildObject(m_MaterialPackage); - Storage->Packages.push_back(m_MaterialPackage->InstanceUID); - - TrackSet<TimecodeComponent> MPTCTrack = - CreateTimecodeTrack<MaterialPackage>(m_HeaderPart, *m_MaterialPackage, - EditRate, TCFrameRate, 0, m_Dict); - m_DurationUpdateList.push_back(&(MPTCTrack.Sequence->Duration)); - m_DurationUpdateList.push_back(&(MPTCTrack.Clip->Duration)); - - TrackSet<DMSegment> MPTrack = - CreateTrackAndSequence<MaterialPackage, DMSegment>(m_HeaderPart, *m_MaterialPackage, - TrackName, EditRate, DataDefinition, - 2, m_Dict); - m_DurationUpdateList.push_back(&(MPTrack.Sequence->Duration)); - - MPTrack.Clip = new DMSegment(m_Dict); - m_HeaderPart.AddChildObject(MPTrack.Clip); - MPTrack.Sequence->StructuralComponents.push_back(MPTrack.Clip->InstanceUID); - MPTrack.Clip->DataDefinition = DataDefinition; - // MPTrack.Clip->SourcePackageID = SourcePackageUMID; - // MPTrack.Clip->SourceTrackID = 2; - m_DurationUpdateList.push_back(&(MPTrack.Clip->Duration)); - - - // - // File (Source) Package - // - m_FilePackage = new SourcePackage(m_Dict); - m_FilePackage->Name = PackageLabel.c_str(); - m_FilePackage->PackageUID = SourcePackageUMID; - ECD->LinkedPackageUID = SourcePackageUMID; - - m_HeaderPart.AddChildObject(m_FilePackage); - Storage->Packages.push_back(m_FilePackage->InstanceUID); - - TrackSet<TimecodeComponent> FPTCTrack = - CreateTimecodeTrack<SourcePackage>(m_HeaderPart, *m_FilePackage, - EditRate, TCFrameRate, - ui64_C(3600) * TCFrameRate, m_Dict); - m_DurationUpdateList.push_back(&(FPTCTrack.Sequence->Duration)); - m_DurationUpdateList.push_back(&(FPTCTrack.Clip->Duration)); - - TrackSet<DMSegment> FPTrack = - CreateTrackAndSequence<SourcePackage, DMSegment>(m_HeaderPart, *m_FilePackage, - TrackName, EditRate, DataDefinition, - 2, m_Dict); - m_DurationUpdateList.push_back(&(FPTrack.Sequence->Duration)); - - FPTrack.Clip = new DMSegment(m_Dict); - m_HeaderPart.AddChildObject(FPTrack.Clip); - FPTrack.Sequence->StructuralComponents.push_back(FPTrack.Clip->InstanceUID); - FPTrack.Clip->DataDefinition = DataDefinition; - FPTrack.Clip->EventComment = "D-Cinema Timed Text"; - - m_DurationUpdateList.push_back(&(FPTrack.Clip->Duration)); - m_EssenceDescriptor->LinkedTrackID = FPTrack.Track->TrackID; -} - -// -void -ASDCP::h__Writer::AddEssenceDescriptor(const UL& WrappingUL) -{ - // - // Essence Descriptor - // - m_EssenceDescriptor->EssenceContainer = WrappingUL; - m_HeaderPart.m_Preface->PrimaryPackage = m_FilePackage->InstanceUID; - - // - // Essence Descriptors - // - assert(m_Dict); - UL GenericContainerUL(m_Dict->ul(MDD_GCMulti)); - m_HeaderPart.EssenceContainers.push_back(GenericContainerUL); - - if ( m_Info.EncryptedEssence ) - { - UL CryptEssenceUL(m_Dict->ul(MDD_EncryptedContainerLabel)); - m_HeaderPart.EssenceContainers.push_back(CryptEssenceUL); - m_HeaderPart.m_Preface->DMSchemes.push_back(UL(m_Dict->ul(MDD_CryptographicFrameworkLabel))); - AddDMScrypt(m_HeaderPart, *m_FilePackage, m_Info, WrappingUL, m_Dict); - } - else - { - m_HeaderPart.EssenceContainers.push_back(WrappingUL); - } - - m_HeaderPart.m_Preface->EssenceContainers = m_HeaderPart.EssenceContainers; - m_HeaderPart.AddChildObject(m_EssenceDescriptor); - - std::list<InterchangeObject*>::iterator sdli = m_EssenceSubDescriptorList.begin(); - for ( ; sdli != m_EssenceSubDescriptorList.end(); sdli++ ) - m_HeaderPart.AddChildObject(*sdli); - - m_FilePackage->Descriptor = m_EssenceDescriptor->InstanceUID; -} - -// Result_t -ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit) +ASDCP::h__ASDCPWriter::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerEditUnit) { assert(m_Dict); Result_t result = RESULT_OK; @@ -452,7 +106,7 @@ ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerE m_BodyPart.BodySID = 1; UL OPAtomUL(m_Dict->ul(MDD_OPAtom)); m_BodyPart.OperationalPattern = OPAtomUL; - m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(1, m_BodyPart.ThisPartition)); // Second RIP Entry + m_RIP.PairArray.push_back(RIP::PartitionPair(1, m_BodyPart.ThisPartition)); // Second RIP Entry UL BodyUL(m_Dict->ul(MDD_ClosedCompleteBodyPartition)); result = m_BodyPart.WriteToFile(m_File, BodyUL); @@ -469,9 +123,13 @@ ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerE m_FooterPart.IndexSID = 129; if ( BytesPerEditUnit == 0 ) - m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset); + { + m_FooterPart.SetIndexParamsVBR(&m_HeaderPart.m_Primer, EditRate, ECoffset); + } else - m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate); + { + m_FooterPart.SetIndexParamsCBR(&m_HeaderPart.m_Primer, BytesPerEditUnit, EditRate); + } } return result; @@ -479,12 +137,24 @@ ASDCP::h__Writer::CreateBodyPart(const MXF::Rational& EditRate, ui32_t BytesPerE // Result_t -ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& WrappingUL, - const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition, - const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit) +ASDCP::h__ASDCPWriter::WriteASDCPHeader(const std::string& PackageLabel, const UL& WrappingUL, + const std::string& TrackName, const UL& EssenceUL, const UL& DataDefinition, + const MXF::Rational& EditRate, ui32_t TCFrameRate, ui32_t BytesPerEditUnit) { InitHeader(); - AddSourceClip(EditRate, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel); + + // First RIP Entry + if ( m_Info.LabelSetType == LS_MXF_SMPTE ) // ERK + { + m_RIP.PairArray.push_back(RIP::PartitionPair(0, 0)); // 3-part, no essence in header + } + else + { + m_RIP.PairArray.push_back(RIP::PartitionPair(1, 0)); // 2-part, essence in header + } + + // timecode rate and essence rate are the same + AddSourceClip(EditRate, EditRate, TCFrameRate, TrackName, EssenceUL, DataDefinition, PackageLabel); AddEssenceDescriptor(WrappingUL); Result_t result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); @@ -495,20 +165,78 @@ ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& Wrap return result; } +// +Result_t +ASDCP::h__ASDCPWriter::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf,const byte_t* EssenceUL, + AESEncContext* Ctx, HMACContext* HMAC) +{ + return Write_EKLV_Packet(m_File, *m_Dict, m_HeaderPart, m_Info, m_CtFrameBuf, m_FramesWritten, + m_StreamOffset, FrameBuf, EssenceUL, Ctx, HMAC); +} + +// standard method of writing the header and footer of a completed MXF file +// +Result_t +ASDCP::h__ASDCPWriter::WriteASDCPFooter() +{ + // update all Duration properties + DurationElementList_t::iterator dli = m_DurationUpdateList.begin(); + + for (; dli != m_DurationUpdateList.end(); ++dli ) + { + **dli = m_FramesWritten; + } + + m_EssenceDescriptor->ContainerDuration = m_FramesWritten; + m_FooterPart.PreviousPartition = m_RIP.PairArray.back().ByteOffset; + + Kumu::fpos_t here = m_File.Tell(); + m_RIP.PairArray.push_back(RIP::PartitionPair(0, here)); // Last RIP Entry + m_HeaderPart.FooterPartition = here; + + assert(m_Dict); + // re-label the header partition, set the footer + UL OPAtomUL(m_Dict->ul(MDD_OPAtom)); + m_HeaderPart.OperationalPattern = OPAtomUL; + m_HeaderPart.m_Preface->OperationalPattern = OPAtomUL; + m_FooterPart.OperationalPattern = OPAtomUL; + + m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers; + m_FooterPart.FooterPartition = here; + m_FooterPart.ThisPartition = here; + + Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten); + + if ( ASDCP_SUCCESS(result) ) + result = m_RIP.WriteToFile(m_File); + + if ( ASDCP_SUCCESS(result) ) + result = m_File.Seek(0); + + if ( ASDCP_SUCCESS(result) ) + result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); + + m_File.Close(); + return result; +} + + +//------------------------------------------------------------------------------------------ +// + // standard method of writing a plaintext or encrypted frame Result_t -ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL, - AESEncContext* Ctx, HMACContext* HMAC, std::string* hash) +ASDCP::Write_EKLV_Packet(Kumu::FileWriter& File, const ASDCP::Dictionary& Dict, const MXF::OP1aHeader& HeaderPart, + const ASDCP::WriterInfo& Info, ASDCP::FrameBuffer& CtFrameBuf, ui32_t& FramesWritten, + ui64_t & StreamOffset, const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL, + AESEncContext* Ctx, HMACContext* HMAC) { Result_t result = RESULT_OK; IntegrityPack IntPack; - m_File.StartHashing(); - byte_t overhead[128]; Kumu::MemIOWriter Overhead(overhead, 128); - assert(m_Dict); if ( FrameBuf.Size() == 0 ) { @@ -516,33 +244,33 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte return RESULT_EMPTY_FB; } - if ( m_Info.EncryptedEssence ) + if ( Info.EncryptedEssence ) { if ( ! Ctx ) return RESULT_CRYPT_CTX; - if ( m_Info.UsesHMAC && ! HMAC ) + if ( Info.UsesHMAC && ! HMAC ) return RESULT_HMAC_CTX; if ( FrameBuf.PlaintextOffset() > FrameBuf.Size() ) return RESULT_LARGE_PTO; // encrypt the essence data (create encrypted source value) - result = EncryptFrameBuffer(FrameBuf, m_CtFrameBuf, Ctx); + result = EncryptFrameBuffer(FrameBuf, CtFrameBuf, Ctx); // create HMAC - if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC ) - result = IntPack.CalcValues(m_CtFrameBuf, m_Info.AssetUUID, m_FramesWritten + 1, HMAC); + if ( ASDCP_SUCCESS(result) && Info.UsesHMAC ) + result = IntPack.CalcValues(CtFrameBuf, Info.AssetUUID, FramesWritten + 1, HMAC); if ( ASDCP_SUCCESS(result) ) { // write UL - Overhead.WriteRaw(m_Dict->ul(MDD_CryptEssence), SMPTE_UL_LENGTH); + Overhead.WriteRaw(Dict.ul(MDD_CryptEssence), SMPTE_UL_LENGTH); // construct encrypted triplet header - ui32_t ETLength = klv_cryptinfo_size + m_CtFrameBuf.Size(); + ui32_t ETLength = klv_cryptinfo_size + CtFrameBuf.Size(); ui32_t BER_length = MXF_BER_LENGTH; - if ( m_Info.UsesHMAC ) + if ( Info.UsesHMAC ) ETLength += klv_intpack_size; else ETLength += (MXF_BER_LENGTH * 3); // for empty intpack @@ -562,39 +290,39 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte { if ( ! ( Overhead.WriteBER(ETLength, BER_length) // write encrypted triplet length && Overhead.WriteBER(UUIDlen, MXF_BER_LENGTH) // write ContextID length - && Overhead.WriteRaw(m_Info.ContextID, UUIDlen) // write ContextID + && Overhead.WriteRaw(Info.ContextID, UUIDlen) // write ContextID && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH) // write PlaintextOffset length && Overhead.WriteUi64BE(FrameBuf.PlaintextOffset()) // write PlaintextOffset && Overhead.WriteBER(SMPTE_UL_LENGTH, MXF_BER_LENGTH) // write essence UL length && Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH) // write the essence UL && Overhead.WriteBER(sizeof(ui64_t), MXF_BER_LENGTH) // write SourceLength length && Overhead.WriteUi64BE(FrameBuf.Size()) // write SourceLength - && Overhead.WriteBER(m_CtFrameBuf.Size(), BER_length) ) ) // write ESV length + && Overhead.WriteBER(CtFrameBuf.Size(), BER_length) ) ) // write ESV length { result = RESULT_KLV_CODING; } } if ( ASDCP_SUCCESS(result) ) - result = m_File.Writev(Overhead.Data(), Overhead.Length()); + result = File.Writev(Overhead.Data(), Overhead.Length()); } if ( ASDCP_SUCCESS(result) ) { - m_StreamOffset += Overhead.Length(); + StreamOffset += Overhead.Length(); // write encrypted source value - result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size()); + result = File.Writev((byte_t*)CtFrameBuf.RoData(), CtFrameBuf.Size()); } if ( ASDCP_SUCCESS(result) ) { - m_StreamOffset += m_CtFrameBuf.Size(); + StreamOffset += CtFrameBuf.Size(); byte_t hmoverhead[512]; Kumu::MemIOWriter HMACOverhead(hmoverhead, 512); // write the HMAC - if ( m_Info.UsesHMAC ) + if ( Info.UsesHMAC ) { HMACOverhead.WriteRaw(IntPack.Data, klv_intpack_size); } @@ -605,8 +333,8 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte } // write HMAC - result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length()); - m_StreamOffset += HMACOverhead.Length(); + result = File.Writev(HMACOverhead.Data(), HMACOverhead.Length()); + StreamOffset += HMACOverhead.Length(); } } else @@ -625,82 +353,18 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte Overhead.WriteBER(FrameBuf.Size(), BER_length); if ( ASDCP_SUCCESS(result) ) - result = m_File.Writev(Overhead.Data(), Overhead.Length()); + result = File.Writev(Overhead.Data(), Overhead.Length()); if ( ASDCP_SUCCESS(result) ) - result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size()); + result = File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size()); if ( ASDCP_SUCCESS(result) ) - m_StreamOffset += Overhead.Length() + FrameBuf.Size(); + StreamOffset += Overhead.Length() + FrameBuf.Size(); } if ( ASDCP_SUCCESS(result) ) - result = m_File.Writev(); - - if (hash) { - *hash = m_File.StopHashing(); - } - - return result; -} - -Result_t -ASDCP::h__Writer::FakeWriteEKLVPacket(int size) -{ - Result_t result = RESULT_OK; - - m_StreamOffset += size; - m_File.Seek(size, Kumu::SP_POS); - - return result; -} - - -// standard method of writing the header and footer of a completed MXF file -// -Result_t -ASDCP::h__Writer::WriteMXFFooter() -{ - // Set top-level file package correctly for OP-Atom - - // m_MPTCSequence->Duration = m_MPTimecode->Duration = m_MPClSequence->Duration = m_MPClip->Duration = - // m_FPTCSequence->Duration = m_FPTimecode->Duration = m_FPClSequence->Duration = m_FPClip->Duration = - - DurationElementList_t::iterator dli = m_DurationUpdateList.begin(); - - for (; dli != m_DurationUpdateList.end(); dli++ ) - **dli = m_FramesWritten; - - m_EssenceDescriptor->ContainerDuration = m_FramesWritten; - m_FooterPart.PreviousPartition = m_HeaderPart.m_RIP.PairArray.back().ByteOffset; - - Kumu::fpos_t here = m_File.Tell(); - m_HeaderPart.m_RIP.PairArray.push_back(RIP::Pair(0, here)); // Last RIP Entry - m_HeaderPart.FooterPartition = here; - - assert(m_Dict); - // re-label the partition - UL OPAtomUL(m_Dict->ul(MDD_OPAtom)); - m_HeaderPart.OperationalPattern = OPAtomUL; - m_HeaderPart.m_Preface->OperationalPattern = m_HeaderPart.OperationalPattern; - - m_FooterPart.OperationalPattern = m_HeaderPart.OperationalPattern; - m_FooterPart.EssenceContainers = m_HeaderPart.EssenceContainers; - m_FooterPart.FooterPartition = here; - m_FooterPart.ThisPartition = here; - - Result_t result = m_FooterPart.WriteToFile(m_File, m_FramesWritten); - - if ( ASDCP_SUCCESS(result) ) - result = m_HeaderPart.m_RIP.WriteToFile(m_File); - - if ( ASDCP_SUCCESS(result) ) - result = m_File.Seek(0); + result = File.Writev(); - if ( ASDCP_SUCCESS(result) ) - result = m_HeaderPart.WriteToFile(m_File, m_HeaderSize); - - m_File.Close(); return result; } diff --git a/asdcplib/src/j2c-test.cpp b/asdcplib/src/j2c-test.cpp index 8f028261..8c26e1cf 100755 --- a/asdcplib/src/j2c-test.cpp +++ b/asdcplib/src/j2c-test.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2010, John Hurst +Copyright (c) 2005-2014, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file j2c-test.cpp - \version $Id: j2c-test.cpp,v 1.6 2010/06/17 20:11:42 jhurst Exp $ + \version $Id: j2c-test.cpp,v 1.8 2014/06/02 22:07:51 jhurst Exp $ \brief JP2K parser test */ @@ -167,6 +167,7 @@ main(int argc, const char** argv) Marker MyMarker; CodestreamParser Parser; std::list<std::string>::iterator i; + bool has_soc = false; Result_t result = FB.Capacity(1024*1024*4); @@ -181,6 +182,28 @@ main(int argc, const char** argv) while ( p < end_p && ASDCP_SUCCESS(GetNextMarker(&p, MyMarker)) ) { + if ( MyMarker.m_Type == MRK_SOC ) + { + if ( has_soc ) + { + fprintf(stderr, "Duplicate SOC detected.\n"); + result = RESULT_FAIL; + break; + } + else + { + has_soc = true; + continue; + } + + if ( ! has_soc ) + { + fprintf(stderr, "Markers detected before SOC.\n"); + result = RESULT_FAIL; + break; + } + } + if ( Options.verbose_flag ) { MyMarker.Dump(stdout); @@ -189,27 +212,50 @@ main(int argc, const char** argv) hexdump(MyMarker.m_Data - 2, MyMarker.m_DataSize + 2, stdout); } - switch ( MyMarker.m_Type ) + if ( MyMarker.m_Type == MRK_SOD ) { - case MRK_SOD: p = end_p; - break; - - case MRK_SIZ: - { - Accessor::SIZ SIZ_(MyMarker); - SIZ_.Dump(stdout); - } - break; - - case MRK_COM: - { - Accessor::COM COM_(MyMarker); - COM_.Dump(stdout); - } - break; + } + else if ( MyMarker.m_Type == MRK_SIZ ) + { + Accessor::SIZ SIZ_(MyMarker); + SIZ_.Dump(stdout); + } + else if ( MyMarker.m_Type == MRK_COD ) + { + Accessor::COD COD_(MyMarker); + COD_.Dump(stdout); + } + else if ( MyMarker.m_Type == MRK_COM ) + { + Accessor::COM COM_(MyMarker); + COM_.Dump(stdout); + } + else if ( MyMarker.m_Type == MRK_QCD ) + { + Accessor::QCD QCD_(MyMarker); + QCD_.Dump(stdout); + } + else + { + fprintf(stderr, "Unprocessed marker - %s\n", GetMarkerString(MyMarker.m_Type)); + } + } + + /* + while ( p < end_p ) + { + if ( *p == 0xff ) + { + fprintf(stdout, "0x%02x 0x%02x 0x%02x\n", *(p+1), *(p+2), *(p+3)); + p += 4; + } + else + { + ++p; } } + */ } } diff --git a/asdcplib/src/klvsplit.cpp b/asdcplib/src/klvsplit.cpp new file mode 100755 index 00000000..2de65288 --- /dev/null +++ b/asdcplib/src/klvsplit.cpp @@ -0,0 +1,342 @@ +/* +Copyright (c) 2005-2013, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file klvwalk.cpp + \version $Id: klvsplit.cpp,v 1.5 2015/10/07 16:41:23 jhurst Exp $ + \brief KLV+MXF test +*/ + +#include "MXF.h" +#include <KM_log.h> + + +using namespace ASDCP; +using Kumu::DefaultLogSink; + + +//------------------------------------------------------------------------------------------ +// +// command line option parser class + +static const char* PROGRAM_NAME = "klvsplit"; // program name for messages +typedef std::list<std::string> FileList_t; + +// Increment the iterator, test for an additional non-option command line argument. +// Causes the caller to return if there are no remaining arguments or if the next +// argument begins with '-'. +#define TEST_EXTRA_ARG(i,c) if ( ++i >= argc || argv[(i)][0] == '-' ) \ + { \ + fprintf(stderr, "Argument not found for option -%c.\n", (c)); \ + return; \ + } + +// +void +banner(FILE* stream = stdout) +{ + fprintf(stream, "\n\ +%s (asdcplib %s)\n\n\ +Copyright (c) 2005-2013 John Hurst\n\ +%s is part of the asdcplib DCP tools package.\n\ +asdcplib may be copied only under the terms of the license found at\n\ +the top of every file in the asdcplib distribution kit.\n\n\ +Specify the -h (help) option for further information about %s\n\n", + PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME, PROGRAM_NAME); +} + +// +void +usage(FILE* stream = stdout) +{ + fprintf(stream, "\ +USAGE: %s [-l <limit>] [-p <prefix>] [-s <suffix>] [-u|-U] [-v] \n\ + (<type-name>|<type-ul>) <mxf-filename>+\n\ +\n\ + %s -d\n\ +\n\ + %s [-h|-help] [-V]\n\ +\n\ + -d - List the valid packet type names\n\ + -h | -help - Show help\n\ + -l <limit> - Stop processing after <limit> matching packets\n\ + -p <prefix> - Use <prefix> to start output filenames (default\n\ + uses the input filename minus any extension\n\ + -s <suffix> - Append <suffix> to output filenames\n\ + -u - Unwrap the packet value (i.e., do not output KL)\n\ + -U - Do not unwrap (default)\n\ + -v - Verbose. Prints informative messages to stderr\n\ + -V - Show version information\n\ +\n\ + NOTES: o There is no option grouping, all options must be distinct arguments.\n\ + o All option arguments must be separated from the option by whitespace.\n\ +\n", PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME); +} + +// +// + class CommandOptions + { + CommandOptions(); + + public: + bool error_flag; // true if the given options are in error or not complete + bool version_flag; // true if the version display option was selected + bool help_flag; // true if the help display option was selected + bool verbose_flag; // true if the informative messages option was selected + bool unwrap_mode; // true if we are to strip the K and L before writing + bool list_mode; + ASDCP::UL target_ul; // a UL value identifying the packets to be extracted + ui64_t extract_limit; // limit extraction to the given number of packets + std::string prefix; // output filename prefix + std::string suffix; // output filename suffix + FileList_t inFileList; // File to operate on + + CommandOptions(int argc, const char** argv, const ASDCP::Dictionary& dict) : + error_flag(true), version_flag(false), help_flag(false), + verbose_flag(false), unwrap_mode(false), list_mode(false), extract_limit(ui64_C(-1)) + { + for ( int i = 1; i < argc; ++i ) + { + + if ( (strcmp( argv[i], "-help") == 0) ) + { + help_flag = true; + continue; + } + + if ( argv[i][0] == '-' && isalpha(argv[i][1]) && argv[i][2] == 0 ) + { + switch ( argv[i][1] ) + { + case 'd': list_mode = true; break; + case 'h': help_flag = true; break; + + case 'l': + TEST_EXTRA_ARG(i, 'l'); + extract_limit = Kumu::xabs(strtoll(argv[i], 0, 10)); + break; + + case 'p': + TEST_EXTRA_ARG(i, 'p'); + prefix = argv[i]; + break; + + case 's': + TEST_EXTRA_ARG(i, 's'); + suffix = argv[i]; + break; + + case 'u': unwrap_mode = true; break; + case 'U': unwrap_mode = false; break; + case 'V': version_flag = true; break; + case 'v': verbose_flag = true; break; + + default: + fprintf(stderr, "Unrecognized option: %s\n", argv[i]); + return; + } + } + else if ( argv[i][0] != '-' ) + { + if ( ! target_ul.HasValue() ) + { + if ( ! target_ul.DecodeHex(argv[i]) ) + { + const ASDCP::MDDEntry *e = dict.FindSymbol(argv[i]); + + if ( e != 0 ) + target_ul = e->ul; + } + + if ( ! target_ul.HasValue() ) + { + fprintf(stderr, "Value is not a UL or valid object name: %s\n", argv[i]); + return; + } + } + else + { + inFileList.push_back(argv[i]); + } + } + else + { + fprintf(stderr, "Unrecognized option: %s\n", argv[i]); + return; + } + } + + if ( help_flag || version_flag ) + return; + + if ( ! list_mode ) + { + if ( inFileList.empty() ) + { + fputs("Input filename(s) required.\n", stderr); + return; + } + + if ( ! target_ul.HasValue() ) + { + fputs("Packet UL not set. Use %s -u <ul> or keyword.\n", stderr); + return; + } + } + + error_flag = false; + } + }; + + +//--------------------------------------------------------------------------------------------------- +// + +int +main(int argc, const char** argv) +{ + const Dictionary *dict = &DefaultCompositeDict(); + CommandOptions Options(argc, argv, *dict); + + if ( Options.version_flag ) + banner(); + + if ( Options.help_flag ) + usage(); + + if ( Options.version_flag || Options.help_flag ) + return 0; + + if ( Options.error_flag ) + { + fprintf(stderr, "There was a problem. Type %s -h for help.\n", PROGRAM_NAME); + return 3; + } + + if ( Options.list_mode ) + { + DefaultLogSink().UnsetFilterFlag(Kumu::LOG_ALLOW_WARN); + char buf[64]; + + MDD_t di = (MDD_t)0; + while ( di < MDD_Max ) + { + const MDDEntry& e = dict->Type(di); + + if ( e.name != 0 && ( e.ul[4] == 1 || e.ul[4] == 2 ) ) + { + if ( Options.verbose_flag ) + { + UL tmp_ul(e.ul); + printf("%s %s\n", tmp_ul.EncodeString(buf, 64), e.name); + } + else + { + printf("%s\n", e.name); + } + } + + di = (MDD_t)(di + 1); + } + + return 0; + } + + Result_t result = RESULT_OK; + FileList_t::iterator fi; + + for ( fi = Options.inFileList.begin(); KM_SUCCESS(result) && fi != Options.inFileList.end(); ++fi ) + { + if ( Options.verbose_flag ) + fprintf(stderr, "Opening file %s\n", (fi->c_str())); + + std::string this_prefix = Options.prefix.empty() ? Kumu::PathSetExtension(*fi, "") + "_" : Options.prefix; + Kumu::FileReader reader; + KLVFilePacket packet; + char filename_buf[1024]; + ui64_t item_counter = 0; + + result = reader.OpenRead(fi->c_str()); + + if ( KM_SUCCESS(result) ) + result = packet.InitFromFile(reader); + + while ( KM_SUCCESS(result) && item_counter < Options.extract_limit ) + { + if ( packet.GetUL() == Options.target_ul + || packet.GetUL().MatchIgnoreStream(Options.target_ul) ) + { + snprintf(filename_buf, 1024, "%s%010qu%s", this_prefix.c_str(), item_counter, Options.suffix.c_str()); + + if ( Options.verbose_flag ) + fprintf(stderr, "%s (%llu bytes)\n", filename_buf, packet.ValueLength()); + + Kumu::FileWriter writer; + writer.OpenWrite(filename_buf); + + if ( KM_SUCCESS(result) ) + { + if ( Options.unwrap_mode ) + { + result = writer.Write(packet.m_Buffer.RoData() + packet.KLLength(), packet.ValueLength()); + } + else + { + result = writer.Write(packet.m_Buffer.RoData(), packet.m_Buffer.Size()); + } + + ++item_counter; + } + } + + if ( KM_SUCCESS(result) ) + result = packet.InitFromFile(reader); + } + + if ( result == RESULT_ENDOFFILE ) + result = RESULT_OK; + } + + if ( KM_FAILURE(result) ) + { + fputs("Program stopped on error.\n", stderr); + + if ( result != RESULT_FAIL ) + { + fputs(result, stderr); + fputc('\n', stderr); + } + + return 1; + } + + return 0; +} + + +// +// end klvwalk.cpp +// diff --git a/asdcplib/src/klvwalk.cpp b/asdcplib/src/klvwalk.cpp index 299cb02a..ef30bc40 100755 --- a/asdcplib/src/klvwalk.cpp +++ b/asdcplib/src/klvwalk.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2009, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file klvwalk.cpp - \version $Id: klvwalk.cpp,v 1.18 2010/11/15 17:04:13 jhurst Exp $ + \version $Id: klvwalk.cpp,v 1.23 2015/10/09 23:41:11 jhurst Exp $ \brief KLV+MXF test */ @@ -65,7 +65,7 @@ banner(FILE* stream = stdout) { fprintf(stream, "\n\ %s (asdcplib %s)\n\n\ -Copyright (c) 2005-2009 John Hurst\n\ +Copyright (c) 2005-2013 John Hurst\n\ %s is part of the asdcplib DCP tools package.\n\ asdcplib may be copied only under the terms of the license found at\n\ the top of every file in the asdcplib distribution kit.\n\n\ @@ -78,12 +78,13 @@ void usage(FILE* stream = stdout) { fprintf(stream, "\ -USAGE: %s [-r] [-v] <input-file> [<input-file2> ...]\n\ +USAGE: %s [-r|-p] [-v] <input-file> [<input-file2> ...]\n\ \n\ %s [-h|-help] [-V]\n\ \n\ -h | -help - Show help\n\ - -r - When KLV data is an MXF OPAtom file, display OPAtom headers\n\ + -r - When KLV data is an MXF OPAtom or OP 1a file, display headers\n\ + -p - Display partition headers by walking the RIP\n\ -v - Verbose. Prints informative messages to stderr\n\ -V - Show version information\n\ \n\ @@ -104,10 +105,12 @@ USAGE: %s [-r] [-v] <input-file> [<input-file2> ...]\n\ bool help_flag; // true if the help display option was selected bool verbose_flag; // true if the informative messages option was selected bool read_mxf_flag; // true if the -r option was selected + bool walk_parts_flag; // true if the -p option was selected FileList_t inFileList; // File to operate on CommandOptions(int argc, const char** argv) : - error_flag(true), version_flag(false), help_flag(false), verbose_flag(false), read_mxf_flag(false) + error_flag(true), version_flag(false), help_flag(false), + verbose_flag(false), read_mxf_flag(false), walk_parts_flag(false) { for ( int i = 1; i < argc; i++ ) { @@ -124,6 +127,7 @@ USAGE: %s [-r] [-v] <input-file> [<input-file2> ...]\n\ { case 'h': help_flag = true; break; case 'r': read_mxf_flag = true; break; + case 'p': walk_parts_flag = true; break; case 'V': version_flag = true; break; case 'v': verbose_flag = true; break; @@ -194,21 +198,47 @@ main(int argc, const char** argv) { Kumu::FileReader Reader; const Dictionary* Dict = &DefaultCompositeDict(); - ASDCP::MXF::OPAtomHeader Header(Dict); + ASDCP::MXF::OP1aHeader Header(Dict); + ASDCP::MXF::RIP RIP(Dict); result = Reader.OpenRead((*fi).c_str()); if ( ASDCP_SUCCESS(result) ) + result = MXF::SeekToRIP(Reader); + + if ( ASDCP_SUCCESS(result) ) + { + result = RIP.InitFromFile(Reader); + ui32_t test_s = RIP.PairArray.size(); + + if ( ASDCP_FAILURE(result) ) + { + DefaultLogSink().Error("File contains no RIP\n"); + result = RESULT_OK; + } + else if ( RIP.PairArray.empty() ) + { + DefaultLogSink().Error("RIP contains no Pairs.\n"); + } + + Reader.Seek(0); + } + else + { + DefaultLogSink().Error("read_mxf SeekToRIP failed: %s\n", result.Label()); + } + + if ( ASDCP_SUCCESS(result) ) result = Header.InitFromFile(Reader); if ( ASDCP_SUCCESS(result) ) Header.Dump(stdout); - if ( ASDCP_SUCCESS(result) && Header.m_RIP.PairArray.size() > 2 ) + if ( ASDCP_SUCCESS(result) && RIP.PairArray.size() > 2 ) { - MXF::Array<MXF::RIP::Pair>::const_iterator pi = Header.m_RIP.PairArray.begin(); + MXF::RIP::const_pair_iterator pi = RIP.PairArray.begin(); - for ( pi++; pi != Header.m_RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ ) + for ( pi++; pi != RIP.PairArray.end() && ASDCP_SUCCESS(result); pi++ ) { result = Reader.Seek((*pi).ByteOffset); @@ -239,7 +269,62 @@ main(int argc, const char** argv) } if ( ASDCP_SUCCESS(result) ) - Header.m_RIP.Dump(stdout); + RIP.Dump(stdout); + } + else if ( Options.walk_parts_flag ) + { + Kumu::FileReader Reader; + const Dictionary* Dict = &DefaultCompositeDict(); + ASDCP::MXF::OP1aHeader Header(Dict); + ASDCP::MXF::RIP RIP(Dict); + + result = Reader.OpenRead((*fi).c_str()); + + if ( ASDCP_SUCCESS(result) ) + result = MXF::SeekToRIP(Reader); + + if ( ASDCP_SUCCESS(result) ) + { + result = RIP.InitFromFile(Reader); + ui32_t test_s = RIP.PairArray.size(); + + if ( ASDCP_FAILURE(result) ) + { + DefaultLogSink().Error("File contains no RIP\n"); + result = RESULT_OK; + } + else if ( RIP.PairArray.empty() ) + { + DefaultLogSink().Error("RIP contains no Pairs.\n"); + } + + Reader.Seek(0); + } + else + { + DefaultLogSink().Error("walk_parts SeekToRIP failed: %s\n", result.Label()); + } + + if ( ASDCP_SUCCESS(result) ) + { + RIP.Dump(); + + MXF::RIP::const_pair_iterator i; + for ( i = RIP.PairArray.begin(); i != RIP.PairArray.end(); ++i ) + { + Reader.Seek(i->ByteOffset); + MXF::Partition plain_part(Dict); + plain_part.InitFromFile(Reader); + + if ( plain_part.ThisPartition != i->ByteOffset ) + { + DefaultLogSink().Error("ThisPartition value error: wanted=%qu, got=%qu\n", + plain_part.ThisPartition, i->ByteOffset); + } + + plain_part.Dump(); + } + } } else // dump klv { diff --git a/asdcplib/src/kmfilegen.cpp b/asdcplib/src/kmfilegen.cpp index fb4360ea..989030d0 100755 --- a/asdcplib/src/kmfilegen.cpp +++ b/asdcplib/src/kmfilegen.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file kmfilegen.cpp - \version $Id: kmfilegen.cpp,v 1.8 2009/03/04 17:52:45 jhurst Exp $ + \version $Id: kmfilegen.cpp,v 1.10 2015/10/16 16:55:33 jhurst Exp $ \brief large file test program */ @@ -123,15 +123,16 @@ public: bool verbose_flag; // true if the verbose option was selected bool version_flag; // true if the version display option was selected bool help_flag; // true if the help display option was selected - const char* filename; // filename to be processed - const char* write_filename; // filename to write with val_write_flag + std::string filename; // filename to be processed + std::string write_filename; // filename to write with val_write_flag ui32_t chunk_count; MajorMode_t mode; // MajorMode selector // CommandOptions(int argc, const char** argv) : - error_flag(true), order(""), verbose_flag(false), version_flag(false), help_flag(false), - filename(""), write_filename(""), chunk_count(0), mode(MMT_VALIDATE) + error_flag(true), order(""), verbose_flag(false), + version_flag(false), help_flag(false), + chunk_count(0), mode(MMT_VALIDATE) { // order = "rand"; @@ -151,7 +152,7 @@ public: case 'c': mode = MMT_CREATE; TEST_EXTRA_ARG(i, 'c'); - chunk_count = atoi(argv[i]); + chunk_count = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'V': version_flag = true; break; @@ -187,7 +188,7 @@ public: { if (argv[i][0] != '-' ) { - if ( filename != "" ) + if ( ! filename.empty() ) { fprintf(stderr, "Extra filename found: %s\n", argv[i]); return; @@ -206,7 +207,7 @@ public: if ( help_flag || version_flag ) return; - if ( strlen ( filename ) == 0 ) + if ( filename.empty() ) { fprintf(stderr, "Filename required.\n"); return; @@ -221,7 +222,7 @@ public: if ( strcmp(order, "") == 0 ) order = "rand"; - if ( strcmp ( filename, write_filename ) == 0 ) + if ( filename == write_filename ) { fprintf(stderr, "Output and input files must be different.\n"); return; @@ -382,7 +383,7 @@ randomize_list(read_list_t* read_list, ui32_t check_total) Result_t ReadValidateWriteLargeFile(CommandOptions& Options) { - assert(Options.write_filename); + assert(!Options.write_filename.empty()); ui32_t check_total = 0; ui32_t write_total = 0; ui32_t read_count = 0; diff --git a/asdcplib/src/kmrandgen.cpp b/asdcplib/src/kmrandgen.cpp index 560fa6ec..36ca7271 100644 --- a/asdcplib/src/kmrandgen.cpp +++ b/asdcplib/src/kmrandgen.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file kmrandgen.cpp - \version $Id: kmrandgen.cpp,v 1.8 2009/03/04 17:52:45 jhurst Exp $ + \version $Id: kmrandgen.cpp,v 1.9 2015/10/07 16:41:23 jhurst Exp $ \brief psuedo-random number generation utility */ @@ -133,7 +133,7 @@ public: case 's': TEST_EXTRA_ARG(i, 's'); - request_size = abs(atoi(argv[i])); + request_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'v': verbose_flag = true; break; diff --git a/asdcplib/src/path-test.cpp b/asdcplib/src/path-test.cpp index b556bddc..bbd0750b 100644 --- a/asdcplib/src/path-test.cpp +++ b/asdcplib/src/path-test.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file path-test.cpp - \version $Id: path-test.cpp,v 1.8 2009/07/10 18:14:01 jhurst Exp $ + \version $Id: path-test.cpp,v 1.10 2015/02/22 20:16:28 jhurst Exp $ \brief test harness for path manglers defined in KM_fileio.h */ @@ -111,8 +111,15 @@ main(int argc, const char** argv) FindInPaths(PathMatchAny(), InList, OutList); PathList_t::iterator pi; - for ( pi = OutList.begin(); pi != OutList.end(); pi++ ) - cerr << *pi << endl; + if ( false ) + { + for ( pi = OutList.begin(); pi != OutList.end(); pi++ ) + cerr << *pi << endl; + } + else + { + cerr << OutList.size() << ( ( OutList.size() == 1 ) ? " file" : " files" ) << endl; + } cerr << "----------------------------------" << endl; OutList.clear(); @@ -134,6 +141,7 @@ main(int argc, const char** argv) FreeSpaceForPath("/", free_space, total_space); cerr << "Free space: " << free_space << endl; cerr << "Total space: " << total_space << endl; + cerr << "Used space: " << ( (total_space - free_space ) / float(total_space) ) << endl; cerr << "OK" << endl; diff --git a/asdcplib/src/phdr-unwrap.cpp b/asdcplib/src/phdr-unwrap.cpp new file mode 100755 index 00000000..aa3dae21 --- /dev/null +++ b/asdcplib/src/phdr-unwrap.cpp @@ -0,0 +1,442 @@ +/* +Copyright (c) 2011-2014, John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file phdr-unwrap.cpp + \version $Id: phdr-unwrap.cpp,v 1.6 2015/10/07 16:41:23 jhurst Exp $ + \brief prototype unwrapping for HDR images in AS-02 + + This program extracts picture (P-HDR picture) from an AS-02 MXF file. +*/ + +#include <KM_fileio.h> +#include <AS_02_PHDR.h> + +using namespace ASDCP; + +const ui32_t FRAME_BUFFER_SIZE = 4 * Kumu::Megabyte; + +//------------------------------------------------------------------------------------------ +// +// command line option parser class + +static const char* PROGRAM_NAME = "as-02-unwrap"; // program name for messages + +// Increment the iterator, test for an additional non-option command line argument. +// Causes the caller to return if there are no remaining arguments or if the next +// argument begins with '-'. +#define TEST_EXTRA_ARG(i,c) \ + if ( ++i >= argc || argv[(i)][0] == '-' ) { \ + fprintf(stderr, "Argument not found for option -%c.\n", (c)); \ + return; \ + } + +// +void +banner(FILE* stream = stdout) +{ + fprintf(stream, "\n\ +%s (asdcplib %s)\n\n\ +Copyright (c) 2011-2015, John Hurst\n\n\ +asdcplib may be copied only under the terms of the license found at\n\ +the top of every file in the asdcplib distribution kit.\n\n\ +Specify the -h (help) option for further information about %s\n\n", + PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME); +} + +// +void +usage(FILE* stream = stdout) +{ + fprintf(stream, "\ +USAGE: %s [-h|-help] [-V]\n\ +\n\ + %s [-b <buffer-size>] [-d <duration>]\n\ + [-f <starting-frame>] [-m] [-R] [-s <size>] [-v] [-W]\n\ + [-w] <input-file> [<file-prefix>]\n\n", + PROGRAM_NAME, PROGRAM_NAME); + + fprintf(stream, "\ +Options:\n\ + -b <buffer-size> - Specify size in bytes of picture frame buffer\n\ + Defaults to 4,194,304 (4MB)\n\ + -d <duration> - Number of frames to process, default all\n\ + -f <start-frame> - Starting frame number, default 0\n\ + -h | -help - Show help\n\ + -k <key-string> - Use key for ciphertext operations\n\ + -m - verify HMAC values when reading\n\ + -s <size> - Number of bytes to dump to output when -v is given\n\ + -V - Show version information\n\ + -v - Verbose, prints informative messages to stderr\n\ + -W - Read input file only, do not write destination file\n\ + -w <width> - Width of numeric element in a series of frame file names\n\ + (default 6)\n\ +\n\ + NOTES: o There is no option grouping, all options must be distinct arguments.\n\ + o All option arguments must be separated from the option by whitespace.\n\n"); +} + +// +class CommandOptions +{ + CommandOptions(); + +public: + bool error_flag; // true if the given options are in error or not complete + bool key_flag; // true if an encryption key was given + bool read_hmac; // true if HMAC values are to be validated + bool verbose_flag; // true if the verbose option was selected + ui32_t fb_dump_size; // number of bytes of frame buffer to dump + bool no_write_flag; // true if no output files are to be written + bool version_flag; // true if the version display option was selected + bool help_flag; // true if the help display option was selected + bool stereo_image_flag; // if true, expect stereoscopic JP2K input (left eye first) + ui32_t number_width; // number of digits in a serialized filename (for JPEG extract) + ui32_t start_frame; // frame number to begin processing + ui32_t duration; // number of frames to be processed + bool duration_flag; // true if duration argument given + ui32_t fb_size; // size of picture frame buffer + const char* file_prefix; // filename pre for files written by the extract mode + byte_t key_value[KeyLen]; // value of given encryption key (when key_flag is true) + byte_t key_id_value[UUIDlen];// value of given key ID (when key_id_flag is true) + const char* input_filename; + std::string prefix_buffer; + + // + CommandOptions(int argc, const char** argv) : + error_flag(true), key_flag(false), read_hmac(false), verbose_flag(false), + fb_dump_size(0), no_write_flag(false), + version_flag(false), help_flag(false), number_width(6), + start_frame(0), duration(0xffffffff), duration_flag(false), + fb_size(FRAME_BUFFER_SIZE), file_prefix(0), + input_filename(0) + { + memset(key_value, 0, KeyLen); + memset(key_id_value, 0, UUIDlen); + + for ( int i = 1; i < argc; ++i ) + { + + if ( (strcmp( argv[i], "-help") == 0) ) + { + help_flag = true; + continue; + } + + if ( argv[i][0] == '-' + && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) + && argv[i][2] == 0 ) + { + switch ( argv[i][1] ) + { + case 'b': + TEST_EXTRA_ARG(i, 'b'); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); + + if ( verbose_flag ) + fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); + + break; + + case 'd': + TEST_EXTRA_ARG(i, 'd'); + duration_flag = true; + duration = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'f': + TEST_EXTRA_ARG(i, 'f'); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'h': help_flag = true; break; + case 'm': read_hmac = true; break; + + case 's': + TEST_EXTRA_ARG(i, 's'); + fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'V': version_flag = true; break; + case 'v': verbose_flag = true; break; + case 'W': no_write_flag = true; break; + + case 'w': + TEST_EXTRA_ARG(i, 'w'); + number_width = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + default: + fprintf(stderr, "Unrecognized option: %s\n", argv[i]); + return; + } + } + else + { + if ( argv[i][0] != '-' ) + { + if ( input_filename == 0 ) + { + input_filename = argv[i]; + } + else if ( file_prefix == 0 ) + { + file_prefix = argv[i]; + } + } + else + { + fprintf(stderr, "Unrecognized argument: %s\n", argv[i]); + return; + } + } + } + + if ( help_flag || version_flag ) + return; + + if ( input_filename == 0 ) + { + fputs("At least one filename argument is required.\n", stderr); + return; + } + + if ( file_prefix == 0 ) + { + prefix_buffer = Kumu::PathSetExtension(input_filename, "") + "_"; + file_prefix = prefix_buffer.c_str(); + } + + error_flag = false; + } +}; + + +//------------------------------------------------------------------------------------------ +// JPEG 2000 essence + + +// Read one or more plaintext JPEG 2000 codestreams from a plaintext P-HDR file +// Read one or more plaintext JPEG 2000 codestreams from a ciphertext P-HDR file +// Read one or more ciphertext JPEG 2000 codestreams from a ciphertext P-HDR file +// +Result_t +read_JP2K_file(CommandOptions& Options) +{ + AESDecContext* Context = 0; + HMACContext* HMAC = 0; + AS_02::PHDR::MXFReader Reader; + AS_02::PHDR::FrameBuffer FrameBuffer(Options.fb_size); + ui32_t frame_count = 0; + + std::string PHDR_master_metadata; // todo: write to a file? + + Result_t result = Reader.OpenRead(Options.input_filename, PHDR_master_metadata); + fprintf(stderr, "PHDR_master_metadata size=%zd\n", PHDR_master_metadata.size()); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + { + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + } + + ASDCP::MXF::RGBAEssenceDescriptor *rgba_descriptor = 0; + ASDCP::MXF::CDCIEssenceDescriptor *cdci_descriptor = 0; + + result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_RGBAEssenceDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&rgba_descriptor)); + + if ( KM_SUCCESS(result) ) + { + assert(rgba_descriptor); + frame_count = rgba_descriptor->ContainerDuration; + + if ( Options.verbose_flag ) + { + rgba_descriptor->Dump(); + } + } + else + { + result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_CDCIEssenceDescriptor), + reinterpret_cast<MXF::InterchangeObject**>(&cdci_descriptor)); + + if ( KM_SUCCESS(result) ) + { + assert(cdci_descriptor); + frame_count = cdci_descriptor->ContainerDuration; + + if ( Options.verbose_flag ) + { + cdci_descriptor->Dump(); + } + } + else + { + fprintf(stderr, "File does not contain an essence descriptor.\n"); + frame_count = Reader.AS02IndexReader().GetDuration(); + } + } + + if ( frame_count == 0 ) + { + frame_count = Reader.AS02IndexReader().GetDuration(); + } + + if ( frame_count == 0 ) + { + fprintf(stderr, "Unable to determine file duration.\n"); + return RESULT_FAIL; + } + } + + if ( ASDCP_SUCCESS(result) && Options.key_flag ) + { + Context = new AESDecContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) && Options.read_hmac ) + { + WriterInfo Info; + Reader.FillWriterInfo(Info); + + if ( Info.UsesHMAC ) + { + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + else + { + fputs("File does not contain HMAC values, ignoring -m option.\n", stderr); + } + } + } + + ui32_t last_frame = Options.start_frame + ( Options.duration ? Options.duration : frame_count); + if ( last_frame > frame_count ) + last_frame = frame_count; + + char name_format[64]; + snprintf(name_format, 64, "%%s%%0%du.j2c", Options.number_width); + + for ( ui32_t i = Options.start_frame; ASDCP_SUCCESS(result) && i < last_frame; i++ ) + { + result = Reader.ReadFrame(i, FrameBuffer, Context, HMAC); + + char filename[1024]; + snprintf(filename, 1024, name_format, Options.file_prefix, i); + + if ( ASDCP_SUCCESS(result) && Options.verbose_flag ) + { + printf("Frame %d, %d bytes", i, FrameBuffer.Size()); + + if ( ! Options.no_write_flag ) + { + printf(" -> %s", filename); + } + + printf("\n"); + } + + if ( ASDCP_SUCCESS(result) && ( ! Options.no_write_flag ) ) + { + Kumu::FileWriter OutFile; + ui32_t write_count; + result = OutFile.OpenWrite(filename); + + if ( ASDCP_SUCCESS(result) ) + result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count); + + if ( ASDCP_SUCCESS(result) && Options.verbose_flag ) + { + FrameBuffer.Dump(stderr, Options.fb_dump_size); + } + } + } + + return result; +} + +// +int +main(int argc, const char** argv) +{ + char str_buf[64]; + CommandOptions Options(argc, argv); + + if ( Options.version_flag ) + banner(); + + if ( Options.help_flag ) + usage(); + + if ( Options.version_flag || Options.help_flag ) + return 0; + + if ( Options.error_flag ) + { + fprintf(stderr, "There was a problem. Type %s -h for help.\n", PROGRAM_NAME); + return 3; + } + + EssenceType_t EssenceType; + Result_t result = ASDCP::EssenceType(Options.input_filename, EssenceType); + + if ( ASDCP_SUCCESS(result) ) + { + switch ( EssenceType ) + { + case ESS_AS02_JPEG_2000: + result = read_JP2K_file(Options); + break; + + default: + fprintf(stderr, "%s: Unknown file type, not P-HDR essence.\n", Options.input_filename); + return 5; + } + } + + if ( ASDCP_FAILURE(result) ) + { + fputs("Program stopped on error.\n", stderr); + + if ( result != RESULT_FAIL ) + { + fputs(result, stderr); + fputc('\n', stderr); + } + + return 1; + } + + return 0; +} + + +// +// end phdr-unwrap.cpp +// diff --git a/asdcplib/src/phdr-wrap.cpp b/asdcplib/src/phdr-wrap.cpp new file mode 100755 index 00000000..c77e10e7 --- /dev/null +++ b/asdcplib/src/phdr-wrap.cpp @@ -0,0 +1,674 @@ +/* +Copyright (c) 2011-2014, John Hurst + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file phdr-wrap.cpp + \version $Id: phdr-wrap.cpp,v 1.6 2015/10/16 16:55:33 jhurst Exp $ + \brief prototype wrapping for HDR images in AS-02 + + This program wraps IMF essence (P-HDR picture) in to an AS-02 MXF file. +*/ + +#include <KM_fileio.h> +#include <KM_prng.h> +#include <AS_02_PHDR.h> + +using namespace ASDCP; + +const ui32_t FRAME_BUFFER_SIZE = 4 * Kumu::Megabyte; +const ASDCP::Dictionary *g_dict = 0; + + +const char* +RationalToString(const ASDCP::Rational& r, char* buf, const ui32_t& len) +{ + snprintf(buf, len, "%d/%d", r.Numerator, r.Denominator); + return buf; +} + + + +//------------------------------------------------------------------------------------------ +// +// command line option parser class + +static const char* PROGRAM_NAME = "as-02-wrap"; // program name for messages + +// local program identification info written to file headers +class MyInfo : public WriterInfo +{ +public: + MyInfo() + { + static byte_t default_ProductUUID_Data[UUIDlen] = + { 0xef, 0xe4, 0x59, 0xab, 0xbe, 0x0f, 0x4c, 0x7d, + 0xb3, 0xa2, 0xb8, 0x96, 0x79, 0xe2, 0x3e, 0x8e }; + + memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen); + CompanyName = "WidgetCo"; + ProductName = "phdr-wrap"; + ProductVersion = ASDCP::Version(); + } +} s_MyInfo; + + + +// Increment the iterator, test for an additional non-option command line argument. +// Causes the caller to return if there are no remaining arguments or if the next +// argument begins with '-'. +#define TEST_EXTRA_ARG(i,c) \ + if ( ++i >= argc || argv[(i)][0] == '-' ) { \ + fprintf(stderr, "Argument not found for option -%c.\n", (c)); \ + return; \ + } + +// +void +banner(FILE* stream = stdout) +{ + fprintf(stream, "\n\ +%s (asdcplib %s)\n\n\ +Copyright (c) 2011-2015, John Hurst\n\n\ +asdcplib may be copied only under the terms of the license found at\n\ +the top of every file in the asdcplib distribution kit.\n\n\ +Specify the -h (help) option for further information about %s\n\n", + PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME); +} + +// +void +usage(FILE* stream = stdout) +{ + fprintf(stream, "\ +USAGE: %s [-h|-help] [-V]\n\ +\n\ + %s [-a <uuid>] [-A <w>/<h>] [-b <buffer-size>] [-C <UL>] [-d <duration>]\n\ + [-D <depth>] [-e|-E] [-i] [-j <key-id-string>] [-k <key-string>]\n\ + [-M] [-m <expr>] [-p <ul>] [-r <n>/<d>] [-R] [-s <seconds>]\n\ + [-t <min>] [-T <max>] [-u] [-v] [-W] [-x <int>] [-X <int>] [-Y]\n\ + [-z|-Z] <input-file>+ <output-file>\n\n", + PROGRAM_NAME, PROGRAM_NAME); + + fprintf(stream, "\ +Options:\n\ + -h | -help - Show help\n\ + -V - Show version information\n\ + -a <uuid> - Specify the Asset ID of the file\n\ + -A <w>/<h> - Set aspect ratio for image (default 4/3)\n\ + -b <buffer-size> - Specify size in bytes of picture frame buffer\n\ + Defaults to 4,194,304 (4MB)\n\ + -C <ul> - Set ChannelAssignment UL value\n\ + -d <duration> - Number of frames to process, default all\n\ + -D <depth> - Component depth for YCbCr images (default: 10)\n\ + -e - Encrypt JP2K headers (default)\n\ + -E - Do not encrypt JP2K headers\n\ + -F (0|1) - Set field dominance for interlaced image (default: 0)\n\ + -i - Indicates input essence is interlaced fields (forces -Y)\n\ + -j <key-id-str> - Write key ID instead of creating a random value\n\ + -k <key-string> - Use key for ciphertext operations\n\ + -M - Do not create HMAC values when writing\n\ + -m <filename> - Filename of master metadata instance (the contents of\n\ + which will be placed in the MXF wrapper)\n\ + -p <ul> - Set broadcast profile\n\ + -r <n>/<d> - Edit Rate of the output file. 24/1 is the default\n\ + -R - Indicates RGB image essence (default)\n\ + -s <seconds> - Duration of a frame-wrapped partition (default 60)\n\ + -t <min> - Set RGB component minimum code value (default: 0)\n\ + -T <max> - Set RGB component maximum code value (default: 1023)\n\ + -u - Print UL catalog to stderr\n\ + -v - Verbose, prints informative messages to stderr\n\ + -W - Read input file only, do not write source file\n\ + -x <int> - Horizontal subsampling degree (default: 2)\n\ + -X <int> - Vertical subsampling degree (default: 2)\n\ + -Y - Indicates YCbCr image essence (default: RGB)\n\ + -z - Fail if j2c inputs have unequal parameters (default)\n\ + -Z - Ignore unequal parameters in j2c inputs\n\ +\n\ + NOTES: o There is no option grouping, all options must be distinct arguments.\n\ + o All option arguments must be separated from the option by whitespace.\n\n"); +} + +// +// +class CommandOptions +{ + CommandOptions(); + +public: + bool error_flag; // true if the given options are in error or not complete + bool key_flag; // true if an encryption key was given + bool asset_id_flag; // true if an asset ID was given + bool encrypt_header_flag; // true if j2c headers are to be encrypted + bool write_hmac; // true if HMAC values are to be generated and written + bool verbose_flag; // true if the verbose option was selected + ui32_t fb_dump_size; // number of bytes of frame buffer to dump + bool no_write_flag; // true if no output files are to be written + bool version_flag; // true if the version display option was selected + bool help_flag; // true if the help display option was selected + ui32_t duration; // number of frames to be processed + bool j2c_pedantic; // passed to JP2K::SequenceParser::OpenRead + bool use_cdci_descriptor; // + Rational edit_rate; // edit rate of JP2K sequence + ui32_t fb_size; // size of picture frame buffer + byte_t key_value[KeyLen]; // value of given encryption key (when key_flag is true) + bool key_id_flag; // true if a key ID was given + byte_t key_id_value[UUIDlen];// value of given key ID (when key_id_flag is true) + byte_t asset_id_value[UUIDlen];// value of asset ID (when asset_id_flag is true) + std::string out_file; // + bool show_ul_values_flag; /// if true, dump the UL table before going tp work. + Kumu::PathList_t filenames; // list of filenames to be processed + + UL picture_coding; + ui32_t rgba_MaxRef; + ui32_t rgba_MinRef; + + ui32_t horizontal_subsampling; + ui32_t vertical_subsampling; + ui32_t component_depth; + ui8_t frame_layout; + ASDCP::Rational aspect_ratio; + ui8_t field_dominance; + ui32_t mxf_header_size; + + //new attributes for AS-02 support + AS_02::IndexStrategy_t index_strategy; //Shim parameter index_strategy_frame/clip + ui32_t partition_space; //Shim parameter partition_spacing + + std::string PHDR_master_metadata; // + + // + CommandOptions(int argc, const char** argv) : + error_flag(true), key_flag(false), key_id_flag(false), asset_id_flag(false), + encrypt_header_flag(true), write_hmac(true), verbose_flag(false), fb_dump_size(0), + no_write_flag(false), version_flag(false), help_flag(false), + duration(0xffffffff), j2c_pedantic(true), use_cdci_descriptor(false), edit_rate(24,1), fb_size(FRAME_BUFFER_SIZE), + show_ul_values_flag(false), index_strategy(AS_02::IS_FOLLOW), partition_space(60), + rgba_MaxRef(1023), rgba_MinRef(0), + horizontal_subsampling(2), vertical_subsampling(2), component_depth(10), + frame_layout(0), aspect_ratio(ASDCP::Rational(4,3)), field_dominance(0), + mxf_header_size(16384) + { + memset(key_value, 0, KeyLen); + memset(key_id_value, 0, UUIDlen); + + for ( int i = 1; i < argc; i++ ) + { + + if ( (strcmp( argv[i], "-help") == 0) ) + { + help_flag = true; + continue; + } + + if ( argv[i][0] == '-' + && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) + && argv[i][2] == 0 ) + { + switch ( argv[i][1] ) + { + case 'A': + TEST_EXTRA_ARG(i, 'A'); + if ( ! DecodeRational(argv[i], aspect_ratio) ) + { + fprintf(stderr, "Error decoding aspect ratio value: %s\n", argv[i]); + return; + } + break; + + case 'a': + asset_id_flag = true; + TEST_EXTRA_ARG(i, 'a'); + { + ui32_t length; + Kumu::hex2bin(argv[i], asset_id_value, UUIDlen, &length); + + if ( length != UUIDlen ) + { + fprintf(stderr, "Unexpected asset ID length: %u, expecting %u characters.\n", length, UUIDlen); + return; + } + } + break; + + case 'b': + TEST_EXTRA_ARG(i, 'b'); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); + + if ( verbose_flag ) + fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); + + break; + + case 'D': + TEST_EXTRA_ARG(i, 'D'); + component_depth = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'd': + TEST_EXTRA_ARG(i, 'd'); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'E': encrypt_header_flag = false; break; + case 'e': encrypt_header_flag = true; break; + + case 'F': + TEST_EXTRA_ARG(i, 'F'); + field_dominance = Kumu::xabs(strtol(argv[i], 0, 10)); + if ( field_dominance > 1 ) + { + fprintf(stderr, "Field dominance value must be \"0\" or \"1\"\n"); + return; + } + break; + + case 'h': help_flag = true; break; + + case 'i': + frame_layout = 1; + use_cdci_descriptor = true; + break; + + case 'j': + key_id_flag = true; + TEST_EXTRA_ARG(i, 'j'); + { + ui32_t length; + Kumu::hex2bin(argv[i], key_id_value, UUIDlen, &length); + + if ( length != UUIDlen ) + { + fprintf(stderr, "Unexpected key ID length: %u, expecting %u characters.\n", length, UUIDlen); + return; + } + } + break; + + case 'k': key_flag = true; + TEST_EXTRA_ARG(i, 'k'); + { + ui32_t length; + Kumu::hex2bin(argv[i], key_value, KeyLen, &length); + + if ( length != KeyLen ) + { + fprintf(stderr, "Unexpected key length: %u, expecting %u characters.\n", length, KeyLen); + return; + } + } + break; + + case 'M': write_hmac = false; break; + + case 'm': + TEST_EXTRA_ARG(i, 'm'); + if ( KM_FAILURE(Kumu::ReadFileIntoString(argv[i], PHDR_master_metadata) ) ) + { + fprintf(stderr, "Unable to read metadata file %s\n", argv[i]); + return; + } + break; + + case 'p': + TEST_EXTRA_ARG(i, 'p'); + if ( ! picture_coding.DecodeHex(argv[i]) ) + { + fprintf(stderr, "Error decoding PictureEssenceCoding UL value: %s\n", argv[i]); + return; + } + break; + + case 'r': + TEST_EXTRA_ARG(i, 'r'); + if ( ! DecodeRational(argv[i], edit_rate) ) + { + fprintf(stderr, "Error decoding edit rate value: %s\n", argv[i]); + return; + } + + break; + + case 'R': + use_cdci_descriptor = false; + break; + + case 's': + TEST_EXTRA_ARG(i, 's'); + partition_space = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 't': + TEST_EXTRA_ARG(i, 't'); + rgba_MinRef = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'T': + TEST_EXTRA_ARG(i, 'T'); + rgba_MaxRef = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'u': show_ul_values_flag = true; break; + case 'V': version_flag = true; break; + case 'v': verbose_flag = true; break; + case 'W': no_write_flag = true; break; + + case 'x': + TEST_EXTRA_ARG(i, 'x'); + horizontal_subsampling = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'X': + TEST_EXTRA_ARG(i, 'X'); + vertical_subsampling = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case 'Y': + use_cdci_descriptor = true; + break; + + case 'Z': j2c_pedantic = false; break; + case 'z': j2c_pedantic = true; break; + + default: + fprintf(stderr, "Unrecognized option: %s\n", argv[i]); + return; + } + } + else + { + + if ( argv[i][0] != '-' ) + { + filenames.push_back(argv[i]); + } + else + { + fprintf(stderr, "Unrecognized argument: %s\n", argv[i]); + return; + } + } + } + + if ( help_flag || version_flag ) + return; + + if ( filenames.size() < 2 ) + { + fputs("Option requires at least two filename arguments: <input-file> <output-file>\n", stderr); + return; + } + + out_file = filenames.back(); + filenames.pop_back(); + + if ( ! picture_coding.HasValue() ) + { + picture_coding = UL(g_dict->ul(MDD_JP2KEssenceCompression_BroadcastProfile_1)); + } + + error_flag = false; + } +}; + + +//------------------------------------------------------------------------------------------ +// JPEG 2000 essence + +namespace ASDCP { + Result_t JP2K_PDesc_to_MD(const ASDCP::JP2K::PictureDescriptor& PDesc, + const ASDCP::Dictionary& dict, + ASDCP::MXF::GenericPictureEssenceDescriptor& GenericPictureEssenceDescriptor, + ASDCP::MXF::JPEG2000PictureSubDescriptor& EssenceSubDescriptor); +} + +// Write one or more plaintext JPEG 2000 codestreams to a plaintext AS-02 file +// Write one or more plaintext JPEG 2000 codestreams to a ciphertext AS-02 file +// +Result_t +write_JP2K_file(CommandOptions& Options) +{ + AS_02::PHDR::MXFWriter Writer; + AS_02::PHDR::FrameBuffer FrameBuffer(Options.fb_size); + AS_02::PHDR::SequenceParser Parser; + + AESEncContext* Context = 0; + HMACContext* HMAC = 0; + byte_t IV_buf[CBC_BLOCK_SIZE]; + Kumu::FortunaRNG RNG; + + ASDCP::MXF::FileDescriptor *essence_descriptor = 0; + ASDCP::MXF::InterchangeObject_list_t essence_sub_descriptors; + + // set up essence parser + Result_t result = Parser.OpenRead(Options.filenames.front().c_str(), Options.j2c_pedantic); + + // set up MXF writer + if ( ASDCP_SUCCESS(result) ) + { + ASDCP::JP2K::PictureDescriptor PDesc; + Parser.FillPictureDescriptor(PDesc); + PDesc.EditRate = Options.edit_rate; + + if ( Options.verbose_flag ) + { + fprintf(stderr, "JPEG 2000 P-HDR pictures\n"); + fputs("PictureDescriptor:\n", stderr); + fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size); + JP2K::PictureDescriptorDump(PDesc); + } + + if ( Options.use_cdci_descriptor ) + { + ASDCP::MXF::CDCIEssenceDescriptor* tmp_dscr = new ASDCP::MXF::CDCIEssenceDescriptor(g_dict); + essence_sub_descriptors.push_back(new ASDCP::MXF::JPEG2000PictureSubDescriptor(g_dict)); + + result = ASDCP::JP2K_PDesc_to_MD(PDesc, *g_dict, + *static_cast<ASDCP::MXF::GenericPictureEssenceDescriptor*>(tmp_dscr), + *static_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back())); + + if ( ASDCP_SUCCESS(result) ) + { + tmp_dscr->PictureEssenceCoding = Options.picture_coding; + tmp_dscr->HorizontalSubsampling = Options.horizontal_subsampling; + tmp_dscr->VerticalSubsampling = Options.vertical_subsampling; + tmp_dscr->ComponentDepth = Options.component_depth; + tmp_dscr->FrameLayout = Options.frame_layout; + tmp_dscr->AspectRatio = Options.aspect_ratio; + tmp_dscr->FieldDominance = Options.field_dominance; + essence_descriptor = static_cast<ASDCP::MXF::FileDescriptor*>(tmp_dscr); + } + } + else + { // use RGB + ASDCP::MXF::RGBAEssenceDescriptor* tmp_dscr = new ASDCP::MXF::RGBAEssenceDescriptor(g_dict); + essence_sub_descriptors.push_back(new ASDCP::MXF::JPEG2000PictureSubDescriptor(g_dict)); + + result = ASDCP::JP2K_PDesc_to_MD(PDesc, *g_dict, + *static_cast<ASDCP::MXF::GenericPictureEssenceDescriptor*>(tmp_dscr), + *static_cast<ASDCP::MXF::JPEG2000PictureSubDescriptor*>(essence_sub_descriptors.back())); + + if ( ASDCP_SUCCESS(result) ) + { + tmp_dscr->PictureEssenceCoding = UL(g_dict->ul(MDD_JP2KEssenceCompression_BroadcastProfile_1)); + tmp_dscr->ComponentMaxRef = Options.rgba_MaxRef; + tmp_dscr->ComponentMinRef = Options.rgba_MinRef; + essence_descriptor = static_cast<ASDCP::MXF::FileDescriptor*>(tmp_dscr); + } + } + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here + Info.LabelSetType = LS_MXF_SMPTE; + + if ( Options.asset_id_flag ) + memcpy(Info.AssetUUID, Options.asset_id_value, UUIDlen); + else + Kumu::GenRandomUUID(Info.AssetUUID); + + // configure encryption + if( Options.key_flag ) + { + Kumu::GenRandomUUID(Info.ContextID); + Info.EncryptedEssence = true; + + if ( Options.key_id_flag ) + memcpy(Info.CryptographicKeyID, Options.key_id_value, UUIDlen); + else + RNG.FillRandom(Info.CryptographicKeyID, UUIDlen); + + Context = new AESEncContext; + result = Context->InitKey(Options.key_value); + + if ( ASDCP_SUCCESS(result) ) + result = Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + + if ( ASDCP_SUCCESS(result) && Options.write_hmac ) + { + Info.UsesHMAC = true; + HMAC = new HMACContext; + result = HMAC->InitKey(Options.key_value, Info.LabelSetType); + } + } + + if ( ASDCP_SUCCESS(result) ) + { + result = Writer.OpenWrite(Options.out_file, Info, essence_descriptor, essence_sub_descriptors, + Options.edit_rate, Options.mxf_header_size, Options.index_strategy, Options.partition_space); + } + } + + if ( ASDCP_SUCCESS(result) ) + { + ui32_t duration = 0; + result = Parser.Reset(); + + while ( ASDCP_SUCCESS(result) && duration++ < Options.duration ) + { + result = Parser.ReadFrame(FrameBuffer); + + if ( ASDCP_SUCCESS(result) ) + { + if ( Options.verbose_flag ) + FrameBuffer.Dump(stderr, Options.fb_dump_size); + + if ( Options.encrypt_header_flag ) + FrameBuffer.PlaintextOffset(0); + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + { + result = Writer.WriteFrame(FrameBuffer, Context, HMAC); + + // The Writer class will forward the last block of ciphertext + // to the encryption context for use as the IV for the next + // frame. If you want to use non-sequitur IV values, un-comment + // the following line of code. + // if ( ASDCP_SUCCESS(result) && Options.key_flag ) + // Context->SetIVec(RNG.FillRandom(IV_buf, CBC_BLOCK_SIZE)); + } + } + + if ( result == RESULT_ENDOFFILE ) + result = RESULT_OK; + } + + if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag ) + result = Writer.Finalize(Options.PHDR_master_metadata); + + return result; +} + +// +int +main(int argc, const char** argv) +{ + Result_t result = RESULT_OK; + char str_buf[64]; + g_dict = &ASDCP::DefaultSMPTEDict(); + assert(g_dict); + + CommandOptions Options(argc, argv); + + if ( Options.version_flag ) + banner(); + + if ( Options.help_flag ) + usage(); + + if ( Options.show_ul_values_flag ) + { + g_dict->Dump(stdout); + } + + if ( Options.version_flag || Options.help_flag || Options.show_ul_values_flag ) + return 0; + + if ( Options.error_flag ) + { + fprintf(stderr, "There was a problem. Type %s -h for help.\n", PROGRAM_NAME); + return 3; + } + + EssenceType_t EssenceType; + result = ASDCP::RawEssenceType(Options.filenames.front().c_str(), EssenceType); + + if ( ASDCP_SUCCESS(result) ) + { + switch ( EssenceType ) + { + case ESS_JPEG_2000: + result = write_JP2K_file(Options); + break; + + default: + fprintf(stderr, "%s: Unknown file type, not P-HDR-compatible essence.\n", + Options.filenames.front().c_str()); + return 5; + } + } + + if ( ASDCP_FAILURE(result) ) + { + fputs("Program stopped on error.\n", stderr); + + if ( result != RESULT_FAIL ) + { + fputs(result, stderr); + fputc('\n', stderr); + } + + return 1; + } + + return 0; +} + + +// +// end phdr-wrap.cpp +// diff --git a/asdcplib/src/pinkwave.cpp b/asdcplib/src/pinkwave.cpp new file mode 100644 index 00000000..327a2621 --- /dev/null +++ b/asdcplib/src/pinkwave.cpp @@ -0,0 +1,269 @@ +/* +Copyright (c) 2015, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file wavsplit.cpp + \version $Id: pinkwave.cpp,v 1.1 2015/10/07 16:41:23 jhurst Exp $ + \brief Black WAV file generator +*/ + +#include "Wav.h" +#include "ST2095_PinkNoise.h" +#include <assert.h> + +using namespace ASDCP; + +//------------------------------------------------------------------------------------------ +// +// command line option parser class + +static const char* PROGRAM_NAME = "pinkwave"; // program name for messages + +// Macros used to test command option data state. + +// Increment the iterator, test for an additional non-option command line argument. +// Causes the caller to return if there are no remaining arguments or if the next +// argument begins with '-'. +#define TEST_EXTRA_ARG(i,c) if ( ++i >= argc || argv[(i)][0] == '-' ) \ + { \ + fprintf(stderr, "Argument not found for option %c.\n", (c)); \ + return; \ + } +// +void +banner(FILE* stream = stderr) +{ + fprintf(stream, "\n\ +%s (asdcplib %s)\n\n\ +Copyright (c) 2015 John Hurst\n\n\ +%s is part of asdcplib.\n\ +asdcplib may be copied only under the terms of the license found at\n\ +the top of every file in the asdcplib distribution kit.\n\n\ +Specify the -h (help) option for further information about %s\n\n", + PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME, PROGRAM_NAME); +} + +// +void +usage(FILE* stream = stderr) +{ + fprintf(stream, "\ +USAGE: %s [-v|-h[-d]] <filename>\n\ +\n\ + -V - Show version\n\ + -h - Show help\n\ + -d <duration> - Number of edit units to process, default 1440\n\ + -9 - Make a 96 kHz file (default 48 kHz)\n\ +\n\ +Other Options:\n\ + -v - Verbose, show extra detail during run\n\ +\n\ + NOTES: o There is no option grouping, all options must be distinct arguments.\n\ + o All option arguments must be separated from the option by whitespace.\n\ +\n", PROGRAM_NAME); +} + +// +// +class CommandOptions +{ + CommandOptions(); + +public: + bool error_flag; // true if the given options are in error or not complete + bool verbose_flag; // true if the verbose option was selected + bool version_flag; // true if the version display option was selected + bool help_flag; // true if the help display option was selected + bool s96_flag; // true if the samples should be at 96 kHz + ui32_t duration; // number of frames to be processed + float HpFc; // Highpass filter cutoff frequency in Hz + float LpFc; // Lowpass filter cutoff frequency in Hz + const char* filename; // + + CommandOptions(int argc, const char** argv) : + error_flag(true), verbose_flag(false), version_flag(false), help_flag(false), s96_flag(false), + duration(1440), HpFc(PinkFilterHighPassConstant), LpFc(PinkFilterLowPassConstant), filename(0) + { + for ( int i = 1; i < argc; i++ ) + { + if ( argv[i][0] == '-' && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) && argv[i][2] == 0 ) + { + switch ( argv[i][1] ) + { + case 'V': version_flag = true; break; + case 'h': help_flag = true; break; + case 'v': verbose_flag = true; break; + + case 'd': + TEST_EXTRA_ARG(i, 'd'); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case '9': + s96_flag = true; + break; + + default: + fprintf(stderr, "Unrecognized option: %c\n", argv[i][1]); + return; + } + } + else + { + if ( filename ) + { + fprintf(stderr, "Unexpected extra filename.\n"); + return; + } + + filename = argv[i]; + } + } + + if ( filename == 0 ) + { + fputs("Output filename required.\n", stderr); + return; + } + + error_flag = false; + } +}; + +// +// +Result_t +make_pink_wav_file(CommandOptions& Options) +{ + PCM::FrameBuffer FrameBuffer; + PCM::AudioDescriptor ADesc; + + ADesc.EditRate = Rational(24,1); + ADesc.AudioSamplingRate = Options.s96_flag ? ASDCP::SampleRate_96k : ASDCP::SampleRate_48k; + ADesc.Locked = 0; + ADesc.ChannelCount = 1; + ADesc.QuantizationBits = 24; + ADesc.BlockAlign = 3; + ADesc.AvgBps = ADesc.BlockAlign * ADesc.AudioSamplingRate.Quotient(); + ADesc.LinkedTrackID = 1; + ADesc.ContainerDuration = Options.duration; + + // set up LCG and pink filter + PinkFilter pink_filter(Options.s96_flag ? ASDCP::SampleRate_96k.Numerator : ASDCP::SampleRate_48k.Numerator, + Options.HpFc, Options.LpFc); + + LinearCongruentialGenerator lcg(Options.s96_flag ? ASDCP::SampleRate_96k.Numerator : ASDCP::SampleRate_48k.Numerator); + + + FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc)); + FrameBuffer.Size(FrameBuffer.Capacity()); + ui32_t samples_per_frame = PCM::CalcSamplesPerFrame(ADesc); + + if ( Options.verbose_flag ) + { + fprintf(stderr, "%s kHz PCM Audio, 24 fps (%u spf)\n", + (Options.s96_flag?"96":"48"), samples_per_frame); + fputs("AudioDescriptor:\n", stderr); + PCM::AudioDescriptorDump(ADesc); + } + + // set up output file + Kumu::FileWriter OutFile; + Result_t result = OutFile.OpenWrite(Options.filename); + + if ( ASDCP_SUCCESS(result) ) + { + RF64::SimpleRF64Header WavHeader(ADesc); + result = WavHeader.WriteToFile(OutFile); + } + + if ( ASDCP_SUCCESS(result) ) + { + ui32_t write_count = 0; + ui32_t duration = 0; + byte_t scaled_pink[sizeof(ui32_t)]; + + while ( ASDCP_SUCCESS(result) && (duration++ < Options.duration) ) + { + // fill the frame buffer with a frame of pink noise + byte_t *p = FrameBuffer.Data(); + + for ( int i = 0; i < samples_per_frame; ++i ) + { + float pink_sample = pink_filter.GetNextSample(lcg.GetNextSample()); + ScalePackSample(pink_sample, p, ADesc.BlockAlign); + p += ADesc.BlockAlign; + } + + result = OutFile.Write(FrameBuffer.RoData(), FrameBuffer.Size(), &write_count); + } + } + + return result; +} + + +// +int +main(int argc, const char** argv) +{ + Result_t result = RESULT_OK; + CommandOptions Options(argc, argv); + + if ( Options.help_flag ) + { + usage(); + return 0; + } + + if ( Options.error_flag ) + return 3; + + if ( Options.version_flag ) + banner(); + + else + result = make_pink_wav_file(Options); + + if ( result != RESULT_OK ) + { + fputs("Program stopped on error.\n", stderr); + + if ( result != RESULT_FAIL ) + { + fputs(result, stderr); + fputc('\n', stderr); + } + + return 1; + } + + return 0; +} + + +// +// end pinkwave.cpp +// diff --git a/asdcplib/src/wavesplit.cpp b/asdcplib/src/wavesplit.cpp index 87851982..a39f6869 100755 --- a/asdcplib/src/wavesplit.cpp +++ b/asdcplib/src/wavesplit.cpp @@ -25,7 +25,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*! \file wavesplit.cpp - \version $Id: wavesplit.cpp,v 1.11 2010/02/16 18:40:57 jhurst Exp $ + \version $Id: wavesplit.cpp,v 1.13 2015/10/07 16:41:23 jhurst Exp $ \brief WAV file splitter */ @@ -138,12 +138,12 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); - duration = atoi(argv[i]); // TODO: test for negative value, should use strtol() + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = atoi(argv[i]); // TODO: test for negative value, should use strtol() + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'h': help_flag = true; break; diff --git a/asdcplib/src/wscript b/asdcplib/src/wscript deleted file mode 100644 index 7aa1788b..00000000 --- a/asdcplib/src/wscript +++ /dev/null @@ -1,89 +0,0 @@ -# -# Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -def configure(conf): - conf.env.append_value('CXXFLAGS', '-D_FILE_OFFSET_BITS=64') - conf.env.append_value('CXXFLAGS', '-DPACKAGE_VERSION="1.9.45-dvdomatic"') - if conf.options.target_windows: - conf.env.append_value('CXXFLAGS', '-DASDCP_PLATFORM="win32"') - conf.env.append_value('CXXFLAGS', '-DKM_WIN32') - else: - conf.env.append_value('CXXFLAGS', '-DASDCP_PLATFORM="linux"') - -def build(bld): - if bld.env.STATIC: - obj = bld(features = 'cxx cxxstlib') - else: - obj = bld(features = 'cxx cxxshlib') - - obj.name = 'libkumu-libdcp%s' % bld.env.API_VERSION - obj.target = 'kumu-libdcp%s' % bld.env.API_VERSION - obj.uselib = 'OPENSSL BOOST_FILESYSTEM' - obj.includes = ['.'] - obj.export_includes = ['.'] - obj.source = """ - KM_fileio.cpp - KM_log.cpp - KM_util.cpp - KM_xml.cpp - KM_tai.cpp - KM_prng.cpp - """ - - if bld.env.STATIC: - obj = bld(features = 'cxx cxxstlib') - else: - obj = bld(features = 'cxx cxxshlib') - - obj.name = 'libasdcp-libdcp%s' % bld.env.API_VERSION - obj.target = 'asdcp-libdcp%s' % bld.env.API_VERSION - obj.uselib = 'OPENSSL' - obj.use = 'libkumu-libdcp%s' % bld.env.API_VERSION - obj.includes = ['.'] - obj.export_includes = ['.'] - obj.source = """ - MPEG2_Parser.cpp - MPEG.cpp - JP2K_Codestream_Parser.cpp - JP2K_Sequence_Parser.cpp - JP2K.cpp - PCM_Parser.cpp - Wav.cpp - TimedText_Parser.cpp - KLV.cpp - Dict.cpp - MXFTypes.cpp - MXF.cpp - Index.cpp - Metadata.cpp - AS_DCP.cpp - AS_DCP_MXF.cpp - AS_DCP_AES.cpp - h__Reader.cpp - h__Writer.cpp - AS_DCP_MPEG2.cpp - AS_DCP_JP2K.cpp - AS_DCP_PCM.cpp - AS_DCP_TimedText.cpp - PCMParserList.cpp - MDD.cpp - """ - - if bld.env.STATIC: - bld.install_files('${PREFIX}/lib', 'libkumu-libdcp%s.a' % bld.env.API_VERSION) - bld.install_files('${PREFIX}/lib', 'libasdcp-libdcp%s.a' % bld.env.API_VERSION) diff --git a/asdcplib/win32/Makefile.in b/asdcplib/win32/Makefile.in index 9f1d64da..4cee193b 100644 --- a/asdcplib/win32/Makefile.in +++ b/asdcplib/win32/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -41,6 +40,51 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -60,7 +104,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = win32 -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/Makefile.wmk ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_expat.m4 \ @@ -75,11 +119,30 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = Makefile.mak CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -258,11 +321,11 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -tags: TAGS -TAGS: +tags TAGS: + +ctags CTAGS: -ctags: CTAGS -CTAGS: +cscope cscopelist: distdir: $(DISTFILES) @@ -398,15 +461,16 @@ uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/asdcplib/win32/Makefile.mak b/asdcplib/win32/Makefile.mak index 96be7f93..e2f538e0 100644 --- a/asdcplib/win32/Makefile.mak +++ b/asdcplib/win32/Makefile.mak @@ -1,4 +1,4 @@ -# $Id: Makefile.wmk,v 1.4 2012/03/07 18:16:52 mikey Exp $
+# $Id: Makefile.wmk,v 1.6 2013/06/26 19:34:18 msheby Exp $
# Copyright (c) 2007-2012 John Hurst. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -33,11 +33,11 @@ OBJDIR = . !ifdef ENABLE_RANDOM_UUID
CXXFLAGS1 = /nologo /W3 /GR /EHsc /DWIN32 /DKM_WIN32 /D_CONSOLE /I. /I$(SRCDIR) /DASDCP_PLATFORM=\"win32\" \
- /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DPACKAGE_VERSION=\"1.9.45\" \
+ /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DPACKAGE_VERSION=\"2.5.11\" \
/I"$(WITH_OPENSSL)"\inc32 /DCONFIG_RANDOM_UUID=1
!else
CXXFLAGS1 = /nologo /W3 /GR /EHsc /DWIN32 /DKM_WIN32 /D_CONSOLE /I. /I$(SRCDIR) /DASDCP_PLATFORM=\"win32\" \
- /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DPACKAGE_VERSION=\"1.9.45\" \
+ /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_WARNINGS /DPACKAGE_VERSION=\"2.5.11\" \
/I"$(WITH_OPENSSL)"\inc32
!endif
LIB_EXE = lib.exe
@@ -83,14 +83,26 @@ ASDCP_OBJS = MPEG2_Parser.obj MPEG.obj JP2K_Codestream_Parser.obj \ Index.obj Metadata.obj AS_DCP.obj AS_DCP_MXF.obj AS_DCP_AES.obj \
h__Reader.obj h__Writer.obj AS_DCP_MPEG2.obj AS_DCP_JP2K.obj \
AS_DCP_PCM.obj AS_DCP_TimedText.obj PCMParserList.obj \
- MDD.obj
+ MDD.obj AS_DCP_ATMOS.obj AS_DCP_DCData.obj \
+ DCData_ByteStream_Parser.obj DCData_Sequence_Parser.obj \
+ AtmosSyncChannel_Generator.obj AtmosSyncChannel_Mixer.obj \
+ PCMDataProviders.obj SyncEncoder.obj CRC16.obj \
+ UUIDInformation.obj
+AS02_OBJS = h__02_Reader.obj h__02_Writer.obj AS_02_JP2K.obj \
+ AS_02_PCM.obj
{$(SRCDIR)\}.cpp{}.obj:
$(CXX) $(CXXFLAGS) -Fd$(OBJDIR)\ /c $<
+{$(SRCDIR)\}.c{}.obj:
+ $(CXX) $(CXXFLAGS) -Fd$(OBJDIR)\ /c $<
+
all: kmfilegen.exe kmrandgen.exe kmuuidgen.exe asdcp-test.exe \
asdcp-wrap.exe asdcp-unwrap.exe asdcp-info.exe \
blackwave.exe klvwalk.exe j2c-test.exe wavesplit.exe
+!IFDEF USE_AS_02
+ as-02-wrap.exe as-02-unwrap.exe \
+!ENDIF
clean:
erase *.exe *.lib *.obj *.ilk *.pdb *.idb
@@ -111,6 +123,11 @@ libkumu.lib : $(KUMU_OBJS) libasdcp.lib: libkumu.lib $(ASDCP_OBJS)
$(LIB_EXE) $(LIBFLAGS) /OUT:libasdcp.lib $**
+!IFDEF USE_AS_02
+libas02.lib: libasdcp.lib libkumu.lib $(AS02_OBJS)
+ $(LIB_EXE) $(LIBFLAGS) /OUT:libas02.lib $**
+!ENDIF
+
blackwave.exe: libasdcp.lib blackwave.obj
$(LINK) $(LINKFLAGS) /OUT:blackwave.exe $** Advapi32.lib
@@ -147,5 +164,13 @@ asdcp-util.exe: libasdcp.lib asdcp-util.obj j2c-test.exe: libasdcp.lib j2c-test.obj
$(LINK) $(LINKFLAGS) /OUT:j2c-test.exe $** Advapi32.lib
+!IFDEF USE_AS_02
+as-02-wrap.exe: libas02.lib as-02-wrap.obj
+ $(LINK) $(LINKFLAGS) /OUT:as-02-wrap.exe $** Advapi32.lib
+
+as-02-unwrap.exe: libas02.lib as-02-unwrap.obj
+ $(LINK) $(LINKFLAGS) /OUT:as-02-unwrap.exe $** Advapi32.lib
+!ENDIF
+
# END Makefile
diff --git a/asdcplib/win32/Makefile.wmk b/asdcplib/win32/Makefile.wmk index 0539026e..95788b73 100755 --- a/asdcplib/win32/Makefile.wmk +++ b/asdcplib/win32/Makefile.wmk @@ -1,4 +1,4 @@ -# $Id: Makefile.wmk,v 1.4 2012/03/07 18:16:52 mikey Exp $
+# $Id: Makefile.wmk,v 1.6 2013/06/26 19:34:18 msheby Exp $
# Copyright (c) 2007-2012 John Hurst. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -83,14 +83,26 @@ ASDCP_OBJS = MPEG2_Parser.obj MPEG.obj JP2K_Codestream_Parser.obj \ Index.obj Metadata.obj AS_DCP.obj AS_DCP_MXF.obj AS_DCP_AES.obj \
h__Reader.obj h__Writer.obj AS_DCP_MPEG2.obj AS_DCP_JP2K.obj \
AS_DCP_PCM.obj AS_DCP_TimedText.obj PCMParserList.obj \
- MDD.obj
+ MDD.obj AS_DCP_ATMOS.obj AS_DCP_DCData.obj \
+ DCData_ByteStream_Parser.obj DCData_Sequence_Parser.obj \
+ AtmosSyncChannel_Generator.obj AtmosSyncChannel_Mixer.obj \
+ PCMDataProviders.obj SyncEncoder.obj CRC16.obj \
+ UUIDInformation.obj
+AS02_OBJS = h__02_Reader.obj h__02_Writer.obj AS_02_JP2K.obj \
+ AS_02_PCM.obj
{$(SRCDIR)\}.cpp{}.obj:
$(CXX) $(CXXFLAGS) -Fd$(OBJDIR)\ /c $<
+{$(SRCDIR)\}.c{}.obj:
+ $(CXX) $(CXXFLAGS) -Fd$(OBJDIR)\ /c $<
+
all: kmfilegen.exe kmrandgen.exe kmuuidgen.exe asdcp-test.exe \
asdcp-wrap.exe asdcp-unwrap.exe asdcp-info.exe \
blackwave.exe klvwalk.exe j2c-test.exe wavesplit.exe
+!IFDEF USE_AS_02
+ as-02-wrap.exe as-02-unwrap.exe \
+!ENDIF
clean:
erase *.exe *.lib *.obj *.ilk *.pdb *.idb
@@ -111,6 +123,11 @@ libkumu.lib : $(KUMU_OBJS) libasdcp.lib: libkumu.lib $(ASDCP_OBJS)
$(LIB_EXE) $(LIBFLAGS) /OUT:libasdcp.lib $**
+!IFDEF USE_AS_02
+libas02.lib: libasdcp.lib libkumu.lib $(AS02_OBJS)
+ $(LIB_EXE) $(LIBFLAGS) /OUT:libas02.lib $**
+!ENDIF
+
blackwave.exe: libasdcp.lib blackwave.obj
$(LINK) $(LINKFLAGS) /OUT:blackwave.exe $** Advapi32.lib
@@ -147,5 +164,13 @@ asdcp-util.exe: libasdcp.lib asdcp-util.obj j2c-test.exe: libasdcp.lib j2c-test.obj
$(LINK) $(LINKFLAGS) /OUT:j2c-test.exe $** Advapi32.lib
+!IFDEF USE_AS_02
+as-02-wrap.exe: libas02.lib as-02-wrap.obj
+ $(LINK) $(LINKFLAGS) /OUT:as-02-wrap.exe $** Advapi32.lib
+
+as-02-unwrap.exe: libas02.lib as-02-unwrap.obj
+ $(LINK) $(LINKFLAGS) /OUT:as-02-unwrap.exe $** Advapi32.lib
+!ENDIF
+
# END Makefile
diff --git a/asdcplib/win32/README.txt b/asdcplib/win32/README.txt index ca3d9fd8..76e76c79 100755 --- a/asdcplib/win32/README.txt +++ b/asdcplib/win32/README.txt @@ -49,6 +49,10 @@ Without XML parsing: C:\Program Files\asdcplib\win32>nmake WITH_OPENSSL="c:\Program Files\openssl-0.9.8j"
/f Makefile.mak
+Without XML parsing but with the AS-02 library and executables:
+C:\Program Files\asdcplib\win32>nmake WITH_OPENSSL="c:\Program Files\openssl-0.9.8j"
+ USE_AS_02=1 /f Makefile.mak
+
Want a 64-bit build? Change the following line in Makefile.mak:
LINKFLAGS1 = /NOLOGO /SUBSYSTEM:console /MACHINE:I386 /LIBPATH:. /DEBUG
to
diff --git a/asdcplib/wscript b/asdcplib/wscript deleted file mode 100644 index 7f39d386..00000000 --- a/asdcplib/wscript +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -def configure(conf): - conf.recurse('src') - -def build(bld): - bld.recurse('src') |
