+
+string
+VideoContent::technical_summary () const
+{
+ return String::compose ("video: length %1, size %2x%3, rate %4", video_length(), video_size().width, video_size().height, video_frame_rate());
+}
+
+libdcp::Size
+VideoContent::video_size_after_3d_split () const
+{
+ libdcp::Size const s = video_size ();
+ switch (video_frame_type ()) {
+ case VIDEO_FRAME_TYPE_2D:
+ return s;
+ case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT:
+ return libdcp::Size (s.width / 2, s.height);
+ }
+
+ assert (false);
+}
+
+void
+VideoContent::set_colour_conversion (ColourConversion c)
+{
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ _colour_conversion = c;
+ }
+
+ signal_changed (VideoContentProperty::COLOUR_CONVERSION);
+}
+
+/** @return Video size after 3D split and crop */
+libdcp::Size
+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, rounded up so that the frame index
+ * is that of the next complete frame which starts after `t'.
+ */
+VideoContent::Frame
+VideoContent::time_to_content_video_frames (DCPTime t) const
+{
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
+ /* 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; source rate will be equal to DCP rate if we ignore
+ double/skip. There's no need to call Film::active_frame_rate_change() here
+ as we know that we are it (since we're video).
+ */
+ FrameRateChange frc (video_frame_rate(), film->video_frame_rate());
+ return ceil (t * film->video_frame_rate() / (frc.factor() * TIME_HZ));
+}