+2013-07-08 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.108 released.
+
+2013-07-08 Carl Hetherington <cth@carlh.net>
+
+ * Add option to pad sound so that silent channels
+ can be added.
+
+2013-07-08 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.107 released.
+
+2013-07-06 Carl Hetherington <cth@carlh.net>
+
+ * Various tweaks to layout, trying to make
+ it more consistent and better looking
+ (especially on OS X).
+
+2013-07-04 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.107beta1 released.
+
+2013-07-04 Carl Hetherington <cth@carlh.net>
+
+ * Try to initialise the number of threads to the number
+ of cores in the machine (#170).
+
+ * Pass _FILE_OFFSET_BITS=64 so that fopen() doesn't refuse
+ to open files of >2GB; fixes failure to re-start jobs
+ where the MXF has grown larger than 2GB on 32-bit machines.
+
+2013-07-01 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.106 released.
+
+2013-07-01 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.106beta1 released.
+
+2013-06-28 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.105 released.
+
+2013-06-28 Carl Hetherington <cth@carlh.net>
+
+ * Work around GTK bugs related to the directory
+ picker (in the new film dialogue). There is a
+ buggy GTK included in Ubuntu 13.04 (and Mint 15).
+
+2013-06-27 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.104 released.
+
+2013-06-27 Carl Hetherington <cth@carlh.net>
+
+ * Hopefully fix problems with end-trim not working.
+
+2013-06-24 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.103 released.
+
+2013-06-20 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.102 released.
+
+2013-06-19 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.101 released.
+
+2013-06-19 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.101beta5 released.
+
+2013-06-19 Carl Hetherington <cth@carlh.net>
+
+ * Fix hang when there are problems decoding
+ audio.
+
+2013-06-19 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.101beta4 released.
+
+2013-06-19 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.101beta3 released.
+
+2013-06-19 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.101beta2 released.
+
+2013-06-19 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.101beta1 released.
+
+2013-06-14 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.100 released.
+
2013-06-13 Carl Hetherington <cth@carlh.net>
* Fix ffmpeg's pixel format 13.
if target.platform == 'windows':
return ()
else:
- return (('openjpeg-cdist', None),
- ('libcxml', None),
- ('ffmpeg-cdist', '7a23ec9c771184ab563cfe24ad9b427f38368961'),
- ('libdcp', None))
+ # XXX: should be some versions in here
+ return (('ffmpeg-cdist', 'e797834288eaf05a2f406524ae04aaa0f114cb08'),
+ ('libdcp', 'v0.54'))
-def build(env, target):
- cmd = './waf configure --prefix=%s' % env.work_dir_cscript()
+def build(target):
+ cmd = './waf configure --prefix=%s' % target.work_dir_cscript()
if target.platform == 'windows':
cmd += ' --target-windows'
elif target.platform == 'linux':
cmd += ' --static'
- env.command(cmd)
+ target.command(cmd)
- env.command('./waf')
+ target.command('./waf')
if target.platform == 'linux' or target.platform == 'osx':
- env.command('./waf install')
+ target.command('./waf install')
-def package(env, target, version):
+def package(target, version):
if target.platform == 'windows':
shutil.copyfile('build/platform/windows/installer.%s.nsi' % target.bits, 'build/platform/windows/installer2.%s.nsi' % target.bits)
- env.command('sed -i "s~%%resources%%~%s/platform/windows~g" build/platform/windows/installer2.%s.nsi' % (os.getcwd(), target.bits))
- env.command('sed -i "s~%%deps%%~%s~g" build/platform/windows/installer2.%s.nsi' % (env.windows_prefix, target.bits))
- env.command('sed -i "s~%%binaries%%~%s/build~g" build/platform/windows/installer2.%s.nsi' % (os.getcwd(), target.bits))
- env.command('sed -i "s~%%bits%%~32~g" build/platform/windows/installer2.%s.nsi' % target.bits)
- env.command('makensis build/platform/windows/installer2.%s.nsi' % target.bits)
+ target.command('sed -i "s~%%resources%%~%s/platform/windows~g" build/platform/windows/installer2.%s.nsi' % (os.getcwd(), target.bits))
+ target.command('sed -i "s~%%deps%%~%s~g" build/platform/windows/installer2.%s.nsi' % (target.windows_prefix, target.bits))
+ target.command('sed -i "s~%%binaries%%~%s/build~g" build/platform/windows/installer2.%s.nsi' % (os.getcwd(), target.bits))
+ target.command('sed -i "s~%%bits%%~32~g" build/platform/windows/installer2.%s.nsi' % target.bits)
+ target.command('makensis build/platform/windows/installer2.%s.nsi' % target.bits)
return os.path.abspath(glob.glob('build/platform/windows/*%s*.exe' % target.bits)[0])
elif target.platform == 'linux':
if target.bits == 32:
cpu = 'amd64'
shutil.copyfile('platform/linux/control-%s-%d' % (target.version, target.bits), 'debian/control')
- env.command('./waf dist')
+ target.command('./waf dist')
f = open('debian/files', 'w')
print >>f,'dcpomatic_%s-1_%s.deb video extra' % (version, cpu)
shutil.rmtree('build/deb', ignore_errors=True)
os.makedirs('build/deb')
os.chdir('build/deb')
shutil.move('../../dcpomatic-%s.tar.bz2' % version, 'dcpomatic_%s.orig.tar.bz2' % version)
- env.command('tar xjf dcpomatic_%s.orig.tar.bz2' % version)
+ target.command('tar xjf dcpomatic_%s.orig.tar.bz2' % version)
os.chdir('dcpomatic-%s' % version)
- env.command('dch -b -v %s-1 "New upstream release."' % version)
- env.set('CDIST_LINKFLAGS', env.get('LINKFLAGS'))
- env.set('CDIST_CXXFLAGS', env.get('CXXFLAGS'))
- env.set('CDIST_PKG_CONFIG_PATH', env.get('PKG_CONFIG_PATH'))
- env.command('dpkg-buildpackage')
+ target.command('dch -b -v %s-1 "New upstream release."' % version)
+ target.set('CDIST_LINKFLAGS', target.get('LINKFLAGS'))
+ target.set('CDIST_CXXFLAGS', target.get('CXXFLAGS'))
+ target.set('CDIST_PKG_CONFIG_PATH', target.get('PKG_CONFIG_PATH'))
+ target.command('dpkg-buildpackage')
debs = []
for p in glob.glob('../*.deb'):
return debs
elif target.platform == 'osx':
- env.command('bash platform/osx/make_dmg.sh')
+ target.command('bash platform/osx/make_dmg.sh')
return os.path.abspath(glob.glob('build/platform/osx/DVD-o-matic*.dmg')[0])
-def make_pot(env):
- env.command('./waf pot')
+def make_pot(target):
+ target.command('./waf pot')
return [os.path.abspath('build/src/lib/libdcpomatic.pot'),
os.path.abspath('build/src/wx/libdcpomatic-wx.pot'),
os.path.abspath('build/src/tools/dcpomatic.pot')]
-def make_manual(env):
+def make_manual(target):
os.chdir('doc/manual')
- env.command('make')
+ target.command('make')
return [os.path.abspath('pdf'), os.path.abspath('html')]
Section: video
Priority: extra
Maintainer: Carl Hetherington <cth@carlh.net>
-Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7)
+Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7), libgtk2.0-dev (>= 2.24.10)
Standards-Version: 3.9.3
Homepage: http://carlh.net/software/dcpomatic
Package: dcpomatic
Architecture: i386
-Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libsndfile1 (>= 1.0.25), libmagick++4 (>= 8:6.6.9.7), libxml++2.6-2 (>= 2.34.1)
+Depends: libc6 (>= 2.15), libssh-4 (>= 0.5.2), libboost-filesystem1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libsndfile1 (>= 1.0.25), libmagick++4 (>= 8:6.6.9.7), libxml++2.6-2 (>= 2.34.1), libgtk2.0-0 (>= 2.24.10)
Description: Generator of Digital Cinema Packages (DCPs)
DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio
files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
Section: video
Priority: extra
Maintainer: Carl Hetherington <cth@carlh.net>
-Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7)
+Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7), libgtk2.0-dev (>= 2.4.10)
Standards-Version: 3.9.3
Homepage: http://carlh.net/software/dcpomatic
Section: video
Priority: extra
Maintainer: Carl Hetherington <cth@carlh.net>
-Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7)
+Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7), libgtk2.0-dev (>= 2.24.13)
Standards-Version: 3.9.3
Homepage: http://carlh.net/software/dcpomatic
Package: dcpomatic
Architecture: i386
-Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2)
+Depends: libc6 (>= 2.15), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2), libgtk2.0-0 (>= 2.24.13)
Description: Generator of Digital Cinema Packages (DCPs)
DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio
files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
Section: video
Priority: extra
Maintainer: Carl Hetherington <cth@carlh.net>
-Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libwxgtk2.8-dev (>= 2.8.12.1), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7)
+Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7), libgtk2.0-dev (>= 2.24.13)
Standards-Version: 3.9.3
Homepage: http://carlh.net/software/dcpomatic
Package: dcpomatic
Architecture: amd64
-Depends: libc6 (>= 2.15), libwxgtk2.8-0 (>= 2.8.12.1), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2)
+Depends: libc6 (>= 2.15), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2), libgtk2.0-0 (>= 2.24.13)
Description: Generator of Digital Cinema Packages (DCPs)
DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio
files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
--- /dev/null
+Source: dvdomatic
+Section: video
+Priority: extra
+Maintainer: Carl Hetherington <cth@carlh.net>
+Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7), libgtk2.0-dev (>= 2.24.13)
+Standards-Version: 3.9.3
+Homepage: http://carlh.net/software/dvdomatic
+
+Package: dvdomatic
+Architecture: i386
+Depends: libc6 (>= 2.15), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2), libgtk2.0-0 (>= 2.24.13)
+Description: Generator of Digital Cinema Packages (DCPs)
+ DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio
+ files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
+ digital projectors.
+
+Package: dvdomatic-dbg
+Architecture: i386
+Section: debug
+Priority: extra
+Depends: ${dvdomatic:Depends}, ${misc:Depends}
+Description: debugging symbols for dvdomatic
+ This package contains the debugging symbols for dvdomatic.
--- /dev/null
+Source: dvdomatic
+Section: video
+Priority: extra
+Maintainer: Carl Hetherington <cth@carlh.net>
+Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.3), g++ (>= 4:4.6.3), pkg-config (>= 0.26), libssh-dev (>= 0.5.2), libboost-filesystem-dev (>= 1.46.0), libboost-thread-dev (>= 1.46.0), libsndfile1-dev (>= 1.0.25), libmagick++-dev (>= 8:6.6.9.7), libgtk2.0-dev (>= 2.24.13)
+Standards-Version: 3.9.3
+Homepage: http://carlh.net/software/dvdomatic
+
+Package: dvdomatic
+Architecture: amd64
+Depends: libc6 (>= 2.15), libssh-4 (>= 0.5.2), libboost-filesystem1.49.0 (>= 1.49.0), libboost-thread1.49.0 (>= 1.49.0), libsndfile1 (>= 1.0.25), libmagick++5 (>= 8:6.7.7.10), libxml++2.6-2 (>= 2.34.2), libgtk2.0-0 (>= 2.24.13)
+Description: Generator of Digital Cinema Packages (DCPs)
+ DVD-o-matic generates Digital Cinema Packages (DCPs) from video and audio
+ files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
+ digital projectors.
+
+Package: dvdomatic-dbg
+Architecture: amd64
+Section: debug
+Priority: extra
+Depends: ${dvdomatic:Depends}, ${misc:Depends}
+Description: debugging symbols for dvdomatic
+ This package contains the debugging symbols for dvdomatic.
+
# DMG size in megabytes
DMG_SIZE=256
WORK=build/platform/osx
-ENV=/Users/carl/Environments/osx/10.8
-DEPS=/Users/carl/cdist
+ENV=/Users/carl/Environments/osx
+ROOT=/Users/carl/cdist
appdir="DVD-o-matic.app"
approot=$appdir/Contents
mkdir -p $WORK/$libs
mkdir -p $WORK/$resources
-cp build/src/tools/dcpomatic $WORK/$macos/
-cp build/src/lib/libdcpomatic.dylib $WORK/$libs/
-cp build/src/wx/libdcpomatic-wx.dylib $WORK/$libs/
-cp $DEPS/lib/libdcp.dylib $WORK/$libs/
-cp $DEPS/lib/libasdcp-libdcp.dylib $WORK/$libs/
-cp $DEPS/lib/libkumu-libdcp.dylib $WORK/$libs/
-cp $DEPS/lib/libopenjpeg*.dylib $WORK/$libs/
-cp $DEPS/lib/libavformat*.dylib $WORK/$libs/
-cp $DEPS/lib/libavfilter*.dylib $WORK/$libs/
-cp $DEPS/lib/libavutil*.dylib $WORK/$libs/
-cp $DEPS/lib/libavcodec*.dylib $WORK/$libs/
-cp $DEPS/lib/libswscale*.dylib $WORK/$libs/
-cp $DEPS/lib/libpostproc*.dylib $WORK/$libs/
-cp $DEPS/lib/libswresample*.dylib $WORK/$libs/
-cp $ENV/lib/libboost_system.dylib $WORK/$libs/
-cp $ENV/lib/libboost_filesystem.dylib $WORK/$libs/
-cp $ENV/lib/libboost_thread.dylib $WORK/$libs/
-cp $ENV/lib/libboost_date_time.dylib $WORK/$libs/
-cp $ENV/lib/libssl*.dylib $WORK/$libs/
-cp $ENV/lib/libcrypto*.dylib $WORK/$libs/
-cp $ENV/lib/libxml++-2.6*.dylib $WORK/$libs/
-cp $ENV/lib/libxml2*.dylib $WORK/$libs/
-cp $ENV/lib/libglibmm-2.4*.dylib $WORK/$libs/
-cp $ENV/lib/libgobject*.dylib $WORK/$libs/
-cp $ENV/lib/libgthread*.dylib $WORK/$libs/
-cp $ENV/lib/libgmodule*.dylib $WORK/$libs/
-cp $ENV/lib/libsigc*.dylib $WORK/$libs/
-cp $ENV/lib/libglib-2*.dylib $WORK/$libs/
-cp $ENV/lib/libintl*.dylib $WORK/$libs/
-cp $ENV/lib/libsndfile*.dylib $WORK/$libs/
-cp $ENV/lib/libMagick++*.dylib $WORK/$libs/
-cp $ENV/lib/libMagickCore*.dylib $WORK/$libs/
-cp $ENV/lib/libMagickWand*.dylib $WORK/$libs/
-cp $ENV/lib/libssh*.dylib $WORK/$libs/
-cp $ENV/lib/libwx*.dylib $WORK/$libs/
-cp $ENV/lib/libfontconfig*.dylib $WORK/$libs/
-cp $ENV/lib/libfreetype*.dylib $WORK/$libs/
-cp $ENV/lib/libexpat*.dylib $WORK/$libs/
+function universal_copy {
+ echo $2
+ for f in $1/32/$2; do
+ if [ -h $f ]; then
+ ln -s $(readlink $f) $3/`basename $f`
+ else
+ g=`echo $f | sed -e "s/\/32\//\/64\//g"`
+ mkdir -p $3
+ lipo -create $f $g -output $3/`basename $f`
+ fi
+ done
+}
+
+universal_copy $ROOT src/dvdomatic/build/src/tools/dvdomatic $WORK/$macos
+universal_copy $ROOT src/dvdomatic/build/src/lib/libdvdomatic.dylib $WORK/$libs
+universal_copy $ROOT src/dvdomatic/build/src/wx/libdvdomatic-wx.dylib $WORK/$libs
+universal_copy $ROOT lib/libcxml.dylib $WORK/$libs
+universal_copy $ROOT lib/libdcp.dylib $WORK/$libs
+universal_copy $ROOT lib/libasdcp-libdcp.dylib $WORK/$libs
+universal_copy $ROOT lib/libkumu-libdcp.dylib $WORK/$libs
+universal_copy $ROOT lib/libopenjpeg*.dylib $WORK/$libs
+universal_copy $ROOT lib/libavformat*.dylib $WORK/$libs
+universal_copy $ROOT lib/libavfilter*.dylib $WORK/$libs
+universal_copy $ROOT lib/libavutil*.dylib $WORK/$libs
+universal_copy $ROOT lib/libavcodec*.dylib $WORK/$libs
+universal_copy $ROOT lib/libswscale*.dylib $WORK/$libs
+universal_copy $ROOT lib/libpostproc*.dylib $WORK/$libs
+universal_copy $ROOT lib/libswresample*.dylib $WORK/$libs
+universal_copy $ENV lib/libboost_system.dylib $WORK/$libs
+universal_copy $ENV lib/libboost_filesystem.dylib $WORK/$libs
+universal_copy $ENV lib/libboost_thread.dylib $WORK/$libs
+universal_copy $ENV lib/libboost_date_time.dylib $WORK/$libs
+universal_copy $ENV lib/libxml++-2.6*.dylib $WORK/$libs
+universal_copy $ENV lib/libxml2*.dylib $WORK/$libs
+universal_copy $ENV lib/libglibmm-2.4*.dylib $WORK/$libs
+universal_copy $ENV lib/libgobject*.dylib $WORK/$libs
+universal_copy $ENV lib/libgthread*.dylib $WORK/$libs
+universal_copy $ENV lib/libgmodule*.dylib $WORK/$libs
+universal_copy $ENV lib/libsigc*.dylib $WORK/$libs
+universal_copy $ENV lib/libglib-2*.dylib $WORK/$libs
+universal_copy $ENV lib/libintl*.dylib $WORK/$libs
+universal_copy $ENV lib/libsndfile*.dylib $WORK/$libs
+universal_copy $ENV lib/libMagick++*.dylib $WORK/$libs
+universal_copy $ENV lib/libMagickCore*.dylib $WORK/$libs
+universal_copy $ENV lib/libMagickWand*.dylib $WORK/$libs
+universal_copy $ENV lib/libssh*.dylib $WORK/$libs
+universal_copy $ENV lib/libwx*.dylib $WORK/$libs
+universal_copy $ENV lib/libfontconfig*.dylib $WORK/$libs
+universal_copy $ENV lib/libfreetype*.dylib $WORK/$libs
+universal_copy $ENV lib/libexpat*.dylib $WORK/$libs
for obj in $WORK/$macos/dcpomatic $WORK/$libs/*.dylib; do
deps=`otool -L $obj | awk '{print $1}' | egrep "(/Users/carl|libboost|libssh)"`
fi
done
-pwd
cp build/platform/osx/Info.plist $WORK/$approot
cp icons/dcpomatic.icns $WORK/$resources/DVD-o-matic.icns
set -e
-ENV=/Users/carl/Environments/osx/10.8
-DEPS=/Users/carl/cdist
+ENV=/Users/carl/Environments/osx/64
+DEPS=/Users/carl/cdist/64
-export PKG_CONFIG_PATH=$DEPS/lib/pkgconfig:$ENV/lib/pkgconfig
+export PKG_CONFIG_PATH=$DEPS/lib/pkgconfig:$ENV/lib/pkgconfig:/usr/lib/pkgconfig
export LINKFLAGS="-L$ENV/lib"
export CXXFLAGS="-I$ENV/include"
export PATH=$PATH:$ENV/bin
File "%deps%/bin/avfilter-3.dll"
File "%deps%/bin/avformat-55.dll"
File "%deps%/bin/avutil-52.dll"
+File "%deps%/bin/avdevice-55.dll"
File "%deps%/bin/dcp.dll"
File "%deps%/bin/libintl-8.dll"
File "%deps%/bin/kumu-libdcp.dll"
File "%deps%/bin/libexpat-1.dll"
File "%deps%/bin/libbz2.dll"
File "%deps%/bin/cxml.dll"
+File "%deps%/bin/ffprobe.exe"
File "%binaries%/src/wx/dcpomatic-wx.dll"
File "%binaries%/src/lib/dcpomatic.dll"
RMDir /r "$INSTDIR\*.*"
RMDir "$INSTDIR"
-<<<<<<< HEAD
Delete "$DESKTOP\DCP-o-matic.lnk"
Delete "$DESKTOP\DCP-o-matic batch converter.lnk"
Delete "$DESKTOP\DCP-o-matic encode server.lnk"
RmDir "$SMPROGRAMS\DCP-o-matic"
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\DCP-o-matic"
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\DCP-o-matic"
-=======
-Delete "$DESKTOP\DVD-o-matic.lnk"
-Delete "$DESKTOP\DVD-o-matic batch converter.lnk"
-Delete "$DESKTOP\DVD-o-matic encode server.lnk"
-Delete "$SMPROGRAMS\DVD-o-matic\*.*"
-RmDir "$SMPROGRAMS\DVD-o-matic"
-DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\DVD-o-matic"
-DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\DVD-o-matic"
->>>>>>> master
SectionEnd
File "%deps%/bin/avfilter-3.dll"
File "%deps%/bin/avformat-55.dll"
File "%deps%/bin/avutil-52.dll"
+File "%deps%/bin/avdevice-55.dll"
File "%deps%/bin/dcp.dll"
File "%deps%/bin/libintl-8.dll"
File "%deps%/bin/kumu-libdcp.dll"
File "%deps%/bin/libexpat-1.dll"
File "%deps%/bin/libbz2.dll"
File "%deps%/bin/cxml.dll"
+File "%deps%/bin/ffprobe.exe"
File "%binaries%/src/wx/dcpomatic-wx.dll"
File "%binaries%/src/lib/dcpomatic.dll"
--- /dev/null
+#!/bin/bash
+
+export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:build/src/lib:build/src:/Users/carl/Environments/osx/64/lib
+if [ "$1" == "--debug" ]; then
+ shift
+ gdb --args build/src/tools/dvdomatic "$*"
+elif [ "$1" == "--valgrind" ]; then
+ shift
+ valgrind --tool="memcheck" build/src/tools/dvdomatic $*
+elif [ "$1" == "--i18n" ]; then
+ shift
+ LANGUAGE=fr_FR.UTF8 LANG=fr_FR.UTF8 build/src/tools/dvdomatic "$*"
+else
+ build/src/tools/dvdomatic "$*"
+fi
#!/bin/bash
-export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:build/src/lib:build/src:/Users/carl/Environments/osx/10.8/lib
+export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:build/src/lib:build/src:/Users/carl/Environments/osx/64/lib
if [ "$1" == "--debug" ]; then
shift
gdb --args build/src/tools/makedcp "$@"
export LD_LIBRARY_PATH=build/src/lib:$LD_LIBRARY_PATH
if [ "$1" == "--debug" ]; then
- gdb --args build/test/unit-tests
+ gdb --args build/test/unit-tests --catch_system_errors=no
elif [ "$1" == "--valgrind" ]; then
valgrind --tool="memcheck" --leak-check=full build/test/unit-tests
else
- build/test/unit-tests
+ build/test/unit-tests --catch_system_errors=no
fi
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+#include "combiner.h"
+#include "image.h"
+
+using boost::shared_ptr;
+
+Combiner::Combiner (shared_ptr<Log> log)
+ : TimedVideoProcessor (log)
+{
+
+}
+
+/** Process video for the left half of the frame.
+ * Subtitle parameter will be ignored.
+ * @param image Frame image.
+ */
+void
+Combiner::process_video (shared_ptr<const Image> image, bool, shared_ptr<Subtitle>, double)
+{
+ _image.reset (new SimpleImage (image));
+}
+
+/** Process video for the right half of the frame.
+ * @param image Frame image.
+ * @param sub Subtitle (which will be put onto the whole frame)
+ */
+void
+Combiner::process_video_b (shared_ptr<const Image> image, bool, shared_ptr<Subtitle> sub, double t)
+{
+ if (!_image) {
+ /* It's possible for filters in the A-side to mean that we get a B frame
+ before any A; just skip the B frame in that case. This at least prevents
+ a crash, but may not be right.
+ */
+ return;
+ }
+
+ /* Copy the right half of this image into our _image */
+ /* XXX: this should probably be in the Image class */
+ for (int i = 0; i < image->components(); ++i) {
+ int const line_size = image->line_size()[i];
+ int const half_line_size = line_size / 2;
+
+ uint8_t* p = _image->data()[i];
+ uint8_t* q = image->data()[i];
+
+ for (int j = 0; j < image->lines (i); ++j) {
+ memcpy (p + half_line_size, q + half_line_size, half_line_size);
+ p += _image->stride()[i];
+ q += image->stride()[i];
+ }
+ }
+
+ Video (_image, false, sub, t);
+ _image.reset ();
+}
using std::string;
using std::ofstream;
using std::list;
+using std::max;
using boost::shared_ptr;
using boost::lexical_cast;
using boost::optional;
/** Construct default configuration */
Config::Config ()
- : _num_local_encoding_threads (2)
+ : _num_local_encoding_threads (max (2U, boost::thread::hardware_concurrency()))
, _server_port (6192)
, _tms_path (N_("."))
, _sound_processor (SoundProcessor::from_id (N_("dolby_cp750")))
#include <fstream>
#include <boost/algorithm/string.hpp>
#include "cross.h"
-#ifdef DCPOMATIC_POSIX
+#include "compose.hpp"
+#include "log.h"
+#ifdef DCPOMATIC_LINUX
#include <unistd.h>
+#include <mntent.h>
#endif
#ifdef DCPOMATIC_WINDOWS
-#include "windows.h"
+#include <windows.h>
+#undef DATADIR
+#include <shlwapi.h>
#endif
#ifdef DCPOMATIC_OSX
#include <sys/sysctl.h>
#endif
using std::pair;
+using std::list;
using std::ifstream;
using std::string;
+using std::make_pair;
+using boost::shared_ptr;
void
dcpomatic_sleep (int s)
return info;
}
+void
+run_ffprobe (boost::filesystem::path content, boost::filesystem::path out, shared_ptr<Log> log)
+{
+#ifdef DCPOMATIC_WINDOWS
+ SECURITY_ATTRIBUTES security;
+ security.nLength = sizeof (security);
+ security.bInheritHandle = TRUE;
+ security.lpSecurityDescriptor = 0;
+
+ HANDLE child_stderr_read;
+ HANDLE child_stderr_write;
+ if (!CreatePipe (&child_stderr_read, &child_stderr_write, &security, 0)) {
+ log->log ("ffprobe call failed (could not CreatePipe)");
+ return;
+ }
+
+ wchar_t dir[512];
+ GetModuleFileName (GetModuleHandle (0), dir, sizeof (dir));
+ PathRemoveFileSpec (dir);
+ SetCurrentDirectory (dir);
+
+ STARTUPINFO startup_info;
+ ZeroMemory (&startup_info, sizeof (startup_info));
+ startup_info.cb = sizeof (startup_info);
+ startup_info.hStdError = child_stderr_write;
+ startup_info.dwFlags |= STARTF_USESTDHANDLES;
+
+ wchar_t command[512];
+ wcscpy (command, L"ffprobe.exe \"");
+
+ wchar_t file[512];
+ MultiByteToWideChar (CP_UTF8, 0, content.string().c_str(), -1, file, sizeof(file));
+ wcscat (command, file);
+
+ wcscat (command, L"\"");
+
+ PROCESS_INFORMATION process_info;
+ ZeroMemory (&process_info, sizeof (process_info));
+ if (!CreateProcess (0, command, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &startup_info, &process_info)) {
+ log->log ("ffprobe call failed (could not CreateProcess)");
+ return;
+ }
+
+ FILE* o = fopen (out.string().c_str(), "w");
+ if (!o) {
+ log->log ("ffprobe call failed (could not create output file)");
+ return;
+ }
+
+ CloseHandle (child_stderr_write);
+
+ while (1) {
+ char buffer[512];
+ DWORD read;
+ if (!ReadFile(child_stderr_read, buffer, sizeof(buffer), &read, 0) || read == 0) {
+ break;
+ }
+ fwrite (buffer, read, 1, o);
+ }
+
+ fclose (o);
+
+ WaitForSingleObject (process_info.hProcess, INFINITE);
+ CloseHandle (process_info.hProcess);
+ CloseHandle (process_info.hThread);
+ CloseHandle (child_stderr_read);
+#else
+ string ffprobe = "ffprobe \"" + content.string() + "\" 2> \"" + out.string() + "\"";
+ log->log (String::compose ("Probing with %1", ffprobe));
+ system (ffprobe.c_str ());
+#endif
+}
+
+list<pair<string, string> >
+mount_info ()
+{
+ list<pair<string, string> > m;
+
+#ifdef DCPOMATIC_LINUX
+ FILE* f = setmntent ("/etc/mtab", "r");
+ if (!f) {
+ return m;
+ }
+
+ while (1) {
+ struct mntent* mnt = getmntent (f);
+ if (!mnt) {
+ break;
+ }
+
+ m.push_back (make_pair (mnt->mnt_dir, mnt->mnt_type));
+ }
+
+ endmntent (f);
+#endif
+
+ return m;
+}
*/
+#include <boost/filesystem.hpp>
+
#ifdef DCPOMATIC_WINDOWS
#define WEXITSTATUS(w) (w)
#endif
+class Log;
+
void dcpomatic_sleep (int);
extern std::pair<std::string, int> cpu_info ();
+extern void run_ffprobe (boost::filesystem::path, boost::filesystem::path, boost::shared_ptr<Log>);
+extern std::list<std::pair<std::string, std::string> > mount_info ();
using std::vector;
using std::list;
using std::cout;
+using std::min;
using std::make_pair;
using boost::shared_ptr;
using boost::optional;
double
FFmpegDecoder::compute_pts_offset (double first_video, double first_audio, float video_frame_rate)
{
- assert (first_video >= 0);
- assert (first_audio >= 0);
-
double const old_first_video = first_video;
/* Round the first video to a frame boundary */
FFmpegDecoder::~FFmpegDecoder ()
{
+ boost::mutex::scoped_lock lm (_mutex);
+
if (_subtitle_codec_context) {
avcodec_close (_subtitle_codec_context);
}
}
}
-
- int const data_size = av_samples_get_buffer_size (
- 0, audio_codec_context()->channels, _frame->nb_samples, audio_sample_format (), 1
- );
-
- assert (audio_codec_context()->channels == _ffmpeg_content->audio_channels());
- audio (deinterleave_audio (_frame->data, data_size), _audio_position);
+ copy_packet.data += decode_result;
+ copy_packet.size -= decode_result;
}
-
- copy_packet.data += decode_result;
- copy_packet.size -= decode_result;
}
}
}
, _dci_metadata (Config::instance()->default_dci_metadata ())
, _dcp_video_frame_rate (24)
, _dcp_audio_channels (MAX_AUDIO_CHANNELS)
+ , _minimum_audio_channels (0)
, _dirty (false)
{
set_dci_date_today ();
}
set_directory (result.string ());
- _log.reset (new FileLog (file ("log")));
}
Film::Film (Film const & o)
, _dci_metadata (o._dci_metadata)
, _dcp_video_frame_rate (o._dcp_video_frame_rate)
, _dci_date (o._dci_date)
+ , _minimum_audio_channels (o._minimum_audio_channels)
, _dirty (o._dirty)
{
_playlist->ContentChanged.connect (bind (&Film::playlist_content_changed, this, _1, _2));
string
Film::internal_video_mxf_dir () const
{
- boost::filesystem::path p;
return dir ("video");
}
#endif
pair<string, int> const c = cpu_info ();
log()->log (String::compose ("CPU: %1, %2 processors", c.first, c.second));
+ list<pair<string, string> > const m = mount_info ();
+ for (list<pair<string, string> >::const_iterator i = m.begin(); i != m.end(); ++i) {
+ log()->log (String::compose ("Mount: %1 %2", i->first, i->second));
+ }
if (container() == 0) {
throw MissingSettingError (_("container"));
root->add_child("DCPVideoFrameRate")->add_child_text (lexical_cast<string> (_dcp_video_frame_rate));
root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date));
root->add_child("DCPAudioChannels")->add_child_text (lexical_cast<string> (_dcp_audio_channels));
+ root->add_child("MinimumAudioChannels")->add_child_text (lexical_cast<string> (_minimum_audio_channels));
_playlist->as_xml (root->add_child ("Playlist"));
doc.write_to_file_formatted (file ("metadata.xml"));
_dcp_video_frame_rate = f.number_child<int> ("DCPVideoFrameRate");
_dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate"));
_dcp_audio_channels = f.number_child<int> ("DCPAudioChannels");
+ _minimum_audio_channels = f.number_child<int> ("MinimumAudioChannels");
_playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"));
}
+void
+Film::set_minimum_audio_channels (int c)
+{
+ {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ _minimum_audio_channels = c;
+ }
+ signal_changed (MINIMUM_AUDIO_CHANNELS);
+}
+
void
Film::set_dcp_video_frame_rate (int f)
{
J2K_BANDWIDTH,
DCI_METADATA,
DCP_VIDEO_FRAME_RATE,
+ MINIMUM_AUDIO_CHANNELS
};
return _dcp_audio_channels;
}
+ int minimum_audio_channels () const {
+ boost::mutex::scoped_lock lm (_state_mutex);
+ return _minimum_audio_channels;
+ }
+
/* SET */
void set_directory (std::string);
void set_dci_metadata (DCIMetadata);
void set_dcp_video_frame_rate (int);
void set_dci_date_today ();
+ void set_minimum_audio_channels (int);
/** Emitted when some property has of the Film has changed */
mutable boost::signals2::signal<void (Property)> Changed;
/** The date that we should use in a DCI name */
boost::gregorian::date _dci_date;
int _dcp_audio_channels;
+ int _minimum_audio_channels;
/** true if our state has changed since we last saved it */
mutable bool _dirty;
*/
+#ifndef DCPOMATIC_RATIO_H
+#define DCPOMATIC_RATIO_H
+
#include <vector>
#include <libdcp/util.h>
static std::vector<Ratio const *> _ratios;
};
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2013 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.
+
+*/
+
+#include <boost/shared_ptr.hpp>
+#include <stdint.h>
+#include "trimmer.h"
+
+using std::cout;
+using std::max;
+using boost::shared_ptr;
+
+/** @param audio_sample_rate Audio sampling rate, or 0 if there is no audio */
+Trimmer::Trimmer (
+ shared_ptr<Log> log,
+ int video_trim_start,
+ int video_trim_end,
+ int video_length,
+ int audio_sample_rate,
+ float frames_per_second,
+ int dcp_frames_per_second
+ )
+ : AudioVideoProcessor (log)
+ , _video_start (video_trim_start)
+ , _video_end (video_length - video_trim_end)
+ , _video_in (0)
+ , _audio_in (0)
+{
+ FrameRateConversion frc (frames_per_second, dcp_frames_per_second);
+
+ if (frc.skip) {
+ _video_start /= 2;
+ _video_end /= 2;
+ } else if (frc.repeat) {
+ _video_start *= 2;
+ _video_end *= 2;
+ }
+
+ if (audio_sample_rate) {
+ _audio_start = video_frames_to_audio_frames (_video_start, audio_sample_rate, frames_per_second);
+ _audio_end = video_frames_to_audio_frames (_video_end, audio_sample_rate, frames_per_second);
+ }
+
+ /* XXX: this is a hack; if there is no trim at the end, set
+ the audio end point to infinity so that
+ shorter-video-than-audio does not trim audio (which breaks
+ the current set of regression tests). This could be
+ removed if a) the regression tests are regenerated and b) I
+ can work out what DCP length should be.
+
+ There is also a problem whereby black video frames inserted
+ at the start of the output by the matcher are not taken into account,
+ so if black frames are inserted it means more gets trimmed off the
+ end than should be. Hack around this in similar fashion with the
+ _video_end = INT_MAX line.
+ */
+ if (video_trim_end == 0) {
+ _video_end = INT_MAX;
+ _audio_end = INT64_MAX;
+ }
+}
+
+void
+Trimmer::process_video (shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub)
+{
+ if (_video_in >= _video_start && _video_in < _video_end) {
+ Video (image, same, sub);
+ }
+
+ ++_video_in;
+}
+
+void
+Trimmer::process_audio (shared_ptr<const AudioBuffers> audio)
+{
+ int64_t offset = _audio_start - _audio_in;
+ if (offset > audio->frames()) {
+ /* we haven't reached the start of the untrimmed section yet */
+ _audio_in += audio->frames ();
+ return;
+ }
+
+ if (offset < 0) {
+ offset = 0;
+ }
+
+ int64_t length = _audio_end - max (_audio_in, _audio_start);
+ if (length < 0) {
+ _audio_in += audio->frames ();
+ return;
+ }
+
+ if (length > (audio->frames() - offset)) {
+ length = audio->frames () - offset;
+ }
+
+ _audio_in += audio->frames ();
+
+ if (offset != 0 || length != audio->frames ()) {
+ shared_ptr<AudioBuffers> copy (new AudioBuffers (audio));
+ copy->move (offset, 0, length);
+ copy->set_frames (length);
+ audio = copy;
+ }
+
+ Audio (audio);
+}
+
#define MAX_AUDIO_CHANNELS 6
class Scaler;
+class Film;
extern std::string seconds_to_hms (int);
extern std::string time_to_hms (Time);
extern char const * dcpomatic_version;
extern char const * dcpomatic_git_commit;
+extern char const * dcpomatic_cxx_flags;
*/
#include <fstream>
+#include <cerrno>
#include <libdcp/picture_asset.h>
#include <libdcp/sound_asset.h>
#include <libdcp/picture_frame.h>
boost::filesystem::path p;
p /= _film->internal_video_mxf_dir ();
p /= _film->internal_video_mxf_filename ();
- FILE* mxf = fopen (p.string().c_str(), N_("rb"));
+ FILE* mxf = fopen (p.string().c_str(), "rb");
if (!mxf) {
+ _film->log()->log (String::compose ("Could not open existing MXF at %1 (errno=%2)", p.string(), errno));
return;
}
obj.source = sources + ' version.cc'
if bld.env.TARGET_WINDOWS:
- obj.uselib += ' WINSOCK2 BFD DBGHELP IBERTY'
+ obj.uselib += ' WINSOCK2 BFD DBGHELP IBERTY SHLWAPI'
obj.source += ' stack.cpp'
if bld.env.STATIC:
obj.uselib += ' XML++'
add_item (file, _("&Properties..."), ID_file_properties, NEEDS_FILM);
#ifndef __WXOSX__
file->AppendSeparator ();
-#endif
+#endif
add_item (file, _("&Exit"), wxID_EXIT, ALWAYS);
#ifdef __WXOSX__
<< " -v, --version show DCP-o-matic version\n"
<< " -h, --help show this help\n"
<< " -d, --deps list DCP-o-matic dependency details and quit\n"
+ << " -f, --flags show flags passed to C++ compiler on build\n"
<< " -n, --no-progress do not print progress to stdout\n"
<< " -r, --no-remote do not use any remote servers\n"
<< "\n"
{ "version", no_argument, 0, 'v'},
{ "help", no_argument, 0, 'h'},
{ "deps", no_argument, 0, 'd'},
+ { "flags", no_argument, 0, 'f'},
{ "no-progress", no_argument, 0, 'n'},
{ "no-remote", no_argument, 0, 'r'},
{ "log-level", required_argument, 0, 'l' },
{ 0, 0, 0, 0 }
};
- int c = getopt_long (argc, argv, "vhdnrl:", long_options, &option_index);
+ int c = getopt_long (argc, argv, "vhdfnrl:", long_options, &option_index);
if (c == -1) {
break;
case 'd':
cout << dependency_version_summary () << "\n";
exit (EXIT_SUCCESS);
+ case 'f':
+ cout << dcpomatic_cxx_flags << "\n";
+ exit (EXIT_SUCCESS);
case 'n':
progress = false;
break;
def build(bld):
for t in ['dcpomatic_cli', 'dcpomatic_server_cli']:
obj = bld(features = 'cxx cxxprogram')
- obj.uselib = 'BOOST_THREAD OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC'
+ obj.uselib = 'BOOST_THREAD OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC WXWIDGETS'
obj.includes = ['..']
obj.use = ['libdcpomatic']
obj.source = '%s.cc' % t
if not bld.env.DISABLE_GUI:
for t in ['dcpomatic', 'dcpomatic_batch', 'dcpomatic_server']:
obj = bld(features = 'cxx cxxprogram')
- obj.uselib = 'DCP CXML OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC'
+ obj.uselib = 'DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC CXML WXWIDGETS'
+ if bld.env.STATIC:
+ obj.uselib += ' GTK'
obj.includes = ['..']
obj.use = ['libdcpomatic', 'libdcpomatic-wx']
obj.source = '%s.cc' % t
int c = 0;
for (size_t i = 0; i < credits.Count(); ++i) {
- add_label_to_sizer (sizers[c], panel, credits[i]);
+ add_label_to_sizer (sizers[c], panel, credits[i], false);
++c;
if (c == N) {
c = 0;
SetTitle (wxString::Format (_("DCP-o-matic audio - %s"), std_to_wx(_content->file().filename().string()).data()));
}
-
void
AudioDialog::try_to_load_analysis ()
{
wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
_misc_panel->SetSizer (s);
- wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6);
+ wxFlexGridSizer* table = new wxFlexGridSizer (3, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
table->AddGrowableCol (1, 1);
s->Add (table, 1, wxALL | wxEXPAND, 8);
table->Add (_language, 1, wxEXPAND);
table->AddSpacer (0);
- wxStaticText* restart = add_label_to_sizer (table, _misc_panel, _("(restart DVD-o-matic to see language changes)"));
+ wxStaticText* restart = add_label_to_sizer (table, _misc_panel, _("(restart DVD-o-matic to see language changes)"), false);
wxFont font = restart->GetFont();
font.SetStyle (wxFONTSTYLE_ITALIC);
font.SetPointSize (font.GetPointSize() - 1);
table->AddSpacer (0);
table->AddSpacer (0);
- add_label_to_sizer (table, _misc_panel, _("Threads to use for encoding on this host"));
+ add_label_to_sizer (table, _misc_panel, _("Threads to use for encoding on this host"), true);
_num_local_encoding_threads = new wxSpinCtrl (_misc_panel);
- table->Add (_num_local_encoding_threads, 1, wxEXPAND);
+ table->Add (_num_local_encoding_threads, 1);
table->AddSpacer (0);
- add_label_to_sizer (table, _misc_panel, _("Default duration of still images"));
+ add_label_to_sizer (table, _misc_panel, _("Default duration of still images"), true);
_default_still_length = new wxSpinCtrl (_misc_panel);
table->Add (_default_still_length, 1, wxEXPAND);
- add_label_to_sizer (table, _misc_panel, _("s"));
+ add_label_to_sizer (table, _misc_panel, _("s"), false);
- add_label_to_sizer (table, _misc_panel, _("Default directory for new films"));
-#ifdef __WXMSW__
+ add_label_to_sizer (table, _misc_panel, _("Default directory for new films"), true);
+#ifdef DCPOMATIC_USE_OWN_DIR_PICKER
_default_directory = new DirPickerCtrl (_misc_panel);
#else
_default_directory = new wxDirPickerCtrl (_misc_panel, wxDD_DIR_MUST_EXIST);
table->Add (_default_directory, 1, wxEXPAND);
table->AddSpacer (0);
- add_label_to_sizer (table, _misc_panel, _("Default DCI name details"));
+ add_label_to_sizer (table, _misc_panel, _("Default DCI name details"), true);
_default_dci_metadata_button = new wxButton (_misc_panel, wxID_ANY, _("Edit..."));
table->Add (_default_dci_metadata_button);
table->AddSpacer (1);
- add_label_to_sizer (table, _misc_panel, _("Default container"));
+ add_label_to_sizer (table, _misc_panel, _("Default container"), true);
_default_container = new wxChoice (_misc_panel, wxID_ANY);
table->Add (_default_container);
table->AddSpacer (1);
- add_label_to_sizer (table, _misc_panel, _("Default content type"));
+ add_label_to_sizer (table, _misc_panel, _("Default content type"), true);
_default_dcp_content_type = new wxChoice (_misc_panel, wxID_ANY);
table->Add (_default_dcp_content_type);
table->AddSpacer (1);
wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
_tms_panel->SetSizer (s);
- wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6);
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
table->AddGrowableCol (1, 1);
s->Add (table, 1, wxALL | wxEXPAND, 8);
- add_label_to_sizer (table, _tms_panel, _("IP address"));
+ add_label_to_sizer (table, _tms_panel, _("IP address"), true);
_tms_ip = new wxTextCtrl (_tms_panel, wxID_ANY);
table->Add (_tms_ip, 1, wxEXPAND);
- add_label_to_sizer (table, _tms_panel, _("Target path"));
+ add_label_to_sizer (table, _tms_panel, _("Target path"), true);
_tms_path = new wxTextCtrl (_tms_panel, wxID_ANY);
table->Add (_tms_path, 1, wxEXPAND);
- add_label_to_sizer (table, _tms_panel, _("User name"));
+ add_label_to_sizer (table, _tms_panel, _("User name"), true);
_tms_user = new wxTextCtrl (_tms_panel, wxID_ANY);
table->Add (_tms_user, 1, wxEXPAND);
- add_label_to_sizer (table, _tms_panel, _("Password"));
+ add_label_to_sizer (table, _tms_panel, _("Password"), true);
_tms_password = new wxTextCtrl (_tms_panel, wxID_ANY);
table->Add (_tms_password, 1, wxEXPAND);
wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
_metadata_panel->SetSizer (s);
- wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6);
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
table->AddGrowableCol (1, 1);
s->Add (table, 1, wxALL | wxEXPAND, 8);
- add_label_to_sizer (table, _metadata_panel, _("Issuer"));
+ add_label_to_sizer (table, _metadata_panel, _("Issuer"), true);
_issuer = new wxTextCtrl (_metadata_panel, wxID_ANY);
table->Add (_issuer, 1, wxEXPAND);
- add_label_to_sizer (table, _metadata_panel, _("Creator"));
+ add_label_to_sizer (table, _metadata_panel, _("Creator"), true);
_creator = new wxTextCtrl (_metadata_panel, wxID_ANY);
table->Add (_creator, 1, wxEXPAND);
wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
_servers_panel->SetSizer (s);
- wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6);
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
table->AddGrowableCol (0, 1);
s->Add (table, 1, wxALL | wxEXPAND, 8);
{
wxSizer* s = new wxBoxSizer (wxVERTICAL);
_add_server = new wxButton (_servers_panel, wxID_ANY, _("Add"));
- s->Add (_add_server);
+ s->Add (_add_server, 0, wxTOP | wxBOTTOM, 2);
_edit_server = new wxButton (_servers_panel, wxID_ANY, _("Edit"));
- s->Add (_edit_server);
+ s->Add (_edit_server, 0, wxTOP | wxBOTTOM, 2);
_remove_server = new wxButton (_servers_panel, wxID_ANY, _("Remove"));
- s->Add (_remove_server);
+ s->Add (_remove_server, 0, wxTOP | wxBOTTOM, 2);
table->Add (s, 0);
}
#include <wx/spinctrl.h>
#include <wx/listctrl.h>
#include <wx/filepicker.h>
+#include "wx_util.h"
class DirPickerCtrl;
class wxNotebook;
wxTextCtrl* _tms_password;
wxSpinCtrl* _num_local_encoding_threads;
wxSpinCtrl* _default_still_length;
-#ifdef __WXMSW__
+#ifdef DCPOMATIC_USE_OWN_DIR_PICKER
DirPickerCtrl* _default_directory;
#else
wxDirPickerCtrl* _default_directory;
DCIMetadataDialog::DCIMetadataDialog (wxWindow* parent, DCIMetadata dm)
: wxDialog (parent, wxID_ANY, _("DCI name"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
- wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6);
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
table->AddGrowableCol (1, 1);
- add_label_to_sizer (table, this, _("Audio Language (e.g. EN)"));
+ add_label_to_sizer (table, this, _("Audio Language (e.g. EN)"), true);
_audio_language = new wxTextCtrl (this, wxID_ANY);
table->Add (_audio_language, 1, wxEXPAND);
- add_label_to_sizer (table, this, _("Subtitle Language (e.g. FR)"));
+ add_label_to_sizer (table, this, _("Subtitle Language (e.g. FR)"), true);
_subtitle_language = new wxTextCtrl (this, wxID_ANY);
table->Add (_subtitle_language, 1, wxEXPAND);
- add_label_to_sizer (table, this, _("Territory (e.g. UK)"));
+ add_label_to_sizer (table, this, _("Territory (e.g. UK)"), true);
_territory = new wxTextCtrl (this, wxID_ANY);
table->Add (_territory, 1, wxEXPAND);
- add_label_to_sizer (table, this, _("Rating (e.g. 15)"));
+ add_label_to_sizer (table, this, _("Rating (e.g. 15)"), true);
_rating = new wxTextCtrl (this, wxID_ANY);
table->Add (_rating, 1, wxEXPAND);
- add_label_to_sizer (table, this, _("Studio (e.g. TCF)"));
+ add_label_to_sizer (table, this, _("Studio (e.g. TCF)"), true);
_studio = new wxTextCtrl (this, wxID_ANY);
table->Add (_studio, 1, wxEXPAND);
- add_label_to_sizer (table, this, _("Facility (e.g. DLA)"));
+ add_label_to_sizer (table, this, _("Facility (e.g. DLA)"), true);
_facility = new wxTextCtrl (this, wxID_ANY);
table->Add (_facility, 1, wxEXPAND);
- add_label_to_sizer (table, this, _("Package Type (e.g. OV)"));
+ add_label_to_sizer (table, this, _("Package Type (e.g. OV)"), true);
_package_type = new wxTextCtrl (this, wxID_ANY);
table->Add (_package_type, 1, wxEXPAND);
_dcp_sizer = new wxBoxSizer (wxVERTICAL);
_dcp_panel->SetSizer (_dcp_sizer);
- wxGridBagSizer* grid = new wxGridBagSizer (4, 4);
+ wxGridBagSizer* grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
_dcp_sizer->Add (grid, 0, wxEXPAND | wxALL, 8);
int r = 0;
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Name"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Name"), true, wxGBPosition (r, 0));
_name = new wxTextCtrl (_dcp_panel, wxID_ANY);
- grid->Add (_name, wxGBPosition(r, 1), wxDefaultSpan, wxEXPAND);
+ grid->Add (_name, wxGBPosition(r, 1), wxDefaultSpan, wxEXPAND | wxLEFT | wxRIGHT);
++r;
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("DCP Name"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("DCP Name"), true, wxGBPosition (r, 0));
_dcp_name = new wxStaticText (_dcp_panel, wxID_ANY, wxT (""));
grid->Add (_dcp_name, wxGBPosition(r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
++r;
+ int flags = wxALIGN_CENTER_VERTICAL;
+#ifdef __WXOSX__
+ flags |= wxALIGN_RIGHT;
+#endif
+
_use_dci_name = new wxCheckBox (_dcp_panel, wxID_ANY, _("Use DCI name"));
- grid->Add (_use_dci_name, wxGBPosition (r, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
+ grid->Add (_use_dci_name, wxGBPosition (r, 0), wxDefaultSpan, flags);
_edit_dci_button = new wxButton (_dcp_panel, wxID_ANY, _("Details..."));
grid->Add (_edit_dci_button, wxGBPosition (r, 1), wxDefaultSpan);
++r;
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Container"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Container"), true, wxGBPosition (r, 0));
_container = new wxChoice (_dcp_panel, wxID_ANY);
- grid->Add (_container, wxGBPosition (r, 1));
+ grid->Add (_container, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND);
++r;
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Content Type"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Content Type"), true, wxGBPosition (r, 0));
_dcp_content_type = new wxChoice (_dcp_panel, wxID_ANY);
grid->Add (_dcp_content_type, wxGBPosition (r, 1));
++r;
{
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("DCP Frame Rate"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("DCP Frame Rate"), true, wxGBPosition (r, 0));
wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_dcp_frame_rate = new wxChoice (_dcp_panel, wxID_ANY);
s->Add (_dcp_frame_rate, 1, wxALIGN_CENTER_VERTICAL);
++r;
{
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("JPEG2000 bandwidth"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("JPEG2000 bandwidth"), true, wxGBPosition (r, 0));
wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_j2k_bandwidth = new wxSpinCtrl (_dcp_panel, wxID_ANY);
s->Add (_j2k_bandwidth, 1);
- add_label_to_sizer (s, _dcp_panel, _("MBps"));
+ add_label_to_sizer (s, _dcp_panel, _("MBps"), false);
grid->Add (s, wxGBPosition (r, 1));
}
++r;
- add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Scaler"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Scaler"), true, wxGBPosition (r, 0));
_scaler = new wxChoice (_dcp_panel, wxID_ANY);
- grid->Add (_scaler, wxGBPosition (r, 1));
+ grid->Add (_scaler, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
++r;
vector<Scaler const *> const sc = Scaler::all ();
_dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this);
_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_frame_rate_changed), 0, this);
_best_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::best_dcp_frame_rate_clicked), 0, this);
+// _pad_with_silence->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::pad_with_silence_toggled), 0, this);
+// _minimum_audio_channels->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::minimum_audio_channels_changed), 0, this);
_with_subtitles->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::with_subtitles_toggled), 0, this);
_subtitle_offset->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_offset_changed), 0, this);
_subtitle_scale->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::subtitle_scale_changed), 0, this);
wxBoxSizer* video_sizer = new wxBoxSizer (wxVERTICAL);
_video_panel->SetSizer (video_sizer);
- wxGridBagSizer* grid = new wxGridBagSizer (4, 4);
+ wxGridBagSizer* grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
video_sizer->Add (grid, 0, wxALL, 8);
int r = 0;
- add_label_to_grid_bag_sizer (grid, _video_panel, _("Left crop"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _video_panel, _("Left crop"), true, wxGBPosition (r, 0));
_left_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1));
grid->Add (_left_crop, wxGBPosition (r, 1));
++r;
- add_label_to_grid_bag_sizer (grid, _video_panel, _("Right crop"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _video_panel, _("Right crop"), true, wxGBPosition (r, 0));
_right_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1));
grid->Add (_right_crop, wxGBPosition (r, 1));
++r;
- add_label_to_grid_bag_sizer (grid, _video_panel, _("Top crop"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _video_panel, _("Top crop"), true, wxGBPosition (r, 0));
_top_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1));
grid->Add (_top_crop, wxGBPosition (r, 1));
++r;
- add_label_to_grid_bag_sizer (grid, _video_panel, _("Bottom crop"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _video_panel, _("Bottom crop"), true, wxGBPosition (r, 0));
_bottom_crop = new wxSpinCtrl (_video_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1));
grid->Add (_bottom_crop, wxGBPosition (r, 1));
++r;
- add_label_to_grid_bag_sizer (grid, _video_panel, _("Scale to"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _video_panel, _("Scale to"), true, wxGBPosition (r, 0));
_ratio = new wxChoice (_video_panel, wxID_ANY);
grid->Add (_ratio, wxGBPosition (r, 1));
++r;
/* VIDEO-only stuff */
{
- add_label_to_grid_bag_sizer (grid, _video_panel, _("Filters"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _video_panel, _("Filters"), true, wxGBPosition (r, 0));
wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_filters = new wxStaticText (_video_panel, wxID_ANY, _("None"));
s->Add (_filters, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6);
_filters_button = new wxButton (_video_panel, wxID_ANY, _("Edit..."));
- s->Add (_filters_button, 0);
+ s->Add (_filters_button, 0, wxALIGN_CENTER_VERTICAL);
grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
}
++r;
- add_label_to_grid_bag_sizer (grid, _video_panel, _("Colour look-up table"), wxGBPosition (r, 0));
+ add_label_to_grid_bag_sizer (grid, _video_panel, _("Colour look-up table"), true, wxGBPosition (r, 0));
_colour_lut = new wxChoice (_video_panel, wxID_ANY);
for (int i = 0; i < 2; ++i) {
_colour_lut->Append (std_to_wx (colour_lut_index_to_name (i)));
h->Add (_loop_content, 0, wxALL, 6);
_loop_count = new wxSpinCtrl (_content_panel, wxID_ANY);
h->Add (_loop_count, 0, wxALL, 6);
- add_label_to_sizer (h, _content_panel, _("times"));
+ add_label_to_sizer (h, _content_panel, _("times"), false);
_content_sizer->Add (h, 0, wxALL, 6);
_content_notebook = new wxNotebook (_content_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_LEFT);
wxBoxSizer* audio_sizer = new wxBoxSizer (wxVERTICAL);
_audio_panel->SetSizer (audio_sizer);
- wxFlexGridSizer* grid = new wxFlexGridSizer (3, 4, 4);
+ wxFlexGridSizer* grid = new wxFlexGridSizer (3, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
audio_sizer->Add (grid, 0, wxALL, 8);
_show_audio = new wxButton (_audio_panel, wxID_ANY, _("Show Audio..."));
grid->AddSpacer (0);
grid->AddSpacer (0);
- add_label_to_sizer (grid, _audio_panel, _("Audio Gain"));
+ add_label_to_sizer (grid, _audio_panel, _("Audio Gain"), true);
{
wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_audio_gain = new wxSpinCtrl (_audio_panel);
s->Add (_audio_gain, 1);
- add_label_to_sizer (s, _audio_panel, _("dB"));
+ add_label_to_sizer (s, _audio_panel, _("dB"), false);
grid->Add (s, 1);
}
_audio_gain_calculate_button = new wxButton (_audio_panel, wxID_ANY, _("Calculate..."));
grid->Add (_audio_gain_calculate_button);
- add_label_to_sizer (grid, _audio_panel, _("Audio Delay"));
+ add_label_to_sizer (grid, _audio_panel, _("Audio Delay"), false);
{
wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_audio_delay = new wxSpinCtrl (_audio_panel);
s->Add (_audio_delay, 1);
/// TRANSLATORS: this is an abbreviation for milliseconds, the unit of time
- add_label_to_sizer (s, _audio_panel, _("ms"));
+ add_label_to_sizer (s, _audio_panel, _("ms"), false);
grid->Add (s);
}
grid->AddSpacer (0);
- add_label_to_sizer (grid, _audio_panel, _("Audio Stream"));
+ add_label_to_sizer (grid, _audio_panel, _("Audio Stream"), true);
_audio_stream = new wxChoice (_audio_panel, wxID_ANY);
grid->Add (_audio_stream, 1);
_audio_description = new wxStaticText (_audio_panel, wxID_ANY, wxT (""));
_audio_mapping = new AudioMappingView (_audio_panel);
audio_sizer->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6);
+#if 0
+ {
+ _pad_with_silence = new wxCheckBox (_audio_panel, wxID_ANY, _("Pad with silence to"));
+ grid->Add (_pad_with_silence);
+ wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
+ _minimum_audio_channels = new wxSpinCtrl (_audio_panel);
+ s->Add (_minimum_audio_channels, 1);
+ add_label_to_sizer (s, _audio_panel, _("channels"), false);
+ grid->Add (s);
+ }
+
+ {
+ _use_content_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use content's audio"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+ grid->Add (video_control (_use_content_audio));
+ wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
+ _audio_stream = new wxChoice (_audio_panel, wxID_ANY);
+ s->Add (video_control (_audio_stream), 1);
+ _audio = new wxStaticText (_audio_panel, wxID_ANY, wxT (""));
+ s->Add (video_control (_audio), 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8);
+ grid->Add (s);
+ }
+#endif
+
_audio_gain->SetRange (-60, 60);
_audio_delay->SetRange (-1000, 1000);
+// _minimum_audio_channels->SetRange (0, MAX_AUDIO_CHANNELS);
}
void
_subtitle_panel = new wxPanel (_content_notebook);
wxBoxSizer* subtitle_sizer = new wxBoxSizer (wxVERTICAL);
_subtitle_panel->SetSizer (subtitle_sizer);
- wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4);
+ wxFlexGridSizer* grid = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
subtitle_sizer->Add (grid, 0, wxALL, 8);
_with_subtitles = new wxCheckBox (_subtitle_panel, wxID_ANY, _("With Subtitles"));
grid->AddSpacer (0);
{
- add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset"));
+ add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Offset"), true);
wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_subtitle_offset = new wxSpinCtrl (_subtitle_panel);
s->Add (_subtitle_offset);
- add_label_to_sizer (s, _subtitle_panel, _("pixels"));
+ add_label_to_sizer (s, _subtitle_panel, _("pixels"), false);
grid->Add (s);
}
{
- add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Scale"));
+ add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Scale"), true);
wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_subtitle_scale = new wxSpinCtrl (_subtitle_panel);
s->Add (_subtitle_scale);
- add_label_to_sizer (s, _subtitle_panel, _("%"));
+ add_label_to_sizer (s, _subtitle_panel, _("%"), false);
grid->Add (s);
}
- add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Stream"));
+ add_label_to_sizer (grid, _subtitle_panel, _("Subtitle Stream"), true);
_subtitle_stream = new wxChoice (_subtitle_panel, wxID_ANY);
grid->Add (_subtitle_stream, 1, wxEXPAND | wxALL, 6);
grid->AddSpacer (0);
wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4);
timing_sizer->Add (grid, 0, wxALL, 8);
- add_label_to_sizer (grid, _timing_panel, _("Start time"));
+ add_label_to_sizer (grid, _timing_panel, _("Start time"), true);
_start = new Timecode (_timing_panel);
grid->Add (_start);
- add_label_to_sizer (grid, _timing_panel, _("Length"));
+ add_label_to_sizer (grid, _timing_panel, _("Length"), true);
_length = new Timecode (_timing_panel);
grid->Add (_length);
}
setup_content ();
setup_subtitle_control_sensitivity ();
setup_show_audio_sensitivity ();
+ setup_minimum_audio_channels ();
break;
case Film::LOOP:
checked_set (_loop_content, _film->loop() > 1);
_best_dcp_frame_rate->Enable (_film->best_dcp_video_frame_rate () != _film->dcp_video_frame_rate ());
break;
}
+ case Film::MINIMUM_AUDIO_CHANNELS:
+// checked_set (_minimum_audio_channels, _film->minimum_audio_channels ());
+ setup_minimum_audio_channels ();
+ break;
}
}
}
Crop const crop = _film->crop ();
- if (crop.left || crop.right || crop.top || crop.bottom) {
- libdcp::Size const cropped = _film->cropped_size (_film->video_size ());
+ if ((crop.left || crop.right || crop.top || crop.bottom) && _film->size() != libdcp::Size (0, 0)) {
+ libdcp::Size const cropped = _film->cropped_size (_film->size ());
d << wxString::Format (
_("Cropped to %dx%d (%.2f:1)\n"),
cropped.width, cropped.height,
vc->set_ratio (ratios[n]);
}
}
+
+void
+FilmEditor::setup_minimum_audio_channels ()
+{
+#if 0
+ if (!_film || !_film->audio_stream ()) {
+ _pad_with_silence->SetValue (false);
+ return;
+ }
+
+ _pad_with_silence->SetValue (_film->audio_stream()->channels() < _film->minimum_audio_channels());
+
+ AudioMapping m (_film);
+ _minimum_audio_channels->SetRange (m.minimum_dcp_channels() + 1, MAX_AUDIO_CHANNELS);
+#endif
+}
+
+void
+FilmEditor::pad_with_silence_toggled (wxCommandEvent &)
+{
+
+}
+
+void
+FilmEditor::minimum_audio_channels_changed (wxCommandEvent &)
+{
+ if (!_film) {
+ return;
+ }
+
+// _film->set_minimum_audio_channels (_minimum_audio_channels->GetValue ());
+}
void start_changed ();
void length_changed ();
void ratio_changed (wxCommandEvent &);
+ void pad_with_silence_toggled (wxCommandEvent &);
+ void minimum_audio_channels_changed (wxCommandEvent &);
/* Handle changes to the model */
void film_changed (Film::Property);
void setup_container ();
void setup_content_sensitivity ();
void setup_loop_sensitivity ();
+ void setup_minimum_audio_channels ();
void active_jobs_changed (bool);
boost::shared_ptr<Content> selected_content ();
wxChoice* _dcp_content_type;
wxChoice* _dcp_frame_rate;
wxButton* _best_dcp_frame_rate;
+ wxCheckBox* _pad_with_silence;
+ wxSpinCtrl* _minimum_audio_channels;
wxChoice* _audio_stream;
wxStaticText* _audio_description;
wxChoice* _subtitle_stream;
GainCalculatorDialog::GainCalculatorDialog (wxWindow* parent)
: wxDialog (parent, wxID_ANY, _("Gain Calculator"))
{
- wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6);
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
table->AddGrowableCol (1, 1);
- add_label_to_sizer (table, this, _("I want to play this back at fader"));
+ add_label_to_sizer (table, this, _("I want to play this back at fader"), true);
_wanted = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, wxTextValidator (wxFILTER_NUMERIC));
table->Add (_wanted, 1, wxEXPAND);
- add_label_to_sizer (table, this, _("But I have to use fader"));
+ add_label_to_sizer (table, this, _("But I have to use fader"), true);
_actual = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, wxDefaultSize, 0, wxTextValidator (wxFILTER_NUMERIC));
table->Add (_actual, 1, wxEXPAND);
grid->AddGrowableCol (1, 1);
{
- add_label_to_sizer (grid, this, (_("Duration")));
+ add_label_to_sizer (grid, this, _("Duration"), true);
wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
_video_length = new wxSpinCtrl (this);
s->Add (_video_length);
/// TRANSLATORS: this is an abbreviation for seconds, the unit of time
- add_label_to_sizer (s, this, _("s"));
+ add_label_to_sizer (s, this, _("s"), false);
grid->Add (s);
}
if (!(*i)->finished_cancelled()) {
_job_records[*i].gauge->SetValue (100);
}
- (*i)->Finished ();
_job_records[*i].finalised = true;
_job_records[*i].cancel->Enable (false);
if (!(*i)->error_details().empty ()) {
#include <wx/stdpaths.h>
#include "lib/config.h"
#include "new_film_dialog.h"
-#ifdef __WXMSW__
+#include "wx_util.h"
+#ifdef DCPOMATIC_USE_OWN_DIR_PICKER
#include "dir_picker_ctrl.h"
#endif
-#include "wx_util.h"
using namespace std;
using namespace boost;
wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
SetSizer (overall_sizer);
- wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6);
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
table->AddGrowableCol (1, 1);
overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6);
- add_label_to_sizer (table, this, _("Film name"));
+ add_label_to_sizer (table, this, _("Film name"), true);
_name = new wxTextCtrl (this, wxID_ANY);
- table->Add (_name, 1, wxEXPAND);
+ table->Add (_name, 0, wxEXPAND);
+
+ add_label_to_sizer (table, this, _("Create in folder"), true);
- add_label_to_sizer (table, this, _("Create in folder"));
-#ifdef __WXMSW__
- _folder = new DirPickerCtrl (this);
+#ifdef DCPOMATIC_USE_OWN_DIR_PICKER
+ _folder = new DirPickerCtrl (this);
#else
_folder = new wxDirPickerCtrl (this, wxDD_DIR_MUST_EXIST);
#endif
#include <wx/wx.h>
#include <wx/filepicker.h>
+#include "wx_util.h"
class DirPickerCtrl;
private:
wxTextCtrl* _name;
-#ifdef __WXMSW__
+#ifdef DCPOMATIC_USE_OWN_DIR_PICKER
DirPickerCtrl* _folder;
-#else
+#else
wxDirPickerCtrl* _folder;
-#endif
+#endif
static boost::optional<std::string> _directory;
};
: wxDialog (parent, wxID_ANY, _("Film Properties"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
, _film (film)
{
- wxFlexGridSizer* table = new wxFlexGridSizer (2, 3, 6);
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
- add_label_to_sizer (table, this, _("Frames"));
+ add_label_to_sizer (table, this, _("Frames"), true);
_frames = new wxStaticText (this, wxID_ANY, wxT (""));
table->Add (_frames, 1, wxALIGN_CENTER_VERTICAL);
- add_label_to_sizer (table, this, _("Disk space required"));
+ add_label_to_sizer (table, this, _("Disk space required"), true);
_disk = new wxStaticText (this, wxID_ANY, wxT (""));
table->Add (_disk, 1, wxALIGN_CENTER_VERTICAL);
- add_label_to_sizer (table, this, _("Frames already encoded"));
+ add_label_to_sizer (table, this, _("Frames already encoded"), true);
_encoded = new ThreadedStaticText (this, _("counting..."), boost::bind (&PropertiesDialog::frames_already_encoded, this));
table->Add (_encoded, 1, wxALIGN_CENTER_VERTICAL);
_server = new ServerDescription (wx_to_std (N_("localhost")), 1);
}
- wxFlexGridSizer* table = new wxFlexGridSizer (2, 4, 4);
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
table->AddGrowableCol (1, 1);
- add_label_to_sizer (table, this, _("Host name or IP address"));
+ add_label_to_sizer (table, this, _("Host name or IP address"), true);
_host = new wxTextCtrl (this, wxID_ANY);
table->Add (_host, 1, wxEXPAND);
- add_label_to_sizer (table, this, _("Threads to use"));
+ add_label_to_sizer (table, this, _("Threads to use"), true);
_threads = new wxSpinCtrl (this, wxID_ANY);
table->Add (_threads, 1, wxEXPAND);
_hours = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, size, 0, validator);
_hours->SetMaxLength (2);
sizer->Add (_hours);
- add_label_to_sizer (sizer, this, wxT (":"));
+ add_label_to_sizer (sizer, this, wxT (":"), false);
_minutes = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, size);
_minutes->SetMaxLength (2);
sizer->Add (_minutes);
- add_label_to_sizer (sizer, this, wxT (":"));
+ add_label_to_sizer (sizer, this, wxT (":"), false);
_seconds = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, size);
_seconds->SetMaxLength (2);
sizer->Add (_seconds);
- add_label_to_sizer (sizer, this, wxT ("."));
+ add_label_to_sizer (sizer, this, wxT ("."), false);
_frames = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, size);
_frames->SetMaxLength (2);
sizer->Add (_frames);
"""
def configure(conf):
- conf.check_cfg(package = '', path = conf.options.wx_config, args = '--cppflags --cxxflags --libs', uselib_store = 'WXWIDGETS', mandatory = True)
+ conf.check_cfg(msg='Checking for wxWidgets', package='', path=conf.options.wx_config, args='--cppflags --cxxflags --libs',
+ uselib_store='WXWIDGETS', mandatory=True)
+
+ if conf.env.STATIC:
+ # wx-config returns its static libraries as full paths, without -l prefixes, which confuses
+ # check_cfg(), so just hard-code it all.
+ conf.env.STLIB_WXWIDGETS = ['wx_gtk2u_xrc-2.9', 'wx_gtk2u_qa-2.9', 'wx_baseu_net-2.9', 'wx_gtk2u_html-2.9',
+ 'wx_gtk2u_adv-2.9', 'wx_gtk2u_core-2.9', 'wx_baseu_xml-2.9', 'wx_baseu-2.9']
+ conf.env.LIB_WXWIDGETS = ['tiff', 'SM']
+
+ conf.in_msg = 1
+ wx_version = conf.check_cfg(package='', path=conf.options.wx_config, args='--version').strip()
+ conf.im_msg = 0
+ if wx_version != '2.9.4':
+ conf.fatal('wxwidgets version 2.9.4 is required; %s found' % wx_version)
def build(bld):
if bld.env.STATIC:
obj.includes = [ '..' ]
obj.export_includes = ['.']
obj.uselib = 'WXWIDGETS'
+ if bld.env.TARGET_LINUX:
+ obj.uselib += ' GTK'
obj.use = 'libdcpomatic'
obj.source = sources
obj.target = 'dcpomatic-wx'
* @param s Sizer to add to.
* @param p Parent window for the wxStaticText.
* @param t Text for the wxStaticText.
+ * @param left true if this label is a `left label'; ie the sort
+ * of label which should be right-aligned on OS X.
* @param prop Proportion to pass when calling Add() on the wxSizer.
*/
wxStaticText *
-add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, int prop)
+add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, bool left, int prop)
{
+ int flags = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT;
+#ifdef __WXOSX__
+ if (left) {
+ flags |= wxALIGN_RIGHT;
+ t += wxT (":");
+ }
+#endif
wxStaticText* m = new wxStaticText (p, wxID_ANY, t);
- s->Add (m, prop, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+ s->Add (m, prop, flags, 6);
return m;
}
wxStaticText *
-add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, wxGBPosition pos, wxGBSpan span)
+add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool left, wxGBPosition pos, wxGBSpan span)
{
+ int flags = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT;
+#ifdef __WXOSX__
+ if (left) {
+ flags |= wxALIGN_RIGHT;
+ t += wxT (":");
+ }
+#endif
wxStaticText* m = new wxStaticText (p, wxID_ANY, t);
- s->Add (m, pos, span, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+ s->Add (m, pos, span, flags);
return m;
}
*/
+#ifndef DCPOMATIC_WX_UTIL_H
+#define DCPOMATIC_WX_UTIL_H
+
#include <wx/wx.h>
#include <wx/gbsizer.h>
#include <boost/function.hpp>
#include <boost/thread.hpp>
+#ifdef __WXGTK__
+#include <gtk/gtk.h>
+#endif
class wxFilePickerCtrl;
class wxSpinCtrl;
class wxGridBagSizer;
+#define DCPOMATIC_SIZER_X_GAP 8
+#define DCPOMATIC_SIZER_Y_GAP 8
+
/** @file src/wx/wx_util.h
* @brief Some utility functions and classes.
*/
extern void error_dialog (wxWindow *, wxString);
extern bool confirm_dialog (wxWindow *, wxString);
-extern wxStaticText* add_label_to_sizer (wxSizer *, wxWindow *, wxString, int prop = 0);
-extern wxStaticText* add_label_to_grid_bag_sizer (wxGridBagSizer *, wxWindow *, wxString, wxGBPosition, wxGBSpan span = wxDefaultSpan);
+extern wxStaticText* add_label_to_sizer (wxSizer *, wxWindow *, wxString, bool left, int prop = 0);
+extern wxStaticText* add_label_to_grid_bag_sizer (wxGridBagSizer *, wxWindow *, wxString, bool, wxGBPosition, wxGBSpan span = wxDefaultSpan);
extern std::string wx_to_std (wxString);
extern wxString std_to_wx (std::string);
extern void dcpomatic_setup_i18n ();
extern void checked_set (wxCheckBox* widget, bool value);
extern void checked_set (wxRadioButton* widget, bool value);
extern void checked_set (wxStaticText* widget, std::string value);
+
+/* GTK 2.24.17 has a buggy GtkFileChooserButton and it was put in Ubuntu 13.04.
+ Use our own dir picker as this is the least bad option I can think of.
+*/
+#if defined(__WXMSW__) || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 24 && GTK_MICRO_VERSION == 17)
+#define DCPOMATIC_USE_OWN_DIR_PICKER
+#endif
+
+#endif
#include "sndfile_decoder.h"
#include "dcp_content_type.h"
#include "ui_signaller.h"
+#include "ratio.h"
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE dcpomatic_test
#include <boost/test/unit_test.hpp>
Config::instance()->set_servers (vector<ServerDescription*> ());
Config::instance()->set_server_port (61920);
Config::instance()->set_default_dci_metadata (DCIMetadata ());
- Config::instance()->set_default_container (0);
- Config::instance()->set_default_dcp_content_type (0);
+ Config::instance()->set_default_container (static_cast<Ratio*> (0));
+ Config::instance()->set_default_dcp_content_type (static_cast<DCPContentType*> (0));
ui_signaller = new UISignaller ();
}
--- /dev/null
+/*
+ Copyright (C) 2012 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.
+
+*/
+
+using boost::shared_ptr;
+
+shared_ptr<const Image> trimmer_test_last_video;
+int trimmer_test_video_frames = 0;
+shared_ptr<const AudioBuffers> trimmer_test_last_audio;
+
+void
+trimmer_test_video_helper (shared_ptr<const Image> image, bool, shared_ptr<Subtitle>)
+{
+ trimmer_test_last_video = image;
+ ++trimmer_test_video_frames;
+}
+
+void
+trimmer_test_audio_helper (shared_ptr<const AudioBuffers> audio)
+{
+ trimmer_test_last_audio = audio;
+}
+
+BOOST_AUTO_TEST_CASE (trimmer_passthrough_test)
+{
+ Trimmer trimmer (shared_ptr<Log> (), 0, 0, 200, 48000, 25, 25);
+ trimmer.Video.connect (bind (&trimmer_test_video_helper, _1, _2, _3));
+ trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1));
+
+ shared_ptr<SimpleImage> video (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true));
+ shared_ptr<AudioBuffers> audio (new AudioBuffers (6, 42 * 1920));
+
+ trimmer.process_video (video, false, shared_ptr<Subtitle> ());
+ trimmer.process_audio (audio);
+
+ BOOST_CHECK_EQUAL (video.get(), trimmer_test_last_video.get());
+ BOOST_CHECK_EQUAL (audio.get(), trimmer_test_last_audio.get());
+ BOOST_CHECK_EQUAL (audio->frames(), trimmer_test_last_audio->frames());
+}
+
+
+/** Test the audio handling of the Trimmer */
+BOOST_AUTO_TEST_CASE (trimmer_audio_test)
+{
+ Trimmer trimmer (shared_ptr<Log> (), 25, 75, 200, 48000, 25, 25);
+
+ trimmer.Audio.connect (bind (&trimmer_test_audio_helper, _1));
+
+ /* 21 video frames-worth of audio frames; should be completely stripped */
+ trimmer_test_last_audio.reset ();
+ shared_ptr<AudioBuffers> audio (new AudioBuffers (6, 21 * 1920));
+ trimmer.process_audio (audio);
+ BOOST_CHECK (trimmer_test_last_audio == 0);
+
+ /* 42 more video frames-worth, 4 should be stripped from the start */
+ audio.reset (new AudioBuffers (6, 42 * 1920));
+ trimmer.process_audio (audio);
+ BOOST_CHECK (trimmer_test_last_audio);
+ BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 38 * 1920);
+
+ /* 42 more video frames-worth, should be kept as-is */
+ trimmer_test_last_audio.reset ();
+ audio.reset (new AudioBuffers (6, 42 * 1920));
+ trimmer.process_audio (audio);
+ BOOST_CHECK (trimmer_test_last_audio);
+ BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 42 * 1920);
+
+ /* 25 more video frames-worth, 5 should be trimmed from the end */
+ trimmer_test_last_audio.reset ();
+ audio.reset (new AudioBuffers (6, 25 * 1920));
+ trimmer.process_audio (audio);
+ BOOST_CHECK (trimmer_test_last_audio);
+ BOOST_CHECK_EQUAL (trimmer_test_last_audio->frames(), 20 * 1920);
+
+ /* Now some more; all should be trimmed */
+ trimmer_test_last_audio.reset ();
+ audio.reset (new AudioBuffers (6, 100 * 1920));
+ trimmer.process_audio (audio);
+ BOOST_CHECK (trimmer_test_last_audio == 0);
+}
+
+BOOST_AUTO_TEST_CASE (trim_end_test)
+{
+ Trimmer trimmer (shared_ptr<Log> (), 0, 75, 200, 48000, 25, 25);
+
+ shared_ptr<SimpleImage> image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (256, 256), true));
+
+ trimmer.Video.connect (bind (&trimmer_test_video_helper, _1, _2, _3));
+ trimmer_test_video_frames = 0;
+ for (int i = 0; i < 200; ++i) {
+ trimmer.process_video (image, false, shared_ptr<Subtitle> ());
+ }
+
+ BOOST_CHECK_EQUAL (trimmer_test_video_frames, 125);
+}
def build(bld):
obj = bld(features = 'cxx cxxprogram')
obj.name = 'unit-tests'
- obj.uselib = 'BOOST_TEST CXML DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC'
+ obj.uselib = 'BOOST_TEST DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC CXML'
obj.use = 'libdcpomatic'
obj.source = 'test.cc'
obj.target = 'unit-tests'
conf.env.TARGET_LINUX = not conf.env.TARGET_WINDOWS and not conf.env.TARGET_OSX
conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-D__STDC_LIMIT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing',
- '-Wall', '-Wno-attributes', '-Wextra'])
+ '-Wall', '-Wno-attributes', '-Wextra', '-D_FILE_OFFSET_BITS=64'])
if conf.env.TARGET_WINDOWS:
conf.env.append_value('CXXFLAGS', ['-DDCPOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE'])
conf.check(lib = 'bfd', uselib_store = 'BFD', msg = "Checking for library bfd")
conf.check(lib = 'dbghelp', uselib_store = 'DBGHELP', msg = "Checking for library dbghelp")
conf.check(lib = 'iberty', uselib_store = 'IBERTY', msg = "Checking for library iberty")
+ conf.check(lib = 'shlwapi', uselib_store = 'SHLWAPI', msg = "Checking for library shlwapi")
boost_lib_suffix = '-mt'
boost_thread = 'boost_thread_win32-mt'
else:
else:
# This is hackio grotesquio for static builds (ie for .deb packages). We need to link some things
# statically and some dynamically, or things get horribly confused and the dynamic linker (I think)
- # crashes horribly. These calls do what the check_cfg calls would have done, but specify the
+ # crashes. These calls do what the check_cfg calls would have done, but specify the
# different bits as static or dynamic as required. It'll break if you look at it funny, but
# I think anyone else who builds would do so dynamically.
+ conf.env.HAVE_CXML = 1
+ conf.env.STLIB_CXML = ['cxml']
conf.env.HAVE_DCP = 1
conf.env.STLIB_DCP = ['dcp', 'asdcp-libdcp', 'kumu-libdcp']
conf.env.LIB_DCP = ['glibmm-2.4', 'xml++-2.6', 'ssl', 'crypto', 'bz2']
conf.env.HAVE_CXML = 1
conf.env.STLIB_CXML = ['cxml']
- conf.check_cfg(package = 'libxml++-2.6', args = '--cflags --libs', uselib_store = 'XML++', mandatory = True)
+ conf.check_cfg(package='libxml++-2.6', args='--cflags --libs', uselib_store='XML++', mandatory=True)
conf.env.HAVE_AVFORMAT = 1
conf.env.STLIB_AVFORMAT = ['avformat']
conf.env.HAVE_AVFILTER = 1
if conf.env.TARGET_LINUX:
conf.check_cfg(package='liblzma', args='--cflags --libs', uselib_store='LZMA', mandatory=True)
+ if conf.env.STATIC:
+ conf.check_cfg(package='gtk+-2.0', args='--cflags --libs', uselib_store='GTK', mandatory=True)
+ else:
+ # On Linux we need to be able to include <gtk/gtk.h> to check GTK's version
+ conf.check_cfg(package='gtk+-2.0', args='--cflags', uselib_store='GTK', mandatory=True)
conf.check_cfg(package = '', path = conf.options.magickpp_config, args = '--cppflags --cxxflags --libs', uselib_store = 'MAGICK', mandatory = True)
conf.recurse('test')
def build(bld):
- create_version_cc(VERSION)
+ create_version_cc(VERSION, bld.env.CXXFLAGS)
bld.recurse('src')
bld.recurse('test')
GRSYMS GRTAGS GSYMS GTAGS
"""
-def create_version_cc(version):
+def create_version_cc(version, cxx_flags):
if os.path.exists('.git'):
cmd = "LANG= git log --abbrev HEAD^..HEAD ."
output = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0].splitlines()
text = '#include "version.h"\n'
text += 'char const * dcpomatic_git_commit = \"%s\";\n' % commit
text += 'char const * dcpomatic_version = \"%s\";\n' % version
+
+ t = ''
+ for f in cxx_flags:
+ f = f.replace('"', '\\"')
+ t += f + ' '
+ text += 'char const * dcpomatic_cxx_flags = \"%s\";\n' % t[:-1]
+
print('Writing version information to src/lib/version.cc')
o = open('src/lib/version.cc', 'w')
o.write(text)