Basics of joining.
[dcpomatic.git] / src / lib / video_content.cc
index 23ef2cf89dcce74463abcbadc0bbd8d824b0905d..ca4ed8a9f019bcd9525997f779e76b5c33822af8 100644 (file)
@@ -26,6 +26,9 @@
 #include "compose.hpp"
 #include "config.h"
 #include "colour_conversion.h"
+#include "util.h"
+#include "film.h"
+#include "exceptions.h"
 
 #include "i18n.h"
 
@@ -40,9 +43,21 @@ using std::string;
 using std::stringstream;
 using std::setprecision;
 using std::cout;
+using std::vector;
 using boost::shared_ptr;
 using boost::lexical_cast;
 using boost::optional;
+using boost::dynamic_pointer_cast;
+
+VideoContent::VideoContent (shared_ptr<const Film> f)
+       : Content (f)
+       , _video_length (0)
+       , _video_frame_rate (0)
+       , _video_frame_type (VIDEO_FRAME_TYPE_2D)
+       , _ratio (Ratio::from_id ("185"))
+{
+       setup_default_colour_conversion ();
+}
 
 VideoContent::VideoContent (shared_ptr<const Film> f, Time s, VideoContent::Frame len)
        : Content (f, s)
@@ -84,6 +99,48 @@ VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Nod
        _colour_conversion = ColourConversion (node->node_child ("ColourConversion"));
 }
 
+VideoContent::VideoContent (shared_ptr<const Film> f, vector<shared_ptr<Content> > c)
+       : Content (f, c)
+{
+       shared_ptr<VideoContent> ref = dynamic_pointer_cast<VideoContent> (c[0]);
+       assert (ref);
+       
+       for (size_t i = 0; i < c.size(); ++i) {
+               shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (c[i]);
+
+               if (vc->video_size() != ref->video_size()) {
+                       throw JoinError (_("Content to be joined must have the same picture size."));
+               }
+
+               if (vc->video_frame_rate() != ref->video_frame_rate()) {
+                       throw JoinError (_("Content to be joined must have the same video frame rate."));
+               }
+
+               if (vc->video_frame_type() != ref->video_frame_type()) {
+                       throw JoinError (_("Content to be joined must have the same video frame type."));
+               }
+
+               if (vc->crop() != ref->crop()) {
+                       throw JoinError (_("Content to be joined must have the same crop."));
+               }
+
+               if (vc->ratio() != ref->ratio()) {
+                       throw JoinError (_("Content to be joined must have the same ratio."));
+               }
+
+               if (vc->colour_conversion() != ref->colour_conversion()) {
+                       throw JoinError (_("Content to be joined must have the same colour conversion."));
+               }
+       }
+
+       _video_size = ref->video_size ();
+       _video_frame_rate = ref->video_frame_rate ();
+       _video_frame_type = ref->video_frame_type ();
+       _crop = ref->crop ();
+       _ratio = ref->ratio ();
+       _colour_conversion = ref->colour_conversion ();
+}
+
 void
 VideoContent::as_xml (xmlpp::Node* node) const
 {
@@ -227,7 +284,7 @@ string
 VideoContent::identifier () const
 {
        stringstream s;
-       s << Content::digest()
+       s << Content::identifier()
          << "_" << crop().left
          << "_" << crop().right
          << "_" << crop().top
@@ -289,3 +346,21 @@ VideoContent::video_size_after_crop () const
 {
        return crop().apply (video_size_after_3d_split ());
 }
+
+/** @param t A time offset from the start of this piece of content.
+ *  @return Corresponding frame index.
+ */
+VideoContent::Frame
+VideoContent::time_to_content_video_frames (Time t) const
+{
+       shared_ptr<const Film> film = _film.lock ();
+       assert (film);
+       
+       FrameRateConversion frc (video_frame_rate(), film->video_frame_rate());
+
+       /* Here we are converting from time (in the DCP) to a frame number in the content.
+          Hence we need to use the DCP's frame rate and the double/skip correction, not
+          the source's rate.
+       */
+       return t * film->video_frame_rate() / (frc.factor() * TIME_HZ);
+}