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"
46 #include "content_kind.h"
48 #include "language_tag.h"
51 #include <boost/filesystem.hpp>
52 #include <boost/function.hpp>
53 #include <boost/optional.hpp>
58 struct verify_invalid_language3;
64 class CertificateChain;
73 * @brief A Composition Playlist
75 * A CPL contains some metadata and a list of Reel objects, each of which may contain picture, sound and other assets
76 * such as subtitles and closed captions.
78 * After creating a CPL you can add Reel objects with add(), and write an XML file describing the CPL with
81 class CPL : public Asset
84 CPL (std::string annotation_text, ContentKind content_kind, Standard standard);
86 /** Construct a CPL object from a XML file.
87 * If notes is not null, non-fatal errors will be added.
88 * Exceptions will be thrown on non-recoverable errors.
90 explicit CPL(boost::filesystem::path file, std::vector<dcp::VerificationNote>* notes = nullptr);
93 std::shared_ptr<const Asset> other,
94 EqualityOptions const& options,
98 /** Add a reel to this CPL
99 * @param reel Reel to add
101 void add (std::shared_ptr<Reel> reel);
103 void set (std::vector<std::shared_ptr<Reel>> reels);
105 /** Add a KDM to this CPL. If the KDM is for any of this CPLs assets it will be used
106 * to decrypt those assets.
109 void add (DecryptedKDM const &);
111 /** @return the reels in this CPL */
112 std::vector<std::shared_ptr<Reel>> reels () const {
116 /** @return the ReelFileAssets in this CPL in all reels */
117 std::vector<std::shared_ptr<const ReelFileAsset>> reel_file_assets () const;
118 std::vector<std::shared_ptr<ReelFileAsset>> reel_file_assets ();
120 /** @return true if we have any encrypted content */
121 bool any_encrypted () const;
123 /** @return true if we have all our encryptable content is encrypted */
124 bool all_encrypted () const;
126 /** Write a CompositionPlaylist XML file
128 * @param file Filename to write
129 * @param signer Signer to sign the CPL, or 0 to add no signature
130 * @param include_mca_subdescriptors true to add a MCASubDescriptors tag to metadata,
134 boost::filesystem::path file,
135 std::shared_ptr<const CertificateChain>,
136 bool include_mca_subdescriptors = true
139 void resolve_refs (std::vector<std::shared_ptr<Asset>>);
141 int64_t duration () const;
143 std::string issuer () const {
147 void set_issuer (std::string issuer) {
151 std::string creator () const {
155 void set_creator (std::string creator) {
159 void set_issue_date (std::string issue_date) {
160 _issue_date = issue_date;
163 /** @return contents of the <AnnotationText> node, if present */
164 boost::optional<std::string> annotation_text () const {
165 return _annotation_text;
168 void set_annotation_text (std::string at) {
169 _annotation_text = at;
172 /** @return contents of the <ContentTitleText> node */
173 std::string content_title_text () const {
174 return _content_title_text;
177 void set_content_title_text (std::string ct) {
178 _content_title_text = ct;
181 void set_content_kind (dcp::ContentKind k) {
185 /** @return the type of the content, used by media servers
186 * to categorise things (e.g. feature, trailer, etc.)
188 ContentKind content_kind () const {
189 return _content_kind;
192 boost::optional<ContentVersion> content_version () const;
194 std::vector<ContentVersion> content_versions () const {
195 return _content_versions;
198 void set_content_version (ContentVersion v) {
199 _content_versions.clear ();
200 _content_versions.push_back (v);
203 void set_content_versions (std::vector<ContentVersion> v);
205 std::vector<Rating> ratings () const {
209 void set_ratings (std::vector<Rating> r) {
213 boost::optional<std::string> full_content_title_text () const {
214 return _full_content_title_text;
217 void set_full_content_title_text (std::string t) {
218 _full_content_title_text = t;
221 boost::optional<std::string> full_content_title_text_language () const {
222 return _full_content_title_text_language;
225 void set_full_content_title_text_language (dcp::LanguageTag l) {
226 _full_content_title_text_language = l.to_string();
229 boost::optional<std::string> release_territory () const {
230 return _release_territory;
233 void set_release_territory (dcp::LanguageTag::RegionSubtag t) {
234 _release_territory = t.subtag();
237 boost::optional<std::string> release_territory_scope () const {
238 return _release_territory_scope;
241 boost::optional<int> version_number () const {
242 return _version_number;
245 void set_version_number (int v);
247 void unset_version_number ();
249 boost::optional<Status> status () const {
253 void set_status (Status s) {
257 boost::optional<std::string> chain () const {
261 void set_chain (std::string c) {
265 boost::optional<std::string> distributor () const {
269 void set_distributor (std::string d) {
273 boost::optional<std::string> facility () const {
277 void set_facility (std::string f) {
281 boost::optional<Luminance> luminance () const {
285 void set_luminance (Luminance l) {
289 boost::optional<dcp::MainSoundConfiguration> main_sound_configuration () const {
290 return _main_sound_configuration;
293 void set_main_sound_configuration(dcp::MainSoundConfiguration c) {
294 _main_sound_configuration = c;
297 boost::optional<int> main_sound_sample_rate () const {
298 return _main_sound_sample_rate;
301 void set_main_sound_sample_rate (int r) {
302 _main_sound_sample_rate = r;
305 boost::optional<dcp::Size> main_picture_stored_area () const {
306 return _main_picture_stored_area;
309 void set_main_picture_stored_area (dcp::Size s) {
310 _main_picture_stored_area = s;
313 boost::optional<dcp::Size> main_picture_active_area () const {
314 return _main_picture_active_area;
317 void set_main_picture_active_area(dcp::Size area);
319 std::vector<std::string> additional_subtitle_languages () const {
320 return _additional_subtitle_languages;
323 void set_additional_subtitle_languages (std::vector<dcp::LanguageTag> const& lang);
325 void set_sign_language_video_language (dcp::LanguageTag lang) {
326 _sign_language_video_language = lang.to_string();
329 boost::optional<std::string> sign_language_video_language () const {
330 return _sign_language_video_language;
333 void set_dolby_edr_image_transfer_function(std::string function) {
334 _dolby_edr_image_transfer_function = function;
337 boost::optional<std::string> dolby_edr_image_transfer_function() const {
338 return _dolby_edr_image_transfer_function;
341 Standard standard () const {
345 /** @return true iff this CPL was read from a file and it contained
346 * a CompositionMetadataAsset node.
348 bool read_composition_metadata() const {
349 return _read_composition_metadata;
352 static std::string static_pkl_type (Standard standard);
355 /** @return type string for PKLs for this asset */
356 std::string pkl_type (Standard standard) const override;
359 friend struct ::verify_invalid_language3;
361 void maybe_write_composition_metadata_asset(xmlpp::Element* node, bool include_mca_subdescriptors) const;
362 void read_composition_metadata_asset (cxml::ConstNodePtr node);
363 void write_mca_subdescriptors(xmlpp::Element* parent, std::shared_ptr<const SoundAsset> asset) const;
366 std::string _creator;
367 std::string _issue_date;
368 boost::optional<std::string> _annotation_text;
369 std::string _content_title_text; ///< <ContentTitleText>
370 ContentKind _content_kind; ///< <ContentKind>
371 std::vector<ContentVersion> _content_versions;
372 std::vector<Rating> _ratings;
373 /** ID for CompositionMetadataAsset tag; either a random one, ready for writing a new tag,
374 * or the one read in from the existing CPL.
376 std::string _cpl_metadata_id = make_uuid();
377 /** Human-readable name of the composition, without any metadata (i.e. no -FTR-EN-XX- etc.) */
378 boost::optional<std::string> _full_content_title_text;
379 boost::optional<std::string> _full_content_title_text_language;
380 /** This is stored and returned as a string so that we can tolerate non-RFC-5646 strings,
381 * but must be set as a dcp::LanguageTag to try to ensure that we create compliant output.
383 boost::optional<std::string> _release_territory;
384 boost::optional<std::string> _release_territory_scope;
385 boost::optional<int> _version_number;
386 boost::optional<Status> _status;
387 boost::optional<std::string> _chain;
388 boost::optional<std::string> _distributor;
389 boost::optional<std::string> _facility;
390 boost::optional<Luminance> _luminance;
391 boost::optional<MainSoundConfiguration> _main_sound_configuration;
392 boost::optional<int> _main_sound_sample_rate;
393 boost::optional<dcp::Size> _main_picture_stored_area;
394 boost::optional<dcp::Size> _main_picture_active_area;
395 /* See note for _release_territory above */
396 std::vector<std::string> _additional_subtitle_languages;
397 boost::optional<std::string> _sign_language_video_language;
398 boost::optional<std::string> _dolby_edr_image_transfer_function;
399 bool _read_composition_metadata = false;
401 std::vector<std::shared_ptr<Reel>> _reels;
403 /** Standard of CPL that was read in */