+ return optional<double> ();
+}
+
+string
+VideoContent::processing_description () const
+{
+ /* stringstream is OK here as this string is just for presentation to the user */
+ SafeStringStream d;
+
+ if (video_size().width && video_size().height) {
+ d << String::compose (
+ _("Content video is %1x%2"),
+ video_size_after_3d_split().width,
+ video_size_after_3d_split().height
+ );
+
+
+ double ratio = video_size_after_3d_split().ratio ();
+
+ if (sample_aspect_ratio ()) {
+ d << ", " << _("pixel aspect ratio") << " " << fixed << setprecision(2) << sample_aspect_ratio().get () << ":1";
+ ratio *= sample_aspect_ratio().get ();
+ }
+
+ d << "\n" << _("Display aspect ratio") << " " << fixed << setprecision(2) << ratio << ":1\n";
+ }
+
+ if ((crop().left || crop().right || crop().top || crop().bottom) && video_size() != dcp::Size (0, 0)) {
+ dcp::Size cropped = video_size_after_crop ();
+ d << String::compose (
+ _("Cropped to %1x%2"),
+ cropped.width, cropped.height
+ );
+
+ d << " (" << fixed << setprecision(2) << cropped.ratio () << ":1)\n";
+ }
+
+ dcp::Size const container_size = film()->frame_size ();
+ dcp::Size const scaled = scale().size (dynamic_pointer_cast<const VideoContent> (shared_from_this ()), container_size, container_size);
+
+ if (scaled != video_size_after_crop ()) {
+ d << String::compose (
+ _("Scaled to %1x%2"),
+ scaled.width, scaled.height
+ );
+
+ d << " (" << fixed << setprecision(2) << scaled.ratio() << ":1)\n";
+ }
+
+ if (scaled != container_size) {
+ d << String::compose (
+ _("Padded with black to fit container %1 (%2x%3)"),
+ film()->container()->nickname (),
+ container_size.width, container_size.height
+ );
+
+ d << " (" << fixed << setprecision(2) << container_size.ratio () << ":1)\n";
+ }
+
+ d << _("Content frame rate");
+ d << " " << fixed << setprecision(4) << video_frame_rate() << "\n";
+
+ FrameRateChange frc (video_frame_rate(), film()->video_frame_rate ());
+ d << frc.description () << "\n";
+
+ return d.str ();
+}
+
+void
+VideoContent::add_properties (list<pair<string, string> >& p) const
+{
+ p.push_back (make_pair (_("Video length"), raw_convert<string> (video_length ()) + " " + _("video frames")));
+ p.push_back (make_pair (_("Video size"), raw_convert<string> (video_size().width) + "x" + raw_convert<string> (video_size().height)));
+ p.push_back (make_pair (_("Video frame rate"), raw_convert<string> (video_frame_rate()) + " " + _("frames per second")));
+}
+
+list<DCPTime>
+VideoContent::reel_split_points () const
+{
+ list<DCPTime> t;
+ /* XXX: this is questionable; perhaps the position should be forced to be on a frame boundary */
+ t.push_back (position().round_up (film()->video_frame_rate()));
+ return t;
+}
+
+double
+VideoContent::video_frame_rate () const
+{
+ boost::mutex::scoped_lock lm (_mutex);
+ return _video_frame_rate.get_value_or (film()->video_frame_rate ());