Merge branch 'main' into v2.17.x
authorCarl Hetherington <cth@carlh.net>
Thu, 16 May 2024 12:59:50 +0000 (14:59 +0200)
committerCarl Hetherington <cth@carlh.net>
Thu, 16 May 2024 12:59:50 +0000 (14:59 +0200)
1  2 
cscript
run/environment
run/tests
src/lib/dcp_film_encoder.cc
src/lib/ffmpeg_decoder.cc
src/lib/player.cc
src/lib/player.h
src/lib/util.cc
src/wx/video_panel.cc
wscript

diff --cc cscript
index 67c73453b62194f465a7146cad6f82ab59c52d35,eb2c8e4364ceb19287eca839beabc46f732d4b81..6f7399f55403bfcdddf7cddcee14adc56eeb9384
+++ b/cscript
@@@ -533,7 -523,19 +533,7 @@@ def make_spec(filename, version, target
      print('/usr/bin/gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :', file=f)
  
  def dependencies(target, options):
-     deps = [('libdcp', '9b9af8a80860210c6a29446f7a24795eeda9e7bc', {'c++17': target.platform == 'osx'})]
 -
 -    if target.platform == 'linux':
 -        ffmpeg_options = { 'shared': False }
 -    else:
 -        ffmpeg_options = {}
 -
 -    if target.platform != 'linux' or target.distro != 'arch':
 -        deps = [('ffmpeg', '7276e269a93c2ae30e302c34708e8095ac5475e8', ffmpeg_options)]
 -    else:
 -        # Use distro-provided FFmpeg on Arch
 -        deps = []
 -
 -    deps.append(('libdcp', 'v1.8.100'))
++    deps = [('libdcp', 'v1.9.7', {'c++17': target.platform == 'osx'})]
      deps.append(('libsub', 'v1.6.47'))
      deps.append(('leqm-nrt', '30dcaea1373ac62fba050e02ce5b0c1085797a23'))
      deps.append(('rtaudio', 'f619b76'))
diff --cc run/environment
Simple merge
diff --cc run/tests
index f0a764e4a7877b3a4a47bd0c9d5d5797fddc2c57,5db647af48f6faf136e7285bd626951d0f8fc9b7..eb8b8f122cf22a960c0950dea7f2620f4028e606
+++ b/run/tests
@@@ -5,33 -5,70 +5,73 @@@ set -
  
  PRIVATE_GIT="881c48805e352dfe150993814757ca974282be18"
  
- if [ "$1" == "--check" ]; then
-     shift 1
-     check=1
- else
-     check=0
- fi
 +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
 +source $DIR/environment
 +
+ type=""
+ check=0
+ while [[ $# -gt 0 ]]; do
+     case $1 in
+         -e)
+         environment=$2
+         shift
+         shift
+         ;;
+         --debug)
+         type="debug"
+         shift
+         ;;
+         --backtrace)
+         type="backtrace"
+         shift
+         ;;
+         --valgrind)
+         type="valgrind"
+         shift
+         ;;
+         --callgrind)
+         type="callgrind"
+         shift
+         ;;
+         --quiet)
+         type="quiet"
+         shift
+         ;;
+         --drd)
+         type="drd"
+         shift
+         ;;
+         --helgrind)
+         type="helgrind"
+         shift
+         ;;
+         --check)
+         check=1
+         shift
+         ;;
+         *)
+         break
+         ;;
+     esac
+ done
  
  if [ "$(uname)" == "Linux" ]; then 
 -  export LD_LIBRARY_PATH=build/src/lib:/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH
 -  rm -f build/test/dcpomatic2_openssl
 -  # This must be our patched openssl or tests will fail
 -  if [ ! -f build/test/dcpomatic2_openssl ]; then 
 -    ln -s ../../../openssl/apps/openssl build/test/dcpomatic2_openssl
 -  fi
 -  export DCPOMATIC_TEST_TOOLS_PATH=/opt/asdcplib/bin
 -  if [ -f /src/backports/dcp_inspect ]; then
 -    export DCPOMATIC_DCP_INSPECT=/src/backports/dcp_inspect
 -  fi
 -  set +e
 -  python3 -m clairmeta.cli --help > /dev/null 2>&1
 -  if [ "$?" == "0" ]; then
 -    export DCPOMATIC_CLAIRMETA=1
 -  fi
 -  set -e
 +    rm -f build/test/dcpomatic2_openssl
 +    mkdir -p build/test
 +    # This must be our patched openssl or tests will fail
 +    if [ ! -f build/test/dcpomatic2_openssl ]; then
 +        ln -s ../../../openssl/apps/openssl build/test/dcpomatic2_openssl
 +    fi
 +    export DCPOMATIC_TEST_TOOLS_PATH=/opt/asdcplib/bin
 +    if [ -f /src/backports/dcp_inspect ]; then
 +        export DCPOMATIC_DCP_INSPECT=/src/backports/dcp_inspect
 +    fi
 +    set +e
 +    python3 -m clairmeta.cli --help > /dev/null 2>&1
 +    if [ "$?" == "0" ]; then
 +        export DCPOMATIC_CLAIRMETA=1
 +    fi
 +    set -e
  fi
  
  if [ "$(uname)" == "Darwin" ]; then
  fi
  
  if [ "$check" == "1" ]; then
 -      if [ "$DCPOMATIC_TEST_PRIVATE" == "" ]; then
 -              pushd ../dcpomatic-test-private
 -      else
 -              pushd $DCPOMATIC_TEST_PRIVATE
 -      fi
 -      current=$(git rev-parse HEAD)
 -      if [ "$current" != "$PRIVATE_GIT" ]; then
 -              echo "Unexpected dcpomatic-test-private version"
 -              exit 1
 -      fi
 -      popd
 +    if [ "$DCPOMATIC_TEST_PRIVATE" == "" ]; then
 +        pushd ../dcpomatic-test-private
 +    else
 +        pushd $DCPOMATIC_TEST_PRIVATE
 +    fi
 +    current=$(git rev-parse HEAD)
 +    if [ "$current" != "$PRIVATE_GIT" ]; then
 +        echo "Unexpected dcpomatic-test-private version"
 +        exit 1
 +    fi
 +    popd
  fi
  
- if [ "$1" == "--debug" ]; then
-     shift;
+ if [ "$type" == "debug" ]; then
      gdb --args build/test/unit-tests --catch_system_errors=no --log_level=test_suite $*
- elif [ "$1" == "--backtrace" ]; then
-     shift;
+ elif [ "$type" == "backtrace" ]; then
      gdb -batch -ex "run" -ex "thread apply all bt" -return-child-result --args build/test/unit-tests --catch_system_errors=yes $*
- elif [ "$1" == "--valgrind" ]; then
-     shift;
+ elif [ "$type" == "valgrind" ]; then
  #    valgrind --tool="memcheck" --vgdb=yes --vgdb-error=0 build/test/unit-tests $*
      valgrind --tool="memcheck" --suppressions=suppressions build/test/unit-tests $*
- elif [ "$1" == "--callgrind" ]; then
-     shift;
+ elif [ "$type" == "callgrind" ]; then
      valgrind --tool="callgrind" build/test/unit-tests $*
- elif [ "$1" == "--quiet" ]; then
-     shift;
+ elif [ "$type" == "quiet" ]; then
      build/test/unit-tests --catch_system_errors=no $*
- elif [ "$1" == "--drd" ]; then
-     shift;
+ elif [ "$type" == "drd" ]; then
      valgrind --tool="drd" build/test/unit-tests $*
- elif [ "$1" == "--helgrind" ]; then
-     shift;
+ elif [ "$type" == "helgrind" ]; then
      valgrind --tool="helgrind" build/test/unit-tests $*
  else
      ulimit -c unlimited
index 878ef3c6f63f7fe98e0d9cecadf0995999a16631,0000000000000000000000000000000000000000..83da57756b65de252b5b2228a5b514612fc6e271
mode 100644,000000..100644
--- /dev/null
@@@ -1,194 -1,0 +1,197 @@@
-       while (!_player.pass()) {}
 +/*
 +    Copyright (C) 2012-2020 Carl Hetherington <cth@carlh.net>
 +
 +    This file is part of DCP-o-matic.
 +
 +    DCP-o-matic 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.
 +
 +    DCP-o-matic 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 DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
 +
 +*/
 +
 +
 +/** @file  src/dcp_film_encoder.cc
 + *  @brief A class which takes a Film and some Options, then uses those to encode the film into a DCP.
 + *
 + *  A decoder is selected according to the content type, and the encoder can be specified
 + *  as a parameter to the constructor.
 + */
 +
 +
 +#include "audio_decoder.h"
 +#include "compose.hpp"
 +#include "dcp_film_encoder.h"
 +#include "film.h"
 +#include "j2k_encoder.h"
 +#include "job.h"
 +#include "mpeg2_encoder.h"
 +#include "player.h"
 +#include "player_video.h"
 +#include "referenced_reel_asset.h"
 +#include "text_content.h"
 +#include "video_decoder.h"
 +#include "writer.h"
 +#include <boost/signals2.hpp>
 +#include <iostream>
 +
 +#include "i18n.h"
 +
 +
 +using std::cout;
 +using std::dynamic_pointer_cast;
 +using std::list;
 +using std::make_shared;
 +using std::shared_ptr;
 +using std::string;
 +using std::vector;
 +using std::weak_ptr;
 +using boost::optional;
 +#if BOOST_VERSION >= 106100
 +using namespace boost::placeholders;
 +#endif
 +using namespace dcpomatic;
 +
 +
 +/** Construct a DCP encoder.
 + *  @param film Film that we are encoding.
 + *  @param job Job that this encoder is being used in.
 + */
 +DCPFilmEncoder::DCPFilmEncoder(shared_ptr<const Film> film, weak_ptr<Job> job)
 +      : FilmEncoder(film, job)
 +      , _writer(film, job, film->dir(film->dcp_name()))
 +      , _finishing (false)
 +      , _non_burnt_subtitles (false)
 +{
 +      switch (_film->video_encoding()) {
 +      case VideoEncoding::JPEG2000:
 +              _encoder.reset(new J2KEncoder(film, _writer));
 +              break;
 +      case VideoEncoding::MPEG2:
 +              _encoder.reset(new MPEG2Encoder(film, _writer));
 +              break;
 +      case VideoEncoding::COUNT:
 +              DCPOMATIC_ASSERT(false);
 +      }
 +
 +      /* Now that we have a Writer we can clear out the assets directory */
 +      clean_up_asset_directory(film->assets_path());
 +
 +      _player_video_connection = _player.Video.connect(bind(&DCPFilmEncoder::video, this, _1, _2));
 +      _player_audio_connection = _player.Audio.connect(bind(&DCPFilmEncoder::audio, this, _1, _2));
 +      _player_text_connection = _player.Text.connect(bind(&DCPFilmEncoder::text, this, _1, _2, _3, _4));
 +      _player_atmos_connection = _player.Atmos.connect(bind(&DCPFilmEncoder::atmos, this, _1, _2, _3));
 +
 +      for (auto c: film->content ()) {
 +              for (auto i: c->text) {
 +                      if (i->use() && !i->burn()) {
 +                              _non_burnt_subtitles = true;
 +                      }
 +              }
 +      }
 +}
 +
 +DCPFilmEncoder::~DCPFilmEncoder()
 +{
 +      /* We must stop receiving more video data before we die */
 +      _player_video_connection.release ();
 +      _player_audio_connection.release ();
 +      _player_text_connection.release ();
 +      _player_atmos_connection.release ();
 +}
 +
 +void
 +DCPFilmEncoder::go()
 +{
 +      _writer.start();
 +      _encoder->begin();
 +
 +      {
 +              auto job = _job.lock ();
 +              DCPOMATIC_ASSERT (job);
 +              job->sub (_("Encoding"));
 +      }
 +
 +      if (_non_burnt_subtitles) {
 +              _writer.write(_player.get_subtitle_fonts());
 +      }
 +
-       auto job = _job.lock ();
-       DCPOMATIC_ASSERT (job);
-       job->set_progress (float(time.get()) / _film->length().get());
++      int passes = 0;
++      while (!_player.pass()) {
++              if ((++passes % 8) == 0) {
++                      auto job = _job.lock();
++                      DCPOMATIC_ASSERT(job);
++                      job->set_progress(_player.progress());
++              }
++      }
 +
 +      for (auto i: get_referenced_reel_assets(_film, _film->playlist())) {
 +              _writer.write(i);
 +      }
 +
 +      _finishing = true;
 +      _encoder->end();
 +      _writer.finish();
 +}
 +
 +
 +void
 +DCPFilmEncoder::pause()
 +{
 +      _encoder->pause();
 +}
 +
 +
 +void
 +DCPFilmEncoder::resume()
 +{
 +      _encoder->resume();
 +}
 +
 +void
 +DCPFilmEncoder::video(shared_ptr<PlayerVideo> data, DCPTime time)
 +{
 +      _encoder->encode(data, time);
 +}
 +
 +void
 +DCPFilmEncoder::audio(shared_ptr<AudioBuffers> data, DCPTime time)
 +{
 +      _writer.write(data, time);
-       return _encoder->video_frames_enqueued();
 +}
 +
 +void
 +DCPFilmEncoder::text(PlayerText data, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
 +{
 +      if (type == TextType::CLOSED_CAPTION || _non_burnt_subtitles) {
 +              _writer.write(data, type, track, period);
 +      }
 +}
 +
 +
 +void
 +DCPFilmEncoder::atmos(shared_ptr<const dcp::AtmosFrame> data, DCPTime time, AtmosMetadata metadata)
 +{
 +      _writer.write(data, time, metadata);
 +}
 +
 +
 +optional<float>
 +DCPFilmEncoder::current_rate() const
 +{
 +      return _encoder->current_encoding_rate();
 +}
 +
 +Frame
 +DCPFilmEncoder::frames_done() const
 +{
++      return _player.frames_done();
 +}
Simple merge
Simple merge
index 2502ae536b844a56d5e036cbe540477c64f1be27,48f6f97ca2b6a542cb9d5b39afcde5a657527058..314031698a387e4a18190a61c93369e7cb0e5229
@@@ -155,8 -157,7 +157,9 @@@ private
        dcpomatic::ContentTime dcp_to_content_time (std::shared_ptr<const Piece> piece, dcpomatic::DCPTime t) const;
        dcpomatic::DCPTime content_time_to_dcp (std::shared_ptr<const Piece> piece, dcpomatic::ContentTime t) const;
        std::shared_ptr<PlayerVideo> black_player_video_frame (Eyes eyes) const;
 +      void emit_video_until(dcpomatic::DCPTime time);
 +      void insert_video(std::shared_ptr<PlayerVideo> pv, dcpomatic::DCPTime time, dcpomatic::DCPTime end);
+       std::pair<std::shared_ptr<Piece>, boost::optional<dcpomatic::DCPTime>> earliest_piece_and_time() const;
  
        void video (std::weak_ptr<Piece>, ContentVideo);
        void audio (std::weak_ptr<Piece>, AudioStreamPtr, ContentAudio);
diff --cc src/lib/util.cc
Simple merge
Simple merge
diff --cc wscript
Simple merge