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 explicit CPL (boost::filesystem::path file);
90 std::shared_ptr<const Asset> other,
91 EqualityOptions const& options,
95 /** Add a reel to this CPL
96 * @param reel Reel to add
98 void add (std::shared_ptr<Reel> reel);
100 void set (std::vector<std::shared_ptr<Reel>> reels);
102 /** Add a KDM to this CPL. If the KDM is for any of this CPLs assets it will be used
103 * to decrypt those assets.
106 void add (DecryptedKDM const &);
108 /** @return the reels in this CPL */
109 std::vector<std::shared_ptr<Reel>> reels () const {
113 /** @return the ReelFileAssets in this CPL in all reels */
114 std::vector<std::shared_ptr<const ReelFileAsset>> reel_file_assets () const;
115 std::vector<std::shared_ptr<ReelFileAsset>> reel_file_assets ();
117 /** @return true if we have any encrypted content */
118 bool any_encrypted () const;
120 /** @return true if we have all our encryptable content is encrypted */
121 bool all_encrypted () const;
123 /** Write a CompositionPlaylist XML file
125 * @param file Filename to write
126 * @param signer Signer to sign the CPL, or 0 to add no signature
127 * @param include_mca_subdescriptors true to add a MCASubDescriptors tag to metadata,
131 boost::filesystem::path file,
132 std::shared_ptr<const CertificateChain>,
133 bool include_mca_subdescriptors = true
136 void resolve_refs (std::vector<std::shared_ptr<Asset>>);
138 int64_t duration () const;
140 std::string issuer () const {
144 void set_issuer (std::string issuer) {
148 std::string creator () const {
152 void set_creator (std::string creator) {
156 void set_issue_date (std::string issue_date) {
157 _issue_date = issue_date;
160 /** @return contents of the <AnnotationText> node, if present */
161 boost::optional<std::string> annotation_text () const {
162 return _annotation_text;
165 void set_annotation_text (std::string at) {
166 _annotation_text = at;
169 /** @return contents of the <ContentTitleText> node */
170 std::string content_title_text () const {
171 return _content_title_text;
174 void set_content_title_text (std::string ct) {
175 _content_title_text = ct;
178 void set_content_kind (dcp::ContentKind k) {
182 /** @return the type of the content, used by media servers
183 * to categorise things (e.g. feature, trailer, etc.)
185 ContentKind content_kind () const {
186 return _content_kind;
189 boost::optional<ContentVersion> content_version () const;
191 std::vector<ContentVersion> content_versions () const {
192 return _content_versions;
195 void set_content_version (ContentVersion v) {
196 _content_versions.clear ();
197 _content_versions.push_back (v);
200 void set_content_versions (std::vector<ContentVersion> v);
202 std::vector<Rating> ratings () const {
206 void set_ratings (std::vector<Rating> r) {
210 boost::optional<std::string> full_content_title_text () const {
211 return _full_content_title_text;
214 void set_full_content_title_text (std::string t) {
215 _full_content_title_text = t;
218 boost::optional<std::string> full_content_title_text_language () const {
219 return _full_content_title_text_language;
222 void set_full_content_title_text_language (dcp::LanguageTag l) {
223 _full_content_title_text_language = l.to_string();
226 boost::optional<std::string> release_territory () const {
227 return _release_territory;
230 void set_release_territory (dcp::LanguageTag::RegionSubtag t) {
231 _release_territory = t.subtag();
234 boost::optional<std::string> release_territory_scope () const {
235 return _release_territory_scope;
238 boost::optional<int> version_number () const {
239 return _version_number;
242 void set_version_number (int v);
244 void unset_version_number ();
246 boost::optional<Status> status () const {
250 void set_status (Status s) {
254 boost::optional<std::string> chain () const {
258 void set_chain (std::string c) {
262 boost::optional<std::string> distributor () const {
266 void set_distributor (std::string d) {
270 boost::optional<std::string> facility () const {
274 void set_facility (std::string f) {
278 boost::optional<Luminance> luminance () const {
282 void set_luminance (Luminance l) {
286 boost::optional<dcp::MainSoundConfiguration> main_sound_configuration () const {
287 return _main_sound_configuration;
290 void set_main_sound_configuration(dcp::MainSoundConfiguration c) {
291 _main_sound_configuration = c;
294 boost::optional<int> main_sound_sample_rate () const {
295 return _main_sound_sample_rate;
298 void set_main_sound_sample_rate (int r) {
299 _main_sound_sample_rate = r;
302 boost::optional<dcp::Size> main_picture_stored_area () const {
303 return _main_picture_stored_area;
306 void set_main_picture_stored_area (dcp::Size s) {
307 _main_picture_stored_area = s;
310 boost::optional<dcp::Size> main_picture_active_area () const {
311 return _main_picture_active_area;
314 void set_main_picture_active_area(dcp::Size area);
316 std::vector<std::string> additional_subtitle_languages () const {
317 return _additional_subtitle_languages;
320 void set_additional_subtitle_languages (std::vector<dcp::LanguageTag> const& lang);
322 void set_sign_language_video_language (dcp::LanguageTag lang) {
323 _sign_language_video_language = lang.to_string();
326 boost::optional<std::string> sign_language_video_language () const {
327 return _sign_language_video_language;
330 Standard standard () const {
334 /** @return true iff this CPL was read from a file and it contained
335 * a CompositionMetadataAsset node.
337 bool read_composition_metadata() const {
338 return _read_composition_metadata;
341 static std::string static_pkl_type (Standard standard);
344 /** @return type string for PKLs for this asset */
345 std::string pkl_type (Standard standard) const override;
348 friend struct ::verify_invalid_language3;
350 void maybe_write_composition_metadata_asset(xmlpp::Element* node, bool include_mca_subdescriptors) const;
351 void read_composition_metadata_asset (cxml::ConstNodePtr node);
352 void write_mca_subdescriptors(xmlpp::Element* parent, std::shared_ptr<const SoundAsset> asset) const;
355 std::string _creator;
356 std::string _issue_date;
357 boost::optional<std::string> _annotation_text;
358 std::string _content_title_text; ///< <ContentTitleText>
359 ContentKind _content_kind; ///< <ContentKind>
360 std::vector<ContentVersion> _content_versions;
361 std::vector<Rating> _ratings;
362 /** ID for CompositionMetadataAsset tag; either a random one, ready for writing a new tag,
363 * or the one read in from the existing CPL.
365 std::string _cpl_metadata_id = make_uuid();
366 /** Human-readable name of the composition, without any metadata (i.e. no -FTR-EN-XX- etc.) */
367 boost::optional<std::string> _full_content_title_text;
368 boost::optional<std::string> _full_content_title_text_language;
369 /** This is stored and returned as a string so that we can tolerate non-RFC-5646 strings,
370 * but must be set as a dcp::LanguageTag to try to ensure that we create compliant output.
372 boost::optional<std::string> _release_territory;
373 boost::optional<std::string> _release_territory_scope;
374 boost::optional<int> _version_number;
375 boost::optional<Status> _status;
376 boost::optional<std::string> _chain;
377 boost::optional<std::string> _distributor;
378 boost::optional<std::string> _facility;
379 boost::optional<Luminance> _luminance;
380 boost::optional<MainSoundConfiguration> _main_sound_configuration;
381 boost::optional<int> _main_sound_sample_rate;
382 boost::optional<dcp::Size> _main_picture_stored_area;
383 boost::optional<dcp::Size> _main_picture_active_area;
384 /* See note for _release_territory above */
385 std::vector<std::string> _additional_subtitle_languages;
386 boost::optional<std::string> _sign_language_video_language;
387 bool _read_composition_metadata = false;
389 std::vector<std::shared_ptr<Reel>> _reels;
391 /** Standard of CPL that was read in */