+ return 1 - double (f - fade_out_start) / fade_out();
+ }
+
+ 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";