+ optional<string> c = f.optional_string_child ("DCPContentType");
+ if (c) {
+ _dcp_content_type = DCPContentType::from_dci_name (c.get ());
+ }
+ }
+
+ {
+ optional<string> c = f.optional_string_child ("Container");
+ if (c) {
+ _container = Ratio::from_id (c.get ());
+ }
+ }
+
+ _resolution = string_to_resolution (f.string_child ("Resolution"));
+ _scaler = Scaler::from_id (f.string_child ("Scaler"));
+ _with_subtitles = f.bool_child ("WithSubtitles");
+ _j2k_bandwidth = f.number_child<int> ("J2KBandwidth");
+ _dci_metadata = DCIMetadata (f.node_child ("DCIMetadata"));
+ _video_frame_rate = f.number_child<int> ("VideoFrameRate");
+ _dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate"));
+ _audio_channels = f.number_child<int> ("AudioChannels");
+ _sequence_video = f.bool_child ("SequenceVideo");
+ _three_d = f.bool_child ("ThreeD");
+
+ _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"));
+
+ _dirty = false;
+}
+
+/** Given a directory name, return its full path within the Film's directory.
+ * The directory (and its parents) will be created if they do not exist.
+ */
+string
+Film::dir (string d) const
+{
+ boost::mutex::scoped_lock lm (_directory_mutex);
+
+ boost::filesystem::path p;
+ p /= _directory;
+ p /= d;
+
+ boost::filesystem::create_directories (p);
+
+ return p.string ();
+}
+
+/** Given a file or directory name, return its full path within the Film's directory.
+ * _directory_mutex must not be locked on entry.
+ * Any required parent directories will be created.
+ */
+string
+Film::file (string f) const
+{
+ boost::mutex::scoped_lock lm (_directory_mutex);
+
+ boost::filesystem::path p;
+ p /= _directory;
+ p /= f;
+
+ boost::filesystem::create_directories (p.parent_path ());
+
+ return p.string ();
+}
+
+/** @return a DCI-compliant name for a DCP of this film */
+string
+Film::dci_name (bool if_created_now) const
+{
+ stringstream d;
+
+ string fixed_name = to_upper_copy (name());
+ for (size_t i = 0; i < fixed_name.length(); ++i) {
+ if (fixed_name[i] == ' ') {
+ fixed_name[i] = '-';
+ }