+ _isdcf_metadata = _template_film->_isdcf_metadata;
+}
+
+pair<double, double>
+Film::speed_up_range (int dcp_frame_rate) const
+{
+ return _playlist->speed_up_range (dcp_frame_rate);
+}
+
+void
+Film::copy_from (shared_ptr<const Film> film)
+{
+ read_metadata (film->file (metadata_file));
+}
+
+bool
+Film::references_dcp_video () const
+{
+ BOOST_FOREACH (shared_ptr<Content> i, _playlist->content()) {
+ shared_ptr<DCPContent> d = dynamic_pointer_cast<DCPContent>(i);
+ if (d && d->reference_video()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+Film::references_dcp_audio () const
+{
+ BOOST_FOREACH (shared_ptr<Content> i, _playlist->content()) {
+ shared_ptr<DCPContent> d = dynamic_pointer_cast<DCPContent>(i);
+ if (d && d->reference_audio()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+list<DCPTextTrack>
+Film::closed_caption_tracks () const
+{
+ list<DCPTextTrack> tt;
+ BOOST_FOREACH (shared_ptr<Content> i, content()) {
+ BOOST_FOREACH (shared_ptr<TextContent> j, i->text) {
+ /* XXX: Empty DCPTextTrack ends up being a magic value here */
+ DCPTextTrack dtt = j->dcp_track().get_value_or(DCPTextTrack());
+ if (j->type() == TEXT_CLOSED_CAPTION && find(tt.begin(), tt.end(), dtt) == tt.end()) {
+ tt.push_back (dtt);
+ }
+ }
+ }
+
+ return tt;