2 Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
4 This file is part of libdcp.
6 libdcp is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 libdcp is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with libdcp. If not, see <http://www.gnu.org/licenses/>.
19 In addition, as a special exception, the copyright holders give
20 permission to link the code of portions of this program with the
21 OpenSSL library under certain conditions as described in each
22 individual source file, and distribute linked combinations
25 You must obey the GNU General Public License in all respects
26 for all of the code used other than OpenSSL. If you modify
27 file(s) with this exception, you may extend this exception to your
28 version of the file(s), but you are not obligated to do so. If you
29 do not wish to do so, delete this exception statement from your
30 version. If you delete this exception statement from all source
31 files in the program, then also delete it here.
45 #include "certificate.h"
47 #include "language_tag.h"
50 #include <boost/filesystem.hpp>
51 #include <boost/function.hpp>
52 #include <boost/optional.hpp>
57 struct verify_invalid_language3;
66 class CertificateChain;
71 * @brief A Composition Playlist
73 * A CPL contains some metadata and a list of Reel objects, each of which may contain picture, sound and other assets
74 * such as subtitles and closed captions.
76 * After creating a CPL you can add Reel objects with add(), and write an XML file describing the CPL with
79 class CPL : public Asset
82 CPL (std::string annotation_text, ContentKind content_kind, Standard standard);
84 /** Construct a CPL object from a XML file */
85 explicit CPL (boost::filesystem::path file);
88 std::shared_ptr<const Asset> other,
89 EqualityOptions options,
93 /** Add a reel to this CPL
94 * @param reel Reel to add
96 void add (std::shared_ptr<Reel> reel);
98 /** Add a KDM to this CPL. If the KDM is for any of this CPLs assets it will be used
99 * to decrypt those assets.
102 void add (DecryptedKDM const &);
104 /** @return the reels in this CPL */
105 std::vector<std::shared_ptr<Reel>> reels () const {
109 /** @return the ReelFileAssets in this CPL in all reels */
110 std::vector<std::shared_ptr<const ReelFileAsset>> reel_file_assets () const;
111 std::vector<std::shared_ptr<ReelFileAsset>> reel_file_assets ();
113 /** @return true if we have any encrypted content */
114 bool any_encrypted () const;
116 /** @return true if we have all our encryptable content is encrypted */
117 bool all_encrypted () const;
119 /** Write an CompositonPlaylist XML file
121 * @param file Filename to write
122 * @param signer Signer to sign the CPL, or 0 to add no signature
125 boost::filesystem::path file,
126 std::shared_ptr<const CertificateChain>
129 void resolve_refs (std::vector<std::shared_ptr<Asset>>);
131 int64_t duration () const;
133 std::string issuer () const {
137 void set_issuer (std::string issuer) {
141 std::string creator () const {
145 void set_creator (std::string creator) {
149 void set_issue_date (std::string issue_date) {
150 _issue_date = issue_date;
153 /** @return contents of the <AnnotationText> node, if present */
154 boost::optional<std::string> annotation_text () const {
155 return _annotation_text;
158 void set_annotation_text (std::string at) {
159 _annotation_text = at;
162 /** @return contents of the <ContentTitleText> node */
163 std::string content_title_text () const {
164 return _content_title_text;
167 void set_content_title_text (std::string ct) {
168 _content_title_text = ct;
171 void set_content_kind (dcp::ContentKind k) {
175 /** @return the type of the content, used by media servers
176 * to categorise things (e.g. feature, trailer, etc.)
178 ContentKind content_kind () const {
179 return _content_kind;
182 boost::optional<ContentVersion> content_version () const;
184 std::vector<ContentVersion> content_versions () const {
185 return _content_versions;
188 void set_content_version (ContentVersion v) {
189 _content_versions.clear ();
190 _content_versions.push_back (v);
193 void set_content_versions (std::vector<ContentVersion> v);
195 std::vector<Rating> ratings () const {
199 void set_ratings (std::vector<Rating> r) {
203 boost::optional<std::string> full_content_title_text () const {
204 return _full_content_title_text;
207 void set_full_content_title_text (std::string t) {
208 _full_content_title_text = t;
211 boost::optional<std::string> full_content_title_text_language () const {
212 return _full_content_title_text_language;
215 void set_full_content_title_text_language (dcp::LanguageTag l) {
216 _full_content_title_text_language = l.to_string();
219 boost::optional<std::string> release_territory () const {
220 return _release_territory;
223 void set_release_territory (dcp::LanguageTag::RegionSubtag t) {
224 _release_territory = t.subtag();
227 boost::optional<std::string> release_territory_scope () const {
228 return _release_territory_scope;
231 boost::optional<int> version_number () const {
232 return _version_number;
235 void set_version_number (int v);
237 void unset_version_number ();
239 boost::optional<Status> status () const {
243 void set_status (Status s) {
247 boost::optional<std::string> chain () const {
251 void set_chain (std::string c) {
255 boost::optional<std::string> distributor () const {
259 void set_distributor (std::string d) {
263 boost::optional<std::string> facility () const {
267 void set_facility (std::string f) {
271 boost::optional<Luminance> luminance () const {
275 void set_luminance (Luminance l) {
279 boost::optional<std::string> main_sound_configuration () const {
280 return _main_sound_configuration;
283 void set_main_sound_configuration (std::string c) {
284 _main_sound_configuration = c;
287 boost::optional<int> main_sound_sample_rate () const {
288 return _main_sound_sample_rate;
291 void set_main_sound_sample_rate (int r) {
292 _main_sound_sample_rate = r;
295 boost::optional<dcp::Size> main_picture_stored_area () const {
296 return _main_picture_stored_area;
299 void set_main_picture_stored_area (dcp::Size s) {
300 _main_picture_stored_area = s;
303 boost::optional<dcp::Size> main_picture_active_area () const {
304 return _main_picture_active_area;
307 void set_main_picture_active_area (dcp::Size s) {
308 _main_picture_active_area = s;
311 std::vector<std::string> additional_subtitle_languages () const {
312 return _additional_subtitle_languages;
315 void set_additional_subtitle_languages (std::vector<dcp::LanguageTag> const& lang);
317 void set_sign_language_video_language (dcp::LanguageTag lang) {
318 _sign_language_video_language = lang.to_string();
321 boost::optional<std::string> sign_language_video_language () const {
322 return _sign_language_video_language;
325 Standard standard () const {
329 static std::string static_pkl_type (Standard standard);
332 /** @return type string for PKLs for this asset */
333 std::string pkl_type (Standard standard) const override;
336 friend struct ::verify_invalid_language3;
338 void maybe_write_composition_metadata_asset (xmlpp::Element* node) const;
339 void read_composition_metadata_asset (cxml::ConstNodePtr node);
342 std::string _creator;
343 std::string _issue_date;
344 boost::optional<std::string> _annotation_text;
345 std::string _content_title_text; ///< <ContentTitleText>
346 ContentKind _content_kind; ///< <ContentKind>
347 std::vector<ContentVersion> _content_versions;
348 std::vector<Rating> _ratings;
349 /** ID for CompositionMetadataAsset tag; either a random one, ready for writing a new tag,
350 * or the one read in from the existing CPL.
352 std::string _cpl_metadata_id = make_uuid();
353 /** Human-readable name of the composition, without any metadata (i.e. no -FTR-EN-XX- etc.) */
354 boost::optional<std::string> _full_content_title_text;
355 boost::optional<std::string> _full_content_title_text_language;
356 /** This is stored and returned as a string so that we can tolerate non-RFC-5646 strings,
357 * but must be set as a dcp::LanguageTag to try to ensure that we create compliant output.
359 boost::optional<std::string> _release_territory;
360 boost::optional<std::string> _release_territory_scope;
361 boost::optional<int> _version_number;
362 boost::optional<Status> _status;
363 boost::optional<std::string> _chain;
364 boost::optional<std::string> _distributor;
365 boost::optional<std::string> _facility;
366 boost::optional<Luminance> _luminance;
367 boost::optional<std::string> _main_sound_configuration;
368 boost::optional<int> _main_sound_sample_rate;
369 boost::optional<dcp::Size> _main_picture_stored_area;
370 boost::optional<dcp::Size> _main_picture_active_area;
371 /* See note for _release_territory above */
372 std::vector<std::string> _additional_subtitle_languages;
373 boost::optional<std::string> _sign_language_video_language;
375 std::vector<std::shared_ptr<Reel>> _reels;
377 /** Standard of CPL that was read in */