summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2018-07-21 21:47:25 +0100
committerCarl Hetherington <cth@carlh.net>2018-07-21 21:47:25 +0100
commit6199e090dc1e32d3753ba7e7d7ea8c5f0d79f046 (patch)
treeb09d9b6b19dadb694590981775a61f829b6f3622 /src/lib
parentcbd4450197a083bf58bda510e626f73ba583cb66 (diff)
Revert "Remove join function; the code is long and I don't think anybody"
It turns out Carsten uses it :) This reverts commit bd5e8b83a3a18787241982efdae809d4db21f65d.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_content.cc21
-rw-r--r--src/lib/audio_content.h1
-rw-r--r--src/lib/caption_content.cc77
-rw-r--r--src/lib/caption_content.h1
-rw-r--r--src/lib/content.cc34
-rw-r--r--src/lib/content.h1
-rw-r--r--src/lib/exceptions.h8
-rw-r--r--src/lib/ffmpeg_content.cc61
-rw-r--r--src/lib/ffmpeg_content.h1
-rw-r--r--src/lib/video_content.cc52
-rw-r--r--src/lib/video_content.h3
11 files changed, 258 insertions, 2 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc
index d4ce6c243..a252e4b5a 100644
--- a/src/lib/audio_content.cc
+++ b/src/lib/audio_content.cc
@@ -91,6 +91,27 @@ AudioContent::AudioContent (Content* parent, cxml::ConstNodePtr node)
}
}
+AudioContent::AudioContent (Content* parent, vector<shared_ptr<Content> > c)
+ : ContentPart (parent)
+{
+ shared_ptr<AudioContent> ref = c[0]->audio;
+ DCPOMATIC_ASSERT (ref);
+
+ for (size_t i = 1; i < c.size(); ++i) {
+ if (c[i]->audio->gain() != ref->gain()) {
+ throw JoinError (_("Content to be joined must have the same audio gain."));
+ }
+
+ if (c[i]->audio->delay() != ref->delay()) {
+ throw JoinError (_("Content to be joined must have the same audio delay."));
+ }
+ }
+
+ _gain = ref->gain ();
+ _delay = ref->delay ();
+ _streams = ref->streams ();
+}
+
void
AudioContent::as_xml (xmlpp::Node* node) const
{
diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h
index d73c73735..a1f5ba8a0 100644
--- a/src/lib/audio_content.h
+++ b/src/lib/audio_content.h
@@ -44,6 +44,7 @@ class AudioContent : public ContentPart
{
public:
explicit AudioContent (Content* parent);
+ AudioContent (Content* parent, std::vector<boost::shared_ptr<Content> >);
void as_xml (xmlpp::Node *) const;
std::string technical_summary () const;
diff --git a/src/lib/caption_content.cc b/src/lib/caption_content.cc
index d44fb55c5..0d13568e2 100644
--- a/src/lib/caption_content.cc
+++ b/src/lib/caption_content.cc
@@ -228,6 +228,83 @@ CaptionContent::CaptionContent (Content* parent, cxml::ConstNodePtr node, int ve
_original_type = string_to_caption_type (node->optional_string_child("Type").get_value_or("open"));
}
+CaptionContent::CaptionContent (Content* parent, vector<shared_ptr<Content> > c)
+ : ContentPart (parent)
+{
+ shared_ptr<CaptionContent> ref = c[0]->caption;
+ DCPOMATIC_ASSERT (ref);
+ list<shared_ptr<Font> > ref_fonts = ref->fonts ();
+
+ for (size_t i = 1; i < c.size(); ++i) {
+
+ if (c[i]->caption->use() != ref->use()) {
+ throw JoinError (_("Content to be joined must have the same 'use subtitles' setting."));
+ }
+
+ if (c[i]->caption->burn() != ref->burn()) {
+ throw JoinError (_("Content to be joined must have the same 'burn subtitles' setting."));
+ }
+
+ if (c[i]->caption->x_offset() != ref->x_offset()) {
+ throw JoinError (_("Content to be joined must have the same subtitle X offset."));
+ }
+
+ if (c[i]->caption->y_offset() != ref->y_offset()) {
+ throw JoinError (_("Content to be joined must have the same subtitle Y offset."));
+ }
+
+ if (c[i]->caption->x_scale() != ref->x_scale()) {
+ throw JoinError (_("Content to be joined must have the same subtitle X scale."));
+ }
+
+ if (c[i]->caption->y_scale() != ref->y_scale()) {
+ throw JoinError (_("Content to be joined must have the same subtitle Y scale."));
+ }
+
+ if (c[i]->caption->line_spacing() != ref->line_spacing()) {
+ throw JoinError (_("Content to be joined must have the same subtitle line spacing."));
+ }
+
+ if ((c[i]->caption->fade_in() != ref->fade_in()) || (c[i]->caption->fade_out() != ref->fade_out())) {
+ throw JoinError (_("Content to be joined must have the same subtitle fades."));
+ }
+
+ if ((c[i]->caption->outline_width() != ref->outline_width())) {
+ throw JoinError (_("Content to be joined must have the same outline width."));
+ }
+
+ list<shared_ptr<Font> > fonts = c[i]->caption->fonts ();
+ if (fonts.size() != ref_fonts.size()) {
+ throw JoinError (_("Content to be joined must use the same fonts."));
+ }
+
+ list<shared_ptr<Font> >::const_iterator j = ref_fonts.begin ();
+ list<shared_ptr<Font> >::const_iterator k = fonts.begin ();
+
+ while (j != ref_fonts.end ()) {
+ if (**j != **k) {
+ throw JoinError (_("Content to be joined must use the same fonts."));
+ }
+ ++j;
+ ++k;
+ }
+ }
+
+ _use = ref->use ();
+ _burn = ref->burn ();
+ _x_offset = ref->x_offset ();
+ _y_offset = ref->y_offset ();
+ _x_scale = ref->x_scale ();
+ _y_scale = ref->y_scale ();
+ _language = ref->language ();
+ _fonts = ref_fonts;
+ _line_spacing = ref->line_spacing ();
+ _fade_in = ref->fade_in ();
+ _fade_out = ref->fade_out ();
+ _outline_width = ref->outline_width ();
+
+ connect_to_fonts ();
+}
/** _mutex must not be held on entry */
void
diff --git a/src/lib/caption_content.h b/src/lib/caption_content.h
index 4152dc533..767fc7234 100644
--- a/src/lib/caption_content.h
+++ b/src/lib/caption_content.h
@@ -59,6 +59,7 @@ class CaptionContent : public ContentPart
{
public:
explicit CaptionContent (Content* parent);
+ CaptionContent (Content* parent, std::vector<boost::shared_ptr<Content> >);
void as_xml (xmlpp::Node *) const;
std::string identifier () const;
diff --git a/src/lib/content.cc b/src/lib/content.cc
index 13c5794fe..629672b73 100644
--- a/src/lib/content.cc
+++ b/src/lib/content.cc
@@ -104,6 +104,40 @@ Content::Content (shared_ptr<const Film> film, cxml::ConstNodePtr node)
_video_frame_rate = node->optional_number_child<double> ("VideoFrameRate");
}
+Content::Content (shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
+ : _film (film)
+ , _position (c.front()->position ())
+ , _trim_start (c.front()->trim_start ())
+ , _trim_end (c.back()->trim_end ())
+ , _video_frame_rate (c.front()->video_frame_rate())
+ , _change_signals_frequent (false)
+{
+ for (size_t i = 0; i < c.size(); ++i) {
+ if (i > 0 && c[i]->trim_start() > ContentTime ()) {
+ throw JoinError (_("Only the first piece of content to be joined can have a start trim."));
+ }
+
+ if (i < (c.size() - 1) && c[i]->trim_end () > ContentTime ()) {
+ throw JoinError (_("Only the last piece of content to be joined can have an end trim."));
+ }
+
+ if (
+ (_video_frame_rate && !c[i]->_video_frame_rate) ||
+ (!_video_frame_rate && c[i]->_video_frame_rate)
+ ) {
+ throw JoinError (_("Content to be joined must have the same video frame rate"));
+ }
+
+ if (_video_frame_rate && fabs (_video_frame_rate.get() - c[i]->_video_frame_rate.get()) > VIDEO_FRAME_RATE_EPSILON) {
+ throw JoinError (_("Content to be joined must have the same video frame rate"));
+ }
+
+ for (size_t j = 0; j < c[i]->number_of_paths(); ++j) {
+ _paths.push_back (c[i]->path (j));
+ }
+ }
+}
+
void
Content::as_xml (xmlpp::Node* node, bool with_paths) const
{
diff --git a/src/lib/content.h b/src/lib/content.h
index 2a249011a..d84f636fb 100644
--- a/src/lib/content.h
+++ b/src/lib/content.h
@@ -67,6 +67,7 @@ public:
Content (boost::shared_ptr<const Film>, DCPTime);
Content (boost::shared_ptr<const Film>, boost::filesystem::path);
Content (boost::shared_ptr<const Film>, cxml::ConstNodePtr);
+ Content (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
virtual ~Content () {}
/** Examine the content to establish digest, frame rates and any other
diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h
index 769857fd3..eceafa105 100644
--- a/src/lib/exceptions.h
+++ b/src/lib/exceptions.h
@@ -81,6 +81,14 @@ private:
boost::filesystem::path _file;
};
+class JoinError : public std::runtime_error
+{
+public:
+ explicit JoinError (std::string s)
+ : std::runtime_error (s)
+ {}
+};
+
/** @class OpenFileError.
* @brief Indicates that some error occurred when trying to open a file.
*/
diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc
index ddf4548b4..db999df20 100644
--- a/src/lib/ffmpeg_content.cc
+++ b/src/lib/ffmpeg_content.cc
@@ -128,6 +128,67 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr no
}
+FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
+ : Content (film, c)
+{
+ vector<shared_ptr<Content> >::const_iterator i = c.begin ();
+
+ bool need_video = false;
+ bool need_audio = false;
+ bool need_caption = false;
+
+ if (i != c.end ()) {
+ need_video = static_cast<bool> ((*i)->video);
+ need_audio = static_cast<bool> ((*i)->audio);
+ need_caption = static_cast<bool> ((*i)->caption);
+ }
+
+ while (i != c.end ()) {
+ if (need_video != static_cast<bool> ((*i)->video)) {
+ throw JoinError (_("Content to be joined must all have or not have video"));
+ }
+ if (need_audio != static_cast<bool> ((*i)->audio)) {
+ throw JoinError (_("Content to be joined must all have or not have audio"));
+ }
+ if (need_caption != static_cast<bool> ((*i)->caption)) {
+ throw JoinError (_("Content to be joined must all have or not have captions"));
+ }
+ ++i;
+ }
+
+ if (need_video) {
+ video.reset (new VideoContent (this, c));
+ }
+ if (need_audio) {
+ audio.reset (new AudioContent (this, c));
+ }
+ if (need_caption) {
+ caption.reset (new CaptionContent (this, c));
+ }
+
+ shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
+ DCPOMATIC_ASSERT (ref);
+
+ for (size_t i = 0; i < c.size(); ++i) {
+ shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (c[i]);
+ if (fc->caption && fc->caption->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
+ throw JoinError (_("Content to be joined must use the same subtitle stream."));
+ }
+ }
+
+ /* XXX: should probably check that more of the stuff below is the same in *this and ref */
+
+ _subtitle_streams = ref->subtitle_streams ();
+ _subtitle_stream = ref->subtitle_stream ();
+ _first_video = ref->_first_video;
+ _filters = ref->_filters;
+ _color_range = ref->_color_range;
+ _color_primaries = ref->_color_primaries;
+ _color_trc = ref->_color_trc;
+ _colorspace = ref->_colorspace;
+ _bits_per_pixel = ref->_bits_per_pixel;
+}
+
void
FFmpegContent::as_xml (xmlpp::Node* node, bool with_paths) const
{
diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h
index 21f5d4680..64f6f9ff8 100644
--- a/src/lib/ffmpeg_content.h
+++ b/src/lib/ffmpeg_content.h
@@ -48,6 +48,7 @@ class FFmpegContent : public Content
public:
FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path);
FFmpegContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int version, std::list<std::string> &);
+ FFmpegContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
boost::shared_ptr<FFmpegContent> shared_from_this () {
return boost::dynamic_pointer_cast<FFmpegContent> (Content::shared_from_this ());
diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc
index 0dba55525..d3ba6c1ab 100644
--- a/src/lib/video_content.cc
+++ b/src/lib/video_content.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -154,6 +154,56 @@ VideoContent::VideoContent (Content* parent, cxml::ConstNodePtr node, int versio
}
}
+VideoContent::VideoContent (Content* parent, vector<shared_ptr<Content> > c)
+ : ContentPart (parent)
+ , _length (0)
+ , _yuv (false)
+{
+ shared_ptr<VideoContent> ref = c[0]->video;
+ DCPOMATIC_ASSERT (ref);
+
+ for (size_t i = 1; i < c.size(); ++i) {
+
+ if (c[i]->video->size() != ref->size()) {
+ throw JoinError (_("Content to be joined must have the same picture size."));
+ }
+
+ if (c[i]->video->frame_type() != ref->frame_type()) {
+ throw JoinError (_("Content to be joined must have the same video frame type."));
+ }
+
+ if (c[i]->video->crop() != ref->crop()) {
+ throw JoinError (_("Content to be joined must have the same crop."));
+ }
+
+ if (c[i]->video->scale() != ref->scale()) {
+ throw JoinError (_("Content to be joined must have the same scale setting."));
+ }
+
+ if (c[i]->video->colour_conversion() != ref->colour_conversion()) {
+ throw JoinError (_("Content to be joined must have the same colour conversion."));
+ }
+
+ if (c[i]->video->fade_in() != ref->fade_in() || c[i]->video->fade_out() != ref->fade_out()) {
+ throw JoinError (_("Content to be joined must have the same fades."));
+ }
+
+ _length += c[i]->video->length ();
+
+ if (c[i]->video->yuv ()) {
+ _yuv = true;
+ }
+ }
+
+ _size = ref->size ();
+ _frame_type = ref->frame_type ();
+ _crop = ref->crop ();
+ _scale = ref->scale ();
+ _colour_conversion = ref->colour_conversion ();
+ _fade_in = ref->fade_in ();
+ _fade_out = ref->fade_out ();
+}
+
void
VideoContent::as_xml (xmlpp::Node* node) const
{
diff --git a/src/lib/video_content.h b/src/lib/video_content.h
index 1fc87bb9b..774210c13 100644
--- a/src/lib/video_content.h
+++ b/src/lib/video_content.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -52,6 +52,7 @@ class VideoContent : public ContentPart, public boost::enable_shared_from_this<V
{
public:
explicit VideoContent (Content* parent);
+ VideoContent (Content* parent, std::vector<boost::shared_ptr<Content> >);
void as_xml (xmlpp::Node *) const;
std::string technical_summary () const;