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"
50 #include <boost/filesystem.hpp>
51 #include <boost/function.hpp>
52 #include <boost/optional.hpp>
57 struct verify_invalid_language3;
63 class CertificateChain;
72 * @brief A Composition Playlist
74 * A CPL contains some metadata and a list of Reel objects, each of which may contain picture, sound and other assets
75 * such as subtitles and closed captions.
77 * After creating a CPL you can add Reel objects with add(), and write an XML file describing the CPL with
80 class CPL : public Asset
83 CPL (std::string annotation_text, ContentKind content_kind, Standard standard);
85 /** Construct a CPL object from a XML file */
86 explicit CPL (boost::filesystem::path file);
89 std::shared_ptr<const Asset> other,
90 EqualityOptions const& options,
94 /** Add a reel to this CPL
95 * @param reel Reel to add
97 void add (std::shared_ptr<Reel> reel);
99 void set (std::vector<std::shared_ptr<Reel>> reels);
101 /** Add a KDM to this CPL. If the KDM is for any of this CPLs assets it will be used
102 * to decrypt those assets.
105 void add (DecryptedKDM const &);
107 /** @return the reels in this CPL */
108 std::vector<std::shared_ptr<Reel>> reels () const {
112 /** @return the ReelFileAssets in this CPL in all reels */
113 std::vector<std::shared_ptr<const ReelFileAsset>> reel_file_assets () const;
114 std::vector<std::shared_ptr<ReelFileAsset>> reel_file_assets ();
116 /** @return true if we have any encrypted content */
117 bool any_encrypted () const;
119 /** @return true if we have all our encryptable content is encrypted */
120 bool all_encrypted () const;
122 /** Write a CompositionPlaylist XML file
124 * @param file Filename to write
125 * @param signer Signer to sign the CPL, or 0 to add no signature
126 * @param include_mca_subdescriptors true to add a MCASubDescriptors tag to metadata,
130 boost::filesystem::path file,
131 std::shared_ptr<const CertificateChain>,
132 bool include_mca_subdescriptors = true
135 void resolve_refs (std::vector<std::shared_ptr<Asset>>);
137 int64_t duration () const;
139 std::string issuer () const {
143 void set_issuer (std::string issuer) {
147 std::string creator () const {
151 void set_creator (std::string creator) {
155 void set_issue_date (std::string issue_date) {
156 _issue_date = issue_date;
159 /** @return contents of the <AnnotationText> node, if present */
160 boost::optional<std::string> annotation_text () const {
161 return _annotation_text;
164 void set_annotation_text (std::string at) {
165 _annotation_text = at;
168 /** @return contents of the <ContentTitleText> node */
169 std::string content_title_text () const {
170 return _content_title_text;
173 void set_content_title_text (std::string ct) {
174 _content_title_text = ct;
177 void set_content_kind (dcp::ContentKind k) {
181 /** @return the type of the content, used by media servers
182 * to categorise things (e.g. feature, trailer, etc.)
184 ContentKind content_kind () const {
185 return _content_kind;
188 boost::optional<ContentVersion> content_version () const;
190 std::vector<ContentVersion> content_versions () const {
191 return _content_versions;
194 void set_content_version (ContentVersion v) {
195 _content_versions.clear ();
196 _content_versions.push_back (v);
199 void set_content_versions (std::vector<ContentVersion> v);
201 std::vector<Rating> ratings () const {
205 void set_ratings (std::vector<Rating> r) {
209 boost::optional<std::string> full_content_title_text () const {
210 return _full_content_title_text;
213 void set_full_content_title_text (std::string t) {
214 _full_content_title_text = t;
217 boost::optional<std::string> full_content_title_text_language () const {
218 return _full_content_title_text_language;
221 void set_full_content_title_text_language (dcp::LanguageTag l) {
222 _full_content_title_text_language = l.to_string();
225 boost::optional<std::string> release_territory () const {
226 return _release_territory;
229 void set_release_territory (dcp::LanguageTag::RegionSubtag t) {
230 _release_territory = t.subtag();
233 boost::optional<std::string> release_territory_scope () const {
234 return _release_territory_scope;
237 boost::optional<int> version_number () const {
238 return _version_number;
241 void set_version_number (int v);
243 void unset_version_number ();
245 boost::optional<Status> status () const {
249 void set_status (Status s) {
253 boost::optional<std::string> chain () const {
257 void set_chain (std::string c) {
261 boost::optional<std::string> distributor () const {
265 void set_distributor (std::string d) {
269 boost::optional<std::string> facility () const {
273 void set_facility (std::string f) {
277 boost::optional<Luminance> luminance () const {
281 void set_luminance (Luminance l) {
285 boost::optional<dcp::MainSoundConfiguration> main_sound_configuration () const {
286 return _main_sound_configuration;
289 void set_main_sound_configuration(dcp::MainSoundConfiguration c) {
290 _main_sound_configuration = c;
293 boost::optional<int> main_sound_sample_rate () const {
294 return _main_sound_sample_rate;
297 void set_main_sound_sample_rate (int r) {
298 _main_sound_sample_rate = r;
301 boost::optional<dcp::Size> main_picture_stored_area () const {
302 return _main_picture_stored_area;
305 void set_main_picture_stored_area (dcp::Size s) {
306 _main_picture_stored_area = s;
309 boost::optional<dcp::Size> main_picture_active_area () const {
310 return _main_picture_active_area;
313 void set_main_picture_active_area(dcp::Size area);
315 std::vector<std::string> additional_subtitle_languages () const {
316 return _additional_subtitle_languages;
319 void set_additional_subtitle_languages (std::vector<dcp::LanguageTag> const& lang);
321 void set_sign_language_video_language (dcp::LanguageTag lang) {
322 _sign_language_video_language = lang.to_string();
325 boost::optional<std::string> sign_language_video_language () const {
326 return _sign_language_video_language;
329 Standard standard () const {
333 /** @return true iff this CPL was read from a file and it contained
334 * a CompositionMetadataAsset node.
336 bool read_composition_metadata() const {
337 return _read_composition_metadata;
340 static std::string static_pkl_type (Standard standard);
343 /** @return type string for PKLs for this asset */
344 std::string pkl_type (Standard standard) const override;
347 friend struct ::verify_invalid_language3;
349 void maybe_write_composition_metadata_asset(xmlpp::Element* node, bool include_mca_subdescriptors) const;
350 void read_composition_metadata_asset (cxml::ConstNodePtr node);
351 void write_mca_subdescriptors(xmlpp::Element* parent, std::shared_ptr<const SoundAsset> asset) const;
354 std::string _creator;
355 std::string _issue_date;
356 boost::optional<std::string> _annotation_text;
357 std::string _content_title_text; ///< <ContentTitleText>
358 ContentKind _content_kind; ///< <ContentKind>
359 std::vector<ContentVersion> _content_versions;
360 std::vector<Rating> _ratings;
361 /** ID for CompositionMetadataAsset tag; either a random one, ready for writing a new tag,
362 * or the one read in from the existing CPL.
364 std::string _cpl_metadata_id = make_uuid();
365 /** Human-readable name of the composition, without any metadata (i.e. no -FTR-EN-XX- etc.) */
366 boost::optional<std::string> _full_content_title_text;
367 boost::optional<std::string> _full_content_title_text_language;
368 /** This is stored and returned as a string so that we can tolerate non-RFC-5646 strings,
369 * but must be set as a dcp::LanguageTag to try to ensure that we create compliant output.
371 boost::optional<std::string> _release_territory;
372 boost::optional<std::string> _release_territory_scope;
373 boost::optional<int> _version_number;
374 boost::optional<Status> _status;
375 boost::optional<std::string> _chain;
376 boost::optional<std::string> _distributor;
377 boost::optional<std::string> _facility;
378 boost::optional<Luminance> _luminance;
379 boost::optional<MainSoundConfiguration> _main_sound_configuration;
380 boost::optional<int> _main_sound_sample_rate;
381 boost::optional<dcp::Size> _main_picture_stored_area;
382 boost::optional<dcp::Size> _main_picture_active_area;
383 /* See note for _release_territory above */
384 std::vector<std::string> _additional_subtitle_languages;
385 boost::optional<std::string> _sign_language_video_language;
386 bool _read_composition_metadata = false;
388 std::vector<std::shared_ptr<Reel>> _reels;
390 /** Standard of CPL that was read in */