#include "image.h"
#include "j2k_image_proxy.h"
#include "text_decoder.h"
+#include "util.h"
#include "video_decoder.h"
#include <dcp/cpl.h>
#include <dcp/dcp.h>
+++ /dev/null
-/*
- 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_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_encoder.h"
-#include "film.h"
-#include "j2k_encoder.h"
-#include "job.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.
- */
-DCPEncoder::DCPEncoder (shared_ptr<const Film> film, weak_ptr<Job> job)
- : Encoder (film, job)
- , _writer(film, job)
- , _j2k_encoder(film, _writer)
- , _finishing (false)
- , _non_burnt_subtitles (false)
-{
- _player_video_connection = _player.Video.connect(bind(&DCPEncoder::video, this, _1, _2));
- _player_audio_connection = _player.Audio.connect(bind(&DCPEncoder::audio, this, _1, _2));
- _player_text_connection = _player.Text.connect(bind(&DCPEncoder::text, this, _1, _2, _3, _4));
- _player_atmos_connection = _player.Atmos.connect(bind(&DCPEncoder::atmos, this, _1, _2, _3));
-
- for (auto c: film->content ()) {
- for (auto i: c->text) {
- if (i->use() && !i->burn()) {
- _non_burnt_subtitles = true;
- }
- }
- }
-}
-
-DCPEncoder::~DCPEncoder ()
-{
- /* 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
-DCPEncoder::go ()
-{
- _writer.start();
- _j2k_encoder.begin();
-
- {
- auto job = _job.lock ();
- DCPOMATIC_ASSERT (job);
- job->sub (_("Encoding"));
- }
-
- if (_non_burnt_subtitles) {
- _writer.write(_player.get_subtitle_fonts());
- }
-
- while (!_player.pass()) {}
-
- for (auto i: get_referenced_reel_assets(_film, _film->playlist())) {
- _writer.write(i);
- }
-
- _finishing = true;
- _j2k_encoder.end();
- _writer.finish(_film->dir(_film->dcp_name()));
-}
-
-
-void
-DCPEncoder::pause()
-{
- _j2k_encoder.pause();
-}
-
-
-void
-DCPEncoder::resume()
-{
- _j2k_encoder.resume();
-}
-
-void
-DCPEncoder::video (shared_ptr<PlayerVideo> data, DCPTime time)
-{
- _j2k_encoder.encode(data, time);
-}
-
-void
-DCPEncoder::audio (shared_ptr<AudioBuffers> data, DCPTime time)
-{
- _writer.write(data, time);
-
- auto job = _job.lock ();
- DCPOMATIC_ASSERT (job);
- job->set_progress (float(time.get()) / _film->length().get());
-}
-
-void
-DCPEncoder::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
-DCPEncoder::atmos (shared_ptr<const dcp::AtmosFrame> data, DCPTime time, AtmosMetadata metadata)
-{
- _writer.write(data, time, metadata);
-}
-
-
-optional<float>
-DCPEncoder::current_rate () const
-{
- return _j2k_encoder.current_encoding_rate();
-}
-
-Frame
-DCPEncoder::frames_done () const
-{
- return _j2k_encoder.video_frames_enqueued();
-}
+++ /dev/null
-/*
- 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/>.
-
-*/
-
-
-#include "atmos_metadata.h"
-#include "dcp_text_track.h"
-#include "dcpomatic_time.h"
-#include "encoder.h"
-#include "player_text.h"
-#include "j2k_encoder.h"
-#include "writer.h"
-#include <dcp/atmos_frame.h>
-
-
-class AudioBuffers;
-class Film;
-class Job;
-class Player;
-class PlayerVideo;
-
-struct frames_not_lost_when_threads_disappear;
-
-
-/** @class DCPEncoder */
-class DCPEncoder : public Encoder
-{
-public:
- DCPEncoder (std::shared_ptr<const Film> film, std::weak_ptr<Job> job);
- ~DCPEncoder ();
-
- void go () override;
-
- boost::optional<float> current_rate () const override;
- Frame frames_done () const override;
-
- /** @return true if we are in the process of calling Encoder::process_end */
- bool finishing () const override {
- return _finishing;
- }
-
- void pause() override;
- void resume() override;
-
-private:
-
- friend struct ::frames_not_lost_when_threads_disappear;
-
- void video (std::shared_ptr<PlayerVideo>, dcpomatic::DCPTime);
- void audio (std::shared_ptr<AudioBuffers>, dcpomatic::DCPTime);
- void text (PlayerText, TextType, boost::optional<DCPTextTrack>, dcpomatic::DCPTimePeriod);
- void atmos (std::shared_ptr<const dcp::AtmosFrame>, dcpomatic::DCPTime, AtmosMetadata metadata);
-
- Writer _writer;
- J2KEncoder _j2k_encoder;
- bool _finishing;
- bool _non_burnt_subtitles;
-
- boost::signals2::scoped_connection _player_video_connection;
- boost::signals2::scoped_connection _player_audio_connection;
- boost::signals2::scoped_connection _player_text_connection;
- boost::signals2::scoped_connection _player_atmos_connection;
-};
--- /dev/null
+/*
+ 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 "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)
+ , _j2k_encoder(film, _writer)
+ , _finishing (false)
+ , _non_burnt_subtitles (false)
+{
+ _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();
+ _j2k_encoder.begin();
+
+ {
+ auto job = _job.lock ();
+ DCPOMATIC_ASSERT (job);
+ job->sub (_("Encoding"));
+ }
+
+ if (_non_burnt_subtitles) {
+ _writer.write(_player.get_subtitle_fonts());
+ }
+
+ while (!_player.pass()) {}
+
+ for (auto i: get_referenced_reel_assets(_film, _film->playlist())) {
+ _writer.write(i);
+ }
+
+ _finishing = true;
+ _j2k_encoder.end();
+ _writer.finish(_film->dir(_film->dcp_name()));
+}
+
+
+void
+DCPFilmEncoder::pause()
+{
+ _j2k_encoder.pause();
+}
+
+
+void
+DCPFilmEncoder::resume()
+{
+ _j2k_encoder.resume();
+}
+
+void
+DCPFilmEncoder::video(shared_ptr<PlayerVideo> data, DCPTime time)
+{
+ _j2k_encoder.encode(data, time);
+}
+
+void
+DCPFilmEncoder::audio(shared_ptr<AudioBuffers> data, DCPTime time)
+{
+ _writer.write(data, time);
+
+ auto job = _job.lock ();
+ DCPOMATIC_ASSERT (job);
+ job->set_progress (float(time.get()) / _film->length().get());
+}
+
+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 _j2k_encoder.current_encoding_rate();
+}
+
+Frame
+DCPFilmEncoder::frames_done() const
+{
+ return _j2k_encoder.video_frames_enqueued();
+}
--- /dev/null
+/*
+ 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/>.
+
+*/
+
+
+#include "atmos_metadata.h"
+#include "dcp_text_track.h"
+#include "dcpomatic_time.h"
+#include "film_encoder.h"
+#include "player_text.h"
+#include "j2k_encoder.h"
+#include "writer.h"
+#include <dcp/atmos_frame.h>
+
+
+class AudioBuffers;
+class Film;
+class Job;
+class Player;
+class PlayerVideo;
+
+struct frames_not_lost_when_threads_disappear;
+
+
+/** @class DCPFilmEncoder */
+class DCPFilmEncoder : public FilmEncoder
+{
+public:
+ DCPFilmEncoder(std::shared_ptr<const Film> film, std::weak_ptr<Job> job);
+ ~DCPFilmEncoder();
+
+ void go () override;
+
+ boost::optional<float> current_rate () const override;
+ Frame frames_done () const override;
+
+ /** @return true if we are in the process of calling Encoder::process_end */
+ bool finishing () const override {
+ return _finishing;
+ }
+
+ void pause() override;
+ void resume() override;
+
+private:
+
+ friend struct ::frames_not_lost_when_threads_disappear;
+
+ void video (std::shared_ptr<PlayerVideo>, dcpomatic::DCPTime);
+ void audio (std::shared_ptr<AudioBuffers>, dcpomatic::DCPTime);
+ void text (PlayerText, TextType, boost::optional<DCPTextTrack>, dcpomatic::DCPTimePeriod);
+ void atmos (std::shared_ptr<const dcp::AtmosFrame>, dcpomatic::DCPTime, AtmosMetadata metadata);
+
+ Writer _writer;
+ J2KEncoder _j2k_encoder;
+ bool _finishing;
+ bool _non_burnt_subtitles;
+
+ boost::signals2::scoped_connection _player_video_connection;
+ boost::signals2::scoped_connection _player_audio_connection;
+ boost::signals2::scoped_connection _player_text_connection;
+ boost::signals2::scoped_connection _player_atmos_connection;
+};
#include "image.h"
#include "log.h"
#include "player_video.h"
+#include "util.h"
#include "variant.h"
#include "version.h"
#include <dcp/raw_convert.h>
#include "encode_server_description.h"
#include "encode_server_finder.h"
#include "exceptions.h"
+#include "util.h"
#include "variant.h"
#include <dcp/raw_convert.h>
#include <libcxml/cxml.h>
+++ /dev/null
-/*
- Copyright (C) 2012-2017 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/encoder.cc
- * @brief A class which takes a Film and some Options, then uses those to encode the film
- * into some output format.
- *
- * A decoder is selected according to the content type, and the encoder can be specified
- * as a parameter to the constructor.
- */
-
-
-#include "encoder.h"
-#include "player.h"
-
-#include "i18n.h"
-
-
-/** Construct an encoder.
- * @param film Film that we are encoding.
- * @param job Job that this encoder is being used in.
- */
-Encoder::Encoder (std::shared_ptr<const Film> film, std::weak_ptr<Job> job)
- : _film (film)
- , _job (job)
- , _player(film, Image::Alignment::PADDED)
-{
-
-}
+++ /dev/null
-/*
- Copyright (C) 2012-2021 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/>.
-
-*/
-
-
-#ifndef DCPOMATIC_ENCODER_H
-#define DCPOMATIC_ENCODER_H
-
-
-#include "player.h"
-#include "player_text.h"
-#include <boost/signals2.hpp>
-
-
-class Film;
-class Encoder;
-class Player;
-class Job;
-class PlayerVideo;
-class AudioBuffers;
-
-
-/** @class Encoder
- * @brief Parent class for something that can encode a film into some format
- */
-class Encoder
-{
-public:
- Encoder (std::shared_ptr<const Film> film, std::weak_ptr<Job> job);
- virtual ~Encoder () {}
-
- Encoder (Encoder const&) = delete;
- Encoder& operator= (Encoder const&) = delete;
-
- virtual void go () = 0;
-
- /** @return the current frame rate over the last short while */
- virtual boost::optional<float> current_rate () const {
- return {};
- }
-
- /** @return the number of frames that are done */
- virtual Frame frames_done () const = 0;
- virtual bool finishing () const = 0;
- virtual void pause() {}
- virtual void resume() {}
-
-protected:
- std::shared_ptr<const Film> _film;
- std::weak_ptr<Job> _job;
- Player _player;
-};
-
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2017-2018 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/>.
-
-*/
-
-
-#include "butler.h"
-#include "cross.h"
-#include "ffmpeg_encoder.h"
-#include "film.h"
-#include "image.h"
-#include "job.h"
-#include "log.h"
-#include "player.h"
-#include "player_video.h"
-#include "compose.hpp"
-#include <iostream>
-
-#include "i18n.h"
-
-
-using std::cout;
-using std::list;
-using std::make_shared;
-using std::shared_ptr;
-using std::string;
-using std::weak_ptr;
-using boost::bind;
-using boost::optional;
-using namespace dcpomatic;
-#if BOOST_VERSION >= 106100
-using namespace boost::placeholders;
-#endif
-
-
-FFmpegEncoder::FFmpegEncoder (
- shared_ptr<const Film> film,
- weak_ptr<Job> job,
- boost::filesystem::path output,
- ExportFormat format,
- bool mixdown_to_stereo,
- bool split_reels,
- bool audio_stream_per_channel,
- int x264_crf
- )
- : Encoder (film, job)
- , _output_audio_channels(mixdown_to_stereo ? 2 : (_film->audio_channels() > 8 ? 16 : _film->audio_channels()))
- , _history (200)
- , _output (output)
- , _format (format)
- , _split_reels (split_reels)
- , _audio_stream_per_channel (audio_stream_per_channel)
- , _x264_crf (x264_crf)
- , _butler(
- _film,
- _player,
- mixdown_to_stereo ? stereo_map() : many_channel_map(),
- _output_audio_channels,
- boost::bind(&PlayerVideo::force, FFmpegFileEncoder::pixel_format(format)),
- VideoRange::VIDEO,
- Image::Alignment::PADDED,
- false,
- false,
- Butler::Audio::ENABLED
- )
-{
- _player.set_always_burn_open_subtitles();
- _player.set_play_referenced();
-}
-
-
-AudioMapping
-FFmpegEncoder::stereo_map() const
-{
- auto map = AudioMapping(_film->audio_channels(), 2);
- float const overall_gain = 2 / (4 + sqrt(2));
- float const minus_3dB = 1 / sqrt(2);
- switch (_film->audio_channels()) {
- case 2:
- map.set(dcp::Channel::LEFT, 0, 1);
- map.set(dcp::Channel::RIGHT, 1, 1);
- break;
- case 4:
- map.set(dcp::Channel::LEFT, 0, overall_gain);
- map.set(dcp::Channel::RIGHT, 1, overall_gain);
- map.set(dcp::Channel::CENTRE, 0, overall_gain * minus_3dB);
- map.set(dcp::Channel::CENTRE, 1, overall_gain * minus_3dB);
- map.set(dcp::Channel::LS, 0, overall_gain);
- break;
- case 6:
- map.set(dcp::Channel::LEFT, 0, overall_gain);
- map.set(dcp::Channel::RIGHT, 1, overall_gain);
- map.set(dcp::Channel::CENTRE, 0, overall_gain * minus_3dB);
- map.set(dcp::Channel::CENTRE, 1, overall_gain * minus_3dB);
- map.set(dcp::Channel::LS, 0, overall_gain);
- map.set(dcp::Channel::RS, 1, overall_gain);
- break;
- }
- /* XXX: maybe we should do something better for >6 channel DCPs */
- return map;
-}
-
-
-AudioMapping
-FFmpegEncoder::many_channel_map() const
-{
- auto map = AudioMapping(_film->audio_channels(), _output_audio_channels);
- for (int i = 0; i < _film->audio_channels(); ++i) {
- map.set(i, i, 1);
- }
- return map;
-}
-
-
-void
-FFmpegEncoder::go ()
-{
- {
- auto job = _job.lock ();
- DCPOMATIC_ASSERT (job);
- job->sub (_("Encoding"));
- }
-
- Waker waker;
-
- list<FileEncoderSet> file_encoders;
-
- int const files = _split_reels ? _film->reels().size() : 1;
- for (int i = 0; i < files; ++i) {
-
- boost::filesystem::path filename = _output;
- auto extension = dcp::filesystem::extension(filename);
- filename = dcp::filesystem::change_extension(filename, "");
-
- if (files > 1) {
- /// TRANSLATORS: _reel%1 here is to be added to an export filename to indicate
- /// which reel it is. Preserve the %1; it will be replaced with the reel number.
- filename = filename.string() + String::compose(_("_reel%1"), i + 1);
- }
-
- file_encoders.push_back (
- FileEncoderSet (
- _film->frame_size(),
- _film->video_frame_rate(),
- _film->audio_frame_rate(),
- _output_audio_channels,
- _format,
- _audio_stream_per_channel,
- _x264_crf,
- _film->three_d(),
- filename,
- extension
- )
- );
- }
-
- auto reel_periods = _film->reels ();
- auto reel = reel_periods.begin ();
- auto encoder = file_encoders.begin ();
-
- auto const video_frame = DCPTime::from_frames (1, _film->video_frame_rate ());
- int const audio_frames = video_frame.frames_round(_film->audio_frame_rate());
- std::vector<float> interleaved(_output_audio_channels * audio_frames);
- auto deinterleaved = make_shared<AudioBuffers>(_output_audio_channels, audio_frames);
- int const gets_per_frame = _film->three_d() ? 2 : 1;
- for (DCPTime time; time < _film->length(); time += video_frame) {
-
- if (file_encoders.size() > 1 && !reel->contains(time)) {
- /* Next reel and file */
- ++reel;
- ++encoder;
- DCPOMATIC_ASSERT (reel != reel_periods.end());
- DCPOMATIC_ASSERT (encoder != file_encoders.end());
- }
-
- for (int j = 0; j < gets_per_frame; ++j) {
- Butler::Error e;
- auto video = _butler.get_video(Butler::Behaviour::BLOCKING, &e);
- _butler.rethrow();
- if (video.first) {
- auto fe = encoder->get(video.first->eyes());
- if (fe) {
- fe->video(video.first, video.second - reel->from);
- }
- } else {
- if (e.code != Butler::Error::Code::FINISHED) {
- throw DecodeError(String::compose("Error during decoding: %1", e.summary()));
- }
- }
- }
-
- _history.event ();
-
- {
- boost::mutex::scoped_lock lm (_mutex);
- _last_time = time;
- }
-
- auto job = _job.lock ();
- if (job) {
- job->set_progress(float(time.get()) / _film->length().get());
- }
-
- waker.nudge ();
-
- _butler.get_audio(Butler::Behaviour::BLOCKING, interleaved.data(), audio_frames);
- /* XXX: inefficient; butler interleaves and we deinterleave again */
- float* p = interleaved.data();
- for (int j = 0; j < audio_frames; ++j) {
- for (int k = 0; k < _output_audio_channels; ++k) {
- deinterleaved->data(k)[j] = *p++;
- }
- }
- encoder->audio (deinterleaved);
- }
-
- for (auto i: file_encoders) {
- i.flush ();
- }
-}
-
-optional<float>
-FFmpegEncoder::current_rate () const
-{
- return _history.rate ();
-}
-
-Frame
-FFmpegEncoder::frames_done () const
-{
- boost::mutex::scoped_lock lm (_mutex);
- return _last_time.frames_round (_film->video_frame_rate ());
-}
-
-FFmpegEncoder::FileEncoderSet::FileEncoderSet (
- dcp::Size video_frame_size,
- int video_frame_rate,
- int audio_frame_rate,
- int channels,
- ExportFormat format,
- bool audio_stream_per_channel,
- int x264_crf,
- bool three_d,
- boost::filesystem::path output,
- string extension
- )
-{
- if (three_d) {
- _encoders[Eyes::LEFT] = make_shared<FFmpegFileEncoder>(
- video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
- // TRANSLATORS: L here is an abbreviation for "left", to indicate the left-eye part of a 3D export
- audio_stream_per_channel, x264_crf, String::compose("%1_%2%3", output.string(), _("L"), extension)
- );
- _encoders[Eyes::RIGHT] = make_shared<FFmpegFileEncoder>(
- video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
- // TRANSLATORS: R here is an abbreviation for "right", to indicate the right-eye part of a 3D export
- audio_stream_per_channel, x264_crf, String::compose("%1_%2%3", output.string(), _("R"), extension)
- );
- } else {
- _encoders[Eyes::BOTH] = make_shared<FFmpegFileEncoder>(
- video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
- audio_stream_per_channel, x264_crf, String::compose("%1%2", output.string(), extension)
- );
- }
-}
-
-shared_ptr<FFmpegFileEncoder>
-FFmpegEncoder::FileEncoderSet::get (Eyes eyes) const
-{
- if (_encoders.size() == 1) {
- /* We are doing a 2D export... */
- if (eyes == Eyes::LEFT) {
- /* ...but we got some 3D data; put the left eye into the output... */
- eyes = Eyes::BOTH;
- } else if (eyes == Eyes::RIGHT) {
- /* ...and ignore the right eye.*/
- return {};
- }
- }
-
- auto i = _encoders.find (eyes);
- DCPOMATIC_ASSERT (i != _encoders.end());
- return i->second;
-}
-
-void
-FFmpegEncoder::FileEncoderSet::flush ()
-{
- for (auto& i: _encoders) {
- i.second->flush ();
- }
-}
-
-void
-FFmpegEncoder::FileEncoderSet::audio (shared_ptr<AudioBuffers> a)
-{
- for (auto& i: _encoders) {
- i.second->audio (a);
- }
-}
+++ /dev/null
-/*
- Copyright (C) 2017-2018 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/>.
-
-*/
-
-#ifndef DCPOMATIC_FFMPEG_ENCODER_H
-#define DCPOMATIC_FFMPEG_ENCODER_H
-
-#include "audio_mapping.h"
-#include "butler.h"
-#include "encoder.h"
-#include "event_history.h"
-#include "ffmpeg_file_encoder.h"
-
-
-class FFmpegEncoder : public Encoder
-{
-public:
- FFmpegEncoder (
- std::shared_ptr<const Film> film,
- std::weak_ptr<Job> job,
- boost::filesystem::path output,
- ExportFormat format,
- bool mixdown_to_stereo,
- bool split_reels,
- bool audio_stream_per_channel,
- int x264_crf
- );
-
- void go () override;
-
- boost::optional<float> current_rate () const override;
- Frame frames_done () const override;
- bool finishing () const override {
- return false;
- }
-
-private:
-
- class FileEncoderSet
- {
- public:
- FileEncoderSet (
- dcp::Size video_frame_size,
- int video_frame_rate,
- int audio_frame_rate,
- int channels,
- ExportFormat,
- bool audio_stream_per_channel,
- int x264_crf,
- bool three_d,
- boost::filesystem::path output,
- std::string extension
- );
-
- std::shared_ptr<FFmpegFileEncoder> get (Eyes eyes) const;
- void flush ();
- void audio (std::shared_ptr<AudioBuffers>);
-
- private:
- std::map<Eyes, std::shared_ptr<FFmpegFileEncoder>> _encoders;
- };
-
- AudioMapping stereo_map() const;
- AudioMapping many_channel_map() const;
-
- int _output_audio_channels;
-
- mutable boost::mutex _mutex;
- dcpomatic::DCPTime _last_time;
-
- EventHistory _history;
-
- boost::filesystem::path _output;
- ExportFormat _format;
- bool _split_reels;
- bool _audio_stream_per_channel;
- int _x264_crf;
-
- Butler _butler;
-};
-
-#endif
#include "compose.hpp"
#include "cross.h"
-#include "ffmpeg_encoder.h"
+#include "ffmpeg_file_encoder.h"
#include "ffmpeg_wrapper.h"
#include "film.h"
#include "image.h"
#define DCPOMATIC_FFMPEG_FILE_ENCODER_H
+#include "audio_buffers.h"
#include "audio_mapping.h"
#include "dcpomatic_time.h"
-#include "encoder.h"
#include "event_history.h"
#include "image_store.h"
#include "log.h"
+#include "player_text.h"
+#include "player_video.h"
#include <dcp/key.h>
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
--- /dev/null
+/*
+ Copyright (C) 2017-2018 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/>.
+
+*/
+
+
+#include "butler.h"
+#include "cross.h"
+#include "ffmpeg_film_encoder.h"
+#include "film.h"
+#include "image.h"
+#include "job.h"
+#include "log.h"
+#include "player.h"
+#include "player_video.h"
+#include "compose.hpp"
+#include <iostream>
+
+#include "i18n.h"
+
+
+using std::cout;
+using std::list;
+using std::make_shared;
+using std::shared_ptr;
+using std::string;
+using std::weak_ptr;
+using boost::bind;
+using boost::optional;
+using namespace dcpomatic;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
+
+
+FFmpegFilmEncoder::FFmpegFilmEncoder(
+ shared_ptr<const Film> film,
+ weak_ptr<Job> job,
+ boost::filesystem::path output,
+ ExportFormat format,
+ bool mixdown_to_stereo,
+ bool split_reels,
+ bool audio_stream_per_channel,
+ int x264_crf
+ )
+ : FilmEncoder(film, job)
+ , _output_audio_channels(mixdown_to_stereo ? 2 : (_film->audio_channels() > 8 ? 16 : _film->audio_channels()))
+ , _history (200)
+ , _output (output)
+ , _format (format)
+ , _split_reels (split_reels)
+ , _audio_stream_per_channel (audio_stream_per_channel)
+ , _x264_crf (x264_crf)
+ , _butler(
+ _film,
+ _player,
+ mixdown_to_stereo ? stereo_map() : many_channel_map(),
+ _output_audio_channels,
+ boost::bind(&PlayerVideo::force, FFmpegFileEncoder::pixel_format(format)),
+ VideoRange::VIDEO,
+ Image::Alignment::PADDED,
+ false,
+ false,
+ Butler::Audio::ENABLED
+ )
+{
+ _player.set_always_burn_open_subtitles();
+ _player.set_play_referenced();
+}
+
+
+AudioMapping
+FFmpegFilmEncoder::stereo_map() const
+{
+ auto map = AudioMapping(_film->audio_channels(), 2);
+ float const overall_gain = 2 / (4 + sqrt(2));
+ float const minus_3dB = 1 / sqrt(2);
+ switch (_film->audio_channels()) {
+ case 2:
+ map.set(dcp::Channel::LEFT, 0, 1);
+ map.set(dcp::Channel::RIGHT, 1, 1);
+ break;
+ case 4:
+ map.set(dcp::Channel::LEFT, 0, overall_gain);
+ map.set(dcp::Channel::RIGHT, 1, overall_gain);
+ map.set(dcp::Channel::CENTRE, 0, overall_gain * minus_3dB);
+ map.set(dcp::Channel::CENTRE, 1, overall_gain * minus_3dB);
+ map.set(dcp::Channel::LS, 0, overall_gain);
+ break;
+ case 6:
+ map.set(dcp::Channel::LEFT, 0, overall_gain);
+ map.set(dcp::Channel::RIGHT, 1, overall_gain);
+ map.set(dcp::Channel::CENTRE, 0, overall_gain * minus_3dB);
+ map.set(dcp::Channel::CENTRE, 1, overall_gain * minus_3dB);
+ map.set(dcp::Channel::LS, 0, overall_gain);
+ map.set(dcp::Channel::RS, 1, overall_gain);
+ break;
+ }
+ /* XXX: maybe we should do something better for >6 channel DCPs */
+ return map;
+}
+
+
+AudioMapping
+FFmpegFilmEncoder::many_channel_map() const
+{
+ auto map = AudioMapping(_film->audio_channels(), _output_audio_channels);
+ for (int i = 0; i < _film->audio_channels(); ++i) {
+ map.set(i, i, 1);
+ }
+ return map;
+}
+
+
+void
+FFmpegFilmEncoder::go()
+{
+ {
+ auto job = _job.lock ();
+ DCPOMATIC_ASSERT (job);
+ job->sub (_("Encoding"));
+ }
+
+ Waker waker;
+
+ list<FileEncoderSet> file_encoders;
+
+ int const files = _split_reels ? _film->reels().size() : 1;
+ for (int i = 0; i < files; ++i) {
+
+ boost::filesystem::path filename = _output;
+ auto extension = dcp::filesystem::extension(filename);
+ filename = dcp::filesystem::change_extension(filename, "");
+
+ if (files > 1) {
+ /// TRANSLATORS: _reel%1 here is to be added to an export filename to indicate
+ /// which reel it is. Preserve the %1; it will be replaced with the reel number.
+ filename = filename.string() + String::compose(_("_reel%1"), i + 1);
+ }
+
+ file_encoders.push_back (
+ FileEncoderSet (
+ _film->frame_size(),
+ _film->video_frame_rate(),
+ _film->audio_frame_rate(),
+ _output_audio_channels,
+ _format,
+ _audio_stream_per_channel,
+ _x264_crf,
+ _film->three_d(),
+ filename,
+ extension
+ )
+ );
+ }
+
+ auto reel_periods = _film->reels ();
+ auto reel = reel_periods.begin ();
+ auto encoder = file_encoders.begin ();
+
+ auto const video_frame = DCPTime::from_frames (1, _film->video_frame_rate ());
+ int const audio_frames = video_frame.frames_round(_film->audio_frame_rate());
+ std::vector<float> interleaved(_output_audio_channels * audio_frames);
+ auto deinterleaved = make_shared<AudioBuffers>(_output_audio_channels, audio_frames);
+ int const gets_per_frame = _film->three_d() ? 2 : 1;
+ for (DCPTime time; time < _film->length(); time += video_frame) {
+
+ if (file_encoders.size() > 1 && !reel->contains(time)) {
+ /* Next reel and file */
+ ++reel;
+ ++encoder;
+ DCPOMATIC_ASSERT (reel != reel_periods.end());
+ DCPOMATIC_ASSERT (encoder != file_encoders.end());
+ }
+
+ for (int j = 0; j < gets_per_frame; ++j) {
+ Butler::Error e;
+ auto video = _butler.get_video(Butler::Behaviour::BLOCKING, &e);
+ _butler.rethrow();
+ if (video.first) {
+ auto fe = encoder->get(video.first->eyes());
+ if (fe) {
+ fe->video(video.first, video.second - reel->from);
+ }
+ } else {
+ if (e.code != Butler::Error::Code::FINISHED) {
+ throw DecodeError(String::compose("Error during decoding: %1", e.summary()));
+ }
+ }
+ }
+
+ _history.event ();
+
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ _last_time = time;
+ }
+
+ auto job = _job.lock ();
+ if (job) {
+ job->set_progress(float(time.get()) / _film->length().get());
+ }
+
+ waker.nudge ();
+
+ _butler.get_audio(Butler::Behaviour::BLOCKING, interleaved.data(), audio_frames);
+ /* XXX: inefficient; butler interleaves and we deinterleave again */
+ float* p = interleaved.data();
+ for (int j = 0; j < audio_frames; ++j) {
+ for (int k = 0; k < _output_audio_channels; ++k) {
+ deinterleaved->data(k)[j] = *p++;
+ }
+ }
+ encoder->audio (deinterleaved);
+ }
+
+ for (auto i: file_encoders) {
+ i.flush ();
+ }
+}
+
+optional<float>
+FFmpegFilmEncoder::current_rate() const
+{
+ return _history.rate ();
+}
+
+Frame
+FFmpegFilmEncoder::frames_done() const
+{
+ boost::mutex::scoped_lock lm (_mutex);
+ return _last_time.frames_round (_film->video_frame_rate ());
+}
+
+FFmpegFilmEncoder::FileEncoderSet::FileEncoderSet(
+ dcp::Size video_frame_size,
+ int video_frame_rate,
+ int audio_frame_rate,
+ int channels,
+ ExportFormat format,
+ bool audio_stream_per_channel,
+ int x264_crf,
+ bool three_d,
+ boost::filesystem::path output,
+ string extension
+ )
+{
+ if (three_d) {
+ _encoders[Eyes::LEFT] = make_shared<FFmpegFileEncoder>(
+ video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
+ // TRANSLATORS: L here is an abbreviation for "left", to indicate the left-eye part of a 3D export
+ audio_stream_per_channel, x264_crf, String::compose("%1_%2%3", output.string(), _("L"), extension)
+ );
+ _encoders[Eyes::RIGHT] = make_shared<FFmpegFileEncoder>(
+ video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
+ // TRANSLATORS: R here is an abbreviation for "right", to indicate the right-eye part of a 3D export
+ audio_stream_per_channel, x264_crf, String::compose("%1_%2%3", output.string(), _("R"), extension)
+ );
+ } else {
+ _encoders[Eyes::BOTH] = make_shared<FFmpegFileEncoder>(
+ video_frame_size, video_frame_rate, audio_frame_rate, channels, format,
+ audio_stream_per_channel, x264_crf, String::compose("%1%2", output.string(), extension)
+ );
+ }
+}
+
+shared_ptr<FFmpegFileEncoder>
+FFmpegFilmEncoder::FileEncoderSet::get(Eyes eyes) const
+{
+ if (_encoders.size() == 1) {
+ /* We are doing a 2D export... */
+ if (eyes == Eyes::LEFT) {
+ /* ...but we got some 3D data; put the left eye into the output... */
+ eyes = Eyes::BOTH;
+ } else if (eyes == Eyes::RIGHT) {
+ /* ...and ignore the right eye.*/
+ return {};
+ }
+ }
+
+ auto i = _encoders.find (eyes);
+ DCPOMATIC_ASSERT (i != _encoders.end());
+ return i->second;
+}
+
+void
+FFmpegFilmEncoder::FileEncoderSet::flush()
+{
+ for (auto& i: _encoders) {
+ i.second->flush ();
+ }
+}
+
+void
+FFmpegFilmEncoder::FileEncoderSet::audio(shared_ptr<AudioBuffers> a)
+{
+ for (auto& i: _encoders) {
+ i.second->audio (a);
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 2017-2018 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/>.
+
+*/
+
+#ifndef DCPOMATIC_FFMPEG_ENCODER_H
+#define DCPOMATIC_FFMPEG_ENCODER_H
+
+#include "audio_mapping.h"
+#include "butler.h"
+#include "event_history.h"
+#include "ffmpeg_file_encoder.h"
+#include "film_encoder.h"
+
+
+class FFmpegFilmEncoder : public FilmEncoder
+{
+public:
+ FFmpegFilmEncoder(
+ std::shared_ptr<const Film> film,
+ std::weak_ptr<Job> job,
+ boost::filesystem::path output,
+ ExportFormat format,
+ bool mixdown_to_stereo,
+ bool split_reels,
+ bool audio_stream_per_channel,
+ int x264_crf
+ );
+
+ void go () override;
+
+ boost::optional<float> current_rate () const override;
+ Frame frames_done () const override;
+ bool finishing () const override {
+ return false;
+ }
+
+private:
+
+ class FileEncoderSet
+ {
+ public:
+ FileEncoderSet (
+ dcp::Size video_frame_size,
+ int video_frame_rate,
+ int audio_frame_rate,
+ int channels,
+ ExportFormat,
+ bool audio_stream_per_channel,
+ int x264_crf,
+ bool three_d,
+ boost::filesystem::path output,
+ std::string extension
+ );
+
+ std::shared_ptr<FFmpegFileEncoder> get (Eyes eyes) const;
+ void flush ();
+ void audio (std::shared_ptr<AudioBuffers>);
+
+ private:
+ std::map<Eyes, std::shared_ptr<FFmpegFileEncoder>> _encoders;
+ };
+
+ AudioMapping stereo_map() const;
+ AudioMapping many_channel_map() const;
+
+ int _output_audio_channels;
+
+ mutable boost::mutex _mutex;
+ dcpomatic::DCPTime _last_time;
+
+ EventHistory _history;
+
+ boost::filesystem::path _output;
+ ExportFormat _format;
+ bool _split_reels;
+ bool _audio_stream_per_channel;
+ int _x264_crf;
+
+ Butler _butler;
+};
+
+#endif
#include "cross.h"
#include "dcp_content.h"
#include "dcp_content_type.h"
-#include "dcp_encoder.h"
+#include "dcp_film_encoder.h"
#include "dcpomatic_log.h"
#include "digester.h"
#include "environment_info.h"
--- /dev/null
+/*
+ Copyright (C) 2012-2017 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/film_encoder.cc
+ * @brief A class which takes a Film and some Options, then uses those to encode the film
+ * into some output format.
+ *
+ * A decoder is selected according to the content type, and the encoder can be specified
+ * as a parameter to the constructor.
+ */
+
+
+#include "film_encoder.h"
+#include "player.h"
+
+#include "i18n.h"
+
+
+/** Construct a FilmEncoder.
+ * @param film Film that we are encoding.
+ * @param job Job that this encoder is being used in.
+ */
+FilmEncoder::FilmEncoder(std::shared_ptr<const Film> film, std::weak_ptr<Job> job)
+ : _film (film)
+ , _job (job)
+ , _player(film, Image::Alignment::PADDED)
+{
+
+}
--- /dev/null
+/*
+ Copyright (C) 2012-2021 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/>.
+
+*/
+
+
+#ifndef DCPOMATIC_FILM_ENCODER_H
+#define DCPOMATIC_FILM_ENCODER_H
+
+
+#include "player.h"
+#include "player_text.h"
+#include <boost/signals2.hpp>
+
+
+class Film;
+class Player;
+class Job;
+class PlayerVideo;
+class AudioBuffers;
+
+
+/** @class FilmEncoder
+ * @brief Parent class for something that can encode a film into some format
+ */
+class FilmEncoder
+{
+public:
+ FilmEncoder(std::shared_ptr<const Film> film, std::weak_ptr<Job> job);
+ virtual ~FilmEncoder() {}
+
+ FilmEncoder(FilmEncoder const&) = delete;
+ FilmEncoder& operator=(FilmEncoder const&) = delete;
+
+ virtual void go () = 0;
+
+ /** @return the current frame rate over the last short while */
+ virtual boost::optional<float> current_rate () const {
+ return {};
+ }
+
+ /** @return the number of frames that are done */
+ virtual Frame frames_done () const = 0;
+ virtual bool finishing () const = 0;
+ virtual void pause() {}
+ virtual void resume() {}
+
+protected:
+ std::shared_ptr<const Film> _film;
+ std::weak_ptr<Job> _job;
+ Player _player;
+};
+
+
+#endif
#include "audio_analyser.h"
-#include "signaller.h"
-#include "player_text.h"
#include "dcp_text_track.h"
#include "dcpomatic_time.h"
+#include "player_text.h"
+#include "signaller.h"
+#include "text_type.h"
#include "weak_film.h"
-#include <boost/signals2.hpp>
#include <boost/atomic.hpp>
-#include <vector>
+#include <boost/signals2.hpp>
#include <string>
+#include <vector>
class Film;
#include "config.h"
#include "dcp_content.h"
-#include "dcp_encoder.h"
+#include "dcp_film_encoder.h"
#include "dcp_transcode_job.h"
#include "dcpomatic_log.h"
#include "environment_info.h"
LOG_GENERAL ("J2K bandwidth %1", film->j2k_bandwidth());
auto tj = make_shared<DCPTranscodeJob>(film, behaviour);
- tj->set_encoder (make_shared<DCPEncoder>(film, tj));
+ tj->set_encoder(make_shared<DCPFilmEncoder>(film, tj));
JobManager::instance()->add (tj);
return tj;
#include "player_text.h"
#include "referenced_reel_asset.h"
#include "render_text.h"
+#include "text_type.h"
#include "weak_film.h"
#include <dcp/atmos_asset_writer.h>
#include <dcp/file.h>
+++ /dev/null
-/*
- Copyright (C) 2019-2021 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/>.
-
-*/
-
-
-#include "compose.hpp"
-#include "film.h"
-#include "job.h"
-#include "player.h"
-#include "subtitle_encoder.h"
-#include <dcp/filesystem.h>
-#include <dcp/interop_subtitle_asset.h>
-#include <dcp/raw_convert.h>
-#include <dcp/smpte_subtitle_asset.h>
-#include <boost/filesystem.hpp>
-#include <boost/bind/bind.hpp>
-
-#include "i18n.h"
-
-
-using std::make_pair;
-using std::make_shared;
-using std::pair;
-using std::shared_ptr;
-using std::string;
-using std::vector;
-using boost::optional;
-#if BOOST_VERSION >= 106100
-using namespace boost::placeholders;
-#endif
-using dcp::raw_convert;
-
-
-/** @param output Directory, if there will be multiple output files, or a filename.
- * @param initial_name Hint that may be used to create filenames, if @ref output is a directory.
- * @param include_font true to refer to and export any font file (for Interop; ignored for SMPTE).
- */
-SubtitleEncoder::SubtitleEncoder (shared_ptr<const Film> film, shared_ptr<Job> job, boost::filesystem::path output, string initial_name, bool split_reels, bool include_font)
- : Encoder (film, job)
- , _split_reels (split_reels)
- , _include_font (include_font)
- , _reel_index (0)
- , _length (film->length())
-{
- _player.set_play_referenced();
- _player.set_ignore_video();
- _player.set_ignore_audio();
- _player.Text.connect(boost::bind(&SubtitleEncoder::text, this, _1, _2, _3, _4));
-
- string const extension = film->interop() ? ".xml" : ".mxf";
-
- int const files = split_reels ? film->reels().size() : 1;
- for (int i = 0; i < files; ++i) {
-
- boost::filesystem::path filename = output;
- if (dcp::filesystem::is_directory(filename)) {
- if (files > 1) {
- /// TRANSLATORS: _reel%1 here is to be added to an export filename to indicate
- /// which reel it is. Preserve the %1; it will be replaced with the reel number.
- filename /= String::compose("%1_reel%2", initial_name, i + 1);
- } else {
- filename /= initial_name;
- }
- }
-
- _assets.push_back(make_pair(shared_ptr<dcp::SubtitleAsset>(), dcp::filesystem::change_extension(filename, extension)));
- }
-
- for (auto i: film->reels()) {
- _reels.push_back (i);
- }
-
- _default_font = dcp::ArrayData (default_font_file());
-}
-
-
-void
-SubtitleEncoder::go ()
-{
- {
- shared_ptr<Job> job = _job.lock ();
- DCPOMATIC_ASSERT (job);
- job->sub (_("Extracting"));
- }
-
- _reel_index = 0;
-
- while (!_player.pass()) {}
-
- int reel = 0;
- for (auto& i: _assets) {
- if (!i.first) {
- /* No subtitles arrived for this asset; make an empty one so we write something to the output */
- if (_film->interop()) {
- auto s = make_shared<dcp::InteropSubtitleAsset>();
- s->set_movie_title (_film->name());
- s->set_reel_number (raw_convert<string>(reel + 1));
- i.first = s;
- } else {
- auto s = make_shared<dcp::SMPTESubtitleAsset>();
- s->set_content_title_text (_film->name());
- s->set_reel_number (reel + 1);
- i.first = s;
- }
- }
-
- if (!_film->interop() || _include_font) {
- for (auto j: _player.get_subtitle_fonts()) {
- i.first->add_font(j->id(), j->data().get_value_or(_default_font));
- }
- }
-
- i.first->write (i.second);
- ++reel;
- }
-}
-
-
-void
-SubtitleEncoder::text (PlayerText subs, TextType type, optional<DCPTextTrack> track, dcpomatic::DCPTimePeriod period)
-{
- if (type != TextType::OPEN_SUBTITLE) {
- return;
- }
-
- if (!_assets[_reel_index].first) {
- shared_ptr<dcp::SubtitleAsset> asset;
- auto lang = _film->subtitle_languages ();
- if (_film->interop ()) {
- auto s = make_shared<dcp::InteropSubtitleAsset>();
- s->set_movie_title (_film->name());
- if (lang.first) {
- s->set_language (lang.first->to_string());
- }
- s->set_reel_number (raw_convert<string>(_reel_index + 1));
- _assets[_reel_index].first = s;
- } else {
- auto s = make_shared<dcp::SMPTESubtitleAsset>();
- s->set_content_title_text (_film->name());
- if (lang.first) {
- s->set_language (*lang.first);
- } else if (track->language) {
- s->set_language (track->language.get());
- }
- s->set_edit_rate (dcp::Fraction (_film->video_frame_rate(), 1));
- s->set_reel_number (_reel_index + 1);
- s->set_time_code_rate (_film->video_frame_rate());
- s->set_start_time (dcp::Time());
- if (_film->encrypted ()) {
- s->set_key (_film->key ());
- }
- _assets[_reel_index].first = s;
- }
- }
-
- for (auto i: subs.string) {
- /* XXX: couldn't / shouldn't we use period here rather than getting time from the subtitle? */
- i.set_in (i.in());
- i.set_out (i.out());
- if (_film->interop() && !_include_font) {
- i.unset_font ();
- }
- _assets[_reel_index].first->add (make_shared<dcp::SubtitleString>(i));
- }
-
- if (_split_reels && (_reel_index < int(_reels.size()) - 1) && period.from > _reels[_reel_index].from) {
- ++_reel_index;
- }
-
- _last = period.from;
-
- auto job = _job.lock ();
- if (job) {
- job->set_progress (float(period.from.get()) / _length.get());
- }
-}
-
-
-Frame
-SubtitleEncoder::frames_done () const
-{
- if (!_last) {
- return 0;
- }
-
- /* XXX: assuming 24fps here but I don't think it matters */
- return _last->seconds() * 24;
-}
+++ /dev/null
-/*
- Copyright (C) 2019-2021 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/>.
-
-*/
-
-
-#include "dcp_text_track.h"
-#include "dcpomatic_time.h"
-#include "encoder.h"
-#include "player_text.h"
-
-
-namespace dcp {
- class SubtitleAsset;
-}
-
-
-class Film;
-
-
-/** @class SubtitleEncoder.
- * @brief An `encoder' which extracts a film's subtitles to DCP XML format.
- */
-class SubtitleEncoder : public Encoder
-{
-public:
- SubtitleEncoder (std::shared_ptr<const Film> film, std::shared_ptr<Job> job, boost::filesystem::path output, std::string initial_name, bool split_reels, bool include_font);
-
- void go () override;
-
- /** @return the number of frames that are done */
- Frame frames_done () const override;
-
- bool finishing () const override {
- return false;
- }
-
-private:
- void text (PlayerText subs, TextType type, boost::optional<DCPTextTrack> track, dcpomatic::DCPTimePeriod period);
-
- std::vector<std::pair<std::shared_ptr<dcp::SubtitleAsset>, boost::filesystem::path>> _assets;
- std::vector<dcpomatic::DCPTimePeriod> _reels;
- bool _split_reels;
- bool _include_font;
- int _reel_index;
- boost::optional<dcpomatic::DCPTime> _last;
- dcpomatic::DCPTime _length;
- dcp::ArrayData _default_font;
-};
--- /dev/null
+/*
+ Copyright (C) 2019-2021 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/>.
+
+*/
+
+
+#include "compose.hpp"
+#include "film.h"
+#include "job.h"
+#include "player.h"
+#include "subtitle_film_encoder.h"
+#include <dcp/filesystem.h>
+#include <dcp/interop_subtitle_asset.h>
+#include <dcp/raw_convert.h>
+#include <dcp/smpte_subtitle_asset.h>
+#include <boost/filesystem.hpp>
+#include <boost/bind/bind.hpp>
+
+#include "i18n.h"
+
+
+using std::make_pair;
+using std::make_shared;
+using std::pair;
+using std::shared_ptr;
+using std::string;
+using std::vector;
+using boost::optional;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
+using dcp::raw_convert;
+
+
+/** @param output Directory, if there will be multiple output files, or a filename.
+ * @param initial_name Hint that may be used to create filenames, if @ref output is a directory.
+ * @param include_font true to refer to and export any font file (for Interop; ignored for SMPTE).
+ */
+SubtitleFilmEncoder::SubtitleFilmEncoder(shared_ptr<const Film> film, shared_ptr<Job> job, boost::filesystem::path output, string initial_name, bool split_reels, bool include_font)
+ : FilmEncoder(film, job)
+ , _split_reels (split_reels)
+ , _include_font (include_font)
+ , _reel_index (0)
+ , _length (film->length())
+{
+ _player.set_play_referenced();
+ _player.set_ignore_video();
+ _player.set_ignore_audio();
+ _player.Text.connect(boost::bind(&SubtitleFilmEncoder::text, this, _1, _2, _3, _4));
+
+ string const extension = film->interop() ? ".xml" : ".mxf";
+
+ int const files = split_reels ? film->reels().size() : 1;
+ for (int i = 0; i < files; ++i) {
+
+ boost::filesystem::path filename = output;
+ if (dcp::filesystem::is_directory(filename)) {
+ if (files > 1) {
+ /// TRANSLATORS: _reel%1 here is to be added to an export filename to indicate
+ /// which reel it is. Preserve the %1; it will be replaced with the reel number.
+ filename /= String::compose("%1_reel%2", initial_name, i + 1);
+ } else {
+ filename /= initial_name;
+ }
+ }
+
+ _assets.push_back(make_pair(shared_ptr<dcp::SubtitleAsset>(), dcp::filesystem::change_extension(filename, extension)));
+ }
+
+ for (auto i: film->reels()) {
+ _reels.push_back (i);
+ }
+
+ _default_font = dcp::ArrayData (default_font_file());
+}
+
+
+void
+SubtitleFilmEncoder::go()
+{
+ {
+ shared_ptr<Job> job = _job.lock ();
+ DCPOMATIC_ASSERT (job);
+ job->sub (_("Extracting"));
+ }
+
+ _reel_index = 0;
+
+ while (!_player.pass()) {}
+
+ int reel = 0;
+ for (auto& i: _assets) {
+ if (!i.first) {
+ /* No subtitles arrived for this asset; make an empty one so we write something to the output */
+ if (_film->interop()) {
+ auto s = make_shared<dcp::InteropSubtitleAsset>();
+ s->set_movie_title (_film->name());
+ s->set_reel_number (raw_convert<string>(reel + 1));
+ i.first = s;
+ } else {
+ auto s = make_shared<dcp::SMPTESubtitleAsset>();
+ s->set_content_title_text (_film->name());
+ s->set_reel_number (reel + 1);
+ i.first = s;
+ }
+ }
+
+ if (!_film->interop() || _include_font) {
+ for (auto j: _player.get_subtitle_fonts()) {
+ i.first->add_font(j->id(), j->data().get_value_or(_default_font));
+ }
+ }
+
+ i.first->write (i.second);
+ ++reel;
+ }
+}
+
+
+void
+SubtitleFilmEncoder::text(PlayerText subs, TextType type, optional<DCPTextTrack> track, dcpomatic::DCPTimePeriod period)
+{
+ if (type != TextType::OPEN_SUBTITLE) {
+ return;
+ }
+
+ if (!_assets[_reel_index].first) {
+ shared_ptr<dcp::SubtitleAsset> asset;
+ auto lang = _film->subtitle_languages ();
+ if (_film->interop ()) {
+ auto s = make_shared<dcp::InteropSubtitleAsset>();
+ s->set_movie_title (_film->name());
+ if (lang.first) {
+ s->set_language (lang.first->to_string());
+ }
+ s->set_reel_number (raw_convert<string>(_reel_index + 1));
+ _assets[_reel_index].first = s;
+ } else {
+ auto s = make_shared<dcp::SMPTESubtitleAsset>();
+ s->set_content_title_text (_film->name());
+ if (lang.first) {
+ s->set_language (*lang.first);
+ } else if (track->language) {
+ s->set_language (track->language.get());
+ }
+ s->set_edit_rate (dcp::Fraction (_film->video_frame_rate(), 1));
+ s->set_reel_number (_reel_index + 1);
+ s->set_time_code_rate (_film->video_frame_rate());
+ s->set_start_time (dcp::Time());
+ if (_film->encrypted ()) {
+ s->set_key (_film->key ());
+ }
+ _assets[_reel_index].first = s;
+ }
+ }
+
+ for (auto i: subs.string) {
+ /* XXX: couldn't / shouldn't we use period here rather than getting time from the subtitle? */
+ i.set_in (i.in());
+ i.set_out (i.out());
+ if (_film->interop() && !_include_font) {
+ i.unset_font ();
+ }
+ _assets[_reel_index].first->add (make_shared<dcp::SubtitleString>(i));
+ }
+
+ if (_split_reels && (_reel_index < int(_reels.size()) - 1) && period.from > _reels[_reel_index].from) {
+ ++_reel_index;
+ }
+
+ _last = period.from;
+
+ auto job = _job.lock ();
+ if (job) {
+ job->set_progress (float(period.from.get()) / _length.get());
+ }
+}
+
+
+Frame
+SubtitleFilmEncoder::frames_done() const
+{
+ if (!_last) {
+ return 0;
+ }
+
+ /* XXX: assuming 24fps here but I don't think it matters */
+ return _last->seconds() * 24;
+}
--- /dev/null
+/*
+ Copyright (C) 2019-2021 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/>.
+
+*/
+
+
+#include "dcp_text_track.h"
+#include "dcpomatic_time.h"
+#include "film_encoder.h"
+#include "player_text.h"
+
+
+namespace dcp {
+ class SubtitleAsset;
+}
+
+
+class Film;
+
+
+/** @class SubtitleFilmEncoder.
+ * @brief An `encoder' which extracts a film's subtitles to DCP XML format.
+ */
+class SubtitleFilmEncoder : public FilmEncoder
+{
+public:
+ SubtitleFilmEncoder(std::shared_ptr<const Film> film, std::shared_ptr<Job> job, boost::filesystem::path output, std::string initial_name, bool split_reels, bool include_font);
+
+ void go () override;
+
+ /** @return the number of frames that are done */
+ Frame frames_done () const override;
+
+ bool finishing () const override {
+ return false;
+ }
+
+private:
+ void text (PlayerText subs, TextType type, boost::optional<DCPTextTrack> track, dcpomatic::DCPTimePeriod period);
+
+ std::vector<std::pair<std::shared_ptr<dcp::SubtitleAsset>, boost::filesystem::path>> _assets;
+ std::vector<dcpomatic::DCPTimePeriod> _reels;
+ bool _split_reels;
+ bool _include_font;
+ int _reel_index;
+ boost::optional<dcpomatic::DCPTime> _last;
+ dcpomatic::DCPTime _length;
+ dcp::ArrayData _default_font;
+};
#include "compose.hpp"
#include "content.h"
#include "config.h"
-#include "dcp_encoder.h"
+#include "dcp_film_encoder.h"
#include "dcpomatic_log.h"
-#include "encoder.h"
#include "examine_content_job.h"
#include "film.h"
+#include "film_encoder.h"
#include "job_manager.h"
#include "log.h"
#include "transcode_job.h"
void
-TranscodeJob::set_encoder (shared_ptr<Encoder> e)
+TranscodeJob::set_encoder(shared_ptr<FilmEncoder> e)
{
_encoder = e;
}
LOG_GENERAL(N_("Transcode job completed successfully: %1 fps"), dcp::locale_convert<string>(frames_per_second(), 2, true));
- if (dynamic_pointer_cast<DCPEncoder>(_encoder)) {
+ if (dynamic_pointer_cast<DCPFilmEncoder>(_encoder)) {
try {
Analytics::instance()->successful_dcp_encode();
} catch (FileError& e) {
#undef IGNORE
-class Encoder;
+class FilmEncoder;
struct frames_not_lost_when_threads_disappear;
return true;
}
- void set_encoder (std::shared_ptr<Encoder> t);
+ void set_encoder(std::shared_ptr<FilmEncoder> encoder);
private:
friend struct ::frames_not_lost_when_threads_disappear;
int remaining_time () const override;
- std::shared_ptr<Encoder> _encoder;
+ std::shared_ptr<FilmEncoder> _encoder;
ChangedBehaviour _changed;
};
dcp_content.cc
dcp_content_type.cc
dcp_decoder.cc
- dcp_encoder.cc
dcp_examiner.cc
dcp_digest_file.cc
+ dcp_film_encoder.cc
dcp_subtitle.cc
dcp_subtitle_content.cc
dcp_subtitle_decoder.cc
dolby_cp750.cc
email.cc
empty.cc
- encoder.cc
encode_server.cc
encode_server_finder.cc
encoded_log_entry.cc
ffmpeg_audio_stream.cc
ffmpeg_content.cc
ffmpeg_decoder.cc
- ffmpeg_encoder.cc
ffmpeg_examiner.cc
ffmpeg_file_encoder.cc
+ ffmpeg_film_encoder.cc
ffmpeg_image_proxy.cc
ffmpeg_stream.cc
ffmpeg_subtitle_stream.cc
ffmpeg_wrapper.cc
film.cc
+ film_encoder.cc
film_util.cc
filter.cc
font.cc
string_text_file_content.cc
string_text_file_decoder.cc
subtitle_analysis.cc
- subtitle_encoder.cc
+ subtitle_film_encoder.cc
territory_type.cc
text_ring_buffers.cc
text_type.cc
#include "lib/email.h"
#include "lib/encode_server_finder.h"
#include "lib/exceptions.h"
-#include "lib/ffmpeg_encoder.h"
+#include "lib/ffmpeg_film_encoder.h"
#include "lib/film.h"
#include "lib/font_config.h"
#ifdef DCPOMATIC_GROK
#include "lib/screen.h"
#include "lib/send_kdm_email_job.h"
#include "lib/signal_manager.h"
-#include "lib/subtitle_encoder.h"
+#include "lib/subtitle_film_encoder.h"
#include "lib/text_content.h"
#include "lib/transcode_job.h"
#include "lib/update_checker.h"
auto job = make_shared<TranscodeJob>(_film, TranscodeJob::ChangedBehaviour::EXAMINE_THEN_STOP);
job->set_encoder (
- make_shared<FFmpegEncoder> (
+ make_shared<FFmpegFilmEncoder>(
_film, job, dialog.path(), dialog.format(), dialog.mixdown_to_stereo(), dialog.split_reels(), dialog.split_streams(), dialog.x264_crf())
);
JobManager::instance()->add (job);
}
auto job = make_shared<TranscodeJob>(_film, TranscodeJob::ChangedBehaviour::EXAMINE_THEN_STOP);
job->set_encoder(
- make_shared<SubtitleEncoder>(_film, job, dialog.path(), _film->isdcf_name(true), dialog.split_reels(), dialog.include_font())
+ make_shared<SubtitleFilmEncoder>(_film, job, dialog.path(), _film->isdcf_name(true), dialog.split_reels(), dialog.include_font())
);
JobManager::instance()->add(job);
}
#include "lib/cross.h"
#include "lib/dcpomatic_log.h"
#include "lib/encode_server_finder.h"
-#include "lib/ffmpeg_encoder.h"
+#include "lib/ffmpeg_film_encoder.h"
#include "lib/film.h"
#include "lib/filter.h"
#ifdef DCPOMATIC_GROK
if (export_format) {
auto job = std::make_shared<TranscodeJob>(film, behaviour);
job->set_encoder (
- std::make_shared<FFmpegEncoder> (
+ std::make_shared<FFmpegFilmEncoder>(
film, job, *export_filename, *export_format == "mp4" ? ExportFormat::H264_AAC : ExportFormat::PRORES_HQ, false, false, false, 23
)
);
#include "lib/constants.h"
#include "lib/cross.h"
#include "lib/job_manager.h"
+#include "lib/util.h"
#include <dcp/combine.h>
LIBDCP_DISABLE_WARNINGS
#include <wx/filepicker.h>
#include "lib/cross.h"
#include "lib/dcpomatic_log.h"
#include "lib/null_log.h"
+#include "lib/util.h"
#include "lib/variant.h"
#include <dcp/cpl.h>
#include <dcp/dcp.h>
#include "lib/kdm_with_metadata.h"
#include "lib/screen.h"
#include "lib/send_kdm_email_job.h"
+#include "lib/util.h"
#include "lib/variant.h"
#include <dcp/encrypted_kdm.h>
#include <dcp/decrypted_kdm.h>
#include "static_text.h"
#include "wx_variant.h"
#include "lib/constants.h"
+#include "lib/util.h"
#include <dcp/file.h>
#include <dcp/filesystem.h>
#include <dcp/raw_convert.h>
#include "timecode.h"
#include "timeline.h"
+#include "lib/change_signaller.h"
+#include "lib/film_property.h"
#include "lib/rect.h"
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
#include "table_dialog.h"
-#include "lib/ffmpeg_encoder.h"
+#include "lib/ffmpeg_file_encoder.h"
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
#include <wx/wx.h>
#include "video_view.h"
+#include "lib/change_signaller.h"
#include "lib/config.h"
#include "lib/film_property.h"
+#include "lib/player.h"
#include "lib/player_text.h"
#include "lib/signaller.h"
#include "lib/timer.h"
#include "kdm_cpl_panel.h"
#include "static_text.h"
#include "wx_util.h"
+#include <dcp/filesystem.h>
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
#include <libxml++/libxml++.h>
#include "timeline_content_view.h"
#include "wx_util.h"
#include "lib/content.h"
+#include "lib/util.h"
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
#include <wx/graphics.h>
#include "lib/dcp_content.h"
#include "lib/dcp_content_type.h"
#include "lib/film.h"
-#include "lib/ffmpeg_encoder.h"
+#include "lib/ffmpeg_film_encoder.h"
#include "lib/log_entry.h"
#include "lib/ratio.h"
#include "lib/text_content.h"
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
auto file = boost::filesystem::path("build") / "test" / "burnt_empty_subtitle_test.mov";
cl.add(file);
- FFmpegEncoder encoder(film, job, file, ExportFormat::PRORES_4444, false, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, file, ExportFormat::PRORES_4444, false, false, false, 23);
encoder.go();
cl.run();
#include "lib/dcp_content.h"
#include "lib/dcpomatic_log.h"
#include "lib/ffmpeg_content.h"
-#include "lib/ffmpeg_encoder.h"
#include "lib/ffmpeg_examiner.h"
+#include "lib/ffmpeg_film_encoder.h"
#include "lib/film.h"
#include "lib/image_content.h"
#include "lib/ratio.h"
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
auto file = boost::filesystem::path("build") / "test" / String::compose("%1.%2", name, extension);
cl.add (file);
- FFmpegEncoder encoder (film, job, file, format, false, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, file, format, false, false, false, 23);
encoder.go ();
cl.run ();
film->write_metadata ();
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test5.mov", ExportFormat::PRORES_HQ, false, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_prores_test5.mov", ExportFormat::PRORES_HQ, false, false, false, 23);
encoder.go ();
}
film->write_metadata();
auto job = make_shared<TranscodeJob> (film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test6.mov", ExportFormat::PRORES_HQ, false, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_prores_test6.mov", ExportFormat::PRORES_HQ, false, false, false, 23);
encoder.go ();
}
s->only_text()->set_effect_colour (dcp::Colour (0, 255, 255));
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test7.mov", ExportFormat::PRORES_HQ, false, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_prores_test7.mov", ExportFormat::PRORES_HQ, false, false, false, 23);
encoder.go ();
}
film->write_metadata();
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test2.mp4", ExportFormat::H264_AAC, false, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test2.mp4", ExportFormat::H264_AAC, false, false, false, 23);
encoder.go ();
}
film->write_metadata();
auto job = make_shared<TranscodeJob> (film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test3.mp4", ExportFormat::H264_AAC, false, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test3.mp4", ExportFormat::H264_AAC, false, false, false, 23);
encoder.go ();
}
film->set_container(Ratio::from_id("185"));
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test4.mp4", ExportFormat::H264_AAC, false, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test4.mp4", ExportFormat::H264_AAC, false, false, false, 23);
encoder.go();
}
Rs->audio->set_mapping (map);
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test5.mp4", ExportFormat::H264_AAC, true, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test5.mp4", ExportFormat::H264_AAC, true, false, false, 23);
encoder.go ();
check_ffmpeg ("build/test/ffmpeg_encoder_h264_test5.mp4", "test/data/ffmpeg_encoder_h264_test5.mp4", 1);
}
auto job = make_shared<TranscodeJob>(film2, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test6_vf.mp4", ExportFormat::H264_AAC, true, false, false, 23);
+ FFmpegFilmEncoder encoder(film2, job, "build/test/ffmpeg_encoder_h264_test6_vf.mp4", ExportFormat::H264_AAC, true, false, false, 23);
encoder.go ();
}
auto film2 = new_test_film2 ("ffmpeg_encoder_3d_dcp_to_h264_export", {dcp});
auto job = make_shared<TranscodeJob>(film2, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_3d_dcp_to_h264.mp4", ExportFormat::H264_AAC, true, false, false, 23);
+ FFmpegFilmEncoder encoder(film2, job, "build/test/ffmpeg_encoder_3d_dcp_to_h264.mp4", ExportFormat::H264_AAC, true, false, false, 23);
encoder.go ();
}
auto film2 = new_test_film2 ("ffmpeg_encoder_h264_test7_export", {dcp});
auto job = make_shared<TranscodeJob> (film2, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test7.mp4", ExportFormat::H264_AAC, true, false, false, 23);
+ FFmpegFilmEncoder encoder(film2, job, "build/test/ffmpeg_encoder_h264_test7.mp4", ExportFormat::H264_AAC, true, false, false, 23);
encoder.go ();
}
film->set_three_d(true);
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_2d_content_in_3d_project.mp4", ExportFormat::H264_AAC, true, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_2d_content_in_3d_project.mp4", ExportFormat::H264_AAC, true, false, false, 23);
encoder.go();
}
film->set_audio_channels (2);
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test8.mp4", ExportFormat::H264_AAC, true, false, false, 23);
+ FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test8.mp4", ExportFormat::H264_AAC, true, false, false, 23);
encoder.go();
}
film->write_metadata ();
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test9.mov", ExportFormat::H264_AAC, false, false, false, 23);
+ FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test9.mov", ExportFormat::H264_AAC, false, false, false, 23);
encoder.go ();
}
film->write_metadata ();
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_from_dcp_with_crop.mov", ExportFormat::PRORES_HQ, false, false, false, 23);
+ FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_from_dcp_with_crop.mov", ExportFormat::PRORES_HQ, false, false, false, 23);
encoder.go ();
}
film->write_metadata ();
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_from_dcp_with_crop.mov", ExportFormat::H264_AAC, false, false, false, 23);
+ FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_from_dcp_with_crop.mov", ExportFormat::H264_AAC, false, false, false, 23);
encoder.go ();
}
content2->video->set_length (240);
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_with_reels.mov", ExportFormat::H264_AAC, false, true, false, 23);
+ FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_with_reels.mov", ExportFormat::H264_AAC, false, true, false, 23);
encoder.go ();
auto check = [](boost::filesystem::path path) {
auto film = new_test_film2 ("ffmpeg_encoder_prores_regression_1", { content });
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_regression_1.mov", ExportFormat::PRORES_HQ, false, true, false, 23);
+ FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_regression_1.mov", ExportFormat::PRORES_HQ, false, true, false, 23);
encoder.go ();
cl.add("build/test/ffmpeg_encoder_prores_regression_1.mov");
auto film = new_test_film2 ("ffmpeg_encoder_prores_regression_2", { content });
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_regression_2.mov", ExportFormat::PRORES_HQ, false, true, false, 23);
+ FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_regression_2.mov", ExportFormat::PRORES_HQ, false, true, false, 23);
encoder.go ();
dcpomatic_log->set_types(logs);
boost::filesystem::path log("build/test/ffmpeg_encoder_missing_frame_at_end.log");
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
- FFmpegEncoder encoder(film, job, output, ExportFormat::PRORES_HQ, false, true, false, 23);
+ FFmpegFilmEncoder encoder(film, job, output, ExportFormat::PRORES_HQ, false, true, false, 23);
encoder.go();
run_ffprobe(output, log, false, "-show_frames -show_format -show_streams -select_streams v:0");
#include "lib/config.h"
#include "lib/content_factory.h"
-#include "lib/dcp_encoder.h"
+#include "lib/dcp_film_encoder.h"
#include "lib/dcp_transcode_job.h"
#include "lib/encode_server_description.h"
#include "lib/film.h"
auto film = new_test_film2("frames_not_lost", content);
film->write_metadata();
auto job = make_dcp(film, TranscodeJob::ChangedBehaviour::IGNORE);
- auto& encoder = dynamic_pointer_cast<DCPEncoder>(job->_encoder)->_j2k_encoder;
+ auto& encoder = dynamic_pointer_cast<DCPFilmEncoder>(job->_encoder)->_j2k_encoder;
while (JobManager::instance()->work_to_do()) {
encoder.remake_threads(rand() % 8, 0, {});
#include "lib/content.h"
#include "lib/content_factory.h"
#include "lib/dcp_content_type.h"
-#include "lib/dcp_encoder.h"
#include "lib/dcpomatic_log.h"
#include "lib/film.h"
#include "lib/job_manager.h"
#include "lib/image.h"
#include "lib/image_content.h"
#include "lib/image_decoder.h"
-#include "lib/ffmpeg_encoder.h"
+#include "lib/ffmpeg_film_encoder.h"
#include "lib/job_manager.h"
#include "lib/player.h"
#include "lib/player_video.h"
{
auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE);
job->set_encoder (
- make_shared<FFmpegEncoder>(film, job, film->file("export.mov"), ExportFormat::PRORES_HQ, true, false, false, 23)
+ make_shared<FFmpegFilmEncoder>(film, job, film->file("export.mov"), ExportFormat::PRORES_HQ, true, false, false, 23)
);
JobManager::instance()->add (job);
BOOST_REQUIRE (!wait_for_jobs());
#include "lib/content.h"
#include "lib/content_factory.h"
#include "lib/cross.h"
-#include "lib/dcp_encoder.h"
+#include "lib/dcp_film_encoder.h"
#include "lib/film.h"
#include "lib/job.h"
#include "lib/video_content.h"
last_sub_name = job->sub_name();
});
- DCPEncoder encoder(film, job);
+ DCPFilmEncoder encoder(film, job);
encoder.go();
}