summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ffmpeg_encoder.cc32
-rw-r--r--src/lib/ffmpeg_encoder.h8
-rw-r--r--src/lib/ffmpeg_file_encoder.cc25
-rw-r--r--src/lib/ffmpeg_file_encoder.h5
-rw-r--r--src/lib/util.cc65
-rw-r--r--src/lib/util.h1
6 files changed, 133 insertions, 3 deletions
diff --git a/src/lib/ffmpeg_encoder.cc b/src/lib/ffmpeg_encoder.cc
index e29d37cec..7c641f5ab 100644
--- a/src/lib/ffmpeg_encoder.cc
+++ b/src/lib/ffmpeg_encoder.cc
@@ -41,8 +41,10 @@ using std::map;
using boost::shared_ptr;
using boost::bind;
using boost::weak_ptr;
+using boost::optional;
using namespace dcpomatic;
+/** @param key Key to use to encrypt MP4 outputs */
FFmpegEncoder::FFmpegEncoder (
shared_ptr<const Film> film,
weak_ptr<Job> job,
@@ -51,6 +53,10 @@ FFmpegEncoder::FFmpegEncoder (
bool mixdown_to_stereo,
bool split_reels,
int x264_crf
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , optional<dcp::Key> key
+ , optional<string> id
+#endif
)
: Encoder (film, job)
, _history (1000)
@@ -79,6 +85,10 @@ FFmpegEncoder::FFmpegEncoder (
_film->three_d(),
filename,
extension
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , key
+ , id
+#endif
)
);
}
@@ -196,20 +206,36 @@ FFmpegEncoder::FileEncoderSet::FileEncoderSet (
bool three_d,
boost::filesystem::path output,
string extension
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , optional<dcp::Key> key
+ , optional<string> id
+#endif
)
{
if (three_d) {
/// TRANSLATORS: L here is an abbreviation for "left", to indicate the left-eye part of a 3D export
_encoders[EYES_LEFT] = shared_ptr<FFmpegFileEncoder>(
- new FFmpegFileEncoder(video_frame_size, video_frame_rate, audio_frame_rate, channels, format, x264_crf, String::compose("%1_%2%3", output.string(), _("L"), extension))
+ new FFmpegFileEncoder(video_frame_size, video_frame_rate, audio_frame_rate, channels, format, x264_crf, String::compose("%1_%2%3", output.string(), _("L"), extension)
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , key, id
+#endif
+ )
);
/// TRANSLATORS: R here is an abbreviation for "right", to indicate the right-eye part of a 3D export
_encoders[EYES_RIGHT] = shared_ptr<FFmpegFileEncoder>(
- new FFmpegFileEncoder(video_frame_size, video_frame_rate, audio_frame_rate, channels, format, x264_crf, String::compose("%1_%2%3", output.string(), _("R"), extension))
+ new FFmpegFileEncoder(video_frame_size, video_frame_rate, audio_frame_rate, channels, format, x264_crf, String::compose("%1_%2%3", output.string(), _("R"), extension)
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , key, id
+#endif
+ )
);
} else {
_encoders[EYES_BOTH] = shared_ptr<FFmpegFileEncoder>(
- new FFmpegFileEncoder(video_frame_size, video_frame_rate, audio_frame_rate, channels, format, x264_crf, String::compose("%1%2", output.string(), extension))
+ new FFmpegFileEncoder(video_frame_size, video_frame_rate, audio_frame_rate, channels, format, x264_crf, String::compose("%1%2", output.string(), extension)
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , key, id
+#endif
+ )
);
}
}
diff --git a/src/lib/ffmpeg_encoder.h b/src/lib/ffmpeg_encoder.h
index 687d2981e..d8ffd2c6b 100644
--- a/src/lib/ffmpeg_encoder.h
+++ b/src/lib/ffmpeg_encoder.h
@@ -39,6 +39,10 @@ public:
bool mixdown_to_stereo,
bool split_reels,
int x264_crf
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , boost::optional<dcp::Key> key
+ , boost::optional<std::string> id
+#endif
);
void go ();
@@ -64,6 +68,10 @@ private:
bool three_d,
boost::filesystem::path output,
std::string extension
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , boost::optional<dcp::Key> key
+ , boost::optional<std::string> id
+#endif
);
boost::shared_ptr<FFmpegFileEncoder> get (Eyes eyes) const;
diff --git a/src/lib/ffmpeg_file_encoder.cc b/src/lib/ffmpeg_file_encoder.cc
index eb7036429..af6066bfd 100644
--- a/src/lib/ffmpeg_file_encoder.cc
+++ b/src/lib/ffmpeg_file_encoder.cc
@@ -38,6 +38,7 @@ using std::pair;
using boost::shared_ptr;
using boost::bind;
using boost::weak_ptr;
+using boost::optional;
using namespace dcpomatic;
int FFmpegFileEncoder::_video_stream_index = 0;
@@ -51,6 +52,10 @@ FFmpegFileEncoder::FFmpegFileEncoder (
ExportFormat format,
int x264_crf,
boost::filesystem::path output
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , optional<dcp::Key> key
+ , optional<string> id
+#endif
)
: _video_options (0)
, _audio_channels (channels)
@@ -80,7 +85,11 @@ FFmpegFileEncoder::FFmpegFileEncoder (
setup_video ();
setup_audio ();
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ int r = avformat_alloc_output_context2 (&_format_context, av_guess_format("mp4", 0, 0), 0, 0);
+#else
int r = avformat_alloc_output_context2 (&_format_context, 0, 0, _output.string().c_str());
+#endif
if (!_format_context) {
throw runtime_error (String::compose("could not allocate FFmpeg format context (%1)", r));
}
@@ -116,6 +125,22 @@ FFmpegFileEncoder::FFmpegFileEncoder (
throw runtime_error ("could not open FFmpeg output file");
}
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ if (key) {
+ AVDictionary* options = 0;
+ av_dict_set (&options, "encryption_key", key->hex().c_str(), 0);
+ /* XXX: is this OK? */
+ av_dict_set (&options, "encryption_kid", "00000000000000000000000000000000", 0);
+ av_dict_set (&options, "encryption_scheme", "cenc-aes-ctr", 0);
+ }
+
+ if (id) {
+ if (av_dict_set(&_format_context->metadata, SWAROOP_ID_TAG, id->c_str(), 0) < 0) {
+ throw runtime_error ("Could not write ID to output");
+ }
+ }
+#endif
+
if (avformat_write_header (_format_context, 0) < 0) {
throw runtime_error ("could not write header to FFmpeg output file");
}
diff --git a/src/lib/ffmpeg_file_encoder.h b/src/lib/ffmpeg_file_encoder.h
index 5308947e6..d763c7eaf 100644
--- a/src/lib/ffmpeg_file_encoder.h
+++ b/src/lib/ffmpeg_file_encoder.h
@@ -25,6 +25,7 @@
#include "event_history.h"
#include "audio_mapping.h"
#include "log.h"
+#include <dcp/key.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
@@ -41,6 +42,10 @@ public:
ExportFormat,
int x264_crf,
boost::filesystem::path output
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ , boost::optional<dcp::Key> key
+ , boost::optional<std::string> id
+#endif
);
void video (boost::shared_ptr<PlayerVideo>, dcpomatic::DCPTime);
diff --git a/src/lib/util.cc b/src/lib/util.cc
index 1f6fba963..3b6be6dcc 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -44,6 +44,7 @@
#include "ffmpeg_image_proxy.h"
#include "image.h"
#include "text_decoder.h"
+#include "job_manager.h"
#include <dcp/locale_convert.h>
#include <dcp/util.h>
#include <dcp/raw_convert.h>
@@ -945,6 +946,70 @@ emit_subtitle_image (ContentTimePeriod period, dcp::SubtitleImage sub, dcp::Size
decoder->emit_bitmap (period, image, rect);
}
+bool
+show_jobs_on_console (bool progress)
+{
+ bool should_stop = false;
+ bool first = true;
+ bool error = false;
+ while (!should_stop) {
+
+ dcpomatic_sleep (5);
+
+ list<shared_ptr<Job> > jobs = JobManager::instance()->get();
+
+ if (!first && progress) {
+ for (size_t i = 0; i < jobs.size(); ++i) {
+ cout << "\033[1A\033[2K";
+ }
+ cout.flush ();
+ }
+
+ first = false;
+
+ int unfinished = 0;
+ int finished_in_error = 0;
+
+ BOOST_FOREACH (shared_ptr<Job> i, jobs) {
+ if (progress) {
+ cout << i->name();
+ if (!i->sub_name().empty()) {
+ cout << "; " << i->sub_name();
+ }
+ cout << ": ";
+
+ if (i->progress ()) {
+ cout << i->status() << " \n";
+ } else {
+ cout << ": Running \n";
+ }
+ }
+
+ if (!i->finished ()) {
+ ++unfinished;
+ }
+
+ if (i->finished_in_error ()) {
+ ++finished_in_error;
+ error = true;
+ }
+
+ if (!progress && i->finished_in_error ()) {
+ /* We won't see this error if we haven't been showing progress,
+ so show it now.
+ */
+ cout << i->status() << "\n";
+ }
+ }
+
+ if (unfinished == 0 || finished_in_error != 0) {
+ should_stop = true;
+ }
+ }
+
+ return error;
+}
+
#ifdef DCPOMATIC_VARIANT_SWAROOP
/* Make up a key from the machine UUID */
diff --git a/src/lib/util.h b/src/lib/util.h
index f5218653d..d90053cdc 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -110,6 +110,7 @@ extern void checked_fwrite (void const * ptr, size_t size, FILE* stream, boost::
extern size_t utf8_strlen (std::string s);
extern std::string day_of_week_to_string (boost::gregorian::greg_weekday d);
extern void emit_subtitle_image (dcpomatic::ContentTimePeriod period, dcp::SubtitleImage sub, dcp::Size size, boost::shared_ptr<TextDecoder> decoder);
+extern bool show_jobs_on_console (bool progress);
#ifdef DCPOMATIC_VARIANT_SWAROOP
extern boost::shared_ptr<dcp::CertificateChain> read_swaroop_chain (boost::filesystem::path path);
extern void write_swaroop_chain (boost::shared_ptr<const dcp::CertificateChain> chain, boost::filesystem::path output);